capability-worker 0.1.3 → 0.1.4

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/README.md CHANGED
@@ -384,9 +384,11 @@ import {
384
384
  HttpError,
385
385
  errorJson,
386
386
  errorResponse,
387
+ corsHeaders,
387
388
  jsonResponse,
388
389
  okJson,
389
- textResponse
390
+ textResponse,
391
+ withCors
390
392
  } from "capability-worker/http";
391
393
 
392
394
  export async function readMeeting(request: Request, env: Env) {
@@ -431,6 +433,9 @@ htmlResponse(value, init);
431
433
  redirectResponse(location, status);
432
434
  errorJson(code, message, status, extra);
433
435
  errorResponse(error);
436
+ corsHeaders(request, options);
437
+ withCors(request, response, options);
438
+ isCorsOriginAllowed(request, options);
434
439
  parseJsonBody(request);
435
440
  readJsonObject(request);
436
441
  isJsonRequested(url, body);
@@ -6,9 +6,23 @@ declare class HttpError extends Error {
6
6
  expose?: boolean;
7
7
  });
8
8
  }
9
+ type CorsAllowedOrigins = Iterable<string> | ((origin: string, request: Request) => boolean);
10
+ type CorsVaryMode = boolean | "always" | "allowed";
11
+ type CorsOptions = {
12
+ allowedOrigins?: CorsAllowedOrigins;
13
+ allowCredentials?: boolean;
14
+ allowOriginForNoOrigin?: boolean;
15
+ methods?: string | string[];
16
+ headers?: string | string[];
17
+ maxAgeSeconds?: number;
18
+ vary?: CorsVaryMode;
19
+ };
9
20
  declare function jsonResponse(value: unknown, init?: ResponseInit | number): Response;
10
21
  declare function okJson(data: unknown, init?: ResponseInit | number): Response;
11
22
  declare function textResponse(value: string, init?: ResponseInit | number): Response;
23
+ declare function corsHeaders(request: Request, options?: CorsOptions): Headers;
24
+ declare function withCors(request: Request, response: Response, options?: CorsOptions): Response;
25
+ declare function isCorsOriginAllowed(request: Request, options?: Pick<CorsOptions, "allowedOrigins">): boolean;
12
26
  declare function htmlResponse(value: string, init?: ResponseInit | number): Response;
13
27
  declare function redirectResponse(location: string, status?: number): Response;
14
28
  declare function errorJson(code: string, message: string, status?: number, extra?: Record<string, unknown>): Response;
@@ -22,4 +36,5 @@ declare function booleanParam(value: unknown): boolean;
22
36
  declare function limitParam(value: unknown, defaultValue?: number, max?: number): number;
23
37
  declare function getRepeated(url: URL, key: string): string[];
24
38
 
