Skip to content

fix(sdk): add 'deepObject' to ArrayStyle to fix compile error with array query parameters#3818

Open
Eddie344 wants to merge 1 commit into
hey-api:mainfrom
Eddie344:fix/array-query-param-deep-object-style
Open

fix(sdk): add 'deepObject' to ArrayStyle to fix compile error with array query parameters#3818
Eddie344 wants to merge 1 commit into
hey-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: The generator was faithfully emitting style: 'deepObject' in sdk.gen.ts for array/tuple query parameters that carry style: deepObject in the spec. However, ArrayStyle was defined as 'form' | 'spaceDelimited' | 'pipeDelimited''deepObject' was missing from the union — so the generated code failed TypeScript compilation with Type '"deepObject"' is not assignable to type 'ArrayStyle | undefined'.
  • Wrong fix (previous version of this PR): silently replace deepObject with form in the generator. This broke real-world serialisation — backends like Laravel/PHP that use style: deepObject on arrays expect products[0]=...&products[1]=... bracket notation, not plain form style.
  • Correct fix: add 'deepObject' to the ArrayStyle union in every client bundle. The generator already emits the right thing; the type just didn't cover it. Users who need bracket notation can pass a custom querySerializer.

Changes

File Change
packages/openapi-ts/src/plugins/@hey-api/client-core/bundle/pathSerializer.ts Add 'deepObject' to exported ArrayStyle (inherited by fetch/axios/ky/ofetch clients)
packages/openapi-ts/src/plugins/@hey-api/client-nuxt/bundle/types.ts Add 'deepObject' to local ArrayStyle
packages/openapi-ts/src/plugins/@hey-api/client-next/bundle/utils.ts Add 'deepObject' to local ArrayStyle
packages/openapi-ts/src/plugins/@hey-api/client-angular/bundle/utils.ts Add 'deepObject' to local ArrayStyle
packages/custom-client/src/core/pathSerializer.ts + utils.ts Add 'deepObject' to ArrayStyle
packages/openapi-ts/src/plugins/@hey-api/sdk/shared/operation.ts Reverted — generator now preserves style: 'deepObject' as-is
specs/3.1.x/parameter-array-deep-object.json Test spec: GET /foo with products array param + style: deepObject
packages/openapi-ts-tests/main/test/3.1.x.test.ts Test description updated; snapshot sdk.gen.ts now asserts style: 'deepObject' is present
packages/openapi-ts-tests/main/test/__snapshots__/… 291 snapshots updated — pathSerializer.gen.ts everywhere reflects the wider ArrayStyle type

Test plan

  • New test 'handles array query parameter with deepObject style' passes and asserts style: 'deepObject' is emitted in sdk.gen.ts
  • All 2089 tests across all packages pass
  • pnpm typecheck exits clean

Closes #3868

🤖 Generated with Claude Code

@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: 1d69355

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

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 39.74%. Comparing base (66720d9) to head (3b0134f).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3818      +/-   ##
==========================================
+ Coverage   39.58%   39.74%   +0.16%     
==========================================
  Files         532      532              
  Lines       19581    19581              
  Branches     5835     5829       -6     
==========================================
+ Hits         7751     7783      +32     
+ Misses       9582     9557      -25     
+ Partials     2248     2241       -7     
Flag Coverage Δ
unittests 39.74% <ø> (+0.16%) ⬆️

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: 3b0134f

@Eddie344
Copy link
Copy Markdown
Author

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

@Eddie344
Copy link
Copy Markdown
Author

Eddie344 commented May 7, 2026

@mrlubos

@Eddie344 Eddie344 force-pushed the fix/array-query-param-deep-object-style branch from 5f801ff to 9876b05 Compare May 11, 2026 14:23
@Eddie344 Eddie344 changed the title fix(sdk): ignore deepObject style for array query parameters fix(sdk): add 'deepObject' to ArrayStyle to fix compile error with array query parameters May 11, 2026
@Eddie344 Eddie344 force-pushed the fix/array-query-param-deep-object-style branch 4 times, most recently from 46cdd28 to da11892 Compare May 11, 2026 14:48
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. and removed size:XS This PR changes 0-9 lines, ignoring generated files. labels May 11, 2026
@Eddie344 Eddie344 force-pushed the fix/array-query-param-deep-object-style branch from da11892 to 1d69355 Compare May 11, 2026 15:11
…back to 'form'

When an array query parameter has `style: deepObject` the generator was
emitting `style: 'deepObject'` in sdk.gen.ts, but `ArrayStyle` in every
client bundle did not include that value, causing a TypeScript compile
error in the generated output.

The correct fix is to add `'deepObject'` to the `ArrayStyle` union in all
client bundles (client-core, client-nuxt, client-next, client-angular,
custom-client). The generator now faithfully preserves the style from the
spec. Users who need bracket notation serialisation (products[0]=...) can
supply a custom `querySerializer`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Eddie344 Eddie344 force-pushed the fix/array-query-param-deep-object-style branch from 1d69355 to 3b0134f Compare May 11, 2026 15:18
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:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

'deepObject' is missing from ArrayStyle in all client bundles

1 participant