-
Notifications
You must be signed in to change notification settings - Fork 217
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
All $refs
must use #/$defs/{def_name}
syntax rather than {def_name}.yaml/json
#3369
Comments
|
pri: 2 |
Some background and info: The JSON Schema emitter produces valid JSON Schema 2020-12. When the emitter needs to combine multiple schemas into a single file, either because the user provided a bundleId to the emitter, or because a type references another type outside a JSON Schema namespace (as is the case above), it does this by producing a bundle as defined in the JSON Schema 2020-12 specification. This is to ensure that you always get consistent behavior whether or not you choose to bundle. I have found that VSCode does not support JSON Schema 2020-12. This emitter implements the bundling behavior added in that specification. Even with using json pointer style references, VSCode will not provide completions for authoring 2020-12 schemas. I think the reference approach when passing I think the correct fix here is the following:
What this would mean is that for this specific case, where referenced types outside of the JSON Schema namespace are included in the same file, the reference would use JSON Pointers and tooling would work in VSCode. However, when passing |
Yes, it would work for me. Thank you for clarifying the bundling approach. Now it makes sense to me. The behavior when using |
Fixes #3369 by changing how types are bundled. In particular, when a type is not a JSON Schema type, we never create a root schema for it. Instead, it is inlined into the defs of any schema which references it, and referenced using a JSON pointer. This PR makes bundling have essentially no impact on emitted schemas, and is merely a way to bundle them into a single file. The approach is as follows: * When a type references another type outside a JSON Schema namespace, include the referenced type under $defs: * Such referenced types do not have a $id or $schema field * Such referenced types are referenced via JSON pointers not ids * Bundling does not alter the bundled schemas or introduce new root schemas. This changes two things from what we do today: * The `$id` of the bundled schemas now includes the file path as it does for non-bundled schemas (whereas before it was just the type name) * non-JSON Schema types do not get $defs in the bundle, so the bundle has the same root schemas as would be written to disk when not bundling. In terms of implementation, the basic approach is to not handle bundling via the emitter framework source files. Instead, we always create source files for root schemas, and inline the necessary defs as we did before (but now using JSON pointers). Then when we're about to write source files, if we're bundling we assemble the bundle and emit that single file, otherwise we emit each source file that contains a root schema. Todo: * [ ] Validate that the bundled schemas continue to work with ajv. * [ ] Cleanups --------- Co-authored-by: Vitalii Kryvenko <[email protected]>
Clear and concise description of the problem
Right now the following simple TSP declaration
produces this JSON schema with
tsp compile .
A single file with the schema is output, which is cool and convenient. However the
$ref
s point to non-existent files. I understand that each object in$defs
also gets an$id
with the file name that$ref
s point to, however all VSCode extensions that I use for providing completions and docs with JSONSchema don't support this kind of intra-file references. They all think as ifBar.yaml
is supposed to be an external schema and try to load that file instead.The extensions that I tested it with which don't support this style of references are:
Expected
The
$ref
s should all use the syntax#/$defs/{def_name}
instead. This is what extensions usually expect when it comes to intra-schema-file references.I don't know why
{def_name}.yaml/json
syntax for references was chosen by default, but if it's really useful in some use cases, then I propose to make the behavior configurable. TSP should be able to generate#/$defs/{def_name}
via the emitter options, for example.Workaround
Right now I'm working around this problem with this custom decorator that I put at the top level type definition in my JSON schema. It overrides the default
$id
of the generated definitions to use the desired syntax. However, this is quite a hack.With this workaround decorator that I place on top of
Foo
model I get the following output:Checklist
The text was updated successfully, but these errors were encountered: