srvx 0.2.8 → 0.3.0

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.
@@ -13,11 +13,14 @@ class BunServer {
13
13
  this.options = options;
14
14
  const fetchHandler = wrapFetch(this, this.options.fetch);
15
15
  this.fetch = (request, server) => {
16
- Object.defineProperties(request, {
17
- bun: { value: { server }, enumerable: true },
18
- remoteAddress: {
19
- get: () => server?.requestIP(request)?.address,
20
- enumerable: true
16
+ Object.defineProperty(request, "x", {
17
+ enumerable: true,
18
+ value: {
19
+ runtime: "bun",
20
+ bun: { server },
21
+ get ip() {
22
+ return server?.requestIP(request)?.address;
23
+ }
21
24
  }
22
25
  });
23
26
  return fetchHandler(request);
@@ -13,11 +13,11 @@ class CloudflareServer {
13
13
  this.options.fetch
14
14
  );
15
15
  this.fetch = (request, env, context) => {
16
- Object.defineProperties(request, {
17
- cloudflare: { value: { env, context }, enumerable: true },
18
- remoteAddress: {
19
- get: () => void 0,
20
- enumerable: true
16
+ Object.defineProperty(request, "x", {
17
+ enumerable: true,
18
+ value: {
19
+ runtime: "cloudflare",
20
+ cloudflare: { env, context }
21
21
  }
22
22
  });
23
23
  return fetchHandler(request);
@@ -13,11 +13,14 @@ class DenoServer {
13
13
  this.options = options;
14
14
  const fetchHandler = wrapFetch(this, this.options.fetch);
15
15
  this.fetch = (request, info) => {
16
- Object.defineProperties(request, {
17
- deno: { value: { info, server: this.deno?.server }, enumerable: true },
18
- remoteAddress: {
19
- get: () => info?.remoteAddr?.hostname,
20
- enumerable: true
16
+ Object.defineProperty(request, "x", {
17
+ enumerable: true,
18
+ value: {
19
+ runtime: "deno",
20
+ deno: { info, server: this.deno?.server },
21
+ get ip() {
22
+ return info?.remoteAddr?.hostname;
23
+ }
21
24
  }
22
25
  });
23
26
  return fetchHandler(request);
@@ -14,8 +14,8 @@ type NodeResponse = InstanceType<typeof NodeResponse>;
14
14
  */
15
15
  declare const NodeResponse: {
16
16
  new (body?: BodyInit | null, init?: ResponseInit): {
17
- "__#4363@#body"?: BodyInit | null;
18
- "__#4363@#init"?: ResponseInit;
17
+ "__#4362@#body"?: BodyInit | null;
18
+ "__#4362@#init"?: ResponseInit;
19
19
  /**
20
20
  * Prepare Node.js response object
21
21
  */
@@ -23,14 +23,14 @@ declare const NodeResponse: {
23
23
  status: number;
24
24
  statusText: string;
25
25
  headers: NodeHttp__default.OutgoingHttpHeader[];
26
- body: string | Buffer<ArrayBufferLike> | Uint8Array<ArrayBufferLike> | ReadableStream<Uint8Array<ArrayBufferLike>> | Readable | DataView<ArrayBufferLike> | null | undefined;
26
+ body: string | Uint8Array<ArrayBufferLike> | ReadableStream<Uint8Array<ArrayBufferLike>> | Readable | Buffer<ArrayBufferLike> | DataView<ArrayBufferLike> | null | undefined;
27
27
  };
28
28
  /** Lazy initialized response instance */
29
- "__#4363@#responseObj"?: globalThis.Response;
29
+ "__#4362@#responseObj"?: globalThis.Response;
30
30
  /** Lazy initialized headers instance */
31
- "__#4363@#headersObj"?: Headers;
31
+ "__#4362@#headersObj"?: Headers;
32
32
  clone(): globalThis.Response;
33
- readonly "__#4363@#response": globalThis.Response;
33
+ readonly "__#4362@#response": globalThis.Response;
34
34
  readonly headers: Headers;
35
35
  readonly ok: boolean;
36
36
  readonly redirected: boolean;
@@ -38,7 +38,7 @@ declare const NodeResponse: {
38
38
  readonly statusText: string;
39
39
  readonly type: ResponseType;
40
40
  readonly url: string;
41
- "__#4363@#fastBody"<T extends object>(as: new (...args: any[]) => T): T | null | false;
41
+ "__#4362@#fastBody"<T extends object>(as: new (...args: any[]) => T): T | null | false;
42
42
  readonly body: ReadableStream<Uint8Array> | null;
43
43
  readonly bodyUsed: boolean;
44
44
  arrayBuffer(): Promise<ArrayBuffer>;
@@ -67,7 +67,7 @@ declare const NodeRequestHeaders: {
67
67
  req: NodeHttp__default.IncomingMessage;
68
68
  res?: NodeHttp__default.ServerResponse;
69
69
  }): {
70
- node: {
70
+ _node: {
71
71
  req: NodeHttp__default.IncomingMessage;
72
72
  res?: NodeHttp__default.ServerResponse;
73
73
  };
@@ -96,7 +96,7 @@ declare const NodeResponseHeaders: {
96
96
  req?: NodeHttp__default.IncomingMessage;
97
97
  res: NodeHttp__default.ServerResponse;
98
98
  }): {
99
- node: {
99
+ _node: {
100
100
  req?: NodeHttp__default.IncomingMessage;
101
101
  res: NodeHttp__default.ServerResponse;
102
102
  };
@@ -96,11 +96,11 @@ const kNodeInspect = /* @__PURE__ */ Symbol.for(
96
96
  const NodeRequestHeaders = /* @__PURE__ */ (() => {
97
97
  const _Headers = class Headers {
98
98
  constructor(nodeCtx) {
99
- this.node = nodeCtx;
99
+ this._node = nodeCtx;
100
100
  }
101
101
  append(name, value) {
102
102
  name = name.toLowerCase();
103
- const _headers = this.node.req.headers;
103
+ const _headers = this._node.req.headers;
104
104
  const _current = _headers[name];
105
105
  if (_current) {
106
106
  if (Array.isArray(_current)) {
@@ -114,18 +114,18 @@ const NodeRequestHeaders = /* @__PURE__ */ (() => {
114
114
  }
115
115
  delete(name) {
116
116
  name = name.toLowerCase();
117
- this.node.req.headers[name] = void 0;
117
+ this._node.req.headers[name] = void 0;
118
118
  }
119
119
  get(name) {
120
120
  name = name.toLowerCase();
121
- const rawValue = this.node.req.headers[name];
121
+ const rawValue = this._node.req.headers[name];
122
122
  if (rawValue === void 0) {
123
123
  return null;
124
124
  }
125
- return _normalizeValue(this.node.req.headers[name]);
125
+ return _normalizeValue(this._node.req.headers[name]);
126
126
  }
127
127
  getSetCookie() {
128
- const setCookie = this.node.req.headers["set-cookie"];
128
+ const setCookie = this._node.req.headers["set-cookie"];
129
129
  if (!setCookie || setCookie.length === 0) {
130
130
  return [];
131
131
  }
@@ -133,11 +133,11 @@ const NodeRequestHeaders = /* @__PURE__ */ (() => {
133
133
  }
134
134
  has(name) {
135
135
  name = name.toLowerCase();
136
- return !!this.node.req.headers[name];
136
+ return !!this._node.req.headers[name];
137
137
  }
138
138
  set(name, value) {
139
139
  name = name.toLowerCase();
140
- this.node.req.headers[name] = value;
140
+ this._node.req.headers[name] = value;
141
141
  }
142
142
  get count() {
143
143
  throw new Error("Method not implemented.");
@@ -146,7 +146,7 @@ const NodeRequestHeaders = /* @__PURE__ */ (() => {
146
146
  throw new Error("Method not implemented.");
147
147
  }
148
148
  toJSON() {
149
- const _headers = this.node.req.headers;
149
+ const _headers = this._node.req.headers;
150
150
  const result = {};
151
151
  for (const key in _headers) {
152
152
  if (_headers[key]) {
@@ -156,7 +156,7 @@ const NodeRequestHeaders = /* @__PURE__ */ (() => {
156
156
  return result;
157
157
  }
158
158
  forEach(cb, thisArg) {
159
- const _headers = this.node.req.headers;
159
+ const _headers = this._node.req.headers;
160
160
  for (const key in _headers) {
161
161
  if (_headers[key]) {
162
162
  cb.call(
@@ -169,19 +169,19 @@ const NodeRequestHeaders = /* @__PURE__ */ (() => {
169
169
  }
170
170
  }
171
171
  *entries() {
172
- const _headers = this.node.req.headers;
172
+ const _headers = this._node.req.headers;
173
173
  for (const key in _headers) {
174
174
  yield [key, _normalizeValue(_headers[key])];
175
175
  }
176
176
  }
177
177
  *keys() {
178
- const keys = Object.keys(this.node.req.headers);
178
+ const keys = Object.keys(this._node.req.headers);
179
179
  for (const key of keys) {
180
180
  yield key;
181
181
  }
182
182
  }
183
183
  *values() {
184
- const values = Object.values(this.node.req.headers);
184
+ const values = Object.values(this._node.req.headers);
185
185
  for (const value of values) {
186
186
  yield _normalizeValue(value);
187
187
  }
@@ -202,33 +202,33 @@ const NodeRequestHeaders = /* @__PURE__ */ (() => {
202
202
  const NodeResponseHeaders = /* @__PURE__ */ (() => {
203
203
  const _Headers = class Headers {
204
204
  constructor(nodeCtx) {
205
- this.node = nodeCtx;
205
+ this._node = nodeCtx;
206
206
  }
207
207
  append(name, value) {
208
- this.node.res.appendHeader(name, value);
208
+ this._node.res.appendHeader(name, value);
209
209
  }
210
210
  delete(name) {
211
- this.node.res.removeHeader(name);
211
+ this._node.res.removeHeader(name);
212
212
  }
213
213
  get(name) {
214
- const rawValue = this.node.res.getHeader(name);
214
+ const rawValue = this._node.res.getHeader(name);
215
215
  if (rawValue === void 0) {
216
216
  return null;
217
217
  }
218
218
  return _normalizeValue(rawValue);
219
219
  }
220
220
  getSetCookie() {
221
- const setCookie = _normalizeValue(this.node.res.getHeader("set-cookie"));
221
+ const setCookie = _normalizeValue(this._node.res.getHeader("set-cookie"));
222
222
  if (!setCookie) {
223
223
  return [];
224
224
  }
225
225
  return splitSetCookieString(setCookie);
226
226
  }
227
227
  has(name) {
228
- return this.node.res.hasHeader(name);
228
+ return this._node.res.hasHeader(name);
229
229
  }
230
230
  set(name, value) {
231
- this.node.res.setHeader(name, value);
231
+ this._node.res.setHeader(name, value);
232
232
  }
233
233
  get count() {
234
234
  throw new Error("Method not implemented.");
@@ -237,7 +237,7 @@ const NodeResponseHeaders = /* @__PURE__ */ (() => {
237
237
  throw new Error("Method not implemented.");
238
238
  }
239
239
  toJSON() {
240
- const _headers = this.node.res.getHeaders();
240
+ const _headers = this._node.res.getHeaders();
241
241
  const result = {};
242
242
  for (const key in _headers) {
243
243
  if (_headers[key]) {
@@ -247,7 +247,7 @@ const NodeResponseHeaders = /* @__PURE__ */ (() => {
247
247
  return result;
248
248
  }
249
249
  forEach(cb, thisArg) {
250
- const _headers = this.node.res.getHeaders();
250
+ const _headers = this._node.res.getHeaders();
251
251
  for (const key in _headers) {
252
252
  if (_headers[key]) {
253
253
  cb.call(
@@ -260,19 +260,19 @@ const NodeResponseHeaders = /* @__PURE__ */ (() => {
260
260
  }
261
261
  }
262
262
  *entries() {
263
- const _headers = this.node.res.getHeaders();
263
+ const _headers = this._node.res.getHeaders();
264
264
  for (const key in _headers) {
265
265
  yield [key, _normalizeValue(_headers[key])];
266
266
  }
267
267
  }
268
268
  *keys() {
269
- const keys = this.node.res.getHeaderNames();
269
+ const keys = this._node.res.getHeaderNames();
270
270
  for (const key of keys) {
271
271
  yield key;
272
272
  }
273
273
  }
274
274
  *values() {
275
- const values = Object.values(this.node.res.getHeaders());
275
+ const values = Object.values(this._node.res.getHeaders());
276
276
  for (const value of values) {
277
277
  yield _normalizeValue(value);
278
278
  }
@@ -303,7 +303,7 @@ const NodeRequestURL = /* @__PURE__ */ (() => {
303
303
  this._hash = "";
304
304
  this._username = "";
305
305
  this._password = "";
306
- this.node = nodeCtx;
306
+ this._node = nodeCtx;
307
307
  }
308
308
  get hash() {
309
309
  return this._hash;
@@ -325,17 +325,17 @@ const NodeRequestURL = /* @__PURE__ */ (() => {
325
325
  }
326
326
  // host
327
327
  get host() {
328
- return this.node.req.headers.host || "";
328
+ return this._node.req.headers.host || "";
329
329
  }
330
330
  set host(value) {
331
331
  this._hostname = void 0;
332
332
  this._port = void 0;
333
- this.node.req.headers.host = value;
333
+ this._node.req.headers.host = value;
334
334
  }
335
335
  // hostname
336
336
  get hostname() {
337
337
  if (this._hostname === void 0) {
338
- const [hostname, port] = parseHost(this.node.req.headers.host);
338
+ const [hostname, port] = parseHost(this._node.req.headers.host);
339
339
  if (this._port === void 0 && port) {
340
340
  this._port = String(Number.parseInt(port) || "");
341
341
  }
@@ -349,11 +349,11 @@ const NodeRequestURL = /* @__PURE__ */ (() => {
349
349
  // port
350
350
  get port() {
351
351
  if (this._port === void 0) {
352
- const [hostname, port] = parseHost(this.node.req.headers.host);
352
+ const [hostname, port] = parseHost(this._node.req.headers.host);
353
353
  if (this._hostname === void 0 && hostname) {
354
354
  this._hostname = hostname;
355
355
  }
356
- this._port = port || String(this.node.req.socket?.localPort || "");
356
+ this._port = port || String(this._node.req.socket?.localPort || "");
357
357
  }
358
358
  return this._port;
359
359
  }
@@ -363,7 +363,7 @@ const NodeRequestURL = /* @__PURE__ */ (() => {
363
363
  // pathname
364
364
  get pathname() {
365
365
  if (this._pathname === void 0) {
366
- const [pathname, search] = parsePath(this.node.req.url || "/");
366
+ const [pathname, search] = parsePath(this._node.req.url || "/");
367
367
  this._pathname = pathname;
368
368
  if (this._search === void 0) {
369
369
  this._search = search;
@@ -379,12 +379,12 @@ const NodeRequestURL = /* @__PURE__ */ (() => {
379
379
  return;
380
380
  }
381
381
  this._pathname = value;
382
- this.node.req.url = value + this.search;
382
+ this._node.req.url = value + this.search;
383
383
  }
384
384
  // search
385
385
  get search() {
386
386
  if (this._search === void 0) {
387
- const [pathname, search] = parsePath(this.node.req.url || "/");
387
+ const [pathname, search] = parsePath(this._node.req.url || "/");
388
388
  this._search = search;
389
389
  if (this._pathname === void 0) {
390
390
  this._pathname = pathname;
@@ -403,7 +403,7 @@ const NodeRequestURL = /* @__PURE__ */ (() => {
403
403
  }
404
404
  this._search = value;
405
405
  this._searchParams = void 0;
406
- this.node.req.url = this.pathname + value;
406
+ this._node.req.url = this.pathname + value;
407
407
  }
408
408
  // searchParams
409
409
  get searchParams() {
@@ -419,7 +419,7 @@ const NodeRequestURL = /* @__PURE__ */ (() => {
419
419
  // protocol
420
420
  get protocol() {
421
421
  if (!this._protocol) {
422
- this._protocol = this.node.req.socket?.encrypted || this.node.req.headers["x-forwarded-proto"] === "https" ? "https:" : "http:";
422
+ this._protocol = this._node.req.socket?.encrypted || this._node.req.headers["x-forwarded-proto"] === "https" ? "https:" : "http:";
423
423
  }
424
424
  return this._protocol;
425
425
  }
@@ -490,23 +490,27 @@ const NodeRequest = /* @__PURE__ */ (() => {
490
490
  #textBody;
491
491
  #bodyStream;
492
492
  constructor(nodeCtx) {
493
- this.node = nodeCtx;
493
+ this._node = nodeCtx;
494
+ this.x = {
495
+ runtime: "node",
496
+ node: nodeCtx,
497
+ get ip() {
498
+ return nodeCtx.req.socket?.remoteAddress;
499
+ }
500
+ };
494
501
  }
495
502
  get headers() {
496
503
  if (!this.#headers) {
497
- this.#headers = new NodeRequestHeaders(this.node);
504
+ this.#headers = new NodeRequestHeaders(this._node);
498
505
  }
499
506
  return this.#headers;
500
507
  }
501
- get remoteAddress() {
502
- return this.node.req.socket?.remoteAddress;
503
- }
504
508
  clone() {
505
- return new _Request({ ...this.node });
509
+ return new _Request({ ...this._node });
506
510
  }
507
511
  get _url() {
508
512
  if (!this.#url) {
509
- this.#url = new NodeRequestURL(this.node);
513
+ this.#url = new NodeRequestURL(this._node);
510
514
  }
511
515
  return this.#url;
512
516
  }
@@ -514,7 +518,7 @@ const NodeRequest = /* @__PURE__ */ (() => {
514
518
  return this._url.href;
515
519
  }
516
520
  get method() {
517
- return this.node.req.method || "GET";
521
+ return this._node.req.method || "GET";
518
522
  }
519
523
  get signal() {
520
524
  if (!this.#abortSignal) {
@@ -529,13 +533,13 @@ const NodeRequest = /* @__PURE__ */ (() => {
529
533
  if (this.#hasBody !== void 0) {
530
534
  return this.#hasBody;
531
535
  }
532
- const method = this.node.req.method?.toUpperCase();
536
+ const method = this._node.req.method?.toUpperCase();
533
537
  if (!method || !(method === "PATCH" || method === "POST" || method === "PUT" || method === "DELETE")) {
534
538
  this.#hasBody = false;
535
539
  return false;
536
540
  }
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");
541
+ if (!Number.parseInt(this._node.req.headers["content-length"] || "")) {
542
+ const isChunked = (this._node.req.headers["transfer-encoding"] || "").split(",").map((e) => e.trim()).filter(Boolean).includes("chunked");
539
543
  if (!isChunked) {
540
544
  this.#hasBody = false;
541
545
  return false;
@@ -552,7 +556,7 @@ const NodeRequest = /* @__PURE__ */ (() => {
552
556
  this.#bodyUsed = true;
553
557
  this.#bodyStream = new ReadableStream({
554
558
  start: (controller) => {
555
- this.node.req.on("data", (chunk) => {
559
+ this._node.req.on("data", (chunk) => {
556
560
  controller.enqueue(chunk);
557
561
  }).once("error", (error) => {
558
562
  controller.error(error);
@@ -586,7 +590,7 @@ const NodeRequest = /* @__PURE__ */ (() => {
586
590
  if (!this.#blobBody) {
587
591
  this.#blobBody = this.bytes().then((bytes) => {
588
592
  return new Blob([bytes], {
589
- type: this.node.req.headers["content-type"]
593
+ type: this._node.req.headers["content-type"]
590
594
  });
591
595
  });
592
596
  }
package/dist/types.d.mts CHANGED
@@ -161,17 +161,18 @@ interface ServerPluginInstance {
161
161
  */
162
162
  response?: (request: ServerRequest, response: Response) => MaybePromise<void | Response>;
163
163
  }
164
- interface ServerRequest extends Request {
164
+ interface ServerRuntimeContext {
165
+ runtime: "node" | "deno" | "bun" | "cloudflare" | (string & {});
165
166
  /**
166
- * Remote address of the client.
167
+ * IP address of the client.
167
168
  */
168
- remoteAddress?: string | undefined;
169
+ ip?: string | undefined;
169
170
  /**
170
171
  * Underlying Node.js server request info.
171
172
  */
172
173
  node?: {
173
174
  req: NodeHttp.IncomingMessage;
174
- res: NodeHttp.ServerResponse;
175
+ res?: NodeHttp.ServerResponse;
175
176
  };
176
177
  /**
177
178
  * Underlying Deno server request info.
@@ -193,10 +194,16 @@ interface ServerRequest extends Request {
193
194
  context: CF.ExecutionContext;
194
195
  };
195
196
  }
197
+ interface ServerRequest extends Request {
198
+ /**
199
+ * Runtime specific request context.
200
+ */
201
+ x?: ServerRuntimeContext;
202
+ }
196
203
  type FetchHandler = (request: Request) => Response | Promise<Response>;
197
204
  type BunFetchHandler = (request: Request, server?: Bun.Server) => Response | Promise<Response>;
198
205
  type DenoFetchHandler = (request: Request, info?: Deno.ServeHandlerInfo<Deno.NetAddr>) => Response | Promise<Response>;
199
206
  type NodeHttpHandler = (nodeReq: NodeHttp.IncomingMessage, nodeRes: NodeHttp.ServerResponse) => void | Promise<void>;
200
207
  type CloudflareFetchHandler = CF.ExportedHandlerFetchHandler;
201
208
 
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 };
209
+ export { type BunFetchHandler, type CloudflareFetchHandler, type DenoFetchHandler, type FetchHandler, type NodeHttpHandler, Response, type Server, type ServerHandler, type ServerOptions, type ServerPlugin, type ServerPluginInstance, type ServerRequest, type ServerRuntimeContext, serve };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "srvx",
3
- "version": "0.2.8",
3
+ "version": "0.3.0",
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",