Tool to down convert OpenAPI 3.1 to OpenAPI 3.0
npm install @apiture/openapi-down-convertopenapi-down-convert is a tool to down-convert an API definition document from
OpenAPI 3.1 to OpenAPI 3.0.
* OpenAPI Specification (OAS) 3.1.0 Release
describes the changes from OAS 3.0 to OAS 3.1.
* See
Migrating from OpenAPI 3.0 to 3.1.0
for going in the other direction. This tool helps "undo" some of those transformations.
Warning: This is not a fully robust tool. It does the minimal work necessary
for OAS 3.1 API documents in order to support tools such as openapi-generator
which do not support OAS 3.1. It only supports the OAS 3.1 features that the
Apiture APIs use.
Warning: Down converting yields a loss in fidelity. Some API information
is lost.
The tool is implemented with Node.js.
``bash`
npm i @apiture/openapi-down-convert
`typescript`
import { Converter, ConverterOptions } from './converter';
const options : ConverterOptions = { verbose: false,
deleteExampleWithId: true,
allOfTransform: false };
const converter = new Converter(oas31Document, options);
try {
const oas30Document = converter.convert();
...
}
} catch (ex) {
// handle the exception
}
Since the use case for the converter is in build pipelines and CLI use,
this operation is synchronous and does not use async/await/Promises.
Install:
`bash`
npm i -g @apiture/openapi-down-convert
then to use:
`bash`
openapi-down-convert --input openapi-3.1.yaml --output openapi-3.0.yaml
Command line options:
`text
Usage: openapi-down-convert [options]
Options:
-i, --input
-o, --output
-a, --allOf If set, convert complex $ref in JSON schemas to allOf
--authorizationUrl
--tokenUrl
-d, --delete-examples-with-id If set, delete any JSON Schema examples that have an id property$comment
--oidc-to-oath2
--convertJsonComments If used, convert in JSON schemasx-comment
to . If omitted, delete$comment
all in JSON schemas.--verbose
(Use to log deletion`
to stdout)
-s, --scopes
This is an alias for --oidc-to-oath2
-v, --verbose Verbose output
-V, --version output the version number
-h, --help display help for command
The verbose mode logs all changes to standard error output stream.
The tool returns a 0 status code upon success or a non-zero status code
if it finds constructs that cannot be down-converted, such as
using contentMediaType: application/octet-stream with a formatbinary
other than , or if a schema has contentEncoding: base64format
and has an existing that is not already base64.
The tool only supports local file-based documents, not URLs.
Download such files to convert:
`bash`
openapi-down-convert --input <(curl -s https://my.host/path/openapi-3.1.yaml) \
--output openapi-3.0.yaml
Here is a list of the transformations the tool performs:
Change openapi: 3.1.x to openapi: 3.0.3
Replace openIdConnect security definition with an oauth2 security requirementopenapi-generator
They are close enough, as far as code generation (such as )Authorization: header
is concerned - it just means an must have a valid token.
Note: This conversion is only performed if the --oidc-to-oauth2 option--scopes
(or it's alias, ) is supplied.authorizationUrl
Use the other options to specify the and tokenUrl for theoauth2 security definition.
TODO: Fetch the openIdConnect connection info and extract the authorization and
token URLs from it.
`yaml`
accessToken:
type: openIdConnect
description: ...
openIdConnectUrl: 'https://auth.apiture.com/openidConnectDiscovery'
becomes something like:
`yaml`
accessToken:
type: oauth2
description: "OpenIDConnect authorization code flow via https://auth.apiture.com/openidConnectDiscovery"
flows:
authorizationCode:
authorizationUrl:
tokenUrl:
scopes:
scope1: Allow the application to access your personal profile data.
scope2: Allow the application to send email on your behalf.
scope3: >-
TODO: describe the 'scope3' scope.
scope4: >-
TODO: describe the 'scope4' scope.
The tool scans all the security objects in all the operations to buildscopes.yaml
a list of the used scopes. The descriptions for the scopes should be
be supplied in the file as simple scopeName: scope description
pairs:
`yaml`
scope1: Allow the application to access your personal profile data.
scope2: Allow the application to send email on your behalf.
For all schemas which contain a $ref object with siblings (description, other$ref
schema elements), replace the : uri with allOf . For example:
`yaml`
myProperty:
description: Blah blah
$ref: '#/components/schemas/MyArray'
becomes:
`yaml`
mySchema:
description: Blah blah
allOf:
- $ref: '#/components/schemas/MyArray'
This also applies to the schema used in parameters or in requestBody objects
and in responses.
Note This transformation is disabled by default because it breaks
openapi-generator 5.4 in cases where the referenced schema is an array.
It generates Typescript types for such cases as
`typescript`
myProperty: Array | null;
model/Model.ts:26:23 - error TS2314: Generic type 'Array
which should be
`typescript`
incompleteAccounts: Array
To enable, use the allOfTransform: true option in the Converter constructor--allOf
or the command line argument. When disabled, the $ref is instead
simplified to a JSON reference.
Other (non-JSON Schema) OAS 3.1 $ref objects can have description and summary.$ref for non-schema objects in OAS 3.0 cannot have description andsummary. openapi-down-convert simply removes description andsummary to yield a valid JSON referencedescription
as required by OAS 3.0. (The resulting OpenAPI will use the $ref
in the target.)
Remove info.license.identifier.
Remove the webhooks object, if present.
OAS 3.0 uses an earlier JSON Schema version
(JSON Schema Specification Wright Draft 00). The tool converts examplesexample
in schemas to a single .
As a special case, if the resulting example includes an id, it is--delete-examples-with-id
deleted if the CLI option is set.
This addresses Spectral issue 2081.
Convert JSON Schema that uses const to an enum with one value. For example
`yaml`
components:
schema:
version:
description: The API version.
type: string
const: '1.0.0'
becomes
`yaml`
components:
schema:
version:
description: The API version.
type: string
enum:
- '1.0.0'
If a schema has a type array of exactly two values, and one of them
is the string 'null', the type is converted to the non-null string item,nullable: true
and added to the schema.
For example:
`yaml`
myResponse:
title: My Response
description: Response from an API operation
type: [ object, 'null' ]
allOf:
...
becomes
`yaml`
myResponse:
title: My Response
description: Response from an API operation
type: object
nullable: true
allOf:
...
and
`yaml`
myResponse:
title: My Response
description: Response from an API operation
type: array
items:
type: [ 'string', 'null' ]
...
becomes
`yaml`
myResponse:
title: My Response
description: Response from an API operation
type: array
items:
type: string
nullable: true
...
This transformation does not handle more complex type array
scenarios such as
`yaml`
type: [ number, string, boolean, 'null']
To support that, the schema would need to be recast using oneOf,properties
but this is not trivial due to other schema attributes that may
be possible (, allOf etc.)
(Contributions welcome.)
The tool removes the unevaluatedProperties value, introduced in later
versions of JSON Schema,
as this is not supported in OAS 3.0 JSON Schema Draft 7
used in OAS 3.0.
`yaml`
myResponse:
title: My Response
description: Response from an API operation
type: object
unevaluatedProperties: false
allOf:
...
becomes
`yaml`
myResponse:
title: My Response
description: Response from an API operation
type: object
allOf:
...
The tool removes any $id or $schema keywords that may appear
inside schema objects.
JSON Schema introduced $comment in schemas in 2020-12.$comment
Since OAS 3.0 uses JSON Schema Draft 4, and some tools
will flag as invalid, this tool removes these comments.
An earlier version of the tool converted $comment to x-comment$comment
However, other tools which do not allow may not not supportx-comment either.
Use the --convert-schema-comments CLI option or setconvertSchemaComments to trueConverter
in the constructor options$comment
to requst conversion of to x-comment rather than deleting $comment.
For example,
`yamlmaxItems
Problems:
title: Problems
description: Problem Items
type: array
maxItems: 1000
$comment: >-
The value 1000 here must match in the ProblemList schema.`
items:
$ref: '#/components/schemas/apiProblem'
becomes
`yamlmaxItems
Problems:
title: Problems
description: Problem Items
type: array
maxItems: 1000
x-comment: >-
The value 1000 here must match in the ProblemList schema.`
items:
$ref: '#/components/schemas/apiProblem'
JSON Schema Draft 7 and later uses contentEncoding to specifyformat: byte
[the encoding of non-JSON string content]
(https://json-schema.org/understanding-json-schema/reference/non_json_data).
Draft 4 supports for Base64 encoded strings.
This tool converts type: string schemas as follows:
| OAS 3.1 schema | OAS 3.0 schema |
|---|---|
|
|
|
|
Currently, the tool does not support the following situations.
Contributions welcome!
* openapi-down-convert does not convertexclusiveMinimum
andexclusiveMaximum
,unevaluatedProperties
,patternProperties
,propertyNames
$ref
as defined in JSON Schema 2020-12; these are not supported in JSON Schema Draft 7
used in OAS 3.0
* The tool only supports self-contained documents. It does not follow or resolve
external documents embedded in the source document.content
* Request body and response body object transformations, such ascontent: { 'application/octet-stream': {} }
reversing ascontentEncoding
described in Migrating from OpenAPI 3.0 to 3.1.0
* Converting other values (7bit, 8bit, binary,quoted-printable
, base16, base32) (Note: contentEncoding: base64 is supported byformat: byte
converting to as listed above.)contentMediaType: 'type/subtype
* Converting to media: { type: 'type/subtype'}` for non-JSON data.