@trpc/server 10.21.3-test.0 → 10.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.
- package/dist/adapters/aws-lambda/index.js +2 -1
- package/dist/adapters/aws-lambda/index.mjs +2 -1
- package/dist/adapters/express.js +5 -2
- package/dist/adapters/express.mjs +5 -2
- package/dist/adapters/fastify/index.js +2 -1
- package/dist/adapters/fastify/index.mjs +2 -1
- package/dist/adapters/fetch/fetchRequestHandler.d.ts.map +1 -1
- package/dist/adapters/fetch/index.js +3 -2
- package/dist/adapters/fetch/index.mjs +3 -2
- package/dist/adapters/next.js +5 -2
- package/dist/adapters/next.mjs +5 -2
- package/dist/adapters/node-http/content-type/form-data/fileUploadHandler.d.ts +70 -0
- package/dist/adapters/node-http/content-type/form-data/fileUploadHandler.d.ts.map +1 -0
- package/dist/adapters/node-http/content-type/form-data/index.d.ts +24 -0
- package/dist/adapters/node-http/content-type/form-data/index.d.ts.map +1 -0
- package/dist/adapters/node-http/content-type/form-data/index.js +723 -0
- package/dist/adapters/node-http/content-type/form-data/index.mjs +708 -0
- package/dist/adapters/node-http/content-type/form-data/memoryUploadHandler.d.ts +31 -0
- package/dist/adapters/node-http/content-type/form-data/memoryUploadHandler.d.ts.map +1 -0
- package/dist/adapters/node-http/content-type/form-data/streamSlice.d.ts +11 -0
- package/dist/adapters/node-http/content-type/form-data/streamSlice.d.ts.map +1 -0
- package/dist/adapters/node-http/content-type/form-data/uploadHandler.d.ts +40 -0
- package/dist/adapters/node-http/content-type/form-data/uploadHandler.d.ts.map +1 -0
- package/dist/adapters/node-http/content-type/json/getPostBody.d.ts +7 -0
- package/dist/adapters/node-http/content-type/json/getPostBody.d.ts.map +1 -0
- package/dist/adapters/node-http/content-type/json/index.d.ts +2 -0
- package/dist/adapters/node-http/content-type/json/index.d.ts.map +1 -0
- package/dist/adapters/node-http/content-type/json/index.js +53 -0
- package/dist/adapters/node-http/content-type/json/index.mjs +49 -0
- package/dist/adapters/node-http/index.js +5 -2
- package/dist/adapters/node-http/index.mjs +5 -2
- package/dist/adapters/node-http/internals/contentType.d.ts +9 -0
- package/dist/adapters/node-http/internals/contentType.d.ts.map +1 -0
- package/dist/adapters/node-http/nodeHTTPRequestHandler.d.ts +1 -7
- package/dist/adapters/node-http/nodeHTTPRequestHandler.d.ts.map +1 -1
- package/dist/adapters/node-http/types.d.ts +7 -0
- package/dist/adapters/node-http/types.d.ts.map +1 -1
- package/dist/adapters/standalone.js +5 -2
- package/dist/adapters/standalone.mjs +5 -2
- package/dist/contentType-3194ed5f.mjs +5 -0
- package/dist/contentType-8356d528.js +54 -0
- package/dist/contentType-8c16408e.js +7 -0
- package/dist/contentType-a75c990c.js +58 -0
- package/dist/contentType-acc3be52.mjs +52 -0
- package/dist/contentType-f27e4bfc.js +5 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/middleware.d.ts +3 -0
- package/dist/core/middleware.d.ts.map +1 -1
- package/dist/http/contentType.d.ts +29 -0
- package/dist/http/contentType.d.ts.map +1 -0
- package/dist/http/index.js +2 -1
- package/dist/http/index.mjs +2 -1
- package/dist/http/resolveHTTPResponse.d.ts +2 -0
- package/dist/http/resolveHTTPResponse.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.mjs +6 -4
- package/dist/{nodeHTTPRequestHandler-8bbfaa5c.js → nodeHTTPRequestHandler-953c8f9a.js} +22 -54
- package/dist/{nodeHTTPRequestHandler-9d8156da.js → nodeHTTPRequestHandler-c1dcd256.js} +22 -47
- package/dist/{nodeHTTPRequestHandler-4f6f12f6.mjs → nodeHTTPRequestHandler-fcbe1351.mjs} +22 -54
- package/dist/{resolveHTTPResponse-b413b925.js → resolveHTTPResponse-9a9f3436.js} +10 -56
- package/dist/{resolveHTTPResponse-a2e412ec.js → resolveHTTPResponse-a7abb046.js} +9 -49
- package/dist/{resolveHTTPResponse-24febe05.mjs → resolveHTTPResponse-e1286cb3.mjs} +10 -50
- package/package.json +14 -2
- package/src/adapters/fetch/fetchRequestHandler.ts +4 -1
- package/src/adapters/node-http/content-type/form-data/fileUploadHandler.ts +268 -0
- package/src/adapters/node-http/content-type/form-data/index.ts +105 -0
- package/src/adapters/node-http/content-type/form-data/memoryUploadHandler.ts +59 -0
- package/src/adapters/node-http/content-type/form-data/streamSlice.ts +51 -0
- package/src/adapters/node-http/content-type/form-data/uploadHandler.ts +85 -0
- package/src/adapters/node-http/{internals → content-type/json}/getPostBody.test.ts +6 -2
- package/src/adapters/node-http/{internals → content-type/json}/getPostBody.ts +5 -7
- package/src/adapters/node-http/content-type/json/index.ts +11 -0
- package/src/adapters/node-http/internals/contentType.ts +29 -0
- package/src/adapters/node-http/nodeHTTPRequestHandler.ts +34 -35
- package/src/adapters/node-http/types.ts +15 -0
- package/src/core/index.ts +1 -1
- package/src/core/internals/procedureBuilder.ts +21 -4
- package/src/core/middleware.ts +1 -0
- package/src/http/contentType.ts +100 -0
- package/src/http/resolveHTTPResponse.ts +18 -65
- package/dist/adapters/node-http/internals/getPostBody.d.ts +0 -14
- package/dist/adapters/node-http/internals/getPostBody.d.ts.map +0 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AnyRouter } from '../../../core';
|
|
2
|
+
import { BaseContentTypeHandler } from '../../../http/contentType';
|
|
3
|
+
import {
|
|
4
|
+
NodeHTTPRequest,
|
|
5
|
+
NodeHTTPRequestHandlerOptions,
|
|
6
|
+
NodeHTTPResponse,
|
|
7
|
+
} from '../types';
|
|
8
|
+
|
|
9
|
+
export interface NodeHTTPContentTypeHandler<
|
|
10
|
+
TRequest extends NodeHTTPRequest,
|
|
11
|
+
TResponse extends NodeHTTPResponse,
|
|
12
|
+
> extends BaseContentTypeHandler<
|
|
13
|
+
NodeHTTPRequestHandlerOptions<AnyRouter, TRequest, TResponse> & {
|
|
14
|
+
query: URLSearchParams;
|
|
15
|
+
}
|
|
16
|
+
> {}
|
|
17
|
+
|
|
18
|
+
export function createNodeHTTPContentTypeHandler(
|
|
19
|
+
contentTypeHandler: NodeHTTPContentTypeHandler<
|
|
20
|
+
NodeHTTPRequest,
|
|
21
|
+
NodeHTTPResponse
|
|
22
|
+
>,
|
|
23
|
+
) {
|
|
24
|
+
return <
|
|
25
|
+
TRequest extends NodeHTTPRequest,
|
|
26
|
+
TResponse extends NodeHTTPResponse,
|
|
27
|
+
>(): NodeHTTPContentTypeHandler<TRequest, TResponse> =>
|
|
28
|
+
contentTypeHandler as any;
|
|
29
|
+
}
|
|
@@ -3,52 +3,59 @@ import { AnyRouter } from '../../core';
|
|
|
3
3
|
import { inferRouterContext } from '../../core/types';
|
|
4
4
|
import { HTTPRequest } from '../../http';
|
|
5
5
|
import { resolveHTTPResponse } from '../../http/resolveHTTPResponse';
|
|
6
|
-
import {
|
|
6
|
+
import { nodeHTTPJSONContentTypeHandler } from './content-type/json';
|
|
7
|
+
import { NodeHTTPContentTypeHandler } from './internals/contentType';
|
|
7
8
|
import {
|
|
8
|
-
NodeHTTPHandlerOptions,
|
|
9
9
|
NodeHTTPRequest,
|
|
10
|
+
NodeHTTPRequestHandlerOptions,
|
|
10
11
|
NodeHTTPResponse,
|
|
11
12
|
} from './types';
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
TRouter extends AnyRouter,
|
|
15
|
-
TRequest extends NodeHTTPRequest,
|
|
16
|
-
TResponse extends NodeHTTPResponse,
|
|
17
|
-
> = {
|
|
18
|
-
req: TRequest;
|
|
19
|
-
res: TResponse;
|
|
20
|
-
path: string;
|
|
21
|
-
} & NodeHTTPHandlerOptions<TRouter, TRequest, TResponse>;
|
|
14
|
+
const defaultJSONContentTypeHandler = nodeHTTPJSONContentTypeHandler();
|
|
22
15
|
|
|
23
16
|
export async function nodeHTTPRequestHandler<
|
|
24
17
|
TRouter extends AnyRouter,
|
|
25
18
|
TRequest extends NodeHTTPRequest,
|
|
26
19
|
TResponse extends NodeHTTPResponse,
|
|
27
20
|
>(opts: NodeHTTPRequestHandlerOptions<TRouter, TRequest, TResponse>) {
|
|
28
|
-
const handleViaMiddleware =
|
|
29
|
-
opts.middleware ??
|
|
30
|
-
((_req, _res, next) => {
|
|
31
|
-
return next();
|
|
32
|
-
});
|
|
21
|
+
const handleViaMiddleware = opts.middleware ?? ((_req, _res, next) => next());
|
|
33
22
|
|
|
34
23
|
return handleViaMiddleware(opts.req, opts.res, async (err) => {
|
|
35
|
-
if (err)
|
|
36
|
-
throw err;
|
|
37
|
-
}
|
|
24
|
+
if (err) throw err;
|
|
38
25
|
|
|
39
|
-
|
|
40
|
-
// Build tRPC dependencies
|
|
41
|
-
|
|
42
|
-
async function createContext(): Promise<inferRouterContext<TRouter>> {
|
|
26
|
+
const createContext = async (): Promise<inferRouterContext<TRouter>> => {
|
|
43
27
|
return await opts.createContext?.(opts);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const bodyResult = await getPostBody(opts);
|
|
28
|
+
};
|
|
47
29
|
|
|
48
30
|
const query = opts.req.query
|
|
49
31
|
? new URLSearchParams(opts.req.query as any)
|
|
50
32
|
: new URLSearchParams(opts.req.url!.split('?')[1]);
|
|
51
33
|
|
|
34
|
+
const jsonContentTypeHandler =
|
|
35
|
+
defaultJSONContentTypeHandler as unknown as NodeHTTPContentTypeHandler<
|
|
36
|
+
TRequest,
|
|
37
|
+
TResponse
|
|
38
|
+
>;
|
|
39
|
+
|
|
40
|
+
const contentTypeHandlers = opts.experimental_contentTypeHandlers ?? [
|
|
41
|
+
jsonContentTypeHandler,
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
const contentTypeHandler =
|
|
45
|
+
contentTypeHandlers.find((handler) =>
|
|
46
|
+
handler.isMatch({
|
|
47
|
+
...opts,
|
|
48
|
+
query,
|
|
49
|
+
}),
|
|
50
|
+
) ??
|
|
51
|
+
// fallback to json
|
|
52
|
+
jsonContentTypeHandler;
|
|
53
|
+
|
|
54
|
+
const bodyResult = await contentTypeHandler.getBody({
|
|
55
|
+
...opts,
|
|
56
|
+
query,
|
|
57
|
+
});
|
|
58
|
+
|
|
52
59
|
const req: HTTPRequest = {
|
|
53
60
|
method: opts.req.method!,
|
|
54
61
|
headers: opts.req.headers,
|
|
@@ -56,9 +63,6 @@ export async function nodeHTTPRequestHandler<
|
|
|
56
63
|
body: bodyResult.ok ? bodyResult.data : undefined,
|
|
57
64
|
};
|
|
58
65
|
|
|
59
|
-
//
|
|
60
|
-
// Invoke tRPC
|
|
61
|
-
|
|
62
66
|
const result = await resolveHTTPResponse({
|
|
63
67
|
batching: opts.batching,
|
|
64
68
|
responseMeta: opts.responseMeta,
|
|
@@ -74,24 +78,19 @@ export async function nodeHTTPRequestHandler<
|
|
|
74
78
|
req: opts.req,
|
|
75
79
|
});
|
|
76
80
|
},
|
|
81
|
+
contentTypeHandler,
|
|
77
82
|
});
|
|
78
83
|
|
|
79
|
-
//
|
|
80
|
-
// Handle result
|
|
81
|
-
|
|
82
84
|
const { res } = opts;
|
|
83
85
|
if ('status' in result && (!res.statusCode || res.statusCode === 200)) {
|
|
84
86
|
res.statusCode = result.status;
|
|
85
87
|
}
|
|
86
|
-
|
|
87
88
|
for (const [key, value] of Object.entries(result.headers ?? {})) {
|
|
88
89
|
if (typeof value === 'undefined') {
|
|
89
90
|
continue;
|
|
90
91
|
}
|
|
91
|
-
|
|
92
92
|
res.setHeader(key, value);
|
|
93
93
|
}
|
|
94
|
-
|
|
95
94
|
res.end(result.body);
|
|
96
95
|
});
|
|
97
96
|
}
|
|
@@ -2,6 +2,7 @@ import { IncomingMessage, ServerResponse } from 'http';
|
|
|
2
2
|
import { AnyRouter, inferRouterContext } from '../../core';
|
|
3
3
|
import { HTTPBaseHandlerOptions } from '../../http';
|
|
4
4
|
import { MaybePromise } from '../../types';
|
|
5
|
+
import { NodeHTTPContentTypeHandler } from './internals/contentType';
|
|
5
6
|
|
|
6
7
|
interface ParsedQs {
|
|
7
8
|
[key: string]: undefined | string | string[] | ParsedQs | ParsedQs[];
|
|
@@ -64,8 +65,22 @@ export type NodeHTTPHandlerOptions<
|
|
|
64
65
|
*/
|
|
65
66
|
middleware?: ConnectMiddleware;
|
|
66
67
|
maxBodySize?: number;
|
|
68
|
+
experimental_contentTypeHandlers?: NodeHTTPContentTypeHandler<
|
|
69
|
+
TRequest,
|
|
70
|
+
TResponse
|
|
71
|
+
>[];
|
|
67
72
|
} & NodeHTTPCreateContextOption<TRouter, TRequest, TResponse>;
|
|
68
73
|
|
|
74
|
+
export type NodeHTTPRequestHandlerOptions<
|
|
75
|
+
TRouter extends AnyRouter,
|
|
76
|
+
TRequest extends NodeHTTPRequest,
|
|
77
|
+
TResponse extends NodeHTTPResponse,
|
|
78
|
+
> = {
|
|
79
|
+
req: TRequest;
|
|
80
|
+
res: TResponse;
|
|
81
|
+
path: string;
|
|
82
|
+
} & NodeHTTPHandlerOptions<TRouter, TRequest, TResponse>;
|
|
83
|
+
|
|
69
84
|
export type NodeHTTPCreateContextFnOptions<TRequest, TResponse> = {
|
|
70
85
|
req: TRequest;
|
|
71
86
|
res: TResponse;
|
package/src/core/index.ts
CHANGED
|
@@ -18,6 +18,6 @@ export type {
|
|
|
18
18
|
} from './procedure';
|
|
19
19
|
export type { inferParser } from './parser';
|
|
20
20
|
export { createInputMiddleware, createOutputMiddleware } from './middleware';
|
|
21
|
-
|
|
21
|
+
export type { MiddlewareFunction, MiddlewareBuilder } from './middleware';
|
|
22
22
|
export { initTRPC } from './initTRPC';
|
|
23
23
|
export * from './types';
|
|
@@ -333,7 +333,12 @@ function createProcedureCaller(_def: AnyProcedureBuilderDef): AnyProcedure {
|
|
|
333
333
|
|
|
334
334
|
// run the middlewares recursively with the resolver as the last one
|
|
335
335
|
const callRecursive = async (
|
|
336
|
-
callOpts: {
|
|
336
|
+
callOpts: {
|
|
337
|
+
ctx: any;
|
|
338
|
+
index: number;
|
|
339
|
+
input?: unknown;
|
|
340
|
+
rawInput?: unknown;
|
|
341
|
+
} = {
|
|
337
342
|
index: 0,
|
|
338
343
|
ctx: opts.ctx,
|
|
339
344
|
},
|
|
@@ -345,11 +350,19 @@ function createProcedureCaller(_def: AnyProcedureBuilderDef): AnyProcedure {
|
|
|
345
350
|
ctx: callOpts.ctx,
|
|
346
351
|
type: opts.type,
|
|
347
352
|
path: opts.path,
|
|
348
|
-
rawInput: opts.rawInput,
|
|
353
|
+
rawInput: callOpts.rawInput ?? opts.rawInput,
|
|
349
354
|
meta: _def.meta,
|
|
350
355
|
input: callOpts.input,
|
|
351
|
-
next
|
|
352
|
-
|
|
356
|
+
next(_nextOpts?: any) {
|
|
357
|
+
const nextOpts = _nextOpts as
|
|
358
|
+
| {
|
|
359
|
+
ctx?: Record<string, unknown>;
|
|
360
|
+
input?: unknown;
|
|
361
|
+
rawInput?: unknown;
|
|
362
|
+
}
|
|
363
|
+
| undefined;
|
|
364
|
+
|
|
365
|
+
return callRecursive({
|
|
353
366
|
index: callOpts.index + 1,
|
|
354
367
|
ctx:
|
|
355
368
|
nextOpts && 'ctx' in nextOpts
|
|
@@ -359,6 +372,10 @@ function createProcedureCaller(_def: AnyProcedureBuilderDef): AnyProcedure {
|
|
|
359
372
|
nextOpts && 'input' in nextOpts
|
|
360
373
|
? nextOpts.input
|
|
361
374
|
: callOpts.input,
|
|
375
|
+
rawInput:
|
|
376
|
+
nextOpts && 'rawInput' in nextOpts
|
|
377
|
+
? nextOpts.rawInput
|
|
378
|
+
: callOpts.rawInput,
|
|
362
379
|
});
|
|
363
380
|
},
|
|
364
381
|
});
|
package/src/core/middleware.ts
CHANGED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
|
+
import { AnyRouter } from '../core';
|
|
3
|
+
import { TRPCError } from '../error/TRPCError';
|
|
4
|
+
import { getCauseFromUnknown } from '../error/utils';
|
|
5
|
+
import { CombinedDataTransformer } from '../transformer';
|
|
6
|
+
import { MaybePromise } from '../types';
|
|
7
|
+
import { HTTPRequest } from './types';
|
|
8
|
+
|
|
9
|
+
type GetInputs = (opts: {
|
|
10
|
+
req: HTTPRequest;
|
|
11
|
+
isBatchCall: boolean;
|
|
12
|
+
router: AnyRouter;
|
|
13
|
+
preprocessedBody: boolean;
|
|
14
|
+
}) => MaybePromise<Record<number, unknown>>;
|
|
15
|
+
|
|
16
|
+
export type BodyResult =
|
|
17
|
+
| {
|
|
18
|
+
ok: true;
|
|
19
|
+
data: unknown;
|
|
20
|
+
/**
|
|
21
|
+
* If the HTTP handler has already parsed the body
|
|
22
|
+
*/
|
|
23
|
+
preprocessed: boolean;
|
|
24
|
+
}
|
|
25
|
+
| { ok: false; error: TRPCError };
|
|
26
|
+
|
|
27
|
+
export type BaseContentTypeHandler<TOptions> = {
|
|
28
|
+
isMatch(opts: TOptions): boolean;
|
|
29
|
+
getBody: (opts: TOptions) => MaybePromise<BodyResult>;
|
|
30
|
+
getInputs: GetInputs;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function getRawProcedureInputOrThrow(opts: {
|
|
34
|
+
req: HTTPRequest;
|
|
35
|
+
preprocessedBody: boolean;
|
|
36
|
+
}) {
|
|
37
|
+
const { req } = opts;
|
|
38
|
+
try {
|
|
39
|
+
if (req.method === 'GET') {
|
|
40
|
+
if (!req.query.has('input')) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
const raw = req.query.get('input');
|
|
44
|
+
return JSON.parse(raw!);
|
|
45
|
+
}
|
|
46
|
+
if (!opts.preprocessedBody && typeof req.body === 'string') {
|
|
47
|
+
// A mutation with no inputs will have req.body === ''
|
|
48
|
+
return req.body.length === 0 ? undefined : JSON.parse(req.body);
|
|
49
|
+
}
|
|
50
|
+
return req.body;
|
|
51
|
+
} catch (err) {
|
|
52
|
+
throw new TRPCError({
|
|
53
|
+
code: 'PARSE_ERROR',
|
|
54
|
+
cause: getCauseFromUnknown(err),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const deserializeInputValue = (
|
|
60
|
+
rawValue: unknown,
|
|
61
|
+
transformer: CombinedDataTransformer,
|
|
62
|
+
) => {
|
|
63
|
+
return typeof rawValue !== 'undefined'
|
|
64
|
+
? transformer.input.deserialize(rawValue)
|
|
65
|
+
: rawValue;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const getJsonContentTypeInputs: GetInputs = (opts) => {
|
|
69
|
+
const rawInput = getRawProcedureInputOrThrow(opts);
|
|
70
|
+
const transformer = opts.router._def._config.transformer;
|
|
71
|
+
|
|
72
|
+
if (!opts.isBatchCall) {
|
|
73
|
+
return {
|
|
74
|
+
0: deserializeInputValue(rawInput, transformer),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* istanbul ignore if */
|
|
79
|
+
if (
|
|
80
|
+
rawInput == null ||
|
|
81
|
+
typeof rawInput !== 'object' ||
|
|
82
|
+
Array.isArray(rawInput)
|
|
83
|
+
) {
|
|
84
|
+
throw new TRPCError({
|
|
85
|
+
code: 'BAD_REQUEST',
|
|
86
|
+
message: '"input" needs to be an object when doing a batch call',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const input: Record<number, unknown> = {};
|
|
90
|
+
for (const key in rawInput) {
|
|
91
|
+
const k = key as any as number;
|
|
92
|
+
const rawValue = rawInput[k];
|
|
93
|
+
|
|
94
|
+
const value = deserializeInputValue(rawValue, transformer);
|
|
95
|
+
|
|
96
|
+
input[k] = value;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return input;
|
|
100
|
+
};
|
|
@@ -7,10 +7,13 @@ import {
|
|
|
7
7
|
inferRouterError,
|
|
8
8
|
} from '../core';
|
|
9
9
|
import { TRPCError, getTRPCErrorFromUnknown } from '../error/TRPCError';
|
|
10
|
-
import { getCauseFromUnknown } from '../error/utils';
|
|
11
10
|
import { TRPCResponse } from '../rpc';
|
|
12
|
-
import { transformTRPCResponse } from '../shared
|
|
11
|
+
import { transformTRPCResponse } from '../shared';
|
|
13
12
|
import { Maybe } from '../types';
|
|
13
|
+
import {
|
|
14
|
+
BaseContentTypeHandler,
|
|
15
|
+
getJsonContentTypeInputs,
|
|
16
|
+
} from './contentType';
|
|
14
17
|
import { getHTTPStatusCode } from './getHTTPStatusCode';
|
|
15
18
|
import { HTTPHeaders, HTTPResponse } from './internals/types';
|
|
16
19
|
import { HTTPBaseHandlerOptions, HTTPRequest } from './types';
|
|
@@ -22,31 +25,10 @@ const HTTP_METHOD_PROCEDURE_TYPE_MAP: Record<
|
|
|
22
25
|
GET: 'query',
|
|
23
26
|
POST: 'mutation',
|
|
24
27
|
};
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
const { req } = opts;
|
|
30
|
-
try {
|
|
31
|
-
if (req.method === 'GET') {
|
|
32
|
-
if (!req.query.has('input')) {
|
|
33
|
-
return undefined;
|
|
34
|
-
}
|
|
35
|
-
const raw = req.query.get('input');
|
|
36
|
-
return JSON.parse(raw!);
|
|
37
|
-
}
|
|
38
|
-
if (!opts.preprocessed && typeof req.body === 'string') {
|
|
39
|
-
// A mutation with no inputs will have req.body === ''
|
|
40
|
-
return req.body.length === 0 ? undefined : JSON.parse(req.body);
|
|
41
|
-
}
|
|
42
|
-
return req.body;
|
|
43
|
-
} catch (err) {
|
|
44
|
-
throw new TRPCError({
|
|
45
|
-
code: 'PARSE_ERROR',
|
|
46
|
-
cause: getCauseFromUnknown(err),
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
}
|
|
28
|
+
|
|
29
|
+
const fallbackContentTypeHandler = {
|
|
30
|
+
getInputs: getJsonContentTypeInputs,
|
|
31
|
+
};
|
|
50
32
|
|
|
51
33
|
interface ResolveHTTPRequestOptions<
|
|
52
34
|
TRouter extends AnyRouter,
|
|
@@ -56,6 +38,7 @@ interface ResolveHTTPRequestOptions<
|
|
|
56
38
|
req: TRequest;
|
|
57
39
|
path: string;
|
|
58
40
|
error?: Maybe<TRPCError>;
|
|
41
|
+
contentTypeHandler?: BaseContentTypeHandler<any>;
|
|
59
42
|
preprocessedBody?: boolean;
|
|
60
43
|
}
|
|
61
44
|
|
|
@@ -64,6 +47,9 @@ export async function resolveHTTPResponse<
|
|
|
64
47
|
TRequest extends HTTPRequest,
|
|
65
48
|
>(opts: ResolveHTTPRequestOptions<TRouter, TRequest>): Promise<HTTPResponse> {
|
|
66
49
|
const { router, req } = opts;
|
|
50
|
+
const contentTypeHandler =
|
|
51
|
+
opts.contentTypeHandler ?? fallbackContentTypeHandler;
|
|
52
|
+
|
|
67
53
|
const batchingEnabled = opts.batching?.enabled ?? true;
|
|
68
54
|
if (req.method === 'HEAD') {
|
|
69
55
|
// can be used for lambda warmup
|
|
@@ -138,50 +124,17 @@ export async function resolveHTTPResponse<
|
|
|
138
124
|
code: 'METHOD_NOT_SUPPORTED',
|
|
139
125
|
});
|
|
140
126
|
}
|
|
141
|
-
|
|
127
|
+
|
|
128
|
+
const inputs = await contentTypeHandler.getInputs({
|
|
129
|
+
isBatchCall,
|
|
142
130
|
req,
|
|
143
|
-
|
|
131
|
+
router,
|
|
132
|
+
preprocessedBody: opts.preprocessedBody ?? false,
|
|
144
133
|
});
|
|
145
134
|
|
|
146
135
|
paths = isBatchCall ? opts.path.split(',') : [opts.path];
|
|
147
136
|
ctx = await opts.createContext();
|
|
148
137
|
|
|
149
|
-
const deserializeInputValue = (rawValue: unknown) => {
|
|
150
|
-
return typeof rawValue !== 'undefined'
|
|
151
|
-
? router._def._config.transformer.input.deserialize(rawValue)
|
|
152
|
-
: rawValue;
|
|
153
|
-
};
|
|
154
|
-
const getInputs = (): Record<number, unknown> => {
|
|
155
|
-
if (!isBatchCall) {
|
|
156
|
-
return {
|
|
157
|
-
0: deserializeInputValue(rawInput),
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/* istanbul ignore if -- @preserve */
|
|
162
|
-
if (
|
|
163
|
-
rawInput == null ||
|
|
164
|
-
typeof rawInput !== 'object' ||
|
|
165
|
-
Array.isArray(rawInput)
|
|
166
|
-
) {
|
|
167
|
-
throw new TRPCError({
|
|
168
|
-
code: 'BAD_REQUEST',
|
|
169
|
-
message: '"input" needs to be an object when doing a batch call',
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
const input: Record<number, unknown> = {};
|
|
173
|
-
for (const key in rawInput) {
|
|
174
|
-
const k = key as any as number;
|
|
175
|
-
const rawValue = rawInput[k];
|
|
176
|
-
|
|
177
|
-
const value = deserializeInputValue(rawValue);
|
|
178
|
-
|
|
179
|
-
input[k] = value;
|
|
180
|
-
}
|
|
181
|
-
return input;
|
|
182
|
-
};
|
|
183
|
-
const inputs = getInputs();
|
|
184
|
-
|
|
185
138
|
const rawResults = await Promise.all(
|
|
186
139
|
paths.map(async (path, index) => {
|
|
187
140
|
const input = inputs[index];
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { TRPCError } from '../../../error/TRPCError';
|
|
2
|
-
import { NodeHTTPRequest } from '../types';
|
|
3
|
-
export declare function getPostBody(opts: {
|
|
4
|
-
req: NodeHTTPRequest;
|
|
5
|
-
maxBodySize?: number;
|
|
6
|
-
}): Promise<{
|
|
7
|
-
ok: true;
|
|
8
|
-
data: unknown;
|
|
9
|
-
preprocessed: boolean;
|
|
10
|
-
} | {
|
|
11
|
-
ok: false;
|
|
12
|
-
error: TRPCError;
|
|
13
|
-
}>;
|
|
14
|
-
//# sourceMappingURL=getPostBody.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getPostBody.d.ts","sourceRoot":"","sources":["../../../../src/adapters/node-http/internals/getPostBody.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,wBAAsB,WAAW,CAAC,IAAI,EAAE;IACtC,GAAG,EAAE,eAAe,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;QAGW,IAAI;UAAQ,OAAO;kBAAgB,OAAO;;QAC1C,KAAK;WAAS,SAAS;GA2BlC"}
|