2 bugs in conversion of openapi json schema.
I tried to convert the json schema defintion for openapi to a schema.t.ts.
At first it looked succesful, but there are several details which are omitted from the final schema. Here are some examples:
The resulting main node is represented by the generated HttpsSpecOpenapisOrgOas30Schema20190402 interface.
This interface describes paths, which is correct.
In reality in a json data file, the paths element could look like:
paths: {
"/some/random/text": {...}
"/another/random/text": {...}
}
By contrast, the generated interface for this paths field is just an empty type.
export interface Paths {}
It should have been more like:
export interface Paths {
[path: string]: ...
}
The openapi json schema defines it using a reference:
"paths": {
"$ref": "#/definitions/Paths"
},
This reference to #/definitions/Paths actually points to:
"Paths": {
"type": "object",
"patternProperties": {
"^\\/": {
"$ref": "#/definitions/PathItem"
},
"^x-": {
}
},
"additionalProperties": false
},
I have to admit, there is something special about this case, because it uses a regex for its property names.
The regex is used to define that its properties (e.g. /some/random/text) should start with a slash.
Well, right now, it just ommits those properties in the generated interface. But it would make more sense to just allow a string, right ?
Another issue is how the Parameter's are converted.
The json schema doc defines a required name field, some other properties and finally an allOf of 3 other types.
"Parameter": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
...
}
...
"patternProperties": {
"^x-": {
}
},
"additionalProperties": false,
"required": [
"name",
"in"
],
"allOf": [
{
"$ref": "#/definitions/ExampleXORExamples"
},
{
"$ref": "#/definitions/SchemaXORContent"
},
{
"$ref": "#/definitions/ParameterLocation"
}
]
},
Unfortunately, it just generates the following union type:
export type Parameter = ExampleXORExamples & SchemaXORContent & ParameterLocation;
It only used the allOf section, but just forgot all about the properties which were defined on Parameter itself.
As a result crucial properties like name are just missing.
I hope this is of use for somebody. 👍 Keep up the good work.
Unfortunately many people already reported the second bug you are talking about with no answer/solution by those who contribute...
Hey, thanks for the report! Could you whittle these down to minimal repro cases?
I'm adding this test case to the repo. Hopefully with a minimal repro case we can whittle things down a bit.
Here's an attempt:
id: https://spec.openapis.org/oas/3.0/schema/2019-04-02
$schema: http://json-schema.org/draft-04/schema#
description: A minimal repro case with one local property and 2 included types.
type: object
properties:
fooBar:
$ref: '#/definitions/FooBar'
definitions:
FooBar:
type: object
properties:
dontForgetMe:
type: string
additionalProperties: false
required:
- dontForgetMe
allOf:
- $ref: '#/definitions/Foo'
- $ref: '#/definitions/Bar'
Foo:
type: object
properties:
foo:
type: string
additionalProperties: false
Bar:
type: object
properties:
bar:
type: string
additionalProperties: false
- I would assume that the output should include a
FooaBarand aFooBarinterface (and then one additional one for the root). - The
FooBaruses anallOfto include the 2 other types, so I would assume that this means that theFooBarinterface extends the 2 other interfaces. - Then finally, the
FooBaralso defines an additional propertydontForgetMe: string.
So, the result should include these 3 interfaces:
interface Foo {
foo?: string;
}
interface Bar {
bar?: string;
}
interface FooBar extends Foo, Bar {
dontForgetMe?: string;
}
Quick update: Second issue should be fixed in v10.0.0.
First issue needs a bit more thought-
- If we allow a string anytime a schema declares a patternProperty, that means you'll be able to assign invalid values to your schema. JSTT has erred on the side of being conservative here, so far.
- It could be worth revisiting this, and being more lenient instead (eg. allow string keys, and emit a comment containing the original regex for documentation). Others have proposed this before too.
- TS template types might change things -- could it be possible to emit TS types that represent some subset of simple regexes?