@trpc/server 11.0.0-next.320 → 11.0.0-next.323

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.
Files changed (29) hide show
  1. package/dist/bundle-analysis.json +71 -70
  2. package/dist/unstable-core-do-not-import/http/index.d.ts +5 -1
  3. package/dist/unstable-core-do-not-import/http/index.d.ts.map +1 -1
  4. package/dist/unstable-core-do-not-import/http/types.d.ts +7 -10
  5. package/dist/unstable-core-do-not-import/http/types.d.ts.map +1 -1
  6. package/dist/unstable-core-do-not-import/initTRPC.d.ts +3 -3
  7. package/dist/unstable-core-do-not-import/procedure.d.ts +13 -1
  8. package/dist/unstable-core-do-not-import/procedure.d.ts.map +1 -1
  9. package/dist/unstable-core-do-not-import/procedureBuilder.d.ts +46 -13
  10. package/dist/unstable-core-do-not-import/procedureBuilder.d.ts.map +1 -1
  11. package/dist/unstable-core-do-not-import/procedureBuilder.js +20 -1
  12. package/dist/unstable-core-do-not-import/procedureBuilder.mjs +20 -1
  13. package/dist/unstable-core-do-not-import/router.d.ts +10 -4
  14. package/dist/unstable-core-do-not-import/router.d.ts.map +1 -1
  15. package/dist/unstable-core-do-not-import/router.js +18 -23
  16. package/dist/unstable-core-do-not-import/router.mjs +20 -25
  17. package/dist/unstable-core-do-not-import/utils.d.ts +3 -0
  18. package/dist/unstable-core-do-not-import/utils.d.ts.map +1 -1
  19. package/dist/unstable-core-do-not-import/utils.js +4 -0
  20. package/dist/unstable-core-do-not-import/utils.mjs +4 -1
  21. package/dist/unstable-core-do-not-import.js +1 -0
  22. package/dist/unstable-core-do-not-import.mjs +1 -1
  23. package/package.json +2 -2
  24. package/src/unstable-core-do-not-import/http/index.ts +5 -1
  25. package/src/unstable-core-do-not-import/http/types.ts +9 -10
  26. package/src/unstable-core-do-not-import/procedure.ts +21 -1
  27. package/src/unstable-core-do-not-import/procedureBuilder.ts +107 -21
  28. package/src/unstable-core-do-not-import/router.ts +45 -32
  29. package/src/unstable-core-do-not-import/utils.ts +5 -0
@@ -1,3 +1,4 @@
1
+ import type { TRPCError } from './error/TRPCError';
1
2
  import type { ProcedureCallOptions } from './procedureBuilder';
2
3
 
3
4
  export const procedureTypes = ['query', 'mutation', 'subscription'] as const;
@@ -22,7 +23,9 @@ export interface ProcedureOptions {
22
23
  interface BuiltProcedureDef {
23
24
  input: unknown;
24
25
  output: unknown;
26
+ experimental_caller?: true;
25
27
  }
28
+
26
29
  /**
27
30
  *
28
31
  * @internal
@@ -45,7 +48,13 @@ export interface Procedure<
45
48
  /**
46
49
  * @internal
47
50
  */
48
- (opts: ProcedureCallOptions): Promise<unknown>;
51
+ (
52
+ opts: TDef['experimental_caller'] extends true
53
+ ? TDef['input']
54
+ : ProcedureCallOptions,
55
+ ): Promise<
56
+ TDef['experimental_caller'] extends true ? TDef['output'] : unknown
57
+ >;
49
58
  }
50
59
 
51
60
  export interface QueryProcedure<TDef extends BuiltProcedureDef>
@@ -72,3 +81,14 @@ export type inferProcedureParams<TProcedure> = TProcedure extends AnyProcedure
72
81
  : never;
73
82
  export type inferProcedureOutput<TProcedure> =
74
83
  inferProcedureParams<TProcedure>['_output_out'];
