Skip to content

Fix/spec types#3715

Merged
mrlubos merged 4 commits intomainfrom
fix/spec-types
Apr 6, 2026
Merged

Fix/spec types#3715
mrlubos merged 4 commits intomainfrom
fix/spec-types

Conversation

@mrlubos
Copy link
Copy Markdown
Member

@mrlubos mrlubos commented Apr 6, 2026

Closes #3716

@bolt-new-by-stackblitz
Copy link
Copy Markdown

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 6, 2026

🦋 Changeset detected

Latest commit: b4a8afe

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@hey-api/spec-types Minor
@hey-api/openapi-python Patch
@hey-api/openapi-ts Patch
@hey-api/shared Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 6, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hey-api-docs Ready Ready Preview, Comment Apr 6, 2026 11:41pm

Request Review

@pullfrog
Copy link
Copy Markdown

pullfrog bot commented Apr 6, 2026

TL;DR — Cleans up @hey-api/spec-types by switching all arrays to mutable Array, separating OpenAPI extensions from base JSON Schema types, introducing generic self-referential typing for JSON Schema documents, and migrating the build from tsc to tsdown.

Key changes

  • Switch all spec arrays from ReadonlyArray to Array — Replaces every ReadonlyArray<T> property across all OpenAPI and JSON Schema type definitions with mutable Array<T>, allowing consumers to modify parsed spec objects.
  • Make JSON Schema BaseDocument generic with TDocument — Introduces a BaseDocument<TDocument> generic type and parameterized ArrayKeywords<TDocument> / ObjectKeywords<TDocument>, enabling self-referential typing when composed at the OpenAPI layer (e.g. SchemaObject extends JSONSchemaDraft2020_12<SchemaObject>).
  • Move extension types from JSON Schema to the OpenAPI layer — Removes EnumExtensions, OpenAPIV3_1SchemaExtensions, and OpenAPIExtensions from JSON Schema Document base types and applies them via intersection at the SchemaObject level instead.
  • Rename OpenAPIExtensions to SpecExtensions and split extension files — Breaks the monolithic extensions file into code-samples.ts, enum.ts, and spec.ts with one concern per file.
  • Tighten Swagger 2.0 swagger field to literal '2.0' — Narrows the type from string to the spec-mandated literal.
  • Migrate build tooling from tsc to tsdown — Adds tsdown.config.ts and turbo.json, switches type output to .d.mts, and aligns this package with the rest of the monorepo's build pipeline.
  • Update IRSchemaObject to pick example from OpenAPIV3_1.SchemaObject — Moves the example property pick to the OpenAPI-level SchemaObject since it was removed from the JSON Schema Document base.

Summary | 18 files | 4 commits | base: mainfix/spec-types


Mutable arrays across all spec types

Before: All array-typed properties (allOf, anyOf, oneOf, enum, required, parameters, servers, tags, security, etc.) used ReadonlyArray<T>, preventing mutation of parsed spec objects.
After: All properties use Array<T>, allowing standard array operations like push, splice, and direct index assignment.

This is the dominant mechanical change across the PR, touching every spec version (v2, v3, v3.1) and both JSON Schema drafts (draft-4, draft-2020-12). The changesets indicate a patch-level bump for @hey-api/spec-types.

v2/spec.ts · v3/spec.ts · v3-1/spec.ts · draft-2020-12/spec.ts


Generic self-referential BaseDocument for JSON Schema

Before: Document directly extended ArrayKeywords, ObjectKeywords, etc. with hardcoded Document self-references, and was also extended by OpenAPI-specific extensions like EnumExtensions and OpenAPIExtensions.
After: BaseDocument<TDocument> is a generic interface, with ArrayKeywords<TDocument> and ObjectKeywords<TDocument> propagating the type parameter. A concrete Document = BaseDocument<Document> alias preserves backwards compatibility, while v3.1 composes SchemaObject extends JSONSchemaDraft2020_12<SchemaObject> for proper recursive typing.

This architectural change means JSON Schema keyword types like allOf, properties, items, etc. resolve to the actual OpenAPI SchemaObject (with extensions) rather than the bare Document when used from v3.1.

How does the generic flow through to v3.1 SchemaObject?

BaseDocument<TDocument> passes TDocument into ArrayKeywords<TDocument> and ObjectKeywords<TDocument>. When v3.1 declares SchemaObject extends JSONSchemaDraft2020_12<SchemaObject>, all recursive positions (allOf, properties, additionalProperties, items, etc.) resolve to SchemaObject rather than bare Document. This means extension properties like x-enum-descriptions and nullable are available at every nesting level without manual casting.

draft-2020-12/spec.ts · v3-1/spec.ts


Extension types separated from JSON Schema

Before: JSON Schema Document interfaces directly extended EnumExtensions, OpenAPIV3_1SchemaExtensions, and OpenAPIExtensions, coupling spec-specific concerns to the generic schema layer.
After: JSON Schema Document types are pure schema definitions; OpenAPI extensions are composed at the SchemaObject level.

