fix: validate generated OpenAPI spec against OAS 3.1 - #1277
Open
grdsdev wants to merge 8 commits into
Open
Conversation
Coverage Report for CI Build 30482055678Coverage increased (+0.09%) to 80.408%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats💛 - Coveralls |
grdsdev
marked this pull request as ready for review
July 28, 2026 20:59
ferhatelmas
reviewed
Jul 29, 2026
ferhatelmas
reviewed
Jul 29, 2026
ferhatelmas
reviewed
Jul 29, 2026
3.2 is a strict superset of 3.1 for our purposes; validated the generated docs against the official OAS 3.2 meta-schema.
Builds both apps, fetches their /documentation/json, and validates against the official OAS 3.2 meta-schema (@hyperjump/json-schema).
schema-base recursively validates Schema Objects against the OAS 3.2 dialect; schema alone only checks them as opaque objects.
OpenAPI 3.2 Schema Objects are pure JSON Schema 2020-12, which has no nullable keyword — it's silently ignored, so these fields were documented as non-nullable despite AJV still accepting null at runtime. Use type: [X, 'null'] instead.
Most codegen tools don't support 3.2 yet; 3.1 already gives us JSON Schema 2020-12 Schema Objects, which is all these route schemas need.
The official OAS 3.1 dialect permits unknown keywords in Schema Objects, so a regressed `nullable: true` wouldn't fail validation. Add a strict dialect overlay (unevaluatedProperties: false) and run it against every embedded Schema Object found in the generated spec.
grdsdev
force-pushed
the
feat/openapi-3-2-0
branch
from
July 29, 2026 18:54
1f665a7 to
f514abb
Compare
ferhatelmas
reviewed
Jul 30, 2026
|
|
||
| try { | ||
| const spec = app.swagger() as { openapi: string } | ||
| expect(spec.openapi).toBe('3.1.0') |
Member
There was a problem hiding this comment.
expect(JSON.stringify(spec)).not.toContain('"nullable"')
can we add this or similar that it doesn't regress?
ferhatelmas
reviewed
Jul 30, 2026
| await app.ready() | ||
|
|
||
| const spec = app.swagger() as { openapi: string } | ||
| expect(spec.openapi).toBe('3.1.0') |
ferhatelmas
reviewed
Jul 30, 2026
Comment on lines
+71
to
+74
| if (parentKey === 'schema') { | ||
| out.push({ path, schema: node }) | ||
| return | ||
| } |
Member
There was a problem hiding this comment.
Is this going to handle a mere field named schema?
we don't have at the moment but I guess it could be useful for iceberg at some point
ferhatelmas
reviewed
Jul 30, 2026
| type: ['string', 'null'], | ||
| pattern: '^[0-9]+(?:\\.[0-9]+)?(?:[gG][bB]|[mM][bB]|[kK][bB]|[bB])$', | ||
| examples: ['100MB'], | ||
| nullable: true, |
Member
There was a problem hiding this comment.
seems one is left behind
storage/src/http/finite.test.ts
Line 52 in 47048ef
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
3.1.0(up from3.0.x) insrc/app.ts/src/admin-app.ts, since 3.1's Schema Object is a full JSON Schema 2020-12 superset — needed because route schemas usetype: [X, 'null']instead of the OAS 3.0nullable: trueidiom. (Originally targeted 3.2.0; downgraded to 3.1.0 since most codegen tools don't support 3.2 yet — 3.1 already covers what we need.)nullable: trueidiom to standard JSON Schematype: [X, 'null'].src/scripts/validate-openapi.ts(npm run docs:validate), which validates both generated specs against the official OAS 3.1 meta-schema (@hyperjump/json-schema/openapi-3-1), including embedded Schema Objects.unevaluatedProperties: falselayered on the official OAS 3.1 dialect) that walks every embedded Schema Object and rejects unknown keywords — catches a regression back to the OAS 3.0nullableidiom, which the official dialect alone permits silently.docs:validateinto CI (.github/workflows/ci.yml), withVECTOR_ENABLED/ICEBERG_ENABLEDset so those routes' schemas are included.Test plan
npm run test:unitpasses (public/admin app suites green).npm run build/tsc -noEmitclean.npm run docs:validatepasses against the current generated specs.nullable: trueidiom locally, confirmeddocs:validatefailed with the exact offending path, then reverted the test change.