@adonix.org/cloud-spark 0.0.71 → 0.0.73

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
@@ -2,6 +2,36 @@ import { StatusCodes } from 'http-status-codes';
2
2
  export { StatusCodes } from 'http-status-codes';
3
3
  import CacheLib from 'cache-control-parser';
4
4
 
5
+ interface Worker {
6
+ fetch(): Promise<Response>;
7
+ }
8
+
9
+ declare abstract class BaseWorker implements Worker {
10
+ private readonly _request;
11
+ private readonly _env;
12
+ private readonly _ctx?;
13
+ constructor(_request: Request, _env?: Env, _ctx?: ExecutionContext | undefined);
14
+ protected get request(): Request;
15
+ protected get env(): Env;
16
+ protected get ctx(): ExecutionContext | undefined;
17
+ abstract fetch(): Promise<Response>;
18
+ }
19
+
20
+ declare abstract class CacheWorker extends BaseWorker {
21
+ protected getCacheKey(): string;
22
+ protected getCachedResponse(): Promise<Response | undefined>;
23
+ protected setCachedResponse(response: Response): void;
24
+ }
25
+
26
+ /**
27
+ * https://github.com/etienne-martin/cache-control-parser
28
+ */
29
+
30
+ type CacheControl = CacheLib.CacheControl;
31
+ declare const CacheControl: {
32
+ parse: (cacheControlHeader: string) => CacheLib.CacheControl;
33
+ stringify: (cacheControl: CacheLib.CacheControl) => string;
34
+ };
5
35
  declare const Time: {
6
36
  readonly Second: 1;
7
37
  readonly Minute: 60;
@@ -68,16 +98,17 @@ declare enum MimeType {
68
98
  }
69
99
  declare function setHeader(headers: Headers, key: string, value: string | string[]): void;
70
100
  declare function mergeHeader(headers: Headers, key: string, value: string | string[]): void;
71
-
72
101
  /**
73
- * https://github.com/etienne-martin/cache-control-parser
102
+ * Normalizes a URL string for use as a consistent cache key.
103
+ *
104
+ * - Sorts query parameters alphabetically so `?b=2&a=1` and `?a=1&b=2` are treated the same.
105
+ * - Strips fragment identifiers (`#...`) since they are not sent in HTTP requests.
106
+ * - Leaves protocol, host, path, and query values intact.
107
+ *
108
+ * @param url The original URL string to normalize.
109
+ * @returns A normalized URL string suitable for hashing or direct cache key use.
74
110
  */
75
-
76
- type CacheControl = CacheLib.CacheControl;
77
- declare const CacheControl: {
78
- parse: (cacheControlHeader: string) => CacheLib.CacheControl;
79
- stringify: (cacheControl: CacheLib.CacheControl) => string;
80
- };
111
+ declare function normalizeUrl(url: string): string;
81
112
 
82
113
  interface CorsProvider {
83
114
  getOrigin(): string | null;
@@ -173,16 +204,9 @@ declare class ServiceUnavailable extends HttpError {
173
204
  constructor(cors: CorsProvider, details?: string);
174
205
  }
175
206
 
176
- declare abstract class BasicWorker implements CorsProvider {
177
- private readonly _request;
178
- private readonly _env;
179
- private readonly _ctx?;
180
- constructor(_request: Request, _env?: Env, _ctx?: ExecutionContext | undefined);
181
- protected get request(): Request;
182
- protected get env(): Env;
183
- protected get ctx(): ExecutionContext | undefined;
207
+ declare abstract class BasicWorker extends CacheWorker implements CorsProvider {
184
208
  fetch(): Promise<Response>;
185
- protected dispatch(request: Request): Promise<Response>;
209
+ protected dispatch(request?: Request): Promise<Response>;
186
210
  protected get(): Promise<Response>;
187
211
  protected put(): Promise<Response>;
188
212
  protected post(): Promise<Response>;
@@ -190,8 +214,6 @@ declare abstract class BasicWorker implements CorsProvider {
190
214
  protected delete(): Promise<Response>;
191
215
  protected options(): Promise<Response>;
192
216
  protected head(): Promise<Response>;
193
- protected getCachedResponse(): Promise<Response | undefined>;
194
- protected setCachedResponse(response: Response): void;
195
217
  protected getResponse<T extends WorkerResponse>(ResponseClass: new (cors: CorsProvider, ...args: any[]) => T, ...args: any[]): Promise<Response>;
196
218
  isAllowed(method: string): boolean;
197
219
  getAllowOrigins(): string[];
@@ -219,7 +241,7 @@ declare abstract class RoutedWorker extends BasicWorker {
219
241
  private readonly routes;
220
242
  protected initialize(routes: RouteInit[]): void;
221
243
  protected add(method: Method, pattern: RegExp | string, callback: RouteCallback): this;
222
- protected dispatch(request: Request): Promise<Response>;
244
+ protected dispatch(request?: Request): Promise<Response>;
223
245
  protected get(): Promise<Response>;
224
246
  protected put(): Promise<Response>;
225
247
  protected post(): Promise<Response>;
@@ -227,4 +249,4 @@ declare abstract class RoutedWorker extends BasicWorker {
227
249
  protected delete(): Promise<Response>;
228
250
  }
229
251
 
230
- export { BadRequest, BasicWorker, CacheControl, ClonedResponse, type CorsProvider, type ErrorJson, Forbidden, Head, HtmlResponse, HttpError, InternalServerError, JsonResponse, Method, MethodNotAllowed, MimeType, NotFound, NotImplemented, Options, Route, type RouteCallback, type RouteInit, RoutedWorker, Routes, ServiceUnavailable, SuccessResponse, TextResponse, Time, Unauthorized, WorkerResponse, getContentType, isMethod, mergeHeader, setHeader };
252
+ export { BadRequest, BasicWorker, CacheControl, ClonedResponse, type CorsProvider, type ErrorJson, Forbidden, Head, HtmlResponse, HttpError, InternalServerError, JsonResponse, Method, MethodNotAllowed, MimeType, NotFound, NotImplemented, Options, Route, type RouteCallback, type RouteInit, RoutedWorker, Routes, ServiceUnavailable, SuccessResponse, TextResponse, Time, Unauthorized, type Worker, WorkerResponse, getContentType, isMethod, mergeHeader, normalizeUrl, setHeader };
package/dist/index.js CHANGED
@@ -2,6 +2,11 @@
2
2
  import { StatusCodes as StatusCodes2 } from "http-status-codes";
3
3
 
4
4
  // src/common.ts
5
+ import CacheLib from "cache-control-parser";
6
+ var CacheControl = {
7
+ parse: CacheLib.parse,
8
+ stringify: CacheLib.stringify
9
+ };
5
10
  var Time = {
6
11
  Second: 1,
7
12
  Minute: 60,
@@ -111,18 +116,55 @@ function mergeHeader(headers, key, value) {
111
116
  setHeader(headers, key, values);
112
117
  }
113
118
  }
119
+ function normalizeUrl(url) {
120
+ const u = new URL(url);
121
+ const params = [...u.searchParams.entries()];
122
+ params.sort(([a], [b]) => a.localeCompare(b));
123
+ u.search = params.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join("&");
124
+ u.hash = "";
125
+ return u.toString();
126
+ }
114
127
 
115
- // src/response.ts
116
- import { getReasonPhrase, StatusCodes } from "http-status-codes";
128
+ // src/base-worker.ts
129
+ var BaseWorker = class {
130
+ constructor(_request, _env = {}, _ctx) {
131
+ this._request = _request;
132
+ this._env = _env;
133
+ this._ctx = _ctx;
134
+ }
135
+ get request() {
136
+ return this._request;
137
+ }
138
+ get env() {
139
+ return this._env;
140
+ }
141
+ get ctx() {
142
+ return this._ctx;
143
+ }
144
+ };
117
145
 
118
- // src/cache.ts
119
- import CacheLib from "cache-control-parser";
120
- var CacheControl = {
121
- parse: CacheLib.parse,
122
- stringify: CacheLib.stringify
146
+ // src/cache-worker.ts
147
+ var CacheWorker = class extends BaseWorker {
148
+ getCacheKey() {
149
+ return normalizeUrl(this.request.url);
150
+ }
151
+ async getCachedResponse() {
152
+ if (this.request.method !== "GET" /* GET */) return;
153
+ return await caches.default.match(this.getCacheKey());
154
+ }
155
+ setCachedResponse(response) {
156
+ if (!response.ok) return;
157
+ if (this.request.method !== "GET" /* GET */) return;
158
+ try {
159
+ this.ctx?.waitUntil(caches.default.put(this.getCacheKey(), response.clone()));
160
+ } catch (e) {
161
+ console.warn("Failed to cache response:", e);
162
+ }
163
+ }
123
164
  };
124
165
 
125
166
  // src/response.ts
167
+ import { getReasonPhrase, StatusCodes } from "http-status-codes";
126
168
  var BasicResponse = class {
127
169
  headers = new Headers();
128
170
  body;
@@ -311,32 +353,18 @@ var ServiceUnavailable = class extends HttpError {
311
353
  };
312
354
 
313
355
  // src/basic-worker.ts
314
- var BasicWorker = class {
315
- constructor(_request, _env = {}, _ctx) {
316
- this._request = _request;
317
- this._env = _env;
318
- this._ctx = _ctx;
319
- }
320
- get request() {
321
- return this._request;
322
- }
323
- get env() {
324
- return this._env;
325
- }
326
- get ctx() {
327
- return this._ctx;
328
- }
356
+ var BasicWorker = class extends CacheWorker {
329
357
  async fetch() {
330
358
  if (!this.isAllowed(this.request.method)) {
331
359
  return this.getResponse(MethodNotAllowed, this.request.method);
332
360
  }
333
361
  try {
334
- return await this.dispatch(this.request);
362
+ return await this.dispatch();
335
363
  } catch (error) {
336
364
  return this.getResponse(InternalServerError, String(error));
337
365
  }
338
366
  }
339
- async dispatch(request) {
367
+ async dispatch(request = this.request) {
340
368
  const method = request.method;
341
369
  const handler = {
342
370
  GET: () => this.get(),
@@ -373,19 +401,6 @@ var BasicWorker = class {
373
401
  await this.dispatch(new Request(this.request, { method: "GET" /* GET */ }))
374
402
  );
375
403
  }
376
- async getCachedResponse() {
377
- if (this.request.method !== "GET" /* GET */) return;
378
- return await caches.default.match(this.request.url);
379
- }
380
- setCachedResponse(response) {
381
- if (!response.ok) return;
382
- if (this.request.method !== "GET" /* GET */) return;
383
- try {
384
- this.ctx?.waitUntil(caches.default.put(this.request.url, response.clone()));
385
- } catch (e) {
386
- console.warn("Failed to cache response:", e);
387
- }
388
- }
389
404
  async getResponse(ResponseClass, ...args) {
390
405
  const response = new ResponseClass(this, ...args).createResponse();
391
406
  this.setCachedResponse(response);
@@ -453,7 +468,7 @@ var RoutedWorker = class extends BasicWorker {
453
468
  this.routes.add(method, new Route(pattern, callback));
454
469
  return this;
455
470
  }
456
- async dispatch(request) {
471
+ async dispatch(request = this.request) {
457
472
  const route = this.routes.get(request.method, request.url);
458
473
  if (!route) return super.dispatch(request);
459
474
  const match = new URL(request.url).pathname.match(route.pattern) ?? [];
@@ -505,6 +520,7 @@ export {
505
520
  getContentType,
506
521
  isMethod,
507
522
  mergeHeader,
523
+ normalizeUrl,
508
524
  setHeader
509
525
  };
510
526
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/common.ts","../src/response.ts","../src/cache.ts","../src/basic-worker.ts","../src/routes.ts","../src/routed-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\nexport { StatusCodes } from \"http-status-codes\";\n\nexport * from \"./basic-worker\";\nexport * from \"./cache\";\nexport * from \"./common\";\nexport * from \"./response\";\nexport * from \"./routed-worker\";\nexport * from \"./routes\";\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\nexport const Time = {\n Second: 1,\n Minute: 60,\n Hour: 60 * 60,\n Day: 60 * 60 * 24,\n Week: 60 * 60 * 24 * 7,\n Year: 60 * 60 * 24 * 365,\n} as const;\n\nexport enum Method {\n GET = \"GET\",\n PUT = \"PUT\",\n POST = \"POST\",\n PATCH = \"PATCH\",\n DELETE = \"DELETE\",\n HEAD = \"HEAD\",\n OPTIONS = \"OPTIONS\",\n}\nconst METHOD_SET: Set<string> = new Set(Object.values(Method));\n\nexport function isMethod(value: string): value is Method {\n return METHOD_SET.has(value);\n}\n\nexport function getContentType(type: MimeType): string {\n if (ADD_CHARSET.has(type)) {\n return `${type}; charset=utf-8`;\n }\n return type;\n}\n\nexport enum MimeType {\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\nconst ADD_CHARSET: Set<MimeType> = new Set([\n MimeType.PLAIN_TEXT,\n MimeType.HTML,\n MimeType.CSS,\n MimeType.CSV,\n MimeType.MARKDOWN,\n MimeType.XML,\n MimeType.JSON,\n MimeType.XML_APP,\n MimeType.FORM_URLENCODED,\n MimeType.NDJSON,\n MimeType.RICH_TEXT,\n MimeType.SVG,\n]);\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()))).filter((v) => v.length);\n\n if (!values.length) {\n headers.delete(key);\n return;\n }\n\n headers.set(key, values.join(\", \"));\n}\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 { getReasonPhrase, StatusCodes } from \"http-status-codes\";\nimport { getContentType, mergeHeader, Method, MimeType, setHeader } from \"./common\";\nimport { CacheControl } from \"./cache\";\n\nexport interface CorsProvider {\n getOrigin(): string | null;\n getAllowOrigins(): string[];\n getAllowMethods(): Method[];\n getAllowHeaders(): string[];\n getExposeHeaders(): string[];\n getMaxAge(): number;\n}\n\nexport interface ErrorJson {\n status: number;\n error: string;\n details: string;\n}\n\nabstract class BasicResponse {\n public headers: Headers = new Headers();\n public body: BodyInit | null;\n public status: StatusCodes = StatusCodes.OK;\n public statusText?: string;\n public mimeType?: MimeType;\n public cache?: CacheControl;\n\n constructor(content: BodyInit | null = null) {\n this.body = this.status === StatusCodes.NO_CONTENT ? null : content;\n }\n\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 public setHeader(key: string, value: string | string[]): void {\n setHeader(this.headers, key, value);\n }\n\n public mergeHeader(key: string, value: string | string[]): void {\n mergeHeader(this.headers, key, value);\n }\n\n public addContentType() {\n if (this.mimeType) {\n this.headers.set(\"Content-Type\", getContentType(this.mimeType));\n }\n }\n\n public addCacheControl() {\n if (this.cache) {\n this.headers.set(\"Cache-Control\", CacheControl.stringify(this.cache));\n }\n }\n}\n\nabstract class CorsResponse extends BasicResponse {\n constructor(public readonly cors: CorsProvider, content: BodyInit | null = null) {\n super(content);\n }\n\n protected addCorsHeaders(): void {\n const origin = this.cors.getOrigin();\n if (!origin) return; // no Origin, skip CORS\n\n this.headers.delete(\"Access-Control-Allow-Origin\");\n\n const allowed = this.cors.getAllowOrigins();\n if (allowed.includes(\"*\")) {\n this.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n } else if (allowed.includes(origin)) {\n this.setHeader(\"Access-Control-Allow-Origin\", origin);\n this.setHeader(\"Access-Control-Allow-Credentials\", \"true\");\n }\n\n this.mergeHeader(\"Access-Control-Expose-Headers\", this.cors.getExposeHeaders());\n this.setHeader(\"Access-Control-Allow-Headers\", this.cors.getAllowHeaders());\n this.setHeader(\"Access-Control-Allow-Methods\", this.cors.getAllowMethods());\n this.setHeader(\"Access-Control-Max-Age\", String(this.cors.getMaxAge()));\n\n this.setHeader(\"X-Content-Type-Options\", \"nosniff\");\n this.mergeHeader(\"Vary\", \"Origin\");\n }\n}\n\nexport abstract class WorkerResponse extends CorsResponse {\n constructor(cors: CorsProvider, body: BodyInit | null = null, cache?: CacheControl) {\n super(cors, body);\n this.cache = cache;\n }\n\n public createResponse(): Response {\n this.addCorsHeaders();\n this.addCacheControl();\n\n const body = this.status === StatusCodes.NO_CONTENT ? null : this.body;\n if (body) this.addContentType();\n return new Response(body, this.responseInit);\n }\n}\n\nexport class ClonedResponse extends WorkerResponse {\n constructor(cors: CorsProvider, response: Response, cache?: CacheControl) {\n const clone = response.clone();\n super(cors, clone.body, cache);\n this.headers = new Headers(clone.headers);\n this.status = clone.status;\n this.statusText = clone.statusText;\n }\n}\n\nexport class SuccessResponse extends WorkerResponse {\n constructor(\n cors: CorsProvider,\n body: BodyInit | null = null,\n cache?: CacheControl,\n status: StatusCodes = StatusCodes.OK\n ) {\n super(cors, body, cache);\n this.status = status;\n }\n}\n\nexport class JsonResponse extends SuccessResponse {\n constructor(\n cors: CorsProvider,\n json: unknown = {},\n cache?: CacheControl,\n status: StatusCodes = StatusCodes.OK\n ) {\n super(cors, JSON.stringify(json), cache, status);\n this.mimeType = MimeType.JSON;\n }\n}\n\nexport class HtmlResponse extends SuccessResponse {\n constructor(\n cors: CorsProvider,\n body: string,\n cache?: CacheControl,\n status: StatusCodes = StatusCodes.OK\n ) {\n super(cors, body, cache, status);\n this.mimeType = MimeType.HTML;\n }\n}\n\nexport class TextResponse extends SuccessResponse {\n constructor(\n cors: CorsProvider,\n content: string,\n cache?: CacheControl,\n status: StatusCodes = StatusCodes.OK\n ) {\n super(cors, content, cache, status);\n this.mimeType = MimeType.PLAIN_TEXT;\n }\n}\n\n/**\n * Remove the body from a GET response.\n */\nexport class Head extends WorkerResponse {\n constructor(cors: CorsProvider, get: Response) {\n super(cors);\n this.headers = new Headers(get.headers);\n }\n}\n\nexport class Options extends SuccessResponse {\n constructor(cors: CorsProvider) {\n super(cors, null, undefined, StatusCodes.NO_CONTENT);\n this.setHeader(\"Allow\", this.cors.getAllowMethods());\n }\n}\n\nexport class HttpError extends JsonResponse {\n constructor(cors: CorsProvider, status: StatusCodes, protected readonly details?: string) {\n const cache: CacheControl = {\n \"no-cache\": true,\n \"no-store\": true,\n \"must-revalidate\": true,\n \"max-age\": 0,\n };\n super(cors, undefined, cache, status);\n }\n\n public get json(): ErrorJson {\n return {\n status: this.status,\n error: getReasonPhrase(this.status),\n details: this.details ?? getReasonPhrase(this.status),\n };\n }\n\n public override createResponse(): Response {\n this.body = JSON.stringify(this.json);\n return super.createResponse();\n }\n}\n\nexport class BadRequest extends HttpError {\n constructor(cors: CorsProvider, details?: string) {\n super(cors, StatusCodes.BAD_REQUEST, details);\n }\n}\n\nexport class Unauthorized extends HttpError {\n constructor(cors: CorsProvider, details?: string) {\n super(cors, StatusCodes.UNAUTHORIZED, details);\n }\n}\n\nexport class Forbidden extends HttpError {\n constructor(cors: CorsProvider, details?: string) {\n super(cors, StatusCodes.FORBIDDEN, details);\n }\n}\n\nexport class NotFound extends HttpError {\n constructor(cors: CorsProvider, details?: string) {\n super(cors, StatusCodes.NOT_FOUND, details);\n }\n}\n\nexport class MethodNotAllowed extends HttpError {\n constructor(cors: CorsProvider, method: string) {\n super(cors, StatusCodes.METHOD_NOT_ALLOWED, `${method} method not allowed.`);\n this.setHeader(\"Allow\", this.cors.getAllowMethods());\n }\n\n public override get json(): ErrorJson & { allowed: Method[] } {\n return {\n ...super.json,\n allowed: this.cors.getAllowMethods(),\n };\n }\n}\n\nexport class InternalServerError extends HttpError {\n constructor(cors: CorsProvider, details?: string) {\n super(cors, StatusCodes.INTERNAL_SERVER_ERROR, details);\n }\n}\n\nexport class NotImplemented extends HttpError {\n constructor(cors: CorsProvider) {\n super(cors, StatusCodes.NOT_IMPLEMENTED);\n }\n}\n\nexport class ServiceUnavailable extends HttpError {\n constructor(cors: CorsProvider, details?: string) {\n super(cors, 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\n/**\n * https://github.com/etienne-martin/cache-control-parser\n */\nimport CacheLib from \"cache-control-parser\";\n\nexport type CacheControl = CacheLib.CacheControl;\nexport const CacheControl = {\n parse: CacheLib.parse,\n stringify: CacheLib.stringify,\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 { isMethod, Method, Time } from \"./common\";\nimport {\n CorsProvider,\n Head,\n InternalServerError,\n MethodNotAllowed,\n NotImplemented,\n Options,\n WorkerResponse,\n} from \"./response\";\n\nexport abstract class BasicWorker implements CorsProvider {\n constructor(\n private readonly _request: Request,\n private readonly _env: Env = {},\n private readonly _ctx?: ExecutionContext\n ) {}\n\n protected get request(): Request {\n return this._request;\n }\n\n protected get env(): Env {\n return this._env;\n }\n\n protected get ctx(): ExecutionContext | undefined {\n return this._ctx;\n }\n\n public async fetch(): Promise<Response> {\n if (!this.isAllowed(this.request.method)) {\n return this.getResponse(MethodNotAllowed, this.request.method);\n }\n\n try {\n return await this.dispatch(this.request);\n } catch (error) {\n return this.getResponse(InternalServerError, String(error));\n }\n }\n\n protected async dispatch(request: Request): Promise<Response> {\n const method = request.method as Method;\n const handler: Record<Method, () => Promise<Response>> = {\n GET: () => this.get(),\n PUT: () => this.put(),\n POST: () => this.post(),\n PATCH: () => this.patch(),\n DELETE: () => this.delete(),\n HEAD: () => this.head(),\n OPTIONS: () => this.options(),\n };\n return (handler[method] ?? (() => this.getResponse(MethodNotAllowed, method)))();\n }\n\n protected async get(): Promise<Response> {\n return this.getResponse(NotImplemented);\n }\n\n protected async put(): Promise<Response> {\n return this.getResponse(NotImplemented);\n }\n\n protected async post(): Promise<Response> {\n return this.getResponse(NotImplemented);\n }\n\n protected async patch(): Promise<Response> {\n return this.getResponse(NotImplemented);\n }\n\n protected async delete(): Promise<Response> {\n return this.getResponse(NotImplemented);\n }\n\n protected async options(): Promise<Response> {\n return this.getResponse(Options);\n }\n\n protected async head(): Promise<Response> {\n // Dispatch a new GET request created from the HEAD request\n // and return the GET response with the body removed.\n return this.getResponse(\n Head,\n await this.dispatch(new Request(this.request, { method: Method.GET }))\n );\n }\n\n protected async getCachedResponse(): Promise<Response | undefined> {\n if (this.request.method !== Method.GET) return;\n\n return await caches.default.match(this.request.url);\n }\n\n protected setCachedResponse(response: Response): void {\n if (!response.ok) return;\n if (this.request.method !== Method.GET) return;\n\n try {\n this.ctx?.waitUntil(caches.default.put(this.request.url, response.clone()));\n } catch (e) {\n console.warn(\"Failed to cache response:\", e);\n }\n }\n\n protected async getResponse<T extends WorkerResponse>(\n ResponseClass: new (cors: CorsProvider, ...args: any[]) => T,\n ...args: any[]\n ): Promise<Response> {\n const response = new ResponseClass(this, ...args).createResponse();\n this.setCachedResponse(response);\n return response;\n }\n\n public isAllowed(method: string): boolean {\n return isMethod(method) && this.getAllowMethods().includes(method);\n }\n\n public getAllowOrigins(): string[] {\n return [\"*\"];\n }\n\n public getAllowMethods(): Method[] {\n return [Method.GET, Method.OPTIONS, Method.HEAD];\n }\n\n public getAllowHeaders(): string[] {\n return [\"Content-Type\"];\n }\n\n public getExposeHeaders(): string[] {\n return [];\n }\n\n public getMaxAge(): number {\n return Time.Week;\n }\n\n public getOrigin(): string | null {\n return this.request.headers.get(\"Origin\");\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 \"./common\";\n\nexport type RouteCallback = (...matches: string[]) => Response | Promise<Response>;\n\nexport type RouteInit = [Method, string, RouteCallback];\n\nexport class Route {\n public readonly pattern: RegExp;\n\n constructor(pattern: RegExp | string, public readonly callback: RouteCallback) {\n this.pattern = new RegExp(pattern);\n }\n}\n\nexport class Routes {\n private readonly map = new Map<Method, Route[]>();\n\n public add(method: Method, route: Route) {\n const existing = this.map.get(method);\n if (existing) {\n existing.push(route);\n } else {\n this.map.set(method, [route]);\n }\n return this;\n }\n\n public get(method: Method, url: string): Route | undefined {\n const routes = this.map.get(method);\n if (!routes) return undefined;\n\n const pathname = new URL(url).pathname;\n return routes.find(({ pattern }) => pattern.test(pathname));\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 { Method } from \"./common\";\nimport { NotFound } from \"./response\";\nimport { Route, Routes, RouteInit, RouteCallback } from \"./routes\";\n\nexport abstract class RoutedWorker extends BasicWorker {\n private readonly routes: Routes = new Routes();\n\n protected initialize(routes: RouteInit[]) {\n routes.forEach(([method, pattern, callback]) => {\n this.add(method, pattern, callback);\n });\n }\n\n protected add(method: Method, pattern: RegExp | string, callback: RouteCallback) {\n this.routes.add(method, new Route(pattern, callback));\n return this;\n }\n\n protected async dispatch(request: Request): Promise<Response> {\n const route = this.routes.get(request.method as Method, request.url);\n if (!route) return super.dispatch(request);\n\n const match = new URL(request.url).pathname.match(route.pattern) ?? [];\n return route.callback.call(this, ...match);\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"],"mappings":"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","names":["StatusCodes","Method","MimeType"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/common.ts","../src/base-worker.ts","../src/cache-worker.ts","../src/response.ts","../src/basic-worker.ts","../src/routes.ts","../src/routed-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\nexport { StatusCodes } from \"http-status-codes\";\n\nexport * from \"./basic-worker\";\nexport * from \"./common\";\nexport * from \"./response\";\nexport * from \"./routed-worker\";\nexport * from \"./routes\";\nexport * from \"./worker\";\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/etienne-martin/cache-control-parser\n */\nimport CacheLib from \"cache-control-parser\";\n\nexport type CacheControl = CacheLib.CacheControl;\nexport const CacheControl = {\n parse: CacheLib.parse,\n stringify: CacheLib.stringify,\n};\n\nexport const Time = {\n Second: 1,\n Minute: 60,\n Hour: 60 * 60,\n Day: 60 * 60 * 24,\n Week: 60 * 60 * 24 * 7,\n Year: 60 * 60 * 24 * 365,\n} as const;\n\nexport enum Method {\n GET = \"GET\",\n PUT = \"PUT\",\n POST = \"POST\",\n PATCH = \"PATCH\",\n DELETE = \"DELETE\",\n HEAD = \"HEAD\",\n OPTIONS = \"OPTIONS\",\n}\nconst METHOD_SET: Set<string> = new Set(Object.values(Method));\n\nexport function isMethod(value: string): value is Method {\n return METHOD_SET.has(value);\n}\n\nexport function getContentType(type: MimeType): string {\n if (ADD_CHARSET.has(type)) {\n return `${type}; charset=utf-8`;\n }\n return type;\n}\n\nexport enum MimeType {\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\nconst ADD_CHARSET: Set<MimeType> = new Set([\n MimeType.PLAIN_TEXT,\n MimeType.HTML,\n MimeType.CSS,\n MimeType.CSV,\n MimeType.MARKDOWN,\n MimeType.XML,\n MimeType.JSON,\n MimeType.XML_APP,\n MimeType.FORM_URLENCODED,\n MimeType.NDJSON,\n MimeType.RICH_TEXT,\n MimeType.SVG,\n]);\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()))).filter((v) => v.length);\n\n if (!values.length) {\n headers.delete(key);\n return;\n }\n\n headers.set(key, values.join(\", \"));\n}\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/**\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): string {\n const u = new URL(url);\n\n const params = [...u.searchParams.entries()];\n params.sort(([a], [b]) => a.localeCompare(b));\n\n u.search = params\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)\n .join(\"&\");\n u.hash = \"\";\n\n return u.toString();\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 { Worker } from \"./worker\";\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 protected get request(): Request {\n return this._request;\n }\n\n protected get env(): Env {\n return this._env;\n }\n\n protected get ctx(): ExecutionContext | undefined {\n return this._ctx;\n }\n\n public abstract fetch(): 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 * https://github.com/etienne-martin/cache-control-parser\n */\nimport { Method, normalizeUrl } from \"./common\";\nimport { BaseWorker } from \"./base-worker\";\n\nexport abstract class CacheWorker extends BaseWorker {\n protected getCacheKey(): string {\n return normalizeUrl(this.request.url);\n }\n\n protected async getCachedResponse(): Promise<Response | undefined> {\n if (this.request.method !== Method.GET) return;\n\n return await caches.default.match(this.getCacheKey());\n }\n\n protected setCachedResponse(response: Response): void {\n if (!response.ok) return;\n if (this.request.method !== Method.GET) return;\n\n try {\n this.ctx?.waitUntil(caches.default.put(this.getCacheKey(), response.clone()));\n } catch (e) {\n console.warn(\"Failed to cache response:\", e);\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 { getReasonPhrase, StatusCodes } from \"http-status-codes\";\nimport { CacheControl, getContentType, mergeHeader, Method, MimeType, setHeader } from \"./common\";\n\nexport interface CorsProvider {\n getOrigin(): string | null;\n getAllowOrigins(): string[];\n getAllowMethods(): Method[];\n getAllowHeaders(): string[];\n getExposeHeaders(): string[];\n getMaxAge(): number;\n}\n\nexport interface ErrorJson {\n status: number;\n error: string;\n details: string;\n}\n\nabstract class BasicResponse {\n public headers: Headers = new Headers();\n public body: BodyInit | null;\n public status: StatusCodes = StatusCodes.OK;\n public statusText?: string;\n public mimeType?: MimeType;\n public cache?: CacheControl;\n\n constructor(content: BodyInit | null = null) {\n this.body = this.status === StatusCodes.NO_CONTENT ? null : content;\n }\n\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 public setHeader(key: string, value: string | string[]): void {\n setHeader(this.headers, key, value);\n }\n\n public mergeHeader(key: string, value: string | string[]): void {\n mergeHeader(this.headers, key, value);\n }\n\n public addContentType() {\n if (this.mimeType) {\n this.headers.set(\"Content-Type\", getContentType(this.mimeType));\n }\n }\n\n public addCacheControl() {\n if (this.cache) {\n this.headers.set(\"Cache-Control\", CacheControl.stringify(this.cache));\n }\n }\n}\n\nabstract class CorsResponse extends BasicResponse {\n constructor(public readonly cors: CorsProvider, content: BodyInit | null = null) {\n super(content);\n }\n\n protected addCorsHeaders(): void {\n const origin = this.cors.getOrigin();\n if (!origin) return; // no Origin, skip CORS\n\n this.headers.delete(\"Access-Control-Allow-Origin\");\n\n const allowed = this.cors.getAllowOrigins();\n if (allowed.includes(\"*\")) {\n this.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n } else if (allowed.includes(origin)) {\n this.setHeader(\"Access-Control-Allow-Origin\", origin);\n this.setHeader(\"Access-Control-Allow-Credentials\", \"true\");\n }\n\n this.mergeHeader(\"Access-Control-Expose-Headers\", this.cors.getExposeHeaders());\n this.setHeader(\"Access-Control-Allow-Headers\", this.cors.getAllowHeaders());\n this.setHeader(\"Access-Control-Allow-Methods\", this.cors.getAllowMethods());\n this.setHeader(\"Access-Control-Max-Age\", String(this.cors.getMaxAge()));\n\n this.setHeader(\"X-Content-Type-Options\", \"nosniff\");\n this.mergeHeader(\"Vary\", \"Origin\");\n }\n}\n\nexport abstract class WorkerResponse extends CorsResponse {\n constructor(cors: CorsProvider, body: BodyInit | null = null, cache?: CacheControl) {\n super(cors, body);\n this.cache = cache;\n }\n\n public createResponse(): Response {\n this.addCorsHeaders();\n this.addCacheControl();\n\n const body = this.status === StatusCodes.NO_CONTENT ? null : this.body;\n if (body) this.addContentType();\n return new Response(body, this.responseInit);\n }\n}\n\nexport class ClonedResponse extends WorkerResponse {\n constructor(cors: CorsProvider, response: Response, cache?: CacheControl) {\n const clone = response.clone();\n super(cors, clone.body, cache);\n this.headers = new Headers(clone.headers);\n this.status = clone.status;\n this.statusText = clone.statusText;\n }\n}\n\nexport class SuccessResponse extends WorkerResponse {\n constructor(\n cors: CorsProvider,\n body: BodyInit | null = null,\n cache?: CacheControl,\n status: StatusCodes = StatusCodes.OK\n ) {\n super(cors, body, cache);\n this.status = status;\n }\n}\n\nexport class JsonResponse extends SuccessResponse {\n constructor(\n cors: CorsProvider,\n json: unknown = {},\n cache?: CacheControl,\n status: StatusCodes = StatusCodes.OK\n ) {\n super(cors, JSON.stringify(json), cache, status);\n this.mimeType = MimeType.JSON;\n }\n}\n\nexport class HtmlResponse extends SuccessResponse {\n constructor(\n cors: CorsProvider,\n body: string,\n cache?: CacheControl,\n status: StatusCodes = StatusCodes.OK\n ) {\n super(cors, body, cache, status);\n this.mimeType = MimeType.HTML;\n }\n}\n\nexport class TextResponse extends SuccessResponse {\n constructor(\n cors: CorsProvider,\n content: string,\n cache?: CacheControl,\n status: StatusCodes = StatusCodes.OK\n ) {\n super(cors, content, cache, status);\n this.mimeType = MimeType.PLAIN_TEXT;\n }\n}\n\n/**\n * Remove the body from a GET response.\n */\nexport class Head extends WorkerResponse {\n constructor(cors: CorsProvider, get: Response) {\n super(cors);\n this.headers = new Headers(get.headers);\n }\n}\n\nexport class Options extends SuccessResponse {\n constructor(cors: CorsProvider) {\n super(cors, null, undefined, StatusCodes.NO_CONTENT);\n this.setHeader(\"Allow\", this.cors.getAllowMethods());\n }\n}\n\nexport class HttpError extends JsonResponse {\n constructor(cors: CorsProvider, status: StatusCodes, protected readonly details?: string) {\n const cache: CacheControl = {\n \"no-cache\": true,\n \"no-store\": true,\n \"must-revalidate\": true,\n \"max-age\": 0,\n };\n super(cors, undefined, cache, status);\n }\n\n public get json(): ErrorJson {\n return {\n status: this.status,\n error: getReasonPhrase(this.status),\n details: this.details ?? getReasonPhrase(this.status),\n };\n }\n\n public override createResponse(): Response {\n this.body = JSON.stringify(this.json);\n return super.createResponse();\n }\n}\n\nexport class BadRequest extends HttpError {\n constructor(cors: CorsProvider, details?: string) {\n super(cors, StatusCodes.BAD_REQUEST, details);\n }\n}\n\nexport class Unauthorized extends HttpError {\n constructor(cors: CorsProvider, details?: string) {\n super(cors, StatusCodes.UNAUTHORIZED, details);\n }\n}\n\nexport class Forbidden extends HttpError {\n constructor(cors: CorsProvider, details?: string) {\n super(cors, StatusCodes.FORBIDDEN, details);\n }\n}\n\nexport class NotFound extends HttpError {\n constructor(cors: CorsProvider, details?: string) {\n super(cors, StatusCodes.NOT_FOUND, details);\n }\n}\n\nexport class MethodNotAllowed extends HttpError {\n constructor(cors: CorsProvider, method: string) {\n super(cors, StatusCodes.METHOD_NOT_ALLOWED, `${method} method not allowed.`);\n this.setHeader(\"Allow\", this.cors.getAllowMethods());\n }\n\n public override get json(): ErrorJson & { allowed: Method[] } {\n return {\n ...super.json,\n allowed: this.cors.getAllowMethods(),\n };\n }\n}\n\nexport class InternalServerError extends HttpError {\n constructor(cors: CorsProvider, details?: string) {\n super(cors, StatusCodes.INTERNAL_SERVER_ERROR, details);\n }\n}\n\nexport class NotImplemented extends HttpError {\n constructor(cors: CorsProvider) {\n super(cors, StatusCodes.NOT_IMPLEMENTED);\n }\n}\n\nexport class ServiceUnavailable extends HttpError {\n constructor(cors: CorsProvider, details?: string) {\n super(cors, 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 { CacheWorker } from \"./cache-worker\";\nimport { isMethod, Method, Time } from \"./common\";\nimport {\n CorsProvider,\n Head,\n InternalServerError,\n MethodNotAllowed,\n NotImplemented,\n Options,\n WorkerResponse,\n} from \"./response\";\n\nexport abstract class BasicWorker extends CacheWorker implements CorsProvider {\n public async fetch(): Promise<Response> {\n if (!this.isAllowed(this.request.method)) {\n return this.getResponse(MethodNotAllowed, this.request.method);\n }\n\n try {\n return await this.dispatch();\n } catch (error) {\n return this.getResponse(InternalServerError, String(error));\n }\n }\n\n protected async dispatch(request: Request = this.request): Promise<Response> {\n const method = request.method as Method;\n const handler: Record<Method, () => Promise<Response>> = {\n GET: () => this.get(),\n PUT: () => this.put(),\n POST: () => this.post(),\n PATCH: () => this.patch(),\n DELETE: () => this.delete(),\n HEAD: () => this.head(),\n OPTIONS: () => this.options(),\n };\n return (handler[method] ?? (() => this.getResponse(MethodNotAllowed, method)))();\n }\n\n protected async get(): Promise<Response> {\n return this.getResponse(NotImplemented);\n }\n\n protected async put(): Promise<Response> {\n return this.getResponse(NotImplemented);\n }\n\n protected async post(): Promise<Response> {\n return this.getResponse(NotImplemented);\n }\n\n protected async patch(): Promise<Response> {\n return this.getResponse(NotImplemented);\n }\n\n protected async delete(): Promise<Response> {\n return this.getResponse(NotImplemented);\n }\n\n protected async options(): Promise<Response> {\n return this.getResponse(Options);\n }\n\n protected async head(): Promise<Response> {\n // Dispatch a new GET request created from the HEAD request\n // and return the GET response with the body removed.\n return this.getResponse(\n Head,\n await this.dispatch(new Request(this.request, { method: Method.GET }))\n );\n }\n\n protected async getResponse<T extends WorkerResponse>(\n ResponseClass: new (cors: CorsProvider, ...args: any[]) => T,\n ...args: any[]\n ): Promise<Response> {\n const response = new ResponseClass(this, ...args).createResponse();\n this.setCachedResponse(response);\n return response;\n }\n\n public isAllowed(method: string): boolean {\n return isMethod(method) && this.getAllowMethods().includes(method);\n }\n\n public getAllowOrigins(): string[] {\n return [\"*\"];\n }\n\n public getAllowMethods(): Method[] {\n return [Method.GET, Method.OPTIONS, Method.HEAD];\n }\n\n public getAllowHeaders(): string[] {\n return [\"Content-Type\"];\n }\n\n public getExposeHeaders(): string[] {\n return [];\n }\n\n public getMaxAge(): number {\n return Time.Week;\n }\n\n public getOrigin(): string | null {\n return this.request.headers.get(\"Origin\");\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 \"./common\";\n\nexport type RouteCallback = (...matches: string[]) => Response | Promise<Response>;\n\nexport type RouteInit = [Method, string, RouteCallback];\n\nexport class Route {\n public readonly pattern: RegExp;\n\n constructor(pattern: RegExp | string, public readonly callback: RouteCallback) {\n this.pattern = new RegExp(pattern);\n }\n}\n\nexport class Routes {\n private readonly map = new Map<Method, Route[]>();\n\n public add(method: Method, route: Route) {\n const existing = this.map.get(method);\n if (existing) {\n existing.push(route);\n } else {\n this.map.set(method, [route]);\n }\n return this;\n }\n\n public get(method: Method, url: string): Route | undefined {\n const routes = this.map.get(method);\n if (!routes) return undefined;\n\n const pathname = new URL(url).pathname;\n return routes.find(({ pattern }) => pattern.test(pathname));\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 { Method } from \"./common\";\nimport { NotFound } from \"./response\";\nimport { Route, Routes, RouteInit, RouteCallback } from \"./routes\";\n\nexport abstract class RoutedWorker extends BasicWorker {\n private readonly routes: Routes = new Routes();\n\n protected initialize(routes: RouteInit[]) {\n routes.forEach(([method, pattern, callback]) => {\n this.add(method, pattern, callback);\n });\n }\n\n protected add(method: Method, pattern: RegExp | string, callback: RouteCallback) {\n this.routes.add(method, new Route(pattern, callback));\n return this;\n }\n\n protected async dispatch(request: Request = this.request): Promise<Response> {\n const route = this.routes.get(request.method as Method, request.url);\n if (!route) return super.dispatch(request);\n\n const match = new URL(request.url).pathname.match(route.pattern) ?? [];\n return route.callback.call(this, ...match);\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"],"mappings":"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","names":["StatusCodes","Method","MimeType"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adonix.org/cloud-spark",
3
- "version": "0.0.71",
3
+ "version": "0.0.73",
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",