Spec version Before After
v3.1 SchemaObject JSONSchemaDraft2020_12 & OpenAPIExtensions JSONSchemaDraft2020_12<SchemaObject> & OpenAPIV3_1SchemaExtensions & SpecExtensions & EnumExtensions
v3 SchemaObject extends EnumExtensions, OpenAPIExtensions extends EnumExtensions, SpecExtensions
v2 SchemaObject extends JSONSchemaDraft4, OpenAPIV2NullableExtensions extends JSONSchemaDraft4, EnumExtensions, OpenAPIV2NullableExtensions
draft-2020-12 Document extends ..., EnumExtensions, OpenAPIV3_1SchemaExtensions, OpenAPIExtensions extends ArrayKeywords, NumberKeywords, ObjectKeywords, StringKeywords
draft-4 Document extends EnumExtensions No extension inheritance

draft-2020-12/spec.ts · draft-4/spec.ts · v3-1/spec.ts · v2/spec.ts


Rename and split extension files

Before: All extension types (CodeSampleObject, LinguistLanguages, EnumExtensions, OpenAPIExtensions) lived in a single file, with OpenAPIExtensions as the name for the generic [x-${string}]: unknown index signature.
After: Extensions are split into code-samples.ts, enum.ts, and spec.ts. OpenAPIExtensions is renamed to SpecExtensions to reflect its broader applicability.

code-samples.ts · enum.ts · spec.ts · index.ts


Build migration to tsdown

Before: Build used tsc --build with .d.ts output and no Turbo configuration.
After: Build uses tsdown with ESM-only output, sourcemaps, .d.mts type declarations, and a dedicated turbo.json for task orchestration.

This aligns @hey-api/spec-types with the build tooling used by the rest of the monorepo. A tsconfig.json project reference to @hey-api/types is also added.

package.json · tsdown.config.ts · turbo.json · tsconfig.json

Pullfrog  | View workflow run | Triggered by Pullfrog𝕏

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 6, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 40.24%. Comparing base (05207e0) to head (b4a8afe).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3715   +/-   ##
=======================================
  Coverage   40.24%   40.24%           
=======================================
  Files         520      520           
  Lines       19302    19302           
  Branches     5726     5720    -6     
=======================================
  Hits         7769     7769           
  Misses       9337     9337           
  Partials     2196     2196           
Flag Coverage Δ
unittests 40.24% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown

@pullfrog pullfrog bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

OpenAPIExtensions was renamed to SpecExtensions and its export removed, but packages/shared/src/ir/types.ts still imports OpenAPIExtensions from @hey-api/spec-types (lines 3, 25, 49, 135). This will break the shared package build.

Additionally, removing OpenAPIV3_1SchemaExtensions from JSONSchemaDraft2020_12.Document means that Pick<JSONSchemaDraft2020_12.Document, 'example'> in IRSchemaObject (line 133 of ir/types.ts) becomes invalid — example is no longer a key of Document.

The type-level restructuring (splitting extensions/openapi into extensions/code-samples, extensions/enum, extensions/spec, and moving EnumExtensions/OpenAPIV3_1SchemaExtensions from Document to SchemaObject) makes sense — JSON Schema Document shouldn't carry OpenAPI-specific extensions. The ReadonlyArrayArray change and stricter swagger: '2.0' are both good fixes. The tsctsdown build migration aligns with the rest of the monorepo.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run𝕏

@mrlubos mrlubos marked this pull request as ready for review April 6, 2026 23:42
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Apr 6, 2026
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 6, 2026

Open in StackBlitz

@hey-api/codegen-core

npm i https://pkg.pr.new/@hey-api/codegen-core@3715

@hey-api/json-schema-ref-parser

npm i https://pkg.pr.new/@hey-api/json-schema-ref-parser@3715

@hey-api/nuxt

npm i https://pkg.pr.new/@hey-api/nuxt@3715

@hey-api/openapi-ts

npm i https://pkg.pr.new/@hey-api/openapi-ts@3715

@hey-api/shared

npm i https://pkg.pr.new/@hey-api/shared@3715

@hey-api/spec-types

npm i https://pkg.pr.new/@hey-api/spec-types@3715

@hey-api/types

npm i https://pkg.pr.new/@hey-api/types@3715

@hey-api/vite-plugin

npm i https://pkg.pr.new/@hey-api/vite-plugin@3715

commit: b4a8afe

Copy link
Copy Markdown

@pullfrog pullfrog bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed — no issues found.

Pullfrog  | View workflow run𝕏

@mrlubos mrlubos merged commit 9f00629 into main Apr 6, 2026
12 checks passed
@mrlubos mrlubos deleted the fix/spec-types branch April 6, 2026 23:49
@hey-api hey-api bot mentioned this pull request Apr 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@hey-api/spec-types is not compatible with moduleResolution:"nodenext"

1 participant