Open dherges opened 6 years ago
Thanks for the reports @dherges.
@BigstickCarpet Is Example A kosher?
@dherges Can you post the complete JSON-Schema for Example B? From what you gave it's not clear to me why the output is incorrect.
Hi @bcherny,
thanks for the response and your time! Here are the full repros.
{
"title": "Example Schema",
"definitions": {
"person": {
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"children": {
"type": "array",
"items": { "$ref": "#/definitions/person" }
}
}
}
},
"type": "object",
"$ref": "#/definitions/person"
}
Error message:
$ node_modules/.bin/json2ts wound-ui/ui/foo.json
error Refs should have been resolved by the resolver! { title: 'Example Schema',
definitions: { person: { type: 'object', properties: [Object] } },
type: 'object',
required: [],
additionalProperties: true,
id: 'Foo',
properties:
{ firstName: { type: 'string' },
children: { type: 'array', items: [Object] } },
'$ref': '#' }
{
"title": "Example Schema",
"definitions": {
"person": {
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"children": {
"type": "array",
"items": { "$ref": "#/definitions/person" }
}
}
}
},
"type": "object",
"properties": {
"$ref": "#/definitions/person/properties"
}
}
export interface ExampleSchema {
firstName?: string;
children?: Person[];
[k: string]: any;
}
export interface Person {
firstName?: string;
children?: Person[];
[k: string]: any;
}
I could live by that output as it's somewhat 'okay' due to duck typing in TypeScript world, but I wonder why two interfaces are being generated?!?
I found two working version by setting $ref: '.'
and $ref: '#'
in the properties.children.items
:
{
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"children": {
"type": "array",
"items": { "$ref": "." }
}
}
}
export interface Bar {
firstName?: string;
children?: Bar[];
[k: string]: any;
}
{
"type": "object",
"properties": {
"firstName": {
"type": "string"
},
"children": {
"type": "array",
"items": { "$ref": "#" }
}
}
}
export interface Bar {
firstName?: string;
children?: Bar[];
[k: string]: any;
}
@bcherny - Example A in @dherges' post isn't supported by json-schema-ref-parser. It's technically not a valid JSON Schema, since a JSON Reference object is only allowed to have a $ref
property (any other property are ignored, per the spec).
{
"$ref": "#/foo/bar",
"name": "Foo" // <--- not allowed
}
That said, json-schema-ref-parser supports JSON Reference objects with additional properties, even though that's not technically spec-compliant. I chose to support it because many people asked for it and had real-world situations where they relied on it. However, allowing a non-spec-compliant feature causes problems such as the one that @dherges is facing.
My recommendation is to go with something like Example B in @dherges' post. Even though it may not seem quite as elegant, it is spec-compliant.
@BigstickCarpet As always, thanks for chiming in.
@dherges You heard it here, Example A is invalid. For example B, nicer output might be:
export type ExampleSchema = Person
export interface Person {
firstName?: string;
children?: Person[];
[k: string]: any;
}
Is that what you had in mind?
@dherges Can you chime in?
Yes, exactly!
I have the same issue. Here is a schema eksctl.json.zip
Any update on this?
I am stil getting this error any workarounds?
As I ran into the same issue (and this is the top result in google), here is what you can do to prevent this error from occurring (not gonna join the debate on valid or invalid schema 😉 ).
As your$ref
can most likely be replaced with an allOf
, instead of doing something like this:
YAML | JSON |
```yaml $ref: "#/definitions/child" definitions: child: description: Hello World ``` | ```json { "$ref": "#/definitions/child", "definitions": { "child": { "description": "Hello World", } } } ``` |
You can do this, and your types should generate
YAML | JSON |
```yaml allOf: - $ref: "#/definitions/child" definitions: child: description: Hello World ``` | ```json { "allOf": [ { "$ref": "#/definitions/child" } ], "definitions": { "child": { "description": "Hello World", } } } ``` |
Just listing an example being used in production, I hope that's ok. https://turbo.build/schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/Schema",
"definitions": {
"Schema": {
"type": "object",
"properties": {...}
}
}
}
Facing the same issue for schema at: https://github.com/decentralized-identity/presentation-exchange/blob/main/schemas/v2.0.0/submission-requirement.json
{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Presentation Submission Requirement", "definitions": { "submission_requirement": { "type": "object", "oneOf": [ { "properties": { "name": { "type": "string" }, "purpose": { "type": "string" }, "rule": { "type": "string", "enum": ["all", "pick"] }, "count": { "type": "integer", "minimum": 1 }, "min": { "type": "integer", "minimum": 0 }, "max": { "type": "integer", "minimum": 0 }, "from": { "type": "string" } }, "required": ["rule", "from"], "additionalProperties": false }, { "properties": { "name": { "type": "string" }, "purpose": { "type": "string" }, "rule": { "type": "string", "enum": ["all", "pick"] }, "count": { "type": "integer", "minimum": 1 }, "min": { "type": "integer", "minimum": 0 }, "max": { "type": "integer", "minimum": 0 }, "from_nested": { "type": "array", "minItems": 1, "items": { "$ref": "#/definitions/submission_requirement" } } }, "required": ["rule", "from_nested"], "additionalProperties": false } ] } }, "$ref": "#/definitions/submission_requirement" }
Using the workaround from @mmdk95 for now
i have the same problem with the openapi schema (3.1) https://github.com/OAI/OpenAPI-Specification/blob/main/schemas/v3.1/schema.json
i have the same problem with the openapi schema (3.1) https://github.com/OAI/OpenAPI-Specification/blob/main/schemas/v3.1/schema.json
same
I have the same issue with ALL schemas from https://app.quicktype.io/schema
A
$ref
breaks when used on the root objectExample A
Non-working example:
Error message will be:
It will log:
I wonder where the
$ref: '#'
comes from?Example B
Working but with duplicated interface
Generated code is: