Conversation
v16 adds native support for the OpenAPI 3.0 `nullable: true` keyword (bcherny/json-schema-to-typescript#755), which makes the local `populateNullableTypes` workaround redundant — and actively harmful: it rewrites `{ ..., nullable: true }` into `anyOf: [{ ..., nullable: true }, { type: "null" }]` but leaves the `nullable` flag on the inner schema, so v16 appends a second `| null` and emits `(T | null) | null` about 120 times per generated types file. Dropping the workaround in favour of the upstream implementation is also strictly more correct. The workaround was only applied to `components.schemas` (see Schemas.ts), so `nullable: true` on inline schemas under `paths` was silently discarded; v16 honours it everywhere. It additionally handles `nullable` next to a `$ref`, which the workaround bailed out on. Verified behaviour-preserving for `components.schemas`: regenerating with v16 and no workaround leaves that whole section byte-identical to the v15 output. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Regenerated with json-schema-to-typescript v16. All changes come from
v16 honouring `nullable: true` on inline schemas under `paths`, which
v15 silently discarded — the specs always declared these fields
nullable.
Request bodies (widening, safe — callers may now also pass `null`):
- PATCH /v2/stacks/{stackId} — `updateSchedule`
- PATCH /v2/mail-addresses/{mailAddressId}/autoresponder — the inline
`{ expiresAt, message, startsAt }` object
- PATCH /v2/contributors/{contributorId} — `descriptions`,
`deviatingContractOwner`, `deviatingSupportInformation`
- PATCH /v2/contributors/{contributorId}/extensions/{extensionId} —
`detailedDescriptions`, `externalFrontends`, `frontendFragments`,
`webhookUrls`
- PUT and PATCH on the project/server storage-space endpoints —
`notificationThresholdInBytes`
Cosmetic (type-equivalent):
- `DomainmigrationDomainNotMigratableValidationError.context` index
signature widened from `string` to
`string | DomainmigrationDomainNotMigratableReason` by
bcherny/json-schema-to-typescript#704 (TS2411 fix). `Reason` is a
union of string literals and therefore a subtype of `string`, so the
index signature accepts and yields exactly the same values as before.
BREAKING CHANGE: `score` on the `metrics` entries of the
GET /v2/page-insights 200 response is now typed `number | null` instead
of `number`. The spec declares it `nullable: true`, so the API could
always return `null` here and the previous type was wrong. Under
`strictNullChecks`, consumers reading `metrics[].score` must now
narrow it before use.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Master's date-time PR (#299) added `RequestSchemas.ts`, modelled on `Schemas.ts` and therefore still calling the `populateNullableTypes` workaround this branch deletes — the merge left the generator uncompilable. The removal is applied there as well; the defensive `cloneDeep` stays. The committed client was regenerated from the merged state, so the generated types carry both the v16 `nullable` handling and master's widened date-time request parameters. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Split out of #303, which bumped the rest of the production dependency majors.
json-schema-to-typescriptwas held back because it is the only bump in that batch that changes the generated client output.There is one breaking public type change (below), so this is a
feat!with aBREAKING CHANGE:footer. lerna-lite will therefore cut a major: the repo is currently on4.455.x, so merging this releases5.0.0. If that is not wanted right now, this PR should wait rather than be downgraded to a non-breaking commit type — the type change is real either way.The
(T | null) | nullnoise is fixed, not shippedA naive bump produces ~164 insertions / 132 deletions across the two generated
types.tsfiles, ~120 of which are redundant(T | null) | nullnestings. Those are not shipped here.Root cause: v16 adds native support for the OpenAPI 3.0
nullable: truekeyword (bcherny/json-schema-to-typescript#755). The localpopulateNullableTypeshelper rewrote{ ..., nullable: true }intoanyOf: [{ ..., nullable: true }, { type: "null" }]but left thenullableflag on the inner schema, so v16 appended a second| null.populateNullableTypesis deleted in favour of the upstream implementation. That is strictly more correct, not just tidier:components.schemas(Schemas.ts), sonullable: trueon inline schemas underpathswas silently discarded. v16 honours it everywhere — this is where every remaining diff line comes from.$refschemas; v16 handlesnullablenext to a$reftoo. (No occurrences in the current specs, so no output change from this.)Evidence that the removal is behaviour-preserving where the helper did apply: regenerating with v16 and no helper leaves the entire
components.schemassection byte-identical to the v15 output. The only change in that section is the cosmetic index signature below.With the fix, the generated diff is 30 lines per file instead of 148.
Classification of every remaining change
Reviewed line by line across both
v2/types.tsandv3-next/types.ts(v3-next mirrors v2 exactly).Widening — safe (request bodies, callers may now also pass
null)PATCH /v2/stacks/{stackId}updateSchedulePATCH /v2/mail-addresses/{mailAddressId}/autoresponder{ expiresAt, message, startsAt }PATCH /v2/contributors/{contributorId}descriptions,deviatingContractOwner,deviatingSupportInformationPATCH /v2/contributors/{contributorId}/extensions/{extensionId}detailedDescriptions,externalFrontends,frontendFragments,webhookUrlsPUT/PATCHproject + server storage-space endpointsnotificationThresholdInBytesCosmetic — type-equivalent
DomainmigrationDomainNotMigratableValidationError.context:From bcherny/json-schema-to-typescript#704 (TS2411 fix — index signatures widened to cover sibling named properties).
DomainmigrationDomainNotMigratableReasonis a union of string literals and therefore a subtype ofstring, so the index signature accepts and yields exactly the same set of values. Noisier to read, identical to use.Narrowing — BREAKING (1 occurrence)
GET /v2/page-insights,200response,metrics[]:The spec declares
scoreas{"type": "number", "format": "double", "nullable": true}. v15 dropped that because the field lives in an inline path schema, so the previous type was wrong — the API could always returnnullhere. UnderstrictNullChecks, consumers readingmetrics[].scoremust now narrow before use. Correct, but breaking, hence the major.Verification
test:client-generation-cleanis not evidence of anything here — it is literallygit diff --exit-code, and nothing in CI runsbuild:client-prod, so generated-output changes are invisible to the PR pipeline. The regeneration was run locally instead; the committed specs underpackages/mittwald/spec/make it deterministic and offline.yarn lint✅yarn nx run-many -t build --skip-nx-cache✅yarn nx run-many -t test:compile --skip-nx-cache✅yarn nx run-many -t test --skip-nx-cache✅packages/generatorunit tests — 23 passed, 7 suites ✅ (the generator'stesttarget is empty, sotest:unitwas run explicitly)build:client-prodreproduced the committed output exactlyThe regeneration is a separate commit (
feat!: update generated client) so the generated diff is reviewable on its own. Note that this means the first commit is not green in isolation — the generator changes without the matching regeneration — which is inherent to the split..yarnrc.ymlsetsnpmMinimalAgeGate: 10080;json-schema-to-typescript@16.0.0is past the 7-day window and installs cleanly.🤖 Generated with Claude Code