fix(schema): don't collapse allOf-intersected string with date-time to empty#3026
Open
schani wants to merge 4 commits into
Open
fix(schema): don't collapse allOf-intersected string with date-time to empty#3026schani wants to merge 4 commits into
schani wants to merge 4 commits into
Conversation
Generated-output differences35 files differ — 0 modified, 35 new, 0 deleted |
Generated-output differences36 files differ — 0 modified, 36 new, 0 deleted |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
Generating C# (or any language) from GitHub's webhook JSON Schema
(
@octokit/webhooks-schemas@4.2.1/schema.json) fails with:No output is produced at all.
Root cause
allOfin JSON Schema is resolved as a type intersection inpackages/quicktype-core/src/rewrites/ResolveIntersections.ts(
IntersectionAccumulator.updatePrimitiveTypes). That method intersects theset of primitive kinds seen across the
allOfmembers usingisPrimitiveTypeKind, which only coversnull | bool | integer | double | string— it does not include "transformed string" kinds such asdate-time,date,time,uuid, etc.So when one
allOfbranch is a plain{"type": "string"}(or a union like{"type": ["string", "null"]}) and another branch is{"type": "string", "format": "date-time"}, thedate-timebranchcontributes nothing to the primitive-kind intersection (it isn't a
"primitive kind"), and the running intersection collapses to the empty set
— even though a
date-timestring is a specialization ofstring, not adisjoint/conflicting type. With no primitive kind, no array kind, and no
object kind left,
IntersectionUnionBuilder.buildUnionbuilds a union withzero members, which trips the
IRNoEmptyUnionsassertion.This exact pattern occurs repeatedly in the real webhook schema, e.g. a
committer.dateproperty is defined as{"type": "string", "format": "date-time"}in one definition and re-stated as{"type": "string"}in anallOfsibling elsewhere — a common pattern when schema authors combine a$refviaallOfwith an object that repeats a property with a looserconstraint.
Fix
In
IntersectionAccumulator.updatePrimitiveTypes, when one side of theintersection has (plain)
"string"and the other has one or moretransformed string kinds, narrow the result to those transformed kinds
instead of dropping them — mirroring the existing
haveNumberspecial casejust above it, which already reconciles
integervsdoublethe same way.getMemberKinds()was also updated so the plain string's accumulated typeattributes are preserved on the narrowed transformed-string kind. Two
different transformed kinds (e.g.
date-timevsuuid) still correctlyconflict and produce an empty intersection, since that is a genuine
contradiction.
Test coverage
Added a JSON Schema fixture that reproduces the bug: an object type whose
dateproperty is{"type": "string", "format": "date-time"}, intersectedvia
allOfwith a sibling schema that restates the same property as plain{"type": "string"}:test/inputs/schema/transformed-string-intersection.schematest/inputs/schema/transformed-string-intersection.1.jsonThis fixture is picked up automatically by every language's
schema-<lang>fixture (per
test/fixtures.tsconventions), so it will be exercised by CIacross all supported target languages.
Verification
node dist/index.js --lang cs --src-lang schema schema.jsonagainst the real@octokit/webhooks-schemas@4.2.1schema failed with the exact reported"empty union" error; a minimized reproduction of the same shape failed the
same way.
generate C# successfully (exit 0), with the affected property emitted as
DateTimeOffset.npx vitest run test/unit: 163/163 tests pass.npm run buildpasses cleanly.QUICKTEST=true FIXTURE=schema-csharp script/test test/inputs/schema/transformed-string-intersection.schemacould not berun in this sandbox (no
dotnettoolchain available to compile/run thegenerated C#), so full fixture round-trip verification for C# is left to
CI; the fixture itself is a normal, automatically-registered
test/inputs/schema/*.schema+.1.jsonpair following the same patternas the existing
intersection*.schemafixtures.Fixes #1770.
🤖 Generated with Claude Code