@trpc/server 9.20.3 → 9.23.0

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 (101) hide show
  1. package/adapters/express/dist/trpc-server-adapters-express.cjs.dev.js +6 -6
  2. package/adapters/express/dist/trpc-server-adapters-express.cjs.prod.js +6 -6
  3. package/adapters/express/dist/trpc-server-adapters-express.esm.js +6 -6
  4. package/adapters/fastify/dist/trpc-server-adapters-fastify.cjs.dev.js +17 -10
  5. package/adapters/fastify/dist/trpc-server-adapters-fastify.cjs.prod.js +17 -10
  6. package/adapters/fastify/dist/trpc-server-adapters-fastify.esm.js +17 -10
  7. package/adapters/next/dist/trpc-server-adapters-next.cjs.dev.js +4 -4
  8. package/adapters/next/dist/trpc-server-adapters-next.cjs.prod.js +4 -4
  9. package/adapters/next/dist/trpc-server-adapters-next.esm.js +4 -4
  10. package/adapters/node-http/dist/trpc-server-adapters-node-http.cjs.dev.js +4 -4
  11. package/adapters/node-http/dist/trpc-server-adapters-node-http.cjs.prod.js +4 -4
  12. package/adapters/node-http/dist/trpc-server-adapters-node-http.esm.js +4 -4
  13. package/adapters/standalone/dist/trpc-server-adapters-standalone.cjs.dev.js +4 -4
  14. package/adapters/standalone/dist/trpc-server-adapters-standalone.cjs.prod.js +4 -4
  15. package/adapters/standalone/dist/trpc-server-adapters-standalone.esm.js +4 -4
  16. package/adapters/ws/dist/trpc-server-adapters-ws.cjs.dev.js +4 -4
  17. package/adapters/ws/dist/trpc-server-adapters-ws.cjs.prod.js +4 -4
  18. package/adapters/ws/dist/trpc-server-adapters-ws.esm.js +4 -4
  19. package/dist/{codes-33cef953.cjs.dev.js → codes-130e62df.cjs.dev.js} +2 -0
  20. package/dist/{codes-fe07bf82.esm.js → codes-5678cc97.esm.js} +2 -0
  21. package/dist/{codes-e0df67c4.cjs.prod.js → codes-aff770a3.cjs.prod.js} +2 -0
  22. package/dist/declarations/src/TRPCError.d.ts +1 -1
  23. package/dist/declarations/src/TRPCError.d.ts.map +1 -1
  24. package/dist/declarations/src/adapters/fastify/fastifyRequestHandler.d.ts +2 -2
  25. package/dist/declarations/src/adapters/fastify/fastifyRequestHandler.d.ts.map +1 -1
  26. package/dist/declarations/src/adapters/fastify/fastifyTRPCPlugin.d.ts +1 -1
  27. package/dist/declarations/src/adapters/fastify/fastifyTRPCPlugin.d.ts.map +1 -1
  28. package/dist/declarations/src/adapters/next.d.ts +1 -1
  29. package/dist/declarations/src/adapters/next.d.ts.map +1 -1
  30. package/dist/declarations/src/adapters/node-http/nodeHTTPRequestHandler.d.ts +1 -1
  31. package/dist/declarations/src/adapters/node-http/nodeHTTPRequestHandler.d.ts.map +1 -1
  32. package/dist/declarations/src/adapters/standalone.d.ts.map +1 -1
  33. package/dist/declarations/src/adapters/ws.d.ts.map +1 -1
  34. package/dist/declarations/src/deprecated/createHttpServer.d.ts +1 -1
  35. package/dist/declarations/src/deprecated/createHttpServer.d.ts.map +1 -1
  36. package/dist/declarations/src/deprecated/requestHandler.d.ts +1 -1
  37. package/dist/declarations/src/deprecated/requestHandler.d.ts.map +1 -1
  38. package/dist/declarations/src/http/internals/getHTTPStatusCode.d.ts +2 -1
  39. package/dist/declarations/src/http/internals/getHTTPStatusCode.d.ts.map +1 -1
  40. package/dist/declarations/src/http/internals/types.d.ts +1 -1
  41. package/dist/declarations/src/http/internals/types.d.ts.map +1 -1
  42. package/dist/declarations/src/http/resolveHTTPResponse.d.ts +2 -2
  43. package/dist/declarations/src/http/resolveHTTPResponse.d.ts.map +1 -1
  44. package/dist/declarations/src/internals/BaseHandlerOptions.d.ts +1 -1
  45. package/dist/declarations/src/internals/BaseHandlerOptions.d.ts.map +1 -1
  46. package/dist/declarations/src/internals/OnErrorFunction.d.ts +1 -1
  47. package/dist/declarations/src/internals/OnErrorFunction.d.ts.map +1 -1
  48. package/dist/declarations/src/internals/middlewares.d.ts +3 -2
  49. package/dist/declarations/src/internals/middlewares.d.ts.map +1 -1
  50. package/dist/declarations/src/internals/procedure.d.ts +47 -34
  51. package/dist/declarations/src/internals/procedure.d.ts.map +1 -1
  52. package/dist/declarations/src/router.d.ts +34 -30
  53. package/dist/declarations/src/router.d.ts.map +1 -1
  54. package/dist/declarations/src/rpc/codes.d.ts +2 -0
  55. package/dist/declarations/src/rpc/codes.d.ts.map +1 -1
  56. package/dist/declarations/src/types.d.ts +8 -0
  57. package/dist/declarations/src/types.d.ts.map +1 -1
  58. package/dist/{nodeHTTPRequestHandler-2cc444d8.cjs.dev.js → nodeHTTPRequestHandler-36ddaba2.cjs.dev.js} +2 -2
  59. package/dist/{nodeHTTPRequestHandler-d00c1126.esm.js → nodeHTTPRequestHandler-372a4a4f.esm.js} +2 -2
  60. package/dist/{nodeHTTPRequestHandler-8ddacc19.cjs.prod.js → nodeHTTPRequestHandler-91e7ca3d.cjs.prod.js} +2 -2
  61. package/dist/{resolveHTTPResponse-562c3d62.cjs.prod.js → resolveHTTPResponse-02e61299.cjs.prod.js} +3 -2
  62. package/dist/{resolveHTTPResponse-3867844c.cjs.dev.js → resolveHTTPResponse-55b2c9bd.cjs.dev.js} +3 -2
  63. package/dist/{resolveHTTPResponse-85f3f5df.esm.js → resolveHTTPResponse-ddb56677.esm.js} +3 -2
  64. package/dist/{subscription-fbda2888.esm.js → subscription-2ea469a3.esm.js} +2 -2
  65. package/dist/{subscription-c2e0bfbc.cjs.prod.js → subscription-7de48383.cjs.dev.js} +2 -2
  66. package/dist/{subscription-b8831081.cjs.dev.js → subscription-f03bec71.cjs.prod.js} +2 -2
  67. package/dist/{transformTRPCResponse-8248515e.cjs.dev.js → transformTRPCResponse-1e125b28.cjs.prod.js} +38 -38
  68. package/dist/{transformTRPCResponse-f73dc4a2.esm.js → transformTRPCResponse-45c225c3.esm.js} +38 -38
  69. package/dist/{transformTRPCResponse-dcbf66c5.cjs.prod.js → transformTRPCResponse-c654ea92.cjs.dev.js} +38 -38
  70. package/dist/trpc-server.cjs.dev.js +45 -19
  71. package/dist/trpc-server.cjs.prod.js +45 -19
  72. package/dist/trpc-server.esm.js +47 -21
  73. package/package.json +4 -4
  74. package/rpc/dist/trpc-server-rpc.cjs.dev.js +1 -1
  75. package/rpc/dist/trpc-server-rpc.cjs.prod.js +1 -1
  76. package/rpc/dist/trpc-server-rpc.esm.js +1 -1
  77. package/src/TRPCError.ts +1 -1
  78. package/src/adapters/express.ts +2 -2
  79. package/src/adapters/fastify/fastifyRequestHandler.ts +7 -8
  80. package/src/adapters/fastify/fastifyTRPCPlugin.ts +14 -6
  81. package/src/adapters/next.ts +6 -2
  82. package/src/adapters/node-http/internals/getPostBody.test.ts +2 -1
  83. package/src/adapters/node-http/nodeHTTPRequestHandler.ts +5 -5
  84. package/src/adapters/standalone.ts +1 -0
  85. package/src/adapters/ws.ts +4 -4
  86. package/src/deprecated/createHttpServer.ts +2 -2
  87. package/src/deprecated/requestHandler.ts +2 -2
  88. package/src/http/internals/getHTTPStatusCode.ts +2 -1
  89. package/src/http/internals/types.ts +2 -2
  90. package/src/http/resolveHTTPResponse.ts +3 -3
  91. package/src/internals/BaseHandlerOptions.ts +1 -1
  92. package/src/internals/OnErrorFunction.ts +1 -1
  93. package/src/internals/middlewares.ts +3 -2
  94. package/src/internals/procedure.ts +176 -68
  95. package/src/router.ts +172 -52
  96. package/src/rpc/codes.ts +1 -0
  97. package/src/subscription.ts +1 -1
  98. package/src/types.ts +7 -0
  99. package/ws/dist/trpc-server-ws.cjs.dev.js +2 -2
  100. package/ws/dist/trpc-server-ws.cjs.prod.js +2 -2
  101. package/ws/dist/trpc-server-ws.esm.js +2 -2
