@trpc/server 10.28.1 → 10.29.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 (97) hide show
  1. package/dist/adapters/aws-lambda/index.d.ts +1 -1
  2. package/dist/adapters/aws-lambda/index.d.ts.map +1 -1
  3. package/dist/adapters/aws-lambda/index.js +1 -1
  4. package/dist/adapters/aws-lambda/index.mjs +1 -1
  5. package/dist/adapters/aws-lambda/utils.d.ts +1 -1
  6. package/dist/adapters/aws-lambda/utils.d.ts.map +1 -1
  7. package/dist/adapters/express.d.ts.map +1 -1
  8. package/dist/adapters/express.js +5 -4
  9. package/dist/adapters/express.mjs +5 -4
  10. package/dist/adapters/fastify/fastifyRequestHandler.d.ts +1 -1
  11. package/dist/adapters/fastify/fastifyRequestHandler.d.ts.map +1 -1
  12. package/dist/adapters/fastify/index.js +50 -15
  13. package/dist/adapters/fastify/index.mjs +50 -15
  14. package/dist/adapters/fetch/fetchRequestHandler.d.ts.map +1 -1
  15. package/dist/adapters/fetch/index.js +66 -20
  16. package/dist/adapters/fetch/index.mjs +66 -20
  17. package/dist/adapters/lambda/index.d.ts +1 -1
  18. package/dist/adapters/lambda/index.d.ts.map +1 -1
  19. package/dist/adapters/next.d.ts.map +1 -1
  20. package/dist/adapters/next.js +3 -2
  21. package/dist/adapters/next.mjs +3 -2
  22. package/dist/adapters/node-http/content-type/form-data/index.js +19 -46
  23. package/dist/adapters/node-http/content-type/form-data/index.mjs +19 -40
  24. package/dist/adapters/node-http/content-type/form-data/streamSlice.d.ts +7 -3
  25. package/dist/adapters/node-http/content-type/form-data/streamSlice.d.ts.map +1 -1
  26. package/dist/adapters/node-http/index.js +5 -4
  27. package/dist/adapters/node-http/index.mjs +5 -4
  28. package/dist/adapters/node-http/nodeHTTPRequestHandler.d.ts.map +1 -1
  29. package/dist/adapters/standalone.js +5 -4
  30. package/dist/adapters/standalone.mjs +5 -4
  31. package/dist/batchStreamFormatter-2c1405a1.js +31 -0
  32. package/dist/batchStreamFormatter-93cdcdd4.js +32 -0
  33. package/dist/batchStreamFormatter-fc1ffb26.mjs +30 -0
  34. package/dist/core/initTRPC.d.ts.map +1 -1
  35. package/dist/core/internals/mergeRouters.d.ts.map +1 -1
  36. package/dist/core/internals/procedureBuilder.d.ts +1 -1
  37. package/dist/core/internals/procedureBuilder.d.ts.map +1 -1
  38. package/dist/core/router.d.ts +1 -1
  39. package/dist/core/router.d.ts.map +1 -1
  40. package/dist/deprecated/interop.d.ts.map +1 -1
  41. package/dist/deprecated/router.d.ts +3 -3
  42. package/dist/deprecated/router.d.ts.map +1 -1
  43. package/dist/error/formatter.d.ts +1 -1
  44. package/dist/error/formatter.d.ts.map +1 -1
  45. package/dist/http/batchStreamFormatter.d.ts +24 -0
  46. package/dist/http/batchStreamFormatter.d.ts.map +1 -0
  47. package/dist/http/getHTTPStatusCode.d.ts +1 -1
  48. package/dist/http/getHTTPStatusCode.d.ts.map +1 -1
  49. package/dist/http/index.d.ts +1 -0
  50. package/dist/http/index.d.ts.map +1 -1
  51. package/dist/http/index.js +3 -1
  52. package/dist/http/index.mjs +2 -1
  53. package/dist/http/internals/types.d.ts +8 -1
  54. package/dist/http/internals/types.d.ts.map +1 -1
  55. package/dist/http/resolveHTTPResponse.d.ts +36 -2
  56. package/dist/http/resolveHTTPResponse.d.ts.map +1 -1
  57. package/dist/internals/types.d.ts +1 -1
  58. package/dist/internals/types.d.ts.map +1 -1
  59. package/dist/{nodeHTTPRequestHandler-bd47641d.js → nodeHTTPRequestHandler-53b9fc2d.js} +44 -12
  60. package/dist/{nodeHTTPRequestHandler-0f979796.mjs → nodeHTTPRequestHandler-bdad2781.mjs} +42 -13
  61. package/dist/{nodeHTTPRequestHandler-5bbf93f1.js → nodeHTTPRequestHandler-e637755a.js} +42 -13
  62. package/dist/resolveHTTPResponse-2bdf2cd7.js +256 -0
  63. package/dist/resolveHTTPResponse-2c307e04.js +284 -0
  64. package/dist/resolveHTTPResponse-a9be3d96.mjs +282 -0
  65. package/dist/subscription.d.ts.map +1 -1
  66. package/package.json +4 -4
  67. package/src/adapters/aws-lambda/index.ts +2 -2
  68. package/src/adapters/aws-lambda/utils.ts +1 -1
  69. package/src/adapters/express.ts +1 -1
  70. package/src/adapters/fastify/fastifyRequestHandler.ts +64 -17
  71. package/src/adapters/fastify/fastifyTRPCPlugin.ts +1 -1
  72. package/src/adapters/fetch/fetchRequestHandler.ts +72 -25
  73. package/src/adapters/lambda/index.ts +1 -1
  74. package/src/adapters/next.ts +1 -1
  75. package/src/adapters/node-http/content-type/form-data/fileUploadHandler.ts +1 -1
  76. package/src/adapters/node-http/content-type/form-data/index.ts +1 -1
  77. package/src/adapters/node-http/content-type/form-data/streamSlice.ts +19 -21
  78. package/src/adapters/node-http/nodeHTTPRequestHandler.ts +51 -12
  79. package/src/adapters/ws.ts +3 -3
  80. package/src/core/initTRPC.ts +2 -2
  81. package/src/core/internals/mergeRouters.ts +1 -1
  82. package/src/core/internals/procedureBuilder.ts +5 -5
  83. package/src/core/router.ts +2 -2
  84. package/src/deprecated/internals/procedure.ts +2 -2
  85. package/src/deprecated/interop.ts +1 -1
  86. package/src/deprecated/router.ts +6 -6
  87. package/src/error/formatter.ts +1 -1
  88. package/src/http/batchStreamFormatter.ts +29 -0
  89. package/src/http/getHTTPStatusCode.ts +1 -1
  90. package/src/http/index.ts +1 -0
  91. package/src/http/internals/types.ts +9 -1
  92. package/src/http/resolveHTTPResponse.ts +337 -126
  93. package/src/internals/types.ts +1 -1
  94. package/src/subscription.ts +1 -1
  95. package/dist/resolveHTTPResponse-4e576698.mjs +0 -174
  96. package/dist/resolveHTTPResponse-9523b4e3.js +0 -176
  97. package/dist/resolveHTTPResponse-ba557d3e.js +0 -166
@@ -1,12 +1,11 @@
1
- /* eslint-disable @typescript-eslint/no-non-null-assertion */
2
1
  import {
3
2
  AnyRouter,
4
- ProcedureType,
5
3
  callProcedure,
6
4
  inferRouterContext,
7
5
  inferRouterError,
6
+ ProcedureType,
8
7
  } from '../core';
9
- import { TRPCError, getTRPCErrorFromUnknown } from '../error/TRPCError';
8
+ import { getTRPCErrorFromUnknown, TRPCError } from '../error/TRPCError';
10
9
  import { TRPCResponse } from '../rpc';
11
10
  import { getErrorShape } from '../shared/getErrorShape';
12
11
  import { transformTRPCResponse } from '../shared/transformTRPCResponse';
@@ -16,7 +15,7 @@ import {
16
15
  getJsonContentTypeInputs,
17
16
  } from './contentType';
18
17
  import { getHTTPStatusCode } from './getHTTPStatusCode';
19
- import { HTTPHeaders, HTTPResponse } from './internals/types';
18
+ import { HTTPHeaders, HTTPResponse, ResponseChunk } from './internals/types';
20
19
  import { HTTPBaseHandlerOptions, HTTPRequest } from './types';
21
20
 
22
21
  const HTTP_METHOD_PROCEDURE_TYPE_MAP: Record<
@@ -31,6 +30,12 @@ const fallbackContentTypeHandler = {
31
30
  getInputs: getJsonContentTypeInputs,
32
31
  };
33
32
 
33
+ type PartialBy<TBaseType, TKey extends keyof TBaseType> = Omit<
34
+ TBaseType,
35
+ TKey
36
+ > &
37
+ Partial<Pick<TBaseType, TKey>>;
38
+
34
39
  interface ResolveHTTPRequestOptions<
35
40
  TRouter extends AnyRouter,
36
41
  TRequest extends HTTPRequest,
@@ -41,72 +46,241 @@ interface ResolveHTTPRequestOptions<
41
46
  error?: Maybe<TRPCError>;
42
47
  contentTypeHandler?: BaseContentTypeHandler<any>;
43
48
  preprocessedBody?: boolean;
49
+ /**
50
+ * Called as soon as the response head is known,
51
+ * with headers that were generated **without** knowing the response body.
52
+ *
53
+ * Without this callback, streaming is disabled.
54
+ */
55
+ onHead: (headResponse: Omit<HTTPResponse, 'body'>) => void;
56
+ /**
57
+ * Called for every procedure with `[index, result]`.
58
+ *
59
+ * Will be called a single time with `index = -1` if
60
+ * - response is an error
61
+ * - response is empty (HEAD request)
62
+ *
63
+ * Without this callback, streaming is disabled.
64
+ */
65
+ onChunk: (chunk: ResponseChunk) => void;
44
66
  }
45
67
 
46
- export async function resolveHTTPResponse<
68
+ function initResponse<
47
69
  TRouter extends AnyRouter,
48
70
  TRequest extends HTTPRequest,
49
- >(opts: ResolveHTTPRequestOptions<TRouter, TRequest>): Promise<HTTPResponse> {
50
- const { router, req } = opts;
51
- const contentTypeHandler =
52
- opts.contentTypeHandler ?? fallbackContentTypeHandler;
71
+ >(initOpts: {
72
+ ctx: inferRouterContext<TRouter> | undefined;
73
+ paths: string[] | undefined;
74
+ type: ProcedureType | 'unknown';
75
+ responseMeta?: HTTPBaseHandlerOptions<TRouter, TRequest>['responseMeta'];
76
+ untransformedJSON?:
77
+ | TRPCResponse<unknown, inferRouterError<TRouter>>
78
+ | TRPCResponse<unknown, inferRouterError<TRouter>>[]
79
+ | undefined;
80
+ errors?: TRPCError[];
81
+ }): HTTPResponse {
82
+ const {
83
+ ctx,
84
+ paths,
85
+ type,
86
+ responseMeta,
87
+ untransformedJSON,
88
+ errors = [],
89
+ } = initOpts;
53
90
 
54
- const batchingEnabled = opts.batching?.enabled ?? true;
55
- if (req.method === 'HEAD') {
56
- // can be used for lambda warmup
57
- return {
58
- status: 204,
59
- };
91
+ let status = untransformedJSON ? getHTTPStatusCode(untransformedJSON) : 200;
92
+ const headers: HTTPHeaders = {
93
+ 'Content-Type': 'application/json',
94
+ };
95
+
96
+ const eagerGeneration = !untransformedJSON;
97
+ const data = eagerGeneration
98
+ ? []
99
+ : Array.isArray(untransformedJSON)
100
+ ? untransformedJSON
101
+ : [untransformedJSON];
102
+
103
+ const meta =
104
+ responseMeta?.({
105
+ ctx,
106
+ paths,
107
+ type,
108
+ data,
109
+ errors,
110
+ eagerGeneration,
111
+ }) ?? {};
112
+
113
+ for (const [key, value] of Object.entries(meta.headers ?? {})) {
114
+ headers[key] = value;
115
+ }
116
+ if (meta.status) {
117
+ status = meta.status;
60
118
  }
61
- const type =
62
- HTTP_METHOD_PROCEDURE_TYPE_MAP[req.method] ?? ('unknown' as const);
63
- let ctx: inferRouterContext<TRouter> | undefined = undefined;
64
- let paths: string[] | undefined = undefined;
65
119
 
66
- const isBatchCall = !!req.query.get('batch');
67
- type TRouterError = inferRouterError<TRouter>;
68
- type TRouterResponse = TRPCResponse<unknown, TRouterError>;
69
-
70
- function endResponse(
71
- untransformedJSON: TRouterResponse | TRouterResponse[],
72
- errors: TRPCError[],
73
- ): HTTPResponse {
74
- let status = getHTTPStatusCode(untransformedJSON);
75
- const headers: HTTPHeaders = {
76
- 'Content-Type': 'application/json',
120
+ return {
121
+ status,
122
+ headers,
123
+ };
124
+ }
125
+
126
+ async function inputToProcedureCall<
127
+ TRouter extends AnyRouter,
128
+ TRequest extends HTTPRequest,
129
+ >(procedureOpts: {
130
+ opts: Pick<
131
+ ResolveHTTPRequestOptions<TRouter, TRequest>,
132
+ 'router' | 'onError' | 'req'
133
+ >;
134
+ ctx: inferRouterContext<TRouter> | undefined;
135
+ type: 'query' | 'mutation';
136
+ input: unknown;
137
+ path: string;
138
+ }): Promise<TRPCResponse<unknown, inferRouterError<TRouter>>> {
139
+ const { opts, ctx, type, input, path } = procedureOpts;
140
+ try {
141
+ const data = await callProcedure({
142
+ procedures: opts.router._def.procedures,
143
+ path,
144
+ rawInput: input,
145
+ ctx,
146
+ type,
147
+ });
148
+ return {
149
+ result: {
150
+ data,
151
+ },
77
152
  };
153
+ } catch (cause) {
154
+ const error = getTRPCErrorFromUnknown(cause);
78
155
 
79
- const meta =
80
- opts.responseMeta?.({
81
- ctx,
82
- paths,
156
+ opts.onError?.({ error, path, input, ctx, type: type, req: opts.req });
157
+
158
+ return {
159
+ error: getErrorShape({
160
+ config: opts.router._def._config,
161
+ error,
83
162
  type,
84
- data: Array.isArray(untransformedJSON)
85
- ? untransformedJSON
86
- : [untransformedJSON],
87
- errors,
88
- }) ?? {};
163
+ path,
164
+ input,
165
+ ctx,
166
+ }),
167
+ };
168
+ }
169
+ }
89
170
 
90
- for (const [key, value] of Object.entries(meta.headers ?? {})) {
91
- headers[key] = value;
92
- }
93
- if (meta.status) {
94
- status = meta.status;
95
- }
171
+ function caughtErrorToData<
172
+ TRouter extends AnyRouter,
173
+ TRequest extends HTTPRequest,
174
+ >(
175
+ cause: unknown,
176
+ errorOpts: {
177
+ opts: Pick<
178
+ ResolveHTTPRequestOptions<TRouter, TRequest>,
179
+ 'router' | 'onError' | 'req'
180
+ >;
181
+ ctx: inferRouterContext<TRouter> | undefined;
182
+ type: ProcedureType | 'unknown';
183
+ path?: string;
184
+ input?: unknown;
185
+ },
186
+ ) {
187
+ const { router, req, onError } = errorOpts.opts;
188
+ const error = getTRPCErrorFromUnknown(cause);
189
+ onError?.({
190
+ error,
191
+ path: errorOpts.path,
192
+ input: errorOpts.input,
193
+ ctx: errorOpts.ctx,
194
+ type: errorOpts.type,
195
+ req,
196
+ });
197
+ const untransformedJSON = {
198
+ error: getErrorShape({
199
+ config: router._def._config,
200
+ error,
201
+ type: errorOpts.type,
202
+ path: errorOpts.path,
203
+ input: errorOpts.input,
204
+ ctx: errorOpts.ctx,
205
+ }),
206
+ };
207
+ const transformedJSON = transformTRPCResponse(
208
+ router._def._config,
209
+ untransformedJSON,
210
+ );
211
+ const body = JSON.stringify(transformedJSON);
212
+ return {
213
+ error,
214
+ untransformedJSON,
215
+ body,
216
+ };
217
+ }
96
218
 
97
- const transformedJSON = transformTRPCResponse(
98
- router._def._config,
99
- untransformedJSON,
100
- );
219
+ /**
220
+ * Since `resolveHTTPResponse` is a public API (community adapters),
221
+ * let's give it a strong type signature to increase discoverability.
222
+ */
101
223
 
102
- const body = JSON.stringify(transformedJSON);
224
+ /**
225
+ * Non-streaming signature for `resolveHTTPResponse`:
226
+ * @param opts.onHead `undefined`
227
+ * @param opts.onChunk `undefined`
228
+ * @returns `Promise<HTTPResponse>`
229
+ */
230
+ export async function resolveHTTPResponse<
231
+ TRouter extends AnyRouter,
232
+ TRequest extends HTTPRequest,
233
+ >(
234
+ opts: Omit<
235
+ ResolveHTTPRequestOptions<TRouter, TRequest>,
236
+ 'onHead' | 'onChunk'
237
+ >,
238
+ ): Promise<HTTPResponse>;
239
+ /**
240
+ * Streaming signature for `resolveHTTPResponse`:
241
+ * @param opts.onHead called as soon as the response head is known
242
+ * @param opts.onChunk called for every procedure with `[index, result]`
243
+ * @returns `Promise<void>` since the response is streamed
244
+ */
245
+ export async function resolveHTTPResponse<
246
+ TRouter extends AnyRouter,
247
+ TRequest extends HTTPRequest,
248
+ >(opts: ResolveHTTPRequestOptions<TRouter, TRequest>): Promise<void>;
249
+ // implementation
250
+ export async function resolveHTTPResponse<
251
+ TRouter extends AnyRouter,
252
+ TRequest extends HTTPRequest,
253
+ >(
254
+ opts: PartialBy<
255
+ ResolveHTTPRequestOptions<TRouter, TRequest>,
256
+ 'onHead' | 'onChunk'
257
+ >,
258
+ ): Promise<HTTPResponse | void> {
259
+ const { router, req, onHead, onChunk } = opts;
103
260
 
104
- return {
105
- body,
106
- status,
107
- headers,
261
+ if (req.method === 'HEAD') {
262
+ // can be used for lambda warmup
263
+ const headResponse: HTTPResponse = {
264
+ status: 204,
108
265
  };
266
+ onHead?.(headResponse);
267
+ onChunk?.([-1, '']);
268
+ return headResponse;
109
269
  }
270
+ const contentTypeHandler =
271
+ opts.contentTypeHandler ?? fallbackContentTypeHandler;
272
+ const batchingEnabled = opts.batching?.enabled ?? true;
273
+ const type =
274
+ HTTP_METHOD_PROCEDURE_TYPE_MAP[req.method] ?? ('unknown' as const);
275
+ let ctx: inferRouterContext<TRouter> | undefined = undefined;
276
+ let paths: string[] | undefined;
277
+
278
+ const isBatchCall = !!req.query.get('batch');
279
+ const isStreamCall =
280
+ isBatchCall &&
281
+ onHead &&
282
+ onChunk &&
283
+ req.headers['trpc-batch-mode'] === 'stream';
110
284
 
111
285
  try {
112
286
  if (opts.error) {
@@ -138,91 +312,128 @@ export async function resolveHTTPResponse<
138
312
 
139
313
  paths = isBatchCall ? opts.path.split(',') : [opts.path];
140
314
  ctx = await opts.createContext();
315
+ const promises = paths.map((path, index) =>
316
+ inputToProcedureCall({ opts, ctx, type, input: inputs[index], path }),
317
+ );
141
318
 
142
- const rawResults = await Promise.all(
143
- paths.map(async (path, index) => {
144
- const input = inputs[index];
319
+ if (!isStreamCall) {
320
+ /**
321
+ * Non-streaming response:
322
+ * - await all responses in parallel, blocking on the slowest one
323
+ * - create headers with known response body
324
+ * - return a complete HTTPResponse
325
+ */
145
326
 
146
- try {
147
- const output = await callProcedure({
148
- procedures: router._def.procedures,
149
- path,
150
- rawInput: input,
151
- ctx,
152
- type,
153
- });
154
- return {
155
- input,
156
- path,
157
- data: output,
158
- };
159
- } catch (cause) {
160
- const error = getTRPCErrorFromUnknown(cause);
161
-
162
- opts.onError?.({ error, path, input, ctx, type: type, req });
163
- return {
164
- input,
165
- path,
166
- error,
167
- };
168
- }
169
- }),
170
- );
171
- const errors = rawResults.flatMap((obj) => (obj.error ? [obj.error] : []));
172
- const resultEnvelopes = rawResults.map((obj): TRouterResponse => {
173
- const { path, input } = obj;
174
-
175
- if (obj.error) {
176
- return {
177
- error: getErrorShape({
178
- config: router._def._config,
179
- error: obj.error,
180
- type,
181
- path,
182
- input,
183
- ctx,
184
- }),
185
- };
186
- } else {
187
- return {
188
- result: {
189
- data: obj.data,
190
- },
191
- };
192
- }
327
+ const untransformedJSON = await Promise.all(promises);
328
+ const errors = untransformedJSON.flatMap((response) =>
329
+ 'error' in response ? [response.error] : [],
330
+ );
331
+
332
+ const headResponse = initResponse({
333
+ ctx,
334
+ paths,
335
+ type,
336
+ responseMeta: opts.responseMeta,
337
+ untransformedJSON,
338
+ errors,
339
+ });
340
+ onHead?.(headResponse);
341
+
342
+ // return body stuff
343
+ const result = isBatchCall ? untransformedJSON : untransformedJSON[0]!; // eslint-disable-line @typescript-eslint/no-non-null-assertion -- `untransformedJSON` should be the length of `paths` which should be at least 1 otherwise there wouldn't be a request at all
344
+ const transformedJSON = transformTRPCResponse(
345
+ router._def._config,
346
+ result,
347
+ );
348
+ const body = JSON.stringify(transformedJSON);
349
+ onChunk?.([-1, body]);
350
+
351
+ return {
352
+ status: headResponse.status,
353
+ headers: headResponse.headers,
354
+ body,
355
+ };
356
+ }
357
+
358
+ /**
359
+ * Streaming response:
360
+ * - block on none, call `onChunk` as soon as each response is ready
361
+ * - create headers with minimal data (cannot know the response body in advance)
362
+ * - return void
363
+ */
364
+ const headResponse = initResponse({
365
+ ctx,
366
+ paths,
367
+ type,
368
+ responseMeta: opts.responseMeta,
193
369
  });
370
+ onHead(headResponse);
371
+
372
+ const indexedPromises = new Map(
373
+ promises.map((promise, index) => [
374
+ index,
375
+ promise.then((r) => [index, r] as const),
376
+ ]),
377
+ );
378
+ for (let i = 0; i < paths.length; i++) {
379
+ const [index, untransformedJSON] = await Promise.race(
380
+ indexedPromises.values(),
381
+ );
382
+ indexedPromises.delete(index);
383
+
384
+ try {
385
+ const transformedJSON = transformTRPCResponse(
386
+ router._def._config,
387
+ untransformedJSON,
388
+ );
389
+ const body = JSON.stringify(transformedJSON);
194
390
 
195
- const result = isBatchCall ? resultEnvelopes : resultEnvelopes[0]!;
196
- return endResponse(result, errors);
391
+ onChunk([index, body]);
392
+ } catch (cause) {
393
+ const path = paths[index];
394
+ const input = inputs[index];
395
+ const { body } = caughtErrorToData(cause, {
396
+ opts,
397
+ ctx,
398
+ type,
399
+ path,
400
+ input,
401
+ });
402
+
403
+ onChunk([index, body]);
404
+ }
405
+ }
406
+ return;
197
407
  } catch (cause) {
198
408
  // we get here if
199
409
  // - batching is called when it's not enabled
200
410
  // - `createContext()` throws
411
+ // - `router._def._config.transformer.output.serialize()` throws
201
412
  // - post body is too large
202
413
  // - input deserialization fails
203
414
  // - `errorFormatter` return value is malformed
204
- const error = getTRPCErrorFromUnknown(cause);
415
+ const { error, untransformedJSON, body } = caughtErrorToData(cause, {
416
+ opts,
417
+ ctx,
418
+ type,
419
+ });
205
420
 
206
- opts.onError?.({
207
- error,
208
- path: undefined,
209
- input: undefined,
421
+ const headResponse = initResponse({
210
422
  ctx,
211
- type: type,
212
- req,
423
+ paths,
424
+ type,
425
+ responseMeta: opts.responseMeta,
426
+ untransformedJSON,
427
+ errors: [error],
213
428
  });
214
- return endResponse(
215
- {
216
- error: getErrorShape({
217
- config: router._def._config,
218
- error,
219
- type,
220
- path: undefined,
221
- input: undefined,
222
- ctx,
223
- }),
224
- },
225
- [error],
226
- );
429
+ onHead?.(headResponse);
430
+
431
+ onChunk?.([-1, body]);
432
+
433
+ return {
434
+ status: headResponse.status,
435
+ headers: headResponse.headers,
436
+ body,
437
+ };
227
438
  }
228
439
  }
@@ -1,4 +1,4 @@
1
- import { ProcedureType, inferRouterContext } from '../core';
1
+ import { inferRouterContext, ProcedureType } from '../core';
2
2
  import { AnyRouter } from '../core/router';
3
3
  import { TRPCError } from '../error/TRPCError';
4
4
 
@@ -1,5 +1,5 @@
1
1
  import { getTRPCErrorFromUnknown } from './error/TRPCError';
2
- import { Observable, Observer, observable } from './observable';
2
+ import { Observable, observable, Observer } from './observable';
3
3
 
4
4
  /**
5
5
  * @deprecated