Skip to content

Commit c41980d

Browse files
authored
feat: trpc plugin, generate client helpers to provide prisima-like typing (#510)
1 parent 4b389fb commit c41980d

File tree

9 files changed

+707
-80
lines changed

9 files changed

+707
-80
lines changed

packages/plugins/tanstack-query/tests/plugin.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ ${sharedModel}
9090
`,
9191
true,
9292
false,
93-
[`${origDir}/dist`, 'svelte', '@types/react', '@tanstack/svelte-query'],
93+
[`${origDir}/dist`, 'svelte@^3.0.0', '@types/react', '@tanstack/svelte-query'],
9494
true
9595
);
9696
});
@@ -109,7 +109,7 @@ ${sharedModel}
109109
`,
110110
true,
111111
false,
112-
[`${origDir}/dist`, 'svelte', '@types/react', '@tanstack/svelte-query', 'superjson'],
112+
[`${origDir}/dist`, 'svelte@^3.0.0', '@types/react', '@tanstack/svelte-query', 'superjson'],
113113
true
114114
);
115115
});

packages/plugins/trpc/package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
},
1111
"scripts": {
1212
"clean": "rimraf dist",
13-
"build": "pnpm lint && pnpm clean && tsc && copyfiles ./package.json ./README.md ./LICENSE dist",
13+
"build": "pnpm lint && pnpm clean && tsc && copyfiles ./package.json ./README.md ./LICENSE 'res/**/*' dist",
1414
"watch": "tsc --watch",
1515
"lint": "eslint src --ext ts",
1616
"prepublishOnly": "pnpm build",
@@ -32,15 +32,20 @@
3232
"prettier": "^2.8.3",
3333
"ts-morph": "^16.0.0",
3434
"tslib": "^2.4.1",
35+
"upper-case-first": "^2.0.2",
3536
"zod": "3.21.1"
3637
},
3738
"devDependencies": {
39+
"@trpc/next": "^10.32.0",
40+
"@trpc/react-query": "^10.32.0",
41+
"@trpc/server": "^10.32.0",
3842
"@types/jest": "^29.5.0",
3943
"@types/lower-case-first": "^1.0.1",
4044
"@types/prettier": "^2.7.2",
4145
"@zenstackhq/testtools": "workspace:*",
4246
"copyfiles": "^2.4.1",
4347
"jest": "^29.5.0",
48+
"next": "^13.4.7",
4449
"rimraf": "^3.0.2",
4550
"ts-jest": "^29.0.5",
4651
"typescript": "^4.9.4"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* eslint-disable */
2+
3+
import type { AnyRouter } from '@trpc/server';
4+
import type { NextPageContext } from 'next';
5+
import { type CreateTRPCNext, createTRPCNext as _createTRPCNext } from '@trpc/next';
6+
import type { DeepOverrideAtPath } from './utils';
7+
import type { ClientType } from '../routers';
8+
9+
export function createTRPCReact<
10+
TRouter extends AnyRouter,
11+
TPath extends string | undefined = undefined,
12+
TSSRContext extends NextPageContext = NextPageContext,
13+
TFlags = null
14+
>(opts: Parameters<typeof _createTRPCNext>[0]) {
15+
const r: CreateTRPCNext<TRouter, TSSRContext, TFlags> = _createTRPCNext<TRouter, TSSRContext, TFlags>(opts);
16+
return r as DeepOverrideAtPath<CreateTRPCNext<TRouter, TSSRContext, TFlags>, ClientType<TRouter>, TPath>;
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* eslint-disable */
2+
3+
import type { AnyRouter } from '@trpc/server';
4+
import type { CreateTRPCReactOptions } from '@trpc/react-query/shared';
5+
import { type CreateTRPCReact, createTRPCReact as _createTRPCReact } from '@trpc/react-query';
6+
import type { DeepOverrideAtPath } from './utils';
7+
import type { ClientType } from '../routers';
8+
9+
export function createTRPCReact<
10+
TRouter extends AnyRouter,
11+
TPath extends string | undefined = undefined,
12+
TSSRContext = unknown,
13+
TFlags = null
14+
>(opts?: CreateTRPCReactOptions<TRouter>) {
15+
const r: CreateTRPCReact<TRouter, TSSRContext, TFlags> = _createTRPCReact<TRouter, TSSRContext, TFlags>(opts);
16+
return r as DeepOverrideAtPath<CreateTRPCReact<TRouter, TSSRContext, TFlags>, ClientType<TRouter>, TPath>;
17+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* eslint-disable */
2+
3+
// inspired by: https://stackoverflow.com/questions/70632026/generic-to-recursively-modify-a-given-type-interface-in-typescript
4+
5+
type Primitive = string | Function | number | boolean | Symbol | undefined | null;
6+
7+
/**
8+
* Recursively merges `T` and `R`. If there's a shared key, use `R`'s field type to overwrite `T`.
9+
*/
10+
export type DeepOverride<T, R> = T extends Primitive
11+
? R
12+
: R extends Primitive
13+
? R
14+
: {
15+
[K in keyof T]: K extends keyof R ? DeepOverride<T[K], R[K]> : T[K];
16+
} & {
17+
[K in Exclude<keyof R, keyof T>]: R[K];
18+
};
19+
20+
/**
21+
* Traverse to `Path` (denoted by dot separated string literal type) in `T`, and starting from there,
22+
* recursively merge with `R`.
23+
*/
24+
export type DeepOverrideAtPath<T, R, Path extends string | undefined = undefined> = Path extends undefined
25+
? DeepOverride<T, R>
26+
: Path extends `${infer P1}.${infer P2}`
27+
? P1 extends keyof T
28+
? Omit<T, P1> & Record<P1, DeepOverride<T[P1], DeepOverrideAtPath<T[P1], R, P2>>>
29+
: never
30+
: Path extends keyof T
31+
? Omit<T, Path> & Record<Path, DeepOverride<T[Path], R>>
32+
: never;

0 commit comments

Comments
 (0)