srvx 0.2.6 → 0.2.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.
@@ -1,4 +1,4 @@
1
- import { ServerOptions, Server, BunFetchandler } from '../types.mjs';
1
+ import { ServerOptions, Server, BunFetchHandler } from '../types.mjs';
2
2
  import * as Bun from 'bun';
3
3
  import 'node:http';
4
4
  import 'node:https';
@@ -13,12 +13,12 @@ declare const Response: {
13
13
  redirect(url: string | URL, status?: number): Response;
14
14
  };
15
15
  declare function serve(options: ServerOptions): BunServer;
16
- declare class BunServer implements Server<BunFetchandler> {
16
+ declare class BunServer implements Server<BunFetchHandler> {
17
17
  readonly runtime = "bun";
18
18
  readonly options: ServerOptions;
19
19
  readonly bun: Server["bun"];
20
20
  readonly serveOptions: Bun.ServeOptions | Bun.TLSServeOptions;
21
- readonly fetch: BunFetchandler;
21
+ readonly fetch: BunFetchHandler;
22
22
  constructor(options: ServerOptions);
23
23
  serve(): Promise<Awaited<this>>;
24
24
  get url(): string | undefined;
@@ -1,4 +1,4 @@
1
- import { ServerOptions, Server, FetchHandler, NodeHttpHandler } from '../types.mjs';
1
+ import { ServerRequest, ServerOptions, Server, FetchHandler, NodeHttpHandler } from '../types.mjs';
2
2
  import NodeHttp__default from 'node:http';
3
3
  import { Readable } from 'node:stream';
4
4
  import 'node:https';
@@ -6,13 +6,13 @@ import 'node:net';
6
6
  import 'bun';
7
7
  import '@cloudflare/workers-types';
8
8
 
9
- type NodeFastResponse = InstanceType<typeof NodeFastResponse>;
9
+ type NodeResponse = InstanceType<typeof NodeResponse>;
10
10
  /**
11
11
  * Fast Response for Node.js runtime
12
12
  *
13
13
  * It is faster because in most cases it doesn't create a full Response instance.
14
14
  */
15
- declare const NodeFastResponse: {
15
+ declare const NodeResponse: {
16
16
  new (body?: BodyInit | null, init?: ResponseInit): {
17
17
  "__#4363@#body"?: BodyInit | null;
18
18
  "__#4363@#init"?: ResponseInit;
@@ -23,14 +23,14 @@ declare const NodeFastResponse: {
23
23
  status: number;
24
24
  statusText: string;
25
25
  headers: NodeHttp__default.OutgoingHttpHeader[];
26
- body: string | Uint8Array<ArrayBufferLike> | ReadableStream<Uint8Array<ArrayBufferLike>> | Readable | Buffer<ArrayBufferLike> | DataView<ArrayBufferLike> | null | undefined;
26
+ body: string | Buffer<ArrayBufferLike> | Uint8Array<ArrayBufferLike> | ReadableStream<Uint8Array<ArrayBufferLike>> | Readable | DataView<ArrayBufferLike> | null | undefined;
27
27
  };
28
28
  /** Lazy initialized response instance */
29
- "__#4363@#responseObj"?: Response;
29
+ "__#4363@#responseObj"?: globalThis.Response;
30
30
  /** Lazy initialized headers instance */
31
31
  "__#4363@#headersObj"?: Headers;
32
- clone(): Response;
33
- readonly "__#4363@#response": Response;
32
+ clone(): globalThis.Response;
33
+ readonly "__#4363@#response": globalThis.Response;
34
34
  readonly headers: Headers;
35
35
  readonly ok: boolean;
36
36
  readonly redirected: boolean;
@@ -48,9 +48,80 @@ declare const NodeFastResponse: {
48
48
  text(): Promise<string>;
49
49
  json(): Promise<any>;
50
50
  };
51
+ json(data: any, init?: ResponseInit): globalThis.Response;
52
+ error(): globalThis.Response;
53
+ redirect(url: string | URL, status?: number): globalThis.Response;
54
+ };
55
+
56
+ declare const NodeRequest: {
57
+ new (nodeCtx: {
58
+ req: NodeHttp__default.IncomingMessage;
59
+ res: NodeHttp__default.ServerResponse;
60
+ }): ServerRequest;
61
+ };
62
+
63
+ declare const kNodeInspect: unique symbol;
64
+
65
+ declare const NodeRequestHeaders: {
66
+ new (nodeCtx: {
67
+ req: NodeHttp__default.IncomingMessage;
68
+ res?: NodeHttp__default.ServerResponse;
69
+ }): {
70
+ node: {
71
+ req: NodeHttp__default.IncomingMessage;
72
+ res?: NodeHttp__default.ServerResponse;
73
+ };
74
+ append(name: string, value: string): void;
75
+ delete(name: string): void;
76
+ get(name: string): string | null;
77
+ getSetCookie(): string[];
78
+ has(name: string): boolean;
79
+ set(name: string, value: string): void;
80
+ readonly count: number;
81
+ getAll(_name: "set-cookie" | "Set-Cookie"): string[];
82
+ toJSON(): Record<string, string>;
83
+ forEach(cb: (value: string, key: string, parent: /*elided*/ any) => void, thisArg?: any): void;
84
+ entries(): HeadersIterator<[string, string]>;
85
+ keys(): HeadersIterator<string>;
86
+ values(): HeadersIterator<string>;
87
+ [Symbol.iterator](): HeadersIterator<[string, string]>;
88
+ readonly [Symbol.toStringTag]: string;
89
+ [kNodeInspect](): {
90
+ [k: string]: string;
91
+ };
92
+ };
93
+ };
94
+ declare const NodeResponseHeaders: {
95
+ new (nodeCtx: {
96
+ req?: NodeHttp__default.IncomingMessage;
97
+ res: NodeHttp__default.ServerResponse;
98
+ }): {
99
+ node: {
100
+ req?: NodeHttp__default.IncomingMessage;
101
+ res: NodeHttp__default.ServerResponse;
102
+ };
103
+ append(name: string, value: string): void;
104
+ delete(name: string): void;
105
+ get(name: string): string | null;
106
+ getSetCookie(): string[];
107
+ has(name: string): boolean;
108
+ set(name: string, value: string): void;
109
+ readonly count: number;
110
+ getAll(_name: "set-cookie" | "Set-Cookie"): string[];
111
+ toJSON(): Record<string, string>;
112
+ forEach(cb: (value: string, key: string, parent: /*elided*/ any) => void, thisArg?: any): void;
113
+ entries(): HeadersIterator<[string, string]>;
114
+ keys(): HeadersIterator<string>;
115
+ values(): HeadersIterator<string>;
116
+ [Symbol.iterator](): HeadersIterator<[string, string]>;
117
+ readonly [Symbol.toStringTag]: string;
118
+ [kNodeInspect](): {
119
+ [k: string]: string;
120
+ };
121
+ };
51
122
  };
52
123
 
53
124
  declare function serve(options: ServerOptions): Server;
54
125
  declare function toNodeHandler(fetchHandler: FetchHandler): NodeHttpHandler;
55
126
 
56
- export { NodeFastResponse as Response, serve, toNodeHandler };
127
+ export { NodeRequest, NodeRequestHeaders, NodeResponse, NodeResponseHeaders, NodeRequest as Request, NodeResponse as Response, serve, toNodeHandler };
@@ -89,19 +89,18 @@ function streamBody(stream, nodeRes) {
89
89
  });
90
90
  }
91
91
 
92
- const kNodeReq = /* @__PURE__ */ Symbol.for("srvx.node.request");
93
92
  const kNodeInspect = /* @__PURE__ */ Symbol.for(
94
93
  "nodejs.util.inspect.custom"
95
94
  );
96
95
 
97
- const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
98
- class NodeReqHeadersProxy2 {
99
- constructor(req) {
100
- this[kNodeReq] = req;
96
+ const NodeRequestHeaders = /* @__PURE__ */ (() => {
97
+ const _Headers = class Headers {
98
+ constructor(nodeCtx) {
99
+ this.node = nodeCtx;
101
100
  }
102
101
  append(name, value) {
103
102
  name = name.toLowerCase();
104
- const _headers = this[kNodeReq].headers;
103
+ const _headers = this.node.req.headers;
105
104
  const _current = _headers[name];
106
105
  if (_current) {
107
106
  if (Array.isArray(_current)) {
@@ -115,14 +114,18 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
115
114
  }
116
115
  delete(name) {
117
116
  name = name.toLowerCase();
118
- this[kNodeReq].headers[name] = void 0;
117
+ this.node.req.headers[name] = void 0;
119
118
  }
120
119
  get(name) {
121
120
  name = name.toLowerCase();
122
- return _normalizeValue(this[kNodeReq].headers[name]);
121
+ const rawValue = this.node.req.headers[name];
122
+ if (rawValue === void 0) {
123
+ return null;
124
+ }
125
+ return _normalizeValue(this.node.req.headers[name]);
123
126
  }
124
127
  getSetCookie() {
125
- const setCookie = this[kNodeReq].headers["set-cookie"];
128
+ const setCookie = this.node.req.headers["set-cookie"];
126
129
  if (!setCookie || setCookie.length === 0) {
127
130
  return [];
128
131
  }
@@ -130,11 +133,11 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
130
133
  }
131
134
  has(name) {
132
135
  name = name.toLowerCase();
133
- return !!this[kNodeReq].headers[name];
136
+ return !!this.node.req.headers[name];
134
137
  }
135
138
  set(name, value) {
136
139
  name = name.toLowerCase();
137
- this[kNodeReq].headers[name] = value;
140
+ this.node.req.headers[name] = value;
138
141
  }
139
142
  get count() {
140
143
  throw new Error("Method not implemented.");
@@ -143,7 +146,7 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
143
146
  throw new Error("Method not implemented.");
144
147
  }
145
148
  toJSON() {
146
- const _headers = this[kNodeReq].headers;
149
+ const _headers = this.node.req.headers;
147
150
  const result = {};
148
151
  for (const key in _headers) {
149
152
  if (_headers[key]) {
@@ -153,7 +156,7 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
153
156
  return result;
154
157
  }
155
158
  forEach(cb, thisArg) {
156
- const _headers = this[kNodeReq].headers;
159
+ const _headers = this.node.req.headers;
157
160
  for (const key in _headers) {
158
161
  if (_headers[key]) {
159
162
  cb.call(
@@ -166,24 +169,24 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
166
169
  }
167
170
  }
168
171
  *entries() {
169
- const _headers = this[kNodeReq].headers;
172
+ const _headers = this.node.req.headers;
170
173
  for (const key in _headers) {
171
174
  yield [key, _normalizeValue(_headers[key])];
172
175
  }
173
176
  }
174
177
  *keys() {
175
- const keys = Object.keys(this[kNodeReq].headers);
178
+ const keys = Object.keys(this.node.req.headers);
176
179
  for (const key of keys) {
177
180
  yield key;
178
181
  }
179
182
  }
180
183
  *values() {
181
- const values = Object.values(this[kNodeReq].headers);
184
+ const values = Object.values(this.node.req.headers);
182
185
  for (const value of values) {
183
186
  yield _normalizeValue(value);
184
187
  }
185
188
  }
186
- [(Symbol.iterator)]() {
189
+ [Symbol.iterator]() {
187
190
  return this.entries()[Symbol.iterator]();
188
191
  }
189
192
  get [Symbol.toStringTag]() {
@@ -192,160 +195,273 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
192
195
  [kNodeInspect]() {
193
196
  return Object.fromEntries(this.entries());
194
197
  }
195
- }
196
- Object.setPrototypeOf(NodeReqHeadersProxy2.prototype, Headers.prototype);
197
- return NodeReqHeadersProxy2;
198
+ };
199
+ Object.setPrototypeOf(_Headers.prototype, globalThis.Headers.prototype);
200
+ return _Headers;
201
+ })();
202
+ const NodeResponseHeaders = /* @__PURE__ */ (() => {
203
+ const _Headers = class Headers {
204
+ constructor(nodeCtx) {
205
+ this.node = nodeCtx;
206
+ }
207
+ append(name, value) {
208
+ this.node.res.appendHeader(name, value);
209
+ }
210
+ delete(name) {
211
+ this.node.res.removeHeader(name);
212
+ }
213
+ get(name) {
214
+ const rawValue = this.node.res.getHeader(name);
215
+ if (rawValue === void 0) {
216
+ return null;
217
+ }
218
+ return _normalizeValue(rawValue);
219
+ }
220
+ getSetCookie() {
221
+ const setCookie = _normalizeValue(this.node.res.getHeader("set-cookie"));
222
+ if (!setCookie) {
223
+ return [];
224
+ }
225
+ return splitSetCookieString(setCookie);
226
+ }
227
+ has(name) {
228
+ return this.node.res.hasHeader(name);
229
+ }
230
+ set(name, value) {
231
+ this.node.res.setHeader(name, value);
232
+ }
233
+ get count() {
234
+ throw new Error("Method not implemented.");
235
+ }
236
+ getAll(_name) {
237
+ throw new Error("Method not implemented.");
238
+ }
239
+ toJSON() {
240
+ const _headers = this.node.res.getHeaders();
241
+ const result = {};
242
+ for (const key in _headers) {
243
+ if (_headers[key]) {
244
+ result[key] = _normalizeValue(_headers[key]);
245
+ }
246
+ }
247
+ return result;
248
+ }
249
+ forEach(cb, thisArg) {
250
+ const _headers = this.node.res.getHeaders();
251
+ for (const key in _headers) {
252
+ if (_headers[key]) {
253
+ cb.call(
254
+ thisArg,
255
+ _normalizeValue(_headers[key]),
256
+ key,
257
+ this
258
+ );
259
+ }
260
+ }
261
+ }
262
+ *entries() {
263
+ const _headers = this.node.res.getHeaders();
264
+ for (const key in _headers) {
265
+ yield [key, _normalizeValue(_headers[key])];
266
+ }
267
+ }
268
+ *keys() {
269
+ const keys = this.node.res.getHeaderNames();
270
+ for (const key of keys) {
271
+ yield key;
272
+ }
273
+ }
274
+ *values() {
275
+ const values = Object.values(this.node.res.getHeaders());
276
+ for (const value of values) {
277
+ yield _normalizeValue(value);
278
+ }
279
+ }
280
+ [Symbol.iterator]() {
281
+ return this.entries()[Symbol.iterator]();
282
+ }
283
+ get [Symbol.toStringTag]() {
284
+ return "Headers";
285
+ }
286
+ [kNodeInspect]() {
287
+ return Object.fromEntries(this.entries());
288
+ }
289
+ };
290
+ Object.setPrototypeOf(_Headers.prototype, globalThis.Headers.prototype);
291
+ return _Headers;
198
292
  })();
199
293
  function _normalizeValue(value) {
200
294
  if (Array.isArray(value)) {
201
295
  return value.join(", ");
202
296
  }
203
- return value || "";
297
+ return typeof value === "string" ? value : String(value ?? "");
204
298
  }
205
299
 
206
- const NodeReqURLProxy = /* @__PURE__ */ (() => class _NodeReqURLProxy {
207
- constructor(req) {
208
- this.hash = "";
209
- this.password = "";
210
- this.username = "";
211
- this[kNodeReq] = req;
212
- }
213
- // host
214
- get host() {
215
- return this[kNodeReq].headers.host || "";
216
- }
217
- set host(value) {
218
- this._hostname = void 0;
219
- this._port = void 0;
220
- this[kNodeReq].headers.host = value;
221
- }
222
- // hostname
223
- get hostname() {
224
- if (this._hostname === void 0) {
225
- const [hostname, port] = parseHost(this[kNodeReq].headers.host);
226
- if (this._port === void 0 && port) {
227
- this._port = String(Number.parseInt(port) || "");
300
+ const NodeRequestURL = /* @__PURE__ */ (() => {
301
+ const _URL = class URL {
302
+ constructor(nodeCtx) {
303
+ this._hash = "";
304
+ this._username = "";
305
+ this._password = "";
306
+ this.node = nodeCtx;
307
+ }
308
+ get hash() {
309
+ return this._hash;
310
+ }
311
+ set hash(value) {
312
+ this._hash = value;
313
+ }
314
+ get username() {
315
+ return this._username;
316
+ }
317
+ set username(value) {
318
+ this._username = value;
319
+ }
320
+ get password() {
321
+ return this._password;
322
+ }
323
+ set password(value) {
324
+ this._password = value;
325
+ }
326
+ // host
327
+ get host() {
328
+ return this.node.req.headers.host || "";
329
+ }
330
+ set host(value) {
331
+ this._hostname = void 0;
332
+ this._port = void 0;
333
+ this.node.req.headers.host = value;
334
+ }
335
+ // hostname
336
+ get hostname() {
337
+ if (this._hostname === void 0) {
338
+ const [hostname, port] = parseHost(this.node.req.headers.host);
339
+ if (this._port === void 0 && port) {
340
+ this._port = String(Number.parseInt(port) || "");
341
+ }
342
+ this._hostname = hostname || "localhost";
228
343
  }
229
- this._hostname = hostname || "localhost";
344
+ return this._hostname;
230
345
  }
231
- return this._hostname;
232
- }
233
- set hostname(value) {
234
- this._hostname = value;
235
- }
236
- // port
237
- get port() {
238
- if (this._port === void 0) {
239
- const [hostname, port] = parseHost(this[kNodeReq].headers.host);
240
- if (this._hostname === void 0 && hostname) {
241
- this._hostname = hostname;
346
+ set hostname(value) {
347
+ this._hostname = value;
348
+ }
349
+ // port
350
+ get port() {
351
+ if (this._port === void 0) {
352
+ const [hostname, port] = parseHost(this.node.req.headers.host);
353
+ if (this._hostname === void 0 && hostname) {
354
+ this._hostname = hostname;
355
+ }
356
+ this._port = port || String(this.node.req.socket?.localPort || "");
242
357
  }
243
- this._port = port || String(this[kNodeReq].socket?.localPort || "");
358
+ return this._port;
244
359
  }
245
- return this._port;
246
- }
247
- set port(value) {
248
- this._port = String(Number.parseInt(value) || "");
249
- }
250
- // pathname
251
- get pathname() {
252
- if (this._pathname === void 0) {
253
- const [pathname, search] = parsePath(this[kNodeReq].url || "/");
254
- this._pathname = pathname;
360
+ set port(value) {
361
+ this._port = String(Number.parseInt(value) || "");
362
+ }
363
+ // pathname
364
+ get pathname() {
365
+ if (this._pathname === void 0) {
366
+ const [pathname, search] = parsePath(this.node.req.url || "/");
367
+ this._pathname = pathname;
368
+ if (this._search === void 0) {
369
+ this._search = search;
370
+ }
371
+ }
372
+ return this._pathname;
373
+ }
374
+ set pathname(value) {
375
+ if (value[0] !== "/") {
376
+ value = "/" + value;
377
+ }
378
+ if (value === this._pathname) {
379
+ return;
380
+ }
381
+ this._pathname = value;
382
+ this.node.req.url = value + this.search;
383
+ }
384
+ // search
385
+ get search() {
255
386
  if (this._search === void 0) {
387
+ const [pathname, search] = parsePath(this.node.req.url || "/");
256
388
  this._search = search;
389
+ if (this._pathname === void 0) {
390
+ this._pathname = pathname;
391
+ }
257
392
  }
393
+ return this._search;
258
394
  }
259
- return this._pathname;
260
- }
261
- set pathname(value) {
262
- if (value[0] !== "/") {
263
- value = "/" + value;
395
+ set search(value) {
396
+ if (value === "?") {
397
+ value = "";
398
+ } else if (value && value[0] !== "?") {
399
+ value = "?" + value;
400
+ }
401
+ if (value === this._search) {
402
+ return;
403
+ }
404
+ this._search = value;
405
+ this._searchParams = void 0;
406
+ this.node.req.url = this.pathname + value;
264
407
  }
265
- if (value === this._pathname) {
266
- return;
408
+ // searchParams
409
+ get searchParams() {
410
+ if (!this._searchParams) {
411
+ this._searchParams = new URLSearchParams(this.search);
412
+ }
413
+ return this._searchParams;
267
414
  }
268
- this._pathname = value;
269
- this[kNodeReq].url = value + this.search;
270
- }
271
- // search
272
- get search() {
273
- if (this._search === void 0) {
274
- const [pathname, search] = parsePath(this[kNodeReq].url || "/");
275
- this._search = search;
276
- if (this._pathname === void 0) {
277
- this._pathname = pathname;
415
+ set searchParams(value) {
416
+ this._searchParams = value;
417
+ this._search = value.toString();
418
+ }
419
+ // protocol
420
+ get protocol() {
421
+ if (!this._protocol) {
422
+ this._protocol = this.node.req.socket?.encrypted || this.node.req.headers["x-forwarded-proto"] === "https" ? "https:" : "http:";
278
423
  }
424
+ return this._protocol;
279
425
  }
280
- return this._search;
281
- }
282
- set search(value) {
283
- if (value === "?") {
284
- value = "";
285
- } else if (value && value[0] !== "?") {
286
- value = "?" + value;
426
+ set protocol(value) {
427
+ this._protocol = value;
287
428
  }
288
- if (value === this._search) {
289
- return;
429
+ // origin
430
+ get origin() {
431
+ return `${this.protocol}//${this.host}`;
290
432
  }
291
- this._search = value;
292
- this._searchParams = void 0;
293
- this[kNodeReq].url = this.pathname + value;
294
- }
295
- // searchParams
296
- get searchParams() {
297
- if (!this._searchParams) {
298
- this._searchParams = new URLSearchParams(this.search);
433
+ set origin(_value) {
299
434
  }
300
- return this._searchParams;
301
- }
302
- set searchParams(value) {
303
- this._searchParams = value;
304
- this._search = value.toString();
305
- }
306
- // protocol
307
- get protocol() {
308
- if (!this._protocol) {
309
- this._protocol = this[kNodeReq].socket?.encrypted || this[kNodeReq].headers["x-forwarded-proto"] === "https" ? "https:" : "http:";
435
+ // href
436
+ get href() {
437
+ return `${this.protocol}//${this.host}${this.pathname}${this.search}`;
310
438
  }
311
- return this._protocol;
312
- }
313
- set protocol(value) {
314
- this._protocol = value;
315
- }
316
- // origin
317
- get origin() {
318
- return `${this.protocol}//${this.host}`;
319
- }
320
- set origin(_value) {
321
- }
322
- // href
323
- get href() {
324
- return `${this.protocol}//${this.host}${this.pathname}${this.search}`;
325
- }
326
- set href(value) {
327
- const _url = new URL(value);
328
- this._protocol = _url.protocol;
329
- this.username = _url.username;
330
- this.password = _url.password;
331
- this._hostname = _url.hostname;
332
- this._port = _url.port;
333
- this.pathname = _url.pathname;
334
- this.search = _url.search;
335
- this.hash = _url.hash;
336
- }
337
- toString() {
338
- return this.href;
339
- }
340
- toJSON() {
341
- return this.href;
342
- }
343
- get [(Symbol.toStringTag)]() {
344
- return "URL";
345
- }
346
- [kNodeInspect]() {
347
- return this.href;
348
- }
439
+ set href(value) {
440
+ const _url = new globalThis.URL(value);
441
+ this._protocol = _url.protocol;
442
+ this.username = _url.username;
443
+ this.password = _url.password;
444
+ this._hostname = _url.hostname;
445
+ this._port = _url.port;
446
+ this.pathname = _url.pathname;
447
+ this.search = _url.search;
448
+ this.hash = _url.hash;
449
+ }
450
+ toString() {
451
+ return this.href;
452
+ }
453
+ toJSON() {
454
+ return this.href;
455
+ }
456
+ get [Symbol.toStringTag]() {
457
+ return "URL";
458
+ }
459
+ [kNodeInspect]() {
460
+ return this.href;
461
+ }
462
+ };
463
+ Object.setPrototypeOf(_URL.prototype, globalThis.URL.prototype);
464
+ return _URL;
349
465
  })();
350
466
  function parsePath(input) {
351
467
  const url = (input || "/").replace(/\\/g, "/");
@@ -360,8 +476,8 @@ function parseHost(host) {
360
476
  return [s[0], String(Number.parseInt(s[1]) || "")];
361
477
  }
362
478
 
363
- const NodeRequestProxy = /* @__PURE__ */ (() => {
364
- class NodeRequestProxy2 {
479
+ const NodeRequest = /* @__PURE__ */ (() => {
480
+ const _Request = class Request {
365
481
  #url;
366
482
  #headers;
367
483
  #bodyUsed = false;
@@ -373,29 +489,32 @@ const NodeRequestProxy = /* @__PURE__ */ (() => {
373
489
  #jsonBody;
374
490
  #textBody;
375
491
  #bodyStream;
376
- constructor(nodeReq) {
377
- this[kNodeReq] = nodeReq;
492
+ constructor(nodeCtx) {
493
+ this.node = nodeCtx;
378
494
  }
379
495
  get headers() {
380
496
  if (!this.#headers) {
381
- this.#headers = new NodeReqHeadersProxy(this[kNodeReq]);
497
+ this.#headers = new NodeRequestHeaders(this.node);
382
498
  }
383
499
  return this.#headers;
384
500
  }
385
501
  get remoteAddress() {
386
- return this[kNodeReq].socket?.remoteAddress;
502
+ return this.node.req.socket?.remoteAddress;
387
503
  }
388
504
  clone() {
389
- return new NodeRequestProxy2(this[kNodeReq]);
505
+ return new _Request({ ...this.node });
390
506
  }
391
- get url() {
507
+ get _url() {
392
508
  if (!this.#url) {
393
- this.#url = new NodeReqURLProxy(this[kNodeReq]);
509
+ this.#url = new NodeRequestURL(this.node);
394
510
  }
395
- return this.#url.href;
511
+ return this.#url;
512
+ }
513
+ get url() {
514
+ return this._url.href;
396
515
  }
397
516
  get method() {
398
- return this[kNodeReq].method || "GET";
517
+ return this.node.req.method || "GET";
399
518
  }
400
519
  get signal() {
401
520
  if (!this.#abortSignal) {
@@ -410,13 +529,13 @@ const NodeRequestProxy = /* @__PURE__ */ (() => {
410
529
  if (this.#hasBody !== void 0) {
411
530
  return this.#hasBody;
412
531
  }
413
- const method = this[kNodeReq].method?.toUpperCase();
532
+ const method = this.node.req.method?.toUpperCase();
414
533
  if (!method || !(method === "PATCH" || method === "POST" || method === "PUT" || method === "DELETE")) {
415
534
  this.#hasBody = false;
416
535
  return false;
417
536
  }
418
- if (!Number.parseInt(this[kNodeReq].headers["content-length"] || "")) {
419
- const isChunked = (this[kNodeReq].headers["transfer-encoding"] || "").split(",").map((e) => e.trim()).filter(Boolean).includes("chunked");
537
+ if (!Number.parseInt(this.node.req.headers["content-length"] || "")) {
538
+ const isChunked = (this.node.req.headers["transfer-encoding"] || "").split(",").map((e) => e.trim()).filter(Boolean).includes("chunked");
420
539
  if (!isChunked) {
421
540
  this.#hasBody = false;
422
541
  return false;
@@ -433,7 +552,7 @@ const NodeRequestProxy = /* @__PURE__ */ (() => {
433
552
  this.#bodyUsed = true;
434
553
  this.#bodyStream = new ReadableStream({
435
554
  start: (controller) => {
436
- this[kNodeReq].on("data", (chunk) => {
555
+ this.node.req.on("data", (chunk) => {
437
556
  controller.enqueue(chunk);
438
557
  }).once("error", (error) => {
439
558
  controller.error(error);
@@ -467,7 +586,7 @@ const NodeRequestProxy = /* @__PURE__ */ (() => {
467
586
  if (!this.#blobBody) {
468
587
  this.#blobBody = this.bytes().then((bytes) => {
469
588
  return new Blob([bytes], {
470
- type: this[kNodeReq].headers["content-type"]
589
+ type: this.node.req.headers["content-type"]
471
590
  });
472
591
  });
473
592
  }
@@ -497,7 +616,7 @@ const NodeRequestProxy = /* @__PURE__ */ (() => {
497
616
  }
498
617
  return this.#jsonBody;
499
618
  }
500
- get [(Symbol.toStringTag)]() {
619
+ get [Symbol.toStringTag]() {
501
620
  return "Request";
502
621
  }
503
622
  [kNodeInspect]() {
@@ -507,9 +626,9 @@ const NodeRequestProxy = /* @__PURE__ */ (() => {
507
626
  headers: this.headers
508
627
  };
509
628
  }
510
- }
511
- Object.setPrototypeOf(NodeRequestProxy2.prototype, Request.prototype);
512
- return NodeRequestProxy2;
629
+ };
630
+ Object.setPrototypeOf(_Request.prototype, globalThis.Request.prototype);
631
+ return _Request;
513
632
  })();
514
633
  async function _readStream(stream) {
515
634
  const chunks = [];
@@ -523,14 +642,38 @@ async function _readStream(stream) {
523
642
  return Buffer.concat(chunks);
524
643
  }
525
644
 
526
- const NodeFastResponse = /* @__PURE__ */ (() => {
527
- class NodeFastResponse2 {
645
+ const NodeResponse = /* @__PURE__ */ (() => {
646
+ const CONTENT_TYPE = "content-type";
647
+ const JSON_TYPE = "application/json";
648
+ const JSON_HEADER = [[CONTENT_TYPE, JSON_TYPE]];
649
+ const _Response = class Response {
528
650
  #body;
529
651
  #init;
530
652
  constructor(body, init) {
531
653
  this.#body = body;
532
654
  this.#init = init;
533
655
  }
656
+ static json(data, init) {
657
+ if (init?.headers) {
658
+ if (!init.headers[CONTENT_TYPE]) {
659
+ const initHeaders = new Headers(init.headers);
660
+ if (!initHeaders.has(CONTENT_TYPE)) {
661
+ initHeaders.set(CONTENT_TYPE, JSON_TYPE);
662
+ }
663
+ init = { ...init, headers: initHeaders };
664
+ }
665
+ } else {
666
+ init = init ? { ...init } : {};
667
+ init.headers = JSON_HEADER;
668
+ }
669
+ return new _Response(JSON.stringify(data), init);
670
+ }
671
+ static error() {
672
+ return globalThis.Response.error();
673
+ }
674
+ static redirect(url, status) {
675
+ return globalThis.Response.redirect(url, status);
676
+ }
534
677
  /**
535
678
  * Prepare Node.js response object
536
679
  */
@@ -572,7 +715,7 @@ const NodeFastResponse = /* @__PURE__ */ (() => {
572
715
  } else if (typeof bodyInit.pipe === "function") {
573
716
  body = bodyInit;
574
717
  } else {
575
- const res = new Response(bodyInit);
718
+ const res = new globalThis.Response(bodyInit);
576
719
  body = res.body;
577
720
  for (const [key, value] of res.headers) {
578
721
  headers.push([key, value]);
@@ -597,11 +740,11 @@ const NodeFastResponse = /* @__PURE__ */ (() => {
597
740
  if (this.#responseObj) {
598
741
  return this.#responseObj.clone();
599
742
  }
600
- return new Response(this.#body, this.#init);
743
+ return new globalThis.Response(this.#body, this.#init);
601
744
  }
602
745
  get #response() {
603
746
  if (!this.#responseObj) {
604
- this.#responseObj = new Response(this.#body, this.#init);
747
+ this.#responseObj = new globalThis.Response(this.#body, this.#init);
605
748
  this.#body = void 0;
606
749
  this.#init = void 0;
607
750
  this.#headersObj = void 0;
@@ -740,9 +883,9 @@ const NodeFastResponse = /* @__PURE__ */ (() => {
740
883
  }
741
884
  return this.text().then((text) => JSON.parse(text));
742
885
  }
743
- }
744
- Object.setPrototypeOf(NodeFastResponse2.prototype, Response.prototype);
745
- return NodeFastResponse2;
886
+ };
887
+ Object.setPrototypeOf(_Response.prototype, globalThis.Response.prototype);
888
+ return _Response;
746
889
  })();
747
890
 
748
891
  function serve(options) {
@@ -750,8 +893,7 @@ function serve(options) {
750
893
  }
751
894
  function toNodeHandler(fetchHandler) {
752
895
  return (nodeReq, nodeRes) => {
753
- const request = new NodeRequestProxy(nodeReq);
754
- request.node = { req: nodeReq, res: nodeRes };
896
+ const request = new NodeRequest({ req: nodeReq, res: nodeRes });
755
897
  const res = fetchHandler(request);
756
898
  return res instanceof Promise ? res.then((resolvedRes) => sendNodeResponse(nodeRes, resolvedRes)) : sendNodeResponse(nodeRes, res);
757
899
  };
@@ -763,8 +905,7 @@ class NodeServer {
763
905
  const fetchHandler = wrapFetch(this, this.options.fetch);
764
906
  this.fetch = fetchHandler;
765
907
  const handler = (nodeReq, nodeRes) => {
766
- const request = new NodeRequestProxy(nodeReq);
767
- request.node = { req: nodeReq, res: nodeRes };
908
+ const request = new NodeRequest({ req: nodeReq, res: nodeRes });
768
909
  const res = fetchHandler(request);
769
910
  return res instanceof Promise ? res.then((resolvedRes) => sendNodeResponse(nodeRes, resolvedRes)) : sendNodeResponse(nodeRes, res);
770
911
  };
@@ -820,4 +961,4 @@ class NodeServer {
820
961
  }
821
962
  }
822
963
 
823
- export { NodeFastResponse as Response, serve, toNodeHandler };
964
+ export { NodeRequest, NodeRequestHeaders, NodeResponse, NodeResponseHeaders, NodeRequest as Request, NodeResponse as Response, serve, toNodeHandler };
package/dist/types.d.mts CHANGED
@@ -194,9 +194,9 @@ interface ServerRequest extends Request {
194
194
  };
195
195
  }
196
196
  type FetchHandler = (request: Request) => Response | Promise<Response>;
197
- type BunFetchandler = (request: Request, server?: Bun.Server) => Response | Promise<Response>;
197
+ type BunFetchHandler = (request: Request, server?: Bun.Server) => Response | Promise<Response>;
198
198
  type DenoFetchHandler = (request: Request, info?: Deno.ServeHandlerInfo<Deno.NetAddr>) => Response | Promise<Response>;
199
199
  type NodeHttpHandler = (nodeReq: NodeHttp.IncomingMessage, nodeRes: NodeHttp.ServerResponse) => void | Promise<void>;
200
200
  type CloudflareFetchHandler = CF.ExportedHandlerFetchHandler;
201
201
 
202
- export { type BunFetchandler, type CloudflareFetchHandler, type DenoFetchHandler, type FetchHandler, type NodeHttpHandler, Response, type Server, type ServerHandler, type ServerOptions, type ServerPlugin, type ServerPluginInstance, type ServerRequest, serve };
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.6",
3
+ "version": "0.2.8",
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",
@@ -14,13 +13,14 @@
14
13
  "./node": "./dist/adapters/node.mjs",
15
14
  "./cloudflare": "./dist/adapters/cloudflare.mjs",
16
15
  ".": {
16
+ "types": "./dist/types.d.mts",
17
17
  "deno": "./dist/adapters/deno.mjs",
18
18
  "bun": "./dist/adapters/bun.mjs",
19
19
  "workerd": "./dist/adapters/cloudflare.mjs",
20
- "node": "./dist/adapters/node.mjs",
21
- "types": "./dist/types.d.mts"
20
+ "node": "./dist/adapters/node.mjs"
22
21
  }
23
22
  },
23
+ "types": "./dist/types.d.mts",
24
24
  "files": [
25
25
  "dist"
26
26
  ],
@@ -30,12 +30,12 @@
30
30
  "dev": "vitest dev",
31
31
  "lint": "eslint . && prettier -c .",
32
32
  "lint:fix": "automd && eslint . --fix && prettier -w .",
33
- "play:mkcert": "openssl req -x509 -newkey rsa:2048 -nodes -keyout server.key -out server.crt -days 365 -subj /CN=srvx.local",
34
- "play:node": "node playground/app.mjs",
35
- "play:deno": "deno run -A playground/app.mjs",
33
+ "prepack": "pnpm build",
36
34
  "play:bun": "bun playground/app.mjs",
37
35
  "play:cf": "pnpx wrangler dev playground/app.mjs",
38
- "prepack": "pnpm build",
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",
39
39
  "release": "pnpm test && changelogen --release && npm publish && git push --follow-tags",
40
40
  "test": "pnpm lint && pnpm test:types && vitest run --coverage",
41
41
  "test:types": "tsc --noEmit --skipLibCheck"
@@ -66,5 +66,8 @@
66
66
  "unbuild": "^3.5.0",
67
67
  "vitest": "^3.0.9"
68
68
  },
69
- "packageManager": "pnpm@10.6.5"
69
+ "packageManager": "pnpm@10.6.5",
70
+ "engines": {
71
+ "node": ">=20.11.1"
72
+ }
70
73
  }