25
- export { HttpError, booleanParam, errorJson, errorResponse, getRepeated, htmlResponse, isJsonRequested, jsonResponse, limitParam, okJson, parseJsonBody, readJsonObject, redirectResponse, stringArrayParam, stringParam, textResponse };
39
+ export { HttpError, booleanParam, corsHeaders, errorJson, errorResponse, getRepeated, htmlResponse, isCorsOriginAllowed, isJsonRequested, jsonResponse, limitParam, okJson, parseJsonBody, readJsonObject, redirectResponse, stringArrayParam, stringParam, textResponse, withCors };
40
+ export type { CorsAllowedOrigins, CorsOptions, CorsVaryMode };
@@ -1 +1 @@
1
- class t extends Error{status;code;expose;constructor(t,e,n,r){super(n),this.name="HttpError",this.status=t,this.code=e,this.expose=r?.expose??t<500}}function e(t,e=200){const n=m(e);return new Response(JSON.stringify(t,null,2),{...n,headers:x(n.headers,"content-type","application/json; charset=utf-8")})}function n(t,n=200){return e({ok:!0,data:t},n)}function r(t,e=200){return new Response(t.endsWith("\n")?t:`${t}\n`,{...m(e),headers:x(m(e).headers,"content-type","text/plain; charset=utf-8")})}function o(t,e=200){const n=m(e);return new Response(t,{...n,headers:x(n.headers,"content-type","text/html; charset=utf-8")})}function s(t,e=302){return new Response(null,{status:e,headers:{location:t,"cache-control":"no-store"}})}function a(t,n,r=400,o={}){return e({ok:!1,error:{code:t,message:n},...o},r)}function c(e){return e instanceof t?a(e.code,e.expose?e.message:"Internal error.",e.status):a("internal_error","Internal error.",500)}async function u(t){if(!t.body)return{};try{const e=await t.json();return!e||"object"!=typeof e||Array.isArray(e)?{}:e}catch{return{}}}async function i(e){const n=await e.json().catch(()=>null);if(!n||"object"!=typeof n||Array.isArray(n))throw new t(400,"invalid_json","Expected a JSON object.");return n}function f(t,e){const n=t.searchParams.get("json");return""===n||"1"===n||"true"===n||!0===e?.json}function h(t){if("string"!=typeof t)return;const e=t.trim();return e.length>0?e:void 0}function p(t){if(Array.isArray(t))return t.filter(t=>"string"==typeof t).map(t=>t.trim()).filter(Boolean);const e=h(t);return e?[e]:[]}function l(t){return!0===t||"true"===t||"1"===t||""===t}function y(t,e=20,n=100){const r="number"==typeof t?t:Number(t);return Number.isFinite(r)?Math.max(1,Math.min(n,Math.floor(r))):e}function d(t,e){return t.searchParams.getAll(e).map(t=>t.trim()).filter(Boolean)}function m(t){return"number"==typeof t?{status:t}:t}function x(t,e,n){const r=new Headers(t);return r.has(e)||r.set(e,n),r}export{t as HttpError,l as booleanParam,a as errorJson,c as errorResponse,d as getRepeated,o as htmlResponse,f as isJsonRequested,e as jsonResponse,y as limitParam,n as okJson,u as parseJsonBody,i as readJsonObject,s as redirectResponse,p as stringArrayParam,h as stringParam,r as textResponse};
1
+ class t extends Error{status;code;expose;constructor(t,e,n,r){super(n),this.name="HttpError",this.status=t,this.code=e,this.expose=r?.expose??t<500}}function e(t,e=200){const n=x(e);return new Response(JSON.stringify(t,null,2),{...n,headers:b(n.headers,"content-type","application/json; charset=utf-8")})}function n(t,n=200){return e({ok:!0,data:t},n)}function r(t,e=200){return new Response(t.endsWith("\n")?t:`${t}\n`,{...x(e),headers:b(x(e).headers,"content-type","text/plain; charset=utf-8")})}function o(t,e={}){const n=new Headers,r=t.headers.get("origin"),o=!!r&&A(r,t,e.allowedOrigins);r&&o?(n.set("access-control-allow-origin",r),e.allowCredentials&&n.set("access-control-allow-credentials","true")):!r&&e.allowOriginForNoOrigin&&n.set("access-control-allow-origin","*");const s=e.vary??"allowed";return("always"===s||!0===s&&r||"allowed"===s&&o)&&n.set("vary","Origin"),n.set("access-control-allow-methods",j(e.methods,"GET,POST,PUT,PATCH,DELETE,OPTIONS")),n.set("access-control-allow-headers",j(e.headers,"content-type,x-capability-account-id,x-capability-timestamp,x-capability-key-id,x-capability-signature")),n.set("access-control-max-age",String(e.maxAgeSeconds??86400)),n}function s(t,e,n={}){const r=new Headers(e.headers);return o(t,n).forEach((t,e)=>r.set(e,t)),new Response(e.body,{status:e.status,statusText:e.statusText,headers:r})}function a(t,e={}){const n=t.headers.get("origin");return Boolean(n&&A(n,t,e.allowedOrigins))}function i(t,e=200){const n=x(e);return new Response(t,{...n,headers:b(n.headers,"content-type","text/html; charset=utf-8")})}function c(t,e=302){return new Response(null,{status:e,headers:{location:t,"cache-control":"no-store"}})}function u(t,n,r=400,o={}){return e({ok:!1,error:{code:t,message:n},...o},r)}function l(e){return e instanceof t?u(e.code,e.expose?e.message:"Internal error.",e.status):u("internal_error","Internal error.",500)}async function f(t){if(!t.body)return{};try{const e=await t.json();return!e||"object"!=typeof e||Array.isArray(e)?{}:e}catch{return{}}}async function d(e){const n=await e.json().catch(()=>null);if(!n||"object"!=typeof n||Array.isArray(n))throw new t(400,"invalid_json","Expected a JSON object.");return n}function h(t,e){const n=t.searchParams.get("json");return""===n||"1"===n||"true"===n||!0===e?.json}function p(t){if("string"!=typeof t)return;const e=t.trim();return e.length>0?e:void 0}function y(t){if(Array.isArray(t))return t.filter(t=>"string"==typeof t).map(t=>t.trim()).filter(Boolean);const e=p(t);return e?[e]:[]}function g(t){return!0===t||"true"===t||"1"===t||""===t}function w(t,e=20,n=100){const r="number"==typeof t?t:Number(t);return Number.isFinite(r)?Math.max(1,Math.min(n,Math.floor(r))):e}function m(t,e){return t.searchParams.getAll(e).map(t=>t.trim()).filter(Boolean)}function x(t){return"number"==typeof t?{status:t}:t}function b(t,e,n){const r=new Headers(t);return r.has(e)||r.set(e,n),r}function A(t,e,n){if(!n)return!0;if("function"==typeof n)return n(t,e);for(const e of n)if("*"===e||e===t)return!0;return!1}function j(t,e){return"string"==typeof t?t:Array.isArray(t)?t.join(","):e}export{t as HttpError,g as booleanParam,o as corsHeaders,u as errorJson,l as errorResponse,m as getRepeated,i as htmlResponse,a as isCorsOriginAllowed,h as isJsonRequested,e as jsonResponse,w as limitParam,n as okJson,f as parseJsonBody,d as readJsonObject,c as redirectResponse,y as stringArrayParam,p as stringParam,r as textResponse,s as withCors};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capability-worker",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Shared toolkit for Cloudflare Workers that expose CLI-like capabilities over HTTP.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@11.9.0",
@@ -2,5 +2,4 @@ packages:
2
2
  - worker
3
3
 
4
4
  minimumReleaseAgeExclude:
5
- - capability-worker@0.1.1
6
-
5
+ - capability-worker@0.1.4
@@ -9,7 +9,7 @@
9
9
  "deploy": "pnpm run build:capability-assets && wrangler deploy"
10
10
  },
11
11
  "dependencies": {
12
- "capability-worker": "^0.1.1"
12
+ "capability-worker": "^0.1.4"
13
13
  },
14
14
  "devDependencies": {
15
15
  "@cloudflare/workers-types": "^4.20260627.0",
@@ -17,4 +17,3 @@
17
17
  "wrangler": "^4.51.0"
18
18
  }
19
19
  }
20
-