Skip to content

feat(parser): populate inline oneOf discriminator mapping and extract every variant#57

Merged
gjtorikian merged 1 commit intomainfrom
feat/inline-oneof-discriminator-mapping
May 5, 2026
Merged

feat(parser): populate inline oneOf discriminator mapping and extract every variant#57
gjtorikian merged 1 commit intomainfrom
feat/inline-oneof-discriminator-mapping

Conversation

@gjtorikian
Copy link
Copy Markdown
Collaborator

Summary

Companion to #55 (variant naming). When a oneOf field lists inline anonymous object variants instead of $ref links — the shape that the api_keys spec rename in workos/openapi-spec@058a0a4 introduced for ApiKey.owner and the webhook event payloads — the IR previously dropped the discriminator mapping and let every variant TypeRef collapse to the same qualifyInlineModelName(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 nameVariantModel infrastructure through to the union TypeRef so emitters can render typed dispatch.

  • schemas.ts: union construction now resolves a discriminator from three sources, in order: explicit discriminator: with explicit mapping (trust the spec), explicit discriminator: with no mapping (derive from variant const values via deriveInlineVariantMapping), and synthetic detection on inline-only oneOf (detectConstPropertyDiscriminator, then deriveConstNamingDiscriminator + deriveInlineVariantMapping).
  • schemas.ts: each oneOf variant's TypeRef is routed through the resolved mapping, producing distinct model refs ({ kind: 'model', name: 'ApiKeyOwner' } for type: organization, { kind: 'model', name: 'UserApiKeyOwner' } for type: user) instead of all collapsing to the parent-derived name.
  • extractInlineModelDeep and extractInlineModelsFromProperties: extract every inline variant under a oneOf, not just the first. Without this, only ApiKeyCreatedDataOwner ended up in the model registry and UserApiKeyCreatedDataOwner was missing — emitters would later fail to find the type referenced from the discriminator mapping.

Test plan

  • npm test (all 1385 tests pass)
  • End-to-end probe via parseSpec(open-api-spec.yaml) against the buggy 058a0a4 spec confirms ApiKey.owner, ApiKeyCreatedData.owner, ApiKeyRevokedData.owner carry typed union variants and a populated discriminator.mapping.
  • Both organization and user variant models (ApiKeyOwner / UserApiKeyOwner, ApiKeyCreatedDataOwner / UserApiKeyCreatedDataOwner, ApiKeyRevokedDataOwner / UserApiKeyRevokedDataOwner) now register in spec.models.

🤖 Generated with Claude Code

… 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>
@gjtorikian gjtorikian merged commit 2d01eb8 into main May 5, 2026
5 checks passed
@gjtorikian gjtorikian deleted the feat/inline-oneof-discriminator-mapping branch May 5, 2026 04:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant