@adonix.org/cloud-spark 0.0.143 → 0.0.144

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.d.ts CHANGED
@@ -27,26 +27,26 @@ declare const CacheControl: {
27
27
  * Standard HTTP header names and common values.
28
28
  */
29
29
  declare namespace HttpHeader {
30
- const VARY = "Vary";
31
30
  const ALLOW = "Allow";
32
31
  const ORIGIN = "Origin";
33
- const USER_AGENT = "User-Agent";
34
32
  const CONTENT_TYPE = "Content-Type";
35
33
  const CACHE_CONTROL = "Cache-Control";
36
- const X_FRAME_OPTIONS = "X-Frame-Options";
37
- const X_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options";
38
- const REFERRER_POLICY = "Referrer-Policy";
39
- const PERMISSIONS_POLICY = "Permissions-Policy";
34
+ const USER_AGENT = "User-Agent";
35
+ const VARY = "Vary";
40
36
  const CONTENT_SECURITY_POLICY = "Content-Security-Policy";
37
+ const PERMISSIONS_POLICY = "Permissions-Policy";
41
38
  const STRICT_TRANSPORT_SECURITY = "Strict-Transport-Security";
42
- const MAX_AGE = "Access-Control-Max-Age";
43
- const ALLOW_ORIGIN = "Access-Control-Allow-Origin";
44
- const ALLOW_HEADERS = "Access-Control-Allow-Headers";
45
- const ALLOW_METHODS = "Access-Control-Allow-Methods";
46
- const EXPOSE_HEADERS = "Access-Control-Expose-Headers";
47
- const ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
39
+ const REFERRER_POLICY = "Referrer-Policy";
40
+ const X_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options";
41
+ const X_FRAME_OPTIONS = "X-Frame-Options";
42
+ const ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
43
+ const ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers";
44
+ const ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods";
45
+ const ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
46
+ const ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers";
47
+ const ACCESS_CONTROL_MAX_AGE = "Access-Control-Max-Age";
48
+ const ACCESS_CONTROL_REQUEST_HEADERS = "Access-Control-Request-Headers";
48
49
  const ALLOW_ALL_ORIGINS = "*";
49
- const CROSS_SITE = "cross-site";
50
50
  }
51
51
  /**
52
52
  * Standard HTTP request methods.
@@ -169,6 +169,14 @@ interface CorsConfig {
169
169
  * Use this option to explicitly allow certain response headers to be read.
170
170
  */
171
171
  exposedHeaders: string[];
172
+ /**
173
+ * Whether the resource supports user credentials (cookies, HTTP authentication).
174
+ *
175
+ * Defaults to false.
176
+ *
177
+ * If true, the Access-Control-Allow-Origin response header must not be "*".
178
+ */
179
+ allowCredentials: boolean;
172
180
  /**
173
181
  * Maximum age (in seconds) that the results of a preflight request
174
182
  * can be cached by the client.
@@ -406,7 +414,7 @@ declare function lexCompare(a: string, b: string): number;
406
414
  * Sets a header on the given Headers object.
407
415
  *
408
416
  * - If `value` is an array, any duplicates and empty strings are removed.
409
- * - If the resulting value array is empty, the header is deleted.
417
+ * - If the resulting value is empty, the header is deleted.
410
418
  * - Otherwise, values are joined with `", "` and set as the header value.
411
419
  *
412
420
  * @param headers - The Headers object to modify.
package/dist/index.js CHANGED
@@ -16,36 +16,36 @@ var CacheControl = {
16
16
  import { StatusCodes } from "http-status-codes";
17
17
  var HttpHeader;
18
18
  ((HttpHeader2) => {
19
- HttpHeader2.VARY = "Vary";
20
19
  HttpHeader2.ALLOW = "Allow";
21
20
  HttpHeader2.ORIGIN = "Origin";
22
- HttpHeader2.USER_AGENT = "User-Agent";
23
21
  HttpHeader2.CONTENT_TYPE = "Content-Type";
24
22
  HttpHeader2.CACHE_CONTROL = "Cache-Control";
25
- HttpHeader2.X_FRAME_OPTIONS = "X-Frame-Options";
26
- HttpHeader2.X_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options";
27
- HttpHeader2.REFERRER_POLICY = "Referrer-Policy";
28
- HttpHeader2.PERMISSIONS_POLICY = "Permissions-Policy";
23
+ HttpHeader2.USER_AGENT = "User-Agent";
24
+ HttpHeader2.VARY = "Vary";
29
25
  HttpHeader2.CONTENT_SECURITY_POLICY = "Content-Security-Policy";
26
+ HttpHeader2.PERMISSIONS_POLICY = "Permissions-Policy";
30
27
  HttpHeader2.STRICT_TRANSPORT_SECURITY = "Strict-Transport-Security";
31
- HttpHeader2.MAX_AGE = "Access-Control-Max-Age";
32
- HttpHeader2.ALLOW_ORIGIN = "Access-Control-Allow-Origin";
33
- HttpHeader2.ALLOW_HEADERS = "Access-Control-Allow-Headers";
34
- HttpHeader2.ALLOW_METHODS = "Access-Control-Allow-Methods";
35
- HttpHeader2.EXPOSE_HEADERS = "Access-Control-Expose-Headers";
36
- HttpHeader2.ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
28
+ HttpHeader2.REFERRER_POLICY = "Referrer-Policy";
29
+ HttpHeader2.X_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options";
30
+ HttpHeader2.X_FRAME_OPTIONS = "X-Frame-Options";
31
+ HttpHeader2.ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
32
+ HttpHeader2.ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers";
33
+ HttpHeader2.ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods";
34
+ HttpHeader2.ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
35
+ HttpHeader2.ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers";
36
+ HttpHeader2.ACCESS_CONTROL_MAX_AGE = "Access-Control-Max-Age";
37
+ HttpHeader2.ACCESS_CONTROL_REQUEST_HEADERS = "Access-Control-Request-Headers";
37
38
  HttpHeader2.ALLOW_ALL_ORIGINS = "*";
38
- HttpHeader2.CROSS_SITE = "cross-site";
39
39
  })(HttpHeader || (HttpHeader = {}));
40
- var Method = /* @__PURE__ */ ((Method3) => {
41
- Method3["GET"] = "GET";
42
- Method3["PUT"] = "PUT";
43
- Method3["HEAD"] = "HEAD";
44
- Method3["POST"] = "POST";
45
- Method3["PATCH"] = "PATCH";
46
- Method3["DELETE"] = "DELETE";
47
- Method3["OPTIONS"] = "OPTIONS";
48
- return Method3;
40
+ var Method = /* @__PURE__ */ ((Method4) => {
41
+ Method4["GET"] = "GET";
42
+ Method4["PUT"] = "PUT";
43
+ Method4["HEAD"] = "HEAD";
44
+ Method4["POST"] = "POST";
45
+ Method4["PATCH"] = "PATCH";
46
+ Method4["DELETE"] = "DELETE";
47
+ Method4["OPTIONS"] = "OPTIONS";
48
+ return Method4;
49
49
  })(Method || {});
50
50
  var { GET, PUT, HEAD, POST, PATCH, DELETE, OPTIONS } = Method;
51
51
 
@@ -187,6 +187,9 @@ var CacheHandler = class extends Middleware {
187
187
  }
188
188
  };
189
189
 
190
+ // src/responses.ts
191
+ import { getReasonPhrase, StatusCodes as StatusCodes2 } from "http-status-codes";
192
+
190
193
  // src/utils/header.ts
191
194
  function setHeader(headers, key, value) {
192
195
  const raw = Array.isArray(value) ? value : [value];
@@ -245,51 +248,7 @@ function getOrigin(request) {
245
248
  }
246
249
  }
247
250
 
248
- // src/middleware/cors/utils.ts
249
- function addCorsHeaders(worker, cors2, headers) {
250
- deleteCorsHeaders(headers);
251
- const origin = getOrigin(worker.request);
252
- if (!origin) return;
253
- if (allowAnyOrigin(cors2)) {
254
- setHeader(headers, HttpHeader.ALLOW_ORIGIN, HttpHeader.ALLOW_ALL_ORIGINS);
255
- } else if (cors2.allowedOrigins.length > 0) {
256
- mergeHeader(headers, HttpHeader.VARY, HttpHeader.ORIGIN);
257
- if (cors2.allowedOrigins.includes(origin)) {
258
- setHeader(headers, HttpHeader.ALLOW_ORIGIN, origin);
259
- setHeader(headers, HttpHeader.ALLOW_CREDENTIALS, "true");
260
- }
261
- }
262
- setHeader(headers, HttpHeader.MAX_AGE, String(cors2.maxAge));
263
- setHeader(headers, HttpHeader.ALLOW_HEADERS, cors2.allowedHeaders);
264
- mergeHeader(headers, HttpHeader.ALLOW_METHODS, worker.getAllowedMethods());
265
- mergeHeader(headers, HttpHeader.EXPOSE_HEADERS, cors2.exposedHeaders);
266
- }
267
- function allowAnyOrigin(cors2) {
268
- return cors2.allowedOrigins.includes("*");
269
- }
270
- function deleteCorsHeaders(headers) {
271
- headers.delete(HttpHeader.MAX_AGE);
272
- headers.delete(HttpHeader.ALLOW_ORIGIN);
273
- headers.delete(HttpHeader.ALLOW_HEADERS);
274
- headers.delete(HttpHeader.ALLOW_METHODS);
275
- headers.delete(HttpHeader.EXPOSE_HEADERS);
276
- headers.delete(HttpHeader.ALLOW_CREDENTIALS);
277
- }
278
-
279
- // src/middleware/cors/constants.ts
280
- var defaultCorsConfig = {
281
- allowedOrigins: ["*"],
282
- // Origins allowed for CORS requests
283
- allowedHeaders: [HttpHeader.CONTENT_TYPE],
284
- // HTTP headers allowed in requests
285
- exposedHeaders: [],
286
- // Headers exposed to the client
287
- maxAge: Time.Week
288
- // Max age in seconds for preflight caching
289
- };
290
-
291
251
  // src/responses.ts
292
- import { getReasonPhrase, StatusCodes as StatusCodes2 } from "http-status-codes";
293
252
  var BaseResponse = class {
294
253
  /** HTTP headers for the response. */
295
254
  headers = new Headers();
@@ -394,6 +353,115 @@ var Options = class extends SuccessResponse {
394
353
  }
395
354
  };
396
355
 
356
+ // src/middleware/cors/utils.ts
357
+ var SIMPLE_METHODS = /* @__PURE__ */ new Set([GET, HEAD, OPTIONS]);
358
+ async function options(worker, cors2) {
359
+ const options2 = new Options();
360
+ const origin = getOrigin(worker.request);
361
+ if (origin) {
362
+ setAllowOrigin(options2.headers, cors2, origin);
363
+ setAllowCredentials(options2.headers, cors2, origin);
364
+ }
365
+ setAllowMethods(options2.headers, worker);
366
+ setMaxAge(options2.headers, cors2);
367
+ setAllowHeaders(options2.headers, worker, cors2);
368
+ return options2.getResponse();
369
+ }
370
+ async function apply(response, worker, cors2) {
371
+ const clone = new ClonedResponse(response);
372
+ const origin = getOrigin(worker.request);
373
+ deleteCorsHeaders(clone.headers);
374
+ if (origin) {
375
+ setAllowOrigin(clone.headers, cors2, origin);
376
+ setAllowCredentials(clone.headers, cors2, origin);
377
+ }
378
+ setExposedHeaders(clone.headers, cors2);
379
+ return clone.getResponse();
380
+ }
381
+ function setAllowOrigin(headers, cors2, origin) {
382
+ if (allowAnyOrigin(cors2)) {
383
+ setHeader(headers, HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN, HttpHeader.ALLOW_ALL_ORIGINS);
384
+ } else {
385
+ if (cors2.allowedOrigins.includes(origin)) {
386
+ setHeader(headers, HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN, origin);
387
+ }
388
+ mergeHeader(headers, HttpHeader.VARY, HttpHeader.ORIGIN);
389
+ }
390
+ }
391
+ function setAllowCredentials(headers, cors2, origin) {
392
+ if (!origin) return;
393
+ if (!allowAnyOrigin(cors2) && cors2.allowCredentials) {
394
+ setHeader(headers, HttpHeader.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
395
+ }
396
+ }
397
+ function setAllowMethods(headers, worker) {
398
+ const methods = worker.getAllowedMethods().filter((method) => !SIMPLE_METHODS.has(method));
399
+ if (methods.length > 0) {
400
+ setHeader(headers, HttpHeader.ACCESS_CONTROL_ALLOW_METHODS, methods);
401
+ }
402
+ }
403
+ function setMaxAge(headers, cors2) {
404
+ setHeader(headers, HttpHeader.ACCESS_CONTROL_MAX_AGE, String(cors2.maxAge));
405
+ }
406
+ function setAllowHeaders(headers, worker, cors2) {
407
+ if (cors2.allowedHeaders.length > 0) {
408
+ setHeader(headers, HttpHeader.ACCESS_CONTROL_ALLOW_HEADERS, cors2.allowedHeaders);
409
+ return;
410
+ }
411
+ const requestHeaders = worker.request.headers.get(HttpHeader.ACCESS_CONTROL_REQUEST_HEADERS);
412
+ if (requestHeaders) {
413
+ setHeader(headers, HttpHeader.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders);
414
+ mergeHeader(headers, HttpHeader.VARY, HttpHeader.ACCESS_CONTROL_ALLOW_HEADERS);
415
+ }
416
+ }
417
+ function setExposedHeaders(headers, cors2) {
418
+ setHeader(headers, HttpHeader.ACCESS_CONTROL_EXPOSE_HEADERS, cors2.exposedHeaders);
419
+ }
420
+ function allowAnyOrigin(cors2) {
421
+ return cors2.allowedOrigins.includes("*");
422
+ }
423
+ function deleteCorsHeaders(headers) {
424
+ headers.delete(HttpHeader.ACCESS_CONTROL_MAX_AGE);
425
+ headers.delete(HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN);
426
+ headers.delete(HttpHeader.ACCESS_CONTROL_ALLOW_HEADERS);
427
+ headers.delete(HttpHeader.ACCESS_CONTROL_ALLOW_METHODS);
428
+ headers.delete(HttpHeader.ACCESS_CONTROL_EXPOSE_HEADERS);
429
+ headers.delete(HttpHeader.ACCESS_CONTROL_ALLOW_CREDENTIALS);
430
+ }
431
+
432
+ // src/middleware/cors/constants.ts
433
+ var defaultCorsConfig = {
434
+ /**
435
+ * By default, allow all origins.
436
+ * Note: This must be overridden if you also enable `allowCredentials`.
437
+ */
438
+ allowedOrigins: ["*"],
439
+ /**
440
+ * Default to allowing only "Content-Type".
441
+ * This permits requests with JSON or form bodies, while blocking
442
+ * arbitrary custom headers unless explicitly added.
443
+ */
444
+ allowedHeaders: [HttpHeader.CONTENT_TYPE],
445
+ /**
446
+ * No response headers are exposed by default.
447
+ * Client-side code will only be able to read CORS-safelisted headers
448
+ * (e.g. Cache-Control, Content-Type, Expires, Last-Modified, Pragma).
449
+ */
450
+ exposedHeaders: [],
451
+ /**
452
+ * Credentials (cookies, HTTP auth) are disallowed by default.
453
+ * This avoids the spec restriction that forbids using "*" for origins
454
+ * when credentials are enabled.
455
+ */
456
+ allowCredentials: false,
457
+ /**
458
+ * Default preflight cache duration: 1 week.
459
+ * Browsers may cache OPTIONS responses for up to this many seconds.
460
+ * Adjust lower if your CORS rules may change frequently.
461
+ */
462
+ maxAge: Time.Week
463
+ };
464
+
397
465
  // src/middleware/cors/handler.ts
398
466
  function cors(init) {
399
467
  return new CorsHandler(init);
@@ -412,22 +480,21 @@ var CorsHandler = class extends Middleware {
412
480
  this.config = { ...defaultCorsConfig, ...init };
413
481
  }
414
482
  /**
415
- * Handle a request by applying CORS headers to the response.
483
+ * Applies CORS headers to a request.
416
484
  *
417
- * @param worker - The Worker instance containing the request context.
418
- * @param next - Function to invoke the next middleware in the chain.
419
- * @returns A Response object with CORS headers applied.
485
+ * - Returns a preflight response for `OPTIONS` requests.
486
+ * - For other methods, calls `next()` and applies CORS headers to the result.
487
+ *
488
+ * @param worker - The Worker handling the request.
489
+ * @param next - Function to invoke the next middleware.
490
+ * @returns Response with CORS headers applied.
420
491
  */
421
492
  async handle(worker, next) {
422
493
  if (worker.request.method === OPTIONS) {
423
- const options = new Options();
424
- addCorsHeaders(worker, this.config, options.headers);
425
- return options.getResponse();
494
+ return options(worker, this.config);
426
495
  }
427
496
  const response = await next();
428
- const clone = new ClonedResponse(response);
429
- addCorsHeaders(worker, this.config, clone.headers);
430
- return clone.getResponse();
497
+ return apply(response, worker, this.config);
431
498
  }
432
499
  };
433
500
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants/cache.ts","../src/constants/http.ts","../src/constants/media-types.ts","../src/constants/time.ts","../src/middleware/middleware.ts","../src/utils/compare.ts","../src/utils/url.ts","../src/middleware/cache/handler.ts","../src/utils/header.ts","../src/utils/request.ts","../src/middleware/cors/utils.ts","../src/middleware/cors/constants.ts","../src/responses.ts","../src/middleware/cors/handler.ts","../src/errors.ts","../src/workers/base-worker.ts","../src/workers/middleware-worker.ts","../src/workers/basic-worker.ts","../src/routes.ts","../src/workers/route-worker.ts"],"sourcesContent":["/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport CacheLib from \"cache-control-parser\";\n\n/**\n * @see {@link https://github.com/etienne-martin/cache-control-parser | cache-control-parser}\n */\nexport type CacheControl = CacheLib.CacheControl;\nexport const CacheControl = {\n parse: CacheLib.parse,\n stringify: CacheLib.stringify,\n\n /** A CacheControl directive that disables all caching. */\n DISABLE: Object.freeze({\n \"no-cache\": true,\n \"no-store\": true,\n \"must-revalidate\": true,\n \"max-age\": 0,\n }) satisfies CacheControl,\n};\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * https://github.com/prettymuchbryce/http-status-codes\n */\nexport { StatusCodes } from \"http-status-codes\";\n\n/**\n * Standard HTTP header names and common values.\n */\nexport namespace HttpHeader {\n export const VARY = \"Vary\";\n export const ALLOW = \"Allow\";\n export const ORIGIN = \"Origin\";\n export const USER_AGENT = \"User-Agent\";\n export const CONTENT_TYPE = \"Content-Type\";\n export const CACHE_CONTROL = \"Cache-Control\";\n\n // Security Headers\n export const X_FRAME_OPTIONS = \"X-Frame-Options\"; // e.g. \"DENY\" or \"SAMEORIGIN\"\n export const X_CONTENT_TYPE_OPTIONS = \"X-Content-Type-Options\"; // usually \"nosniff\"\n export const REFERRER_POLICY = \"Referrer-Policy\"; // e.g. \"no-referrer\", \"strict-origin-when-cross-origin\"\n export const PERMISSIONS_POLICY = \"Permissions-Policy\"; // formerly Feature-Policy, controls APIs like geolocation/camera\n export const CONTENT_SECURITY_POLICY = \"Content-Security-Policy\"; // fine-grained script/style/image restrictions\n export const STRICT_TRANSPORT_SECURITY = \"Strict-Transport-Security\"; // e.g. \"max-age=63072000; includeSubDomains; preload\"\n\n // Cors Headers\n export const MAX_AGE = \"Access-Control-Max-Age\";\n export const ALLOW_ORIGIN = \"Access-Control-Allow-Origin\";\n export const ALLOW_HEADERS = \"Access-Control-Allow-Headers\";\n export const ALLOW_METHODS = \"Access-Control-Allow-Methods\";\n export const EXPOSE_HEADERS = \"Access-Control-Expose-Headers\";\n export const ALLOW_CREDENTIALS = \"Access-Control-Allow-Credentials\";\n\n // Values\n export const ALLOW_ALL_ORIGINS = \"*\";\n export const CROSS_SITE = \"cross-site\";\n}\n\n/**\n * Standard HTTP request methods.\n */\nexport enum Method {\n GET = \"GET\",\n PUT = \"PUT\",\n HEAD = \"HEAD\",\n POST = \"POST\",\n PATCH = \"PATCH\",\n DELETE = \"DELETE\",\n OPTIONS = \"OPTIONS\",\n}\n\n/**\n * Shorthand constants for each HTTP method.\n *\n * These are equivalent to the corresponding enum members in `Method`.\n * For example, `GET === Method.GET`.\n */\nexport const { GET, PUT, HEAD, POST, PATCH, DELETE, OPTIONS } = Method;\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Common media types used for HTTP headers.\n */\nexport enum MediaType {\n PLAIN_TEXT = \"text/plain\",\n HTML = \"text/html\",\n CSS = \"text/css\",\n CSV = \"text/csv\",\n XML = \"text/xml\",\n MARKDOWN = \"text/markdown\",\n RICH_TEXT = \"text/richtext\",\n JSON = \"application/json\",\n XML_APP = \"application/xml\",\n YAML = \"application/x-yaml\",\n FORM_URLENCODED = \"application/x-www-form-urlencoded\",\n NDJSON = \"application/x-ndjson\",\n MSGPACK = \"application/x-msgpack\",\n PROTOBUF = \"application/x-protobuf\",\n MULTIPART_FORM_DATA = \"multipart/form-data\",\n MULTIPART_MIXED = \"multipart/mixed\",\n MULTIPART_ALTERNATIVE = \"multipart/alternative\",\n MULTIPART_DIGEST = \"multipart/digest\",\n MULTIPART_RELATED = \"multipart/related\",\n MULTIPART_SIGNED = \"multipart/signed\",\n MULTIPART_ENCRYPTED = \"multipart/encrypted\",\n OCTET_STREAM = \"application/octet-stream\",\n PDF = \"application/pdf\",\n ZIP = \"application/zip\",\n GZIP = \"application/gzip\",\n MSWORD = \"application/msword\",\n DOCX = \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n EXCEL = \"application/vnd.ms-excel\",\n XLSX = \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n POWERPOINT = \"application/vnd.ms-powerpoint\",\n PPTX = \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n ICO = \"image/x-icon\",\n ICO_MS = \"image/vnd.microsoft.icon\",\n GIF = \"image/gif\",\n PNG = \"image/png\",\n JPEG = \"image/jpeg\",\n WEBP = \"image/webp\",\n SVG = \"image/svg+xml\",\n HEIF = \"image/heif\",\n AVIF = \"image/avif\",\n EVENT_STREAM = \"text/event-stream\",\n TAR = \"application/x-tar\",\n BZIP2 = \"application/x-bzip2\",\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Time constants in seconds. Month is approximated as 30 days.\n */\nexport const Time = {\n Second: 1,\n Minute: 60,\n Hour: 3600, // 60 * 60\n Day: 86400, // 60 * 60 * 24\n Week: 604800, // 60 * 60 * 24 * 7\n Month: 2592000, // 60 * 60 * 24 * 30\n Year: 31536000, // 60 * 60 * 24 * 365\n} as const;\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Worker } from \"../interfaces/worker\";\n\n/**\n * Abstract base class for middleware.\n *\n * Middleware classes implement request/response processing logic in a\n * chainable manner. Each middleware receives a `Worker` object and a\n * `next` function that invokes the next middleware in the chain.\n *\n * Subclasses **must implement** the `handle` method.\n *\n * Example subclass:\n * ```ts\n * class LoggingMiddleware extends Middleware {\n * public async handle(worker: Worker, next: () => Promise<Response>): Promise<Response> {\n * console.log(`Processing request: ${worker.request.url}`);\n * const response = await next();\n * console.log(`Response status: ${response.status}`);\n * return response;\n * }\n * }\n * ```\n */\nexport abstract class Middleware {\n /**\n * Process a request in the middleware chain.\n *\n * @param worker - The `Worker` instance representing the request context.\n * @param next - Function to invoke the next middleware in the chain.\n * Must be called to continue the chain unless the middleware\n * terminates early (e.g., returns a response directly).\n * @returns A `Response` object, either returned directly or from `next()`.\n */\n public abstract handle(worker: Worker, next: () => Promise<Response>): Promise<Response>;\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Lexicographically compares two strings.\n *\n * This comparator can be used in `Array.prototype.sort()` to produce a\n * consistent, stable ordering of string arrays.\n *\n * @param a - The first string to compare.\n * @param b - The second string to compare.\n * @returns A number indicating the relative order of `a` and `b`.\n */\nexport function lexCompare(a: string, b: string): number {\n if (a < b) return -1;\n if (a > b) return 1;\n return 0;\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { lexCompare } from \"./compare\";\n\n/**\n * Normalizes a URL string for use as a consistent cache key.\n *\n * - Sorts query parameters alphabetically so `?b=2&a=1` and `?a=1&b=2` are treated the same.\n * - Strips fragment identifiers (`#...`) since they are not sent in HTTP requests.\n * - Leaves protocol, host, path, and query values intact.\n *\n * @param url The original URL string to normalize.\n * @returns A normalized URL string suitable for hashing or direct cache key use.\n */\nexport function normalizeUrl(url: string): URL {\n const u = new URL(url);\n\n const params = [...u.searchParams.entries()];\n params.sort(([a], [b]) => lexCompare(a, b));\n\n u.search = params\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)\n .join(\"&\");\n u.hash = \"\";\n\n return u;\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Middleware } from \"../middleware\";\nimport { Worker } from \"../../interfaces/worker\";\nimport { GET } from \"../../constants/http\";\nimport { normalizeUrl } from \"../../utils/url\";\n\n/**\n * Middleware for caching GET requests.\n *\n * This middleware checks a cache (either a named cache or the default)\n * before passing the request down the middleware chain. Responses for\n * successful GET requests are automatically stored in the cache.\n *\n * Non-GET requests are never cached. The cache key can be customized\n * via the `getKey` function; otherwise, the URL is normalized and used.\n *\n * @param cacheName - Optional name of the cache to use. Defaults to `caches.default`.\n * @param getKey - Optional function to generate a cache key from a request.\n * @returns A {@link Middleware} instance that can be added to your middleware chain.\n */\nexport function cache(\n cacheName?: string,\n getKey?: (request: Request) => URL | RequestInfo,\n): Middleware {\n return new CacheHandler(cacheName, getKey);\n}\n\nclass CacheHandler extends Middleware {\n /**\n * @param cacheName - Optional name of the cache to use. If omitted,\n * `caches.default` is used.\n * @param getKey - Optional function to generate a cache key from a request.\n * Defaults to using the normalized request URL.\n */\n constructor(\n protected readonly cacheName?: string,\n protected readonly getKey?: (request: Request) => URL | RequestInfo,\n ) {\n super();\n }\n\n /**\n * Handle a request in the caching middleware.\n *\n * Checks the cache for GET requests and returns the cached response if available.\n * Otherwise, calls `next()` to continue the middleware chain and caches\n * the response if successful.\n *\n * @param worker - The Worker instance containing the request context.\n * @param next - Function to invoke the next middleware in the chain.\n * @returns A Response object, either from cache or the next middleware.\n */\n public override async handle(worker: Worker, next: () => Promise<Response>): Promise<Response> {\n const cache = this.cacheName ? await caches.open(this.cacheName) : caches.default;\n\n if (worker.request.method === GET) {\n const cached = await cache.match(this.getCacheKey(worker.request));\n if (cached) return cached;\n }\n\n const response = await next();\n\n if (worker.request.method === GET && response.ok) {\n worker.ctx.waitUntil(cache.put(this.getCacheKey(worker.request), response.clone()));\n }\n return response;\n }\n\n /**\n * Generate the cache key for a request.\n *\n * @param request - The Request object to generate a cache key for.\n * @returns A URL or RequestInfo used as the cache key.\n *\n * If a custom `getKey` function was provided in the constructor, it is used.\n * Otherwise, the request URL is normalized.\n */\n private getCacheKey(request: Request): URL | RequestInfo {\n return this.getKey ? this.getKey(request) : normalizeUrl(request.url);\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { lexCompare } from \"./compare\";\n\n/**\n * Sets a header on the given Headers object.\n *\n * - If `value` is an array, any duplicates and empty strings are removed.\n * - If the resulting value array is empty, the header is deleted.\n * - Otherwise, values are joined with `\", \"` and set as the header value.\n *\n * @param headers - The Headers object to modify.\n * @param key - The header name to set.\n * @param value - The header value(s) to set. Can be a string or array of strings.\n */\nexport function setHeader(headers: Headers, key: string, value: string | string[]): void {\n const raw = Array.isArray(value) ? value : [value];\n const values = Array.from(new Set(raw.map((v) => v.trim())))\n .filter((v) => v.length)\n .sort(lexCompare);\n\n if (!values.length) {\n headers.delete(key);\n return;\n }\n\n headers.set(key, values.join(\", \"));\n}\n\n/**\n * Merges new value(s) into an existing header on the given Headers object.\n *\n * - Preserves any existing values and adds new ones.\n * - Removes duplicates and trims all values.\n * - If the header does not exist, it is created.\n * - If the resulting value array is empty, the header is deleted.\n *\n * @param headers - The Headers object to modify.\n * @param key - The header name to merge into.\n * @param value - The new header value(s) to add. Can be a string or array of strings.\n */\nexport function mergeHeader(headers: Headers, key: string, value: string | string[]): void {\n const values = Array.isArray(value) ? value : [value];\n if (!values.length) return;\n\n const existing = headers.get(key);\n if (existing) {\n const merged = existing.split(\",\").map((v) => v.trim());\n values.forEach((v) => merged.push(v.trim()));\n setHeader(headers, key, merged);\n } else {\n setHeader(headers, key, values);\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { HttpHeader, Method } from \"../constants/http\";\nimport { MediaType } from \"../constants/media-types\";\n\n/**\n * A set containing all supported HTTP methods.\n *\n * Useful for runtime checks like validating request methods.\n */\nconst METHOD_SET: Set<string> = new Set(Object.values(Method));\n\n/**\n * Type guard that checks if a string is a valid HTTP method.\n *\n * @param value - The string to test.\n * @returns True if `value` is a recognized HTTP method.\n */\nexport function isMethod(value: string): value is Method {\n return METHOD_SET.has(value);\n}\n\n/**\n * A set of media types that require a `charset` parameter when setting\n * the `Content-Type` header.\n *\n * This includes common text-based media types such as HTML, CSS, JSON,\n * XML, CSV, Markdown, and others.\n */\nconst ADD_CHARSET: Set<MediaType> = new Set([\n MediaType.CSS,\n MediaType.CSV,\n MediaType.XML,\n MediaType.SVG,\n MediaType.HTML,\n MediaType.JSON,\n MediaType.NDJSON,\n MediaType.XML_APP,\n MediaType.MARKDOWN,\n MediaType.RICH_TEXT,\n MediaType.PLAIN_TEXT,\n MediaType.FORM_URLENCODED,\n]);\n\n/**\n * Returns the proper Content-Type string for a given media type.\n * Appends `charset=utf-8` for text-based types that require it.\n *\n * @param type - The media type.\n * @returns A string suitable for the `Content-Type` header.\n */\nexport function getContentType(type: MediaType): string {\n if (ADD_CHARSET.has(type)) {\n return `${type}; charset=utf-8`;\n }\n return type;\n}\n\n/**\n * Extracts and normalizes the `Origin` header from a request.\n *\n * Returns the origin (scheme + host + port) as a string if present and valid.\n * Returns `null` if:\n * - The `Origin` header is missing\n * - The `Origin` header is `\"null\"` (opaque origin)\n * - The `Origin` header is malformed\n *\n * @param request - The incoming {@link Request} object.\n * @returns The normalized origin string, or `null` if not present or invalid.\n */\nexport function getOrigin(request: Request): string | null {\n const origin = request.headers.get(HttpHeader.ORIGIN)?.trim();\n if (!origin || origin === \"null\") return null;\n\n try {\n return new URL(origin).origin;\n } catch {\n return null;\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { HttpHeader } from \"../../constants/http\";\nimport { CorsConfig } from \"../../interfaces/cors-config\";\nimport { Worker } from \"../../interfaces/worker\";\nimport { mergeHeader, setHeader } from \"../../utils/header\";\nimport { getOrigin } from \"../../utils/request\";\n\n/**\n * Adds CORS headers to the given Headers object based on the request and config.\n */\nexport function addCorsHeaders(worker: Worker, cors: CorsConfig, headers: Headers): void {\n deleteCorsHeaders(headers);\n\n const origin = getOrigin(worker.request);\n if (!origin) return;\n\n if (allowAnyOrigin(cors)) {\n // Allowed Origin: *\n setHeader(headers, HttpHeader.ALLOW_ORIGIN, HttpHeader.ALLOW_ALL_ORIGINS);\n } else if (cors.allowedOrigins.length > 0) {\n // Allowed Origin: [\"https://example.com\"]\n // Always add Vary: Origin\n mergeHeader(headers, HttpHeader.VARY, HttpHeader.ORIGIN);\n\n if (cors.allowedOrigins.includes(origin)) {\n // When the provided origin is allowed:\n setHeader(headers, HttpHeader.ALLOW_ORIGIN, origin);\n setHeader(headers, HttpHeader.ALLOW_CREDENTIALS, \"true\");\n }\n }\n\n // Add for all CORS requests.\n setHeader(headers, HttpHeader.MAX_AGE, String(cors.maxAge));\n setHeader(headers, HttpHeader.ALLOW_HEADERS, cors.allowedHeaders);\n mergeHeader(headers, HttpHeader.ALLOW_METHODS, worker.getAllowedMethods());\n mergeHeader(headers, HttpHeader.EXPOSE_HEADERS, cors.exposedHeaders);\n}\n\n/** Returns true if the CORS config allows all origins (`*`). */\nfunction allowAnyOrigin(cors: CorsConfig): boolean {\n return cors.allowedOrigins.includes(\"*\");\n}\n\n/** Removes all standard CORS headers from a Headers object. */\nfunction deleteCorsHeaders(headers: Headers): void {\n headers.delete(HttpHeader.MAX_AGE);\n headers.delete(HttpHeader.ALLOW_ORIGIN);\n headers.delete(HttpHeader.ALLOW_HEADERS);\n headers.delete(HttpHeader.ALLOW_METHODS);\n headers.delete(HttpHeader.EXPOSE_HEADERS);\n headers.delete(HttpHeader.ALLOW_CREDENTIALS);\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { HttpHeader } from \"../../constants/http\";\nimport { Time } from \"../../constants/time\";\nimport { CorsConfig } from \"../../interfaces/cors-config\";\n\n/**\n * Default configuration for CORS middleware.\n */\nexport const defaultCorsConfig: CorsConfig = {\n allowedOrigins: [\"*\"], // Origins allowed for CORS requests\n allowedHeaders: [HttpHeader.CONTENT_TYPE], // HTTP headers allowed in requests\n exposedHeaders: [], // Headers exposed to the client\n maxAge: Time.Week, // Max age in seconds for preflight caching\n} as const;\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getReasonPhrase, StatusCodes } from \"http-status-codes\";\nimport { CacheControl } from \"./constants/cache\";\nimport { setHeader, mergeHeader } from \"./utils/header\";\nimport { getContentType } from \"./utils/request\";\nimport { MediaType } from \"./constants/media-types\";\nimport { HttpHeader } from \"./constants/http\";\n\n/**\n * Base class for building HTTP responses.\n * Manages headers, status, and media type.\n */\nabstract class BaseResponse {\n /** HTTP headers for the response. */\n public headers: Headers = new Headers();\n\n /** HTTP status code (default 200 OK). */\n public status: StatusCodes = StatusCodes.OK;\n\n /** Optional status text. Defaults to standard reason phrase. */\n public statusText?: string;\n\n /** Default media type of the response body. */\n public mediaType: MediaType = MediaType.PLAIN_TEXT;\n\n /** Converts current state to ResponseInit for constructing a Response. */\n protected get responseInit(): ResponseInit {\n return {\n headers: this.headers,\n status: this.status,\n statusText: this.statusText ?? getReasonPhrase(this.status),\n };\n }\n\n /** Sets a header, overwriting any existing value. */\n public setHeader(key: string, value: string | string[]): void {\n setHeader(this.headers, key, value);\n }\n\n /** Merges a header with existing values (does not overwrite). */\n public mergeHeader(key: string, value: string | string[]): void {\n mergeHeader(this.headers, key, value);\n }\n\n /** Adds a Content-Type header if not already existing (does not overwrite). */\n public addContentType() {\n if (!this.headers.get(HttpHeader.CONTENT_TYPE)) {\n this.headers.set(HttpHeader.CONTENT_TYPE, getContentType(this.mediaType));\n }\n }\n}\n\n/**\n * Base response class that adds caching headers.\n */\nabstract class CacheResponse extends BaseResponse {\n constructor(public cache?: CacheControl) {\n super();\n }\n\n /** Adds Cache-Control header if caching is configured. */\n protected addCacheHeader(): void {\n if (this.cache) {\n this.headers.set(HttpHeader.CACHE_CONTROL, CacheControl.stringify(this.cache));\n }\n }\n}\n\n/**\n * Core worker response. Combines caching, and security headers.\n */\nexport abstract class WorkerResponse extends CacheResponse {\n constructor(\n private readonly body: BodyInit | null = null,\n cache?: CacheControl,\n ) {\n super(cache);\n }\n\n /** Builds the Response object with body, headers, and status. */\n public async getResponse(): Promise<Response> {\n this.addCacheHeader();\n\n const body = this.status === StatusCodes.NO_CONTENT ? null : this.body;\n\n if (body) this.addContentType();\n return new Response(body, this.responseInit);\n }\n}\n\n/**\n * Wraps an existing Response and clones its body, headers, and status.\n */\nexport class ClonedResponse extends WorkerResponse {\n constructor(response: Response, cache?: CacheControl) {\n const clone = response.clone();\n super(clone.body, cache);\n this.headers = new Headers(clone.headers);\n this.status = clone.status;\n this.statusText = clone.statusText;\n }\n}\n\n/**\n * Represents a successful response with customizable body, cache and status.\n */\nexport class SuccessResponse extends WorkerResponse {\n constructor(\n body: BodyInit | null = null,\n cache?: CacheControl,\n status: StatusCodes = StatusCodes.OK,\n ) {\n super(body, cache);\n this.status = status;\n }\n}\n\n/**\n * JSON response. Automatically sets Content-Type to application/json.\n */\nexport class JsonResponse extends SuccessResponse {\n constructor(json: unknown = {}, cache?: CacheControl, status: StatusCodes = StatusCodes.OK) {\n super(JSON.stringify(json), cache, status);\n this.mediaType = MediaType.JSON;\n }\n}\n\n/**\n * HTML response. Automatically sets Content-Type to text/html.\n */\nexport class HtmlResponse extends SuccessResponse {\n constructor(body: string, cache?: CacheControl, status: StatusCodes = StatusCodes.OK) {\n super(body, cache, status);\n this.mediaType = MediaType.HTML;\n }\n}\n\n/**\n * Plain text response. Automatically sets Content-Type to text/plain.\n */\nexport class TextResponse extends SuccessResponse {\n constructor(content: string, cache?: CacheControl, status: StatusCodes = StatusCodes.OK) {\n super(content, cache, status);\n this.mediaType = MediaType.PLAIN_TEXT;\n }\n}\n\n/**\n * Response for HEAD requests. Copy headers and status from a GET response\n * without the body.\n */\nexport class Head extends WorkerResponse {\n constructor(get: Response) {\n super();\n this.status = get.status;\n this.statusText = get.statusText;\n this.headers = new Headers(get.headers);\n }\n}\n\n/**\n * Response for OPTIONS preflight requests.\n */\nexport class Options extends SuccessResponse {\n constructor() {\n super(null, undefined, StatusCodes.NO_CONTENT);\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { addCorsHeaders } from \"./utils\";\nimport { Worker } from \"../../interfaces/worker\";\nimport { Middleware } from \"../middleware\";\nimport { CorsConfig, CorsInit } from \"../../interfaces/cors-config\";\nimport { defaultCorsConfig } from \"./constants\";\nimport { ClonedResponse, Options } from \"../../responses\";\nimport { OPTIONS } from \"../../constants/http\";\n\n/**\n * Creates a CORS middleware instance.\n *\n * This middleware automatically handles Cross-Origin Resource Sharing (CORS)\n * for incoming requests, including preflight OPTIONS requests, and adds\n * appropriate headers to responses.\n *\n * @param init - Optional configuration for CORS behavior. See {@link CorsConfig}.\n * @returns A {@link Middleware} instance that can be used in your middleware chain.\n */\nexport function cors(init?: CorsInit): Middleware {\n return new CorsHandler(init);\n}\n\nclass CorsHandler extends Middleware {\n /** The configuration used for this instance, with all defaults applied. */\n private readonly config: CorsConfig;\n\n /**\n * Create a new CORS middleware instance.\n *\n * @param init - Partial configuration to override the defaults. Any values\n * not provided will use `defaultCorsConfig`.\n */\n constructor(init?: CorsInit) {\n super();\n this.config = { ...defaultCorsConfig, ...init };\n }\n\n /**\n * Handle a request by applying CORS headers to the response.\n *\n * @param worker - The Worker instance containing the request context.\n * @param next - Function to invoke the next middleware in the chain.\n * @returns A Response object with CORS headers applied.\n */\n public override async handle(worker: Worker, next: () => Promise<Response>): Promise<Response> {\n if (worker.request.method === OPTIONS) {\n const options = new Options();\n addCorsHeaders(worker, this.config, options.headers);\n return options.getResponse();\n }\n\n const response = await next();\n\n const clone = new ClonedResponse(response);\n addCorsHeaders(worker, this.config, clone.headers);\n return clone.getResponse();\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getReasonPhrase, StatusCodes } from \"http-status-codes\";\nimport { JsonResponse } from \"./responses\";\nimport { ErrorJson } from \"./interfaces/error-json\";\nimport { Worker } from \"./interfaces/worker\";\nimport { CacheControl } from \"./constants/cache\";\nimport { HttpHeader } from \"./constants/http\";\n\n/**\n * Generic HTTP error response.\n * Sends a JSON body with status, error message, and details.\n */\nexport class HttpError extends JsonResponse {\n /**\n * @param worker The worker handling the request.\n * @param status HTTP status code.\n * @param details Optional detailed error message.\n */\n constructor(\n status: StatusCodes,\n protected readonly details?: string,\n ) {\n const json: ErrorJson = {\n status,\n error: getReasonPhrase(status),\n details: details ?? \"\",\n };\n super(json, CacheControl.DISABLE, status);\n }\n}\n\n/** 400 Bad Request error response. */\nexport class BadRequest extends HttpError {\n constructor(details?: string) {\n super(StatusCodes.BAD_REQUEST, details);\n }\n}\n\n/** 401 Unauthorized error response. */\nexport class Unauthorized extends HttpError {\n constructor(details?: string) {\n super(StatusCodes.UNAUTHORIZED, details);\n }\n}\n\n/** 403 Forbidden error response. */\nexport class Forbidden extends HttpError {\n constructor(details?: string) {\n super(StatusCodes.FORBIDDEN, details);\n }\n}\n\n/** 404 Not Found error response. */\nexport class NotFound extends HttpError {\n constructor(details?: string) {\n super(StatusCodes.NOT_FOUND, details);\n }\n}\n\n/** 405 Method Not Allowed error response. */\nexport class MethodNotAllowed extends HttpError {\n constructor(worker: Worker) {\n super(StatusCodes.METHOD_NOT_ALLOWED, `${worker.request.method} method not allowed.`);\n this.setHeader(HttpHeader.ALLOW, worker.getAllowedMethods());\n }\n}\n\n/** 500 Internal Server Error response. */\nexport class InternalServerError extends HttpError {\n constructor(details?: string) {\n super(StatusCodes.INTERNAL_SERVER_ERROR, details);\n }\n}\n\n/** 501 Not Implemented error response. */\nexport class NotImplemented extends HttpError {\n constructor(details?: string) {\n super(StatusCodes.NOT_IMPLEMENTED, details);\n }\n}\n\n/** 501 Method Not Implemented error response for unsupported HTTP methods. */\nexport class MethodNotImplemented extends NotImplemented {\n constructor(worker: Worker) {\n super(`${worker.request.method} method not implemented.`);\n }\n}\n\n/** 503 Service Unavailable error response. */\nexport class ServiceUnavailable extends HttpError {\n constructor(details?: string) {\n super(StatusCodes.SERVICE_UNAVAILABLE, details);\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Method } from \"../constants/http\";\nimport { FetchHandler } from \"../interfaces/fetch-handler\";\nimport { Worker, WorkerClass } from \"../interfaces/worker\";\n\n/**\n * Provides the foundational structure for handling requests,\n * environment bindings, and the worker execution context.\n *\n * Features:\n * - Holds the current `Request` object (`request` getter).\n * - Provides access to environment bindings (`env` getter).\n * - Provides access to the worker execution context (`ctx` getter).\n * - Subclasses must implement `fetch()` to process the request.\n */\nexport abstract class BaseWorker implements Worker {\n constructor(\n private readonly _request: Request,\n private readonly _env: Env,\n private readonly _ctx: ExecutionContext,\n ) {}\n\n /** The Request object associated with this worker invocation */\n public get request(): Request {\n return this._request;\n }\n\n /** Environment bindings (e.g., KV, secrets, or other globals) */\n public get env(): Env {\n return this._env;\n }\n\n /** Execution context for background tasks or `waitUntil` */\n public get ctx(): ExecutionContext {\n return this._ctx;\n }\n\n /**\n * Dispatches the incoming request to the appropriate handler and produces a response.\n *\n * Subclasses must implement this method to define how the worker generates a `Response`\n * for the current request. This is the central point where request processing occurs.\n *\n * @returns A Promise that resolves to the `Response` for the request.\n */\n protected abstract dispatch(): Promise<Response>;\n\n public abstract getAllowedMethods(): Method[];\n\n /**\n * Creates a new instance of the current Worker subclass.\n *\n * @param request - The {@link Request} to pass to the new worker instance.\n * @returns A new worker instance of the same subclass as `this`.\n */\n protected create(request: Request): this {\n const ctor = this.constructor as WorkerClass<this>;\n return new ctor(request, this.env, this.ctx);\n }\n\n /**\n * Process the {@link Request} and produce a {@link Response}.\n *\n * @returns A {@link Response} promise for the {@link Request}.\n */\n public abstract fetch(): Promise<Response>;\n\n /**\n * **Ignite** your `Worker` implementation into a Cloudflare handler.\n *\n * @returns A `FetchHandler` that launches a new worker instance for each request.\n *\n * ```ts\n * export default MyWorker.ignite();\n * ```\n */\n public static ignite<W extends Worker>(this: WorkerClass<W>): FetchHandler {\n return {\n fetch: (request: Request, env: Env, ctx: ExecutionContext) =>\n new this(request, env, ctx).fetch(),\n };\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BaseWorker } from \"./base-worker\";\nimport { Middleware } from \"../middleware/middleware\";\n\n/** Internal base worker for handling middleware chains. */\nexport abstract class MiddlewareWorker extends BaseWorker {\n /** Middleware handlers registered for this worker. */\n protected readonly middlewares: Middleware[] = [];\n\n /**\n * Add a middleware instance to this worker.\n *\n * The middleware will run for every request handled by this worker,\n * in the order they are added.\n *\n * @param handler - The middleware to run.\n * @returns `this` to allow chaining multiple `.use()` calls.\n */\n public use(handler: Middleware): this {\n this.middlewares.push(handler);\n return this;\n }\n\n /**\n * Executes the middleware chain and dispatches the request.\n *\n * @returns The Response produced by the last middleware or `dispatch()`.\n */\n public override async fetch(): Promise<Response> {\n const chain = this.middlewares.reduceRight(\n (next, handler) => () => handler.handle(this, next),\n () => this.dispatch(),\n );\n return await chain();\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MethodNotAllowed, InternalServerError, MethodNotImplemented } from \"../errors\";\nimport { MiddlewareWorker } from \"./middleware-worker\";\nimport { Head, WorkerResponse } from \"../responses\";\nimport { Method, GET, HEAD, OPTIONS } from \"../constants/http\";\nimport { isMethod } from \"../utils/request\";\n\n/**\n * Basic worker class providing HTTP method dispatching and error handling.\n */\nexport abstract class BasicWorker extends MiddlewareWorker {\n /**\n * Entry point to handle a fetch request.\n */\n public override async fetch(): Promise<Response> {\n if (!this.isAllowed(this.request.method)) {\n return this.getResponse(MethodNotAllowed, this);\n }\n\n try {\n await this.init();\n return await super.fetch();\n } catch (error) {\n console.error(error);\n return this.getResponse(InternalServerError);\n }\n }\n\n /**\n * Dispatches the request to the method-specific handler.\n */\n protected override async dispatch(): Promise<Response> {\n const method = this.request.method as Method;\n const handler: Record<Method, () => Promise<Response>> = {\n GET: () => this.get(),\n PUT: () => this.put(),\n HEAD: () => this.head(),\n POST: () => this.post(),\n PATCH: () => this.patch(),\n DELETE: () => this.delete(),\n OPTIONS: () => this.options(),\n };\n\n return (handler[method] ?? (() => this.getResponse(MethodNotAllowed, this)))();\n }\n\n /**\n * Hook for subclasses to perform any initialization.\n */\n protected init(): void | Promise<void> {\n return;\n }\n\n /**\n * Checks if the given HTTP method is allowed for this worker.\n * @param method HTTP method string\n * @returns true if the method is allowed\n */\n public isAllowed(method: string): boolean {\n return isMethod(method) && this.getAllowedMethods().includes(method);\n }\n\n /** Override and implement this method for GET requests. */\n protected async get(): Promise<Response> {\n return this.getResponse(MethodNotImplemented, this);\n }\n\n /** Override and implement this method for PUT requests. */\n protected async put(): Promise<Response> {\n return this.getResponse(MethodNotImplemented, this);\n }\n\n /** Override and implement this method for POST requests. */\n protected async post(): Promise<Response> {\n return this.getResponse(MethodNotImplemented, this);\n }\n\n /** Override and implement this method for PATCH requests. */\n protected async patch(): Promise<Response> {\n return this.getResponse(MethodNotImplemented, this);\n }\n\n /** Override and implement this method for DELETE requests. */\n protected async delete(): Promise<Response> {\n return this.getResponse(MethodNotImplemented, this);\n }\n\n /** Override and implement this method for OPTIONS requests. */\n protected async options(): Promise<Response> {\n return this.getResponse(MethodNotImplemented, this);\n }\n\n /**\n * Default handler for HEAD requests.\n * Performs a GET request and removes the body for HEAD semantics.\n *\n * Usually does not need to be overridden as this behavior covers\n * standard HEAD requirements.\n */\n protected async head(): Promise<Response> {\n const worker = this.create(new Request(this.request, { method: GET }));\n return this.getResponse(Head, await worker.fetch());\n }\n\n /**\n * DEFAULT allowed HTTP methods for subclasses.\n *\n * These defaults were selected for getting started quickly and should be\n * overridden for each specific worker.\n */\n public getAllowedMethods(): Method[] {\n return [GET, HEAD, OPTIONS];\n }\n\n /**\n * Simplify and standardize {@link Response} creation by extending {@link WorkerResponse}\n * or any of its subclasses and passing to this method.\n *\n * Or directly use any of the built-in classes.\n *\n * ```ts\n * this.getResponse(TextResponse, \"Hello World!\")\n * ```\n *\n * @param ResponseClass The response class to instantiate\n * @param args Additional constructor arguments\n * @returns A Promise resolving to the {@link Response} object\n */\n protected async getResponse<\n Ctor extends new (...args: any[]) => { getResponse(): Promise<Response> },\n >(ResponseClass: Ctor, ...args: ConstructorParameters<Ctor>): Promise<Response> {\n return new ResponseClass(...args).getResponse();\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { match } from \"path-to-regexp\";\nimport { MatchedRoute, Route, PathParams, RouteTable } from \"./interfaces/route\";\nimport { Method } from \"./constants/http\";\n\n/**\n * Container for route definitions and matching logic.\n * Implements Iterable to allow iteration over all routes.\n */\nexport class Routes implements Iterable<Route> {\n /** Internal array of registered routes */\n private readonly routes: Route[] = [];\n\n /**\n * Add routes to the router.\n *\n * Accepts any iterable of [method, path, handler] tuples.\n * This includes arrays, Sets, or generators.\n *\n * @param routes - Iterable of route tuples to add.\n */\n public add(routes: RouteTable): void {\n for (const [method, path, handler] of routes) {\n const matcher = match<PathParams>(path);\n this.routes.push({ method, matcher, handler });\n }\n }\n\n /**\n * Attempt to match a URL against the registered routes.\n *\n * @param method - HTTP method of the request\n * @param url - Full URL string to match against\n * @returns A MatchedRoute object if a route matches, otherwise null\n */\n public match(method: Method, url: string): MatchedRoute | null {\n const pathname = new URL(url).pathname;\n\n for (const route of this) {\n if (route.method !== method) continue;\n\n const found = route.matcher(pathname);\n if (found) return { route, params: found.params };\n }\n\n return null;\n }\n\n /**\n * Iterate over all registered routes.\n */\n public *[Symbol.iterator](): Iterator<Route> {\n yield* this.routes;\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BasicWorker } from \"./basic-worker\";\nimport { NotFound } from \"../errors\";\nimport { Routes } from \"../routes\";\nimport { RouteHandler, RouteTable } from \"../interfaces/route\";\nimport { WorkerClass } from \"../interfaces/worker\";\nimport { BaseWorker } from \"./base-worker\";\nimport { Method } from \"../constants/http\";\n\n/**\n * Base worker supporting route-based request handling.\n *\n * Subclass `RouteWorker` to define a worker with multiple route handlers.\n *\n * Routes can be registered individually via `route()` or in bulk via `routes()`.\n */\nexport abstract class RouteWorker extends BasicWorker {\n /** Internal table of registered routes. */\n private readonly _routes: Routes = new Routes();\n\n /**\n * Registers a single new route in the worker.\n *\n * When a request matches the specified method and path, the provided handler\n * will be executed. The handler can be either:\n * - A function that receives URL parameters, or\n * - A Worker subclass that will handle the request.\n *\n * @param method - HTTP method for the route (GET, POST, etc.).\n * @param path - URL path pattern (Express-style, e.g., \"/users/:id\").\n * @param handler - The function or Worker class to run when the route matches.\n * @returns The current worker instance, allowing method chaining.\n */\n protected route(method: Method, path: string, handler: RouteHandler): this {\n this.routes([[method, path, handler]]);\n return this;\n }\n\n /**\n * Registers multiple routes at once in the worker.\n *\n * Each route should be a tuple `[method, path, handler]` where:\n * - `method` - HTTP method for the route (GET, POST, etc.).\n * - `path` - URL path pattern (Express-style, e.g., \"/users/:id\").\n * - `handler` - A function that receives URL parameters or a Worker subclass\n * that will handle the request.\n *\n * @param routes - An iterable of routes to register. Each item is a `[method, path, handler]` tuple.\n * @returns The current worker instance, allowing method chaining.\n */\n protected routes(routes: RouteTable): this {\n this._routes.add(routes);\n return this;\n }\n\n /**\n * Matches the incoming request against registered routes and dispatches it.\n *\n * If a route is found:\n * - If the handler is a Worker class, a new instance is created and its `fetch()` is called.\n * - If the handler is a callback function, it is invoked with the extracted path parameters.\n *\n * If no route matches, the request is passed to the parent `dispatch()` handler.\n *\n * @returns A `Promise<Response>` from the matched handler or parent dispatch.\n */\n protected override async dispatch(): Promise<Response> {\n const found = this._routes.match(this.request.method as Method, this.request.url);\n if (!found) return super.dispatch();\n\n const { handler } = found.route;\n if (RouteWorker.isWorkerClass(handler)) {\n return new handler(this.request, this.env, this.ctx).fetch();\n }\n return handler.call(this, found.params);\n }\n\n /**\n * Runtime type guard to check if a given handler is a Worker class.\n *\n * A Worker class is any class that extends `BaseWorker`.\n *\n * @param handler - The constructor function to test.\n * @returns `true` if `handler` is a subclass of `BaseWorker` at runtime, `false` otherwise.\n */\n private static isWorkerClass(handler: RouteHandler): handler is WorkerClass {\n return BaseWorker.prototype.isPrototypeOf(handler.prototype);\n }\n\n protected override async get(): Promise<Response> {\n return this.getResponse(NotFound);\n }\n\n protected override async put(): Promise<Response> {\n return this.getResponse(NotFound);\n }\n\n protected override async post(): Promise<Response> {\n return this.getResponse(NotFound);\n }\n\n protected override async patch(): Promise<Response> {\n return this.getResponse(NotFound);\n }\n\n protected override async delete(): Promise<Response> {\n return this.getResponse(NotFound);\n }\n\n protected override async options(): Promise<Response> {\n return this.getResponse(NotFound);\n }\n}\n"],"mappings":"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","names":["HttpHeader","Method","MediaType","cache","cors","StatusCodes","StatusCodes","cache","getReasonPhrase","StatusCodes","getReasonPhrase","StatusCodes"]}
1
+ {"version":3,"sources":["../src/constants/cache.ts","../src/constants/http.ts","../src/constants/media-types.ts","../src/constants/time.ts","../src/middleware/middleware.ts","../src/utils/compare.ts","../src/utils/url.ts","../src/middleware/cache/handler.ts","../src/responses.ts","../src/utils/header.ts","../src/utils/request.ts","../src/middleware/cors/utils.ts","../src/middleware/cors/constants.ts","../src/middleware/cors/handler.ts","../src/errors.ts","../src/workers/base-worker.ts","../src/workers/middleware-worker.ts","../src/workers/basic-worker.ts","../src/routes.ts","../src/workers/route-worker.ts"],"sourcesContent":["/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport CacheLib from \"cache-control-parser\";\n\n/**\n * @see {@link https://github.com/etienne-martin/cache-control-parser | cache-control-parser}\n */\nexport type CacheControl = CacheLib.CacheControl;\nexport const CacheControl = {\n parse: CacheLib.parse,\n stringify: CacheLib.stringify,\n\n /** A CacheControl directive that disables all caching. */\n DISABLE: Object.freeze({\n \"no-cache\": true,\n \"no-store\": true,\n \"must-revalidate\": true,\n \"max-age\": 0,\n }) satisfies CacheControl,\n};\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * https://github.com/prettymuchbryce/http-status-codes\n */\nexport { StatusCodes } from \"http-status-codes\";\n\n/**\n * Standard HTTP header names and common values.\n */\nexport namespace HttpHeader {\n export const ALLOW = \"Allow\";\n export const ORIGIN = \"Origin\";\n export const CONTENT_TYPE = \"Content-Type\";\n export const CACHE_CONTROL = \"Cache-Control\";\n export const USER_AGENT = \"User-Agent\";\n export const VARY = \"Vary\";\n\n // Security Headers\n export const CONTENT_SECURITY_POLICY = \"Content-Security-Policy\"; // fine-grained script/style/image restrictions\n export const PERMISSIONS_POLICY = \"Permissions-Policy\"; // formerly Feature-Policy, controls APIs like geolocation/camera\n export const STRICT_TRANSPORT_SECURITY = \"Strict-Transport-Security\"; // e.g. \"max-age=63072000; includeSubDomains; preload\"\n export const REFERRER_POLICY = \"Referrer-Policy\"; // e.g. \"no-referrer\", \"strict-origin-when-cross-origin\"\n export const X_CONTENT_TYPE_OPTIONS = \"X-Content-Type-Options\"; // usually \"nosniff\"\n export const X_FRAME_OPTIONS = \"X-Frame-Options\"; // e.g. \"DENY\" or \"SAMEORIGIN\"\n\n // Cors Headers\n export const ACCESS_CONTROL_ALLOW_CREDENTIALS = \"Access-Control-Allow-Credentials\";\n export const ACCESS_CONTROL_ALLOW_HEADERS = \"Access-Control-Allow-Headers\";\n export const ACCESS_CONTROL_ALLOW_METHODS = \"Access-Control-Allow-Methods\";\n export const ACCESS_CONTROL_ALLOW_ORIGIN = \"Access-Control-Allow-Origin\";\n export const ACCESS_CONTROL_EXPOSE_HEADERS = \"Access-Control-Expose-Headers\";\n export const ACCESS_CONTROL_MAX_AGE = \"Access-Control-Max-Age\";\n export const ACCESS_CONTROL_REQUEST_HEADERS = \"Access-Control-Request-Headers\";\n\n // Values\n export const ALLOW_ALL_ORIGINS = \"*\";\n}\n\n/**\n * Standard HTTP request methods.\n */\nexport enum Method {\n GET = \"GET\",\n PUT = \"PUT\",\n HEAD = \"HEAD\",\n POST = \"POST\",\n PATCH = \"PATCH\",\n DELETE = \"DELETE\",\n OPTIONS = \"OPTIONS\",\n}\n\n/**\n * Shorthand constants for each HTTP method.\n *\n * These are equivalent to the corresponding enum members in `Method`.\n * For example, `GET === Method.GET`.\n */\nexport const { GET, PUT, HEAD, POST, PATCH, DELETE, OPTIONS } = Method;\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Common media types used for HTTP headers.\n */\nexport enum MediaType {\n PLAIN_TEXT = \"text/plain\",\n HTML = \"text/html\",\n CSS = \"text/css\",\n CSV = \"text/csv\",\n XML = \"text/xml\",\n MARKDOWN = \"text/markdown\",\n RICH_TEXT = \"text/richtext\",\n JSON = \"application/json\",\n XML_APP = \"application/xml\",\n YAML = \"application/x-yaml\",\n FORM_URLENCODED = \"application/x-www-form-urlencoded\",\n NDJSON = \"application/x-ndjson\",\n MSGPACK = \"application/x-msgpack\",\n PROTOBUF = \"application/x-protobuf\",\n MULTIPART_FORM_DATA = \"multipart/form-data\",\n MULTIPART_MIXED = \"multipart/mixed\",\n MULTIPART_ALTERNATIVE = \"multipart/alternative\",\n MULTIPART_DIGEST = \"multipart/digest\",\n MULTIPART_RELATED = \"multipart/related\",\n MULTIPART_SIGNED = \"multipart/signed\",\n MULTIPART_ENCRYPTED = \"multipart/encrypted\",\n OCTET_STREAM = \"application/octet-stream\",\n PDF = \"application/pdf\",\n ZIP = \"application/zip\",\n GZIP = \"application/gzip\",\n MSWORD = \"application/msword\",\n DOCX = \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n EXCEL = \"application/vnd.ms-excel\",\n XLSX = \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\n POWERPOINT = \"application/vnd.ms-powerpoint\",\n PPTX = \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\n ICO = \"image/x-icon\",\n ICO_MS = \"image/vnd.microsoft.icon\",\n GIF = \"image/gif\",\n PNG = \"image/png\",\n JPEG = \"image/jpeg\",\n WEBP = \"image/webp\",\n SVG = \"image/svg+xml\",\n HEIF = \"image/heif\",\n AVIF = \"image/avif\",\n EVENT_STREAM = \"text/event-stream\",\n TAR = \"application/x-tar\",\n BZIP2 = \"application/x-bzip2\",\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Time constants in seconds. Month is approximated as 30 days.\n */\nexport const Time = {\n Second: 1,\n Minute: 60,\n Hour: 3600, // 60 * 60\n Day: 86400, // 60 * 60 * 24\n Week: 604800, // 60 * 60 * 24 * 7\n Month: 2592000, // 60 * 60 * 24 * 30\n Year: 31536000, // 60 * 60 * 24 * 365\n} as const;\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Worker } from \"../interfaces/worker\";\n\n/**\n * Abstract base class for middleware.\n *\n * Middleware classes implement request/response processing logic in a\n * chainable manner. Each middleware receives a `Worker` object and a\n * `next` function that invokes the next middleware in the chain.\n *\n * Subclasses **must implement** the `handle` method.\n *\n * Example subclass:\n * ```ts\n * class LoggingMiddleware extends Middleware {\n * public async handle(worker: Worker, next: () => Promise<Response>): Promise<Response> {\n * console.log(`Processing request: ${worker.request.url}`);\n * const response = await next();\n * console.log(`Response status: ${response.status}`);\n * return response;\n * }\n * }\n * ```\n */\nexport abstract class Middleware {\n /**\n * Process a request in the middleware chain.\n *\n * @param worker - The `Worker` instance representing the request context.\n * @param next - Function to invoke the next middleware in the chain.\n * Must be called to continue the chain unless the middleware\n * terminates early (e.g., returns a response directly).\n * @returns A `Response` object, either returned directly or from `next()`.\n */\n public abstract handle(worker: Worker, next: () => Promise<Response>): Promise<Response>;\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Lexicographically compares two strings.\n *\n * This comparator can be used in `Array.prototype.sort()` to produce a\n * consistent, stable ordering of string arrays.\n *\n * @param a - The first string to compare.\n * @param b - The second string to compare.\n * @returns A number indicating the relative order of `a` and `b`.\n */\nexport function lexCompare(a: string, b: string): number {\n if (a < b) return -1;\n if (a > b) return 1;\n return 0;\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { lexCompare } from \"./compare\";\n\n/**\n * Normalizes a URL string for use as a consistent cache key.\n *\n * - Sorts query parameters alphabetically so `?b=2&a=1` and `?a=1&b=2` are treated the same.\n * - Strips fragment identifiers (`#...`) since they are not sent in HTTP requests.\n * - Leaves protocol, host, path, and query values intact.\n *\n * @param url The original URL string to normalize.\n * @returns A normalized URL string suitable for hashing or direct cache key use.\n */\nexport function normalizeUrl(url: string): URL {\n const u = new URL(url);\n\n const params = [...u.searchParams.entries()];\n params.sort(([a], [b]) => lexCompare(a, b));\n\n u.search = params\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)\n .join(\"&\");\n u.hash = \"\";\n\n return u;\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Middleware } from \"../middleware\";\nimport { Worker } from \"../../interfaces/worker\";\nimport { GET } from \"../../constants/http\";\nimport { normalizeUrl } from \"../../utils/url\";\n\n/**\n * Middleware for caching GET requests.\n *\n * This middleware checks a cache (either a named cache or the default)\n * before passing the request down the middleware chain. Responses for\n * successful GET requests are automatically stored in the cache.\n *\n * Non-GET requests are never cached. The cache key can be customized\n * via the `getKey` function; otherwise, the URL is normalized and used.\n *\n * @param cacheName - Optional name of the cache to use. Defaults to `caches.default`.\n * @param getKey - Optional function to generate a cache key from a request.\n * @returns A {@link Middleware} instance that can be added to your middleware chain.\n */\nexport function cache(\n cacheName?: string,\n getKey?: (request: Request) => URL | RequestInfo,\n): Middleware {\n return new CacheHandler(cacheName, getKey);\n}\n\nclass CacheHandler extends Middleware {\n /**\n * @param cacheName - Optional name of the cache to use. If omitted,\n * `caches.default` is used.\n * @param getKey - Optional function to generate a cache key from a request.\n * Defaults to using the normalized request URL.\n */\n constructor(\n protected readonly cacheName?: string,\n protected readonly getKey?: (request: Request) => URL | RequestInfo,\n ) {\n super();\n }\n\n /**\n * Handle a request in the caching middleware.\n *\n * Checks the cache for GET requests and returns the cached response if available.\n * Otherwise, calls `next()` to continue the middleware chain and caches\n * the response if successful.\n *\n * @param worker - The Worker instance containing the request context.\n * @param next - Function to invoke the next middleware in the chain.\n * @returns A Response object, either from cache or the next middleware.\n */\n public override async handle(worker: Worker, next: () => Promise<Response>): Promise<Response> {\n const cache = this.cacheName ? await caches.open(this.cacheName) : caches.default;\n\n if (worker.request.method === GET) {\n const cached = await cache.match(this.getCacheKey(worker.request));\n if (cached) return cached;\n }\n\n const response = await next();\n\n if (worker.request.method === GET && response.ok) {\n worker.ctx.waitUntil(cache.put(this.getCacheKey(worker.request), response.clone()));\n }\n return response;\n }\n\n /**\n * Generate the cache key for a request.\n *\n * @param request - The Request object to generate a cache key for.\n * @returns A URL or RequestInfo used as the cache key.\n *\n * If a custom `getKey` function was provided in the constructor, it is used.\n * Otherwise, the request URL is normalized.\n */\n private getCacheKey(request: Request): URL | RequestInfo {\n return this.getKey ? this.getKey(request) : normalizeUrl(request.url);\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getReasonPhrase, StatusCodes } from \"http-status-codes\";\nimport { CacheControl } from \"./constants/cache\";\nimport { setHeader, mergeHeader } from \"./utils/header\";\nimport { getContentType } from \"./utils/request\";\nimport { MediaType } from \"./constants/media-types\";\nimport { HttpHeader } from \"./constants/http\";\n\n/**\n * Base class for building HTTP responses.\n * Manages headers, status, and media type.\n */\nabstract class BaseResponse {\n /** HTTP headers for the response. */\n public headers: Headers = new Headers();\n\n /** HTTP status code (default 200 OK). */\n public status: StatusCodes = StatusCodes.OK;\n\n /** Optional status text. Defaults to standard reason phrase. */\n public statusText?: string;\n\n /** Default media type of the response body. */\n public mediaType: MediaType = MediaType.PLAIN_TEXT;\n\n /** Converts current state to ResponseInit for constructing a Response. */\n protected get responseInit(): ResponseInit {\n return {\n headers: this.headers,\n status: this.status,\n statusText: this.statusText ?? getReasonPhrase(this.status),\n };\n }\n\n /** Sets a header, overwriting any existing value. */\n public setHeader(key: string, value: string | string[]): void {\n setHeader(this.headers, key, value);\n }\n\n /** Merges a header with existing values (does not overwrite). */\n public mergeHeader(key: string, value: string | string[]): void {\n mergeHeader(this.headers, key, value);\n }\n\n /** Adds a Content-Type header if not already existing (does not overwrite). */\n public addContentType() {\n if (!this.headers.get(HttpHeader.CONTENT_TYPE)) {\n this.headers.set(HttpHeader.CONTENT_TYPE, getContentType(this.mediaType));\n }\n }\n}\n\n/**\n * Base response class that adds caching headers.\n */\nabstract class CacheResponse extends BaseResponse {\n constructor(public cache?: CacheControl) {\n super();\n }\n\n /** Adds Cache-Control header if caching is configured. */\n protected addCacheHeader(): void {\n if (this.cache) {\n this.headers.set(HttpHeader.CACHE_CONTROL, CacheControl.stringify(this.cache));\n }\n }\n}\n\n/**\n * Core worker response. Combines caching, and security headers.\n */\nexport abstract class WorkerResponse extends CacheResponse {\n constructor(\n private readonly body: BodyInit | null = null,\n cache?: CacheControl,\n ) {\n super(cache);\n }\n\n /** Builds the Response object with body, headers, and status. */\n public async getResponse(): Promise<Response> {\n this.addCacheHeader();\n\n const body = this.status === StatusCodes.NO_CONTENT ? null : this.body;\n\n if (body) this.addContentType();\n return new Response(body, this.responseInit);\n }\n}\n\n/**\n * Wraps an existing Response and clones its body, headers, and status.\n */\nexport class ClonedResponse extends WorkerResponse {\n constructor(response: Response, cache?: CacheControl) {\n const clone = response.clone();\n super(clone.body, cache);\n this.headers = new Headers(clone.headers);\n this.status = clone.status;\n this.statusText = clone.statusText;\n }\n}\n\n/**\n * Represents a successful response with customizable body, cache and status.\n */\nexport class SuccessResponse extends WorkerResponse {\n constructor(\n body: BodyInit | null = null,\n cache?: CacheControl,\n status: StatusCodes = StatusCodes.OK,\n ) {\n super(body, cache);\n this.status = status;\n }\n}\n\n/**\n * JSON response. Automatically sets Content-Type to application/json.\n */\nexport class JsonResponse extends SuccessResponse {\n constructor(json: unknown = {}, cache?: CacheControl, status: StatusCodes = StatusCodes.OK) {\n super(JSON.stringify(json), cache, status);\n this.mediaType = MediaType.JSON;\n }\n}\n\n/**\n * HTML response. Automatically sets Content-Type to text/html.\n */\nexport class HtmlResponse extends SuccessResponse {\n constructor(body: string, cache?: CacheControl, status: StatusCodes = StatusCodes.OK) {\n super(body, cache, status);\n this.mediaType = MediaType.HTML;\n }\n}\n\n/**\n * Plain text response. Automatically sets Content-Type to text/plain.\n */\nexport class TextResponse extends SuccessResponse {\n constructor(content: string, cache?: CacheControl, status: StatusCodes = StatusCodes.OK) {\n super(content, cache, status);\n this.mediaType = MediaType.PLAIN_TEXT;\n }\n}\n\n/**\n * Response for HEAD requests. Copy headers and status from a GET response\n * without the body.\n */\nexport class Head extends WorkerResponse {\n constructor(get: Response) {\n super();\n this.status = get.status;\n this.statusText = get.statusText;\n this.headers = new Headers(get.headers);\n }\n}\n\n/**\n * Response for OPTIONS preflight requests.\n */\nexport class Options extends SuccessResponse {\n constructor() {\n super(null, undefined, StatusCodes.NO_CONTENT);\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { lexCompare } from \"./compare\";\n\n/**\n * Sets a header on the given Headers object.\n *\n * - If `value` is an array, any duplicates and empty strings are removed.\n * - If the resulting value is empty, the header is deleted.\n * - Otherwise, values are joined with `\", \"` and set as the header value.\n *\n * @param headers - The Headers object to modify.\n * @param key - The header name to set.\n * @param value - The header value(s) to set. Can be a string or array of strings.\n */\nexport function setHeader(headers: Headers, key: string, value: string | string[]): void {\n const raw = Array.isArray(value) ? value : [value];\n const values = Array.from(new Set(raw.map((v) => v.trim())))\n .filter((v) => v.length)\n .sort(lexCompare);\n\n if (!values.length) {\n headers.delete(key);\n return;\n }\n\n headers.set(key, values.join(\", \"));\n}\n\n/**\n * Merges new value(s) into an existing header on the given Headers object.\n *\n * - Preserves any existing values and adds new ones.\n * - Removes duplicates and trims all values.\n * - If the header does not exist, it is created.\n * - If the resulting value array is empty, the header is deleted.\n *\n * @param headers - The Headers object to modify.\n * @param key - The header name to merge into.\n * @param value - The new header value(s) to add. Can be a string or array of strings.\n */\nexport function mergeHeader(headers: Headers, key: string, value: string | string[]): void {\n const values = Array.isArray(value) ? value : [value];\n if (!values.length) return;\n\n const existing = headers.get(key);\n if (existing) {\n const merged = existing.split(\",\").map((v) => v.trim());\n values.forEach((v) => merged.push(v.trim()));\n setHeader(headers, key, merged);\n } else {\n setHeader(headers, key, values);\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { HttpHeader, Method } from \"../constants/http\";\nimport { MediaType } from \"../constants/media-types\";\n\n/**\n * A set containing all supported HTTP methods.\n *\n * Useful for runtime checks like validating request methods.\n */\nconst METHOD_SET: Set<string> = new Set(Object.values(Method));\n\n/**\n * Type guard that checks if a string is a valid HTTP method.\n *\n * @param value - The string to test.\n * @returns True if `value` is a recognized HTTP method.\n */\nexport function isMethod(value: string): value is Method {\n return METHOD_SET.has(value);\n}\n\n/**\n * A set of media types that require a `charset` parameter when setting\n * the `Content-Type` header.\n *\n * This includes common text-based media types such as HTML, CSS, JSON,\n * XML, CSV, Markdown, and others.\n */\nconst ADD_CHARSET: Set<MediaType> = new Set([\n MediaType.CSS,\n MediaType.CSV,\n MediaType.XML,\n MediaType.SVG,\n MediaType.HTML,\n MediaType.JSON,\n MediaType.NDJSON,\n MediaType.XML_APP,\n MediaType.MARKDOWN,\n MediaType.RICH_TEXT,\n MediaType.PLAIN_TEXT,\n MediaType.FORM_URLENCODED,\n]);\n\n/**\n * Returns the proper Content-Type string for a given media type.\n * Appends `charset=utf-8` for text-based types that require it.\n *\n * @param type - The media type.\n * @returns A string suitable for the `Content-Type` header.\n */\nexport function getContentType(type: MediaType): string {\n if (ADD_CHARSET.has(type)) {\n return `${type}; charset=utf-8`;\n }\n return type;\n}\n\n/**\n * Extracts and normalizes the `Origin` header from a request.\n *\n * Returns the origin (scheme + host + port) as a string if present and valid.\n * Returns `null` if:\n * - The `Origin` header is missing\n * - The `Origin` header is `\"null\"` (opaque origin)\n * - The `Origin` header is malformed\n *\n * @param request - The incoming {@link Request} object.\n * @returns The normalized origin string, or `null` if not present or invalid.\n */\nexport function getOrigin(request: Request): string | null {\n const origin = request.headers.get(HttpHeader.ORIGIN)?.trim();\n if (!origin || origin === \"null\") return null;\n\n try {\n return new URL(origin).origin;\n } catch {\n return null;\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { GET, HEAD, HttpHeader, Method, OPTIONS } from \"../../constants/http\";\nimport { CorsConfig } from \"../../interfaces/cors-config\";\nimport { Worker } from \"../../interfaces/worker\";\nimport { ClonedResponse, Options } from \"../../responses\";\nimport { mergeHeader, setHeader } from \"../../utils/header\";\nimport { getOrigin } from \"../../utils/request\";\n\n/**\n * Set of HTTP methods considered \"simple\" under the CORS specification.\n *\n * Simple methods do not trigger a preflight request:\n * - GET\n * - HEAD\n * - OPTIONS\n */\nconst SIMPLE_METHODS = new Set<Method>([GET, HEAD, OPTIONS]);\n\n/**\n * Handles a CORS preflight OPTIONS request.\n *\n * Sets the appropriate CORS headers based on the provided configuration\n * and the origin of the request.\n *\n * @param worker - The Worker handling the request.\n * @param cors - The CORS configuration.\n * @returns A Response object for the preflight request.\n */\nexport async function options(worker: Worker, cors: CorsConfig): Promise<Response> {\n const options = new Options();\n const origin = getOrigin(worker.request);\n\n if (origin) {\n setAllowOrigin(options.headers, cors, origin);\n setAllowCredentials(options.headers, cors, origin);\n }\n setAllowMethods(options.headers, worker);\n setMaxAge(options.headers, cors);\n setAllowHeaders(options.headers, worker, cors);\n\n return options.getResponse();\n}\n\n/**\n * Applies CORS headers to an existing response.\n *\n * Useful for normal (non-preflight) responses where the response\n * should include CORS headers based on the request origin.\n *\n * @param response - The original Response object.\n * @param worker - The Worker handling the request.\n * @param cors - The CORS configuration.\n * @returns A new Response object with CORS headers applied.\n */\nexport async function apply(\n response: Response,\n worker: Worker,\n cors: CorsConfig,\n): Promise<Response> {\n const clone = new ClonedResponse(response);\n const origin = getOrigin(worker.request);\n\n deleteCorsHeaders(clone.headers);\n\n if (origin) {\n setAllowOrigin(clone.headers, cors, origin);\n setAllowCredentials(clone.headers, cors, origin);\n }\n setExposedHeaders(clone.headers, cors);\n return clone.getResponse();\n}\n\n/**\n * Sets the Access-Control-Allow-Origin header based on the CORS config\n * and request origin.\n *\n * @param headers - The headers object to modify.\n * @param cors - The CORS configuration.\n * @param origin - The request's origin, or null if not present.\n */\nexport function setAllowOrigin(headers: Headers, cors: CorsConfig, origin: string): void {\n if (allowAnyOrigin(cors)) {\n setHeader(headers, HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN, HttpHeader.ALLOW_ALL_ORIGINS);\n } else {\n if (cors.allowedOrigins.includes(origin)) {\n setHeader(headers, HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN, origin);\n }\n mergeHeader(headers, HttpHeader.VARY, HttpHeader.ORIGIN);\n }\n}\n\n/**\n * Sets the Access-Control-Allow-Credentials header if credentials\n * are allowed and the origin is not '*'.\n *\n * @param headers - The headers object to modify.\n * @param cors - The CORS configuration.\n * @param origin - The request's origin, or null if not present.\n */\nexport function setAllowCredentials(headers: Headers, cors: CorsConfig, origin: string): void {\n if (!origin) return;\n\n if (!allowAnyOrigin(cors) && cors.allowCredentials) {\n setHeader(headers, HttpHeader.ACCESS_CONTROL_ALLOW_CREDENTIALS, \"true\");\n }\n}\n\n/**\n * Sets the Access-Control-Allow-Methods header based on the Worker's\n * allowed methods.\n *\n * @param headers - The headers object to modify.\n * @param worker - The Worker handling the request.\n */\nexport function setAllowMethods(headers: Headers, worker: Worker): void {\n const methods = worker.getAllowedMethods().filter((method) => !SIMPLE_METHODS.has(method));\n\n if (methods.length > 0) {\n setHeader(headers, HttpHeader.ACCESS_CONTROL_ALLOW_METHODS, methods);\n }\n}\n\n/**\n * Sets the Access-Control-Max-Age header based on the CORS config.\n *\n * @param headers - The headers object to modify.\n * @param cors - The CORS configuration.\n */\nexport function setMaxAge(headers: Headers, cors: CorsConfig): void {\n setHeader(headers, HttpHeader.ACCESS_CONTROL_MAX_AGE, String(cors.maxAge));\n}\n\n/**\n * Sets the Access-Control-Allow-Headers header.\n *\n * If allowedHeaders are explicitly set in the CORS config, those are used.\n * Otherwise, the headers requested by the client are echoed back.\n *\n * @param headers - The headers object to modify.\n * @param worker - The Worker handling the request.\n * @param cors - The CORS configuration.\n */\nexport function setAllowHeaders(headers: Headers, worker: Worker, cors: CorsConfig): void {\n if (cors.allowedHeaders.length > 0) {\n setHeader(headers, HttpHeader.ACCESS_CONTROL_ALLOW_HEADERS, cors.allowedHeaders);\n return;\n }\n const requestHeaders = worker.request.headers.get(HttpHeader.ACCESS_CONTROL_REQUEST_HEADERS);\n if (requestHeaders) {\n setHeader(headers, HttpHeader.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders);\n mergeHeader(headers, HttpHeader.VARY, HttpHeader.ACCESS_CONTROL_ALLOW_HEADERS);\n }\n}\n\n/**\n * Sets the Access-Control-Expose-Headers header for a response.\n *\n * @param headers - The headers object to modify.\n * @param cors - The CORS configuration.\n */\nexport function setExposedHeaders(headers: Headers, cors: CorsConfig): void {\n setHeader(headers, HttpHeader.ACCESS_CONTROL_EXPOSE_HEADERS, cors.exposedHeaders);\n}\n\n/**\n * Returns true if the CORS config allows all origins ('*').\n *\n * @param cors - The CORS configuration.\n */\nexport function allowAnyOrigin(cors: CorsConfig): boolean {\n return cors.allowedOrigins.includes(\"*\");\n}\n\n/**\n * Deletes any existing CORS headers from the provided headers object.\n *\n * @param headers - The headers object to modify.\n */\nexport function deleteCorsHeaders(headers: Headers): void {\n headers.delete(HttpHeader.ACCESS_CONTROL_MAX_AGE);\n headers.delete(HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN);\n headers.delete(HttpHeader.ACCESS_CONTROL_ALLOW_HEADERS);\n headers.delete(HttpHeader.ACCESS_CONTROL_ALLOW_METHODS);\n headers.delete(HttpHeader.ACCESS_CONTROL_EXPOSE_HEADERS);\n headers.delete(HttpHeader.ACCESS_CONTROL_ALLOW_CREDENTIALS);\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { HttpHeader } from \"../../constants/http\";\nimport { Time } from \"../../constants/time\";\nimport { CorsConfig } from \"../../interfaces/cors-config\";\n\n/**\n * Default configuration for CORS middleware.\n */\nexport const defaultCorsConfig: CorsConfig = {\n /**\n * By default, allow all origins.\n * Note: This must be overridden if you also enable `allowCredentials`.\n */\n allowedOrigins: [\"*\"],\n\n /**\n * Default to allowing only \"Content-Type\".\n * This permits requests with JSON or form bodies, while blocking\n * arbitrary custom headers unless explicitly added.\n */\n allowedHeaders: [HttpHeader.CONTENT_TYPE],\n\n /**\n * No response headers are exposed by default.\n * Client-side code will only be able to read CORS-safelisted headers\n * (e.g. Cache-Control, Content-Type, Expires, Last-Modified, Pragma).\n */\n exposedHeaders: [],\n\n /**\n * Credentials (cookies, HTTP auth) are disallowed by default.\n * This avoids the spec restriction that forbids using \"*\" for origins\n * when credentials are enabled.\n */\n allowCredentials: false,\n\n /**\n * Default preflight cache duration: 1 week.\n * Browsers may cache OPTIONS responses for up to this many seconds.\n * Adjust lower if your CORS rules may change frequently.\n */\n maxAge: Time.Week,\n} as const;\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { apply, options } from \"./utils\";\nimport { Worker } from \"../../interfaces/worker\";\nimport { Middleware } from \"../middleware\";\nimport { CorsConfig, CorsInit } from \"../../interfaces/cors-config\";\nimport { defaultCorsConfig } from \"./constants\";\nimport { OPTIONS } from \"../../constants/http\";\n\n/**\n * Creates a CORS middleware instance.\n *\n * This middleware automatically handles Cross-Origin Resource Sharing (CORS)\n * for incoming requests, including preflight OPTIONS requests, and adds\n * appropriate headers to responses.\n *\n * @param init - Optional configuration for CORS behavior. See {@link CorsConfig}.\n * @returns A {@link Middleware} instance that can be used in your middleware chain.\n */\nexport function cors(init?: CorsInit): Middleware {\n return new CorsHandler(init);\n}\n\nclass CorsHandler extends Middleware {\n /** The configuration used for this instance, with all defaults applied. */\n private readonly config: CorsConfig;\n\n /**\n * Create a new CORS middleware instance.\n *\n * @param init - Partial configuration to override the defaults. Any values\n * not provided will use `defaultCorsConfig`.\n */\n constructor(init?: CorsInit) {\n super();\n this.config = { ...defaultCorsConfig, ...init };\n }\n\n /**\n * Applies CORS headers to a request.\n *\n * - Returns a preflight response for `OPTIONS` requests.\n * - For other methods, calls `next()` and applies CORS headers to the result.\n *\n * @param worker - The Worker handling the request.\n * @param next - Function to invoke the next middleware.\n * @returns Response with CORS headers applied.\n */\n public override async handle(worker: Worker, next: () => Promise<Response>): Promise<Response> {\n if (worker.request.method === OPTIONS) {\n return options(worker, this.config);\n }\n\n const response = await next();\n\n return apply(response, worker, this.config);\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getReasonPhrase, StatusCodes } from \"http-status-codes\";\nimport { JsonResponse } from \"./responses\";\nimport { ErrorJson } from \"./interfaces/error-json\";\nimport { Worker } from \"./interfaces/worker\";\nimport { CacheControl } from \"./constants/cache\";\nimport { HttpHeader } from \"./constants/http\";\n\n/**\n * Generic HTTP error response.\n * Sends a JSON body with status, error message, and details.\n */\nexport class HttpError extends JsonResponse {\n /**\n * @param worker The worker handling the request.\n * @param status HTTP status code.\n * @param details Optional detailed error message.\n */\n constructor(\n status: StatusCodes,\n protected readonly details?: string,\n ) {\n const json: ErrorJson = {\n status,\n error: getReasonPhrase(status),\n details: details ?? \"\",\n };\n super(json, CacheControl.DISABLE, status);\n }\n}\n\n/** 400 Bad Request error response. */\nexport class BadRequest extends HttpError {\n constructor(details?: string) {\n super(StatusCodes.BAD_REQUEST, details);\n }\n}\n\n/** 401 Unauthorized error response. */\nexport class Unauthorized extends HttpError {\n constructor(details?: string) {\n super(StatusCodes.UNAUTHORIZED, details);\n }\n}\n\n/** 403 Forbidden error response. */\nexport class Forbidden extends HttpError {\n constructor(details?: string) {\n super(StatusCodes.FORBIDDEN, details);\n }\n}\n\n/** 404 Not Found error response. */\nexport class NotFound extends HttpError {\n constructor(details?: string) {\n super(StatusCodes.NOT_FOUND, details);\n }\n}\n\n/** 405 Method Not Allowed error response. */\nexport class MethodNotAllowed extends HttpError {\n constructor(worker: Worker) {\n super(StatusCodes.METHOD_NOT_ALLOWED, `${worker.request.method} method not allowed.`);\n this.setHeader(HttpHeader.ALLOW, worker.getAllowedMethods());\n }\n}\n\n/** 500 Internal Server Error response. */\nexport class InternalServerError extends HttpError {\n constructor(details?: string) {\n super(StatusCodes.INTERNAL_SERVER_ERROR, details);\n }\n}\n\n/** 501 Not Implemented error response. */\nexport class NotImplemented extends HttpError {\n constructor(details?: string) {\n super(StatusCodes.NOT_IMPLEMENTED, details);\n }\n}\n\n/** 501 Method Not Implemented error response for unsupported HTTP methods. */\nexport class MethodNotImplemented extends NotImplemented {\n constructor(worker: Worker) {\n super(`${worker.request.method} method not implemented.`);\n }\n}\n\n/** 503 Service Unavailable error response. */\nexport class ServiceUnavailable extends HttpError {\n constructor(details?: string) {\n super(StatusCodes.SERVICE_UNAVAILABLE, details);\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Method } from \"../constants/http\";\nimport { FetchHandler } from \"../interfaces/fetch-handler\";\nimport { Worker, WorkerClass } from \"../interfaces/worker\";\n\n/**\n * Provides the foundational structure for handling requests,\n * environment bindings, and the worker execution context.\n *\n * Features:\n * - Holds the current `Request` object (`request` getter).\n * - Provides access to environment bindings (`env` getter).\n * - Provides access to the worker execution context (`ctx` getter).\n * - Subclasses must implement `fetch()` to process the request.\n */\nexport abstract class BaseWorker implements Worker {\n constructor(\n private readonly _request: Request,\n private readonly _env: Env,\n private readonly _ctx: ExecutionContext,\n ) {}\n\n /** The Request object associated with this worker invocation */\n public get request(): Request {\n return this._request;\n }\n\n /** Environment bindings (e.g., KV, secrets, or other globals) */\n public get env(): Env {\n return this._env;\n }\n\n /** Execution context for background tasks or `waitUntil` */\n public get ctx(): ExecutionContext {\n return this._ctx;\n }\n\n /**\n * Dispatches the incoming request to the appropriate handler and produces a response.\n *\n * Subclasses must implement this method to define how the worker generates a `Response`\n * for the current request. This is the central point where request processing occurs.\n *\n * @returns A Promise that resolves to the `Response` for the request.\n */\n protected abstract dispatch(): Promise<Response>;\n\n public abstract getAllowedMethods(): Method[];\n\n /**\n * Creates a new instance of the current Worker subclass.\n *\n * @param request - The {@link Request} to pass to the new worker instance.\n * @returns A new worker instance of the same subclass as `this`.\n */\n protected create(request: Request): this {\n const ctor = this.constructor as WorkerClass<this>;\n return new ctor(request, this.env, this.ctx);\n }\n\n /**\n * Process the {@link Request} and produce a {@link Response}.\n *\n * @returns A {@link Response} promise for the {@link Request}.\n */\n public abstract fetch(): Promise<Response>;\n\n /**\n * **Ignite** your `Worker` implementation into a Cloudflare handler.\n *\n * @returns A `FetchHandler` that launches a new worker instance for each request.\n *\n * ```ts\n * export default MyWorker.ignite();\n * ```\n */\n public static ignite<W extends Worker>(this: WorkerClass<W>): FetchHandler {\n return {\n fetch: (request: Request, env: Env, ctx: ExecutionContext) =>\n new this(request, env, ctx).fetch(),\n };\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BaseWorker } from \"./base-worker\";\nimport { Middleware } from \"../middleware/middleware\";\n\n/** Internal base worker for handling middleware chains. */\nexport abstract class MiddlewareWorker extends BaseWorker {\n /** Middleware handlers registered for this worker. */\n protected readonly middlewares: Middleware[] = [];\n\n /**\n * Add a middleware instance to this worker.\n *\n * The middleware will run for every request handled by this worker,\n * in the order they are added.\n *\n * @param handler - The middleware to run.\n * @returns `this` to allow chaining multiple `.use()` calls.\n */\n public use(handler: Middleware): this {\n this.middlewares.push(handler);\n return this;\n }\n\n /**\n * Executes the middleware chain and dispatches the request.\n *\n * @returns The Response produced by the last middleware or `dispatch()`.\n */\n public override async fetch(): Promise<Response> {\n const chain = this.middlewares.reduceRight(\n (next, handler) => () => handler.handle(this, next),\n () => this.dispatch(),\n );\n return await chain();\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MethodNotAllowed, InternalServerError, MethodNotImplemented } from \"../errors\";\nimport { MiddlewareWorker } from \"./middleware-worker\";\nimport { Head, WorkerResponse } from \"../responses\";\nimport { Method, GET, HEAD, OPTIONS } from \"../constants/http\";\nimport { isMethod } from \"../utils/request\";\n\n/**\n * Basic worker class providing HTTP method dispatching and error handling.\n */\nexport abstract class BasicWorker extends MiddlewareWorker {\n /**\n * Entry point to handle a fetch request.\n */\n public override async fetch(): Promise<Response> {\n if (!this.isAllowed(this.request.method)) {\n return this.getResponse(MethodNotAllowed, this);\n }\n\n try {\n await this.init();\n return await super.fetch();\n } catch (error) {\n console.error(error);\n return this.getResponse(InternalServerError);\n }\n }\n\n /**\n * Dispatches the request to the method-specific handler.\n */\n protected override async dispatch(): Promise<Response> {\n const method = this.request.method as Method;\n const handler: Record<Method, () => Promise<Response>> = {\n GET: () => this.get(),\n PUT: () => this.put(),\n HEAD: () => this.head(),\n POST: () => this.post(),\n PATCH: () => this.patch(),\n DELETE: () => this.delete(),\n OPTIONS: () => this.options(),\n };\n\n return (handler[method] ?? (() => this.getResponse(MethodNotAllowed, this)))();\n }\n\n /**\n * Hook for subclasses to perform any initialization.\n */\n protected init(): void | Promise<void> {\n return;\n }\n\n /**\n * Checks if the given HTTP method is allowed for this worker.\n * @param method HTTP method string\n * @returns true if the method is allowed\n */\n public isAllowed(method: string): boolean {\n return isMethod(method) && this.getAllowedMethods().includes(method);\n }\n\n /** Override and implement this method for GET requests. */\n protected async get(): Promise<Response> {\n return this.getResponse(MethodNotImplemented, this);\n }\n\n /** Override and implement this method for PUT requests. */\n protected async put(): Promise<Response> {\n return this.getResponse(MethodNotImplemented, this);\n }\n\n /** Override and implement this method for POST requests. */\n protected async post(): Promise<Response> {\n return this.getResponse(MethodNotImplemented, this);\n }\n\n /** Override and implement this method for PATCH requests. */\n protected async patch(): Promise<Response> {\n return this.getResponse(MethodNotImplemented, this);\n }\n\n /** Override and implement this method for DELETE requests. */\n protected async delete(): Promise<Response> {\n return this.getResponse(MethodNotImplemented, this);\n }\n\n /** Override and implement this method for OPTIONS requests. */\n protected async options(): Promise<Response> {\n return this.getResponse(MethodNotImplemented, this);\n }\n\n /**\n * Default handler for HEAD requests.\n * Performs a GET request and removes the body for HEAD semantics.\n *\n * Usually does not need to be overridden as this behavior covers\n * standard HEAD requirements.\n */\n protected async head(): Promise<Response> {\n const worker = this.create(new Request(this.request, { method: GET }));\n return this.getResponse(Head, await worker.fetch());\n }\n\n /**\n * DEFAULT allowed HTTP methods for subclasses.\n *\n * These defaults were selected for getting started quickly and should be\n * overridden for each specific worker.\n */\n public getAllowedMethods(): Method[] {\n return [GET, HEAD, OPTIONS];\n }\n\n /**\n * Simplify and standardize {@link Response} creation by extending {@link WorkerResponse}\n * or any of its subclasses and passing to this method.\n *\n * Or directly use any of the built-in classes.\n *\n * ```ts\n * this.getResponse(TextResponse, \"Hello World!\")\n * ```\n *\n * @param ResponseClass The response class to instantiate\n * @param args Additional constructor arguments\n * @returns A Promise resolving to the {@link Response} object\n */\n protected async getResponse<\n Ctor extends new (...args: any[]) => { getResponse(): Promise<Response> },\n >(ResponseClass: Ctor, ...args: ConstructorParameters<Ctor>): Promise<Response> {\n return new ResponseClass(...args).getResponse();\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { match } from \"path-to-regexp\";\nimport { MatchedRoute, Route, PathParams, RouteTable } from \"./interfaces/route\";\nimport { Method } from \"./constants/http\";\n\n/**\n * Container for route definitions and matching logic.\n * Implements Iterable to allow iteration over all routes.\n */\nexport class Routes implements Iterable<Route> {\n /** Internal array of registered routes */\n private readonly routes: Route[] = [];\n\n /**\n * Add routes to the router.\n *\n * Accepts any iterable of [method, path, handler] tuples.\n * This includes arrays, Sets, or generators.\n *\n * @param routes - Iterable of route tuples to add.\n */\n public add(routes: RouteTable): void {\n for (const [method, path, handler] of routes) {\n const matcher = match<PathParams>(path);\n this.routes.push({ method, matcher, handler });\n }\n }\n\n /**\n * Attempt to match a URL against the registered routes.\n *\n * @param method - HTTP method of the request\n * @param url - Full URL string to match against\n * @returns A MatchedRoute object if a route matches, otherwise null\n */\n public match(method: Method, url: string): MatchedRoute | null {\n const pathname = new URL(url).pathname;\n\n for (const route of this) {\n if (route.method !== method) continue;\n\n const found = route.matcher(pathname);\n if (found) return { route, params: found.params };\n }\n\n return null;\n }\n\n /**\n * Iterate over all registered routes.\n */\n public *[Symbol.iterator](): Iterator<Route> {\n yield* this.routes;\n }\n}\n","/*\n * Copyright (C) 2025 Ty Busby\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BasicWorker } from \"./basic-worker\";\nimport { NotFound } from \"../errors\";\nimport { Routes } from \"../routes\";\nimport { RouteHandler, RouteTable } from \"../interfaces/route\";\nimport { WorkerClass } from \"../interfaces/worker\";\nimport { BaseWorker } from \"./base-worker\";\nimport { Method } from \"../constants/http\";\n\n/**\n * Base worker supporting route-based request handling.\n *\n * Subclass `RouteWorker` to define a worker with multiple route handlers.\n *\n * Routes can be registered individually via `route()` or in bulk via `routes()`.\n */\nexport abstract class RouteWorker extends BasicWorker {\n /** Internal table of registered routes. */\n private readonly _routes: Routes = new Routes();\n\n /**\n * Registers a single new route in the worker.\n *\n * When a request matches the specified method and path, the provided handler\n * will be executed. The handler can be either:\n * - A function that receives URL parameters, or\n * - A Worker subclass that will handle the request.\n *\n * @param method - HTTP method for the route (GET, POST, etc.).\n * @param path - URL path pattern (Express-style, e.g., \"/users/:id\").\n * @param handler - The function or Worker class to run when the route matches.\n * @returns The current worker instance, allowing method chaining.\n */\n protected route(method: Method, path: string, handler: RouteHandler): this {\n this.routes([[method, path, handler]]);\n return this;\n }\n\n /**\n * Registers multiple routes at once in the worker.\n *\n * Each route should be a tuple `[method, path, handler]` where:\n * - `method` - HTTP method for the route (GET, POST, etc.).\n * - `path` - URL path pattern (Express-style, e.g., \"/users/:id\").\n * - `handler` - A function that receives URL parameters or a Worker subclass\n * that will handle the request.\n *\n * @param routes - An iterable of routes to register. Each item is a `[method, path, handler]` tuple.\n * @returns The current worker instance, allowing method chaining.\n */\n protected routes(routes: RouteTable): this {\n this._routes.add(routes);\n return this;\n }\n\n /**\n * Matches the incoming request against registered routes and dispatches it.\n *\n * If a route is found:\n * - If the handler is a Worker class, a new instance is created and its `fetch()` is called.\n * - If the handler is a callback function, it is invoked with the extracted path parameters.\n *\n * If no route matches, the request is passed to the parent `dispatch()` handler.\n *\n * @returns A `Promise<Response>` from the matched handler or parent dispatch.\n */\n protected override async dispatch(): Promise<Response> {\n const found = this._routes.match(this.request.method as Method, this.request.url);\n if (!found) return super.dispatch();\n\n const { handler } = found.route;\n if (RouteWorker.isWorkerClass(handler)) {\n return new handler(this.request, this.env, this.ctx).fetch();\n }\n return handler.call(this, found.params);\n }\n\n /**\n * Runtime type guard to check if a given handler is a Worker class.\n *\n * A Worker class is any class that extends `BaseWorker`.\n *\n * @param handler - The constructor function to test.\n * @returns `true` if `handler` is a subclass of `BaseWorker` at runtime, `false` otherwise.\n */\n private static isWorkerClass(handler: RouteHandler): handler is WorkerClass {\n return BaseWorker.prototype.isPrototypeOf(handler.prototype);\n }\n\n protected override async get(): Promise<Response> {\n return this.getResponse(NotFound);\n }\n\n protected override async put(): Promise<Response> {\n return this.getResponse(NotFound);\n }\n\n protected override async post(): Promise<Response> {\n return this.getResponse(NotFound);\n }\n\n protected override async patch(): Promise<Response> {\n return this.getResponse(NotFound);\n }\n\n protected override async delete(): Promise<Response> {\n return this.getResponse(NotFound);\n }\n\n protected override async options(): Promise<Response> {\n return this.getResponse(NotFound);\n }\n}\n"],"mappings":"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","names":["HttpHeader","Method","MediaType","cache","StatusCodes","StatusCodes","cache","cors","options","getReasonPhrase","StatusCodes","getReasonPhrase","StatusCodes"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adonix.org/cloud-spark",
3
- "version": "0.0.143",
3
+ "version": "0.0.144",
4
4
  "description": "Ignite your Cloudflare Workers with a type-safe library for rapid development.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",