srvx 0.2.5 → 0.2.7
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/README.md +1 -1
- package/dist/adapters/bun.d.mts +5 -4
- package/dist/adapters/bun.mjs +9 -1
- package/dist/adapters/cloudflare.d.mts +1 -0
- package/dist/adapters/deno.d.mts +2 -1
- package/dist/adapters/deno.mjs +9 -2
- package/dist/adapters/node.d.mts +8 -7
- package/dist/adapters/node.mjs +219 -181
- package/dist/shared/srvx.lC_d9z2b.mjs +57 -0
- package/dist/types.d.mts +30 -4
- package/package.json +17 -13
- package/dist/shared/srvx.PbkQy9Ck.mjs +0 -18
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
Universal Server API based on web platform standards. Works with [Deno](https://deno.com/), [Bun](https://bun.sh/) and [Node.js](https://nodejs.org/en).
|
|
11
11
|
|
|
12
|
-
- ✅ Seamless runtime integration with identical usage ([handler](https://srvx.unjs.io/guide/handler) and
|
|
12
|
+
- ✅ Seamless runtime integration with identical usage ([handler](https://srvx.unjs.io/guide/handler) and [instance](https://srvx.unjs.io/guide/server))
|
|
13
13
|
- ✅ Zero overhead [Deno](https://deno.com/) and [Bun](https://bun.sh/) support
|
|
14
14
|
- ✅ [Node.js compatibility](https://srvx.unjs.io/guide/node) with ~native perf and [fast response](https://srvx.unjs.io/guide/node#fast-response) support
|
|
15
15
|
|
package/dist/adapters/bun.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { ServerOptions, Server,
|
|
1
|
+
import { ServerOptions, Server, BunFetchHandler } from '../types.mjs';
|
|
2
2
|
import * as Bun from 'bun';
|
|
3
3
|
import 'node:http';
|
|
4
|
+
import 'node:https';
|
|
4
5
|
import 'node:net';
|
|
5
6
|
import '@cloudflare/workers-types';
|
|
6
7
|
|
|
@@ -12,12 +13,12 @@ declare const Response: {
|
|
|
12
13
|
redirect(url: string | URL, status?: number): Response;
|
|
13
14
|
};
|
|
14
15
|
declare function serve(options: ServerOptions): BunServer;
|
|
15
|
-
declare class BunServer implements Server<
|
|
16
|
+
declare class BunServer implements Server<BunFetchHandler> {
|
|
16
17
|
readonly runtime = "bun";
|
|
17
18
|
readonly options: ServerOptions;
|
|
18
19
|
readonly bun: Server["bun"];
|
|
19
|
-
readonly serveOptions: Bun.ServeOptions;
|
|
20
|
-
readonly fetch:
|
|
20
|
+
readonly serveOptions: Bun.ServeOptions | Bun.TLSServeOptions;
|
|
21
|
+
readonly fetch: BunFetchHandler;
|
|
21
22
|
constructor(options: ServerOptions);
|
|
22
23
|
serve(): Promise<Awaited<this>>;
|
|
23
24
|
get url(): string | undefined;
|
package/dist/adapters/bun.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { r as resolvePort } from '../shared/srvx.
|
|
1
|
+
import { r as resolveTLSOptions, a as resolvePort } from '../shared/srvx.lC_d9z2b.mjs';
|
|
2
2
|
import { w as wrapFetch } from '../shared/srvx.DhN4g5wJ.mjs';
|
|
3
|
+
import 'node:fs';
|
|
3
4
|
|
|
4
5
|
const Response = globalThis.Response;
|
|
5
6
|
function serve(options) {
|
|
@@ -21,11 +22,18 @@ class BunServer {
|
|
|
21
22
|
});
|
|
22
23
|
return fetchHandler(request);
|
|
23
24
|
};
|
|
25
|
+
const tls = resolveTLSOptions(this.options);
|
|
24
26
|
this.serveOptions = {
|
|
25
27
|
hostname: this.options.hostname,
|
|
26
28
|
reusePort: this.options.reusePort,
|
|
27
29
|
port: resolvePort(this.options.port, globalThis.process?.env.PORT),
|
|
28
30
|
...this.options.bun,
|
|
31
|
+
tls: {
|
|
32
|
+
cert: tls?.cert,
|
|
33
|
+
key: tls?.key,
|
|
34
|
+
passphrase: tls?.passphrase,
|
|
35
|
+
...this.options.bun?.tls
|
|
36
|
+
},
|
|
29
37
|
fetch: this.fetch
|
|
30
38
|
};
|
|
31
39
|
if (!options.manual) {
|
package/dist/adapters/deno.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ServerOptions, Server, DenoFetchHandler } from '../types.mjs';
|
|
2
2
|
import 'node:http';
|
|
3
|
+
import 'node:https';
|
|
3
4
|
import 'node:net';
|
|
4
5
|
import 'bun';
|
|
5
6
|
import '@cloudflare/workers-types';
|
|
@@ -17,7 +18,7 @@ declare class DenoServer implements Server<DenoFetchHandler> {
|
|
|
17
18
|
readonly runtime = "deno";
|
|
18
19
|
readonly options: ServerOptions;
|
|
19
20
|
readonly deno: Server["deno"];
|
|
20
|
-
readonly serveOptions: Deno.ServeTcpOptions;
|
|
21
|
+
readonly serveOptions: Deno.ServeTcpOptions | (Deno.ServeTcpOptions & Deno.TlsCertifiedKeyPem);
|
|
21
22
|
readonly fetch: DenoFetchHandler;
|
|
22
23
|
constructor(options: ServerOptions);
|
|
23
24
|
serve(): Promise<this>;
|
package/dist/adapters/deno.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { r as resolvePort, f as fmtURL } from '../shared/srvx.
|
|
1
|
+
import { r as resolveTLSOptions, a as resolvePort, f as fmtURL } from '../shared/srvx.lC_d9z2b.mjs';
|
|
2
2
|
import { w as wrapFetch } from '../shared/srvx.DhN4g5wJ.mjs';
|
|
3
|
+
import 'node:fs';
|
|
3
4
|
|
|
4
5
|
const Response = globalThis.Response;
|
|
5
6
|
function serve(options) {
|
|
@@ -21,10 +22,12 @@ class DenoServer {
|
|
|
21
22
|
});
|
|
22
23
|
return fetchHandler(request);
|
|
23
24
|
};
|
|
25
|
+
const tls = resolveTLSOptions(this.options);
|
|
24
26
|
this.serveOptions = {
|
|
25
27
|
port: resolvePort(this.options.port, globalThis.Deno?.env.get("PORT")),
|
|
26
28
|
hostname: this.options.hostname,
|
|
27
29
|
reusePort: this.options.reusePort,
|
|
30
|
+
...tls ? { key: tls.key, cert: tls.cert, passphrase: tls.passphrase } : {},
|
|
28
31
|
...this.options.deno
|
|
29
32
|
};
|
|
30
33
|
if (!options.manual) {
|
|
@@ -55,7 +58,11 @@ class DenoServer {
|
|
|
55
58
|
return Promise.resolve(this.#listeningPromise).then(() => this);
|
|
56
59
|
}
|
|
57
60
|
get url() {
|
|
58
|
-
return this.#listeningInfo ? fmtURL(
|
|
61
|
+
return this.#listeningInfo ? fmtURL(
|
|
62
|
+
this.#listeningInfo.hostname,
|
|
63
|
+
this.#listeningInfo.port,
|
|
64
|
+
!!this.serveOptions.cert
|
|
65
|
+
) : void 0;
|
|
59
66
|
}
|
|
60
67
|
ready() {
|
|
61
68
|
return Promise.resolve(this.#listeningPromise).then(() => this);
|
package/dist/adapters/node.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ServerOptions, Server, FetchHandler, NodeHttpHandler } from '../types.mjs';
|
|
2
2
|
import NodeHttp__default from 'node:http';
|
|
3
3
|
import { Readable } from 'node:stream';
|
|
4
|
+
import 'node:https';
|
|
4
5
|
import 'node:net';
|
|
5
6
|
import 'bun';
|
|
6
7
|
import '@cloudflare/workers-types';
|
|
@@ -13,8 +14,8 @@ type NodeFastResponse = InstanceType<typeof NodeFastResponse>;
|
|
|
13
14
|
*/
|
|
14
15
|
declare const NodeFastResponse: {
|
|
15
16
|
new (body?: BodyInit | null, init?: ResponseInit): {
|
|
16
|
-
"__#
|
|
17
|
-
"__#
|
|
17
|
+
"__#4363@#body"?: BodyInit | null;
|
|
18
|
+
"__#4363@#init"?: ResponseInit;
|
|
18
19
|
/**
|
|
19
20
|
* Prepare Node.js response object
|
|
20
21
|
*/
|
|
@@ -25,11 +26,11 @@ declare const NodeFastResponse: {
|
|
|
25
26
|
body: string | Uint8Array<ArrayBufferLike> | ReadableStream<Uint8Array<ArrayBufferLike>> | Readable | Buffer<ArrayBufferLike> | DataView<ArrayBufferLike> | null | undefined;
|
|
26
27
|
};
|
|
27
28
|
/** Lazy initialized response instance */
|
|
28
|
-
"__#
|
|
29
|
+
"__#4363@#responseObj"?: globalThis.Response;
|
|
29
30
|
/** Lazy initialized headers instance */
|
|
30
|
-
"__#
|
|
31
|
-
clone(): Response;
|
|
32
|
-
readonly "__#
|
|
31
|
+
"__#4363@#headersObj"?: Headers;
|
|
32
|
+
clone(): globalThis.Response;
|
|
33
|
+
readonly "__#4363@#response": globalThis.Response;
|
|
33
34
|
readonly headers: Headers;
|
|
34
35
|
readonly ok: boolean;
|
|
35
36
|
readonly redirected: boolean;
|
|
@@ -37,7 +38,7 @@ declare const NodeFastResponse: {
|
|
|
37
38
|
readonly statusText: string;
|
|
38
39
|
readonly type: ResponseType;
|
|
39
40
|
readonly url: string;
|
|
40
|
-
"__#
|
|
41
|
+
"__#4363@#fastBody"<T extends object>(as: new (...args: any[]) => T): T | null | false;
|
|
41
42
|
readonly body: ReadableStream<Uint8Array> | null;
|
|
42
43
|
readonly bodyUsed: boolean;
|
|
43
44
|
arrayBuffer(): Promise<ArrayBuffer>;
|
package/dist/adapters/node.mjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import NodeHttp from 'node:http';
|
|
2
|
+
import NodeHttps from 'node:https';
|
|
2
3
|
import { splitSetCookieString } from 'cookie-es';
|
|
3
|
-
import { r as resolvePort, f as fmtURL } from '../shared/srvx.
|
|
4
|
+
import { r as resolveTLSOptions, a as resolvePort, f as fmtURL } from '../shared/srvx.lC_d9z2b.mjs';
|
|
4
5
|
import { w as wrapFetch } from '../shared/srvx.DhN4g5wJ.mjs';
|
|
6
|
+
import 'node:fs';
|
|
5
7
|
|
|
6
8
|
async function sendNodeResponse(nodeRes, webRes) {
|
|
7
9
|
if (!webRes) {
|
|
@@ -11,7 +13,7 @@ async function sendNodeResponse(nodeRes, webRes) {
|
|
|
11
13
|
if (webRes.nodeResponse) {
|
|
12
14
|
const res = webRes.nodeResponse();
|
|
13
15
|
if (!nodeRes.headersSent) {
|
|
14
|
-
nodeRes.writeHead(res.status, res.statusText, res.headers);
|
|
16
|
+
nodeRes.writeHead(res.status, res.statusText, res.headers.flat());
|
|
15
17
|
}
|
|
16
18
|
if (res.body) {
|
|
17
19
|
if (res.body instanceof ReadableStream) {
|
|
@@ -35,7 +37,11 @@ async function sendNodeResponse(nodeRes, webRes) {
|
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
if (!nodeRes.headersSent) {
|
|
38
|
-
nodeRes.writeHead(
|
|
40
|
+
nodeRes.writeHead(
|
|
41
|
+
webRes.status || 200,
|
|
42
|
+
webRes.statusText,
|
|
43
|
+
headerEntries.flat()
|
|
44
|
+
);
|
|
39
45
|
}
|
|
40
46
|
return webRes.body ? streamBody(webRes.body, nodeRes) : endNodeResponse(nodeRes);
|
|
41
47
|
}
|
|
@@ -83,19 +89,18 @@ function streamBody(stream, nodeRes) {
|
|
|
83
89
|
});
|
|
84
90
|
}
|
|
85
91
|
|
|
86
|
-
const kNodeReq = /* @__PURE__ */ Symbol.for("srvx.node.request");
|
|
87
92
|
const kNodeInspect = /* @__PURE__ */ Symbol.for(
|
|
88
93
|
"nodejs.util.inspect.custom"
|
|
89
94
|
);
|
|
90
95
|
|
|
91
96
|
const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
|
|
92
|
-
class
|
|
93
|
-
constructor(
|
|
94
|
-
this
|
|
97
|
+
const _Headers = class Headers {
|
|
98
|
+
constructor(nodeCtx) {
|
|
99
|
+
this.node = nodeCtx;
|
|
95
100
|
}
|
|
96
101
|
append(name, value) {
|
|
97
102
|
name = name.toLowerCase();
|
|
98
|
-
const _headers = this
|
|
103
|
+
const _headers = this.node.req.headers;
|
|
99
104
|
const _current = _headers[name];
|
|
100
105
|
if (_current) {
|
|
101
106
|
if (Array.isArray(_current)) {
|
|
@@ -109,14 +114,14 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
|
|
|
109
114
|
}
|
|
110
115
|
delete(name) {
|
|
111
116
|
name = name.toLowerCase();
|
|
112
|
-
this
|
|
117
|
+
this.node.req.headers[name] = void 0;
|
|
113
118
|
}
|
|
114
119
|
get(name) {
|
|
115
120
|
name = name.toLowerCase();
|
|
116
|
-
return _normalizeValue(this
|
|
121
|
+
return _normalizeValue(this.node.req.headers[name]);
|
|
117
122
|
}
|
|
118
123
|
getSetCookie() {
|
|
119
|
-
const setCookie = this
|
|
124
|
+
const setCookie = this.node.req.headers["set-cookie"];
|
|
120
125
|
if (!setCookie || setCookie.length === 0) {
|
|
121
126
|
return [];
|
|
122
127
|
}
|
|
@@ -124,11 +129,11 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
|
|
|
124
129
|
}
|
|
125
130
|
has(name) {
|
|
126
131
|
name = name.toLowerCase();
|
|
127
|
-
return !!this
|
|
132
|
+
return !!this.node.req.headers[name];
|
|
128
133
|
}
|
|
129
134
|
set(name, value) {
|
|
130
135
|
name = name.toLowerCase();
|
|
131
|
-
this
|
|
136
|
+
this.node.req.headers[name] = value;
|
|
132
137
|
}
|
|
133
138
|
get count() {
|
|
134
139
|
throw new Error("Method not implemented.");
|
|
@@ -137,7 +142,7 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
|
|
|
137
142
|
throw new Error("Method not implemented.");
|
|
138
143
|
}
|
|
139
144
|
toJSON() {
|
|
140
|
-
const _headers = this
|
|
145
|
+
const _headers = this.node.req.headers;
|
|
141
146
|
const result = {};
|
|
142
147
|
for (const key in _headers) {
|
|
143
148
|
if (_headers[key]) {
|
|
@@ -147,7 +152,7 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
|
|
|
147
152
|
return result;
|
|
148
153
|
}
|
|
149
154
|
forEach(cb, thisArg) {
|
|
150
|
-
const _headers = this
|
|
155
|
+
const _headers = this.node.req.headers;
|
|
151
156
|
for (const key in _headers) {
|
|
152
157
|
if (_headers[key]) {
|
|
153
158
|
cb.call(
|
|
@@ -160,24 +165,24 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
|
|
|
160
165
|
}
|
|
161
166
|
}
|
|
162
167
|
*entries() {
|
|
163
|
-
const _headers = this
|
|
168
|
+
const _headers = this.node.req.headers;
|
|
164
169
|
for (const key in _headers) {
|
|
165
170
|
yield [key, _normalizeValue(_headers[key])];
|
|
166
171
|
}
|
|
167
172
|
}
|
|
168
173
|
*keys() {
|
|
169
|
-
const keys = Object.keys(this
|
|
174
|
+
const keys = Object.keys(this.node.req.headers);
|
|
170
175
|
for (const key of keys) {
|
|
171
176
|
yield key;
|
|
172
177
|
}
|
|
173
178
|
}
|
|
174
179
|
*values() {
|
|
175
|
-
const values = Object.values(this
|
|
180
|
+
const values = Object.values(this.node.req.headers);
|
|
176
181
|
for (const value of values) {
|
|
177
182
|
yield _normalizeValue(value);
|
|
178
183
|
}
|
|
179
184
|
}
|
|
180
|
-
[
|
|
185
|
+
[Symbol.iterator]() {
|
|
181
186
|
return this.entries()[Symbol.iterator]();
|
|
182
187
|
}
|
|
183
188
|
get [Symbol.toStringTag]() {
|
|
@@ -186,9 +191,9 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
|
|
|
186
191
|
[kNodeInspect]() {
|
|
187
192
|
return Object.fromEntries(this.entries());
|
|
188
193
|
}
|
|
189
|
-
}
|
|
190
|
-
Object.setPrototypeOf(
|
|
191
|
-
return
|
|
194
|
+
};
|
|
195
|
+
Object.setPrototypeOf(_Headers.prototype, globalThis.Headers.prototype);
|
|
196
|
+
return _Headers;
|
|
192
197
|
})();
|
|
193
198
|
function _normalizeValue(value) {
|
|
194
199
|
if (Array.isArray(value)) {
|
|
@@ -197,149 +202,171 @@ function _normalizeValue(value) {
|
|
|
197
202
|
return value || "";
|
|
198
203
|
}
|
|
199
204
|
|
|
200
|
-
const NodeReqURLProxy = /* @__PURE__ */ (() =>
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
205
|
+
const NodeReqURLProxy = /* @__PURE__ */ (() => {
|
|
206
|
+
const _URL = class URL {
|
|
207
|
+
constructor(nodeCtx) {
|
|
208
|
+
this._hash = "";
|
|
209
|
+
this._username = "";
|
|
210
|
+
this._password = "";
|
|
211
|
+
this.node = nodeCtx;
|
|
212
|
+
}
|
|
213
|
+
get hash() {
|
|
214
|
+
return this._hash;
|
|
215
|
+
}
|
|
216
|
+
set hash(value) {
|
|
217
|
+
this._hash = value;
|
|
218
|
+
}
|
|
219
|
+
get username() {
|
|
220
|
+
return this._username;
|
|
221
|
+
}
|
|
222
|
+
set username(value) {
|
|
223
|
+
this._username = value;
|
|
224
|
+
}
|
|
225
|
+
get password() {
|
|
226
|
+
return this._password;
|
|
227
|
+
}
|
|
228
|
+
set password(value) {
|
|
229
|
+
this._password = value;
|
|
230
|
+
}
|
|
231
|
+
// host
|
|
232
|
+
get host() {
|
|
233
|
+
return this.node.req.headers.host || "";
|
|
234
|
+
}
|
|
235
|
+
set host(value) {
|
|
236
|
+
this._hostname = void 0;
|
|
237
|
+
this._port = void 0;
|
|
238
|
+
this.node.req.headers.host = value;
|
|
239
|
+
}
|
|
240
|
+
// hostname
|
|
241
|
+
get hostname() {
|
|
242
|
+
if (this._hostname === void 0) {
|
|
243
|
+
const [hostname, port] = parseHost(this.node.req.headers.host);
|
|
244
|
+
if (this._port === void 0 && port) {
|
|
245
|
+
this._port = String(Number.parseInt(port) || "");
|
|
246
|
+
}
|
|
247
|
+
this._hostname = hostname || "localhost";
|
|
222
248
|
}
|
|
223
|
-
this._hostname
|
|
249
|
+
return this._hostname;
|
|
224
250
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
this.
|
|
251
|
+
set hostname(value) {
|
|
252
|
+
this._hostname = value;
|
|
253
|
+
}
|
|
254
|
+
// port
|
|
255
|
+
get port() {
|
|
256
|
+
if (this._port === void 0) {
|
|
257
|
+
const [hostname, port] = parseHost(this.node.req.headers.host);
|
|
258
|
+
if (this._hostname === void 0 && hostname) {
|
|
259
|
+
this._hostname = hostname;
|
|
260
|
+
}
|
|
261
|
+
this._port = port || String(this.node.req.socket?.localPort || "");
|
|
236
262
|
}
|
|
237
|
-
this._port
|
|
263
|
+
return this._port;
|
|
238
264
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
265
|
+
set port(value) {
|
|
266
|
+
this._port = String(Number.parseInt(value) || "");
|
|
267
|
+
}
|
|
268
|
+
// pathname
|
|
269
|
+
get pathname() {
|
|
270
|
+
if (this._pathname === void 0) {
|
|
271
|
+
const [pathname, search] = parsePath(this.node.req.url || "/");
|
|
272
|
+
this._pathname = pathname;
|
|
273
|
+
if (this._search === void 0) {
|
|
274
|
+
this._search = search;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return this._pathname;
|
|
278
|
+
}
|
|
279
|
+
set pathname(value) {
|
|
280
|
+
if (value[0] !== "/") {
|
|
281
|
+
value = "/" + value;
|
|
282
|
+
}
|
|
283
|
+
if (value === this._pathname) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
this._pathname = value;
|
|
287
|
+
this.node.req.url = value + this.search;
|
|
288
|
+
}
|
|
289
|
+
// search
|
|
290
|
+
get search() {
|
|
249
291
|
if (this._search === void 0) {
|
|
292
|
+
const [pathname, search] = parsePath(this.node.req.url || "/");
|
|
250
293
|
this._search = search;
|
|
294
|
+
if (this._pathname === void 0) {
|
|
295
|
+
this._pathname = pathname;
|
|
296
|
+
}
|
|
251
297
|
}
|
|
298
|
+
return this._search;
|
|
252
299
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
300
|
+
set search(value) {
|
|
301
|
+
if (value === "?") {
|
|
302
|
+
value = "";
|
|
303
|
+
} else if (value && value[0] !== "?") {
|
|
304
|
+
value = "?" + value;
|
|
305
|
+
}
|
|
306
|
+
if (value === this._search) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
this._search = value;
|
|
310
|
+
this._searchParams = void 0;
|
|
311
|
+
this.node.req.url = this.pathname + value;
|
|
258
312
|
}
|
|
259
|
-
|
|
260
|
-
|
|
313
|
+
// searchParams
|
|
314
|
+
get searchParams() {
|
|
315
|
+
if (!this._searchParams) {
|
|
316
|
+
this._searchParams = new URLSearchParams(this.search);
|
|
317
|
+
}
|
|
318
|
+
return this._searchParams;
|
|
261
319
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
if (this._pathname === void 0) {
|
|
271
|
-
this._pathname = pathname;
|
|
320
|
+
set searchParams(value) {
|
|
321
|
+
this._searchParams = value;
|
|
322
|
+
this._search = value.toString();
|
|
323
|
+
}
|
|
324
|
+
// protocol
|
|
325
|
+
get protocol() {
|
|
326
|
+
if (!this._protocol) {
|
|
327
|
+
this._protocol = this.node.req.socket?.encrypted || this.node.req.headers["x-forwarded-proto"] === "https" ? "https:" : "http:";
|
|
272
328
|
}
|
|
329
|
+
return this._protocol;
|
|
273
330
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
set search(value) {
|
|
277
|
-
if (value === "?") {
|
|
278
|
-
value = "";
|
|
279
|
-
} else if (value && value[0] !== "?") {
|
|
280
|
-
value = "?" + value;
|
|
331
|
+
set protocol(value) {
|
|
332
|
+
this._protocol = value;
|
|
281
333
|
}
|
|
282
|
-
|
|
283
|
-
|
|
334
|
+
// origin
|
|
335
|
+
get origin() {
|
|
336
|
+
return `${this.protocol}//${this.host}`;
|
|
284
337
|
}
|
|
285
|
-
|
|
286
|
-
this._searchParams = void 0;
|
|
287
|
-
this[kNodeReq].url = this.pathname + value;
|
|
288
|
-
}
|
|
289
|
-
// searchParams
|
|
290
|
-
get searchParams() {
|
|
291
|
-
if (!this._searchParams) {
|
|
292
|
-
this._searchParams = new URLSearchParams(this.search);
|
|
338
|
+
set origin(_value) {
|
|
293
339
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
this._searchParams = value;
|
|
298
|
-
this._search = value.toString();
|
|
299
|
-
}
|
|
300
|
-
// protocol
|
|
301
|
-
get protocol() {
|
|
302
|
-
if (!this._protocol) {
|
|
303
|
-
this._protocol = this[kNodeReq].socket?.encrypted || this[kNodeReq].headers["x-forwarded-proto"] === "https" ? "https:" : "http:";
|
|
340
|
+
// href
|
|
341
|
+
get href() {
|
|
342
|
+
return `${this.protocol}//${this.host}${this.pathname}${this.search}`;
|
|
304
343
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
toString() {
|
|
332
|
-
return this.href;
|
|
333
|
-
}
|
|
334
|
-
toJSON() {
|
|
335
|
-
return this.href;
|
|
336
|
-
}
|
|
337
|
-
get [(Symbol.toStringTag)]() {
|
|
338
|
-
return "URL";
|
|
339
|
-
}
|
|
340
|
-
[kNodeInspect]() {
|
|
341
|
-
return this.href;
|
|
342
|
-
}
|
|
344
|
+
set href(value) {
|
|
345
|
+
const _url = new globalThis.URL(value);
|
|
346
|
+
this._protocol = _url.protocol;
|
|
347
|
+
this.username = _url.username;
|
|
348
|
+
this.password = _url.password;
|
|
349
|
+
this._hostname = _url.hostname;
|
|
350
|
+
this._port = _url.port;
|
|
351
|
+
this.pathname = _url.pathname;
|
|
352
|
+
this.search = _url.search;
|
|
353
|
+
this.hash = _url.hash;
|
|
354
|
+
}
|
|
355
|
+
toString() {
|
|
356
|
+
return this.href;
|
|
357
|
+
}
|
|
358
|
+
toJSON() {
|
|
359
|
+
return this.href;
|
|
360
|
+
}
|
|
361
|
+
get [Symbol.toStringTag]() {
|
|
362
|
+
return "URL";
|
|
363
|
+
}
|
|
364
|
+
[kNodeInspect]() {
|
|
365
|
+
return this.href;
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
Object.setPrototypeOf(_URL.prototype, globalThis.URL.prototype);
|
|
369
|
+
return _URL;
|
|
343
370
|
})();
|
|
344
371
|
function parsePath(input) {
|
|
345
372
|
const url = (input || "/").replace(/\\/g, "/");
|
|
@@ -355,7 +382,7 @@ function parseHost(host) {
|
|
|
355
382
|
}
|
|
356
383
|
|
|
357
384
|
const NodeRequestProxy = /* @__PURE__ */ (() => {
|
|
358
|
-
class
|
|
385
|
+
const _Request = class Request {
|
|
359
386
|
#url;
|
|
360
387
|
#headers;
|
|
361
388
|
#bodyUsed = false;
|
|
@@ -367,29 +394,32 @@ const NodeRequestProxy = /* @__PURE__ */ (() => {
|
|
|
367
394
|
#jsonBody;
|
|
368
395
|
#textBody;
|
|
369
396
|
#bodyStream;
|
|
370
|
-
constructor(
|
|
371
|
-
this
|
|
397
|
+
constructor(nodeCtx) {
|
|
398
|
+
this.node = nodeCtx;
|
|
372
399
|
}
|
|
373
400
|
get headers() {
|
|
374
401
|
if (!this.#headers) {
|
|
375
|
-
this.#headers = new NodeReqHeadersProxy(this
|
|
402
|
+
this.#headers = new NodeReqHeadersProxy(this.node);
|
|
376
403
|
}
|
|
377
404
|
return this.#headers;
|
|
378
405
|
}
|
|
379
406
|
get remoteAddress() {
|
|
380
|
-
return this
|
|
407
|
+
return this.node.req.socket?.remoteAddress;
|
|
381
408
|
}
|
|
382
409
|
clone() {
|
|
383
|
-
return new
|
|
410
|
+
return new _Request({ ...this.node });
|
|
384
411
|
}
|
|
385
|
-
get
|
|
412
|
+
get _url() {
|
|
386
413
|
if (!this.#url) {
|
|
387
|
-
this.#url = new NodeReqURLProxy(this
|
|
414
|
+
this.#url = new NodeReqURLProxy(this.node);
|
|
388
415
|
}
|
|
389
|
-
return this.#url
|
|
416
|
+
return this.#url;
|
|
417
|
+
}
|
|
418
|
+
get url() {
|
|
419
|
+
return this._url.href;
|
|
390
420
|
}
|
|
391
421
|
get method() {
|
|
392
|
-
return this
|
|
422
|
+
return this.node.req.method || "GET";
|
|
393
423
|
}
|
|
394
424
|
get signal() {
|
|
395
425
|
if (!this.#abortSignal) {
|
|
@@ -404,18 +434,19 @@ const NodeRequestProxy = /* @__PURE__ */ (() => {
|
|
|
404
434
|
if (this.#hasBody !== void 0) {
|
|
405
435
|
return this.#hasBody;
|
|
406
436
|
}
|
|
407
|
-
const method = this
|
|
437
|
+
const method = this.node.req.method?.toUpperCase();
|
|
408
438
|
if (!method || !(method === "PATCH" || method === "POST" || method === "PUT" || method === "DELETE")) {
|
|
409
439
|
this.#hasBody = false;
|
|
410
440
|
return false;
|
|
411
441
|
}
|
|
412
|
-
if (!Number.parseInt(this
|
|
413
|
-
const isChunked = (this
|
|
442
|
+
if (!Number.parseInt(this.node.req.headers["content-length"] || "")) {
|
|
443
|
+
const isChunked = (this.node.req.headers["transfer-encoding"] || "").split(",").map((e) => e.trim()).filter(Boolean).includes("chunked");
|
|
414
444
|
if (!isChunked) {
|
|
415
445
|
this.#hasBody = false;
|
|
416
446
|
return false;
|
|
417
447
|
}
|
|
418
448
|
}
|
|
449
|
+
this.#hasBody = true;
|
|
419
450
|
return true;
|
|
420
451
|
}
|
|
421
452
|
get body() {
|
|
@@ -426,7 +457,7 @@ const NodeRequestProxy = /* @__PURE__ */ (() => {
|
|
|
426
457
|
this.#bodyUsed = true;
|
|
427
458
|
this.#bodyStream = new ReadableStream({
|
|
428
459
|
start: (controller) => {
|
|
429
|
-
this
|
|
460
|
+
this.node.req.on("data", (chunk) => {
|
|
430
461
|
controller.enqueue(chunk);
|
|
431
462
|
}).once("error", (error) => {
|
|
432
463
|
controller.error(error);
|
|
@@ -460,7 +491,7 @@ const NodeRequestProxy = /* @__PURE__ */ (() => {
|
|
|
460
491
|
if (!this.#blobBody) {
|
|
461
492
|
this.#blobBody = this.bytes().then((bytes) => {
|
|
462
493
|
return new Blob([bytes], {
|
|
463
|
-
type: this
|
|
494
|
+
type: this.node.req.headers["content-type"]
|
|
464
495
|
});
|
|
465
496
|
});
|
|
466
497
|
}
|
|
@@ -490,7 +521,7 @@ const NodeRequestProxy = /* @__PURE__ */ (() => {
|
|
|
490
521
|
}
|
|
491
522
|
return this.#jsonBody;
|
|
492
523
|
}
|
|
493
|
-
get [
|
|
524
|
+
get [Symbol.toStringTag]() {
|
|
494
525
|
return "Request";
|
|
495
526
|
}
|
|
496
527
|
[kNodeInspect]() {
|
|
@@ -500,9 +531,9 @@ const NodeRequestProxy = /* @__PURE__ */ (() => {
|
|
|
500
531
|
headers: this.headers
|
|
501
532
|
};
|
|
502
533
|
}
|
|
503
|
-
}
|
|
504
|
-
Object.setPrototypeOf(
|
|
505
|
-
return
|
|
534
|
+
};
|
|
535
|
+
Object.setPrototypeOf(_Request.prototype, globalThis.Request.prototype);
|
|
536
|
+
return _Request;
|
|
506
537
|
})();
|
|
507
538
|
async function _readStream(stream) {
|
|
508
539
|
const chunks = [];
|
|
@@ -517,7 +548,7 @@ async function _readStream(stream) {
|
|
|
517
548
|
}
|
|
518
549
|
|
|
519
550
|
const NodeFastResponse = /* @__PURE__ */ (() => {
|
|
520
|
-
class
|
|
551
|
+
const _Response = class Response {
|
|
521
552
|
#body;
|
|
522
553
|
#init;
|
|
523
554
|
constructor(body, init) {
|
|
@@ -565,7 +596,7 @@ const NodeFastResponse = /* @__PURE__ */ (() => {
|
|
|
565
596
|
} else if (typeof bodyInit.pipe === "function") {
|
|
566
597
|
body = bodyInit;
|
|
567
598
|
} else {
|
|
568
|
-
const res = new Response(bodyInit);
|
|
599
|
+
const res = new globalThis.Response(bodyInit);
|
|
569
600
|
body = res.body;
|
|
570
601
|
for (const [key, value] of res.headers) {
|
|
571
602
|
headers.push([key, value]);
|
|
@@ -590,11 +621,11 @@ const NodeFastResponse = /* @__PURE__ */ (() => {
|
|
|
590
621
|
if (this.#responseObj) {
|
|
591
622
|
return this.#responseObj.clone();
|
|
592
623
|
}
|
|
593
|
-
return new Response(this.#body, this.#init);
|
|
624
|
+
return new globalThis.Response(this.#body, this.#init);
|
|
594
625
|
}
|
|
595
626
|
get #response() {
|
|
596
627
|
if (!this.#responseObj) {
|
|
597
|
-
this.#responseObj = new Response(this.#body, this.#init);
|
|
628
|
+
this.#responseObj = new globalThis.Response(this.#body, this.#init);
|
|
598
629
|
this.#body = void 0;
|
|
599
630
|
this.#init = void 0;
|
|
600
631
|
this.#headersObj = void 0;
|
|
@@ -733,9 +764,9 @@ const NodeFastResponse = /* @__PURE__ */ (() => {
|
|
|
733
764
|
}
|
|
734
765
|
return this.text().then((text) => JSON.parse(text));
|
|
735
766
|
}
|
|
736
|
-
}
|
|
737
|
-
Object.setPrototypeOf(
|
|
738
|
-
return
|
|
767
|
+
};
|
|
768
|
+
Object.setPrototypeOf(_Response.prototype, globalThis.Response.prototype);
|
|
769
|
+
return _Response;
|
|
739
770
|
})();
|
|
740
771
|
|
|
741
772
|
function serve(options) {
|
|
@@ -743,8 +774,7 @@ function serve(options) {
|
|
|
743
774
|
}
|
|
744
775
|
function toNodeHandler(fetchHandler) {
|
|
745
776
|
return (nodeReq, nodeRes) => {
|
|
746
|
-
const request = new NodeRequestProxy(nodeReq);
|
|
747
|
-
request.node = { req: nodeReq, res: nodeRes };
|
|
777
|
+
const request = new NodeRequestProxy({ req: nodeReq, res: nodeRes });
|
|
748
778
|
const res = fetchHandler(request);
|
|
749
779
|
return res instanceof Promise ? res.then((resolvedRes) => sendNodeResponse(nodeRes, resolvedRes)) : sendNodeResponse(nodeRes, res);
|
|
750
780
|
};
|
|
@@ -756,18 +786,22 @@ class NodeServer {
|
|
|
756
786
|
const fetchHandler = wrapFetch(this, this.options.fetch);
|
|
757
787
|
this.fetch = fetchHandler;
|
|
758
788
|
const handler = (nodeReq, nodeRes) => {
|
|
759
|
-
const request = new NodeRequestProxy(nodeReq);
|
|
760
|
-
request.node = { req: nodeReq, res: nodeRes };
|
|
789
|
+
const request = new NodeRequestProxy({ req: nodeReq, res: nodeRes });
|
|
761
790
|
const res = fetchHandler(request);
|
|
762
791
|
return res instanceof Promise ? res.then((resolvedRes) => sendNodeResponse(nodeRes, resolvedRes)) : sendNodeResponse(nodeRes, res);
|
|
763
792
|
};
|
|
793
|
+
const tls = resolveTLSOptions(this.options);
|
|
764
794
|
this.serveOptions = {
|
|
765
795
|
port: resolvePort(this.options.port, globalThis.process?.env.PORT),
|
|
766
796
|
host: this.options.hostname,
|
|
767
797
|
exclusive: !this.options.reusePort,
|
|
798
|
+
...tls ? { cert: tls.cert, key: tls.key, passphrase: tls.passphrase } : {},
|
|
768
799
|
...this.options.node
|
|
769
800
|
};
|
|
770
|
-
const server =
|
|
801
|
+
const server = this.serveOptions.cert ? NodeHttps.createServer(
|
|
802
|
+
this.serveOptions,
|
|
803
|
+
handler
|
|
804
|
+
) : NodeHttp.createServer(this.serveOptions, handler);
|
|
771
805
|
this.node = { server, handler };
|
|
772
806
|
if (!options.manual) {
|
|
773
807
|
this.serve();
|
|
@@ -787,7 +821,11 @@ class NodeServer {
|
|
|
787
821
|
if (!addr) {
|
|
788
822
|
return;
|
|
789
823
|
}
|
|
790
|
-
return typeof addr === "string" ? addr : fmtURL(
|
|
824
|
+
return typeof addr === "string" ? addr : fmtURL(
|
|
825
|
+
addr.address,
|
|
826
|
+
addr.port,
|
|
827
|
+
this.node.server instanceof NodeHttps.Server
|
|
828
|
+
);
|
|
791
829
|
}
|
|
792
830
|
ready() {
|
|
793
831
|
return Promise.resolve(this.#listeningPromise).then(() => this);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
|
|
3
|
+
function resolvePort(portOptions, portEnv) {
|
|
4
|
+
const portInput = portOptions ?? portEnv;
|
|
5
|
+
if (portInput === void 0) {
|
|
6
|
+
return 3e3;
|
|
7
|
+
}
|
|
8
|
+
return typeof portInput === "number" ? portInput : Number.parseInt(portInput, 10);
|
|
9
|
+
}
|
|
10
|
+
function fmtURL(host, port, secure) {
|
|
11
|
+
if (!host || !port) {
|
|
12
|
+
return void 0;
|
|
13
|
+
}
|
|
14
|
+
if (host.includes(":")) {
|
|
15
|
+
host = `[${host}]`;
|
|
16
|
+
}
|
|
17
|
+
return `http${secure ? "s" : ""}://${host}:${port}/`;
|
|
18
|
+
}
|
|
19
|
+
function resolveTLSOptions(opts) {
|
|
20
|
+
if (!opts.tls || opts.protocol === "http") {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const cert = resolveCertOrKey(opts.tls.cert);
|
|
24
|
+
const key = resolveCertOrKey(opts.tls.key);
|
|
25
|
+
if (!cert && !key) {
|
|
26
|
+
if (opts.protocol === "https") {
|
|
27
|
+
throw new TypeError(
|
|
28
|
+
"TLS `cert` and `key` must be provided for `https` protocol."
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (!cert || !key) {
|
|
34
|
+
throw new TypeError("TLS `cert` and `key` must be provided together.");
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
cert,
|
|
38
|
+
key,
|
|
39
|
+
passphrase: opts.tls.passphrase
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function resolveCertOrKey(value) {
|
|
43
|
+
if (!value) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (typeof value !== "string") {
|
|
47
|
+
throw new TypeError(
|
|
48
|
+
"TLS certificate and key must be strings in PEM format or file paths."
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
if (value.startsWith("-----BEGIN ")) {
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
return readFileSync(value, "utf8");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export { resolvePort as a, fmtURL as f, resolveTLSOptions as r };
|
package/dist/types.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as NodeHttp from 'node:http';
|
|
2
|
+
import * as NodeHttps from 'node:https';
|
|
2
3
|
import * as NodeNet from 'node:net';
|
|
3
4
|
import * as Bun from 'bun';
|
|
4
5
|
import * as CF from '@cloudflare/workers-types';
|
|
@@ -51,16 +52,41 @@ interface ServerOptions {
|
|
|
51
52
|
* **Note:** Despite Node.js built-in behavior that has `exclusive` flag (opposite of `reusePort`) enabled by default, srvx uses non-exclusive mode for consistency.
|
|
52
53
|
*/
|
|
53
54
|
reusePort?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* The protocol to use for the server.
|
|
57
|
+
*
|
|
58
|
+
* Possible values are `http` and `https`.
|
|
59
|
+
*
|
|
60
|
+
* If `protocol` is not set, Server will use `http` as the default protocol or `https` if both `tls.cert` and `tls.key` options are provided.
|
|
61
|
+
*/
|
|
62
|
+
protocol?: "http" | "https";
|
|
63
|
+
/**
|
|
64
|
+
* TLS server options.
|
|
65
|
+
*/
|
|
66
|
+
tls?: {
|
|
67
|
+
/**
|
|
68
|
+
* File path or inlined TLS certificate in PEM format (required).
|
|
69
|
+
*/
|
|
70
|
+
cert?: string;
|
|
71
|
+
/**
|
|
72
|
+
* File path or inlined TLS private key in PEM format (required).
|
|
73
|
+
*/
|
|
74
|
+
key?: string;
|
|
75
|
+
/**
|
|
76
|
+
* Passphrase for the private key (optional).
|
|
77
|
+
*/
|
|
78
|
+
passphrase?: string;
|
|
79
|
+
};
|
|
54
80
|
/**
|
|
55
81
|
* Node.js server options.
|
|
56
82
|
*/
|
|
57
|
-
node?: NodeHttp.ServerOptions & NodeNet.ListenOptions;
|
|
83
|
+
node?: (NodeHttp.ServerOptions | NodeHttps.ServerOptions) & NodeNet.ListenOptions;
|
|
58
84
|
/**
|
|
59
85
|
* Bun server options
|
|
60
86
|
*
|
|
61
87
|
* @docs https://bun.sh/docs/api/http
|
|
62
88
|
*/
|
|
63
|
-
bun?: Omit<Bun.ServeOptions, "fetch">;
|
|
89
|
+
bun?: Omit<Bun.ServeOptions | Bun.TLSServeOptions, "fetch">;
|
|
64
90
|
/**
|
|
65
91
|
* Deno server options
|
|
66
92
|
*
|
|
@@ -168,9 +194,9 @@ interface ServerRequest extends Request {
|
|
|
168
194
|
};
|
|
169
195
|
}
|
|
170
196
|
type FetchHandler = (request: Request) => Response | Promise<Response>;
|
|
171
|
-
type
|
|
197
|
+
type BunFetchHandler = (request: Request, server?: Bun.Server) => Response | Promise<Response>;
|
|
172
198
|
type DenoFetchHandler = (request: Request, info?: Deno.ServeHandlerInfo<Deno.NetAddr>) => Response | Promise<Response>;
|
|
173
199
|
type NodeHttpHandler = (nodeReq: NodeHttp.IncomingMessage, nodeRes: NodeHttp.ServerResponse) => void | Promise<void>;
|
|
174
200
|
type CloudflareFetchHandler = CF.ExportedHandlerFetchHandler;
|
|
175
201
|
|
|
176
|
-
export { type
|
|
202
|
+
export { type BunFetchHandler, type CloudflareFetchHandler, type DenoFetchHandler, type FetchHandler, type NodeHttpHandler, Response, type Server, type ServerHandler, type ServerOptions, type ServerPlugin, type ServerPluginInstance, type ServerRequest, serve };
|
package/package.json
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "srvx",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"description": "Universal Server API based on web platform standards. Works seamlessly with Deno, Bun and Node.js.",
|
|
5
5
|
"repository": "unjs/srvx",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"sideEffects": false,
|
|
8
8
|
"type": "module",
|
|
9
|
-
"types": "./dist/types.d.mts",
|
|
10
9
|
"exports": {
|
|
11
10
|
"./types": "./dist/types.d.mts",
|
|
12
11
|
"./deno": "./dist/adapters/deno.mjs",
|
|
@@ -21,6 +20,7 @@
|
|
|
21
20
|
"types": "./dist/types.d.mts"
|
|
22
21
|
}
|
|
23
22
|
},
|
|
23
|
+
"types": "./dist/types.d.mts",
|
|
24
24
|
"files": [
|
|
25
25
|
"dist"
|
|
26
26
|
],
|
|
@@ -30,11 +30,12 @@
|
|
|
30
30
|
"dev": "vitest dev",
|
|
31
31
|
"lint": "eslint . && prettier -c .",
|
|
32
32
|
"lint:fix": "automd && eslint . --fix && prettier -w .",
|
|
33
|
-
"
|
|
34
|
-
"play:deno": "deno run -A playground/app.mjs",
|
|
33
|
+
"prepack": "pnpm build",
|
|
35
34
|
"play:bun": "bun playground/app.mjs",
|
|
36
35
|
"play:cf": "pnpx wrangler dev playground/app.mjs",
|
|
37
|
-
"
|
|
36
|
+
"play:deno": "deno run -A playground/app.mjs",
|
|
37
|
+
"play:mkcert": "openssl req -x509 -newkey rsa:2048 -nodes -keyout server.key -out server.crt -days 365 -subj /CN=srvx.local",
|
|
38
|
+
"play:node": "node playground/app.mjs",
|
|
38
39
|
"release": "pnpm test && changelogen --release && npm publish && git push --follow-tags",
|
|
39
40
|
"test": "pnpm lint && pnpm test:types && vitest run --coverage",
|
|
40
41
|
"test:types": "tsc --noEmit --skipLibCheck"
|
|
@@ -46,16 +47,16 @@
|
|
|
46
47
|
"cookie-es": "^2.0.0"
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
49
|
-
"@cloudflare/workers-types": "^4.
|
|
50
|
-
"@hono/node-server": "^1.
|
|
50
|
+
"@cloudflare/workers-types": "^4.20250321.0",
|
|
51
|
+
"@hono/node-server": "^1.14.0",
|
|
51
52
|
"@mjackson/node-fetch-server": "^0.6.1",
|
|
52
|
-
"@types/bun": "^1.2.
|
|
53
|
+
"@types/bun": "^1.2.5",
|
|
53
54
|
"@types/deno": "^2.2.0",
|
|
54
|
-
"@types/node": "^22.13.
|
|
55
|
-
"@vitest/coverage-v8": "^3.0.
|
|
55
|
+
"@types/node": "^22.13.13",
|
|
56
|
+
"@vitest/coverage-v8": "^3.0.9",
|
|
56
57
|
"automd": "^0.4.0",
|
|
57
58
|
"changelogen": "^0.6.1",
|
|
58
|
-
"eslint": "^9.
|
|
59
|
+
"eslint": "^9.23.0",
|
|
59
60
|
"eslint-config-unjs": "^0.4.2",
|
|
60
61
|
"execa": "^9.5.2",
|
|
61
62
|
"get-port-please": "^3.1.2",
|
|
@@ -63,7 +64,10 @@
|
|
|
63
64
|
"prettier": "^3.5.3",
|
|
64
65
|
"typescript": "^5.8.2",
|
|
65
66
|
"unbuild": "^3.5.0",
|
|
66
|
-
"vitest": "^3.0.
|
|
67
|
+
"vitest": "^3.0.9"
|
|
67
68
|
},
|
|
68
|
-
"packageManager": "pnpm@10.6.
|
|
69
|
+
"packageManager": "pnpm@10.6.5",
|
|
70
|
+
"engines": {
|
|
71
|
+
"node": ">=20.11.1"
|
|
72
|
+
}
|
|
69
73
|
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
function resolvePort(portOptions, portEnv) {
|
|
2
|
-
const portInput = portOptions ?? portEnv;
|
|
3
|
-
if (portInput === void 0) {
|
|
4
|
-
return 3e3;
|
|
5
|
-
}
|
|
6
|
-
return typeof portInput === "number" ? portInput : Number.parseInt(portInput, 10);
|
|
7
|
-
}
|
|
8
|
-
function fmtURL(host, port, ssl) {
|
|
9
|
-
if (!host || !port) {
|
|
10
|
-
return void 0;
|
|
11
|
-
}
|
|
12
|
-
if (host.includes(":")) {
|
|
13
|
-
host = `[${host}]`;
|
|
14
|
-
}
|
|
15
|
-
return `http${""}://${host}:${port}/`;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export { fmtURL as f, resolvePort as r };
|