Skip to content

fix(frontend): keep the API client's shapes under orval 8 and regenerate it - #232

Merged
bordumb merged 3 commits into
mainfrom
claude/orval-8-client
Sep 29, 2026
Merged

bordumb merged 3 commits into
mainfrom
claude/orval-8-client

Conversation

@bordumb

@bordumb bordumb commented Sep 28, 2026

Copy link
Copy Markdown
Owner

Why

#221 bumped orval from 6.31 to 8 without regenerating the client. Run on the committed spec, orval 8 rewrote 293 files and broke the client's shape:

  • every GET hook became a useMutation, and every POST/PUT/DELETE a useQuery
  • request functions switched to the fetch client's (url, init) call, which customInstance doesn't take
  • imports gained a .ts suffix
  • models lost their property order and named nullable types

What

orval.config.ts: orval 8, configured for the orval 6 shapes (kept orval 8 rather than pinning back to 6):

  • Drop override.query.useQuery/useMutation. In @orval/query 8 they apply to every verb, so a GET with both became a mutation. Unset, GETs get query hooks and other verbs mutation hooks, as under orval 6.
  • httpClient: 'axios', because customInstance takes one request config object. Nothing imports axios.
  • propertySortOrder: 'Alphabetical' and aliasCombinedTypes: true, as orval 6 did.
  • An inline tsconfig without allowImportingTsExtensions, so imports stay extensionless.

The client, regenerated once from the committed spec (not a fresh export):

  • 0 exports removed or renamed, and no query/mutation flips (76 query hooks, 90 mutation hooks). All 76 query keys are identical.
  • Changes are additive, the standard orval 8 React Query v5 output:
    • overloads with DataTag keys and an optional queryClient argument
    • get*MutationKey helpers and named *MutationVariables types
    • an optional signal on non-GET requests
  • The model files' headers drop the orval version ("Generated by orval 🍺"), so future orval upgrades won't touch every file.
  • generated/index.ts is the barrel orval 8 always writes. It's committed so regeneration doesn't leave an untracked file.
  • One behaviour change: path-param queries used to be guarded by !!id; now they run when the id isn't null or undefined. Every caller passes a loaded id.

just generate-client works again. Since #230 the schema export failed without JWT_SECRET_KEY, so it now uses a throwaway key, as the dev recipes do.

Why not pin orval 6

Orval 6.31 reproduces the committed client byte for byte, so pinning would be an empty diff. But orval 8 produces every shape consumers use, and pinning would undo #221 and keep an old major.

Checks

  • pnpm orval on the committed spec, run twice: the second run changes 0 files.
  • pnpm typecheck, pnpm lint: pass.
  • pnpm test: 28 files, 126 tests pass.
  • pnpm build: passes.
  • just generate-client with no JWT_SECRET_KEY set: exits 0. The fresh export drifts from the committed spec (+3.7k/-1.9k), and the client built from it compiles and passes tests. That drift is not part of this PR.

Left for later

  • 125 stale generated files that the committed spec no longer produces still carry orval 6 headers (for example the audit, feedback, scim and sso tags). output.clean: true would remove them. That's a separate decision.
  • The dbt-manifest upload sends FormData, but customInstance JSON-encodes bodies. This is a pre-existing bug, and no UI calls it today.

🤖 Generated with Claude Code

bordumb and others added 3 commits September 28, 2026 23:20
#221 bumped orval from 6.31 to 8 without regenerating the client. Run
on the committed spec, orval 8 rewrote 293 files: every GET hook became
a useMutation and every POST/PUT/DELETE hook a useQuery, request
functions switched to the fetch client's (url, init) call that
customInstance does not accept, imports gained a ".ts" suffix, and
models lost their property order and named nullable types.

Orval 8 applies override.query.useQuery and useMutation to every verb,
and a GET with both becomes a mutation. Leave them unset: GETs then get
query hooks and the other verbs mutation hooks, as under orval 6.

Set the orval 6 behaviour that orval 8 changed:
- httpClient axios: customInstance takes one request config object
- propertySortOrder Alphabetical: model properties keep their order
- aliasCombinedTypes: nullable properties keep their named types
- a tsconfig without allowImportingTsExtensions, so imports stay
  extensionless

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Claude <noreply@anthropic.com>
Output of `pnpm orval` on the committed openapi.json with the orval 8
config from the previous commit. A second run changes nothing.

The hooks consumers use keep their shape. The 28 regenerated tag files
remove or rename no export; their 76 GET hooks stay useQuery and their
90 other hooks useMutation; all 76 query keys are unchanged. Model
types match except for JSDoc and three tighter types
(InvestigationBrief.version is the literal 1, an upload is
Blob | File, UpdateUserRequestRole also exports its values).

Orval 8's React Query v5 output makes most of the size:
- query hooks gain initialData overloads, a DataTag query key and an
  optional queryClient argument
- mutations gain a mutation key and a named variables type
- non-GET request functions take an optional AbortSignal
- path-param queries are enabled when the param is not null or
  undefined (it was truthy), so an empty string now runs the query;
  no caller passes one
- headers drop the orval version, so upgrades stop touching every file

Orval 8 also writes generated/index.ts, which re-exports every tag.
Nothing imports it; it is kept so a regeneration leaves no untracked
file. Turning it off (indexFiles: false) would also stop orval
maintaining model/index.ts.

The 125 files the committed spec no longer produces (the audit,
feedback, runs, scim, settings and sso tags and 119 models) are left
alone and keep their orval 6 header.

The detect-secrets hook moved the baseline entry for configFieldType.ts
up a line, since orval 8 drops an eslint-disable comment there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Claude <noreply@anthropic.com>
Since #230 the app refuses to build without a JWT signing key of 32+
bytes, so export_openapi.py, which imports it, fails before orval runs.
The schema doesn't depend on the key: use a throwaway one when none is
set, as the dev recipes do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
dataing Ready Ready Preview Sep 28, 2026 10:51pm UTC
dataing-app Ready Ready Preview Sep 28, 2026 10:51pm UTC
dataing-docs Ready Ready Preview Sep 28, 2026 10:51pm UTC

@bordumb
bordumb merged commit 5831074 into main Sep 29, 2026
7 checks passed
github-actions Bot pushed a commit that referenced this pull request Sep 29, 2026
## [1.25.5](v1.25.4...v1.25.5) (2026-09-29)

### Bug Fixes

* **frontend:** keep the API client's shapes under orval 8 and regenerate it ([#232](#232)) ([5831074](5831074)), closes [#221](#221) [#230](#230)

This branch was successfully deployed

3 active deployments
Preview – dataing-docs — 9ddd9327 Deployed Sep 28, 2026 by vercel[bot]
Preview – dataing-app — 9ddd9327 Deployed Sep 28, 2026 by vercel[bot]
Preview – dataing — 9ddd9327 Deployed Sep 28, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant