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