84
+
85
+ /**
86
+ * @internal
87
+ */
88
+ export interface ErrorHandlerOptions<TContext> {
89
+ error: TRPCError;
90
+ type: ProcedureType | 'unknown';
91
+ path: string | undefined;
92
+ input: unknown;
93
+ ctx: TContext | undefined;
94
+ }
@@ -45,6 +45,11 @@ type DefaultValue<TValue, TFallback> = TValue extends UnsetMarker
45
45
  ? TFallback
46
46
  : TValue;
47
47
 
48
+ export type CallerOverride = (opts: {
49
+ args: unknown[];
50
+ invoke: (opts: ProcedureCallOptions) => Promise<unknown>;
51
+ _def: AnyProcedure['_def'];
52
+ }) => Promise<unknown>;
48
53
  type ProcedureBuilderDef<TMeta> = {
49
54
  procedure: true;
50
55
  inputs: Parser[];
@@ -52,9 +57,20 @@ type ProcedureBuilderDef<TMeta> = {
52
57
  meta?: TMeta;
53
58
  resolver?: ProcedureBuilderResolver;
54
59
  middlewares: AnyMiddlewareFunction[];
60
+ /**
61
+ * @deprecated use `type` instead
62
+ */
55
63
  mutation?: boolean;
64
+ /**
65
+ * @deprecated use `type` instead
66
+ */
56
67
  query?: boolean;
68
+ /**
69
+ * @deprecated use `type` instead
70
+ */
57
71
  subscription?: boolean;
72
+ type?: ProcedureType;
73
+ caller?: CallerOverride;
58
74
  };
59
75
 
60
76
  type AnyProcedureBuilderDef = ProcedureBuilderDef<any>;
@@ -98,6 +114,7 @@ export type AnyProcedureBuilder = ProcedureBuilder<
98
114
  any,
99
115
  any,
100
116
  any,
117
+ any,
101
118
  any
102
119
  >;
103
120
 
@@ -114,7 +131,8 @@ export type inferProcedureBuilderResolverOptions<
114
131
  infer _TInputIn,
115
132
  infer TInputOut,
116
133
  infer _TOutputIn,
117
- infer _TOutputOut
134
+ infer _TOutputOut,
135
+ infer _TCaller
118
136
  >
119
137
  ? ProcedureResolverOptions<
120
138
  TContext,
@@ -144,6 +162,7 @@ export interface ProcedureBuilder<
144
162
  TInputOut,
145
163
  TOutputIn,
146
164
  TOutputOut,
165
+ TCaller extends boolean,
147
166
  > {
148
167
  /**
149
168
  * Add an input parser to the procedure.
@@ -168,7 +187,8 @@ export interface ProcedureBuilder<
168
187
  IntersectIfDefined<TInputIn, inferParser<$Parser>['in']>,
169
188
  IntersectIfDefined<TInputOut, inferParser<$Parser>['out']>,
170
189
  TOutputIn,
171
- TOutputOut
190
+ TOutputOut,
191
+ TCaller
172
192
  >;
173
193
  /**
174
194
  * Add an output parser to the procedure.
@@ -183,7 +203,8 @@ export interface ProcedureBuilder<
183
203
  TInputIn,
184
204
  TInputOut,
185
205
  IntersectIfDefined<TOutputIn, inferParser<$Parser>['in']>,
186
- IntersectIfDefined<TOutputOut, inferParser<$Parser>['out']>
206
+ IntersectIfDefined<TOutputOut, inferParser<$Parser>['out']>,
207
+ TCaller
187
208
  >;
188
209
  /**
189
210
  * Add a meta data to the procedure.
@@ -198,7 +219,8 @@ export interface ProcedureBuilder<
198
219
  TInputIn,
199
220
  TInputOut,
200
221
  TOutputIn,
201
- TOutputOut
222
+ TOutputOut,
223
+ TCaller
202
224
  >;
203
225
  /**
204
226
  * Add a middleware to the procedure.
@@ -226,7 +248,8 @@ export interface ProcedureBuilder<
226
248
  TInputIn,
227
249
  TInputOut,
228
250
  TOutputIn,
229
- TOutputOut
251
+ TOutputOut,
252
+ TCaller
230
253
  >;
231
254
 
232
255
  /**
@@ -250,7 +273,8 @@ export interface ProcedureBuilder<
250
273
  $InputIn,
251
274
  $InputOut,
252
275
  $OutputIn,
253
- $OutputOut
276
+ $OutputOut,
277
+ TCaller
254
278
  >
255
279
  : TypeError<'Meta mismatch'>
256
280
  : TypeError<'Context mismatch'>,
@@ -261,7 +285,8 @@ export interface ProcedureBuilder<
261
285
  IntersectIfDefined<TInputIn, $InputIn>,
262
286
  IntersectIfDefined<TInputIn, $InputOut>,
263
287
  IntersectIfDefined<TOutputIn, $OutputIn>,
264
- IntersectIfDefined<TOutputOut, $OutputOut>
288
+ IntersectIfDefined<TOutputOut, $OutputOut>,
289
+ TCaller
265
290
  >;
266
291
  /**
267
292
  * Query procedure
@@ -276,10 +301,18 @@ export interface ProcedureBuilder<
276
301
  TOutputIn,
277
302
  $Output
278
303
  >,
279
- ): QueryProcedure<{
280
- input: DefaultValue<TInputIn, void>;
281
- output: DefaultValue<TOutputOut, $Output>;
282
- }>;
304
+ ): QueryProcedure<
305
+ TCaller extends true
306
+ ? {
307
+ experimental_caller: true;
308
+ input: DefaultValue<TInputIn, void>;
309
+ output: DefaultValue<TOutputOut, $Output>;
310
+ }
311
+ : {
312
+ input: DefaultValue<TInputIn, void>;
313
+ output: DefaultValue<TOutputOut, $Output>;
314
+ }
315
+ >;
283
316
 
284
317
  /**
285
318
  * Mutation procedure
@@ -294,10 +327,18 @@ export interface ProcedureBuilder<
294
327
  TOutputIn,
295
328
  $Output
296
329
  >,
297
- ): MutationProcedure<{
298
- input: DefaultValue<TInputIn, void>;
299
- output: DefaultValue<TOutputOut, $Output>;
300
- }>;
330
+ ): MutationProcedure<
331
+ TCaller extends true
332
+ ? {
333
+ experimental_caller: true;
334
+ input: DefaultValue<TInputIn, void>;
335
+ output: DefaultValue<TOutputOut, $Output>;
336
+ }
337
+ : {
338
+ input: DefaultValue<TInputIn, void>;
339
+ output: DefaultValue<TOutputOut, $Output>;
340
+ }
341
+ >;
301
342
 
302
343
  /**
303
344
  * Subscription procedure
@@ -312,10 +353,35 @@ export interface ProcedureBuilder<
312
353
  TOutputIn,
313
354
  $Output
314
355
  >,
315
- ): SubscriptionProcedure<{
316
- input: DefaultValue<TInputIn, void>;
317
- output: DefaultValue<TOutputOut, inferObservableValue<$Output>>;
318
- }>;
356
+ ): SubscriptionProcedure<
357
+ TCaller extends true
358
+ ? {
359
+ experimental_caller: true;
360
+ input: DefaultValue<TInputIn, void>;
361
+ output: DefaultValue<TOutputOut, inferObservableValue<$Output>>;
362
+ }
363
+ : {
364
+ input: DefaultValue<TInputIn, void>;
365
+ output: DefaultValue<TOutputOut, inferObservableValue<$Output>>;
366
+ }
367
+ >;
368
+
369
+ /**
370
+ * Overrides the way a procedure is invoked
371
+ * Do not use this unless you know what you're doing - this is an experimental API
372
+ */
373
+ experimental_caller(
374
+ caller: CallerOverride,
375
+ ): ProcedureBuilder<
376
+ TContext,
377
+ TMeta,
378
+ TContextOverrides,
379
+ TInputIn,
380
+ TInputOut,
381
+ TOutputIn,
382
+ TOutputOut,
383
+ true
384
+ >;
319
385
  /**
320
386
  * @internal
321
387
  */
@@ -350,7 +416,8 @@ export function createBuilder<TContext, TMeta>(
350
416
  UnsetMarker,
351
417
  UnsetMarker,
352
418
  UnsetMarker,
353
- UnsetMarker
419
+ UnsetMarker,
420
+ false
354
421
  > {
355
422
  const _def: AnyProcedureBuilderDef = {
356
423
  procedure: true,
@@ -412,6 +479,11 @@ export function createBuilder<TContext, TMeta>(
412
479
  resolver,
413
480
  ) as AnySubscriptionProcedure;
414
481
  },
482
+ experimental_caller(caller) {
483
+ return createNewBuilder(_def, {
484
+ caller,
485
+ }) as any;
486
+ },
415
487
  };
416
488
 
417
489
  return builder;
@@ -422,6 +494,7 @@ function createResolver(
422
494
  resolver: AnyResolver,
423
495
  ) {
424
496
  const finalBuilder = createNewBuilder(_def, {
497
+ type: _def.type,
425
498
  resolver,
426
499
  middlewares: [
427
500
  async function resolveMiddleware(opts) {
@@ -435,8 +508,21 @@ function createResolver(
435
508
  },
436
509
  ],
437
510
  });
511
+ const invoke = createProcedureCaller(finalBuilder._def);
512
+ const callerOverride = finalBuilder._def.caller;
513
+ if (!callerOverride) {
514
+ return invoke;
515
+ }
516
+ const callerWrapper = (...args: unknown[]) => {
517
+ return callerOverride({
518
+ args,
519
+ invoke,
520
+ _def: finalBuilder._def as unknown as AnyProcedure['_def'],
521
+ });
522
+ };
438
523
 
439
- return createProcedureCaller(finalBuilder._def);
524
+ callerWrapper._def = finalBuilder._def;
525
+ return callerWrapper;
440
526
  }
441
527
 
442
528
  /**
@@ -1,13 +1,17 @@
1
1
  import type { Observable } from '../observable';
2
2
  import { createRecursiveProxy } from './createProxy';
3
3
  import { defaultFormatter } from './error/formatter';
4
- import { TRPCError } from './error/TRPCError';
5
- import type { AnyProcedure, inferProcedureInput } from './procedure';
4
+ import { getTRPCErrorFromUnknown, TRPCError } from './error/TRPCError';
5
+ import type {
6
+ AnyProcedure,
7
+ ErrorHandlerOptions,
8
+ inferProcedureInput,
9
+ } from './procedure';
6
10
  import type { ProcedureCallOptions } from './procedureBuilder';
7
11
  import type { AnyRootTypes, RootConfig } from './rootConfig';
8
12
  import { defaultTransformer } from './transformer';
9
13
  import type { MaybePromise, ValueOf } from './types';
10
- import { mergeWithoutOverrides, omitPrototype } from './utils';
14
+ import { isFunction, mergeWithoutOverrides, omitPrototype } from './utils';
11
15
 
12
16
  export interface RouterRecord {
13
17
  [key: string]: AnyProcedure | RouterRecord;
@@ -32,6 +36,14 @@ export type DecorateRouterRecord<TRecord extends RouterRecord> = {
32
36
  : never;
33
37
  };
34
38
 
39
+ /**
40
+ * @internal
41
+ */
42
+
43
+ export type RouterCallerErrorHandler<TContext> = (
44
+ opts: ErrorHandlerOptions<TContext>,
45
+ ) => void;
46
+
35
47
  /**
36
48
  * @internal
37
49
  */
@@ -45,6 +57,9 @@ export type RouterCaller<
45
57
  * e.g. wrapped in `React.cache` to avoid unnecessary computations
46
58
  */
47
59
  ctx: TRoot['ctx'] | (() => MaybePromise<TRoot['ctx']>),
60
+ options?: {
61
+ onError?: RouterCallerErrorHandler<TRoot['ctx']>;
62
+ },
48
63
  ) => DecorateRouterRecord<TRecord>;
49
64
 
50
65
  export interface Router<
@@ -191,21 +206,9 @@ export function createRouterFactory<TRoot extends AnyRootTypes>(
191
206
  return {
192
207
  ...record,
193
208
  _def,
194
- createCaller(ctx: TRoot['ctx']) {
195
- const proxy = createRecursiveProxy(({ path, args }) => {
196
- const fullPath = path.join('.');
197
- const procedure = _def.procedures[fullPath] as AnyProcedure;
198
-
199
- return procedure({
200
- path: fullPath,
201
- getRawInput: async () => args[0],
202
- ctx,
203
- type: procedure._def.type,
204
- });
205
- });
206
-
207
- return proxy as ReturnType<RouterCaller<any, any>>;
208
- },
209
+ createCaller: createCallerFactory<TRoot>()({
210
+ _def,
211
+ }),
209
212
  };
210
213
  }
211
214
 
@@ -244,34 +247,44 @@ export function callProcedure(
244
247
 
245
248
  export function createCallerFactory<TRoot extends AnyRootTypes>() {
246
249
  return function createCallerInner<TRecord extends RouterRecord>(
247
- router: Router<TRoot, TRecord>,
250
+ router: Pick<Router<TRoot, TRecord>, '_def'>,
248
251
  ): RouterCaller<TRoot, TRecord> {
249
252
  const _def = router._def;
250
253
  type Context = TRoot['ctx'];
251
254
 
252
- return function createCaller(maybeContext) {
253
- const proxy = createRecursiveProxy(({ path, args }) => {
255
+ return function createCaller(
256
+ ctxOrCallback,
257
+ options?: {
258
+ onError?: RouterCallerErrorHandler<Context>;
259
+ },
260
+ ) {
261
+ const proxy = createRecursiveProxy(async ({ path, args }) => {
254
262
  const fullPath = path.join('.');
255
263
 
256
264
  const procedure = _def.procedures[fullPath] as AnyProcedure;
257
265
 
258
- const callProc = (ctx: Context) =>
259
- procedure({
266
+ let ctx: Context | undefined = undefined;
267
+ try {
268
+ ctx = isFunction(ctxOrCallback)
269
+ ? await Promise.resolve(ctxOrCallback())
270
+ : ctxOrCallback;
271
+
272
+ return await procedure({
260
273
  path: fullPath,
261
274
  getRawInput: async () => args[0],
262
275
  ctx,
263
276
  type: procedure._def.type,
264
277
  });
265
-
266
- if (typeof maybeContext === 'function') {
267
- const context = (maybeContext as () => MaybePromise<Context>)();
268
- if (context instanceof Promise) {
269
- return context.then(callProc);
270
- }
271
- return callProc(context);
278
+ } catch (cause) {
279
+ options?.onError?.({
280
+ ctx,
281
+ error: getTRPCErrorFromUnknown(cause),
282
+ input: args[0],
283
+ path: fullPath,
284
+ type: procedure._def.type,
285
+ });
286
+ throw cause;
272
287
  }
273
-
274
- return callProc(maybeContext);
275
288
  });
276
289
 
277
290
  return proxy as ReturnType<RouterCaller<any, any>>;
@@ -27,6 +27,11 @@ export function isObject(value: unknown): value is Record<string, unknown> {
27
27
  return !!value && !Array.isArray(value) && typeof value === 'object';
28
28
  }
29
29
 
30
+ type AnyFn = (...args: any[]) => unknown;
31
+ export function isFunction(fn: unknown): fn is AnyFn {
32
+ return typeof fn === 'function';
33
+ }
34
+
30
35
  /**
31
36
  * Create an object without inheriting anything from `Object.prototype`
32
37
  * @internal