@trpc/server 11.0.0-rc.607 → 11.0.0-rc.619
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/http.d.ts +1 -1
- package/dist/@trpc/server/http.d.ts.map +1 -1
- package/dist/adapters/fetch/fetchRequestHandler.js +1 -2
- package/dist/adapters/fetch/fetchRequestHandler.mjs +1 -2
- package/dist/adapters/node-http/incomingMessageToRequest.d.ts +1 -0
- package/dist/adapters/node-http/incomingMessageToRequest.d.ts.map +1 -1
- package/dist/adapters/node-http/incomingMessageToRequest.js +73 -38
- package/dist/adapters/node-http/incomingMessageToRequest.mjs +73 -39
- package/dist/adapters/node-http/index.js +1 -0
- package/dist/adapters/node-http/index.mjs +1 -1
- package/dist/adapters/standalone.d.ts.map +1 -1
- package/dist/adapters/standalone.js +2 -2
- package/dist/adapters/standalone.mjs +2 -2
- package/dist/adapters/ws.d.ts +1 -1
- package/dist/adapters/ws.d.ts.map +1 -1
- package/dist/adapters/ws.js +2 -2
- package/dist/adapters/ws.mjs +2 -2
- package/dist/bundle-analysis.json +94 -108
- package/dist/http.js +0 -2
- package/dist/http.mjs +0 -1
- package/dist/unstable-core-do-not-import.d.ts +0 -1
- package/dist/unstable-core-do-not-import.d.ts.map +1 -1
- package/dist/unstable-core-do-not-import.js +0 -2
- package/dist/unstable-core-do-not-import.mjs +0 -1
- package/package.json +2 -2
- package/src/@trpc/server/http.ts +0 -1
- package/src/adapters/fetch/fetchRequestHandler.ts +2 -2
- package/src/adapters/node-http/incomingMessageToRequest.ts +99 -39
- package/src/adapters/standalone.ts +7 -4
- package/src/adapters/ws.ts +3 -3
- package/src/unstable-core-do-not-import.ts +0 -1
- package/dist/unstable-core-do-not-import/http/toURL.d.ts +0 -2
- package/dist/unstable-core-do-not-import/http/toURL.d.ts.map +0 -1
- package/dist/unstable-core-do-not-import/http/toURL.js +0 -18
- package/dist/unstable-core-do-not-import/http/toURL.mjs +0 -16
- package/src/unstable-core-do-not-import/http/toURL.ts +0 -17
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type * as http from 'http';
|
|
2
2
|
import { TRPCError } from '../../@trpc/server';
|
|
3
|
-
import { toURL } from '../../http';
|
|
4
3
|
|
|
5
4
|
export interface IncomingMessageWithBody extends http.IncomingMessage {
|
|
6
5
|
/**
|
|
@@ -8,52 +7,112 @@ export interface IncomingMessageWithBody extends http.IncomingMessage {
|
|
|
8
7
|
*/
|
|
9
8
|
body?: unknown;
|
|
10
9
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
|
|
11
|
+
function createBody(
|
|
12
|
+
req: http.IncomingMessage,
|
|
13
|
+
opts: {
|
|
14
|
+
/**
|
|
15
|
+
* Max body size in bytes. If the body is larger than this, the request will be aborted
|
|
16
|
+
*/
|
|
17
|
+
maxBodySize: number | null;
|
|
18
|
+
},
|
|
19
|
+
): RequestInit['body'] {
|
|
20
|
+
// Some adapters will pre-parse the body and add it to the request object
|
|
21
|
+
if ('body' in req) {
|
|
22
|
+
// If the body is already a string, return it directly
|
|
23
|
+
if (typeof req.body === 'string') {
|
|
24
|
+
return req.body;
|
|
25
|
+
}
|
|
26
|
+
// If body exists but isn't a string, stringify it as JSON
|
|
27
|
+
else if (req.body !== undefined) {
|
|
28
|
+
return JSON.stringify(req.body);
|
|
29
|
+
}
|
|
30
|
+
// If body property exists but is undefined, return undefined
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
19
33
|
let size = 0;
|
|
20
|
-
const maxBodySize = opts.maxBodySize;
|
|
21
34
|
let hasClosed = false;
|
|
22
35
|
|
|
23
|
-
|
|
36
|
+
return new ReadableStream({
|
|
24
37
|
start(controller) {
|
|
25
|
-
|
|
38
|
+
const onData = (chunk: Buffer) => {
|
|
26
39
|
size += chunk.length;
|
|
27
|
-
if (maxBodySize
|
|
28
|
-
controller.
|
|
29
|
-
new
|
|
30
|
-
code: 'PAYLOAD_TOO_LARGE',
|
|
31
|
-
}),
|
|
40
|
+
if (!opts.maxBodySize || size <= opts.maxBodySize) {
|
|
41
|
+
controller.enqueue(
|
|
42
|
+
new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength),
|
|
32
43
|
);
|
|
33
|
-
// an error is thrown if we try to close the controller after
|
|
34
|
-
// erroring, so track the closure
|
|
35
|
-
hasClosed = true;
|
|
36
44
|
return;
|
|
37
45
|
}
|
|
38
|
-
controller.
|
|
39
|
-
|
|
40
|
-
|
|
46
|
+
controller.error(
|
|
47
|
+
new TRPCError({
|
|
48
|
+
code: 'PAYLOAD_TOO_LARGE',
|
|
49
|
+
}),
|
|
50
|
+
);
|
|
51
|
+
hasClosed = true;
|
|
52
|
+
req.off('data', onData);
|
|
53
|
+
req.off('end', onEnd);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const onEnd = () => {
|
|
41
57
|
if (hasClosed) {
|
|
42
58
|
return;
|
|
43
59
|
}
|
|
44
60
|
hasClosed = true;
|
|
61
|
+
req.off('data', onData);
|
|
62
|
+
req.off('end', onEnd);
|
|
45
63
|
controller.close();
|
|
46
|
-
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
req.on('data', onData);
|
|
67
|
+
req.on('end', onEnd);
|
|
47
68
|
},
|
|
48
69
|
cancel() {
|
|
49
70
|
req.destroy();
|
|
50
71
|
},
|
|
51
72
|
});
|
|
73
|
+
}
|
|
74
|
+
export function createURL(req: http.IncomingMessage): URL {
|
|
75
|
+
try {
|
|
76
|
+
const protocol =
|
|
77
|
+
req.socket && 'encrypted' in req.socket && req.socket.encrypted
|
|
78
|
+
? 'https:'
|
|
79
|
+
: 'http:';
|
|
52
80
|
|
|
53
|
-
|
|
81
|
+
const host = req.headers.host ?? 'localhost';
|
|
82
|
+
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
84
|
+
return new URL(req.url!, `${protocol}//${host}`);
|
|
85
|
+
} catch (cause) {
|
|
86
|
+
throw new TRPCError({
|
|
87
|
+
code: 'BAD_REQUEST',
|
|
88
|
+
message: 'Invalid URL',
|
|
89
|
+
cause,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function createHeaders(incoming: http.IncomingHttpHeaders): Headers {
|
|
95
|
+
const headers = new Headers();
|
|
96
|
+
|
|
97
|
+
for (const key in incoming) {
|
|
98
|
+
const value = incoming[key];
|
|
99
|
+
if (typeof key === 'string' && key.startsWith(':')) {
|
|
100
|
+
// Skip HTTP/2 pseudo-headers
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (Array.isArray(value)) {
|
|
105
|
+
for (const item of value) {
|
|
106
|
+
headers.append(key, item);
|
|
107
|
+
}
|
|
108
|
+
} else if (value != null) {
|
|
109
|
+
headers.append(key, value);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return headers;
|
|
54
114
|
}
|
|
55
115
|
|
|
56
|
-
const bodyMethods = ['POST', 'PUT', 'PATCH'];
|
|
57
116
|
/**
|
|
58
117
|
* Convert an [`IncomingMessage`](https://nodejs.org/api/http.html#class-httpincomingmessage) to a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request)
|
|
59
118
|
*/
|
|
@@ -67,29 +126,30 @@ export function incomingMessageToRequest(
|
|
|
67
126
|
},
|
|
68
127
|
): Request {
|
|
69
128
|
const ac = new AbortController();
|
|
70
|
-
const headers = new Headers(req.headers as any);
|
|
71
|
-
const url = toURL(`http://${headers.get('host')}${req.url}`);
|
|
72
129
|
req.once('aborted', () => {
|
|
73
130
|
ac.abort();
|
|
74
131
|
});
|
|
75
132
|
|
|
133
|
+
// Get host from either regular header or HTTP/2 pseudo-header
|
|
134
|
+
const url = createURL(req);
|
|
135
|
+
|
|
76
136
|
const init: RequestInit = {
|
|
77
|
-
headers,
|
|
137
|
+
headers: createHeaders(req.headers),
|
|
78
138
|
method: req.method,
|
|
79
139
|
signal: ac.signal,
|
|
80
|
-
// @ts-expect-error this is fine
|
|
81
|
-
duplex: 'half',
|
|
82
140
|
};
|
|
83
141
|
|
|
84
|
-
if (req.method &&
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
142
|
+
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
|
143
|
+
init.body = createBody(req, opts);
|
|
144
|
+
|
|
145
|
+
// init.duplex = 'half' must be set when body is a ReadableStream, and Node follows the spec.
|
|
146
|
+
// However, this property is not defined in the TypeScript types for RequestInit, so we have
|
|
147
|
+
// to cast it here in order to set it without a type error.
|
|
148
|
+
// See https://fetch.spec.whatwg.org/#dom-requestinit-duplex
|
|
149
|
+
// @ts-expect-error this is fine
|
|
150
|
+
init.duplex = 'half';
|
|
92
151
|
}
|
|
152
|
+
|
|
93
153
|
const request = new Request(url, init);
|
|
94
154
|
|
|
95
155
|
return request;
|
|
@@ -7,18 +7,21 @@
|
|
|
7
7
|
* import type { HTTPBaseHandlerOptions } from '@trpc/server/http'
|
|
8
8
|
* ```
|
|
9
9
|
*/
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
import http from 'http';
|
|
12
12
|
// @trpc/server
|
|
13
13
|
import { type AnyRouter } from '../@trpc/server';
|
|
14
|
-
import { toURL } from '../@trpc/server/http';
|
|
15
14
|
// eslint-disable-next-line no-restricted-imports
|
|
16
15
|
import { run } from '../unstable-core-do-not-import';
|
|
17
16
|
import type {
|
|
18
17
|
NodeHTTPCreateContextFnOptions,
|
|
19
18
|
NodeHTTPHandlerOptions,
|
|
20
19
|
} from './node-http';
|
|
21
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
createURL,
|
|
22
|
+
internal_exceptionHandler,
|
|
23
|
+
nodeHTTPRequestHandler,
|
|
24
|
+
} from './node-http';
|
|
22
25
|
|
|
23
26
|
export type CreateHTTPHandlerOptions<TRouter extends AnyRouter> =
|
|
24
27
|
NodeHTTPHandlerOptions<TRouter, http.IncomingMessage, http.ServerResponse>;
|
|
@@ -37,7 +40,7 @@ export function createHTTPHandler<TRouter extends AnyRouter>(
|
|
|
37
40
|
return (req, res) => {
|
|
38
41
|
let path = '';
|
|
39
42
|
run(async () => {
|
|
40
|
-
const url =
|
|
43
|
+
const url = createURL(req);
|
|
41
44
|
|
|
42
45
|
// get procedure path and remove the leading slash
|
|
43
46
|
// /procedure -> procedure
|
package/src/adapters/ws.ts
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
TRPCError,
|
|
14
14
|
} from '../@trpc/server';
|
|
15
15
|
import type { TRPCRequestInfo } from '../@trpc/server/http';
|
|
16
|
-
import {
|
|
16
|
+
import { type BaseHandlerOptions } from '../@trpc/server/http';
|
|
17
17
|
import { parseTRPCMessage } from '../@trpc/server/rpc';
|
|
18
18
|
// @trpc/server/rpc
|
|
19
19
|
import type {
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
type MaybePromise,
|
|
35
35
|
} from '../unstable-core-do-not-import';
|
|
36
36
|
import { Unpromise } from '../vendor/unpromise';
|
|
37
|
-
import type
|
|
37
|
+
import { createURL, type NodeHTTPCreateContextFnOptions } from './node-http';
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
* Importing ws causes a build error
|
|
@@ -178,7 +178,7 @@ export function getWSConnectionHandler<TRouter extends AnyRouter>(
|
|
|
178
178
|
* - if connection params are expected, they will be created once received
|
|
179
179
|
*/
|
|
180
180
|
let ctxPromise =
|
|
181
|
-
|
|
181
|
+
createURL(req).searchParams.get('connectionParams') === '1'
|
|
182
182
|
? unsetContextPromiseSymbol
|
|
183
183
|
: createCtxPromise(() => null);
|
|
184
184
|
|
|
@@ -22,7 +22,6 @@ export * from './unstable-core-do-not-import/http/formDataToObject';
|
|
|
22
22
|
export * from './unstable-core-do-not-import/http/getHTTPStatusCode';
|
|
23
23
|
export * from './unstable-core-do-not-import/http/parseConnectionParams';
|
|
24
24
|
export * from './unstable-core-do-not-import/http/resolveResponse';
|
|
25
|
-
export * from './unstable-core-do-not-import/http/toURL';
|
|
26
25
|
export * from './unstable-core-do-not-import/http/types';
|
|
27
26
|
export * from './unstable-core-do-not-import/initTRPC';
|
|
28
27
|
export * from './unstable-core-do-not-import/middleware';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"toURL.d.ts","sourceRoot":"","sources":["../../../src/unstable-core-do-not-import/http/toURL.ts"],"names":[],"mappings":"AAEA,wBAAgB,KAAK,CAAC,aAAa,EAAE,MAAM,GAAG,GAAG,CAchD"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var TRPCError = require('../error/TRPCError.js');
|
|
4
|
-
|
|
5
|
-
function toURL(urlOrPathname) {
|
|
6
|
-
try {
|
|
7
|
-
const url = urlOrPathname.startsWith('/') ? `http://127.0.0.1${urlOrPathname}` : urlOrPathname;
|
|
8
|
-
return new URL(url);
|
|
9
|
-
} catch (cause) {
|
|
10
|
-
throw new TRPCError.TRPCError({
|
|
11
|
-
code: 'BAD_REQUEST',
|
|
12
|
-
message: 'Invalid URL',
|
|
13
|
-
cause
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
exports.toURL = toURL;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { TRPCError } from '../error/TRPCError.mjs';
|
|
2
|
-
|
|
3
|
-
function toURL(urlOrPathname) {
|
|
4
|
-
try {
|
|
5
|
-
const url = urlOrPathname.startsWith('/') ? `http://127.0.0.1${urlOrPathname}` : urlOrPathname;
|
|
6
|
-
return new URL(url);
|
|
7
|
-
} catch (cause) {
|
|
8
|
-
throw new TRPCError({
|
|
9
|
-
code: 'BAD_REQUEST',
|
|
10
|
-
message: 'Invalid URL',
|
|
11
|
-
cause
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export { toURL };
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { TRPCError } from '../error/TRPCError';
|
|
2
|
-
|
|
3
|
-
export function toURL(urlOrPathname: string): URL {
|
|
4
|
-
try {
|
|
5
|
-
const url = urlOrPathname.startsWith('/')
|
|
6
|
-
? `http://127.0.0.1${urlOrPathname}`
|
|
7
|
-
: urlOrPathname;
|
|
8
|
-
|
|
9
|
-
return new URL(url);
|
|
10
|
-
} catch (cause) {
|
|
11
|
-
throw new TRPCError({
|
|
12
|
-
code: 'BAD_REQUEST',
|
|
13
|
-
message: 'Invalid URL',
|
|
14
|
-
cause,
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
}
|