feat(parser): populate inline oneOf discriminator mapping and extract every variant#57
Merged
gjtorikian merged 1 commit intomainfrom May 5, 2026
Merged
Conversation
… every variant
When a `oneOf` lists inline anonymous object variants instead of `$ref` links,
the IR previously dropped the discriminator mapping and let every variant ref
collapse to the same `qualifyInlineModelName(field, parent)` — leaving emitters
with no signal to dispatch on. The companion variant-naming work (`c496332`)
already produced names like `ApiKeyOwner` / `UserApiKeyOwner`; this commit
wires them through the IR.
- `schemas.ts`: when `oneOf` variants share a const-valued discriminator
property, build the union's `discriminator: { property, mapping }` from
variant const values, reusing the same `nameVariantModel` logic that
named the extracted variant models. Covers three sources:
explicit `discriminator:` with mapping, explicit without mapping
(derive from inline variants), and synthetic detection on inline-only
unions (e.g. `ApiKeyCreatedData.owner`).
- `schemas.ts`: route each oneOf variant's TypeRef through the resolved
mapping so variants get distinct model refs (`ApiKeyOwner` for
`type: organization`, `UserApiKeyOwner` for `type: user`) instead of
collapsing to the parent-derived name.
- `extractInlineModelDeep`: extract every inline variant under nested
oneOf, not just the first. Without this, only `ApiKeyCreatedDataOwner`
was registered and `UserApiKeyCreatedDataOwner` was missing.
- `inline-models.ts`: same fix in the second-pass field inline extractor.
Co-Authored-By: Claude Opus 4.7 (1M context) <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.
Summary
Companion to #55 (variant naming). When a
oneOffield lists inline anonymous object variants instead of$reflinks — the shape that the api_keys spec rename in workos/openapi-spec@058a0a4 introduced forApiKey.ownerand the webhook event payloads — the IR previously dropped the discriminator mapping and let every variant TypeRef collapse to the samequalifyInlineModelName(field, parent). Emitters then had no signal to dispatch on, and the named extracted variants (e.g.UserApiKeyOwner) became orphans in the model registry.This commit threads the variant names produced by the existing
nameVariantModelinfrastructure through to the union TypeRef so emitters can render typed dispatch.schemas.ts: union construction now resolves a discriminator from three sources, in order: explicitdiscriminator:with explicit mapping (trust the spec), explicitdiscriminator:with no mapping (derive from variant const values viaderiveInlineVariantMapping), and synthetic detection on inline-onlyoneOf(detectConstPropertyDiscriminator, thenderiveConstNamingDiscriminator+deriveInlineVariantMapping).schemas.ts: each oneOf variant's TypeRef is routed through the resolved mapping, producing distinct model refs ({ kind: 'model', name: 'ApiKeyOwner' }fortype: organization,{ kind: 'model', name: 'UserApiKeyOwner' }fortype: user) instead of all collapsing to the parent-derived name.extractInlineModelDeepandextractInlineModelsFromProperties: extract every inline variant under aoneOf, not just the first. Without this, onlyApiKeyCreatedDataOwnerended up in the model registry andUserApiKeyCreatedDataOwnerwas missing — emitters would later fail to find the type referenced from the discriminator mapping.Test plan
npm test(all 1385 tests pass)parseSpec(open-api-spec.yaml)against the buggy058a0a4spec confirmsApiKey.owner,ApiKeyCreatedData.owner,ApiKeyRevokedData.ownercarry typed union variants and a populateddiscriminator.mapping.ApiKeyOwner/UserApiKeyOwner,ApiKeyCreatedDataOwner/UserApiKeyCreatedDataOwner,ApiKeyRevokedDataOwner/UserApiKeyRevokedDataOwner) now register inspec.models.🤖 Generated with Claude Code