@trpc/server 11.0.0-rc.413 → 11.0.0-rc.419
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.
- package/dist/@trpc/server/index.d.ts +1 -1
- package/dist/@trpc/server/index.d.ts.map +1 -1
- package/dist/adapters/aws-lambda/getPlanner.d.ts.map +1 -1
- package/dist/adapters/next-app-dir/redirect.d.ts.map +1 -1
- package/dist/adapters/node-http/incomingMessageToRequest.d.ts +0 -1
- package/dist/adapters/node-http/incomingMessageToRequest.d.ts.map +1 -1
- package/dist/adapters/node-http/incomingMessageToRequest.js +3 -1
- package/dist/adapters/node-http/incomingMessageToRequest.mjs +3 -1
- package/dist/adapters/node-http/nodeHTTPRequestHandler.d.ts.map +1 -1
- package/dist/adapters/node-http/nodeHTTPRequestHandler.js +30 -7
- package/dist/adapters/node-http/nodeHTTPRequestHandler.mjs +30 -7
- package/dist/adapters/node-http/types.d.ts +0 -1
- package/dist/adapters/node-http/types.d.ts.map +1 -1
- package/dist/adapters/standalone.d.ts +0 -1
- package/dist/adapters/standalone.d.ts.map +1 -1
- package/dist/adapters/ws.d.ts +1 -2
- package/dist/adapters/ws.d.ts.map +1 -1
- package/dist/adapters/ws.js +98 -81
- package/dist/adapters/ws.mjs +98 -81
- package/dist/bundle-analysis.json +209 -150
- package/dist/index.js +5 -3
- package/dist/index.mjs +2 -1
- package/dist/observable/observable.d.ts +1 -0
- package/dist/observable/observable.d.ts.map +1 -1
- package/dist/observable/observable.js +55 -0
- package/dist/observable/observable.mjs +55 -1
- package/dist/unstable-core-do-not-import/createProxy.d.ts +1 -1
- package/dist/unstable-core-do-not-import/createProxy.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/createProxy.js +8 -6
- package/dist/unstable-core-do-not-import/createProxy.mjs +8 -6
- package/dist/unstable-core-do-not-import/http/contentType.d.ts +7 -4
- package/dist/unstable-core-do-not-import/http/contentType.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/http/contentType.js +55 -17
- package/dist/unstable-core-do-not-import/http/contentType.mjs +56 -18
- package/dist/unstable-core-do-not-import/http/resolveResponse.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/http/resolveResponse.js +302 -149
- package/dist/unstable-core-do-not-import/http/resolveResponse.mjs +301 -148
- package/dist/unstable-core-do-not-import/http/types.d.ts +34 -5
- package/dist/unstable-core-do-not-import/http/types.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/initTRPC.d.ts +12 -12
- package/dist/unstable-core-do-not-import/initTRPC.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/middleware.d.ts +3 -3
- package/dist/unstable-core-do-not-import/middleware.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/procedureBuilder.d.ts +3 -1
- package/dist/unstable-core-do-not-import/procedureBuilder.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/rootConfig.d.ts +12 -0
- package/dist/unstable-core-do-not-import/rootConfig.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/router.d.ts +2 -2
- package/dist/unstable-core-do-not-import/router.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/router.js +7 -2
- package/dist/unstable-core-do-not-import/router.mjs +7 -2
- package/dist/unstable-core-do-not-import/stream/{stream.d.ts → jsonl.d.ts} +5 -5
- package/dist/unstable-core-do-not-import/stream/jsonl.d.ts.map +1 -0
- package/dist/unstable-core-do-not-import/stream/{stream.js → jsonl.js} +90 -89
- package/dist/unstable-core-do-not-import/stream/{stream.mjs → jsonl.mjs} +89 -88
- package/dist/unstable-core-do-not-import/stream/sse.d.ts +95 -0
- package/dist/unstable-core-do-not-import/stream/sse.d.ts.map +1 -0
- package/dist/unstable-core-do-not-import/stream/sse.js +175 -0
- package/dist/unstable-core-do-not-import/stream/sse.mjs +169 -0
- package/dist/unstable-core-do-not-import/stream/utils/createDeferred.d.ts +18 -0
- package/dist/unstable-core-do-not-import/stream/utils/createDeferred.d.ts.map +1 -0
- package/dist/unstable-core-do-not-import/stream/utils/createDeferred.js +46 -0
- package/dist/unstable-core-do-not-import/stream/utils/createDeferred.mjs +43 -0
- package/dist/unstable-core-do-not-import/stream/utils/createReadableStream.d.ts +10 -0
- package/dist/unstable-core-do-not-import/stream/utils/createReadableStream.d.ts.map +1 -0
- package/dist/unstable-core-do-not-import/stream/utils/createReadableStream.js +31 -0
- package/dist/unstable-core-do-not-import/stream/utils/createReadableStream.mjs +29 -0
- package/dist/unstable-core-do-not-import/stream/utils/createServer.d.ts +7 -0
- package/dist/unstable-core-do-not-import/stream/utils/createServer.d.ts.map +1 -0
- package/dist/unstable-core-do-not-import/transformer.d.ts +5 -5
- package/dist/unstable-core-do-not-import/utils.d.ts +4 -0
- package/dist/unstable-core-do-not-import/utils.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import/utils.js +4 -0
- package/dist/unstable-core-do-not-import/utils.mjs +4 -1
- package/dist/unstable-core-do-not-import.d.ts +2 -1
- package/dist/unstable-core-do-not-import.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import.js +11 -4
- package/dist/unstable-core-do-not-import.mjs +3 -2
- package/package.json +4 -4
- package/src/@trpc/server/index.ts +1 -0
- package/src/adapters/node-http/incomingMessageToRequest.ts +3 -2
- package/src/adapters/node-http/nodeHTTPRequestHandler.ts +32 -7
- package/src/adapters/ws.ts +101 -75
- package/src/observable/observable.ts +63 -0
- package/src/unstable-core-do-not-import/createProxy.ts +13 -6
- package/src/unstable-core-do-not-import/http/contentType.ts +78 -21
- package/src/unstable-core-do-not-import/http/resolveResponse.ts +331 -164
- package/src/unstable-core-do-not-import/http/types.ts +42 -5
- package/src/unstable-core-do-not-import/procedureBuilder.ts +8 -1
- package/src/unstable-core-do-not-import/rootConfig.ts +12 -0
- package/src/unstable-core-do-not-import/router.ts +46 -34
- package/src/unstable-core-do-not-import/stream/{stream.ts → jsonl.ts} +99 -85
- package/src/unstable-core-do-not-import/stream/sse.ts +291 -0
- package/src/unstable-core-do-not-import/stream/utils/createDeferred.ts +48 -0
- package/src/unstable-core-do-not-import/stream/utils/createReadableStream.ts +31 -0
- package/src/unstable-core-do-not-import/stream/utils/createServer.ts +46 -0
- package/src/unstable-core-do-not-import/utils.ts +5 -0
- package/src/unstable-core-do-not-import.ts +2 -1
- package/dist/unstable-core-do-not-import/stream/stream.d.ts.map +0 -1
|
@@ -1,20 +1,42 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var observable = require('../../observable/observable.js');
|
|
3
4
|
var getErrorShape = require('../error/getErrorShape.js');
|
|
4
5
|
var TRPCError = require('../error/TRPCError.js');
|
|
5
|
-
var
|
|
6
|
-
var
|
|
6
|
+
var jsonl = require('../stream/jsonl.js');
|
|
7
|
+
var sse = require('../stream/sse.js');
|
|
7
8
|
var transformer = require('../transformer.js');
|
|
8
9
|
var utils = require('../utils.js');
|
|
9
10
|
var contentType = require('./contentType.js');
|
|
10
11
|
var getHTTPStatusCode = require('./getHTTPStatusCode.js');
|
|
11
12
|
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const TYPE_ACCEPTED_METHOD_MAP = {
|
|
14
|
+
mutation: [
|
|
15
|
+
'POST'
|
|
16
|
+
],
|
|
17
|
+
query: [
|
|
18
|
+
'GET'
|
|
19
|
+
],
|
|
20
|
+
subscription: [
|
|
21
|
+
'GET'
|
|
22
|
+
]
|
|
23
|
+
};
|
|
24
|
+
const TYPE_ACCEPTED_METHOD_MAP_WITH_METHOD_OVERRIDE = {
|
|
25
|
+
// never allow GET to do a mutation
|
|
26
|
+
mutation: [
|
|
27
|
+
'POST'
|
|
28
|
+
],
|
|
29
|
+
query: [
|
|
30
|
+
'GET',
|
|
31
|
+
'POST'
|
|
32
|
+
],
|
|
33
|
+
subscription: [
|
|
34
|
+
'GET',
|
|
35
|
+
'POST'
|
|
36
|
+
]
|
|
15
37
|
};
|
|
16
38
|
function initResponse(initOpts) {
|
|
17
|
-
const { ctx , info ,
|
|
39
|
+
const { ctx , info , responseMeta , untransformedJSON , errors =[] , headers , } = initOpts;
|
|
18
40
|
let status = untransformedJSON ? getHTTPStatusCode.getHTTPStatusCode(untransformedJSON) : 200;
|
|
19
41
|
const eagerGeneration = !untransformedJSON;
|
|
20
42
|
const data = eagerGeneration ? [] : Array.isArray(untransformedJSON) ? untransformedJSON : [
|
|
@@ -24,10 +46,10 @@ function initResponse(initOpts) {
|
|
|
24
46
|
ctx,
|
|
25
47
|
info,
|
|
26
48
|
paths: info?.calls.map((call)=>call.path),
|
|
27
|
-
type,
|
|
28
49
|
data,
|
|
29
50
|
errors,
|
|
30
|
-
eagerGeneration
|
|
51
|
+
eagerGeneration,
|
|
52
|
+
type: info?.calls.find((call)=>call.procedure?._def.type)?.procedure?._def.type ?? 'unknown'
|
|
31
53
|
}) ?? {};
|
|
32
54
|
if (meta.headers) {
|
|
33
55
|
if (meta.headers instanceof Headers) {
|
|
@@ -84,15 +106,28 @@ function caughtErrorToData(cause, errorOpts) {
|
|
|
84
106
|
body
|
|
85
107
|
};
|
|
86
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Check if a value is a stream-like object
|
|
111
|
+
* - if it's an async iterable
|
|
112
|
+
* - if it's an object with async iterables or promises
|
|
113
|
+
*/ function isDataStream(v) {
|
|
114
|
+
if (!utils.isObject(v)) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
if (utils.isAsyncIterable(v)) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
return Object.values(v).some(jsonl.isPromise) || Object.values(v).some(utils.isAsyncIterable);
|
|
121
|
+
}
|
|
87
122
|
async function resolveResponse(opts) {
|
|
88
|
-
const { router
|
|
123
|
+
const { router , req } = opts;
|
|
89
124
|
const headers = new Headers([
|
|
90
125
|
[
|
|
91
126
|
'vary',
|
|
92
127
|
'trpc-accept'
|
|
93
128
|
]
|
|
94
129
|
]);
|
|
95
|
-
const config = router
|
|
130
|
+
const config = router._def._config;
|
|
96
131
|
const url = new URL(req.url);
|
|
97
132
|
if (req.method === 'HEAD') {
|
|
98
133
|
// can be used for lambda warmup
|
|
@@ -102,17 +137,21 @@ async function resolveResponse(opts) {
|
|
|
102
137
|
}
|
|
103
138
|
const allowBatching = opts.allowBatching ?? opts.batching?.enabled ?? true;
|
|
104
139
|
const allowMethodOverride = (opts.allowMethodOverride ?? false) && req.method === 'POST';
|
|
105
|
-
const type = HTTP_METHOD_PROCEDURE_TYPE_MAP[req.method] ?? 'unknown';
|
|
106
140
|
let ctx = undefined;
|
|
107
141
|
let info = undefined;
|
|
108
|
-
const
|
|
109
|
-
|
|
142
|
+
const methodMapper = allowMethodOverride ? TYPE_ACCEPTED_METHOD_MAP_WITH_METHOD_OVERRIDE : TYPE_ACCEPTED_METHOD_MAP;
|
|
143
|
+
/**
|
|
144
|
+
* @deprecated
|
|
145
|
+
*/ const isStreamCall = req.headers.get('trpc-accept') === 'application/jsonl';
|
|
146
|
+
const experimentalIterablesAndDeferreds = router._def._config.experimental?.iterablesAndDeferreds ?? true;
|
|
147
|
+
const experimentalSSE = router._def._config.experimental?.sseSubscriptions?.enabled ?? true;
|
|
110
148
|
try {
|
|
111
149
|
info = contentType.getRequestInfo({
|
|
112
150
|
req,
|
|
113
151
|
path: decodeURIComponent(opts.path),
|
|
114
|
-
|
|
115
|
-
searchParams: url.searchParams
|
|
152
|
+
router,
|
|
153
|
+
searchParams: url.searchParams,
|
|
154
|
+
headers: opts.req.headers
|
|
116
155
|
});
|
|
117
156
|
// we create context early so that error handlers may access context information
|
|
118
157
|
ctx = await opts.createContext({
|
|
@@ -127,166 +166,281 @@ async function resolveResponse(opts) {
|
|
|
127
166
|
message: `Batching is not enabled on the server`
|
|
128
167
|
});
|
|
129
168
|
}
|
|
130
|
-
if (
|
|
169
|
+
/* istanbul ignore if -- @preserve */ if (isStreamCall && !info.isBatchCall) {
|
|
131
170
|
throw new TRPCError.TRPCError({
|
|
132
|
-
message: `
|
|
133
|
-
code: '
|
|
171
|
+
message: `Streaming requests must be batched (you can do a batch of 1)`,
|
|
172
|
+
code: 'BAD_REQUEST'
|
|
134
173
|
});
|
|
135
174
|
}
|
|
136
|
-
const
|
|
137
|
-
|
|
175
|
+
const rpcCalls = info.calls.map(async (call)=>{
|
|
176
|
+
const proc = call.procedure;
|
|
138
177
|
try {
|
|
139
|
-
|
|
140
|
-
|
|
178
|
+
if (!proc) {
|
|
179
|
+
throw new TRPCError.TRPCError({
|
|
180
|
+
code: 'NOT_FOUND',
|
|
181
|
+
message: `No procedure found on path "${call.path}"`
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
if (!methodMapper[proc._def.type].includes(req.method)) {
|
|
185
|
+
throw new TRPCError.TRPCError({
|
|
186
|
+
code: 'METHOD_NOT_SUPPORTED',
|
|
187
|
+
message: `Unsupported ${req.method}-request to ${proc._def.type} procedure at path "${call.path}"`
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
/* istanbul ignore if -- @preserve */ if (proc._def.type === 'subscription' && info.isBatchCall) {
|
|
191
|
+
throw new TRPCError.TRPCError({
|
|
192
|
+
code: 'BAD_REQUEST',
|
|
193
|
+
message: `Cannot batch subscription calls`
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
const data = await proc({
|
|
141
197
|
path: call.path,
|
|
142
198
|
getRawInput: call.getRawInput,
|
|
143
199
|
ctx,
|
|
144
|
-
type
|
|
145
|
-
allowMethodOverride
|
|
200
|
+
type: proc._def.type
|
|
146
201
|
});
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
code: 'UNSUPPORTED_MEDIA_TYPE',
|
|
151
|
-
message: 'Cannot return async iterable or nested promises in non-streaming response'
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
if (!experimentalIterablesAndDeferreds) {
|
|
155
|
-
throw new TRPCError.TRPCError({
|
|
156
|
-
code: 'INTERNAL_SERVER_ERROR',
|
|
157
|
-
message: 'Missing experimental flag "iterablesAndDeferreds"'
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
return {
|
|
162
|
-
result: {
|
|
163
|
-
data
|
|
164
|
-
}
|
|
165
|
-
};
|
|
202
|
+
return [
|
|
203
|
+
data
|
|
204
|
+
];
|
|
166
205
|
} catch (cause) {
|
|
167
206
|
const error = TRPCError.getTRPCErrorFromUnknown(cause);
|
|
168
|
-
errors.push(error);
|
|
169
207
|
const input = call.result();
|
|
170
208
|
opts.onError?.({
|
|
171
209
|
error,
|
|
172
210
|
path: call.path,
|
|
173
211
|
input,
|
|
174
212
|
ctx,
|
|
175
|
-
type: type,
|
|
213
|
+
type: call.procedure?._def.type ?? 'unknown',
|
|
176
214
|
req: opts.req
|
|
177
215
|
});
|
|
178
|
-
return
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
type,
|
|
183
|
-
path: call.path,
|
|
184
|
-
input,
|
|
185
|
-
ctx
|
|
186
|
-
})
|
|
187
|
-
};
|
|
216
|
+
return [
|
|
217
|
+
null,
|
|
218
|
+
error
|
|
219
|
+
];
|
|
188
220
|
}
|
|
189
221
|
});
|
|
190
|
-
|
|
222
|
+
// ----------- response handlers -----------
|
|
223
|
+
if (!info.isBatchCall) {
|
|
224
|
+
const [call] = info.calls;
|
|
225
|
+
const [data, error] = await rpcCalls[0];
|
|
226
|
+
switch(info.type){
|
|
227
|
+
case 'unknown':
|
|
228
|
+
case 'mutation':
|
|
229
|
+
case 'query':
|
|
230
|
+
{
|
|
231
|
+
// httpLink
|
|
232
|
+
headers.set('content-type', 'application/json');
|
|
233
|
+
if (isDataStream(data)) {
|
|
234
|
+
throw new TRPCError.TRPCError({
|
|
235
|
+
code: 'UNSUPPORTED_MEDIA_TYPE',
|
|
236
|
+
message: 'Cannot use stream-like response in non-streaming request - use httpBatchStreamLink'
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
const res = error ? {
|
|
240
|
+
error: getErrorShape.getErrorShape({
|
|
241
|
+
config,
|
|
242
|
+
ctx,
|
|
243
|
+
error,
|
|
244
|
+
input: call.result(),
|
|
245
|
+
path: call.path,
|
|
246
|
+
type: info.type
|
|
247
|
+
})
|
|
248
|
+
} : {
|
|
249
|
+
result: {
|
|
250
|
+
data
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
const headResponse = initResponse({
|
|
254
|
+
ctx,
|
|
255
|
+
info,
|
|
256
|
+
responseMeta: opts.responseMeta,
|
|
257
|
+
errors: error ? [
|
|
258
|
+
error
|
|
259
|
+
] : [],
|
|
260
|
+
headers,
|
|
261
|
+
untransformedJSON: [
|
|
262
|
+
res
|
|
263
|
+
]
|
|
264
|
+
});
|
|
265
|
+
return new Response(JSON.stringify(transformer.transformTRPCResponse(config, res)), {
|
|
266
|
+
status: headResponse.status,
|
|
267
|
+
headers
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
case 'subscription':
|
|
271
|
+
{
|
|
272
|
+
// httpSubscriptionLink
|
|
273
|
+
if (!experimentalSSE) {
|
|
274
|
+
throw new TRPCError.TRPCError({
|
|
275
|
+
code: 'METHOD_NOT_SUPPORTED',
|
|
276
|
+
message: 'Missing experimental flag "sseSubscriptions"'
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
if (!observable.isObservable(data) && !utils.isAsyncIterable(data)) {
|
|
280
|
+
throw new TRPCError.TRPCError({
|
|
281
|
+
message: `Subscription ${call.path} did not return an observable or a AsyncGenerator`,
|
|
282
|
+
code: 'INTERNAL_SERVER_ERROR'
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
const dataAsIterable = observable.isObservable(data) ? observable.observableToAsyncIterable(data) : data;
|
|
286
|
+
const stream = sse.sseStreamProducer({
|
|
287
|
+
data: dataAsIterable,
|
|
288
|
+
serialize: (v)=>config.transformer.output.serialize(v)
|
|
289
|
+
});
|
|
290
|
+
for (const [key, value] of Object.entries(sse.sseHeaders)){
|
|
291
|
+
headers.set(key, value);
|
|
292
|
+
}
|
|
293
|
+
const headResponse1 = initResponse({
|
|
294
|
+
ctx,
|
|
295
|
+
info,
|
|
296
|
+
responseMeta: opts.responseMeta,
|
|
297
|
+
errors: [],
|
|
298
|
+
headers,
|
|
299
|
+
untransformedJSON: null
|
|
300
|
+
});
|
|
301
|
+
return new Response(stream, {
|
|
302
|
+
headers,
|
|
303
|
+
status: headResponse1.status
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
// batch response handlers
|
|
309
|
+
if (info.accept === 'application/jsonl') {
|
|
310
|
+
// httpBatchStreamLink
|
|
191
311
|
headers.set('content-type', 'application/json');
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
* - await all responses in parallel, blocking on the slowest one
|
|
195
|
-
* - create headers with known response body
|
|
196
|
-
* - return a complete HTTPResponse
|
|
197
|
-
*/ const untransformedJSON = await Promise.all(promises);
|
|
198
|
-
const errors1 = untransformedJSON.flatMap((response)=>'error' in response ? [
|
|
199
|
-
response.error
|
|
200
|
-
] : []);
|
|
201
|
-
const headResponse = initResponse({
|
|
312
|
+
headers.set('transfer-encoding', 'chunked');
|
|
313
|
+
const headResponse2 = initResponse({
|
|
202
314
|
ctx,
|
|
203
315
|
info,
|
|
204
|
-
type,
|
|
205
316
|
responseMeta: opts.responseMeta,
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
317
|
+
errors: [],
|
|
318
|
+
headers,
|
|
319
|
+
untransformedJSON: null
|
|
209
320
|
});
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
* 0: {
|
|
240
|
-
* // 2
|
|
241
|
-
* result: {
|
|
242
|
-
* // 3
|
|
243
|
-
* data: // 4
|
|
244
|
-
* }
|
|
245
|
-
* }
|
|
246
|
-
* }
|
|
247
|
-
*/ maxDepth: experimentalIterablesAndDeferreds ? 4 : 3,
|
|
248
|
-
formatError (errorOpts) {
|
|
249
|
-
const call = info?.calls[errorOpts.path[0]];
|
|
250
|
-
return getErrorShape.getErrorShape({
|
|
251
|
-
config,
|
|
252
|
-
ctx,
|
|
253
|
-
error: TRPCError.getTRPCErrorFromUnknown(errorOpts.error),
|
|
254
|
-
input: call?.result(),
|
|
255
|
-
path: call?.path,
|
|
256
|
-
type
|
|
257
|
-
});
|
|
258
|
-
},
|
|
259
|
-
data: promises.map(async (it)=>{
|
|
260
|
-
const response = await it;
|
|
261
|
-
if ('result' in response) {
|
|
321
|
+
const stream1 = jsonl.jsonlStreamProducer({
|
|
322
|
+
/**
|
|
323
|
+
* Example structure for `maxDepth: 4`:
|
|
324
|
+
* {
|
|
325
|
+
* // 1
|
|
326
|
+
* 0: {
|
|
327
|
+
* // 2
|
|
328
|
+
* result: {
|
|
329
|
+
* // 3
|
|
330
|
+
* data: // 4
|
|
331
|
+
* }
|
|
332
|
+
* }
|
|
333
|
+
* }
|
|
334
|
+
*/ maxDepth: experimentalIterablesAndDeferreds ? 4 : 3,
|
|
335
|
+
data: rpcCalls.map(async (res)=>{
|
|
336
|
+
const [result, error] = await res;
|
|
337
|
+
const call = info.calls[0];
|
|
338
|
+
if (error) {
|
|
339
|
+
return {
|
|
340
|
+
error: getErrorShape.getErrorShape({
|
|
341
|
+
config,
|
|
342
|
+
ctx,
|
|
343
|
+
error,
|
|
344
|
+
input: call.result(),
|
|
345
|
+
path: call.path,
|
|
346
|
+
type: call.procedure?._def.type ?? 'unknown'
|
|
347
|
+
})
|
|
348
|
+
};
|
|
349
|
+
}
|
|
262
350
|
/**
|
|
263
351
|
* Not very pretty, but we need to wrap nested data in promises
|
|
264
352
|
* Our stream producer will only resolve top-level async values or async values that are directly nested in another async value
|
|
265
|
-
*/
|
|
266
|
-
|
|
353
|
+
*/ const data = observable.isObservable(result) ? observable.observableToAsyncIterable(result) : Promise.resolve(result);
|
|
354
|
+
return {
|
|
267
355
|
result: Promise.resolve({
|
|
268
|
-
|
|
269
|
-
data: Promise.resolve(response.result.data)
|
|
356
|
+
data
|
|
270
357
|
})
|
|
271
358
|
};
|
|
359
|
+
}),
|
|
360
|
+
serialize: config.transformer.output.serialize,
|
|
361
|
+
onError: (cause)=>{
|
|
362
|
+
opts.onError?.({
|
|
363
|
+
error: TRPCError.getTRPCErrorFromUnknown(cause),
|
|
364
|
+
path: undefined,
|
|
365
|
+
input: undefined,
|
|
366
|
+
ctx,
|
|
367
|
+
req: opts.req,
|
|
368
|
+
type: info?.type ?? 'unknown'
|
|
369
|
+
});
|
|
370
|
+
},
|
|
371
|
+
formatError (errorOpts) {
|
|
372
|
+
const call = info?.calls[errorOpts.path[0]];
|
|
373
|
+
const shape = getErrorShape.getErrorShape({
|
|
374
|
+
config,
|
|
375
|
+
ctx,
|
|
376
|
+
error: TRPCError.getTRPCErrorFromUnknown(errorOpts.error),
|
|
377
|
+
input: call?.result(),
|
|
378
|
+
path: call?.path,
|
|
379
|
+
type: call?.procedure?._def.type ?? 'unknown'
|
|
380
|
+
});
|
|
381
|
+
return shape;
|
|
272
382
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
383
|
+
});
|
|
384
|
+
return new Response(stream1, {
|
|
385
|
+
headers,
|
|
386
|
+
status: headResponse2.status
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
// httpBatchLink
|
|
390
|
+
/**
|
|
391
|
+
* Non-streaming response:
|
|
392
|
+
* - await all responses in parallel, blocking on the slowest one
|
|
393
|
+
* - create headers with known response body
|
|
394
|
+
* - return a complete HTTPResponse
|
|
395
|
+
*/ headers.set('content-type', 'application/json');
|
|
396
|
+
const results = (await Promise.all(rpcCalls)).map((res)=>{
|
|
397
|
+
const [data, error] = res;
|
|
398
|
+
if (error) {
|
|
399
|
+
return res;
|
|
285
400
|
}
|
|
401
|
+
if (isDataStream(data)) {
|
|
402
|
+
return [
|
|
403
|
+
null,
|
|
404
|
+
new TRPCError.TRPCError({
|
|
405
|
+
code: 'UNSUPPORTED_MEDIA_TYPE',
|
|
406
|
+
message: 'Cannot use stream-like response in non-streaming request - use httpBatchStreamLink'
|
|
407
|
+
})
|
|
408
|
+
];
|
|
409
|
+
}
|
|
410
|
+
return res;
|
|
286
411
|
});
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
412
|
+
const resultAsRPCResponse = results.map(([data, error], index)=>{
|
|
413
|
+
const call = info.calls[index];
|
|
414
|
+
if (error) {
|
|
415
|
+
return {
|
|
416
|
+
error: getErrorShape.getErrorShape({
|
|
417
|
+
config,
|
|
418
|
+
ctx,
|
|
419
|
+
error,
|
|
420
|
+
input: call.result(),
|
|
421
|
+
path: call.path,
|
|
422
|
+
type: call.procedure?._def.type ?? 'unknown'
|
|
423
|
+
})
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
return {
|
|
427
|
+
result: {
|
|
428
|
+
data
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
});
|
|
432
|
+
const errors = results.map(([_, error])=>error).filter(Boolean);
|
|
433
|
+
const headResponse3 = initResponse({
|
|
434
|
+
ctx,
|
|
435
|
+
info,
|
|
436
|
+
responseMeta: opts.responseMeta,
|
|
437
|
+
untransformedJSON: resultAsRPCResponse,
|
|
438
|
+
errors,
|
|
439
|
+
headers
|
|
440
|
+
});
|
|
441
|
+
return new Response(JSON.stringify(transformer.transformTRPCResponse(config, resultAsRPCResponse)), {
|
|
442
|
+
status: headResponse3.status,
|
|
443
|
+
headers
|
|
290
444
|
});
|
|
291
445
|
} catch (cause) {
|
|
292
446
|
// we get here if
|
|
@@ -296,24 +450,23 @@ async function resolveResponse(opts) {
|
|
|
296
450
|
// - post body is too large
|
|
297
451
|
// - input deserialization fails
|
|
298
452
|
// - `errorFormatter` return value is malformed
|
|
299
|
-
const { error , untransformedJSON
|
|
453
|
+
const { error: error1 , untransformedJSON , body } = caughtErrorToData(cause, {
|
|
300
454
|
opts,
|
|
301
455
|
ctx,
|
|
302
|
-
type
|
|
456
|
+
type: info?.type ?? 'unknown'
|
|
303
457
|
});
|
|
304
|
-
const
|
|
458
|
+
const headResponse4 = initResponse({
|
|
305
459
|
ctx,
|
|
306
460
|
info,
|
|
307
|
-
type,
|
|
308
461
|
responseMeta: opts.responseMeta,
|
|
309
|
-
untransformedJSON
|
|
462
|
+
untransformedJSON,
|
|
310
463
|
errors: [
|
|
311
|
-
|
|
464
|
+
error1
|
|
312
465
|
],
|
|
313
466
|
headers
|
|
314
467
|
});
|
|
315
|
-
return new Response(
|
|
316
|
-
status:
|
|
468
|
+
return new Response(body, {
|
|
469
|
+
status: headResponse4.status,
|
|
317
470
|
headers
|
|
318
471
|
});
|
|
319
472
|
}
|