@adonix.org/cloud-spark 0.0.94 → 0.0.97

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.js CHANGED
@@ -15,14 +15,15 @@ var CacheControl = {
15
15
  var HttpHeader;
16
16
  ((HttpHeader2) => {
17
17
  HttpHeader2.VARY = "Vary";
18
+ HttpHeader2.ALLOW = "Allow";
18
19
  HttpHeader2.CONTENT_TYPE = "Content-Type";
19
20
  HttpHeader2.CACHE_CONTROL = "Cache-Control";
20
- HttpHeader2.X_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options";
21
21
  HttpHeader2.X_FRAME_OPTIONS = "X-Frame-Options";
22
- HttpHeader2.STRICT_TRANSPORT_SECURITY = "Strict-Transport-Security";
23
- HttpHeader2.CONTENT_SECURITY_POLICY = "Content-Security-Policy";
22
+ HttpHeader2.X_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options";
24
23
  HttpHeader2.REFERRER_POLICY = "Referrer-Policy";
25
24
  HttpHeader2.PERMISSIONS_POLICY = "Permissions-Policy";
25
+ HttpHeader2.CONTENT_SECURITY_POLICY = "Content-Security-Policy";
26
+ HttpHeader2.STRICT_TRANSPORT_SECURITY = "Strict-Transport-Security";
26
27
  HttpHeader2.NOSNIFF = "nosniff";
27
28
  HttpHeader2.ORIGIN = "Origin";
28
29
  })(HttpHeader || (HttpHeader = {}));
@@ -43,10 +44,10 @@ var Time = {
43
44
  var Method = /* @__PURE__ */ ((Method4) => {
44
45
  Method4["GET"] = "GET";
45
46
  Method4["PUT"] = "PUT";
47
+ Method4["HEAD"] = "HEAD";
46
48
  Method4["POST"] = "POST";
47
49
  Method4["PATCH"] = "PATCH";
48
50
  Method4["DELETE"] = "DELETE";
49
- Method4["HEAD"] = "HEAD";
50
51
  Method4["OPTIONS"] = "OPTIONS";
51
52
  return Method4;
52
53
  })(Method || {});
@@ -107,22 +108,22 @@ var MediaType = /* @__PURE__ */ ((MediaType2) => {
107
108
  return MediaType2;
108
109
  })(MediaType || {});
109
110
  var ADD_CHARSET = /* @__PURE__ */ new Set([
110
- "text/plain" /* PLAIN_TEXT */,
111
- "text/html" /* HTML */,
112
111
  "text/css" /* CSS */,
113
112
  "text/csv" /* CSV */,
114
- "text/markdown" /* MARKDOWN */,
115
113
  "text/xml" /* XML */,
114
+ "image/svg+xml" /* SVG */,
115
+ "text/html" /* HTML */,
116
116
  "application/json" /* JSON */,
117
- "application/xml" /* XML_APP */,
118
- "application/x-www-form-urlencoded" /* FORM_URLENCODED */,
119
117
  "application/x-ndjson" /* NDJSON */,
118
+ "application/xml" /* XML_APP */,
119
+ "text/markdown" /* MARKDOWN */,
120
120
  "text/richtext" /* RICH_TEXT */,
121
- "image/svg+xml" /* SVG */
121
+ "text/plain" /* PLAIN_TEXT */,
122
+ "application/x-www-form-urlencoded" /* FORM_URLENCODED */
122
123
  ]);
123
124
  function setHeader(headers, key, value) {
124
125
  const raw = Array.isArray(value) ? value : [value];
125
- const values = Array.from(new Set(raw.map((v) => v.trim()))).filter((v) => v.length);
126
+ const values = Array.from(new Set(raw.map((v) => v.trim()))).filter((v) => v.length).sort();
126
127
  if (!values.length) {
127
128
  headers.delete(key);
128
129
  return;
@@ -156,217 +157,79 @@ function getOrigin(request) {
156
157
  // src/cors.ts
157
158
  var Cors;
158
159
  ((Cors2) => {
160
+ Cors2.MAX_AGE = "Access-Control-Max-Age";
159
161
  Cors2.ALLOW_ORIGIN = "Access-Control-Allow-Origin";
160
- Cors2.ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
161
- Cors2.EXPOSE_HEADERS = "Access-Control-Expose-Headers";
162
162
  Cors2.ALLOW_HEADERS = "Access-Control-Allow-Headers";
163
163
  Cors2.ALLOW_METHODS = "Access-Control-Allow-Methods";
164
- Cors2.MAX_AGE = "Access-Control-Max-Age";
164
+ Cors2.EXPOSE_HEADERS = "Access-Control-Expose-Headers";
165
+ Cors2.ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials";
165
166
  Cors2.ALLOW_ALL_ORIGINS = "*";
166
167
  })(Cors || (Cors = {}));
167
168
  function addCorsHeaders(origin, cors, headers) {
168
169
  deleteCorsHeaders(headers);
169
- if (!origin) return;
170
+ if (!origin || origin.trim() === "") return;
170
171
  if (cors.allowAnyOrigin()) {
171
172
  setHeader(headers, Cors.ALLOW_ORIGIN, Cors.ALLOW_ALL_ORIGINS);
172
173
  } else if (cors.getAllowOrigins().includes(origin)) {
173
174
  setHeader(headers, Cors.ALLOW_ORIGIN, origin);
174
175
  setHeader(headers, Cors.ALLOW_CREDENTIALS, "true");
175
- mergeHeader(headers, HttpHeader.VARY, HttpHeader.ORIGIN);
176
176
  }
177
- mergeHeader(headers, Cors.EXPOSE_HEADERS, cors.getExposeHeaders());
178
- setHeader(headers, Cors.ALLOW_HEADERS, cors.getAllowHeaders());
179
- setHeader(headers, Cors.ALLOW_METHODS, cors.getAllowMethods());
180
177
  setHeader(headers, Cors.MAX_AGE, String(cors.getMaxAge()));
178
+ setHeader(headers, Cors.ALLOW_METHODS, cors.getAllowMethods());
179
+ setHeader(headers, Cors.ALLOW_HEADERS, cors.getAllowHeaders());
180
+ mergeHeader(headers, Cors.EXPOSE_HEADERS, cors.getExposeHeaders());
181
181
  }
182
182
  function deleteCorsHeaders(headers) {
183
+ headers.delete(Cors.MAX_AGE);
183
184
  headers.delete(Cors.ALLOW_ORIGIN);
184
- headers.delete(Cors.ALLOW_CREDENTIALS);
185
- headers.delete(Cors.EXPOSE_HEADERS);
185
+ headers.delete(Cors.ALLOW_HEADERS);
186
186
  headers.delete(Cors.ALLOW_METHODS);
187
- headers.delete(Cors.MAX_AGE);
187
+ headers.delete(Cors.EXPOSE_HEADERS);
188
+ headers.delete(Cors.ALLOW_CREDENTIALS);
188
189
  }
189
190
 
190
- // src/base-worker.ts
191
- var BaseWorker = class {
192
- constructor(_request, _env, _ctx) {
193
- this._request = _request;
194
- this._env = _env;
195
- this._ctx = _ctx;
196
- }
197
- /** The Request object associated with this worker invocation */
198
- get request() {
199
- return this._request;
200
- }
201
- /** Environment bindings (e.g., KV, secrets, or other globals) */
202
- get env() {
203
- return this._env;
204
- }
205
- /** Optional execution context for background tasks or `waitUntil` */
206
- get ctx() {
207
- return this._ctx;
208
- }
209
- /**
210
- * Creates a new instance of the current Worker subclass.
211
- *
212
- * @param request - The request to pass to the new worker instance.
213
- * @returns A new worker instance of the same subclass as `this`.
214
- */
215
- createWorker(request) {
216
- const ctor = this.constructor;
217
- return new ctor(request, this.env, this.ctx);
218
- }
191
+ // src/routes.ts
192
+ var Route = class {
219
193
  /**
220
- * **Ignite** your `Worker` implementation into a Cloudflare-compatible handler.
221
- *
222
- * @returns A `FetchHandler` that launches a new worker instance for each request.
223
- *
224
- * @example
225
- * ```ts
226
- * export default MyWorker.ignite();
227
- * ```
194
+ * @param pattern - A RegExp or string used to match the request path
195
+ * @param callback - Function to handle requests matching the pattern
228
196
  */
229
- static ignite() {
230
- return {
231
- fetch: (req, env, ctx) => new this(req, env, ctx).fetch()
232
- };
233
- }
234
- };
235
-
236
- // src/cors-worker.ts
237
- var CorsWorker = class extends BaseWorker {
238
- getAllowOrigins() {
239
- return ["*"];
240
- }
241
- allowAnyOrigin() {
242
- return this.getAllowOrigins().includes("*");
243
- }
244
- getAllowMethods() {
245
- return ["GET" /* GET */, "OPTIONS" /* OPTIONS */, "HEAD" /* HEAD */];
246
- }
247
- getAllowHeaders() {
248
- return ["Content-Type"];
249
- }
250
- getExposeHeaders() {
251
- return [];
252
- }
253
- getMaxAge() {
254
- return Time.Week;
197
+ constructor(pattern, callback) {
198
+ this.callback = callback;
199
+ this.pattern = new RegExp(pattern);
255
200
  }
201
+ pattern;
256
202
  };
257
-
258
- // src/cache-worker.ts
259
- var CacheWorker = class extends CorsWorker {
260
- /**
261
- * Returns the cache key for the current request.
262
- *
263
- * Behavior:
264
- * - By default, returns the normalized request URL.
265
- * - Query parameters are normalized so that the order does not affect the cache key.
266
- * For example, `?a=1&b=2` and `?b=2&a=1` produce the same cache key.
267
- *
268
- * Subclasses may override this method to implement custom cache key strategies.
269
- *
270
- * @returns {URL | RequestInfo} The URL or RequestInfo used as the cache key.
271
- */
272
- getCacheKey() {
273
- return normalizeUrl(this.request.url);
274
- }
275
- /**
276
- * Retrieves a cached Response for the current request, if one exists.
277
- *
278
- * Behavior:
279
- * - Only GET requests are considered.
280
- * - Returns a new Response with dynamic CORS headers applied via `addCacheHeaders`.
281
- * - Returns `undefined` if no cached response is found.
282
- * - Cloudflare dynamic headers (`CF-Cache-Status`, `Age`, `Connection`, etc.) will
283
- * always be present on the returned response, even though they are not stored in the cache.
284
- *
285
- * @param {string} [cacheName] Optional named cache; defaults to `caches.default`.
286
- * @returns {Promise<Response | undefined>} A Response with CORS headers, or undefined.
287
- * @see {@link setCachedResponse}
288
- * @see {@link getCacheKey}
289
- */
290
- async getCachedResponse(cacheName) {
291
- if (this.request.method !== "GET" /* GET */) return;
292
- const cache = cacheName ? await caches.open(cacheName) : caches.default;
293
- const response = await cache.match(this.getCacheKey());
294
- return response ? this.addCacheHeaders(response) : void 0;
295
- }
296
- /**
297
- * Stores a Response in the cache for the current request.
298
- *
299
- * Behavior:
300
- * - Only caches successful GET responses (`response.ok === true`).
301
- * - Strips headers via `removeCacheHeaders` before storing.
302
- * - Uses `ctx.waitUntil` to perform caching asynchronously without blocking the response.
303
- * - All other origin headers (e.g., Cache-Control, Expires) are preserved.
304
- *
305
- * @param {Response} response The Response to cache.
306
- * @param {string} [cacheName] Optional named cache; defaults to `caches.default`.
307
- * @see {@link getCachedResponse}
308
- * @see {@link getCacheKey}
309
- */
310
- async setCachedResponse(response, cacheName) {
311
- if (!response.ok) return;
312
- if (this.request.method !== "GET" /* GET */) return;
313
- const cache = cacheName ? await caches.open(cacheName) : caches.default;
314
- this.ctx.waitUntil(
315
- cache.put(this.getCacheKey(), this.removeCacheHeaders(response.clone()))
316
- );
317
- }
318
- /**
319
- * Adds headers to a cached response.
320
- *
321
- * @param {Response} cached The cached Response.
322
- * @returns {Response} A new Response with dynamic CORS headers applied.
323
- * @see {@link removeCacheHeaders}
324
- */
325
- addCacheHeaders(cached) {
326
- const headers = new Headers(cached.headers);
327
- addCorsHeaders(getOrigin(this.request), this, headers);
328
- return new Response(cached.body, {
329
- status: cached.status,
330
- statusText: cached.statusText,
331
- headers
332
- });
333
- }
203
+ var Routes = class {
204
+ map = /* @__PURE__ */ new Map();
334
205
  /**
335
- * Removes headers that should not be stored in the cache (currently only CORS headers).
206
+ * Adds a route to the collection under the given HTTP method.
336
207
  *
337
- * @param {Response} response The Response to clean before caching.
338
- * @returns {Response} A new Response with excluded headers removed.
339
- * @see {@link addCacheHeaders}
208
+ * @param method - HTTP method (GET, POST, etc.)
209
+ * @param route - Route instance to add
210
+ * @returns The Routes instance (for chaining)
340
211
  */
341
- removeCacheHeaders(response) {
342
- const excludeSet = new Set(this.excludeCacheHeaders().map((h) => h.toLowerCase()));
343
- const headers = new Headers();
344
- for (const [key, value] of response.headers) {
345
- if (!excludeSet.has(key)) {
346
- headers.set(key, value);
347
- }
212
+ add(method, route) {
213
+ const existing = this.map.get(method);
214
+ if (existing) {
215
+ existing.push(route);
216
+ } else {
217
+ this.map.set(method, [route]);
348
218
  }
349
- return new Response(response.body, {
350
- status: response.status,
351
- statusText: response.statusText,
352
- headers
353
- });
219
+ return this;
354
220
  }
355
221
  /**
356
- * Returns the list of headers to exclude from the cached response.
357
- * By default, excludes only dynamic CORS headers.
222
+ * Finds the first route that matches the given method and URL.
358
223
  *
359
- * @returns {string[]} Array of header names to exclude.
360
- * @see {@link removeCacheHeaders}
224
+ * @param method - HTTP method of the request
225
+ * @param url - Full URL string of the request
226
+ * @returns The first matching Route, or undefined if none match
361
227
  */
362
- excludeCacheHeaders() {
363
- return [
364
- Cors.ALLOW_ORIGIN,
365
- Cors.ALLOW_CREDENTIALS,
366
- Cors.EXPOSE_HEADERS,
367
- Cors.ALLOW_METHODS,
368
- Cors.MAX_AGE
369
- ];
228
+ get(method, url) {
229
+ const routes = this.map.get(method);
230
+ if (!routes) return void 0;
231
+ const pathname = new URL(url).pathname;
232
+ return routes.find(({ pattern }) => pattern.test(pathname));
370
233
  }
371
234
  };
372
235
 
@@ -407,6 +270,9 @@ var CorsResponse = class extends BaseResponse {
407
270
  }
408
271
  addCorsHeaders() {
409
272
  addCorsHeaders(this.getOrigin(), this.worker, this.headers);
273
+ if (!this.worker.allowAnyOrigin()) {
274
+ mergeHeader(this.headers, HttpHeader.VARY, HttpHeader.ORIGIN);
275
+ }
410
276
  }
411
277
  getOrigin() {
412
278
  return getOrigin(this.worker.request);
@@ -478,7 +344,7 @@ var Head = class extends WorkerResponse {
478
344
  var Options = class extends SuccessResponse {
479
345
  constructor(worker) {
480
346
  super(worker, null, void 0, StatusCodes2.NO_CONTENT);
481
- this.setHeader("Allow", this.worker.getAllowMethods());
347
+ this.setHeader(HttpHeader.ALLOW, this.worker.getAllowMethods());
482
348
  }
483
349
  };
484
350
  var HttpError = class extends JsonResponse {
@@ -519,9 +385,13 @@ var NotFound = class extends HttpError {
519
385
  }
520
386
  };
521
387
  var MethodNotAllowed = class extends HttpError {
522
- constructor(worker, method) {
523
- super(worker, StatusCodes2.METHOD_NOT_ALLOWED, `${method} method not allowed.`);
524
- this.setHeader("Allow", this.worker.getAllowMethods());
388
+ constructor(worker) {
389
+ super(
390
+ worker,
391
+ StatusCodes2.METHOD_NOT_ALLOWED,
392
+ `${worker.request.method} method not allowed.`
393
+ );
394
+ this.setHeader(HttpHeader.ALLOW, this.worker.getAllowMethods());
525
395
  }
526
396
  get json() {
527
397
  return {
@@ -541,8 +411,8 @@ var NotImplemented = class extends HttpError {
541
411
  }
542
412
  };
543
413
  var MethodNotImplemented = class extends NotImplemented {
544
- constructor(worker, method) {
545
- super(worker, `${method} method not implemented.`);
414
+ constructor(worker) {
415
+ super(worker, `${worker.request.method} method not implemented.`);
546
416
  }
547
417
  };
548
418
  var ServiceUnavailable = class extends HttpError {
@@ -551,11 +421,194 @@ var ServiceUnavailable = class extends HttpError {
551
421
  }
552
422
  };
553
423
 
424
+ // src/base-worker.ts
425
+ var BaseWorker = class {
426
+ constructor(_request, _env, _ctx) {
427
+ this._request = _request;
428
+ this._env = _env;
429
+ this._ctx = _ctx;
430
+ }
431
+ /** The Request object associated with this worker invocation */
432
+ get request() {
433
+ return this._request;
434
+ }
435
+ /** Environment bindings (e.g., KV, secrets, or other globals) */
436
+ get env() {
437
+ return this._env;
438
+ }
439
+ /** Execution context for background tasks or `waitUntil` */
440
+ get ctx() {
441
+ return this._ctx;
442
+ }
443
+ /**
444
+ * Creates a new instance of the current Worker subclass.
445
+ *
446
+ * @param request - The {@link Request} to pass to the new worker instance.
447
+ * @returns A new worker instance of the same subclass as `this`.
448
+ */
449
+ createWorker(request) {
450
+ const ctor = this.constructor;
451
+ return new ctor(request, this.env, this.ctx);
452
+ }
453
+ /**
454
+ * **Ignite** your `Worker` implementation into a Cloudflare-compatible handler.
455
+ *
456
+ * @returns A `FetchHandler` that launches a new worker instance for each request.
457
+ *
458
+ * @example
459
+ * ```ts
460
+ * export default MyWorker.ignite();
461
+ * ```
462
+ */
463
+ static ignite() {
464
+ return {
465
+ fetch: (req, env, ctx) => new this(req, env, ctx).fetch()
466
+ };
467
+ }
468
+ };
469
+
470
+ // src/cors-worker.ts
471
+ var CorsWorker = class extends BaseWorker {
472
+ getAllowOrigins() {
473
+ return ["*"];
474
+ }
475
+ allowAnyOrigin() {
476
+ return this.getAllowOrigins().includes("*");
477
+ }
478
+ getAllowMethods() {
479
+ return ["GET" /* GET */, "HEAD" /* HEAD */, "OPTIONS" /* OPTIONS */];
480
+ }
481
+ getAllowHeaders() {
482
+ return ["Content-Type"];
483
+ }
484
+ getExposeHeaders() {
485
+ return [];
486
+ }
487
+ getMaxAge() {
488
+ return Time.Week;
489
+ }
490
+ };
491
+
492
+ // src/cache-worker.ts
493
+ var CacheWorker = class extends CorsWorker {
494
+ /**
495
+ * Returns the cache key for the current request.
496
+ *
497
+ * Behavior:
498
+ * - By default, returns the normalized request URL.
499
+ * - Query parameters are normalized so that the order does not affect the cache key.
500
+ * For example, `?a=1&b=2` and `?b=2&a=1` produce the same cache key.
501
+ *
502
+ * Subclasses may override this method to implement custom cache key strategies.
503
+ *
504
+ * @returns {URL | RequestInfo} The URL or RequestInfo used as the cache key.
505
+ */
506
+ getCacheKey() {
507
+ return normalizeUrl(this.request.url);
508
+ }
509
+ /**
510
+ * Retrieves a cached Response for the current request, if one exists.
511
+ *
512
+ * Behavior:
513
+ * - Only GET requests are considered.
514
+ * - Returns a new Response with dynamic CORS headers applied via `addCacheHeaders`.
515
+ * - Returns `undefined` if no cached response is found.
516
+ * - Cloudflare dynamic headers (`CF-Cache-Status`, `Age`, `Connection`, etc.) will
517
+ * always be present on the returned response, even though they are not stored in the cache.
518
+ *
519
+ * @param {string} [cacheName] Optional named cache; defaults to `caches.default`.
520
+ * @returns {Promise<Response | undefined>} A Response with CORS headers, or undefined.
521
+ * @see {@link setCachedResponse}
522
+ * @see {@link getCacheKey}
523
+ */
524
+ async getCachedResponse(cacheName) {
525
+ if (this.request.method !== "GET" /* GET */) return;
526
+ const cache = cacheName ? await caches.open(cacheName) : caches.default;
527
+ const response = await cache.match(this.getCacheKey());
528
+ return response ? this.addCacheHeaders(response) : void 0;
529
+ }
530
+ /**
531
+ * Stores a Response in the cache for the current request.
532
+ *
533
+ * Behavior:
534
+ * - Only caches successful GET responses (`response.ok === true`).
535
+ * - Strips headers via `removeCacheHeaders` before storing.
536
+ * - Uses `ctx.waitUntil` to perform caching asynchronously without blocking the response.
537
+ * - All other origin headers (e.g., Cache-Control, Expires) are preserved.
538
+ *
539
+ * @param {Response} response The Response to cache.
540
+ * @param {string} [cacheName] Optional named cache; defaults to `caches.default`.
541
+ * @see {@link getCachedResponse}
542
+ * @see {@link getCacheKey}
543
+ */
544
+ async setCachedResponse(response, cacheName) {
545
+ if (!response.ok) return;
546
+ if (this.request.method !== "GET" /* GET */) return;
547
+ const cache = cacheName ? await caches.open(cacheName) : caches.default;
548
+ this.ctx.waitUntil(
549
+ cache.put(this.getCacheKey(), this.removeCacheHeaders(response.clone()))
550
+ );
551
+ }
552
+ /**
553
+ * Adds headers to a cached response.
554
+ *
555
+ * @param {Response} cached The cached Response.
556
+ * @returns {Response} A new Response with dynamic CORS headers applied.
557
+ * @see {@link removeCacheHeaders}
558
+ */
559
+ addCacheHeaders(cached) {
560
+ const headers = new Headers(cached.headers);
561
+ addCorsHeaders(getOrigin(this.request), this, headers);
562
+ return new Response(cached.body, {
563
+ status: cached.status,
564
+ statusText: cached.statusText,
565
+ headers
566
+ });
567
+ }
568
+ /**
569
+ * Removes headers that should not be stored in the cache (currently only CORS headers).
570
+ *
571
+ * @param {Response} response The Response to clean before caching.
572
+ * @returns {Response} A new Response with excluded headers removed.
573
+ * @see {@link addCacheHeaders}
574
+ */
575
+ removeCacheHeaders(response) {
576
+ const excludeSet = new Set(this.excludeCacheHeaders().map((h) => h.toLowerCase()));
577
+ const headers = new Headers();
578
+ for (const [key, value] of response.headers) {
579
+ if (!excludeSet.has(key)) {
580
+ headers.set(key, value);
581
+ }
582
+ }
583
+ return new Response(response.body, {
584
+ status: response.status,
585
+ statusText: response.statusText,
586
+ headers
587
+ });
588
+ }
589
+ /**
590
+ * Returns the list of headers to exclude from the cached response.
591
+ * By default, excludes only dynamic CORS headers.
592
+ *
593
+ * @returns {string[]} Array of header names to exclude.
594
+ * @see {@link removeCacheHeaders}
595
+ */
596
+ excludeCacheHeaders() {
597
+ return [
598
+ Cors.ALLOW_ORIGIN,
599
+ Cors.ALLOW_CREDENTIALS,
600
+ Cors.EXPOSE_HEADERS,
601
+ Cors.ALLOW_METHODS,
602
+ Cors.MAX_AGE
603
+ ];
604
+ }
605
+ };
606
+
554
607
  // src/basic-worker.ts
555
608
  var BasicWorker = class extends CacheWorker {
556
609
  async fetch() {
557
610
  if (!this.isAllowed(this.request.method)) {
558
- return this.getResponse(MethodNotAllowed, this.request.method);
611
+ return this.getResponse(MethodNotAllowed);
559
612
  }
560
613
  try {
561
614
  return await this.dispatch();
@@ -568,34 +621,37 @@ var BasicWorker = class extends CacheWorker {
568
621
  const handler = {
569
622
  GET: () => this.get(),
570
623
  PUT: () => this.put(),
624
+ HEAD: () => this.head(),
571
625
  POST: () => this.post(),
572
626
  PATCH: () => this.patch(),
573
627
  DELETE: () => this.delete(),
574
- HEAD: () => this.head(),
575
628
  OPTIONS: () => this.options()
576
629
  };
577
- return (handler[method] ?? (() => this.getResponse(MethodNotAllowed, method)))();
630
+ return (handler[method] ?? (() => this.getResponse(MethodNotAllowed)))();
631
+ }
632
+ isAllowed(method) {
633
+ return isMethod(method) && this.getAllowMethods().includes(method);
578
634
  }
579
635
  async get() {
580
- return this.getResponse(MethodNotImplemented, "GET" /* GET */);
636
+ return this.getResponse(MethodNotImplemented);
581
637
  }
582
638
  async put() {
583
- return this.getResponse(MethodNotImplemented, "PUT" /* PUT */);
639
+ return this.getResponse(MethodNotImplemented);
584
640
  }
585
641
  async post() {
586
- return this.getResponse(MethodNotImplemented, "POST" /* POST */);
642
+ return this.getResponse(MethodNotImplemented);
587
643
  }
588
644
  async patch() {
589
- return this.getResponse(MethodNotImplemented, "PATCH" /* PATCH */);
645
+ return this.getResponse(MethodNotImplemented);
590
646
  }
591
647
  async delete() {
592
- return this.getResponse(MethodNotImplemented, "DELETE" /* DELETE */);
648
+ return this.getResponse(MethodNotImplemented);
593
649
  }
594
650
  async options() {
595
651
  return this.getResponse(Options);
596
652
  }
597
653
  async head() {
598
- const worker = this.createWorker(new Request(this.request, { method: "GET" }));
654
+ const worker = this.createWorker(new Request(this.request, { method: "GET" /* GET */ }));
599
655
  return this.getResponse(Head, await worker.fetch());
600
656
  }
601
657
  async getResponse(ResponseClass, ...args) {
@@ -603,58 +659,10 @@ var BasicWorker = class extends CacheWorker {
603
659
  this.setCachedResponse(response);
604
660
  return response;
605
661
  }
606
- isAllowed(method) {
607
- return isMethod(method) && this.getAllowMethods().includes(method);
608
- }
609
- };
610
-
611
- // src/routes.ts
612
- var Route = class {
613
- /**
614
- * @param pattern - A RegExp or string used to match the request path
615
- * @param callback - Function to handle requests matching the pattern
616
- */
617
- constructor(pattern, callback) {
618
- this.callback = callback;
619
- this.pattern = new RegExp(pattern);
620
- }
621
- pattern;
622
- };
623
- var Routes = class {
624
- map = /* @__PURE__ */ new Map();
625
- /**
626
- * Adds a route to the collection under the given HTTP method.
627
- *
628
- * @param method - HTTP method (GET, POST, etc.)
629
- * @param route - Route instance to add
630
- * @returns The Routes instance (for chaining)
631
- */
632
- add(method, route) {
633
- const existing = this.map.get(method);
634
- if (existing) {
635
- existing.push(route);
636
- } else {
637
- this.map.set(method, [route]);
638
- }
639
- return this;
640
- }
641
- /**
642
- * Finds the first route that matches the given method and URL.
643
- *
644
- * @param method - HTTP method of the request
645
- * @param url - Full URL string of the request
646
- * @returns The first matching Route, or undefined if none match
647
- */
648
- get(method, url) {
649
- const routes = this.map.get(method);
650
- if (!routes) return void 0;
651
- const pathname = new URL(url).pathname;
652
- return routes.find(({ pattern }) => pattern.test(pathname));
653
- }
654
662
  };
655
663
 
656
- // src/routed-worker.ts
657
- var RoutedWorker = class extends BasicWorker {
664
+ // src/route-worker.ts
665
+ var RouteWorker = class extends BasicWorker {
658
666
  routes = new Routes();
659
667
  initialize(routes) {
660
668
  routes.forEach(([method, pattern, callback]) => {
@@ -708,7 +716,7 @@ export {
708
716
  NotImplemented,
709
717
  Options,
710
718
  Route,
711
- RoutedWorker,
719
+ RouteWorker,
712
720
  Routes,
713
721
  ServiceUnavailable,
714
722
  StatusCodes,