@trpc/server 10.0.0-proxy-beta.24 → 10.0.0-proxy-beta.25

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 (46) hide show
  1. package/dist/adapters/aws-lambda/index.d.ts.map +1 -1
  2. package/dist/adapters/aws-lambda/index.js +3 -2
  3. package/dist/adapters/aws-lambda/index.mjs +3 -2
  4. package/dist/adapters/express.js +4 -3
  5. package/dist/adapters/express.mjs +4 -3
  6. package/dist/adapters/fastify/index.js +3 -2
  7. package/dist/adapters/fastify/index.mjs +3 -2
  8. package/dist/adapters/fetch/index.js +3 -2
  9. package/dist/adapters/fetch/index.mjs +3 -2
  10. package/dist/adapters/next.js +4 -3
  11. package/dist/adapters/next.mjs +4 -3
  12. package/dist/adapters/node-http/index.js +4 -3
  13. package/dist/adapters/node-http/index.mjs +4 -3
  14. package/dist/adapters/standalone.js +4 -3
  15. package/dist/adapters/standalone.mjs +4 -3
  16. package/dist/adapters/ws.js +3 -2
  17. package/dist/adapters/ws.mjs +2 -1
  18. package/dist/{transformTRPCResponse-23e99f82.mjs → config-287b8ea5.mjs} +28 -52
  19. package/dist/{transformTRPCResponse-92c79c47.js → config-7bd017ac.js} +28 -52
  20. package/dist/http/{internals/getHTTPStatusCode.d.ts → getHTTPStatusCode.d.ts} +2 -2
  21. package/dist/http/getHTTPStatusCode.d.ts.map +1 -0
  22. package/dist/http/index.d.ts +1 -0
  23. package/dist/http/index.d.ts.map +1 -1
  24. package/dist/http/index.js +17 -0
  25. package/dist/http/index.mjs +6 -0
  26. package/dist/index.d.ts +0 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +398 -400
  29. package/dist/index.mjs +389 -390
  30. package/dist/{nodeHTTPRequestHandler-bb607c2b.mjs → nodeHTTPRequestHandler-a3060966.mjs} +1 -1
  31. package/dist/{nodeHTTPRequestHandler-0e40a231.js → nodeHTTPRequestHandler-b1dc9f7c.js} +1 -1
  32. package/dist/{resolveHTTPResponse-9dff3dcc.mjs → resolveHTTPResponse-01a6f231.mjs} +2 -1
  33. package/dist/{resolveHTTPResponse-92daf326.js → resolveHTTPResponse-61271ba9.js} +4 -3
  34. package/dist/transformTRPCResponse-547a4702.mjs +25 -0
  35. package/dist/transformTRPCResponse-cc650f44.js +27 -0
  36. package/http/index.d.ts +1 -0
  37. package/http/index.js +1 -0
  38. package/package.json +12 -6
  39. package/src/adapters/aws-lambda/index.ts +2 -1
  40. package/src/core/router.ts +1 -1
  41. package/src/deprecated/router.ts +1 -1
  42. package/src/http/{internals/getHTTPStatusCode.ts → getHTTPStatusCode.ts} +3 -3
  43. package/src/http/index.ts +1 -0
  44. package/src/http/resolveHTTPResponse.ts +1 -1
  45. package/src/index.ts +0 -1
  46. package/dist/http/internals/getHTTPStatusCode.d.ts.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,125 +1,13 @@
1
- export { r as resolveHTTPResponse } from './resolveHTTPResponse-9dff3dcc.mjs';
2
- import { d as defaultFormatter, a as defaultTransformer, c as createRouterFactory, g as getDataTransformer$1, i as isServerDefault, b as getHTTPStatusCodeFromError } from './transformTRPCResponse-23e99f82.mjs';
3
- export { e as callProcedure, a as defaultTransformer, g as getDataTransformer, p as procedureTypes } from './transformTRPCResponse-23e99f82.mjs';
1
+ import { c as createRouterFactory, d as defaultFormatter, g as getHTTPStatusCodeFromError, a as defaultTransformer, b as getDataTransformer$1, i as isServerDefault } from './config-287b8ea5.mjs';
2
+ export { e as callProcedure, a as defaultTransformer, b as getDataTransformer, p as procedureTypes } from './config-287b8ea5.mjs';
4
3
  import { T as TRPCError, g as getCauseFromUnknown, a as getTRPCErrorFromUnknown } from './TRPCError-e99e7cbe.mjs';
