srvx 0.2.7 → 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, 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,7 +23,7 @@ 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
29
  "__#4363@#responseObj"?: globalThis.Response;
@@ -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 };
@@ -93,7 +93,7 @@ const kNodeInspect = /* @__PURE__ */ Symbol.for(
93
93
  "nodejs.util.inspect.custom"
94
94
  );
95
95
 
96
- const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
96
+ const NodeRequestHeaders = /* @__PURE__ */ (() => {
97
97
  const _Headers = class Headers {
98
98
  constructor(nodeCtx) {
99
99
  this.node = nodeCtx;
@@ -118,6 +118,10 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
118
118
  }
119
119
  get(name) {
120
120
  name = name.toLowerCase();
121
+ const rawValue = this.node.req.headers[name];
122
+ if (rawValue === void 0) {
123
+ return null;
124
+ }
121
125
  return _normalizeValue(this.node.req.headers[name]);
122
126
  }
123
127
  getSetCookie() {
@@ -195,14 +199,105 @@ const NodeReqHeadersProxy = /* @__PURE__ */ (() => {
195
199
  Object.setPrototypeOf(_Headers.prototype, globalThis.Headers.prototype);
196
200
  return _Headers;
197
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;
292
+ })();
198
293
  function _normalizeValue(value) {
199
294
  if (Array.isArray(value)) {
200
295
  return value.join(", ");
201
296
  }
202
- return value || "";
297
+ return typeof value === "string" ? value : String(value ?? "");
203
298
  }
204
299
 
205
- const NodeReqURLProxy = /* @__PURE__ */ (() => {
300
+ const NodeRequestURL = /* @__PURE__ */ (() => {
206
301
  const _URL = class URL {
207
302
  constructor(nodeCtx) {
208
303
  this._hash = "";
@@ -381,7 +476,7 @@ function parseHost(host) {
381
476
  return [s[0], String(Number.parseInt(s[1]) || "")];
382
477
  }
383
478
 
384
- const NodeRequestProxy = /* @__PURE__ */ (() => {
479
+ const NodeRequest = /* @__PURE__ */ (() => {
385
480
  const _Request = class Request {
386
481
  #url;
387
482
  #headers;
@@ -399,7 +494,7 @@ const NodeRequestProxy = /* @__PURE__ */ (() => {
399
494
  }
400
495
  get headers() {
401
496
  if (!this.#headers) {
402
- this.#headers = new NodeReqHeadersProxy(this.node);
497
+ this.#headers = new NodeRequestHeaders(this.node);
403
498
  }
404
499
  return this.#headers;
405
500
  }
@@ -411,7 +506,7 @@ const NodeRequestProxy = /* @__PURE__ */ (() => {
411
506
  }
412
507
  get _url() {
413
508
  if (!this.#url) {
414
- this.#url = new NodeReqURLProxy(this.node);
509
+ this.#url = new NodeRequestURL(this.node);
415
510
  }
416
511
  return this.#url;
417
512
  }
@@ -547,7 +642,10 @@ async function _readStream(stream) {
547
642
  return Buffer.concat(chunks);
548
643
  }
549
644
 
550
- const NodeFastResponse = /* @__PURE__ */ (() => {
645
+ const NodeResponse = /* @__PURE__ */ (() => {
646
+ const CONTENT_TYPE = "content-type";
647
+ const JSON_TYPE = "application/json";
648
+ const JSON_HEADER = [[CONTENT_TYPE, JSON_TYPE]];
551
649
  const _Response = class Response {
552
650
  #body;
553
651
  #init;
@@ -555,6 +653,27 @@ const NodeFastResponse = /* @__PURE__ */ (() => {
555
653
  this.#body = body;
556
654
  this.#init = init;
557
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
+ }
558
677
  /**
559
678
  * Prepare Node.js response object
560
679
  */
@@ -774,7 +893,7 @@ function serve(options) {
774
893
  }
775
894
  function toNodeHandler(fetchHandler) {
776
895
  return (nodeReq, nodeRes) => {
777
- const request = new NodeRequestProxy({ req: nodeReq, res: nodeRes });
896
+ const request = new NodeRequest({ req: nodeReq, res: nodeRes });
778
897
  const res = fetchHandler(request);
779
898
  return res instanceof Promise ? res.then((resolvedRes) => sendNodeResponse(nodeRes, resolvedRes)) : sendNodeResponse(nodeRes, res);
780
899
  };
@@ -786,7 +905,7 @@ class NodeServer {
786
905
  const fetchHandler = wrapFetch(this, this.options.fetch);
787
906
  this.fetch = fetchHandler;
788
907
  const handler = (nodeReq, nodeRes) => {
789
- const request = new NodeRequestProxy({ req: nodeReq, res: nodeRes });
908
+ const request = new NodeRequest({ req: nodeReq, res: nodeRes });
790
909
  const res = fetchHandler(request);
791
910
  return res instanceof Promise ? res.then((resolvedRes) => sendNodeResponse(nodeRes, resolvedRes)) : sendNodeResponse(nodeRes, res);
792
911
  };
@@ -842,4 +961,4 @@ class NodeServer {
842
961
  }
843
962
  }
844
963
 
845
- export { NodeFastResponse as Response, serve, toNodeHandler };
964
+ export { NodeRequest, NodeRequestHeaders, NodeResponse, NodeResponseHeaders, NodeRequest as Request, NodeResponse as Response, serve, toNodeHandler };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "srvx",
3
- "version": "0.2.7",
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",
@@ -13,11 +13,11 @@
13
13
  "./node": "./dist/adapters/node.mjs",
14
14
  "./cloudflare": "./dist/adapters/cloudflare.mjs",
15
15
  ".": {
16
+ "types": "./dist/types.d.mts",
16
17
  "deno": "./dist/adapters/deno.mjs",
17
18
  "bun": "./dist/adapters/bun.mjs",
18
19
  "workerd": "./dist/adapters/cloudflare.mjs",
19
- "node": "./dist/adapters/node.mjs",
20
- "types": "./dist/types.d.mts"
20
+ "node": "./dist/adapters/node.mjs"
21
21
  }
22
22
  },
23
23
  "types": "./dist/types.d.mts",