How to correctly point to refs with JSON Schema emitter, when generated as single file. #4084
-
I am currently attempting to generate a JSON schema from TypeSpec and then use said Schema with a Monaco editor for JSON validation. I couldn't get the behavior of the schema validation to work properly when split into multiple files, so I started to generate the schemas into a single file. Upon doing this I noticed a couple of things.
I was hoping to be pointed in the right direction on how to handle these issues. My current setup looks like such: /typespec/swml/
│
├── main.tsp
│
└── methods/
├── main.tsp
├── answer/
│ └── main.tsp
└── denoise/
└── main.tsp typespec/swml/main.tsp import "@typespec/json-schema";
import "./Methods";
using TypeSpec.JsonSchema;
using SWML.Methods;
@jsonSchema
namespace SWML {
model Section {
main: SWMLMethod[];
...Record<SWMLMethod[]>;
}
model SWMLObject {
version: "1.0.0";
sections: Section
}
} typespec/swml/Methods/main.tsp import "@typespec/json-schema";
import "./answer";
import "./denoise";
using TypeSpec.JsonSchema;
using SWML.Methods;
@jsonSchema
namespace SWML.Methods {
// Union type for methods that do not take any arguments
enum NoArgSWMLMethod {
"answer",
"hangup",
"record",
"stop_record_call",
"denoise",
"stop_denoise",
"receive_fax",
"return",
"stop_tap";
}
@jsonSchema
union SWMLMethod {
Answer,
Denoise,
NoArgSWMLMethod
}
} typespec/swml/Methods/answer/main.tsp import "@typespec/json-schema";
using TypeSpec.JsonSchema;
model Answer {
@doc("Answers an incoming call.")
answer: {
@doc("Maximum time in seconds to wait for an answer. Cannot be less than `7` seconds. Defaults to 14400 seconds.")
@minValue(7)
max_duration?: integer;
@doc("Comma-seperated string of codecs to offer.\n Valid codecs are: [`PCMU,PCMA,G722,G729,AMR-WB,OPUS,VP8,H264`]")
codecs?: string;
}
} typespec/swml/methods/denoise model Denoise {
denoise: {}
} The entire JSON schema that is generated from the above setup: {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "swml.schema.json",
"$defs": {
"NoArgSWMLMethod": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "NoArgSWMLMethod.json",
"type": "string",
"enum": [
"answer",
"hangup",
"record",
"stop_record_call",
"denoise",
"stop_denoise",
"receive_fax",
"return",
"stop_tap"
]
},
"SWMLMethod": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "SWMLMethod.json",
"anyOf": [
{
"$ref": "Answer.json"
},
{
"$ref": "Denoise.json"
},
{
"$ref": "NoArgSWMLMethod.json"
}
]
},
"Answer": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "Answer.json",
"type": "object",
"properties": {
"answer": {
"type": "object",
"properties": {
"max_duration": {
"type": "integer",
"minimum": 7,
"description": "Maximum time in seconds to wait for an answer. Cannot be less than `7` seconds. Defaults to 14400 seconds."
},
"codecs": {
"type": "string",
"description": "Comma-seperated string of codecs to offer.\n Valid codecs are: [`PCMU,PCMA,G722,G729,AMR-WB,OPUS,VP8,H264`]"
}
},
"description": "Answers an incoming call."
}
},
"required": [
"answer"
]
},
"Denoise": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "Denoise.json",
"type": "object",
"properties": {
"denoise": {
"type": "object",
"properties": {}
}
},
"required": [
"denoise"
]
},
"Section": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "Section.json",
"type": "object",
"properties": {
"main": {
"type": "array",
"items": {
"$ref": "SWMLMethod.json"
}
}
},
"required": [
"main"
],
"additionalProperties": {
"type": "array",
"items": {
"$ref": "SWMLMethod.json"
}
}
},
"SWMLObject": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "SWMLObject.json",
"type": "object",
"properties": {
"version": {
"type": "string",
"const": "1.0.0"
},
"sections": {
"$ref": "Section.json"
}
},
"required": [
"version",
"sections"
]
}
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
The root cause here is that our emitter is producing JSON Schema 2020-12 and VSCode supports (I think) draft 7 or so? I am guessing you are emitting a single file via the bundleId option, which produces a bundle as specified in 2020-12 and which unfortunately VSCode doesn't support. One thing that might work - if you have a root object for your schemas, you can put the |
Beta Was this translation helpful? Give feedback.
The root cause here is that our emitter is producing JSON Schema 2020-12 and VSCode supports (I think) draft 7 or so? I am guessing you are emitting a single file via the bundleId option, which produces a bundle as specified in 2020-12 and which unfortunately VSCode doesn't support.
One thing that might work - if you have a root object for your schemas, you can put the
@jsonSchema
decorator directly on that root object, and then any references to other schemas will be inlined and use a ref format that should be compatible. So it would look something this.