srvx 0.8.7 → 0.8.8

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 CHANGED
@@ -53,6 +53,7 @@ $ bunx --bun srvx
53
53
  | ---------------- | ------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- |
54
54
  | `elysia` | [examples/elysia](https://github.com/h3js/srvx/tree/main/examples/elysia/) | `npx giget gh:h3js/srvx/examples/elysia srvx-elysia` |
55
55
  | `express` | [examples/express](https://github.com/h3js/srvx/tree/main/examples/express/) | `npx giget gh:h3js/srvx/examples/express srvx-express` |
56
+ | `fastify` | [examples/fastify](https://github.com/h3js/srvx/tree/main/examples/fastify/) | `npx giget gh:h3js/srvx/examples/fastify srvx-fastify` |
56
57
  | `h3` | [examples/h3](https://github.com/h3js/srvx/tree/main/examples/h3/) | `npx giget gh:h3js/srvx/examples/h3 srvx-h3` |
57
58
  | `hello-world` | [examples/hello-world](https://github.com/h3js/srvx/tree/main/examples/hello-world/) | `npx giget gh:h3js/srvx/examples/hello-world srvx-hello-world` |
58
59
  | `hono` | [examples/hono](https://github.com/h3js/srvx/tree/main/examples/hono/) | `npx giget gh:h3js/srvx/examples/hono srvx-hono` |
@@ -1,4 +1,4 @@
1
- import { NodeResponse, NodeResponseHeaders } from "./response-Ca-wGejU.mjs";
1
+ import { NodeResponse, NodeResponseHeaders } from "./response-6LJL3Qlz.mjs";
2
2
 
3
3
  //#region src/adapters/_node/call.ts
4
4
  function callNodeHandler(handler, req) {
@@ -0,0 +1,293 @@
1
+ import { splitSetCookieString } from "cookie-es";
2
+
3
+ //#region src/adapters/_node/_common.ts
4
+ const kNodeInspect = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
5
+ function inheritProps(target, source, sourceKey) {
6
+ for (const key of Object.getOwnPropertyNames(source)) {
7
+ if (key in target) continue;
8
+ const desc = Object.getOwnPropertyDescriptor(source, key);
9
+ if (desc.get) Object.defineProperty(target, key, {
10
+ ...desc,
11
+ get() {
12
+ return this[sourceKey][key];
13
+ }
14
+ });
15
+ else if (typeof desc.value === "function") Object.defineProperty(target, key, {
16
+ ...desc,
17
+ value(...args) {
18
+ return this[sourceKey][key](...args);
19
+ }
20
+ });
21
+ else Object.defineProperty(target, key, desc);
22
+ }
23
+ }
24
+
25
+ //#endregion
26
+ //#region src/adapters/_node/headers.ts
27
+ const NodeRequestHeaders = /* @__PURE__ */ (() => {
28
+ const _Headers = class Headers$1 {
29
+ _node;
30
+ constructor(nodeCtx) {
31
+ this._node = nodeCtx;
32
+ }
33
+ append(name, value) {
34
+ name = validateHeader(name);
35
+ const _headers = this._node.req.headers;
36
+ const _current = _headers[name];
37
+ if (_current) if (Array.isArray(_current)) _current.push(value);
38
+ else _headers[name] = [_current, value];
39
+ else _headers[name] = value;
40
+ }
41
+ delete(name) {
42
+ name = validateHeader(name);
43
+ this._node.req.headers[name] = void 0;
44
+ }
45
+ get(name) {
46
+ name = validateHeader(name);
47
+ const rawValue = this._node.req.headers[name];
48
+ if (rawValue === void 0) return null;
49
+ return _normalizeValue(this._node.req.headers[name]);
50
+ }
51
+ getSetCookie() {
52
+ const setCookie = this._node.req.headers["set-cookie"];
53
+ if (!setCookie || setCookie.length === 0) return [];
54
+ return splitSetCookieString(setCookie);
55
+ }
56
+ has(name) {
57
+ name = validateHeader(name);
58
+ return !!this._node.req.headers[name];
59
+ }
60
+ set(name, value) {
61
+ name = validateHeader(name);
62
+ this._node.req.headers[name] = value;
63
+ }
64
+ get count() {
65
+ throw new Error("Method not implemented.");
66
+ }
67
+ getAll(_name) {
68
+ throw new Error("Method not implemented.");
69
+ }
70
+ toJSON() {
71
+ const _headers = this._node.req.headers;
72
+ const result = {};
73
+ for (const key in _headers) if (_headers[key]) result[key] = _normalizeValue(_headers[key]);
74
+ return result;
75
+ }
76
+ forEach(cb, thisArg) {
77
+ const _headers = this._node.req.headers;
78
+ for (const key in _headers) if (_headers[key]) cb.call(thisArg, _normalizeValue(_headers[key]), key, this);
79
+ }
80
+ *entries() {
81
+ const headers = this._node.req.headers;
82
+ const isHttp2 = this._node.req.httpVersion === "2.0";
83
+ for (const key in headers) if (!isHttp2 || key[0] !== ":") yield [key, _normalizeValue(headers[key])];
84
+ }
85
+ *keys() {
86
+ const keys = Object.keys(this._node.req.headers);
87
+ for (const key of keys) yield key;
88
+ }
89
+ *values() {
90
+ const values = Object.values(this._node.req.headers);
91
+ for (const value of values) yield _normalizeValue(value);
92
+ }
93
+ [Symbol.iterator]() {
94
+ return this.entries()[Symbol.iterator]();
95
+ }
96
+ get [Symbol.toStringTag]() {
97
+ return "Headers";
98
+ }
99
+ [kNodeInspect]() {
100
+ return Object.fromEntries(this.entries());
101
+ }
102
+ };
103
+ Object.setPrototypeOf(_Headers.prototype, globalThis.Headers.prototype);
104
+ return _Headers;
105
+ })();
106
+ const NodeResponseHeaders = /* @__PURE__ */ (() => {
107
+ const _Headers = class Headers$1 {
108
+ _node;
109
+ constructor(nodeCtx) {
110
+ this._node = nodeCtx;
111
+ }
112
+ append(name, value) {
113
+ this._node.res.appendHeader(name, value);
114
+ }
115
+ delete(name) {
116
+ this._node.res.removeHeader(name);
117
+ }
118
+ get(name) {
119
+ const rawValue = this._node.res.getHeader(name);
120
+ if (rawValue === void 0) return null;
121
+ return _normalizeValue(rawValue);
122
+ }
123
+ getSetCookie() {
124
+ const setCookie = _normalizeValue(this._node.res.getHeader("set-cookie"));
125
+ if (!setCookie) return [];
126
+ return splitSetCookieString(setCookie);
127
+ }
128
+ has(name) {
129
+ return this._node.res.hasHeader(name);
130
+ }
131
+ set(name, value) {
132
+ this._node.res.setHeader(name, value);
133
+ }
134
+ get count() {
135
+ throw new Error("Method not implemented.");
136
+ }
137
+ getAll(_name) {
138
+ throw new Error("Method not implemented.");
139
+ }
140
+ toJSON() {
141
+ const _headers = this._node.res.getHeaders();
142
+ const result = {};
143
+ for (const key in _headers) if (_headers[key]) result[key] = _normalizeValue(_headers[key]);
144
+ return result;
145
+ }
146
+ forEach(cb, thisArg) {
147
+ const _headers = this._node.res.getHeaders();
148
+ for (const key in _headers) if (_headers[key]) cb.call(thisArg, _normalizeValue(_headers[key]), key, this);
149
+ }
150
+ *entries() {
151
+ const _headers = this._node.res.getHeaders();
152
+ for (const key in _headers) yield [key, _normalizeValue(_headers[key])];
153
+ }
154
+ *keys() {
155
+ const keys = this._node.res.getHeaderNames();
156
+ for (const key of keys) yield key;
157
+ }
158
+ *values() {
159
+ const values = Object.values(this._node.res.getHeaders());
160
+ for (const value of values) yield _normalizeValue(value);
161
+ }
162
+ [Symbol.iterator]() {
163
+ return this.entries()[Symbol.iterator]();
164
+ }
165
+ get [Symbol.toStringTag]() {
166
+ return "Headers";
167
+ }
168
+ [kNodeInspect]() {
169
+ return Object.fromEntries(this.entries());
170
+ }
171
+ };
172
+ Object.setPrototypeOf(_Headers.prototype, globalThis.Headers.prototype);
173
+ return _Headers;
174
+ })();
175
+ function _normalizeValue(value) {
176
+ if (Array.isArray(value)) return value.join(", ");
177
+ return typeof value === "string" ? value : String(value ?? "");
178
+ }
179
+ function validateHeader(name) {
180
+ if (name[0] === ":") throw new TypeError(`${JSON.stringify(name)} is an invalid header name.`);
181
+ return name.toLowerCase();
182
+ }
183
+
184
+ //#endregion
185
+ //#region src/adapters/_node/response.ts
186
+ /**
187
+ * Fast Response for Node.js runtime
188
+ *
189
+ * It is faster because in most cases it doesn't create a full Response instance.
190
+ */
191
+ const NodeResponse = /* @__PURE__ */ (() => {
192
+ const NativeResponse = globalThis.Response;
193
+ const STATUS_CODES = globalThis.process?.getBuiltinModule("node:http")?.STATUS_CODES || {};
194
+ class NodeResponse$1 {
195
+ #body;
196
+ #init;
197
+ #headers;
198
+ #response;
199
+ constructor(body, init) {
200
+ this.#body = body;
201
+ this.#init = init;
202
+ }
203
+ get status() {
204
+ return this.#response?.status || this.#init?.status || 200;
205
+ }
206
+ get statusText() {
207
+ return this.#response?.statusText || this.#init?.statusText || STATUS_CODES[this.status] || "";
208
+ }
209
+ get headers() {
210
+ if (this.#response) return this.#response.headers;
211
+ if (this.#headers) return this.#headers;
212
+ const initHeaders = this.#init?.headers;
213
+ return this.#headers = initHeaders instanceof Headers ? initHeaders : new Headers(initHeaders);
214
+ }
215
+ get ok() {
216
+ if (this.#response) return this.#response.ok;
217
+ const status = this.status;
218
+ return status >= 200 && status < 300;
219
+ }
220
+ get _response() {
221
+ if (this.#response) return this.#response;
222
+ this.#response = new NativeResponse(this.#body, this.#headers ? {
223
+ ...this.#init,
224
+ headers: this.#headers
225
+ } : this.#init);
226
+ this.#init = void 0;
227
+ this.#headers = void 0;
228
+ this.#body = void 0;
229
+ return this.#response;
230
+ }
231
+ nodeResponse() {
232
+ const status = this.status;
233
+ const statusText = this.statusText;
234
+ let body;
235
+ let contentType;
236
+ let contentLength;
237
+ if (this.#response) body = this.#response.body;
238
+ else if (this.#body) if (this.#body instanceof ReadableStream) body = this.#body;
239
+ else if (typeof this.#body === "string") {
240
+ body = this.#body;
241
+ contentType = "text/plain; charset=UTF-8";
242
+ contentLength = Buffer.byteLength(this.#body);
243
+ } else if (this.#body instanceof ArrayBuffer) {
244
+ body = Buffer.from(this.#body);
245
+ contentLength = this.#body.byteLength;
246
+ } else if (this.#body instanceof Uint8Array) {
247
+ body = this.#body;
248
+ contentLength = this.#body.byteLength;
249
+ } else if (this.#body instanceof DataView) {
250
+ body = Buffer.from(this.#body.buffer);
251
+ contentLength = this.#body.byteLength;
252
+ } else if (this.#body instanceof Blob) {
253
+ body = this.#body.stream();
254
+ contentType = this.#body.type;
255
+ contentLength = this.#body.size;
256
+ } else if (typeof this.#body.pipe === "function") body = this.#body;
257
+ else body = this._response.body;
258
+ const rawNodeHeaders = [];
259
+ const initHeaders = this.#init?.headers;
260
+ const headerEntries = this.#response?.headers || this.#headers || (initHeaders ? Array.isArray(initHeaders) ? initHeaders : initHeaders?.entries ? initHeaders.entries() : Object.entries(initHeaders).map(([k, v]) => [k.toLowerCase(), v]) : void 0);
261
+ let hasContentTypeHeader;
262
+ let hasContentLength;
263
+ if (headerEntries) for (const [key, value] of headerEntries) {
264
+ if (key === "set-cookie") {
265
+ for (const setCookie of splitSetCookieString(value)) rawNodeHeaders.push(["set-cookie", setCookie]);
266
+ continue;
267
+ }
268
+ rawNodeHeaders.push([key, value]);
269
+ if (key === "content-type") hasContentTypeHeader = true;
270
+ else if (key === "content-length") hasContentLength = true;
271
+ }
272
+ if (contentType && !hasContentTypeHeader) rawNodeHeaders.push(["content-type", contentType]);
273
+ if (contentLength && !hasContentLength) rawNodeHeaders.push(["content-length", String(contentLength)]);
274
+ this.#init = void 0;
275
+ this.#headers = void 0;
276
+ this.#response = void 0;
277
+ this.#body = void 0;
278
+ return {
279
+ status,
280
+ statusText,
281
+ headers: rawNodeHeaders,
282
+ body
283
+ };
284
+ }
285
+ }
286
+ inheritProps(NodeResponse$1.prototype, NativeResponse.prototype, "_response");
287
+ Object.setPrototypeOf(NodeResponse$1, NativeResponse);
288
+ Object.setPrototypeOf(NodeResponse$1.prototype, NativeResponse.prototype);
289
+ return NodeResponse$1;
290
+ })();
291
+
292
+ //#endregion
293
+ export { NodeRequestHeaders, NodeResponse, NodeResponseHeaders, inheritProps, kNodeInspect };
@@ -11,8 +11,10 @@ type NodeRequestContext = {
11
11
  declare const NodeRequest: {
12
12
  new (nodeCtx: NodeRequestContext): ServerRequest;
13
13
  };
14
+ type NodeRequest = InstanceType<typeof NodeRequest>;
14
15
  //#endregion
15
16
  //#region src/adapters/_node/headers.d.ts
17
+ type NodeRequestHeaders = InstanceType<typeof NodeRequestHeaders>;
16
18
  declare const NodeRequestHeaders: {
17
19
  new (nodeCtx: {
18
20
  req: NodeServerRequest;
@@ -27,7 +29,14 @@ declare const NodeResponseHeaders: {
27
29
  };
28
30
  //#endregion
29
31
  //#region src/adapters/_node/response.d.ts
30
- type NodeResponse = InstanceType<typeof NodeResponse>;
32
+ // prettier-ignore
33
+ type PreparedNodeResponseBody = string | Buffer | Uint8Array | DataView | ReadableStream | Readable | undefined | null;
34
+ interface PreparedNodeResponse {
35
+ status: number;
36
+ statusText: string;
37
+ headers: NodeHttp.OutgoingHttpHeader[];
38
+ body: PreparedNodeResponseBody;
39
+ }
31
40
  /**
32
41
  * Fast Response for Node.js runtime
33
42
  *
@@ -35,14 +44,10 @@ type NodeResponse = InstanceType<typeof NodeResponse>;
35
44
  */
36
45
  declare const NodeResponse: {
37
46
  new (body?: BodyInit | null, init?: ResponseInit): globalThis.Response & {
38
- readonly nodeResponse: () => {
39
- status: number;
40
- statusText: string;
41
- headers: NodeHttp.OutgoingHttpHeader[];
42
- body: string | Buffer | Uint8Array | DataView | ReadableStream | Readable | undefined | null;
43
- };
47
+ readonly nodeResponse: () => PreparedNodeResponse;
44
48
  };
45
49
  };
50
+ type NodeResponse = InstanceType<typeof NodeResponse>;
46
51
  //#endregion
47
52
  //#region src/adapters/_node/send.d.ts
48
53
  declare function sendNodeResponse(nodeRes: NodeServerResponse, webRes: Response | NodeResponse): Promise<void>;
@@ -1,7 +1,7 @@
1
1
  import { createWaitUntil, fmtURL, printListening, resolvePortAndHost, resolveTLSOptions } from "../_chunks/_utils-DRF_4b_y.mjs";
2
2
  import { wrapFetch } from "../_chunks/_middleware-BvRR7B4M.mjs";
3
3
  import { FastURL$1 as FastURL } from "../_chunks/_url-CdE4ce6F.mjs";
4
- import { NodeRequestHeaders, NodeResponse, NodeResponseHeaders, kNodeInspect } from "../_chunks/response-Ca-wGejU.mjs";
4
+ import { NodeRequestHeaders, NodeResponse, NodeResponseHeaders, inheritProps, kNodeInspect } from "../_chunks/response-6LJL3Qlz.mjs";
5
5
  import { errorPlugin } from "../_chunks/_plugins-DOhVIkXu.mjs";
6
6
  import { splitSetCookieString } from "cookie-es";
7
7
 
@@ -223,57 +223,45 @@ function parseHost(host) {
223
223
  //#endregion
224
224
  //#region src/adapters/_node/request.ts
225
225
  const NodeRequest = /* @__PURE__ */ (() => {
226
- const unsupportedGetters = [
227
- "cache",
228
- "credentials",
229
- "destination",
230
- "integrity",
231
- "keepalive",
232
- "mode",
233
- "redirect",
234
- "referrer",
235
- "referrerPolicy"
236
- ];
237
- const _Request = class Request {
238
- #url;
239
- #headers;
240
- #bodyUsed = false;
241
- #abortSignal;
242
- #hasBody;
243
- #bodyBytes;
244
- #blobBody;
245
- #formDataBody;
246
- #jsonBody;
247
- #textBody;
248
- #bodyStream;
226
+ const NativeRequest = globalThis.Request;
227
+ const { Readable } = process.getBuiltinModule("node:stream");
228
+ if (!("_srvx" in NativeRequest)) {
229
+ class Request$1 extends NativeRequest {
230
+ static _srvx = true;
231
+ constructor(input, options) {
232
+ if (typeof input === "object" && "_request" in input) input = input._request;
233
+ if ((options?.body)?.getReader !== void 0) options.duplex ??= "half";
234
+ super(input, options);
235
+ }
236
+ }
237
+ globalThis.Request = Request$1;
238
+ }
239
+ class NodeRequest$1 {
249
240
  _node;
241
+ _url;
250
242
  runtime;
251
- constructor(nodeCtx) {
252
- this._node = nodeCtx;
243
+ #request;
244
+ #headers;
245
+ #abortSignal;
246
+ constructor(ctx) {
247
+ this._node = ctx;
248
+ this._url = new NodeRequestURL({ req: ctx.req });
253
249
  this.runtime = {
254
250
  name: "node",
255
- node: nodeCtx
251
+ node: ctx
256
252
  };
257
253
  }
258
254
  get ip() {
259
255
  return this._node.req.socket?.remoteAddress;
260
256
  }
261
- get headers() {
262
- if (!this.#headers) this.#headers = new NodeRequestHeaders(this._node);
263
- return this.#headers;
264
- }
265
- clone() {
266
- return new _Request({ ...this._node });
267
- }
268
- get _url() {
269
- if (!this.#url) this.#url = new NodeRequestURL(this._node);
270
- return this.#url;
257
+ get method() {
258
+ return this._node.req.method || "GET";
271
259
  }
272
260
  get url() {
273
261
  return this._url.href;
274
262
  }
275
- get method() {
276
- return this._node.req.method || "GET";
263
+ get headers() {
264
+ return this.#headers ||= new NodeRequestHeaders(this._node);
277
265
  }
278
266
  get signal() {
279
267
  if (!this.#abortSignal) {
@@ -284,104 +272,24 @@ const NodeRequest = /* @__PURE__ */ (() => {
284
272
  }
285
273
  return this.#abortSignal.signal;
286
274
  }
287
- get bodyUsed() {
288
- return this.#bodyUsed;
289
- }
290
- get _hasBody() {
291
- if (this.#hasBody !== void 0) return this.#hasBody;
292
- const method = this._node.req.method?.toUpperCase();
293
- if (!method || !(method === "PATCH" || method === "POST" || method === "PUT" || method === "DELETE")) {
294
- this.#hasBody = false;
295
- return false;
296
- }
297
- if (!Number.parseInt(this._node.req.headers["content-length"] || "")) {
298
- const isChunked = (this._node.req.headers["transfer-encoding"] || "").split(",").map((e) => e.trim()).filter(Boolean).includes("chunked");
299
- if (!isChunked) {
300
- this.#hasBody = false;
301
- return false;
302
- }
303
- }
304
- this.#hasBody = true;
305
- return true;
306
- }
307
- get body() {
308
- if (!this._hasBody) return null;
309
- if (!this.#bodyStream) {
310
- this.#bodyUsed = true;
311
- this.#bodyStream = new ReadableStream({ start: (controller) => {
312
- this._node.req.on("data", (chunk) => {
313
- controller.enqueue(chunk);
314
- }).once("error", (error) => {
315
- controller.error(error);
316
- this.#abortSignal?.abort();
317
- }).once("close", () => {
318
- this.#abortSignal?.abort();
319
- }).once("end", () => {
320
- controller.close();
321
- });
322
- } });
323
- }
324
- return this.#bodyStream;
325
- }
326
- bytes() {
327
- if (!this.#bodyBytes) {
328
- const _bodyStream = this.body;
329
- this.#bodyBytes = _bodyStream ? _readStream(_bodyStream) : Promise.resolve(new Uint8Array());
275
+ get _request() {
276
+ if (!this.#request) {
277
+ const method = this.method;
278
+ const hasBody = !(method === "GET" || method === "HEAD");
279
+ this.#request = new Request(this.url, {
280
+ method,
281
+ headers: this.headers,
282
+ signal: this.signal,
283
+ body: hasBody ? Readable.toWeb(this._node.req) : void 0
284
+ });
330
285
  }
331
- return this.#bodyBytes;
332
- }
333
- arrayBuffer() {
334
- return this.bytes().then((buff) => {
335
- return buff.buffer.slice(buff.byteOffset, buff.byteOffset + buff.byteLength);
336
- });
337
- }
338
- blob() {
339
- if (!this.#blobBody) this.#blobBody = this.bytes().then((bytes) => {
340
- return new Blob([bytes], { type: this._node.req.headers["content-type"] });
341
- });
342
- return this.#blobBody;
343
- }
344
- formData() {
345
- if (!this.#formDataBody) this.#formDataBody = new Response(this.body, { headers: this.headers }).formData();
346
- return this.#formDataBody;
347
- }
348
- text() {
349
- if (!this.#textBody) this.#textBody = this.bytes().then((bytes) => {
350
- return new TextDecoder().decode(bytes);
351
- });
352
- return this.#textBody;
353
- }
354
- json() {
355
- if (!this.#jsonBody) this.#jsonBody = this.text().then((txt) => {
356
- return JSON.parse(txt);
357
- });
358
- return this.#jsonBody;
359
- }
360
- get [Symbol.toStringTag]() {
361
- return "Request";
362
- }
363
- [kNodeInspect]() {
364
- return {
365
- method: this.method,
366
- url: this.url,
367
- headers: this.headers
368
- };
286
+ return this.#request;
369
287
  }
370
- };
371
- for (const key of unsupportedGetters) Object.defineProperty(_Request.prototype, key, {
372
- enumerable: true,
373
- configurable: false
374
- });
375
- Object.setPrototypeOf(_Request.prototype, globalThis.Request.prototype);
376
- return _Request;
288
+ }
289
+ inheritProps(NodeRequest$1.prototype, NativeRequest.prototype, "_request");
290
+ Object.setPrototypeOf(NodeRequest$1.prototype, Request.prototype);
291
+ return NodeRequest$1;
377
292
  })();
378
- async function _readStream(stream) {
379
- const chunks = [];
380
- await stream.pipeTo(new WritableStream({ write(chunk) {
381
- chunks.push(chunk);
382
- } }));
383
- return Buffer.concat(chunks);
384
- }
385
293
 
386
294
  //#endregion
387
295
  //#region src/adapters/node.ts
package/dist/cli.mjs CHANGED
@@ -130,7 +130,7 @@ async function loadEntry(opts) {
130
130
  const nodeHandler = listenHandler || (typeof mod.default === "function" ? mod.default : void 0);
131
131
  if (nodeHandler) {
132
132
  _legacyNode = true;
133
- const { callNodeHandler } = await import("./_chunks/call-CKpEER8U.mjs");
133
+ const { callNodeHandler } = await import("./_chunks/call-LB9MY5Dv.mjs");
134
134
  fetchHandler = (webReq) => callNodeHandler(nodeHandler, webReq);
135
135
  }
136
136
  }
@@ -216,7 +216,7 @@ async function interceptListen(cb) {
216
216
  };
217
217
  }
218
218
  async function version() {
219
- const version$1 = "0.8.7";
219
+ const version$1 = "0.8.8";
220
220
  return `srvx ${version$1}\n${runtime()}`;
221
221
  }
222
222
  function runtime() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "srvx",
3
- "version": "0.8.7",
3
+ "version": "0.8.8",
4
4
  "description": "Universal Server API based on web platform standards. Works seamlessly with Deno, Bun and Node.js.",
5
5
  "homepage": "https://srvx.h3.dev",
6
6
  "repository": "h3js/srvx",
@@ -58,20 +58,20 @@
58
58
  "cookie-es": "^2.0.0"
59
59
  },
60
60
  "devDependencies": {
61
- "@cloudflare/workers-types": "^4.20250806.0",
62
- "@hono/node-server": "^1.18.1",
61
+ "@cloudflare/workers-types": "^4.20250927.0",
62
+ "@hono/node-server": "^1.19.5",
63
63
  "@mitata/counters": "^0.0.8",
64
64
  "@mjackson/node-fetch-server": "^0.7.0",
65
- "@types/bun": "^1.2.19",
65
+ "@types/bun": "^1.2.23",
66
66
  "@types/deno": "^2.3.0",
67
- "@types/node": "^24.2.0",
68
- "@types/node-forge": "^1.3.13",
69
- "@types/serviceworker": "^0.0.149",
67
+ "@types/node": "^24.5.2",
68
+ "@types/node-forge": "^1.3.14",
69
+ "@types/serviceworker": "^0.0.154",
70
70
  "@vitest/coverage-v8": "^3.2.4",
71
71
  "@whatwg-node/server": "^0.10.12",
72
- "automd": "^0.4.0",
72
+ "automd": "^0.4.2",
73
73
  "changelogen": "^0.6.2",
74
- "eslint": "^9.32.0",
74
+ "eslint": "^9.36.0",
75
75
  "eslint-config-unjs": "^0.5.0",
76
76
  "execa": "^9.6.0",
77
77
  "get-port-please": "^3.2.0",
@@ -80,12 +80,13 @@
80
80
  "node-forge": "^1.3.1",
81
81
  "obuild": "^0.2.1",
82
82
  "prettier": "^3.6.2",
83
+ "srvx-release": "npm:srvx@0.8.7",
83
84
  "tslib": "^2.8.1",
84
85
  "typescript": "^5.9.2",
85
- "undici": "^7.13.0",
86
+ "undici": "^7.16.0",
86
87
  "vitest": "^3.2.4"
87
88
  },
88
- "packageManager": "pnpm@10.12.4",
89
+ "packageManager": "pnpm@10.17.1",
89
90
  "engines": {
90
91
  "node": ">=20.16.0"
91
92
  }
@@ -1,358 +0,0 @@
1
- import { splitSetCookieString } from "cookie-es";
2
-
3
- //#region src/adapters/_node/_common.ts
4
- const kNodeInspect = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
5
-
6
- //#endregion
7
- //#region src/adapters/_node/headers.ts
8
- const NodeRequestHeaders = /* @__PURE__ */ (() => {
9
- const _Headers = class Headers$1 {
10
- _node;
11
- constructor(nodeCtx) {
12
- this._node = nodeCtx;
13
- }
14
- append(name, value) {
15
- name = validateHeader(name);
16
- const _headers = this._node.req.headers;
17
- const _current = _headers[name];
18
- if (_current) if (Array.isArray(_current)) _current.push(value);
19
- else _headers[name] = [_current, value];
20
- else _headers[name] = value;
21
- }
22
- delete(name) {
23
- name = validateHeader(name);
24
- this._node.req.headers[name] = void 0;
25
- }
26
- get(name) {
27
- name = validateHeader(name);
28
- const rawValue = this._node.req.headers[name];
29
- if (rawValue === void 0) return null;
30
- return _normalizeValue(this._node.req.headers[name]);
31
- }
32
- getSetCookie() {
33
- const setCookie = this._node.req.headers["set-cookie"];
34
- if (!setCookie || setCookie.length === 0) return [];
35
- return splitSetCookieString(setCookie);
36
- }
37
- has(name) {
38
- name = validateHeader(name);
39
- return !!this._node.req.headers[name];
40
- }
41
- set(name, value) {
42
- name = validateHeader(name);
43
- this._node.req.headers[name] = value;
44
- }
45
- get count() {
46
- throw new Error("Method not implemented.");
47
- }
48
- getAll(_name) {
49
- throw new Error("Method not implemented.");
50
- }
51
- toJSON() {
52
- const _headers = this._node.req.headers;
53
- const result = {};
54
- for (const key in _headers) if (_headers[key]) result[key] = _normalizeValue(_headers[key]);
55
- return result;
56
- }
57
- forEach(cb, thisArg) {
58
- const _headers = this._node.req.headers;
59
- for (const key in _headers) if (_headers[key]) cb.call(thisArg, _normalizeValue(_headers[key]), key, this);
60
- }
61
- *entries() {
62
- const headers = this._node.req.headers;
63
- const isHttp2 = this._node.req.httpVersion === "2.0";
64
- for (const key in headers) if (!isHttp2 || key[0] !== ":") yield [key, _normalizeValue(headers[key])];
65
- }
66
- *keys() {
67
- const keys = Object.keys(this._node.req.headers);
68
- for (const key of keys) yield key;
69
- }
70
- *values() {
71
- const values = Object.values(this._node.req.headers);
72
- for (const value of values) yield _normalizeValue(value);
73
- }
74
- [Symbol.iterator]() {
75
- return this.entries()[Symbol.iterator]();
76
- }
77
- get [Symbol.toStringTag]() {
78
- return "Headers";
79
- }
80
- [kNodeInspect]() {
81
- return Object.fromEntries(this.entries());
82
- }
83
- };
84
- Object.setPrototypeOf(_Headers.prototype, globalThis.Headers.prototype);
85
- return _Headers;
86
- })();
87
- const NodeResponseHeaders = /* @__PURE__ */ (() => {
88
- const _Headers = class Headers$1 {
89
- _node;
90
- constructor(nodeCtx) {
91
- this._node = nodeCtx;
92
- }
93
- append(name, value) {
94
- this._node.res.appendHeader(name, value);
95
- }
96
- delete(name) {
97
- this._node.res.removeHeader(name);
98
- }
99
- get(name) {
100
- const rawValue = this._node.res.getHeader(name);
101
- if (rawValue === void 0) return null;
102
- return _normalizeValue(rawValue);
103
- }
104
- getSetCookie() {
105
- const setCookie = _normalizeValue(this._node.res.getHeader("set-cookie"));
106
- if (!setCookie) return [];
107
- return splitSetCookieString(setCookie);
108
- }
109
- has(name) {
110
- return this._node.res.hasHeader(name);
111
- }
112
- set(name, value) {
113
- this._node.res.setHeader(name, value);
114
- }
115
- get count() {
116
- throw new Error("Method not implemented.");
117
- }
118
- getAll(_name) {
119
- throw new Error("Method not implemented.");
120
- }
121
- toJSON() {
122
- const _headers = this._node.res.getHeaders();
123
- const result = {};
124
- for (const key in _headers) if (_headers[key]) result[key] = _normalizeValue(_headers[key]);
125
- return result;
126
- }
127
- forEach(cb, thisArg) {
128
- const _headers = this._node.res.getHeaders();
129
- for (const key in _headers) if (_headers[key]) cb.call(thisArg, _normalizeValue(_headers[key]), key, this);
130
- }
131
- *entries() {
132
- const _headers = this._node.res.getHeaders();
133
- for (const key in _headers) yield [key, _normalizeValue(_headers[key])];
134
- }
135
- *keys() {
136
- const keys = this._node.res.getHeaderNames();
137
- for (const key of keys) yield key;
138
- }
139
- *values() {
140
- const values = Object.values(this._node.res.getHeaders());
141
- for (const value of values) yield _normalizeValue(value);
142
- }
143
- [Symbol.iterator]() {
144
- return this.entries()[Symbol.iterator]();
145
- }
146
- get [Symbol.toStringTag]() {
147
- return "Headers";
148
- }
149
- [kNodeInspect]() {
150
- return Object.fromEntries(this.entries());
151
- }
152
- };
153
- Object.setPrototypeOf(_Headers.prototype, globalThis.Headers.prototype);
154
- return _Headers;
155
- })();
156
- function _normalizeValue(value) {
157
- if (Array.isArray(value)) return value.join(", ");
158
- return typeof value === "string" ? value : String(value ?? "");
159
- }
160
- function validateHeader(name) {
161
- if (name[0] === ":") throw new TypeError(`${JSON.stringify(name)} is an invalid header name.`);
162
- return name.toLowerCase();
163
- }
164
-
165
- //#endregion
166
- //#region src/adapters/_node/response.ts
167
- /**
168
- * Fast Response for Node.js runtime
169
- *
170
- * It is faster because in most cases it doesn't create a full Response instance.
171
- */
172
- const NodeResponse = /* @__PURE__ */ (() => {
173
- const CONTENT_TYPE = "content-type";
174
- const JSON_TYPE = "application/json";
175
- const JSON_HEADER = [[CONTENT_TYPE, JSON_TYPE]];
176
- const _Response = class Response {
177
- #body;
178
- #init;
179
- constructor(body, init) {
180
- this.#body = body;
181
- this.#init = init;
182
- }
183
- static json(data, init) {
184
- if (init?.headers) {
185
- if (!init.headers[CONTENT_TYPE]) {
186
- const initHeaders = new Headers(init.headers);
187
- if (!initHeaders.has(CONTENT_TYPE)) initHeaders.set(CONTENT_TYPE, JSON_TYPE);
188
- init = {
189
- ...init,
190
- headers: initHeaders
191
- };
192
- }
193
- } else {
194
- init = init ? { ...init } : {};
195
- init.headers = JSON_HEADER;
196
- }
197
- return new _Response(JSON.stringify(data), init);
198
- }
199
- static error() {
200
- return globalThis.Response.error();
201
- }
202
- static redirect(url, status) {
203
- return globalThis.Response.redirect(url, status);
204
- }
205
- /**
206
- * Prepare Node.js response object
207
- */
208
- nodeResponse() {
209
- const status = this.#init?.status ?? 200;
210
- const statusText = this.#init?.statusText ?? "";
211
- const headers = [];
212
- const headersInit = this.#init?.headers;
213
- if (this.#headersObj) for (const [key, value] of this.#headersObj) if (key === "set-cookie") for (const setCookie of splitSetCookieString(value)) headers.push(["set-cookie", setCookie]);
214
- else headers.push([key, value]);
215
- else if (headersInit) {
216
- const headerEntries = Array.isArray(headersInit) ? headersInit : headersInit.entries ? headersInit.entries() : Object.entries(headersInit);
217
- for (const [key, value] of headerEntries) if (key === "set-cookie") for (const setCookie of splitSetCookieString(value)) headers.push(["set-cookie", setCookie]);
218
- else headers.push([key, value]);
219
- }
220
- const bodyInit = this.#body;
221
- let body;
222
- if (bodyInit) if (typeof bodyInit === "string") body = bodyInit;
223
- else if (bodyInit instanceof ReadableStream) body = bodyInit;
224
- else if (bodyInit instanceof ArrayBuffer) body = Buffer.from(bodyInit);
225
- else if (bodyInit instanceof Uint8Array) body = Buffer.from(bodyInit);
226
- else if (bodyInit instanceof DataView) body = Buffer.from(bodyInit.buffer);
227
- else if (bodyInit instanceof Blob) {
228
- body = bodyInit.stream();
229
- if (bodyInit.type) headers.push(["content-type", bodyInit.type]);
230
- } else if (typeof bodyInit.pipe === "function") body = bodyInit;
231
- else {
232
- const res = new globalThis.Response(bodyInit);
233
- body = res.body;
234
- for (const [key, value] of res.headers) headers.push([key, value]);
235
- }
236
- this.#body = void 0;
237
- this.#init = void 0;
238
- this.#headersObj = void 0;
239
- this.#responseObj = void 0;
240
- return {
241
- status,
242
- statusText,
243
- headers,
244
- body
245
- };
246
- }
247
- /** Lazy initialized response instance */
248
- #responseObj;
249
- /** Lazy initialized headers instance */
250
- #headersObj;
251
- clone() {
252
- if (this.#responseObj) return this.#responseObj.clone();
253
- if (this.#headersObj) return new _Response(this.#body, {
254
- ...this.#init,
255
- headers: this.#headersObj
256
- });
257
- return new _Response(this.#body, this.#init);
258
- }
259
- get #response() {
260
- if (!this.#responseObj) {
261
- this.#responseObj = this.#headersObj ? new globalThis.Response(this.#body, {
262
- ...this.#init,
263
- headers: this.#headersObj
264
- }) : new globalThis.Response(this.#body, this.#init);
265
- this.#body = void 0;
266
- this.#init = void 0;
267
- this.#headersObj = void 0;
268
- }
269
- return this.#responseObj;
270
- }
271
- get headers() {
272
- if (this.#responseObj) return this.#responseObj.headers;
273
- if (!this.#headersObj) this.#headersObj = new Headers(this.#init?.headers);
274
- return this.#headersObj;
275
- }
276
- get ok() {
277
- if (this.#responseObj) return this.#responseObj.ok;
278
- const status = this.#init?.status ?? 200;
279
- return status >= 200 && status < 300;
280
- }
281
- get redirected() {
282
- if (this.#responseObj) return this.#responseObj.redirected;
283
- return false;
284
- }
285
- get status() {
286
- if (this.#responseObj) return this.#responseObj.status;
287
- return this.#init?.status ?? 200;
288
- }
289
- get statusText() {
290
- if (this.#responseObj) return this.#responseObj.statusText;
291
- return this.#init?.statusText ?? "";
292
- }
293
- get type() {
294
- if (this.#responseObj) return this.#responseObj.type;
295
- return "default";
296
- }
297
- get url() {
298
- if (this.#responseObj) return this.#responseObj.url;
299
- return "";
300
- }
301
- #fastBody(as) {
302
- const bodyInit = this.#body;
303
- if (bodyInit === null || bodyInit === void 0) return null;
304
- if (bodyInit instanceof as) return bodyInit;
305
- return false;
306
- }
307
- get body() {
308
- if (this.#responseObj) return this.#responseObj.body;
309
- const fastBody = this.#fastBody(ReadableStream);
310
- if (fastBody !== false) return fastBody;
311
- return this.#response.body;
312
- }
313
- get bodyUsed() {
314
- if (this.#responseObj) return this.#responseObj.bodyUsed;
315
- return false;
316
- }
317
- arrayBuffer() {
318
- if (this.#responseObj) return this.#responseObj.arrayBuffer();
319
- const fastBody = this.#fastBody(ArrayBuffer);
320
- if (fastBody !== false) return Promise.resolve(fastBody || new ArrayBuffer(0));
321
- return this.#response.arrayBuffer();
322
- }
323
- blob() {
324
- if (this.#responseObj) return this.#responseObj.blob();
325
- const fastBody = this.#fastBody(Blob);
326
- if (fastBody !== false) return Promise.resolve(fastBody || new Blob());
327
- return this.#response.blob();
328
- }
329
- bytes() {
330
- if (this.#responseObj) return this.#responseObj.bytes();
331
- const fastBody = this.#fastBody(Uint8Array);
332
- if (fastBody !== false) return Promise.resolve(fastBody || new Uint8Array());
333
- return this.#response.bytes();
334
- }
335
- formData() {
336
- if (this.#responseObj) return this.#responseObj.formData();
337
- const fastBody = this.#fastBody(FormData);
338
- if (fastBody !== false) return Promise.resolve(fastBody || new FormData());
339
- return this.#response.formData();
340
- }
341
- text() {
342
- if (this.#responseObj) return this.#responseObj.text();
343
- const bodyInit = this.#body;
344
- if (bodyInit === null || bodyInit === void 0) return Promise.resolve("");
345
- if (typeof bodyInit === "string") return Promise.resolve(bodyInit);
346
- return this.#response.text();
347
- }
348
- json() {
349
- if (this.#responseObj) return this.#responseObj.json();
350
- return this.text().then((text) => JSON.parse(text));
351
- }
352
- };
353
- Object.setPrototypeOf(_Response.prototype, globalThis.Response.prototype);
354
- return _Response;
355
- })();
356
-
357
- //#endregion
358
- export { NodeRequestHeaders, NodeResponse, NodeResponseHeaders, kNodeInspect };