@trpc/server 10.0.0-alpha.38 → 10.0.0-alpha.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.cjs.dev.js +20 -0
- package/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.cjs.prod.js +20 -0
- package/adapters/aws-lambda/dist/trpc-server-adapters-aws-lambda.esm.js +20 -0
- package/dist/adapters/aws-lambda/index.d.ts.map +1 -1
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/initTRPC.d.ts +1 -1
- package/dist/core/internals/procedureBuilder.d.ts +37 -13
- package/dist/core/internals/procedureBuilder.d.ts.map +1 -1
- package/dist/core/procedure.d.ts +12 -8
- package/dist/core/procedure.d.ts.map +1 -1
- package/dist/core/router.d.ts +17 -3
- package/dist/core/router.d.ts.map +1 -1
- package/dist/core/types.d.ts +3 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index-1a25ccbd.js +33 -0
- package/dist/index-a3bd54c7.mjs +31 -0
- package/dist/index.js +186 -191
- package/dist/index.mjs +185 -192
- package/dist/shared/index.js +2 -28
- package/dist/shared/index.mjs +1 -31
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/adapters/aws-lambda/index.ts +17 -0
- package/src/core/index.ts +2 -1
- package/src/core/internals/procedureBuilder.ts +264 -28
- package/src/core/procedure.ts +17 -10
- package/src/core/router.ts +79 -78
- package/src/core/types.ts +5 -1
- package/src/deprecated/interop.ts +4 -4
- package/src/types.ts +12 -0
- package/dist/core/internals/internalProcedure.d.ts +0 -78
- package/dist/core/internals/internalProcedure.d.ts.map +0 -1
- package/src/core/internals/internalProcedure.ts +0 -297
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { TRPCError } from '../../error/TRPCError';
|
|
2
|
+
import { getCauseFromUnknown, getErrorFromUnknown } from '../../error/utils';
|
|
1
3
|
import { MaybePromise } from '../../types';
|
|
2
|
-
import { MiddlewareFunction } from '../middleware';
|
|
4
|
+
import { MiddlewareFunction, MiddlewareResult } from '../middleware';
|
|
3
5
|
import { Parser, inferParser } from '../parser';
|
|
4
6
|
import {
|
|
5
7
|
MutationProcedure,
|
|
@@ -8,9 +10,11 @@ import {
|
|
|
8
10
|
QueryProcedure,
|
|
9
11
|
SubscriptionProcedure,
|
|
10
12
|
} from '../procedure';
|
|
13
|
+
import { ProcedureType } from '../types';
|
|
11
14
|
import { RootConfig } from './config';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
15
|
+
import { ParseFn, getParseFn } from './getParseFn';
|
|
16
|
+
import { mergeWithoutOverrides } from './mergeWithoutOverrides';
|
|
17
|
+
import { ResolveOptions, middlewareMarker } from './utils';
|
|
14
18
|
import { DefaultValue as FallbackValue, Overwrite, UnsetMarker } from './utils';
|
|
15
19
|
|
|
16
20
|
type CreateProcedureReturnInput<
|
|
@@ -21,8 +25,8 @@ type CreateProcedureReturnInput<
|
|
|
21
25
|
_meta: TPrev['_meta'];
|
|
22
26
|
_ctx_in: TPrev['_ctx_in'];
|
|
23
27
|
_ctx_out: Overwrite<TPrev['_ctx_out'], TNext['_ctx_out']>;
|
|
24
|
-
_input_out: FallbackValue<TNext['_input_out'], TPrev['_input_out']>;
|
|
25
28
|
_input_in: FallbackValue<TNext['_input_in'], TPrev['_input_in']>;
|
|
29
|
+
_input_out: FallbackValue<TNext['_input_out'], TPrev['_input_out']>;
|
|
26
30
|
_output_in: FallbackValue<TNext['_output_in'], TPrev['_output_in']>;
|
|
27
31
|
_output_out: FallbackValue<TNext['_output_out'], TPrev['_output_out']>;
|
|
28
32
|
}>;
|
|
@@ -38,10 +42,10 @@ export interface ProcedureBuilder<TParams extends ProcedureParams> {
|
|
|
38
42
|
_meta: TParams['_meta'];
|
|
39
43
|
_ctx_in: TParams['_ctx_in'];
|
|
40
44
|
_ctx_out: TParams['_ctx_out'];
|
|
41
|
-
_output_in: TParams['_output_in'];
|
|
42
|
-
_output_out: TParams['_output_out'];
|
|
43
45
|
_input_in: inferParser<$TParser>['in'];
|
|
44
46
|
_input_out: inferParser<$TParser>['out'];
|
|
47
|
+
_output_in: TParams['_output_in'];
|
|
48
|
+
_output_out: TParams['_output_out'];
|
|
45
49
|
}>;
|
|
46
50
|
/**
|
|
47
51
|
* Add an output parser to the procedure.
|
|
@@ -72,7 +76,7 @@ export interface ProcedureBuilder<TParams extends ProcedureParams> {
|
|
|
72
76
|
* Extend the procedure with another procedure.
|
|
73
77
|
* @warning The TypeScript inference fails when chaining concatenated procedures.
|
|
74
78
|
*/
|
|
75
|
-
unstable_concat<$ProcedureReturnInput extends
|
|
79
|
+
unstable_concat<$ProcedureReturnInput extends AnyProcedureBuilder>(
|
|
76
80
|
proc: $ProcedureReturnInput,
|
|
77
81
|
): $ProcedureReturnInput extends ProcedureBuilder<infer $TParams>
|
|
78
82
|
? CreateProcedureReturnInput<TParams, $TParams>
|
|
@@ -94,24 +98,7 @@ export interface ProcedureBuilder<TParams extends ProcedureParams> {
|
|
|
94
98
|
>
|
|
95
99
|
>
|
|
96
100
|
: Procedure<TParams>;
|
|
97
|
-
|
|
98
|
-
* Query procedure
|
|
99
|
-
*/
|
|
100
|
-
query<$TOutput>(
|
|
101
|
-
resolver: (
|
|
102
|
-
opts: ResolveOptions<TParams>,
|
|
103
|
-
) => MaybePromise<FallbackValue<TParams['_output_in'], $TOutput>>,
|
|
104
|
-
): UnsetMarker extends TParams['_output_out']
|
|
105
|
-
? QueryProcedure<
|
|
106
|
-
Overwrite<
|
|
107
|
-
TParams,
|
|
108
|
-
{
|
|
109
|
-
_output_in: $TOutput;
|
|
110
|
-
_output_out: $TOutput;
|
|
111
|
-
}
|
|
112
|
-
>
|
|
113
|
-
>
|
|
114
|
-
: QueryProcedure<TParams>;
|
|
101
|
+
|
|
115
102
|
/**
|
|
116
103
|
* Query procedure
|
|
117
104
|
*/
|
|
@@ -168,17 +155,266 @@ export interface ProcedureBuilder<TParams extends ProcedureParams> {
|
|
|
168
155
|
>
|
|
169
156
|
>
|
|
170
157
|
: SubscriptionProcedure<TParams>;
|
|
158
|
+
/**
|
|
159
|
+
* @internal
|
|
160
|
+
*/
|
|
161
|
+
_def: {
|
|
162
|
+
input?: Parser;
|
|
163
|
+
output?: Parser;
|
|
164
|
+
meta?: Record<string, unknown>;
|
|
165
|
+
resolver?: ProcedureBuilderResolver;
|
|
166
|
+
middlewares: ProcedureBuilderMiddleware[];
|
|
167
|
+
mutation?: boolean;
|
|
168
|
+
query?: boolean;
|
|
169
|
+
subscription?: boolean;
|
|
170
|
+
};
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
|
|
173
|
+
type AnyProcedureBuilder = ProcedureBuilder<any>;
|
|
174
|
+
export type ProcedureBuilderDef = AnyProcedureBuilder['_def'];
|
|
175
|
+
|
|
176
|
+
export type ProcedureBuilderMiddleware = MiddlewareFunction<any, any>;
|
|
177
|
+
|
|
178
|
+
export type ProcedureBuilderResolver = (
|
|
179
|
+
opts: ResolveOptions<any>,
|
|
180
|
+
) => Promise<unknown>;
|
|
181
|
+
|
|
182
|
+
function createNewBuilder(
|
|
183
|
+
def1: ProcedureBuilderDef,
|
|
184
|
+
def2: Partial<ProcedureBuilderDef>,
|
|
185
|
+
) {
|
|
186
|
+
const { middlewares = [], ...rest } = def2;
|
|
187
|
+
|
|
188
|
+
// TODO: maybe have a fn here to warn about calls
|
|
189
|
+
return createBuilder({
|
|
190
|
+
...mergeWithoutOverrides(def1, rest),
|
|
191
|
+
middlewares: [...def1.middlewares, ...middlewares],
|
|
192
|
+
} as any);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export function createBuilder<TConfig extends RootConfig>(
|
|
196
|
+
initDef?: ProcedureBuilderDef,
|
|
197
|
+
): ProcedureBuilder<{
|
|
174
198
|
_config: TConfig;
|
|
175
199
|
_ctx_in: TConfig['ctx'];
|
|
176
200
|
_ctx_out: TConfig['ctx'];
|
|
177
|
-
_input_out: UnsetMarker;
|
|
178
201
|
_input_in: UnsetMarker;
|
|
202
|
+
_input_out: UnsetMarker;
|
|
179
203
|
_output_in: UnsetMarker;
|
|
180
204
|
_output_out: UnsetMarker;
|
|
181
205
|
_meta: TConfig['meta'];
|
|
182
206
|
}> {
|
|
183
|
-
|
|
207
|
+
const _def: ProcedureBuilderDef = initDef || {
|
|
208
|
+
middlewares: [],
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
return {
|
|
212
|
+
_def,
|
|
213
|
+
input(input) {
|
|
214
|
+
const parser = getParseFn(input);
|
|
215
|
+
return createNewBuilder(_def, {
|
|
216
|
+
input,
|
|
217
|
+
middlewares: [createInputMiddleware(parser)],
|
|
218
|
+
}) as AnyProcedureBuilder;
|
|
219
|
+
},
|
|
220
|
+
output(output: Parser) {
|
|
221
|
+
const parseOutput = getParseFn(output);
|
|
222
|
+
return createNewBuilder(_def, {
|
|
223
|
+
output,
|
|
224
|
+
middlewares: [createOutputMiddleware(parseOutput)],
|
|
225
|
+
}) as AnyProcedureBuilder;
|
|
226
|
+
},
|
|
227
|
+
meta(meta) {
|
|
228
|
+
return createNewBuilder(_def, {
|
|
229
|
+
meta: meta as Record<string, unknown>,
|
|
230
|
+
}) as AnyProcedureBuilder;
|
|
231
|
+
},
|
|
232
|
+
/** @deprecated **/
|
|
233
|
+
resolve(resolver) {
|
|
234
|
+
return createResolver(_def, resolver);
|
|
235
|
+
},
|
|
236
|
+
unstable_concat(builder) {
|
|
237
|
+
return createNewBuilder(_def, builder._def) as any;
|
|
238
|
+
},
|
|
239
|
+
use(middleware) {
|
|
240
|
+
return createNewBuilder(_def, {
|
|
241
|
+
middlewares: [middleware],
|
|
242
|
+
}) as AnyProcedureBuilder;
|
|
243
|
+
},
|
|
244
|
+
query(resolver) {
|
|
245
|
+
return createResolver(
|
|
246
|
+
{ ..._def, query: true },
|
|
247
|
+
resolver,
|
|
248
|
+
) as QueryProcedure<any>;
|
|
249
|
+
},
|
|
250
|
+
mutation(resolver) {
|
|
251
|
+
return createResolver(
|
|
252
|
+
{ ..._def, mutation: true },
|
|
253
|
+
resolver,
|
|
254
|
+
) as MutationProcedure<any>;
|
|
255
|
+
},
|
|
256
|
+
subscription(resolver) {
|
|
257
|
+
return createResolver(
|
|
258
|
+
{ ..._def, subscription: true },
|
|
259
|
+
resolver,
|
|
260
|
+
) as SubscriptionProcedure<any>;
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export function createInputMiddleware<T>(
|
|
266
|
+
parse: ParseFn<T>,
|
|
267
|
+
): ProcedureBuilderMiddleware {
|
|
268
|
+
return async function inputMiddleware({ next, rawInput }) {
|
|
269
|
+
let input: ReturnType<typeof parse>;
|
|
270
|
+
try {
|
|
271
|
+
input = await parse(rawInput);
|
|
272
|
+
} catch (cause) {
|
|
273
|
+
throw new TRPCError({
|
|
274
|
+
code: 'BAD_REQUEST',
|
|
275
|
+
cause: getCauseFromUnknown(cause),
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
// TODO fix this typing?
|
|
279
|
+
return next({ input } as any);
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export function createOutputMiddleware<T>(
|
|
284
|
+
parse: ParseFn<T>,
|
|
285
|
+
): ProcedureBuilderMiddleware {
|
|
286
|
+
return async function outputMiddleware({ next }) {
|
|
287
|
+
const result = await next();
|
|
288
|
+
if (!result.ok) {
|
|
289
|
+
// pass through failures without validating
|
|
290
|
+
return result;
|
|
291
|
+
}
|
|
292
|
+
try {
|
|
293
|
+
const data = await parse(result.data);
|
|
294
|
+
return {
|
|
295
|
+
...result,
|
|
296
|
+
data,
|
|
297
|
+
};
|
|
298
|
+
} catch (cause) {
|
|
299
|
+
throw new TRPCError({
|
|
300
|
+
message: 'Output validation failed',
|
|
301
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
302
|
+
cause: getCauseFromUnknown(cause),
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function createResolver(
|
|
309
|
+
_def: ProcedureBuilderDef,
|
|
310
|
+
resolver: (opts: ResolveOptions<any>) => MaybePromise<any>,
|
|
311
|
+
) {
|
|
312
|
+
const finalBuilder = createNewBuilder(_def, {
|
|
313
|
+
resolver,
|
|
314
|
+
middlewares: [
|
|
315
|
+
async function resolveMiddleware(opts) {
|
|
316
|
+
const data = await resolver(opts);
|
|
317
|
+
return {
|
|
318
|
+
marker: middlewareMarker,
|
|
319
|
+
ok: true,
|
|
320
|
+
data,
|
|
321
|
+
ctx: opts.ctx,
|
|
322
|
+
} as const;
|
|
323
|
+
},
|
|
324
|
+
],
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
return createProcedureCaller(finalBuilder._def);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* @internal
|
|
332
|
+
*/
|
|
333
|
+
export interface ProcedureCallOptions {
|
|
334
|
+
ctx: unknown;
|
|
335
|
+
rawInput: unknown;
|
|
336
|
+
input?: unknown;
|
|
337
|
+
path: string;
|
|
338
|
+
type: ProcedureType;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const codeblock = `
|
|
342
|
+
If you want to call this function on the server, you do the following:
|
|
343
|
+
This is a client-only function.
|
|
344
|
+
|
|
345
|
+
const caller = appRouter.createCaller({
|
|
346
|
+
/* ... your context */
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
const result = await caller.call('myProcedure', input);
|
|
350
|
+
`.trim();
|
|
351
|
+
|
|
352
|
+
function createProcedureCaller(_def: ProcedureBuilderDef): Procedure<any> {
|
|
353
|
+
const procedure = async function resolve(opts: ProcedureCallOptions) {
|
|
354
|
+
// is direct server-side call
|
|
355
|
+
if (!opts || !('rawInput' in opts)) {
|
|
356
|
+
throw new Error(codeblock);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// run the middlewares recursively with the resolver as the last one
|
|
360
|
+
const callRecursive = async (
|
|
361
|
+
callOpts: { ctx: any; index: number; input?: unknown } = {
|
|
362
|
+
index: 0,
|
|
363
|
+
ctx: opts.ctx,
|
|
364
|
+
},
|
|
365
|
+
): Promise<MiddlewareResult<any>> => {
|
|
366
|
+
try {
|
|
367
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
368
|
+
const middleware = _def.middlewares[callOpts.index]!;
|
|
369
|
+
const result = await middleware({
|
|
370
|
+
ctx: callOpts.ctx,
|
|
371
|
+
type: opts.type,
|
|
372
|
+
path: opts.path,
|
|
373
|
+
rawInput: opts.rawInput,
|
|
374
|
+
meta: _def.meta,
|
|
375
|
+
input: callOpts.input,
|
|
376
|
+
next: async (nextOpts?: { ctx: any; input?: any }) => {
|
|
377
|
+
return await callRecursive({
|
|
378
|
+
index: callOpts.index + 1,
|
|
379
|
+
ctx:
|
|
380
|
+
nextOpts && 'ctx' in nextOpts
|
|
381
|
+
? { ...callOpts.ctx, ...nextOpts.ctx }
|
|
382
|
+
: callOpts.ctx,
|
|
383
|
+
input:
|
|
384
|
+
nextOpts && 'input' in nextOpts
|
|
385
|
+
? nextOpts.input
|
|
386
|
+
: callOpts.input,
|
|
387
|
+
});
|
|
388
|
+
},
|
|
389
|
+
});
|
|
390
|
+
return result;
|
|
391
|
+
} catch (cause) {
|
|
392
|
+
return {
|
|
393
|
+
ok: false,
|
|
394
|
+
error: getErrorFromUnknown(cause),
|
|
395
|
+
marker: middlewareMarker,
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
// there's always at least one "next" since we wrap this.resolver in a middleware
|
|
401
|
+
const result = await callRecursive();
|
|
402
|
+
|
|
403
|
+
if (!result) {
|
|
404
|
+
throw new TRPCError({
|
|
405
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
406
|
+
message:
|
|
407
|
+
'No result from middlewares - did you forget to `return next()`?',
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
if (!result.ok) {
|
|
411
|
+
// re-throw original error
|
|
412
|
+
throw result.error;
|
|
413
|
+
}
|
|
414
|
+
return result.data;
|
|
415
|
+
};
|
|
416
|
+
procedure._def = _def;
|
|
417
|
+
procedure.meta = _def.meta;
|
|
418
|
+
|
|
419
|
+
return procedure as Procedure<any>;
|
|
184
420
|
}
|
package/src/core/procedure.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { DefaultErrorShape } from '../error/formatter';
|
|
2
2
|
import { CombinedDataTransformer } from '../transformer';
|
|
3
3
|
import { RootConfig } from './internals/config';
|
|
4
|
+
import {
|
|
5
|
+
ProcedureBuilderDef,
|
|
6
|
+
ProcedureCallOptions,
|
|
7
|
+
} from './internals/procedureBuilder';
|
|
4
8
|
import { UnsetMarker } from './internals/utils';
|
|
5
9
|
|
|
6
10
|
type ClientContext = Record<string, unknown>;
|
|
@@ -46,19 +50,19 @@ export interface ProcedureParams<
|
|
|
46
50
|
/**
|
|
47
51
|
* @internal
|
|
48
52
|
*/
|
|
49
|
-
|
|
53
|
+
_input_in: TInputIn;
|
|
50
54
|
/**
|
|
51
55
|
* @internal
|
|
52
56
|
*/
|
|
53
|
-
|
|
57
|
+
_input_out: TInputOut;
|
|
54
58
|
/**
|
|
55
59
|
* @internal
|
|
56
60
|
*/
|
|
57
|
-
|
|
61
|
+
_output_in: TOutputIn;
|
|
58
62
|
/**
|
|
59
63
|
* @internal
|
|
60
64
|
*/
|
|
61
|
-
|
|
65
|
+
_output_out: TOutputOut;
|
|
62
66
|
}
|
|
63
67
|
|
|
64
68
|
/**
|
|
@@ -72,37 +76,40 @@ export type ProcedureArgs<TParams extends ProcedureParams> =
|
|
|
72
76
|
: [input: TParams['_input_in'], opts?: ProcedureOptions];
|
|
73
77
|
|
|
74
78
|
/**
|
|
79
|
+
*
|
|
75
80
|
* @internal
|
|
76
81
|
*/
|
|
77
82
|
export interface ProcedureBase<TParams extends ProcedureParams> {
|
|
78
|
-
_def: TParams;
|
|
83
|
+
_def: TParams & ProcedureBuilderDef;
|
|
79
84
|
/**
|
|
80
85
|
* @deprecated use `._def.meta` instead
|
|
81
86
|
*/
|
|
82
87
|
meta?: TParams['_meta'];
|
|
83
88
|
_procedure: true;
|
|
89
|
+
/**
|
|
90
|
+
* @internal
|
|
91
|
+
*/
|
|
92
|
+
(opts: ProcedureCallOptions): Promise<unknown>;
|
|
84
93
|
}
|
|
85
94
|
|
|
86
95
|
export interface QueryProcedure<TParams extends ProcedureParams>
|
|
87
96
|
extends ProcedureBase<TParams> {
|
|
88
97
|
_query: true;
|
|
89
|
-
query(...args: ProcedureArgs<TParams>): Promise<TParams['_output_out']>;
|
|
90
98
|
}
|
|
91
99
|
|
|
92
100
|
export interface MutationProcedure<TParams extends ProcedureParams>
|
|
93
101
|
extends ProcedureBase<TParams> {
|
|
94
102
|
_mutation: true;
|
|
95
|
-
mutate(...args: ProcedureArgs<TParams>): Promise<TParams['_output_out']>;
|
|
96
103
|
}
|
|
97
104
|
|
|
98
105
|
export interface SubscriptionProcedure<TParams extends ProcedureParams>
|
|
99
106
|
extends ProcedureBase<TParams> {
|
|
100
107
|
_subscription: true;
|
|
101
|
-
subscription(
|
|
102
|
-
...args: ProcedureArgs<TParams>
|
|
103
|
-
): Promise<TParams['_output_out']>;
|
|
104
108
|
}
|
|
109
|
+
|
|
105
110
|
export type Procedure<TParams extends ProcedureParams> =
|
|
106
111
|
| QueryProcedure<TParams>
|
|
107
112
|
| MutationProcedure<TParams>
|
|
108
113
|
| SubscriptionProcedure<TParams>;
|
|
114
|
+
|
|
115
|
+
export type AnyProcedure = Procedure<any>;
|
package/src/core/router.ts
CHANGED
|
@@ -9,21 +9,21 @@ import {
|
|
|
9
9
|
} from '../error/formatter';
|
|
10
10
|
import { getHTTPStatusCodeFromError } from '../http/internals/getHTTPStatusCode';
|
|
11
11
|
import { TRPCErrorShape, TRPC_ERROR_CODES_BY_KEY } from '../rpc';
|
|
12
|
+
import { createProxy } from '../shared';
|
|
12
13
|
import { CombinedDataTransformer, defaultTransformer } from '../transformer';
|
|
13
14
|
import { RootConfig } from './internals/config';
|
|
14
|
-
import {
|
|
15
|
-
InternalProcedure,
|
|
16
|
-
InternalProcedureCallOptions,
|
|
17
|
-
} from './internals/internalProcedure';
|
|
18
15
|
import { mergeWithoutOverrides } from './internals/mergeWithoutOverrides';
|
|
19
16
|
import { omitPrototype } from './internals/omitPrototype';
|
|
17
|
+
import { ProcedureCallOptions } from './internals/procedureBuilder';
|
|
20
18
|
import {
|
|
19
|
+
AnyProcedure,
|
|
21
20
|
MutationProcedure,
|
|
22
21
|
Procedure,
|
|
22
|
+
ProcedureArgs,
|
|
23
23
|
QueryProcedure,
|
|
24
24
|
SubscriptionProcedure,
|
|
25
25
|
} from './procedure';
|
|
26
|
-
import { ProcedureType } from './types';
|
|
26
|
+
import { ProcedureType, procedureTypes } from './types';
|
|
27
27
|
|
|
28
28
|
type ProcedureRecord = Record<string, Procedure<any>>;
|
|
29
29
|
|
|
@@ -122,11 +122,24 @@ type inferHandlerFn<TProcedures extends Record<string, Procedure<any>>> = <
|
|
|
122
122
|
...args: inferHandlerInput<TProcedure>
|
|
123
123
|
) => Promise<inferProcedureOutput<TProcedure>>;
|
|
124
124
|
|
|
125
|
+
type DecorateProcedure<TProcedure extends Procedure<any>> = (
|
|
126
|
+
input: ProcedureArgs<TProcedure['_def']>[0],
|
|
127
|
+
) => Promise<TProcedure['_def']['_output_out']>;
|
|
128
|
+
|
|
129
|
+
type assertProcedure<T> = T extends Procedure<any> ? T : never;
|
|
130
|
+
|
|
125
131
|
/**
|
|
126
|
-
* This only exists b/c of interop mode
|
|
127
132
|
* @internal
|
|
128
133
|
*/
|
|
134
|
+
type DecoratedProcedureRecord<TProcedures extends ProcedureRouterRecord> = {
|
|
135
|
+
[TKey in keyof TProcedures]: TProcedures[TKey] extends AnyRouter
|
|
136
|
+
? DecoratedProcedureRecord<TProcedures[TKey]['_def']['record']>
|
|
137
|
+
: DecorateProcedure<assertProcedure<TProcedures[TKey]>>;
|
|
138
|
+
};
|
|
129
139
|
|
|
140
|
+
/**
|
|
141
|
+
* @internal
|
|
142
|
+
*/
|
|
130
143
|
type RouterCaller<TDef extends AnyRouterDef> = (ctx: TDef['_ctx']) => {
|
|
131
144
|
/**
|
|
132
145
|
* @deprecated
|
|
@@ -140,7 +153,7 @@ type RouterCaller<TDef extends AnyRouterDef> = (ctx: TDef['_ctx']) => {
|
|
|
140
153
|
* @deprecated
|
|
141
154
|
*/
|
|
142
155
|
subscription: inferHandlerFn<TDef['subscriptions']>;
|
|
143
|
-
}
|
|
156
|
+
} & DecoratedProcedureRecord<TDef['record']>;
|
|
144
157
|
|
|
145
158
|
export interface Router<TDef extends AnyRouterDef> {
|
|
146
159
|
_def: RouterDef<
|
|
@@ -153,8 +166,6 @@ export interface Router<TDef extends AnyRouterDef> {
|
|
|
153
166
|
errorFormatter: TDef['errorFormatter'];
|
|
154
167
|
/** @deprecated **/
|
|
155
168
|
transformer: TDef['transformer'];
|
|
156
|
-
|
|
157
|
-
// FIXME rename me and deprecate
|
|
158
169
|
createCaller: RouterCaller<TDef>;
|
|
159
170
|
// FIXME rename me and deprecate
|
|
160
171
|
getErrorShape(opts: {
|
|
@@ -183,13 +194,12 @@ export type RouterBuildOptions<TContext> = Partial<
|
|
|
183
194
|
|
|
184
195
|
export type AnyRouter = Router<any>;
|
|
185
196
|
|
|
186
|
-
function
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
},
|
|
191
|
-
});
|
|
197
|
+
function isRouter(
|
|
198
|
+
procedureOrRouter: AnyProcedure | AnyRouter,
|
|
199
|
+
): procedureOrRouter is AnyRouter {
|
|
200
|
+
return 'router' in procedureOrRouter._def;
|
|
192
201
|
}
|
|
202
|
+
|
|
193
203
|
const emptyRouter = {
|
|
194
204
|
_ctx: null as any,
|
|
195
205
|
_errorShape: null as any,
|
|
@@ -226,9 +236,8 @@ export function createRouterFactory<TConfig extends RootConfig>(
|
|
|
226
236
|
for (const [key, procedureOrRouter] of Object.entries(procedures ?? {})) {
|
|
227
237
|
const newPath = `${path}${key}`;
|
|
228
238
|
|
|
229
|
-
if (
|
|
230
|
-
|
|
231
|
-
recursiveGetPaths(router._def.procedures, `${newPath}.`);
|
|
239
|
+
if (isRouter(procedureOrRouter)) {
|
|
240
|
+
recursiveGetPaths(procedureOrRouter._def.procedures, `${newPath}.`);
|
|
232
241
|
continue;
|
|
233
242
|
}
|
|
234
243
|
|
|
@@ -268,74 +277,46 @@ export function createRouterFactory<TConfig extends RootConfig>(
|
|
|
268
277
|
.reduce((acc, [key, val]) => ({ ...acc, [key]: val }), {}),
|
|
269
278
|
};
|
|
270
279
|
|
|
271
|
-
function callProcedure(opts: InternalProcedureCallOptions) {
|
|
272
|
-
const { type, path } = opts;
|
|
273
|
-
|
|
274
|
-
if (!(path in _def.procedures) || !_def.procedures[path]['_def'][type]) {
|
|
275
|
-
throw new TRPCError({
|
|
276
|
-
code: 'NOT_FOUND',
|
|
277
|
-
message: `No "${type}"-procedure on path "${path}"`,
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
const procedure = _def.procedures[path] as InternalProcedure;
|
|
282
|
-
|
|
283
|
-
return procedure(opts);
|
|
284
|
-
}
|
|
285
280
|
const router: AnyRouter = {
|
|
286
281
|
...opts,
|
|
287
282
|
_def,
|
|
288
283
|
transformer: _def.transformer,
|
|
289
284
|
errorFormatter: _def.errorFormatter,
|
|
290
285
|
createCaller(ctx) {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
path,
|
|
302
|
-
rawInput: args[0],
|
|
286
|
+
const proxy = createProxy(({ path, args }) => {
|
|
287
|
+
// interop mode
|
|
288
|
+
if (
|
|
289
|
+
path.length === 1 &&
|
|
290
|
+
procedureTypes.includes(path[0] as ProcedureType)
|
|
291
|
+
) {
|
|
292
|
+
return callProcedure({
|
|
293
|
+
procedures: _def.procedures,
|
|
294
|
+
path: args[0] as string,
|
|
295
|
+
rawInput: args[1],
|
|
303
296
|
ctx,
|
|
304
|
-
type:
|
|
305
|
-
})
|
|
306
|
-
|
|
307
|
-
callProcedure({
|
|
308
|
-
path,
|
|
309
|
-
rawInput: args[0],
|
|
310
|
-
ctx,
|
|
311
|
-
type: 'subscription',
|
|
312
|
-
}) as any,
|
|
297
|
+
type: path[0] as ProcedureType,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
313
300
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
)
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
rawInput,
|
|
334
|
-
ctx,
|
|
335
|
-
type: 'subscription',
|
|
336
|
-
}),
|
|
337
|
-
),
|
|
338
|
-
};
|
|
301
|
+
const fullPath = path.join('.');
|
|
302
|
+
const procedure = _def.procedures[fullPath] as AnyProcedure;
|
|
303
|
+
|
|
304
|
+
let type: ProcedureType = 'query';
|
|
305
|
+
if (procedure._def.mutation) {
|
|
306
|
+
type = 'mutation';
|
|
307
|
+
} else if (procedure._def.subscription) {
|
|
308
|
+
type = 'subscription';
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return procedure({
|
|
312
|
+
path: fullPath,
|
|
313
|
+
rawInput: args[0],
|
|
314
|
+
ctx,
|
|
315
|
+
type,
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
return proxy as ReturnType<RouterCaller<any>>;
|
|
339
320
|
},
|
|
340
321
|
getErrorShape(opts) {
|
|
341
322
|
const { path, error } = opts;
|
|
@@ -363,3 +344,23 @@ export function createRouterFactory<TConfig extends RootConfig>(
|
|
|
363
344
|
return router as any;
|
|
364
345
|
};
|
|
365
346
|
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* @internal
|
|
350
|
+
*/
|
|
351
|
+
export function callProcedure(
|
|
352
|
+
opts: ProcedureCallOptions & { procedures: ProcedureRouterRecord },
|
|
353
|
+
) {
|
|
354
|
+
const { type, path } = opts;
|
|
355
|
+
|
|
356
|
+
if (!(path in opts.procedures) || !opts.procedures[path]?._def[type]) {
|
|
357
|
+
throw new TRPCError({
|
|
358
|
+
code: 'NOT_FOUND',
|
|
359
|
+
message: `No "${type}"-procedure on path "${path}"`,
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
const procedure = opts.procedures[path] as AnyProcedure;
|
|
364
|
+
|
|
365
|
+
return procedure(opts);
|
|
366
|
+
}
|
package/src/core/types.ts
CHANGED
|
@@ -17,10 +17,11 @@ export type inferRouterError<TRouter extends AnyRouter> =
|
|
|
17
17
|
export type inferRouterMeta<TRouter extends AnyRouter> =
|
|
18
18
|
inferRouterDef<TRouter>['_meta'];
|
|
19
19
|
|
|
20
|
+
export const procedureTypes = ['query', 'mutation', 'subscription'] as const;
|
|
20
21
|
/**
|
|
21
22
|
* @public
|
|
22
23
|
*/
|
|
23
|
-
export type ProcedureType =
|
|
24
|
+
export type ProcedureType = typeof procedureTypes[number];
|
|
24
25
|
|
|
25
26
|
export type inferHandlerInput<TProcedure extends Procedure<any>> =
|
|
26
27
|
ProcedureArgs<inferProcedureParams<TProcedure>>;
|
|
@@ -52,3 +53,6 @@ export type inferSubscriptionOutput<
|
|
|
52
53
|
> = inferObservableValue<
|
|
53
54
|
inferProcedureOutput<TRouter['_def']['subscriptions'][TPath]>
|
|
54
55
|
>;
|
|
56
|
+
|
|
57
|
+
export type inferProcedureClientError<T extends Procedure<any>> =
|
|
58
|
+
inferProcedureParams<T>['_config']['errorShape'];
|