5
4
  export { T as TRPCError } from './TRPCError-e99e7cbe.mjs';
6
5
  import { T as TRPC_ERROR_CODES_BY_KEY } from './codes-7d21f749.mjs';
7
6
  import { c as createFlatProxy } from './index-0332d528.mjs';
8
7
 
9
8
  /**
10
- * @internal
11
- */ // FIXME this should use RootConfig
12
- function createMiddlewareFactory() {
13
- return function createMiddleware(fn) {
14
- return fn;
15
- };
16
- }
17
- function isPlainObject(obj) {
18
- return obj && typeof obj === 'object' && !Array.isArray(obj);
19
- }
20
- /**
21
- * @internal
22
- * Please note, `trpc-openapi` uses this function.
23
- */ function createInputMiddleware(parse) {
24
- const inputMiddleware = async ({ next , rawInput , input , })=>{
25
- let parsedInput;
26
- try {
27
- parsedInput = await parse(rawInput);
28
- } catch (cause) {
29
- throw new TRPCError({
30
- code: 'BAD_REQUEST',
31
- cause: getCauseFromUnknown(cause)
32
- });
33
- }
34
- // Multiple input parsers
35
- const combinedInput = isPlainObject(input) && isPlainObject(parsedInput) ? {
36
- ...input,
37
- ...parsedInput
38
- } : parsedInput;
39
- // TODO fix this typing?
40
- return next({
41
- input: combinedInput
42
- });
43
- };
44
- inputMiddleware._type = 'input';
45
- return inputMiddleware;
46
- }
47
- /**
48
- * @internal
49
- */ function createOutputMiddleware(parse) {
50
- const outputMiddleware = async ({ next })=>{
51
- const result = await next();
52
- if (!result.ok) {
53
- // pass through failures without validating
54
- return result;
55
- }
56
- try {
57
- const data = await parse(result.data);
58
- return {
59
- ...result,
60
- data
61
- };
62
- } catch (cause) {
63
- throw new TRPCError({
64
- message: 'Output validation failed',
65
- code: 'INTERNAL_SERVER_ERROR',
66
- cause: getCauseFromUnknown(cause)
67
- });
68
- }
69
- };
70
- outputMiddleware._type = 'output';
71
- return outputMiddleware;
72
- }
73
-
74
- /**
75
- * Ensures there are no duplicate keys when building a procedure.
76
- */ function mergeWithoutOverrides(obj1, ...objs) {
77
- const newObj = Object.assign(Object.create(null), obj1);
78
- for (const overrides of objs){
79
- for(const key in overrides){
80
- if (key in newObj && newObj[key] !== overrides[key]) {
81
- throw new Error(`Duplicate key ${key}`);
82
- }
83
- newObj[key] = overrides[key];
84
- }
85
- }
86
- return newObj;
87
- }
88
-
89
- function mergeRouters(...routerList) {
90
- const record = mergeWithoutOverrides({}, ...routerList.map((r)=>r._def.record));
91
- const errorFormatter = routerList.reduce((currentErrorFormatter, nextRouter)=>{
92
- if (nextRouter._def._config.errorFormatter && nextRouter._def._config.errorFormatter !== defaultFormatter) {
93
- if (currentErrorFormatter !== defaultFormatter && currentErrorFormatter !== nextRouter._def._config.errorFormatter) {
94
- throw new Error('You seem to have several error formatters');
95
- }
96
- return nextRouter._def._config.errorFormatter;
97
- }
98
- return currentErrorFormatter;
99
- }, defaultFormatter);
100
- const transformer = routerList.reduce((prev, current)=>{
101
- if (current._def._config.transformer && current._def._config.transformer !== defaultTransformer) {
102
- if (prev !== defaultTransformer && prev !== current._def._config.transformer) {
103
- throw new Error('You seem to have several transformers');
104
- }
105
- return current._def._config.transformer;
106
- }
107
- return prev;
108
- }, defaultTransformer);
109
- const router = createRouterFactory({
110
- errorFormatter,
111
- transformer,
112
- isDev: routerList.some((r)=>r._def._config.isDev),
113
- allowOutsideOfServer: routerList.some((r)=>r._def._config.allowOutsideOfServer),
114
- isServer: routerList.some((r)=>r._def._config.isServer),
115
- $types: routerList[0]?._def._config.$types
116
- })(record);
117
- return router;
118
- }
119
-
120
- function mergeRoutersGeneric(...args) {
121
- return mergeRouters(...args);
122
- }
9
+ * @deprecated
10
+ */ const middlewareMarker$1 = 'middlewareMarker';
123
11
 
