fix(query): pass operationId and operationName to queryOptions mutator - #3427
Conversation
The `mutationOptions` mutator has received `{ operationId, operationName }`
as its third argument since orval-labs#1974, but the symmetric `queryOptions` mutator
was left with only `{ url }`. That asymmetry made it impossible to write
`queryOptions` overrides that branch on operation identity (e.g. attach
per-operation metadata or invalidate by `operationId`).
Extend the third argument of `queryOptions` mutator calls from `{ url }`
to `{ url, operationId, operationName }`. The change is additive —
mutators that today read `arg3.url` keep working unchanged. Both call
sites are updated: the main query options builder and the
`applyQueryOptionsMutator` helper that backs `invalidate`/`set`/`get`.
The 2nd-arg asymmetry between `queryOptions` (`{ queryProperties }`) and
`mutationOptions` (`{ url }`) is shipped behaviour and is left alone.
Closes orval-labs#3153
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughThreads operation identity into React Query codegen: generator accepts operationId, invokes non-hook queryOptions mutators with { url, operationId, operationName }, updates query-key rewriting, adds docs, test config/mutator helper, generated snapshots, and a regression test validating the change. ChangesQuery Options Operation Identity Enhancement
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds support for passing operation identity into React Query queryOptions mutators, enabling per-operation customization (e.g., tagging/invalidation) and preventing a regression where only url was available.
Changes:
- Extend React Query query-options mutator third argument to include
{ url, operationId, operationName }. - Add a regression test and new generated snapshot fixture for the feature.
- Document the updated mutator third-parameter contract.
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/mutators/custom-query-options-with-operation.ts | Adds a test mutator that prefixes query keys with operation identity fields. |
| tests/configs/react-query.config.ts | Adds a new test generation target wiring the custom queryOptions mutator. |
| tests/api-generation.spec.ts | Adds a regression test asserting operation identity is passed at both query-options mutator call sites. |
| tests/snapshots/react-query/custom-query-options-with-operation/endpoints.ts | New snapshot validating generated code now passes operation identity into the mutator. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/pets.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/petWithTag.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/petCountry.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/petCallingCode.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/pet.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/listPetsSort.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/listPetsParams.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/labradoodleBreed.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/labradoodle.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/index.ts | New generated model barrel snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/error.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/dogType.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/dog.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/dachshundBreed.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/dachshund.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/createPetsSort.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/createPetsParams.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/createPetsBody.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/catType.ts | New generated model snapshot fixture for the added test target. |
| tests/snapshots/react-query/custom-query-options-with-operation/model/cat.ts | New generated model snapshot fixture for the added test target. |
| packages/query/src/query-generator.ts | Updates query codegen to pass operationId/operationName into third-arg mutators at both call sites. |
| docs/content/docs/reference/configuration/output.mdx | Documents the third-arg mutator payload as including operation identity. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| }${ | ||
| queryOptionsMutator.hasThirdArg ? `, { url: \`${route}\` }` : '' | ||
| queryOptionsMutator.hasThirdArg | ||
| ? `, { url: \`${route}\`, operationId: '${operationId}', operationName: '${operationName}' }` |
There was a problem hiding this comment.
Out of scope for this PR. The same single-quote interpolation pattern is already in use for mutationOptions (see packages/query/src/mutation-generator.ts:471, introduced in #1974):
mutationOptionsMutator.hasThirdArg
? `, { operationId: '${operationId}', operationName: '${operationName}' }`
: ''If operationId / operationName need safe escaping, both call sites should switch together (and probably url too — that one also predates this PR). Doing it on the query side only here would diverge the two mutator types' output formats. Happy to file a follow-up issue for repo-wide operation-id encoding once this lands.
| When a `queryOptions` or `mutationOptions` mutator declares a third | ||
| parameter, orval passes `{ url, operationId, operationName }` so the mutator | ||
| can branch on operation identity (for example, to attach per-operation | ||
| metadata or invalidate by `operationId`). |
There was a problem hiding this comment.
Good catch — fixed in 4c1c27e. The docs now describe the two shapes separately:
queryOptions→{ url, operationId, operationName }mutationOptions→{ operationId, operationName }(url is in the 2nd arg)
| const operations: Array<{ operationId: string; url: string }> = [ | ||
| { operationId: 'listPets', url: '/pets' }, | ||
| { operationId: 'showPetById', url: '/pets/${petId}' }, | ||
| { operationId: 'showPetWithOwner', url: '/pets/${petId}/owner' }, | ||
| { operationId: 'healthCheck', url: '/health' }, | ||
| ]; | ||
|
|
||
| const occurrencesOf = (needle: string) => content.split(needle).length - 1; | ||
|
|
||
| for (const { operationId, url } of operations) { | ||
| expect(content).toContain(`url: \`${url}\``); | ||
| // Two occurrences each: one from the main builder, one from the helper. | ||
| expect(occurrencesOf(`operationId: '${operationId}'`)).toBe(2); | ||
| expect(occurrencesOf(`operationName: '${operationId}'`)).toBe(2); |
There was a problem hiding this comment.
Fixed in 4c1c27e — operations table now carries operationName as an explicit field rather than reusing operationId, and the loop asserts each independently.
test(query): decouple operationName from operationId in orval-labs#3153 regression
Summary
Closes #3153.
mutationOptionsmutators have received{ operationId, operationName }as their third argument since #1974, but the symmetricqueryOptionsmutator was left with only{ url }. That asymmetry makes it impossible to writequeryOptionsoverrides that branch on operation identity (the very thing the issue reporter is trying to do).This PR extends the third argument of
queryOptionsmutator calls from{ url }to{ url, operationId, operationName }. The change is additive — mutators that today readarg3.urlkeep working unchanged, so this ships as afix(query)rather than a breaking change.What changed
packages/query/src/query-generator.ts— threadedoperationIdintogenerateQueryImplementation(it was already in scope atgenerateQueryHook) and extended the third arg at both call sites:applyQueryOptionsMutatorhelper that backsinvalidate/set/get(the helper's call shape must stay in lockstep with the main builder's, otherwise the augmentedqueryKeyis silently recomputed against a stale arg shape)output.mdxdocumenting the new third-arg shapeWhy not match
mutationOptionsexactlymutationOptionspasses{ url }as arg 2 and{ operationId, operationName }as arg 3.queryOptionspasses{ queryProperties }as arg 2 — that 2nd-arg asymmetry is shipped behavior and changing it would be breaking. Combiningurl+ operation info into arg 3 letsqueryOptionsmutators access everything they need without touching the 2nd arg's shape.Tests
Added a focused regression test in
tests/api-generation.spec.ts(react-query issue-3153 ...) backed by a new fixture projectpetstoreCustomQueryOptionsWithOperationand a new 3-arg test mutatortests/mutators/custom-query-options-with-operation.ts. The mutator body referencesoperation.operationId, so a regression that drops the field would also fail TypeScript compilation underbun run --filter orval-tests build.The existing
useInvalidateWithQueryOptionsMutatorfixture (1-arg mutator) is left untouched so that thehasThirdArg: falsecode path keeps regression coverage.Counting occurrences (2 per operation) verifies both call sites emit the new third arg — catching the "fixed one site, forgot the other" regression without resorting to multi-line whitespace-flexible regex.
Test plan
bun run build --forcebun run test(all 12 packages green, 1787+ tests in core alone)bun run test:snapshots(4155 tests; only the new fixture's snapshot was added — no existing snapshot changed)bun run typecheckbun run lintbun run format:checkbun run --filter orval-tests build(typecheck-generated for all 15 clients + verify-mock-generated)Summary by CodeRabbit
New Features
Documentation
Tests