@sourceregistry/node-webserver 1.4.0 → 1.5.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.
package/dist/index.es.js CHANGED
@@ -31,7 +31,7 @@ function T(e) {
31
31
  }
32
32
  //#endregion
33
33
  //#region src/middlewares/ratelimiter/InMemory.ts
34
- var E = class {
34
+ var ee = class {
35
35
  constructor(e) {
36
36
  this.data = /* @__PURE__ */ new Map(), this.windowMs = e.windowMs, this.startCleanup();
37
37
  }
@@ -57,35 +57,37 @@ var E = class {
57
57
  async resetAll() {
58
58
  this.data.clear();
59
59
  }
60
- }, D = /* @__PURE__ */ S({ fixedWindowLimit: () => O });
61
- function O(e) {
62
- let { windowMs: t = 6e4, max: n, key: r = (e) => e.getClientAddress(), message: i = "Too many requests, please try again later.", statusCode: a = 429, headers: o = "include", onRateLimit: s, store: c = new E({ windowMs: t }) } = e;
60
+ }, E = /* @__PURE__ */ S({ fixedWindowLimit: () => D });
61
+ function D(e) {
62
+ let { windowMs: t = 6e4, max: n, key: r = (e) => e.getClientAddress(), message: i = "Too many requests, please try again later.", statusCode: a = 429, headers: o = "include", onRateLimit: s, store: c = new ee({ windowMs: t }) } = e;
63
63
  return async (e, t) => {
64
- let l = `rl:${r(e)}`, { current: u, reset: d } = await c.incr(l), f = Math.ceil((d - Date.now()) / 1e3);
65
- if (u > n) {
64
+ let l = r(e);
65
+ if (typeof l != "string" || !/^[a-zA-Z0-9_.-]+$/.test(l)) throw Error("Invalid rate limit key: only alphanumeric, underscore, dot, and hyphen allowed");
66
+ let u = `rl:${l}`, { current: d, reset: f } = await c.incr(u), p = Math.ceil((f - Date.now()) / 1e3);
67
+ if (d > n) {
66
68
  s && s(e, {
67
- current: u,
69
+ current: d,
68
70
  max: n,
69
- key: l
71
+ key: u
70
72
  });
71
73
  let t = {
72
74
  status: a,
73
75
  headers: new Headers()
74
76
  }, r = t.headers;
75
- o === "include" && (r.set("X-RateLimit-Limit", String(n)), r.set("X-RateLimit-Remaining", "0"), r.set("X-RateLimit-Reset", String(Math.floor(d / 1e3))), r.set("Retry-After", String(f)));
77
+ o === "include" && (r.set("X-RateLimit-Limit", String(n)), r.set("X-RateLimit-Remaining", "0"), r.set("X-RateLimit-Reset", String(Math.floor(f / 1e3))), r.set("Retry-After", String(p)));
76
78
  let c;
77
79
  return typeof i == "string" ? (c = i, r.set("Content-Type", "text/plain")) : (c = JSON.stringify(i), r.set("Content-Type", "application/json")), new Response(c, t);
78
80
  }
79
81
  if (e.rateLimit = {
80
- current: u,
82
+ current: d,
81
83
  limit: n,
82
- reset: new Date(d),
83
- remaining: n - u
84
+ reset: new Date(f),
85
+ remaining: n - d
84
86
  }, o === "include") {
85
87
  let t = {
86
88
  "X-RateLimit-Limit": String(n),
87
- "X-RateLimit-Remaining": String(n - u),
88
- "X-RateLimit-Reset": String(Math.floor(d / 1e3))
89
+ "X-RateLimit-Remaining": String(n - d),
90
+ "X-RateLimit-Reset": String(Math.floor(f / 1e3))
89
91
  }, r = e.setHeaders;
90
92
  e.setHeaders = (e) => {
91
93
  r({
@@ -99,7 +101,7 @@ function O(e) {
99
101
  }
100
102
  //#endregion
101
103
  //#region src/middlewares/cros/index.ts
102
- var ee = /* @__PURE__ */ S({ policy: () => M }), te = [
104
+ var te = /* @__PURE__ */ S({ policy: () => j }), ne = [
103
105
  "GET",
104
106
  "POST",
105
107
  "PUT",
@@ -107,13 +109,13 @@ var ee = /* @__PURE__ */ S({ policy: () => M }), te = [
107
109
  "PATCH",
108
110
  "HEAD",
109
111
  "OPTIONS"
110
- ], ne = [
112
+ ], re = [
111
113
  "Accept",
112
114
  "Accept-Language",
113
115
  "Content-Language",
114
116
  "Content-Type",
115
117
  "Range"
116
- ], k = [
118
+ ], O = [
117
119
  "Authorization",
118
120
  "X-Auth-Token",
119
121
  "X-Requested-With",
@@ -123,21 +125,21 @@ var ee = /* @__PURE__ */ S({ policy: () => M }), te = [
123
125
  "X-Real-IP",
124
126
  "X-Custom-Header"
125
127
  ];
126
- function A(e, t) {
127
- return !e || !t ? !1 : t === "*" ? !0 : t === "null" ? e === "null" : Array.isArray(t) ? t.some((t) => A(e, t)) : typeof t == "function" ? t(e) : t instanceof RegExp ? t.test(e) : e === t;
128
+ function k(e, t) {
129
+ return !e || !t ? !1 : t === "*" ? !0 : t === "null" ? e === "null" : Array.isArray(t) ? t.some((t) => k(e, t)) : typeof t == "function" ? t(e) : t instanceof RegExp ? t.test(e) : e === t;
128
130
  }
129
- function j(e, t) {
131
+ function A(e, t) {
130
132
  let { origin: n = "*" } = t;
131
- return e ? n === "*" ? t.credentials ? e : "*" : A(e, n) ? e : null : n === "*" ? "*" : null;
133
+ return e ? n === "*" ? t.credentials ? e : "*" : k(e, n) ? e : null : n === "*" ? "*" : null;
132
134
  }
133
- function M(e = {}) {
134
- let { methods: t = te, allowedHeaders: n = k, exposedHeaders: r, credentials: i = !1, maxAge: a = 86400, onResponse: o } = e, s = t.join(","), c = [...ne, ...n].join(","), l = [
135
+ function j(e = {}) {
136
+ let { methods: t = ne, allowedHeaders: n = O, exposedHeaders: r, credentials: i = !1, maxAge: a = 86400, onResponse: o } = e, s = t.join(","), c = [...re, ...n].join(","), l = [
135
137
  ["Vary", "Origin,Access-Control-Request-Method,Access-Control-Request-Headers"],
136
138
  ["Access-Control-Allow-Methods", s],
137
139
  ["Access-Control-Allow-Headers", c]
138
140
  ];
139
141
  return r && l.push(["Access-Control-Expose-Headers", r.join(",")]), i && l.push(["Access-Control-Allow-Credentials", "true"]), a && l.push(["Access-Control-Max-Age", a.toString()]), async (t, n) => {
140
- let r = t.request, i = r.headers.get("Origin"), a = r.method === "OPTIONS" && i !== null && r.headers.has("Access-Control-Request-Method"), s = j(i, e);
142
+ let r = t.request, i = r.headers.get("Origin"), a = r.method === "OPTIONS" && i !== null && r.headers.has("Access-Control-Request-Method"), s = A(i, e);
141
143
  if (a) {
142
144
  if (!s) return new Response(null, { status: 403 });
143
145
  let e = new Response(null, { status: 204 });
@@ -160,7 +162,7 @@ function M(e = {}) {
160
162
  }
161
163
  //#endregion
162
164
  //#region src/middlewares/security/index.ts
163
- var N = /* @__PURE__ */ S({ headers: () => F }), P = {
165
+ var M = /* @__PURE__ */ S({ headers: () => P }), N = {
164
166
  contentSecurityPolicy: "default-src 'self'; base-uri 'self'; frame-ancestors 'none'; object-src 'none'",
165
167
  frameOptions: "DENY",
166
168
  referrerPolicy: "no-referrer",
@@ -169,44 +171,54 @@ var N = /* @__PURE__ */ S({ headers: () => F }), P = {
169
171
  crossOriginResourcePolicy: "same-origin",
170
172
  strictTransportSecurity: !1
171
173
  };
172
- function F(e = {}) {
174
+ function P(e = {}) {
173
175
  let t = {
174
- ...P,
176
+ ...N,
175
177
  ...e
176
178
  };
177
179
  return async (e, n) => {
178
180
  let r = await n();
179
181
  if (!r) return;
180
182
  let i = new Headers(r.headers);
181
- return I(i, "content-security-policy", t.contentSecurityPolicy), I(i, "x-frame-options", t.frameOptions), I(i, "referrer-policy", t.referrerPolicy), I(i, "permissions-policy", t.permissionsPolicy), I(i, "cross-origin-opener-policy", t.crossOriginOpenerPolicy), I(i, "cross-origin-resource-policy", t.crossOriginResourcePolicy), I(i, "strict-transport-security", t.strictTransportSecurity), new Response(r.body, {
183
+ return F(i, "content-security-policy", t.contentSecurityPolicy), F(i, "x-frame-options", t.frameOptions), F(i, "referrer-policy", t.referrerPolicy), F(i, "permissions-policy", t.permissionsPolicy), F(i, "cross-origin-opener-policy", t.crossOriginOpenerPolicy), F(i, "cross-origin-resource-policy", t.crossOriginResourcePolicy), F(i, "strict-transport-security", t.strictTransportSecurity), new Response(r.body, {
182
184
  status: r.status,
183
185
  statusText: r.statusText,
184
186
  headers: i
185
187
  });
186
188
  };
187
189
  }
188
- function I(e, t, n) {
190
+ function F(e, t, n) {
189
191
  !n || e.has(t) || e.set(t, n);
190
192
  }
191
193
  //#endregion
192
194
  //#region src/middlewares/requestid/index.ts
193
- var L = /* @__PURE__ */ S({ assign: () => R });
194
- function R(t = {}) {
195
- let n = t.headerName?.toLowerCase() ?? "x-request-id", r = t.generate ?? e;
195
+ var I = /* @__PURE__ */ S({ assign: () => L });
196
+ function L(t = {}) {
197
+ let n = t.headerName?.toLowerCase() ?? "x-request-id", r = t.generate ?? e, i = t.clientRequestId ?? !1;
196
198
  return async (e, t) => {
197
- let i = e.request.headers.get(n) ?? r();
198
- Object.assign(e.locals, { requestId: i });
199
- let a = await t();
200
- if (!a) return;
201
- if (a.headers.has(n)) return a;
202
- let o = new Headers(a.headers);
203
- return o.set(n, i), new Response(a.body, {
204
- status: a.status,
205
- statusText: a.statusText,
206
- headers: o
199
+ let a = e.request.headers.get(n) ?? r();
200
+ if (i) {
201
+ let t = e.request.headers.get("x-client-request-id");
202
+ if (t !== null) {
203
+ if (!R(t) || t.length > 512) return new Response("Invalid X-Client-Request-Id header", { status: 400 });
204
+ a = t;
205
+ }
206
+ }
207
+ Object.assign(e.locals, { requestId: a });
208
+ let o = await t();
209
+ if (!o) return;
210
+ if (o.headers.has(n)) return o;
211
+ let s = new Headers(o.headers);
212
+ return s.set(n, a), new Response(o.body, {
213
+ status: o.status,
214
+ statusText: o.statusText,
215
+ headers: s
207
216
  });
208
217
  };
209
218
  }
219
+ function R(e) {
220
+ return /^[\x00-\x7F]*$/.test(e);
221
+ }
210
222
  //#endregion
211
223
  //#region src/middlewares/timeout/index.ts
212
224
  var z = /* @__PURE__ */ S({ deadline: () => B });
@@ -600,7 +612,7 @@ var V = [
600
612
  status: e,
601
613
  headers: { "Content-Type": "application/json" }
602
614
  })
603
- }, re = class {
615
+ }, G = class {
604
616
  constructor(e, t) {
605
617
  this.raw = e.headers.get("cookie") ?? "", this.setCookieHeader = t;
606
618
  }
@@ -622,11 +634,11 @@ var V = [
622
634
  maxAge: 0
623
635
  });
624
636
  }
625
- }, G = class extends Error {
637
+ }, K = class extends Error {
626
638
  constructor(e = "Payload Too Large") {
627
639
  super(e), this.status = 413, this.name = "PayloadTooLargeError";
628
640
  }
629
- }, K = class extends U {
641
+ }, q = class extends U {
630
642
  constructor(e) {
631
643
  super(), this.upgradeHandlerInstalled = !1, this.config = e ?? {
632
644
  type: "http",
@@ -736,7 +748,7 @@ var V = [
736
748
  if (!t) return e;
737
749
  let n = 0, r = new a({ transform(e, r, i) {
738
750
  if (n += Buffer.byteLength(e), n > t) {
739
- i(new G());
751
+ i(new K());
740
752
  return;
741
753
  }
742
754
  i(null, e);
@@ -762,7 +774,7 @@ var V = [
762
774
  if (!this.isTrustedProxy(t)) return this.normalizeAddress(t);
763
775
  let n = e.headers["x-forwarded-for"];
764
776
  if (!n) return this.normalizeAddress(t);
765
- let r = this.parseForwardedHeader(n);
777
+ let r = this.parseForwardedHeader(n).filter((e) => this.isValidIP(e));
766
778
  r.push(t);
767
779
  for (let e = r.length - 1; e >= 0; --e) {
768
780
  let t = r[e];
@@ -806,6 +818,19 @@ var V = [
806
818
  normalizeAddress(e) {
807
819
  return e.startsWith("::ffff:") ? e.slice(7) : e;
808
820
  }
821
+ isValidIP(e) {
822
+ if (e.includes(":")) {
823
+ if (e.includes(":::")) return !1;
824
+ let t = e.split(":");
825
+ return t.length <= 8 && t.every((e) => e === "" || /^[0-9a-fA-F]+$/.test(e));
826
+ }
827
+ let t = e.split(".");
828
+ return t.length === 4 && t.every((e) => {
829
+ if (e === "" || e.length > 3) return !1;
830
+ let t = parseInt(e, 10);
831
+ return !isNaN(t) && t >= 0 && t <= 255 && e === String(t);
832
+ });
833
+ }
809
834
  parseForwardedHeader(e) {
810
835
  return (Array.isArray(e) ? e.join(",") : e).split(",").map((e) => this.normalizeAddress(e.trim())).filter(Boolean);
811
836
  }
@@ -830,7 +855,7 @@ var V = [
830
855
  return Number.isFinite(r) && r <= t;
831
856
  }
832
857
  handleError(e) {
833
- if (e instanceof G) return new Response(e.message, { status: e.status });
858
+ if (e instanceof K) return new Response(e.message, { status: e.status });
834
859
  if (C(e)) return new Response(JSON.stringify({
835
860
  error: e.statusText || "Error",
836
861
  status: e.status
@@ -928,7 +953,7 @@ var V = [
928
953
  r && t.set(n, r);
929
954
  }
930
955
  toRequestEvent(e, t, n) {
931
- let r = new re(e, n.pushSetCookie), i = this.config, a = {}, o = {
956
+ let r = new G(e, n.pushSetCookie), i = this.config, a = {}, o = {
932
957
  name: "node-webserver",
933
958
  dev: this.isDevelopment()
934
959
  }, s = /* @__PURE__ */ new Set(), c = {
@@ -956,7 +981,7 @@ var V = [
956
981
  }, l = this.createEventFetch(c, n);
957
982
  return i.locals && Object.assign(a, i.locals(c)), i.platform && Object.assign(o, i.platform(c)), c;
958
983
  }
959
- }, q = {
984
+ }, J = {
960
985
  ".avif": "image/avif",
961
986
  ".css": "text/css; charset=utf-8",
962
987
  ".gif": "image/gif",
@@ -974,24 +999,24 @@ var V = [
974
999
  ".wasm": "application/wasm",
975
1000
  ".webp": "image/webp",
976
1001
  ".xml": "application/xml; charset=utf-8"
977
- }, J = {
1002
+ }, Y = {
978
1003
  index: "index.html",
979
1004
  cacheControl: "public, max-age=0",
980
1005
  dotFiles: "ignore"
981
1006
  };
982
- async function Y(e, t, n = {}) {
983
- let r = $(t), i = {
984
- ...J,
1007
+ async function X(e, t, n = {}) {
1008
+ let r = se(t), i = {
1009
+ ...Y,
985
1010
  ...n
986
- }, a = await X(e), o = ie(r, i.dotFiles);
1011
+ }, a = await ie(e), o = ae(r, i.dotFiles);
987
1012
  if (o instanceof Response) return o;
988
1013
  let s = v(a, o.length > 0 ? o.join(y) : "");
989
1014
  if (!Q(a, s)) return new Response("Forbidden", { status: 403 });
990
- let c = await ae(s, a, i.index);
1015
+ let c = await oe(s, a, i.index);
991
1016
  if (c instanceof Response) return c;
992
1017
  let l = await m(c), u = new Headers({
993
1018
  "content-length": String(l.size),
994
- "content-type": oe(c),
1019
+ "content-type": $(c),
995
1020
  "cache-control": i.cacheControl,
996
1021
  "last-modified": l.mtime.toUTCString(),
997
1022
  "x-content-type-options": "nosniff"
@@ -1007,10 +1032,10 @@ async function Y(e, t, n = {}) {
1007
1032
  headers: u
1008
1033
  });
1009
1034
  }
1010
- async function X(e) {
1035
+ async function ie(e) {
1011
1036
  return p(e);
1012
1037
  }
1013
- function ie(e, t) {
1038
+ function ae(e, t) {
1014
1039
  if (e.includes("\0")) return new Response("Bad Request", { status: 400 });
1015
1040
  let n = e.replace(/\\/g, "/").split("/").filter(Boolean), r = [];
1016
1041
  for (let e of n) {
@@ -1031,7 +1056,7 @@ function ie(e, t) {
1031
1056
  }
1032
1057
  return r;
1033
1058
  }
1034
- async function ae(e, t, n) {
1059
+ async function oe(e, t, n) {
1035
1060
  try {
1036
1061
  return (await f(e)).isDirectory() ? Z(v(e, n), t) : Z(e, t);
1037
1062
  } catch {
@@ -1050,13 +1075,13 @@ function Q(e, t) {
1050
1075
  let n = _(e, t);
1051
1076
  return n === "" || !n.startsWith("..") && !g(n);
1052
1077
  }
1053
- function oe(e) {
1054
- return q[h(e).toLowerCase()] ?? "application/octet-stream";
1055
- }
1056
1078
  function $(e) {
1079
+ return J[h(e).toLowerCase()] ?? "application/octet-stream";
1080
+ }
1081
+ function se(e) {
1057
1082
  return typeof e.params.path == "string" ? e.params.path : e.url.pathname.replace(/^\/+/, "");
1058
1083
  }
1059
- var se = (e, t = {}) => (n) => Y(e, n, t), ce = (e, ...t) => async (n) => {
1084
+ var ce = (e, t = {}) => (n) => X(e, n, t), le = (e, ...t) => async (n) => {
1060
1085
  let r = {};
1061
1086
  for (let e of t) {
1062
1087
  let t = await e(n);
@@ -1067,16 +1092,19 @@ var se = (e, t = {}) => (n) => Y(e, n, t), ce = (e, ...t) => async (n) => {
1067
1092
  };
1068
1093
  //#endregion
1069
1094
  //#region src/helpers/sse.ts
1070
- function le(e, t = {}) {
1095
+ function ue(e, t = {}) {
1071
1096
  let n = [];
1072
- if (t.comment) for (let e of t.comment.split(/\r?\n/)) n.push(`: ${e}`);
1097
+ if (t.comment) {
1098
+ let e = t.comment.replace(/\r\n/g, " ").replace(/\r/g, " ").replace(/\n/g, " ");
1099
+ n.push(`: ${e}`);
1100
+ }
1073
1101
  if (t.event && n.push(`event: ${t.event}`), t.id && n.push(`id: ${t.id}`), t.retry !== void 0 && n.push(`retry: ${t.retry}`), e !== void 0) {
1074
1102
  let t = typeof e == "string" ? e : JSON.stringify(e);
1075
1103
  for (let e of t.split(/\r?\n/)) n.push(`data: ${e}`);
1076
1104
  }
1077
1105
  return `${n.join("\n")}\n\n`;
1078
1106
  }
1079
- var ue = (e, t = {}) => (n) => {
1107
+ var de = (e, t = {}) => (n) => {
1080
1108
  let r = new TextEncoder(), i = null, a = !1, o, s = async () => {
1081
1109
  if (!a) {
1082
1110
  a = !0;
@@ -1092,7 +1120,7 @@ var ue = (e, t = {}) => (n) => {
1092
1120
  async start(t) {
1093
1121
  i = t;
1094
1122
  let c = (e, n = {}) => {
1095
- a || t.enqueue(r.encode(le(e, n)));
1123
+ a || t.enqueue(r.encode(ue(e, n)));
1096
1124
  };
1097
1125
  n.request.signal.addEventListener("abort", () => {
1098
1126
  s();
@@ -1120,7 +1148,7 @@ var ue = (e, t = {}) => (n) => {
1120
1148
  ...t.headers
1121
1149
  }
1122
1150
  });
1123
- }, de = async (e, t) => {
1151
+ }, fe = async (e, t) => {
1124
1152
  let n = JSON.stringify(await e);
1125
1153
  return new Response(n, {
1126
1154
  ...t,
@@ -1131,19 +1159,19 @@ var ue = (e, t = {}) => (n) => {
1131
1159
  }
1132
1160
  });
1133
1161
  };
1134
- function fe(e, t) {
1162
+ function pe(e, t) {
1135
1163
  throw new Response(null, {
1136
1164
  status: e,
1137
1165
  headers: { location: t.toString() }
1138
1166
  });
1139
1167
  }
1140
- function pe(e, t) {
1168
+ function me(e, t) {
1141
1169
  throw new Response(JSON.stringify(typeof t == "string" ? { message: t } : t), {
1142
1170
  status: e,
1143
1171
  headers: { "content-type": "application/json" }
1144
1172
  });
1145
1173
  }
1146
- var me = async (e, t) => {
1174
+ var he = async (e, t) => {
1147
1175
  let n = await e;
1148
1176
  return new Response(n, {
1149
1177
  ...t,
@@ -1153,7 +1181,7 @@ var me = async (e, t) => {
1153
1181
  ...t?.headers
1154
1182
  }
1155
1183
  });
1156
- }, he = async (e, t) => {
1184
+ }, ge = async (e, t) => {
1157
1185
  let n = await e;
1158
1186
  return new Response(n, {
1159
1187
  ...t,
@@ -1165,6 +1193,6 @@ var me = async (e, t) => {
1165
1193
  });
1166
1194
  };
1167
1195
  //#endregion
1168
- export { W as Action, ee as CORS, D as RateLimiter, L as RequestId, V as RequestMethods, U as Router, N as Security, z as Timeout, K as WebServer, se as dir, ce as enhance, pe as error, he as html, C as isHttpError, w as isRedirect, T as isResponse, de as json, fe as redirect, Y as serveStatic, ue as sse, me as text };
1196
+ export { W as Action, te as CORS, E as RateLimiter, I as RequestId, V as RequestMethods, U as Router, M as Security, z as Timeout, q as WebServer, ce as dir, le as enhance, me as error, ge as html, C as isHttpError, w as isRedirect, T as isResponse, fe as json, pe as redirect, X as serveStatic, de as sse, he as text };
1169
1197
 
1170
1198
  //# sourceMappingURL=index.es.js.map