Skip to content

fix(zod): generate z.union([z.instanceof(Blob), z.instanceof(File)]) for binary format#3627

Open
j-ibarra wants to merge 8 commits intohey-api:mainfrom
j-ibarra:fix/zod-binary-format-blob-file
Open

fix(zod): generate z.union([z.instanceof(Blob), z.instanceof(File)]) for binary format#3627
j-ibarra wants to merge 8 commits intohey-api:mainfrom
j-ibarra:fix/zod-binary-format-blob-file

Conversation

@j-ibarra
Copy link
Copy Markdown
Contributor

@j-ibarra j-ibarra commented Mar 19, 2026

Summary

Fields with format: 'binary' (produced e.g. by contentMediaType: 'application/octet-stream' in OpenAPI 3.1, as emitted by FastAPI ≥ 0.129.1) were generating z.string() in all three Zod plugin variants (v3, v4, mini) because the formatNode switch had no 'binary' case.

This PR adds the missing case to produce z.union([z.instanceof(Blob), z.instanceof(File)]), which mirrors what the TypeScript plugin already generates (Blob | File) and correctly validates file upload fields at runtime.

Before:

publicKey: z.string()

After:

publicKey: z.union([z.instanceof(Blob), z.instanceof(File)])

Changes

  • constants.ts — add instanceof identifier
  • v3/toAst/string.ts — add 'binary' case to formatNode
  • v4/toAst/string.ts — add 'binary' case to formatNode
  • mini/toAst/string.ts — add 'binary' case to formatNode

Related issues

Test plan

  • All existing tests pass across @test/openapi-ts, @test/openapi-ts-zod-v3, and @test/openapi-ts-zod-v4
  • Snapshot tests added for content-binary.json + zod and content-media-type.yaml + zod
  • All zod snapshots (v3, v4, mini × OpenAPI 2.0.x, 3.0.x, 3.1.x) updated to reflect z.instanceof(Blob/File) for binary fields
  • Builds clean for all three Zod plugin variants

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

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

@pullfrog
Copy link
Copy Markdown

pullfrog bot commented Mar 19, 2026

Error

agent completed without reporting progress

Pullfrog  | Rerun failed job ➔View workflow run | Triggered by Pullfrogpullfrog.com𝕏

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 19, 2026

@j-ibarra is attempting to deploy a commit to the Hey API Team on Vercel.

A member of the Team first needs to authorize it.

@dosubot dosubot bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Mar 19, 2026
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 19, 2026

⚠️ No Changeset found

Latest commit: d934c8a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@dosubot dosubot bot added bug 🔥 Broken or incorrect behavior. size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels Mar 19, 2026
…for binary format

Fields with format: 'binary' (e.g. from contentMediaType: 'application/octet-stream'
in OpenAPI 3.1) were generating z.string() in all three Zod plugin variants (v3, v4, mini).

This mirrors what the TypeScript plugin already produces (Blob | File) and correctly
validates file upload fields at runtime.

Fixes hey-api#3408
- Add two new test scenarios to 3.1.x.test.ts:
  - content-binary.json + zod: verifies z.instanceof(Blob/File) for format: binary
  - content-media-type.yaml + zod: verifies z.instanceof(Blob/File) for contentMediaType

- Add content-media-type.yaml spec (backport from merged PR hey-api#3431)
- Apply parser fix for contentMediaType → binary format inference (backport from hey-api#3431)
- Update string-with-format zod snapshot to reflect corrected binary output

Snapshots confirm:
  z.union([z.instanceof(Blob), z.instanceof(File)]) for all binary fields
@j-ibarra j-ibarra force-pushed the fix/zod-binary-format-blob-file branch from 16be560 to 06fe0ff Compare March 19, 2026 04:15
j-ibarra and others added 2 commits March 19, 2026 11:38
Regenerate all zod snapshots to reflect binary format fields now
producing z.instanceof(Blob/File) and align new test snapshots with
current v4-style output.
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 19, 2026

Open in StackBlitz

@hey-api/codegen-core

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

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

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

@hey-api/nuxt

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

@hey-api/openapi-ts

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

@hey-api/shared

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

@hey-api/spec-types

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

@hey-api/types

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

@hey-api/vite-plugin

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

commit: d934c8a

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 19, 2026

Codecov Report

❌ Patch coverage is 0% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 38.97%. Comparing base (46b7d3a) to head (d934c8a).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
...ages/openapi-ts/src/plugins/zod/v3/toAst/string.ts 0.00% 4 Missing ⚠️
...es/openapi-ts/src/plugins/zod/mini/toAst/string.ts 0.00% 2 Missing ⚠️
...ages/openapi-ts/src/plugins/zod/v4/toAst/string.ts 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3627      +/-   ##
==========================================
- Coverage   38.98%   38.97%   -0.02%     
==========================================
  Files         518      518              
  Lines       18968    18975       +7     
  Branches     5606     5609       +3     
==========================================
  Hits         7395     7395              
- Misses       9367     9374       +7     
  Partials     2206     2206              
Flag Coverage Δ
unittests 38.97% <0.00%> (-0.02%) ⬇️

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug 🔥 Broken or incorrect behavior. size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ZOD] Incorrect schema creation for binary files

1 participant