Repository navigation
Commit b3945c9
fix!: only accept jsonified client factories in createContractJsonifiedUtilsFactory (#2328)
## Problem
[Contract Client Factory](https://orpc.dev/docs/contract/client-factory)
tells OpenAPI Link users two things:
- create the client factory with `createContractJsonifiedClientFactory`
from `@orpc/openapi`;
- create the utils with `createContractJsonifiedUtilsFactory` from
`@orpc/tanstack-query` / `@orpc/pinia-colada`.
Following both fails, because the utils factory only accepted a plain
`ContractClientFactory`:
```ts
const createClient = createContractJsonifiedClientFactory(link, { contractRef })
const createUtils = createContractJsonifiedUtilsFactory(createClient, {})
// TS2345: Argument of type 'ContractJsonifiedClientFactory<ClientContext>' is not assignable to parameter of type
// 'ContractClientFactory<ClientContext>'. Type 'JsonifiedClient<RouterContractClient<T, ClientContext>>' is not
// assignable to type 'RouterContractClient<T, ClientContext>'.
```
## Fix
In both `@orpc/tanstack-query` and `@orpc/pinia-colada`,
`createContractJsonifiedUtilsFactory` now takes the jsonified client
factory:
```diff
- clientFactory: ContractClientFactory<TClientContext>,
+ clientFactory: ContractJsonifiedClientFactory<TClientContext>,
```
The jsonified utils factory always produces utils for `JsonifiedClient`,
so its input is now the client factory that declares jsonified clients.
This mirrors `createContractUtilsFactory`, which takes only a
`ContractClientFactory`:
| Client factory | Utils factory |
| --- | --- |
| `createContractClientFactory` (`@orpc/contract`) |
`createContractUtilsFactory` |
| `createContractJsonifiedClientFactory` (`@orpc/openapi`) |
`createContractJsonifiedUtilsFactory` |
Passing the other kind to either utils factory is now a type error.
Previously a plain client factory passed to the jsonified utils factory
was silently re-typed as jsonified.
`createContractJsonifiedClientFactory` is
`createContractClientFactory(...)` cast to
`ContractJsonifiedClientFactory`, so there is no runtime change. Neither
factory type is assignable to the other, so the restriction is enforced
in both directions.
Docs:
- **`createContractJsonifiedUtilsFactory`** gets a JSDoc block with a
`@see` link and the same `meta.path` note as
`createContractUtilsFactory`.
- **`createContractJsonifiedClientFactory`** (`@orpc/openapi`) gets a
JSDoc mirroring `createContractClientFactory`'s. It had none, and this
PR makes it the required input.
- **Docs page:** the two warnings (TanStack Query and Pinia Colada
sections) now say to pass a client factory created by
`createContractJsonifiedClientFactory`.
## Breaking change
`createContractJsonifiedUtilsFactory` no longer accepts a plain
`ContractClientFactory` (types only). Create the client factory with
`createContractJsonifiedClientFactory` from `@orpc/openapi` instead.
## Tests
In both packages, the `createContractJsonifiedUtilsFactory` cases in
`contract-utils.test-d.ts` now use a `ContractJsonifiedClientFactory`.
They cover interceptor input/output/error types and the procedure and
router utils types. Before this PR they failed with the TS2345 above.
## Verification
- `pnpm lint`, `pnpm vitest run packages/tanstack-query
packages/pinia-colada`, `pnpm type:check` (which includes the
playgrounds) and `pnpm docs:validate` pass.
- **Consumer projects**, against packed tarballs of every package from
`main` and from this branch:
- Setup: one TanStack Query consumer and one Pinia Colada consumer, each
installing only `@orpc/contract`, `@orpc/client`, `@orpc/openapi` and
the integration. They follow the docs: OpenAPI Link with `contractRef`,
a required `{ token: string }` context, and scoped options.
- Builds: `composite: true` with TS 6 (bundler and NodeNext) and TS 5.9.
- On `main`: the docs flow fails with the TS2345 above, and a plain
client factory passed to the jsonified utils factory is still accepted.
- On this branch: zero diagnostics, and passing the wrong kind of client
factory to either utils factory is a type error. The required context
reaches every interceptor and call site, jsonified output types reach
`queryOptions`/`fetchQuery`/`mutationOptions`, and the emitted JS is
byte-identical to `main`.
- **Not caused by this PR:** re-checking the emitted `.d.ts` with
`skipLibCheck: false` reports TS2304 for `dataTagSymbol` when a consumer
exports an inferred `queryKey`. This happens identically on `main` and
with `@tanstack/query-core` alone.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01U63hBfpeESmJiHXznRFzjN
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 0e59dd2 commit b3945c9
6 files changed
Lines changed: 53 additions & 22 deletions
File tree
- apps/content/docs/contract
- packages
- openapi/src
- pinia-colada/src
- tanstack-query/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
101 | 101 | | |
102 | 102 | | |
103 | 103 | | |
104 | | - | |
| 104 | + | |
105 | 105 | | |
106 | 106 | | |
107 | 107 | | |
| |||
135 | 135 | | |
136 | 136 | | |
137 | 137 | | |
138 | | - | |
| 138 | + | |
139 | 139 | | |
140 | 140 | | |
141 | 141 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
23 | 32 | | |
24 | 33 | | |
25 | 34 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
| |||
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
21 | | - | |
22 | | - | |
| 22 | + | |
| 23 | + | |
23 | 24 | | |
| 25 | + | |
24 | 26 | | |
25 | 27 | | |
26 | 28 | | |
| |||
98 | 100 | | |
99 | 101 | | |
100 | 102 | | |
101 | | - | |
102 | | - | |
103 | 103 | | |
104 | | - | |
| 104 | + | |
105 | 105 | | |
106 | 106 | | |
107 | 107 | | |
| |||
156 | 156 | | |
157 | 157 | | |
158 | 158 | | |
159 | | - | |
| 159 | + | |
160 | 160 | | |
161 | 161 | | |
162 | 162 | | |
| |||
165 | 165 | | |
166 | 166 | | |
167 | 167 | | |
168 | | - | |
| 168 | + | |
169 | 169 | | |
170 | 170 | | |
171 | 171 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
59 | 70 | | |
60 | 71 | | |
61 | 72 | | |
62 | | - | |
| 73 | + | |
63 | 74 | | |
64 | 75 | | |
65 | | - | |
| 76 | + | |
66 | 77 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
| |||
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
21 | | - | |
22 | | - | |
| 22 | + | |
| 23 | + | |
23 | 24 | | |
| 25 | + | |
24 | 26 | | |
25 | 27 | | |
26 | 28 | | |
| |||
98 | 100 | | |
99 | 101 | | |
100 | 102 | | |
101 | | - | |
102 | | - | |
103 | 103 | | |
104 | | - | |
| 104 | + | |
105 | 105 | | |
106 | 106 | | |
107 | 107 | | |
| |||
156 | 156 | | |
157 | 157 | | |
158 | 158 | | |
159 | | - | |
| 159 | + | |
160 | 160 | | |
161 | 161 | | |
162 | 162 | | |
| |||
165 | 165 | | |
166 | 166 | | |
167 | 167 | | |
168 | | - | |
| 168 | + | |
169 | 169 | | |
170 | 170 | | |
171 | 171 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
59 | 70 | | |
60 | 71 | | |
61 | 72 | | |
62 | | - | |
| 73 | + | |
63 | 74 | | |
64 | 75 | | |
65 | | - | |
| 76 | + | |
66 | 77 | | |
0 commit comments