@@ -1,5 +1,5 @@
1
- import { ProcedureType } from '../router';
2
1
  import { TRPCError } from '../TRPCError';
2
+ import { ProcedureType } from '../router';
3
3
 
4
4
  export const middlewareMarker = Symbol('middlewareMarker');
5
5
  interface MiddlewareResultBase<TContext> {
@@ -27,11 +27,12 @@ export type MiddlewareResult<TContext> =
27
27
  | MiddlewareOKResult<TContext>
28
28
  | MiddlewareErrorResult<TContext>;
29
29
 
30
- export type MiddlewareFunction<TInputContext, TContext> = (opts: {
30
+ export type MiddlewareFunction<TInputContext, TContext, TMeta> = (opts: {
31
31
  ctx: TInputContext;
32
32
  type: ProcedureType;
33
33
  path: string;
34
34
  rawInput: unknown;
35
+ meta?: TMeta;
35
36
  next: {
36
37
  (): Promise<MiddlewareResult<TInputContext>>;
37
38
  <T>(opts: { ctx: T }): Promise<MiddlewareResult<T>>;
@@ -1,51 +1,56 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { TRPCError } from '../TRPCError';
2
3
  import { assertNotBrowser } from '../assertNotBrowser';
3
4
  import { ProcedureType } from '../router';
4
- import { TRPCError } from '../TRPCError';
5
+ import { InferLast } from '../types';
5
6
  import { getErrorFromUnknown } from './errors';
6
7
  import { MiddlewareFunction, middlewareMarker } from './middlewares';
7
8
  import { wrapCallSafe } from './wrapCallSafe';
9
+
8
10
  assertNotBrowser();
9
11
 
10
- export type ProcedureInputParserZodEsque<TInput, TParsedInput> = {
12
+ export type ProcedureParserZodEsque<TInput, TOutput> = {
11
13
  _input: TInput;
12
- _output: TParsedInput;
14
+ _output: TOutput;
13
15
  };
14
16
 
15
- export type ProcedureInputParserMyZodEsque<TInput> = {
16
- parse: (input: any) => TInput;
17
+ export type ProcedureParserMyZodEsque<T> = {
18
+ parse: (input: any) => T;
17
19
  };
18
20
 
19
- export type ProcedureInputParserSuperstructEsque<TInput> = {
20
- create: (input: unknown) => TInput;
21
+ export type ProcedureParserSuperstructEsque<T> = {
22
+ create: (input: unknown) => T;
21
23
  };
22
24
 
23
- export type ProcedureInputParserCustomValidatorEsque<TInput> = (
25
+ export type ProcedureParserCustomValidatorEsque<T> = (
24
26
  input: unknown,
25
- ) => TInput | Promise<TInput>;
27
+ ) => T | Promise<T>;
26
28
 
27
- export type ProcedureInputParserYupEsque<TInput> = {
28
- validateSync: (input: unknown) => TInput;
29
+ export type ProcedureParserYupEsque<T> = {
30
+ validateSync: (input: unknown) => T;
29
31
  };
30
- export type ProcedureInputParser<TInput> =
31
- | ProcedureInputParserYupEsque<TInput>
32
- | ProcedureInputParserSuperstructEsque<TInput>
33
- | ProcedureInputParserCustomValidatorEsque<TInput>
34
- | ProcedureInputParserMyZodEsque<TInput>;
35
32
 
36
- export type ProcedureInputParserWithInputOutput<TInput, TParsedInput> =
37
- ProcedureInputParserZodEsque<TInput, TParsedInput>;
33
+ export type ProcedureParserWithInputOutput<TInput, TOutput> =
34
+ ProcedureParserZodEsque<TInput, TOutput>;
38
35
 
39
- export type ProcedureResolver<TContext, TParsedInput, TOutput> = (opts: {
36
+ export type ProcedureParser<T> =
37
+ | ProcedureParserYupEsque<T>
38
+ | ProcedureParserSuperstructEsque<T>
39
+ | ProcedureParserCustomValidatorEsque<T>
40
+ | ProcedureParserMyZodEsque<T>;
41
+
42
+ export type ProcedureResolver<TContext, TInput, TOutput> = (opts: {
40
43
  ctx: TContext;
41
- input: TParsedInput;
44
+ input: TInput;
42
45
  type: ProcedureType;
43
46
  }) => Promise<TOutput> | TOutput;
44
47
 
45
- interface ProcedureOptions<TContext, TParsedInput, TOutput> {
46
- middlewares: Array<MiddlewareFunction<any, any>>;
47
- resolver: ProcedureResolver<TContext, TParsedInput, TOutput>;
48
- inputParser: ProcedureInputParser<TParsedInput>;
48
+ interface ProcedureOptions<TContext, TMeta, TInput, TOutput, TParsedOutput> {
49
+ middlewares: Array<MiddlewareFunction<any, any, any>>;
50
+ resolver: ProcedureResolver<TContext, TInput, TOutput>;
51
+ inputParser: ProcedureParser<TInput>;
52
+ outputParser: ProcedureParser<TParsedOutput>;
53
+ meta: TMeta;
49
54
  }
50
55
 
51
56
  /**
@@ -58,36 +63,33 @@ export interface ProcedureCallOptions<TContext> {
58
63
  type: ProcedureType;
59
64
  }
60
65
 
61
- type ParseFn<TParsedInput> = (
62
- value: unknown,
63
- ) => TParsedInput | Promise<TParsedInput>;
64
- function getParseFn<TParsedInput>(
65
- inputParser: ProcedureInputParser<TParsedInput>,
66
- ): ParseFn<TParsedInput> {
67
- const parser = inputParser as any;
66
+ type ParseFn<T> = (value: unknown) => T | Promise<T>;
67
+
68
+ function getParseFn<T>(procedureParser: ProcedureParser<T>): ParseFn<T> {
69
+ const parser = procedureParser as any;
68
70
 
69
71
  if (typeof parser === 'function') {
70
- // ProcedureInputParserCustomValidatorEsque
72
+ // ProcedureParserCustomValidatorEsque
71
73
  return parser;
72
74
  }
73
75
 
74
76
  if (typeof parser.parseAsync === 'function') {
75
- // ProcedureInputParserZodEsque
77
+ // ProcedureParserZodEsque
76
78
  return parser.parseAsync.bind(parser);
77
79
  }
78
80
 
79
81
  if (typeof parser.parse === 'function') {
80
- // ProcedureInputParserZodEsque
82
+ // ProcedureParserZodEsque
81
83
  return parser.parse.bind(parser);
82
84
  }
83
85
 
84
86
  if (typeof parser.validateSync === 'function') {
85
- // ProcedureInputParserYupEsque
87
+ // ProcedureParserYupEsque
86
88
  return parser.validateSync.bind(parser);
87
89
  }
88
90
 
89
91
  if (typeof parser.create === 'function') {
90
- // ProcedureInputParserSuperstructEsque
92
+ // ProcedureParserSuperstructEsque
91
93
  return parser.create.bind(parser);
92
94
  }
93
95
 
@@ -97,22 +99,45 @@ function getParseFn<TParsedInput>(
97
99
  /**
98
100
  * @internal
99
101
  */
100
- export class Procedure<TInputContext, TContext, TInput, TParsedInput, TOutput> {
101
- private middlewares: Readonly<Array<MiddlewareFunction<any, any>>>;
102
+ export class Procedure<
103
+ TInputContext,
104
+ TContext,
105
+ TMeta,
106
+ TInput,
107
+ TParsedInput,
108
+ TOutput,
109
+ TParsedOutput,
110
+ TFinalOutput = unknown extends TParsedOutput ? TOutput : TParsedOutput,
111
+ > {
112
+ private middlewares: Readonly<Array<MiddlewareFunction<any, any, any>>>;
102
113
  private resolver: ProcedureResolver<TContext, TParsedInput, TOutput>;
103
- private readonly inputParser: ProcedureInputParser<TParsedInput>;
104
- private parse: ParseFn<TParsedInput>;
114
+ private readonly inputParser: ProcedureParser<TParsedInput>;
115
+ private parseInputFn: ParseFn<TParsedInput>;
116
+ private readonly outputParser: ProcedureParser<TFinalOutput>;
117
+ private parseOutputFn: ParseFn<TFinalOutput>;
118
+ public readonly meta: TMeta;
105
119
 
106
- constructor(opts: ProcedureOptions<TContext, TParsedInput, TOutput>) {
120
+ constructor(
121
+ opts: ProcedureOptions<
122
+ TContext,
123
+ TMeta,
124
+ TParsedInput,
125
+ TOutput,
126
+ TFinalOutput
127
+ >,
128
+ ) {
107
129
  this.middlewares = opts.middlewares;
108
130
  this.resolver = opts.resolver;
109
131
  this.inputParser = opts.inputParser;
110
- this.parse = getParseFn(this.inputParser);
132
+ this.parseInputFn = getParseFn(this.inputParser);
133
+ this.outputParser = opts.outputParser;
134
+ this.parseOutputFn = getParseFn(this.outputParser);
135
+ this.meta = opts.meta;
111
136
  }
112
137
 
113
138
  private async parseInput(rawInput: unknown): Promise<TParsedInput> {
114
139
  try {
115
- return await this.parse(rawInput);
140
+ return await this.parseInputFn(rawInput);
116
141
  } catch (cause) {
117
142
  throw new TRPCError({
118
143
  code: 'BAD_REQUEST',
@@ -121,18 +146,35 @@ export class Procedure<TInputContext, TContext, TInput, TParsedInput, TOutput> {
121
146
  }
122
147
  }
123
148
 
149
+ private async parseOutput(rawOutput: TOutput): Promise<TFinalOutput> {
150
+ try {
151
+ return await this.parseOutputFn(rawOutput);
152
+ } catch (cause) {
153
+ throw new TRPCError({
154
+ code: 'INTERNAL_SERVER_ERROR',
155
+ cause,
156
+ message: 'Output validation failed',
157
+ });
158
+ }
159
+ }
160
+
124
161
  /**
125
- * Trigger middlewares in order, parse raw input & call resolver
162
+ * Trigger middlewares in order, parse raw input, call resolver & parse raw output
126
163
  * @internal
127
164
  */
128
165
  public async call(
129
166
  opts: ProcedureCallOptions<TInputContext>,
130
- ): Promise<TOutput> {
167
+ ): Promise<TFinalOutput> {
131
168
  // wrap the actual resolver and treat as the last "middleware"
132
169
  const middlewaresWithResolver = this.middlewares.concat([
133
170
  async ({ ctx }: { ctx: TContext }) => {
134
171
  const input = await this.parseInput(opts.rawInput);
135
- const data = await this.resolver({ ...opts, ctx, input });
172
+ const rawOutput = await this.resolver({
173
+ ...opts,
174
+ ctx,
175
+ input,
176
+ });
177
+ const data = await this.parseOutput(rawOutput);
136
178
  return {
137
179
  marker: middlewareMarker,
138
180
  ok: true,
@@ -151,6 +193,7 @@ export class Procedure<TInputContext, TContext, TInput, TParsedInput, TOutput> {
151
193
  type: opts.type,
152
194
  path: opts.path,
153
195
  rawInput: opts.rawInput,
196
+ meta: this.meta,
154
197
  next: nextFns[index + 1],
155
198
  }),
156
199
  );
@@ -178,7 +221,7 @@ export class Procedure<TInputContext, TContext, TInput, TParsedInput, TOutput> {
178
221
  throw result.error;
179
222
  }
180
223
 
181
- return result.data as TOutput;
224
+ return result.data as TFinalOutput;
182
225
  }
183
226
 
184
227
  /**
@@ -186,15 +229,25 @@ export class Procedure<TInputContext, TContext, TInput, TParsedInput, TOutput> {
186
229
  * @param middlewares
187
230
  */
188
231
  public inheritMiddlewares(
189
- middlewares: MiddlewareFunction<TInputContext, TContext>[],
232
+ middlewares: MiddlewareFunction<TInputContext, TContext, TMeta>[],
190
233
  ): this {
191
234
  const Constructor: {
192
- new (opts: ProcedureOptions<TContext, TParsedInput, TOutput>): Procedure<
235
+ new (
236
+ opts: ProcedureOptions<
237
+ TContext,
238
+ TMeta,
239
+ TParsedInput,
240
+ TOutput,
241
+ TFinalOutput
242
+ >,
243
+ ): Procedure<
193
244
  TInputContext,
194
245
  TContext,
246
+ TMeta,
195
247
  TInput,
196
248
  TParsedInput,
197
- TOutput
249
+ TOutput,
250
+ TParsedOutput
198
251
  >;
199
252
  } = (this as any).constructor;
200
253
 
@@ -202,48 +255,92 @@ export class Procedure<TInputContext, TContext, TInput, TParsedInput, TOutput> {
202
255
  middlewares: [...middlewares, ...this.middlewares],
203
256
  resolver: this.resolver,
204
257
  inputParser: this.inputParser,
258
+ outputParser: this.outputParser,
259
+ meta: this.meta,
205
260
  });
206
261
 
207
262
  return instance as any;
208
263
  }
209
264
  }
210
265
 
211
- export type CreateProcedureWithInput<TContext, TInput, TParsedInput, TOutput> =
212
- {
213
- input: ProcedureInputParser<TInput>;
214
- resolve: ProcedureResolver<TContext, TParsedInput, TOutput>;
215
- };
266
+ export type CreateProcedureWithInput<TContext, TMeta, TInput, TOutput> = {
267
+ input: ProcedureParser<TInput>;
268
+ output?: ProcedureParser<TOutput>;
269
+ meta?: TMeta;
270
+ resolve: ProcedureResolver<TContext, TInput, InferLast<TOutput>>;
271
+ };
272
+
216
273
  export type CreateProcedureWithInputOutputParser<
217
274
  TContext,
275
+ TMeta,
218
276
  TInput,
219
277
  TParsedInput,
220
278
  TOutput,
279
+ TParsedOutput,
221
280
  > = {
222
- input: ProcedureInputParserWithInputOutput<TInput, TParsedInput>;
223
- resolve: ProcedureResolver<TContext, TParsedInput, TOutput>;
281
+ input: ProcedureParserWithInputOutput<TInput, TParsedInput>;
282
+ output?: ProcedureParserWithInputOutput<TOutput, TParsedOutput>;
283
+ meta?: TMeta;
284
+ resolve: ProcedureResolver<TContext, TParsedInput, InferLast<TOutput>>;
224
285
  };
225
- export type CreateProcedureWithoutInput<TContext, TOutput> = {
226
- resolve: ProcedureResolver<TContext, undefined, TOutput>;
286
+
287
+ export type CreateProcedureWithoutInput<
288
+ TContext,
289
+ TMeta,
290
+ TOutput,
291
+ TParsedOutput,
292
+ > = {
293
+ output?:
294
+ | ProcedureParserWithInputOutput<TOutput, TParsedOutput>
295
+ | ProcedureParser<TOutput>;
296
+ meta?: TMeta;
297
+ resolve: ProcedureResolver<TContext, undefined, InferLast<TOutput>>;
227
298
  };
228
299
 
229
300
  export type CreateProcedureOptions<
230
301
  TContext,
302
+ TMeta = undefined,
231
303
  TInput = undefined,
232
304
  TParsedInput = undefined,
233
305
  TOutput = undefined,
306
+ TParsedOutput = undefined,
234
307
  > =
235
- | CreateProcedureWithInput<TContext, TInput, TParsedInput, TOutput>
236
308
  | CreateProcedureWithInputOutputParser<
237
309
  TContext,
310
+ TMeta,
238
311
  TInput,
239
312
  TParsedInput,
240
- TOutput
313
+ TOutput,
314
+ TParsedOutput
241
315
  >
242
- | CreateProcedureWithoutInput<TContext, TOutput>;
316
+ | CreateProcedureWithInput<TContext, TMeta, TInput, TOutput>
317
+ | CreateProcedureWithoutInput<TContext, TMeta, TOutput, TParsedOutput>;
243
318
 
244
- export function createProcedure<TContext, TInput, TParsedInput, TOutput>(
245
- opts: CreateProcedureOptions<TContext, TInput, TParsedInput, TOutput>,
246
- ): Procedure<unknown, TContext, TInput, TParsedInput, TOutput> {
319
+ export function createProcedure<
320
+ TContext,
321
+ TMeta,
322
+ TInput,
323
+ TParsedInput,
324
+ TOutput,
325
+ TParsedOutput,
326
+ >(
327
+ opts: CreateProcedureOptions<
328
+ TContext,
329
+ TMeta,
330
+ TInput,
331
+ TParsedInput,
332
+ TOutput,
333
+ TParsedOutput
334
+ >,
335
+ ): Procedure<
336
+ unknown,
337
+ TContext,
338
+ TMeta,
339
+ TInput,
340
+ TParsedInput,
341
+ TOutput,
342
+ TParsedOutput
343
+ > {
247
344
  const inputParser =
248
345
  'input' in opts
249
346
  ? opts.input
@@ -257,27 +354,38 @@ export function createProcedure<TContext, TInput, TParsedInput, TOutput>(
257
354
  return undefined;
258
355
  };
259
356
 
357
+ const outputParser =
358
+ 'output' in opts && opts.output
359
+ ? opts.output
360
+ : (output: unknown) => output as TOutput;
361
+
260
362
  return new Procedure({
261
363
  inputParser: inputParser as any,
262
364
  resolver: opts.resolve as any,
263
365
  middlewares: [],
366
+ outputParser: outputParser as any,
367
+ meta: opts.meta as any,
264
368
  });
265
369
  }
266
370
 
267
371
  export type inferProcedureFromOptions<
268
372
  TInputContext,
269
- TOptions extends CreateProcedureOptions<any, any, any, any>,
373
+ TOptions extends CreateProcedureOptions<any, any, any, any, any, any>,
270
374
  > = TOptions extends CreateProcedureOptions<
271
375
  infer TContext,
376
+ infer TMeta,
272
377
  infer TInput,
273
378
  infer TParsedInput,
274
- infer TOutput
379
+ infer TOutput,
380
+ infer TParsedOutput
275
381
  >
276
382
  ? Procedure<
277
383
  TInputContext,
278
384
  TContext,
385
+ TMeta,
279
386
  unknown extends TInput ? undefined : TInput,
280
387
  unknown extends TParsedInput ? undefined : TParsedInput,
281
- TOutput
388
+ TOutput,
389
+ TParsedOutput
282
390
  >
283
391
  : never;