124
12
  function getParseFn$1(procedureParser) {
125
13
  const parser = procedureParser;
@@ -146,129 +34,61 @@ function getParseFn$1(procedureParser) {
146
34
  throw new Error('Could not find a validator fn');
147
35
  }
148
36
  /**
149
- * @deprecated only for backwards compat
150
37
  * @internal
151
- */ function getParseFnOrPassThrough(procedureParser) {
152
- if (!procedureParser) {
153
- return (v)=>v;
38
+ * @deprecated
39
+ */ class Procedure {
40
+ _def() {
41
+ return {
42
+ middlewares: this.middlewares,
43
+ resolver: this.resolver,
44
+ inputParser: this.inputParser,
45
+ outputParser: this.outputParser,
46
+ meta: this.meta
47
+ };
154
48
  }
155
- return getParseFn$1(procedureParser);
156
- }
157
-
158
- /**
159
- * @internal
160
- */ const middlewareMarker$1 = 'middlewareMarker';
161
-
162
- function createNewBuilder(def1, def2) {
163
- const { middlewares =[] , inputs , ...rest } = def2;
164
- // TODO: maybe have a fn here to warn about calls
165
- return createBuilder({
166
- ...mergeWithoutOverrides(def1, rest),
167
- inputs: [
168
- ...def1.inputs,
169
- ...inputs ?? []
170
- ],
171
- middlewares: [
172
- ...def1.middlewares,
173
- ...middlewares
174
- ]
175
- });
176
- }
177
- function createBuilder(initDef) {
178
- const _def = initDef || {
179
- inputs: [],
180
- middlewares: []
181
- };
182
- return {
183
- _def,
184
- input (input) {
185
- const parser = getParseFn$1(input);
186
- return createNewBuilder(_def, {
187
- inputs: [
188
- input
189
- ],
190
- middlewares: [
191
- createInputMiddleware(parser)
192
- ]
193
- });
194
- },
195
- output (output) {
196
- const parseOutput = getParseFn$1(output);
197
- return createNewBuilder(_def, {
198
- output,
199
- middlewares: [
200
- createOutputMiddleware(parseOutput)
201
- ]
202
- });
203
- },
204
- meta (meta) {
205
- return createNewBuilder(_def, {
206
- meta: meta
49
+ async parseInput(rawInput) {
50
+ try {
51
+ return await this.parseInputFn(rawInput);
52
+ } catch (cause) {
53
+ throw new TRPCError({
54
+ code: 'BAD_REQUEST',
55
+ cause: getCauseFromUnknown(cause)
207
56
  });
208
- },
209
- unstable_concat (builder) {
210
- return createNewBuilder(_def, builder._def);
211
- },
212
- use (middleware) {
213
- return createNewBuilder(_def, {
214
- middlewares: [
215
- middleware
216
- ]
57
+ }
58
+ }
59
+ async parseOutput(rawOutput) {
60
+ try {
61
+ return await this.parseOutputFn(rawOutput);
62
+ } catch (cause) {
63
+ throw new TRPCError({
64
+ code: 'INTERNAL_SERVER_ERROR',
65
+ cause: getCauseFromUnknown(cause),
66
+ message: 'Output validation failed'
217
67
  });
218
- },
219
- query (resolver) {
220
- return createResolver({
221
- ..._def,
222
- query: true
223
- }, resolver);
224
- },
225
- mutation (resolver) {
226
- return createResolver({
227
- ..._def,
228
- mutation: true
229
- }, resolver);
230
- },
231
- subscription (resolver) {
232
- return createResolver({
233
- ..._def,
234
- subscription: true
235
- }, resolver);
236
68
  }
237
- };
238
- }
239
- function createResolver(_def, resolver) {
240
- const finalBuilder = createNewBuilder(_def, {
241
- resolver,
242
- middlewares: [
243
- async function resolveMiddleware(opts) {
244
- const data = await resolver(opts);
69
+ }
70
+ /**
71
+ * Trigger middlewares in order, parse raw input, call resolver & parse raw output
72
+ * @internal
73
+ */ async call(opts) {
74
+ // wrap the actual resolver and treat as the last "middleware"
75
+ const middlewaresWithResolver = this.middlewares.concat([
76
+ async ({ ctx })=>{
77
+ const input = await this.parseInput(opts.rawInput);
78
+ const rawOutput = await this.resolver({
79
+ ...opts,
80
+ ctx,
81
+ input
82
+ });
83
+ const data = await this.parseOutput(rawOutput);
245
84
  return {
246
85
  marker: middlewareMarker$1,
247
86
  ok: true,
248
87
  data,
249
- ctx: opts.ctx
88
+ ctx
250
89
  };
251
90
  }
252
- ]
253
- });
254
- return createProcedureCaller(finalBuilder._def);
255
- }
256
- const codeblock = `
257
- If you want to call this function on the server, you do the following:
258
- This is a client-only function.
259
-
260
- const caller = appRouter.createCaller({
261
- /* ... your context */
262
- });
263
-
264
- const result = await caller.call('myProcedure', input);
265
- `.trim();
266
- function createProcedureCaller(_def) {
267
- const procedure = async function resolve(opts) {
268
- // is direct server-side call
269
- if (!opts || !('rawInput' in opts)) {
270
- throw new Error(codeblock);
271
- }
91
+ ]);
272
92
  // run the middlewares recursively with the resolver as the last one
273
93
  const callRecursive = async (callOpts = {
274
94
  index: 0,
@@ -276,28 +96,23 @@ function createProcedureCaller(_def) {
276
96
  })=>{
277
97
  try {
278
98
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
279
- const middleware = _def.middlewares[callOpts.index];
280
- const result = await middleware({
99
+ const result = await middlewaresWithResolver[callOpts.index]({
281
100
  ctx: callOpts.ctx,
282
101
  type: opts.type,
283
102
  path: opts.path,
284
103
  rawInput: opts.rawInput,
285
- meta: _def.meta,
286
- input: callOpts.input,
104
+ meta: this.meta,
287
105
  next: async (nextOpts)=>{
288
106
  return await callRecursive({
289
107
  index: callOpts.index + 1,
290
- ctx: nextOpts && 'ctx' in nextOpts ? {
291
- ...callOpts.ctx,
292
- ...nextOpts.ctx
293
- } : callOpts.ctx,
294
- input: nextOpts && 'input' in nextOpts ? nextOpts.input : callOpts.input
108
+ ctx: nextOpts ? nextOpts.ctx : callOpts.ctx
295
109
  });
296
110
  }
297
111
  });
298
112
  return result;
299
113
  } catch (cause) {
300
114
  return {
115
+ ctx: callOpts.ctx,
301
116
  ok: false,
302
117
  error: getTRPCErrorFromUnknown(cause),
303
118
  marker: middlewareMarker$1
@@ -317,79 +132,54 @@ function createProcedureCaller(_def) {
317
132
  throw result.error;
318
133
  }
319
134
  return result.data;
320
- };
321
- procedure._def = _def;
322
- procedure.meta = _def.meta;
323
- return procedure;
324
- }
325
-
326
- /**
327
- * TODO: This can be improved:
328
- * - We should be able to chain `.meta()`/`.context()` only once
329
- * - Simplify typings
330
- * - Doesn't need to be a class but it doesn't really hurt either
331
- */ class TRPCBuilder {
332
- context() {
333
- return new TRPCBuilder();
334
135
  }
335
- meta() {
336
- return new TRPCBuilder();
136
+ /**
137
+ * Create new procedure with passed middlewares
138
+ * @param middlewares
139
+ */ inheritMiddlewares(middlewares) {
140
+ const Constructor = this.constructor;
141
+ const instance = new Constructor({
142
+ middlewares: [
143
+ ...middlewares,
144
+ ...this.middlewares
145
+ ],
146
+ resolver: this.resolver,
147
+ inputParser: this.inputParser,
148
+ outputParser: this.outputParser,
149
+ meta: this.meta
150
+ });
151
+ return instance;
337
152
  }
338
- create(options) {
339
- return createTRPCInner()(options);
153
+ constructor(opts){
154
+ this.middlewares = opts.middlewares;
155
+ this.resolver = opts.resolver;
156
+ this.inputParser = opts.inputParser;
157
+ this.parseInputFn = getParseFn$1(this.inputParser);
158
+ this.outputParser = opts.outputParser;
159
+ this.parseOutputFn = getParseFn$1(this.outputParser);
160
+ this.meta = opts.meta;
340
161
  }
341
162
  }
342
- /**
343
- * Initialize tRPC - be done exactly once per backend
344
- */ const initTRPC = new TRPCBuilder();
345
- function createTRPCInner() {
346
- return function initTRPCInner(runtime) {
347
- const errorFormatter = runtime?.errorFormatter ?? defaultFormatter;
348
- const transformer = getDataTransformer$1(runtime?.transformer ?? defaultTransformer);
349
- const config = {
350
- transformer,
351
- isDev: runtime?.isDev ?? process.env.NODE_ENV !== 'production',
352
- allowOutsideOfServer: runtime?.allowOutsideOfServer ?? false,
353
- errorFormatter,
354
- isServer: runtime?.isServer ?? isServerDefault,
355
- /**
356
- * @internal
357
- */ $types: createFlatProxy((key)=>{
358
- throw new Error(`Tried to access "$types.${key}" which is not available at runtime`);
359
- })
360
- };
361
- {
362
- // Server check
363
- const isServer = runtime?.isServer ?? isServerDefault;
364
- if (!isServer && runtime?.allowOutsideOfServer !== true) {
365
- throw new Error(`You're trying to use @trpc/server in a non-server environment. This is not supported by default.`);
366
- }
163
+ function createProcedure(opts) {
164
+ const inputParser = 'input' in opts ? opts.input : (input)=>{
165
+ if (input != null) {
166
+ throw new TRPCError({
167
+ code: 'BAD_REQUEST',
168
+ message: 'No input expected'
169
+ });
367
170
  }
368
- return {
369
- /**
370
- * These are just types, they can't be used
371
- * @internal
372
- */ _config: config,
373
- /**
374
- * Builder object for creating procedures
375
- */ procedure: createBuilder(),
376
- /**
377
- * Create reusable middlewares
378
- */ middleware: createMiddlewareFactory(),
379
- /**
380
- * Create a router
381
- */ router: createRouterFactory(config),
382
- /**
383
- * Merge Routers
384
- */ mergeRouters: mergeRoutersGeneric
385
- };
171
+ return undefined;
386
172
  };
173
+ const outputParser = 'output' in opts && opts.output ? opts.output : (output)=>output;
174
+ return new Procedure({
175
+ inputParser: inputParser,
176
+ resolver: opts.resolve,
177
+ middlewares: [],
178
+ outputParser: outputParser,
179
+ meta: opts.meta
180
+ });
387
181
  }
388
182
 
389
- /**
390
- * @deprecated
391
- */ const middlewareMarker = 'middlewareMarker';
392
-
393
183
  function getParseFn(procedureParser) {
394
184
  const parser = procedureParser;
395
185
  if (typeof parser === 'function') {
@@ -415,61 +205,209 @@ function getParseFn(procedureParser) {
415
205
  throw new Error('Could not find a validator fn');
416
206
  }
417
207
  /**
208
+ * @deprecated only for backwards compat
418
209
  * @internal
419
- * @deprecated
420
- */ class Procedure {
421
- _def() {
422
- return {
423
- middlewares: this.middlewares,
424
- resolver: this.resolver,
425
- inputParser: this.inputParser,
426
- outputParser: this.outputParser,
427
- meta: this.meta
428
- };
210
+ */ function getParseFnOrPassThrough(procedureParser) {
211
+ if (!procedureParser) {
212
+ return (v)=>v;
429
213
  }
430
- async parseInput(rawInput) {
214
+ return getParseFn(procedureParser);
215
+ }
216
+
217
+ /**
218
+ * Ensures there are no duplicate keys when building a procedure.
219
+ */ function mergeWithoutOverrides(obj1, ...objs) {
220
+ const newObj = Object.assign(Object.create(null), obj1);
221
+ for (const overrides of objs){
222
+ for(const key in overrides){
223
+ if (key in newObj && newObj[key] !== overrides[key]) {
224
+ throw new Error(`Duplicate key ${key}`);
225
+ }
226
+ newObj[key] = overrides[key];
227
+ }
228
+ }
229
+ return newObj;
230
+ }
231
+
232
+ /**
233
+ * @internal
234
+ */ // FIXME this should use RootConfig
235
+ function createMiddlewareFactory() {
236
+ return function createMiddleware(fn) {
237
+ return fn;
238
+ };
239
+ }
240
+ function isPlainObject(obj) {
241
+ return obj && typeof obj === 'object' && !Array.isArray(obj);
242
+ }
243
+ /**
244
+ * @internal
245
+ * Please note, `trpc-openapi` uses this function.
246
+ */ function createInputMiddleware(parse) {
247
+ const inputMiddleware = async ({ next , rawInput , input , })=>{
248
+ let parsedInput;
431
249
  try {
432
- return await this.parseInputFn(rawInput);
250
+ parsedInput = await parse(rawInput);
433
251
  } catch (cause) {
434
252
  throw new TRPCError({
435
253
  code: 'BAD_REQUEST',
436
254
  cause: getCauseFromUnknown(cause)
437
255
  });
438
- }
439
- }
440
- async parseOutput(rawOutput) {
441
- try {
442
- return await this.parseOutputFn(rawOutput);
443
- } catch (cause) {
444
- throw new TRPCError({
445
- code: 'INTERNAL_SERVER_ERROR',
446
- cause: getCauseFromUnknown(cause),
447
- message: 'Output validation failed'
256
+ }
257
+ // Multiple input parsers
258
+ const combinedInput = isPlainObject(input) && isPlainObject(parsedInput) ? {
259
+ ...input,
260
+ ...parsedInput
261
+ } : parsedInput;
262
+ // TODO fix this typing?
263
+ return next({
264
+ input: combinedInput
265
+ });
266
+ };
267
+ inputMiddleware._type = 'input';
268
+ return inputMiddleware;
269
+ }
270
+ /**
271
+ * @internal
272
+ */ function createOutputMiddleware(parse) {
273
+ const outputMiddleware = async ({ next })=>{
274
+ const result = await next();
275
+ if (!result.ok) {
276
+ // pass through failures without validating
277
+ return result;
278
+ }
279
+ try {
280
+ const data = await parse(result.data);
281
+ return {
282
+ ...result,
283
+ data
284
+ };
285
+ } catch (cause) {
286
+ throw new TRPCError({
287
+ message: 'Output validation failed',
288
+ code: 'INTERNAL_SERVER_ERROR',
289
+ cause: getCauseFromUnknown(cause)
290
+ });
291
+ }
292
+ };
293
+ outputMiddleware._type = 'output';
294
+ return outputMiddleware;
295
+ }
296
+
297
+ /**
298
+ * @internal
299
+ */ const middlewareMarker = 'middlewareMarker';
300
+
301
+ function createNewBuilder(def1, def2) {
302
+ const { middlewares =[] , inputs , ...rest } = def2;
303
+ // TODO: maybe have a fn here to warn about calls
304
+ return createBuilder({
305
+ ...mergeWithoutOverrides(def1, rest),
306
+ inputs: [
307
+ ...def1.inputs,
308
+ ...inputs ?? []
309
+ ],
310
+ middlewares: [
311
+ ...def1.middlewares,
312
+ ...middlewares
313
+ ]
314
+ });
315
+ }
316
+ function createBuilder(initDef) {
317
+ const _def = initDef || {
318
+ inputs: [],
319
+ middlewares: []
320
+ };
321
+ return {
322
+ _def,
323
+ input (input) {
324
+ const parser = getParseFn(input);
325
+ return createNewBuilder(_def, {
326
+ inputs: [
327
+ input
328
+ ],
329
+ middlewares: [
330
+ createInputMiddleware(parser)
331
+ ]
332
+ });
333
+ },
334
+ output (output) {
335
+ const parseOutput = getParseFn(output);
336
+ return createNewBuilder(_def, {
337
+ output,
338
+ middlewares: [
339
+ createOutputMiddleware(parseOutput)
340
+ ]
341
+ });
342
+ },
343
+ meta (meta) {
344
+ return createNewBuilder(_def, {
345
+ meta: meta
346
+ });
347
+ },
348
+ unstable_concat (builder) {
349
+ return createNewBuilder(_def, builder._def);
350
+ },
351
+ use (middleware) {
352
+ return createNewBuilder(_def, {
353
+ middlewares: [
354
+ middleware
355
+ ]
448
356
  });
357
+ },
358
+ query (resolver) {
359
+ return createResolver({
360
+ ..._def,
361
+ query: true
362
+ }, resolver);
363
+ },
364
+ mutation (resolver) {
365
+ return createResolver({
366
+ ..._def,
367
+ mutation: true
368
+ }, resolver);
369
+ },
370
+ subscription (resolver) {
371
+ return createResolver({
372
+ ..._def,
373
+ subscription: true
374
+ }, resolver);
449
375
  }
450
- }
451
- /**
452
- * Trigger middlewares in order, parse raw input, call resolver & parse raw output
453
- * @internal
454
- */ async call(opts) {
455
- // wrap the actual resolver and treat as the last "middleware"
456
- const middlewaresWithResolver = this.middlewares.concat([
457
- async ({ ctx })=>{
458
- const input = await this.parseInput(opts.rawInput);
459
- const rawOutput = await this.resolver({
460
- ...opts,
461
- ctx,
462
- input
463
- });
464
- const data = await this.parseOutput(rawOutput);
376
+ };
377
+ }
378
+ function createResolver(_def, resolver) {
379
+ const finalBuilder = createNewBuilder(_def, {
380
+ resolver,
381
+ middlewares: [
382
+ async function resolveMiddleware(opts) {
383
+ const data = await resolver(opts);
465
384
  return {
466
385
  marker: middlewareMarker,
467
386
  ok: true,
468
387
  data,
469
- ctx
388
+ ctx: opts.ctx
470
389
  };
471
390
  }
472
- ]);
391
+ ]
392
+ });
393
+ return createProcedureCaller(finalBuilder._def);
394
+ }
395
+ const codeblock = `
396
+ If you want to call this function on the server, you do the following:
397
+ This is a client-only function.
398
+
399
+ const caller = appRouter.createCaller({
400
+ /* ... your context */
401
+ });
402
+
403
+ const result = await caller.call('myProcedure', input);
404
+ `.trim();
405
+ function createProcedureCaller(_def) {
406
+ const procedure = async function resolve(opts) {
407
+ // is direct server-side call
408
+ if (!opts || !('rawInput' in opts)) {
409
+ throw new Error(codeblock);
410
+ }
473
411
  // run the middlewares recursively with the resolver as the last one
474
412
  const callRecursive = async (callOpts = {
475
413
  index: 0,
@@ -477,23 +415,28 @@ function getParseFn(procedureParser) {
477
415
  })=>{
478
416
  try {
479
417
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
480
- const result = await middlewaresWithResolver[callOpts.index]({
418
+ const middleware = _def.middlewares[callOpts.index];
419
+ const result = await middleware({
481
420
  ctx: callOpts.ctx,
482
421
  type: opts.type,
483
422
  path: opts.path,
484
423
  rawInput: opts.rawInput,
485
- meta: this.meta,
424
+ meta: _def.meta,
425
+ input: callOpts.input,
486
426
  next: async (nextOpts)=>{
487
427
  return await callRecursive({
488
428
  index: callOpts.index + 1,
489
- ctx: nextOpts ? nextOpts.ctx : callOpts.ctx
429
+ ctx: nextOpts && 'ctx' in nextOpts ? {
430
+ ...callOpts.ctx,
431
+ ...nextOpts.ctx
432
+ } : callOpts.ctx,
433
+ input: nextOpts && 'input' in nextOpts ? nextOpts.input : callOpts.input
490
434
  });
491
435
  }
492
436
  });
493
437
  return result;
494
438
  } catch (cause) {
495
439
  return {
496
- ctx: callOpts.ctx,
497
440
  ok: false,
498
441
  error: getTRPCErrorFromUnknown(cause),
499
442
  marker: middlewareMarker
@@ -513,52 +456,10 @@ function getParseFn(procedureParser) {
513
456
  throw result.error;
514
457
  }
515
458
  return result.data;
516
- }
517
- /**
518
- * Create new procedure with passed middlewares
519
- * @param middlewares
520
- */ inheritMiddlewares(middlewares) {
521
- const Constructor = this.constructor;
522
- const instance = new Constructor({
523
- middlewares: [
524
- ...middlewares,
525
- ...this.middlewares
526
- ],
527
- resolver: this.resolver,
528
- inputParser: this.inputParser,
529
- outputParser: this.outputParser,
530
- meta: this.meta
531
- });
532
- return instance;
533
- }
534
- constructor(opts){
535
- this.middlewares = opts.middlewares;
536
- this.resolver = opts.resolver;
537
- this.inputParser = opts.inputParser;
538
- this.parseInputFn = getParseFn(this.inputParser);
539
- this.outputParser = opts.outputParser;
540
- this.parseOutputFn = getParseFn(this.outputParser);
541
- this.meta = opts.meta;
542
- }
543
- }
544
- function createProcedure(opts) {
545
- const inputParser = 'input' in opts ? opts.input : (input)=>{
546
- if (input != null) {
547
- throw new TRPCError({
548
- code: 'BAD_REQUEST',
549
- message: 'No input expected'
550
- });
551
- }
552
- return undefined;
553
459
  };
554
- const outputParser = 'output' in opts && opts.output ? opts.output : (output)=>output;
555
- return new Procedure({
556
- inputParser: inputParser,
557
- resolver: opts.resolve,
558
- middlewares: [],
559
- outputParser: outputParser,
560
- meta: opts.meta
561
- });
460
+ procedure._def = _def;
461
+ procedure.meta = _def.meta;
462
+ return procedure;
562
463
  }
563
464
 
564
465
  function migrateProcedure(oldProc, type) {
@@ -829,4 +730,102 @@ function safeObject(...args) {
829
730
  return new Router();
830
731
  }
831
732
 
733
+ function mergeRouters(...routerList) {
734
+ const record = mergeWithoutOverrides({}, ...routerList.map((r)=>r._def.record));
735
+ const errorFormatter = routerList.reduce((currentErrorFormatter, nextRouter)=>{
736
+ if (nextRouter._def._config.errorFormatter && nextRouter._def._config.errorFormatter !== defaultFormatter) {
737
+ if (currentErrorFormatter !== defaultFormatter && currentErrorFormatter !== nextRouter._def._config.errorFormatter) {
738
+ throw new Error('You seem to have several error formatters');
739
+ }
740
+ return nextRouter._def._config.errorFormatter;
741
+ }
742
+ return currentErrorFormatter;
743
+ }, defaultFormatter);
744
+ const transformer = routerList.reduce((prev, current)=>{
745
+ if (current._def._config.transformer && current._def._config.transformer !== defaultTransformer) {
746
+ if (prev !== defaultTransformer && prev !== current._def._config.transformer) {
747
+ throw new Error('You seem to have several transformers');
748
+ }
749
+ return current._def._config.transformer;
750
+ }
751
+ return prev;
752
+ }, defaultTransformer);
753
+ const router = createRouterFactory({
754
+ errorFormatter,
755
+ transformer,
756
+ isDev: routerList.some((r)=>r._def._config.isDev),
757
+ allowOutsideOfServer: routerList.some((r)=>r._def._config.allowOutsideOfServer),
758
+ isServer: routerList.some((r)=>r._def._config.isServer),
759
+ $types: routerList[0]?._def._config.$types
760
+ })(record);
761
+ return router;
762
+ }
763
+
764
+ function mergeRoutersGeneric(...args) {
765
+ return mergeRouters(...args);
766
+ }
767
+
768
+ /**
769
+ * TODO: This can be improved:
770
+ * - We should be able to chain `.meta()`/`.context()` only once
771
+ * - Simplify typings
772
+ * - Doesn't need to be a class but it doesn't really hurt either
773
+ */ class TRPCBuilder {
774
+ context() {
775
+ return new TRPCBuilder();
776
+ }
777
+ meta() {
778
+ return new TRPCBuilder();
779
+ }
780
+ create(options) {
781
+ return createTRPCInner()(options);
782
+ }
783
+ }
784
+ /**
785
+ * Initialize tRPC - be done exactly once per backend
786
+ */ const initTRPC = new TRPCBuilder();
787
+ function createTRPCInner() {
788
+ return function initTRPCInner(runtime) {
789
+ const errorFormatter = runtime?.errorFormatter ?? defaultFormatter;
790
+ const transformer = getDataTransformer$1(runtime?.transformer ?? defaultTransformer);
791
+ const config = {
792
+ transformer,
793
+ isDev: runtime?.isDev ?? process.env.NODE_ENV !== 'production',
794
+ allowOutsideOfServer: runtime?.allowOutsideOfServer ?? false,
795
+ errorFormatter,
796
+ isServer: runtime?.isServer ?? isServerDefault,
797
+ /**
798
+ * @internal
799
+ */ $types: createFlatProxy((key)=>{
800
+ throw new Error(`Tried to access "$types.${key}" which is not available at runtime`);
801
+ })
802
+ };
803
+ {
804
+ // Server check
805
+ const isServer = runtime?.isServer ?? isServerDefault;
806
+ if (!isServer && runtime?.allowOutsideOfServer !== true) {
807
+ throw new Error(`You're trying to use @trpc/server in a non-server environment. This is not supported by default.`);
808
+ }
809
+ }
810
+ return {
811
+ /**
812
+ * These are just types, they can't be used
813
+ * @internal
814
+ */ _config: config,
815
+ /**
816
+ * Builder object for creating procedures
817
+ */ procedure: createBuilder(),
818
+ /**
819
+ * Create reusable middlewares
820
+ */ middleware: createMiddlewareFactory(),
821
+ /**
822
+ * Create a router
823
+ */ router: createRouterFactory(config),
824
+ /**
825
+ * Merge Routers
826
+ */ mergeRouters: mergeRoutersGeneric
827
+ };
828
+ };
829
+ }
830
+
832
831
  export { createInputMiddleware, createOutputMiddleware, initTRPC, router };