@lunora/bindings 1.0.0-alpha.14 → 1.0.0-alpha.16

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.
@@ -1 +1 @@
1
- import{createImages as m}from"../packem_shared/createImages-TW6ircG2.mjs";import{buildImageDeliveryUrl as i}from"../packem_shared/buildImageDeliveryUrl-eARoj3MG.mjs";import{buildSignedImageUrl as o,verifySignedImageUrl as a}from"../packem_shared/buildSignedImageUrl-Bpu3Hs42.mjs";export{i as buildImageDeliveryUrl,o as buildSignedImageUrl,m as createImages,a as verifySignedImageUrl};
1
+ import{createImages as m}from"../packem_shared/createImages-TW6ircG2.mjs";import{buildImageDeliveryUrl as i}from"../packem_shared/buildImageDeliveryUrl-eARoj3MG.mjs";import{buildSignedImageUrl as o,verifySignedImageUrl as a}from"../packem_shared/buildSignedImageUrl-BzgCHIu6.mjs";export{i as buildImageDeliveryUrl,o as buildSignedImageUrl,m as createImages,a as verifySignedImageUrl};
@@ -0,0 +1,4 @@
1
+ const v=(e,r)=>{if(e.size<r)return;const t=e.keys().next().value;t!==void 0&&e.delete(t)},p=new TextEncoder,u=10080*60,U=/^[a-z][a-z0-9+\-.]*:\/\//i,$=Array.from({length:32},(e,r)=>r),S=new RegExp(`[${$.map(e=>String.fromCodePoint(e)).join("")}]`,"u"),x=e=>{const r=String.fromCodePoint(...e);return btoa(r).replaceAll("+","-").replaceAll("/","_").replaceAll("=","")},A=e=>{const r=e.replaceAll("-","+").replaceAll("_","/")+"===".slice((e.length+3)%4),t=atob(r),n=new Uint8Array(t.length);for(let a=0;a<t.length;a+=1)n[a]=t.codePointAt(a)??0;return n},C=64,m=new Map,f=async e=>{const r=m.get(e);if(r)return r;v(m,C);const t=crypto.subtle.importKey("raw",p.encode(e),{hash:"SHA-256",name:"HMAC"},!1,["sign","verify"]);return m.set(e,t),t},g=e=>{try{return new URL(e).host}catch{return e.replace(U,"").split("/")[0]??""}},y=e=>{if(S.test(e))throw new TypeError("hmac-url: value must not contain control characters (including CR/LF)")},R=async(e,r)=>{const t=await f(e),n=await crypto.subtle.sign("HMAC",t,p.encode(r));return x(new Uint8Array(n))},I=async(e,r,t)=>{const n=await f(e);return crypto.subtle.verify("HMAC",n,t,p.encode(r))},h=/^\//,L=e=>e===void 0?"":Object.entries(e).filter(([,r])=>r!==void 0).toSorted(([r],[t])=>(r>t?1:0)-(r<t?1:0)).map(([r,t])=>`${r}=${typeof t=="object"?JSON.stringify(t):String(t)}`).join("&"),b=(e,r,t,n)=>`${e.toLowerCase()}
2
+ ${r}
3
+ ${String(t)}
4
+ ${n}`,E=e=>e.split("/").map(r=>encodeURIComponent(r)).join("/"),N=async e=>{const r=e.expiresInSeconds??3600;if(!Number.isFinite(r)||r<=0)throw new TypeError("@lunora/bindings/images: expiresInSeconds must be a positive finite number");if(r>u)throw new TypeError(`@lunora/bindings/images: expiresInSeconds must not exceed ${String(u)} (7 days)`);let t="";try{t=new URL(e.baseUrl).pathname}catch{}if(t!==""&&t!=="/")throw new TypeError(`@lunora/bindings/images: baseUrl must not carry a path ("${t}") — the key is verified from the full URL pathname, so a subpath base would make every signed URL fail verification`);const n=Math.floor(Date.now()/1e3)+r,a=g(e.baseUrl),o=L(e.transform),s=e.key.replace(h,"");y(s);const l=await R(e.secret,b(a,s,n,o)),i=e.baseUrl.endsWith("/")?e.baseUrl.slice(0,-1):e.baseUrl,c=E(s),d=o===""?"":`&t=${encodeURIComponent(o)}`;return`${i}/${c}?exp=${String(n)}&sig=${l}${d}`},j=async(e,r,t)=>{let n;try{n=e instanceof URL?e:new URL(e)}catch{return{reason:"malformed",valid:!1}}const a=n.searchParams.get("exp"),o=a===null?Number.NaN:Number(a),s=n.searchParams.get("sig"),l=n.searchParams.get("t")??"";if(!s||!Number.isInteger(o))return{reason:"malformed",valid:!1};if(o<Math.floor(Date.now()/1e3))return{reason:"expired",valid:!1};let i,c;try{i=n.pathname.replace(h,"").split("/").map(w=>decodeURIComponent(w)).join("/"),y(i),c=A(s)}catch{return{reason:"malformed",valid:!1}}const d=t?.expectedHost===void 0?n.host:g(t.expectedHost);return await I(r,b(d,i,o,l),c)?{key:i,transform:l===""?void 0:l,valid:!0}:{reason:"bad_signature",valid:!1}};export{N as buildSignedImageUrl,j as verifySignedImageUrl};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/bindings",
3
- "version": "1.0.0-alpha.14",
3
+ "version": "1.0.0-alpha.16",
4
4
  "description": "Lightweight Cloudflare binding helpers for Lunora — ctx.kv, ctx.images, ctx.analytics, ctx.pipelines, ctx.vectors, ctx.r2sql — one install, per-binding subpaths",
5
5
  "keywords": [
6
6
  "analytics",
@@ -64,8 +64,8 @@
64
64
  "access": "public"
65
65
  },
66
66
  "dependencies": {
67
- "@lunora/errors": "1.0.0-alpha.9",
68
- "@lunora/platform": "1.0.0-alpha.1"
67
+ "@lunora/errors": "1.0.0-alpha.11",
68
+ "@lunora/platform": "1.0.0-alpha.2"
69
69
  },
70
70
  "engines": {
71
71
  "node": "^22.15.0 || >=24.11.0"
@@ -1,4 +0,0 @@
1
- const w=(e,r)=>{if(e.size<r)return;const t=e.keys().next().value;t!==void 0&&e.delete(t)},m=new TextEncoder,u=10080*60,$=/^[a-z][a-z0-9+\-.]*:\/\//i,v=e=>{const r=String.fromCodePoint(...e);return btoa(r).replaceAll("+","-").replaceAll("/","_").replaceAll("=","")},U=e=>{const r=e.replaceAll("-","+").replaceAll("_","/")+"===".slice((e.length+3)%4),t=atob(r),n=new Uint8Array(t.length);for(let a=0;a<t.length;a+=1)n[a]=t.codePointAt(a)??0;return n},x=64,p=new Map,f=async e=>{const r=p.get(e);if(r)return r;w(p,x);const t=crypto.subtle.importKey("raw",m.encode(e),{hash:"SHA-256",name:"HMAC"},!1,["sign","verify"]);return p.set(e,t),t},g=e=>{try{return new URL(e).host}catch{return e.replace($,"").split("/")[0]??""}},A=async(e,r)=>{const t=await f(e),n=await crypto.subtle.sign("HMAC",t,m.encode(r));return v(new Uint8Array(n))},S=async(e,r,t)=>{const n=await f(e);return crypto.subtle.verify("HMAC",n,t,m.encode(r))},y=/^\//,I=e=>e===void 0?"":Object.entries(e).filter(([,r])=>r!==void 0).toSorted(([r],[t])=>(r>t?1:0)-(r<t?1:0)).map(([r,t])=>`${r}=${typeof t=="object"?JSON.stringify(t):String(t)}`).join("&"),h=(e,r,t,n)=>`${e.toLowerCase()}
2
- ${r}
3
- ${String(t)}
4
- ${n}`,R=e=>e.split("/").map(r=>encodeURIComponent(r)).join("/"),C=async e=>{const r=e.expiresInSeconds??3600;if(!Number.isFinite(r)||r<=0)throw new TypeError("@lunora/bindings/images: expiresInSeconds must be a positive finite number");if(r>u)throw new TypeError(`@lunora/bindings/images: expiresInSeconds must not exceed ${String(u)} (7 days)`);let t="";try{t=new URL(e.baseUrl).pathname}catch{}if(t!==""&&t!=="/")throw new TypeError(`@lunora/bindings/images: baseUrl must not carry a path ("${t}") — the key is verified from the full URL pathname, so a subpath base would make every signed URL fail verification`);const n=Math.floor(Date.now()/1e3)+r,a=g(e.baseUrl),s=I(e.transform),o=e.key.replace(y,""),i=await A(e.secret,h(a,o,n,s)),l=e.baseUrl.endsWith("/")?e.baseUrl.slice(0,-1):e.baseUrl,c=R(o),d=s===""?"":`&t=${encodeURIComponent(s)}`;return`${l}/${c}?exp=${String(n)}&sig=${i}${d}`},L=async(e,r,t)=>{let n;try{n=e instanceof URL?e:new URL(e)}catch{return{reason:"malformed",valid:!1}}const a=n.searchParams.get("exp"),s=a===null?Number.NaN:Number(a),o=n.searchParams.get("sig"),i=n.searchParams.get("t")??"";if(!o||!Number.isInteger(s))return{reason:"malformed",valid:!1};if(s<Math.floor(Date.now()/1e3))return{reason:"expired",valid:!1};let l,c;try{l=n.pathname.replace(y,"").split("/").map(b=>decodeURIComponent(b)).join("/"),c=U(o)}catch{return{reason:"malformed",valid:!1}}const d=t?.expectedHost===void 0?n.host:g(t.expectedHost);return await S(r,h(d,l,s,i),c)?{key:l,transform:i===""?void 0:i,valid:!0}:{reason:"bad_signature",valid:!1}};export{C as buildSignedImageUrl,L as verifySignedImageUrl};