Skip to content

Enable JSON Schema multi file output#2526

Open
kmturley wants to merge 4 commits into
glideapps:masterfrom
kmturley:feature/json-schema-multi-file
Open

Enable JSON Schema multi file output#2526
kmturley wants to merge 4 commits into
glideapps:masterfrom
kmturley:feature/json-schema-multi-file

Conversation

@kmturley

@kmturley kmturley commented Mar 4, 2024

Copy link
Copy Markdown

This PR adds support for json schema multi file output.

Without multi-file-output option:
Screenshot 2024-03-03 at 10 38 34 PM

With multi-file-output option:
Screenshot 2024-03-03 at 10 39 20 PM

Tested with this repo:
https://github.com/kmturley/quicktype-typescript-input-demo

Replacing the packages/quicktype-core/dist/language/JSONSchema.js file with the compiled file from this PR

@schani

schani commented Jul 20, 2026

Copy link
Copy Markdown
Member

Thanks for this — a multi-file JSON Schema output (one file per definition, e.g. for schema registries or per-type $ids) is a feature we want, and the overall shape here is right: single-file output stays byte-for-byte unchanged, and you correctly reused the existing startFile/finishFile/initializeEmitContextForFilename machinery other multi-file renderers already use.

A few things need to be resolved before this can merge, though:

  • Blocker: cross-file $refs dangle. makeRef (JSONSchemaRenderer.ts, untouched by this PR) always emits a same-document pointer, { $ref: "#/definitions/${name}" }. Once each definition moves to its own file, any reference to another definition points at a definitions block that no longer exists in that file — the output isn't valid/resolvable JSON Schema in multi-file mode. makeRef needs to be ref-aware, e.g. emitting Other.schema#/definitions/Other for cross-file references when multiFileOutput is on.
  • Every per-definition file embeds the $schema header and the top-level root type/ref. outputFile (the new private helper in JSONSchemaRenderer.ts) is called both for the root/stdout case and for each object/union/enum, and unconditionally prepends $schema plus topLevelType. That's wrong for every file except the root — per-definition files shouldn't restate the document's root type.
  • No test coverage. Per repo convention this needs end-to-end fixture coverage, but there's also no harness support yet to validate multi-file output at all (every emitted file parses, every cross-file $ref resolves) — needs adding to the JSON Schema fixture path in test/fixtures.ts.
  • Merge conflicts with current master in both changed files (JSONSchemaRenderer.ts, language.ts) — ESM .js import suffixes, biome formatting (object literal vs. Object.assign), and getOptions(): Record<string, never> typing. Mechanical, but need a rebase.
  • Minor: outputFile("stdout", ...) passes a filename that's never used in single-file mode (since startFile/endFile short-circuit when multiFileOutput === false); and the new startFile doc comment (copied from GolangRenderer) says it lowercases the filename, but this implementation doesn't.

Given the size of the ref-rewriting fix (item 1) plus the missing test infrastructure, this needs another pass. @kmturley, want to pick it back up? If not, we'd like to reimplement using this as the starting point, with credit for the original approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants