Skip to content

fix(sdk): ignore deepObject style for array query parameters#3818

Open
Eddie344 wants to merge 2 commits intohey-api:mainfrom
Eddie344:fix/array-query-param-deep-object-style
Open

fix(sdk): ignore deepObject style for array query parameters#3818
Eddie344 wants to merge 2 commits intohey-api:mainfrom
Eddie344:fix/array-query-param-deep-object-style

Conversation

@Eddie344
Copy link
Copy Markdown

@Eddie344 Eddie344 commented Apr 25, 2026

Summary

  • Root cause: In packages/openapi-ts/src/plugins/@hey-api/sdk/shared/operation.ts, when generating querySerializer overrides for query parameters of type array/tuple, the generator blindly forwarded whatever style was set on the parameter — including deepObject. However deepObject is only valid for object parameters per the OpenAPI spec, and the client SDK's ArrayStyle type is 'form' | 'spaceDelimited' | 'pipeDelimited'.
  • Result: an OpenAPI spec with an array query parameter carrying style: deepObject produced generated code like { array: { style: 'deepObject' } } that failed TypeScript compilation with Type '"deepObject"' is not assignable to type 'ArrayStyle | undefined'.
  • Fix: normalise the effective style to 'form' (the default for arrays) when a deepObject style is encountered on an array/tuple parameter. This suppresses the serialiser override entirely for that parameter, which is the correct behaviour — the default form serialiser is used.

Changes

File Change
packages/openapi-ts/src/plugins/@hey-api/sdk/shared/operation.ts Compute arrayStyle = deepObject ? 'form' : parameter.style before generating serialiser config
specs/3.1.x/parameter-array-deep-object.json New test spec: GET /foo with products array query param + style: deepObject
packages/openapi-ts-tests/main/test/3.1.x.test.ts New test case verifying deepObject on array param falls back to form
packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/parameter-array-deep-object/ Generated snapshots — sdk.gen.ts has no querySerializer override (correct)

Test plan

  • New test 'handles array query parameter with deepObject style (falls back to form)' passes
  • All 407 existing @test/openapi-ts tests still pass
  • pnpm typecheck exits clean across all 35 packages
  • Snapshot sdk.gen.ts contains no querySerializer (deepObject was silently normalised to the default form)

🤖 Generated with Claude Code

When a query parameter is typed as `array` but has `style: deepObject`
in the OpenAPI spec, the generator was emitting
`{ array: { style: 'deepObject' } }` in sdk.gen.ts. This caused a
TypeScript compile error because `ArrayStyle` is
`'form' | 'spaceDelimited' | 'pipeDelimited'` — `deepObject` is
only valid for object parameters.

The fix normalises the style to the default `'form'` for array/tuple
parameters that carry a `deepObject` style annotation, so no serialiser
override is emitted for those parameters.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@bolt-new-by-stackblitz
Copy link
Copy Markdown

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

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 25, 2026

Someone is attempting to deploy a commit to the Hey API Team on Vercel.

A member of the Team first needs to authorize it.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 25, 2026

⚠️ No Changeset found

Latest commit: 5f801ff

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 size:XS This PR changes 0-9 lines, ignoring generated files. bug 🔥 Broken or incorrect behavior. labels Apr 25, 2026
@pullfrog
Copy link
Copy Markdown
Contributor

pullfrog Bot commented Apr 25, 2026

TL;DR — When an OpenAPI spec declares style: "deepObject" on an array query parameter, the SDK plugin now normalises it to the default form style instead of emitting invalid TypeScript ('deepObject' is not assignable to ArrayStyle).

Key changes

  • Normalise deepObject to form for array/tuple query parameters — the operationStatements function in the SDK plugin now computes an arrayStyle that maps deepObjectform before deciding whether to emit a querySerializer override, preventing a compile error in generated code.
  • Add test spec, snapshot, and unit test for deepObject on array params — a new OpenAPI 3.1 spec, snapshot directory, and a createClient dry-run unit test verify that the generated SDK omits the serialiser override entirely (correct default behaviour).

Summary | 20 files | 2 commits | base: mainfix/array-query-param-deep-object-style


deepObject style normalisation for array parameters

Before: A spec with style: "deepObject" on an array query parameter generated { array: { style: 'deepObject' } } in the SDK, which failed TypeScript compilation because ArrayStyle only accepts 'form' | 'spaceDelimited' | 'pipeDelimited'.
After: The plugin detects deepObject on array/tuple parameters and treats it as form (the OpenAPI default for arrays). Since form with explode: true is already the default, no querySerializer override is emitted at all.

Per the OpenAPI specification, deepObject is only defined for object-typed parameters. When a spec incorrectly applies it to an array parameter, the safest behaviour is to fall back to the default serialisation — which is exactly what this fix does. The core logic change is two lines in operationStatements: a new arrayStyle variable that conditionally remaps the style, used in both the guard condition and the style property emission.

A new unit test in index.test.ts exercises the fix end-to-end via createClient({ dryRun: true }) with an inline spec containing an array parameter with style: 'deepObject', asserting that generation completes successfully.

Why not throw an error for the invalid style? Specs in the wild sometimes misuse deepObject on arrays — often because the parameter was originally an object and later changed to an array without updating the style. Silently falling back to the default is more resilient than breaking code generation, and matches how most HTTP clients would handle the parameter anyway.

operation.ts · index.test.ts · parameter-array-deep-object.json · sdk.gen.ts

Pullfrog  | View workflow run | via Pullfrog𝕏

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 25, 2026

Codecov Report

❌ Patch coverage is 66.66667% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 39.99%. Comparing base (8b02fcb) to head (5f801ff).

Files with missing lines Patch % Lines
...pi-ts/src/plugins/@hey-api/sdk/shared/operation.ts 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3818      +/-   ##
==========================================
+ Coverage   39.84%   39.99%   +0.15%     
==========================================
  Files         530      530              
  Lines       19475    19476       +1     
  Branches     5808     5803       -5     
==========================================
+ Hits         7759     7789      +30     
+ Misses       9485     9463      -22     
+ Partials     2231     2224       -7     
Flag Coverage Δ
unittests 39.99% <66.66%> (+0.15%) ⬆️

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
Contributor

@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.

The fix correctly normalizes deepObject to form for array/tuple query parameters before evaluating whether a serializer override is needed. This matches the OpenAPI spec (deepObject is only defined for object-typed parameters) and avoids emitting style: 'deepObject' which is not assignable to the client SDK's ArrayStyle type. The arrayStyle local variable is cleanly threaded through both the guard condition and the style emission, so both explode: true (skip override entirely) and explode: false (emit only { explode: false }) cases are handled correctly.

Task list (6/6 completed)
  • Read the PR description and diff overview
  • Review the core logic change in operation.ts
  • Review the test spec and test registration
  • Review generated snapshot files for correctness
  • Verify against OpenAPI 3.1 spec behavior for deepObject + arrays
  • Self-critique and submit review

Pullfrog  | View workflow run𝕏

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 25, 2026

Open in StackBlitz

@hey-api/codegen-core

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

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

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

@hey-api/nuxt

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

@hey-api/openapi-ts

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

@hey-api/shared

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

@hey-api/spec-types

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

@hey-api/types

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

@hey-api/vite-plugin

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

commit: 5f801ff

Adds a createClient unit test that exercises the deepObject→form
normalisation path in operation.ts, providing coverage for the
codecov/patch check.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Eddie344
Copy link
Copy Markdown
Author

@mrlubos I really need this fix, could you check it?

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:XS This PR changes 0-9 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant