palbase 0.14.1 → 0.14.2
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/ai/index.js +2 -2
- package/dist/backend/engine.js +2 -2
- package/dist/backend/env.js +1 -1
- package/dist/backend/index.js +3 -3
- package/dist/backend/stack.js +1 -1
- package/dist/backend/test.js +2 -2
- package/dist/chunks/{VLNIDQ36.js → 3AENUHVO.js} +2 -2
- package/dist/chunks/{YIFQY4BF.js → 427AGWP3.js} +2 -2
- package/dist/chunks/{3CUWIZU2.js → 44ULNVPP.js} +1 -1
- package/dist/chunks/{RZBBS4OL.js → 4UQ4J7RV.js} +2 -2
- package/dist/chunks/{XCY7TFJH.js → 5H7UNNH6.js} +2 -2
- package/dist/chunks/{FZB357V4.js → 6NC5RYCS.js} +1 -1
- package/dist/chunks/{VSB66HSU.js → 7DQ76T2V.js} +2 -2
- package/dist/chunks/{O2LHK2GF.js → A46IASZE.js} +2 -2
- package/dist/chunks/{LND5DXD3.js → BRHGS5AI.js} +2 -2
- package/dist/chunks/{2CR3IN7R.js → CUL5OL4P.js} +2 -2
- package/dist/chunks/{IXOQ6JI5.js → DIOZGDFQ.js} +1 -1
- package/dist/chunks/{7UQMB3JW.js → HHZSOYPP.js} +1 -1
- package/dist/chunks/{RBDGMOJT.js → JKWWY2LJ.js} +2 -2
- package/dist/chunks/LUFWGH2V.js +2 -0
- package/dist/chunks/{GHEORI3H.js → OMK2YEDZ.js} +2 -2
- package/dist/chunks/{2PCIM4VH.js → P67I4TNQ.js} +1 -1
- package/dist/chunks/{NVA3C3Z3.js → PRJZTG2I.js} +1 -1
- package/dist/chunks/{EH4ZWZCT.js → QZH6GPCR.js} +2 -2
- package/dist/chunks/{URK5PA2R.js → RD5JFDGQ.js} +2 -2
- package/dist/chunks/{S6HM2J7J.js → SBUC7GHR.js} +2 -2
- package/dist/chunks/{YYLNEVUC.js → W3OCV3QH.js} +2 -2
- package/dist/chunks/{KLEVI5C3.js → WXNFMEW7.js} +2 -2
- package/dist/chunks/{UXURIXBA.js → ZZNGA77G.js} +1 -1
- package/dist/cli.js +108 -108
- package/dist/refuse/ai.js +1 -1
- package/dist/refuse/backend.js +1 -1
- package/dist/refuse/server.js +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/testing.js +2 -2
- package/dist/web/index.js +2 -2
- package/dist/web/message.js +2 -2
- package/dist/web/palbe.js +2 -2
- package/dist/web/paywall.js +2 -2
- package/dist/web/push-sw.js +1 -1
- package/dist/web/ssr.js +2 -2
- package/dist/web/vite.js +2 -2
- package/package.json +2 -2
- package/types/internal/src/modules/ai.d.ts +3 -7
- package/types/internal/src/modules/secrets.d.ts +1 -1
- package/types/internal/src/modules/stores.d.ts +57 -0
- package/types/server/src/transit.d.ts +8 -1
- package/dist/chunks/WZLLB24Q.js +0 -2
package/dist/refuse/ai.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.14.
|
|
1
|
+
/*! palbase 0.14.2 — Palbase SDK License (see LICENSE) */
|
|
2
2
|
throw new Error("palbase/ai is for servers: it speaks with the project secret key, which never goes into a browser or a mobile app \u2014 call your backend, and let it ask the model");
|
package/dist/refuse/backend.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.14.
|
|
1
|
+
/*! palbase 0.14.2 — Palbase SDK License (see LICENSE) */
|
|
2
2
|
throw new Error("palbase/backend is a server framework: it runs on your backend, never in a browser or a mobile app \u2014 apps use palbase/web (or the native SDKs)");
|
package/dist/refuse/server.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.14.
|
|
1
|
+
/*! palbase 0.14.2 — Palbase SDK License (see LICENSE) */
|
|
2
2
|
throw new Error("palbase/server is for servers: its secret key never goes into a browser or a mobile app \u2014 apps use palbase/web (or the native SDKs) with the publishable key");
|
package/dist/server/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.14.
|
|
2
|
-
import{a as e,b as f,c as g,d as h,e as i,f as j,g as k,h as l,i as m,j as n,k as o,l as p,m as q,n as r,o as s,p as t,q as u,r as v,s as w,t as x,u as y}from"../chunks/
|
|
1
|
+
/*! palbase 0.14.2 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{a as e,b as f,c as g,d as h,e as i,f as j,g as k,h as l,i as m,j as n,k as o,l as p,m as q,n as r,o as s,p as t,q as u,r as v,s as w,t as x,u as y}from"../chunks/LUFWGH2V.js";import{a as c,b as d}from"../chunks/HHZSOYPP.js";import"../chunks/ZZNGA77G.js";import"../chunks/44ULNVPP.js";import{m as b}from"../chunks/OMK2YEDZ.js";import"../chunks/RD5JFDGQ.js";import{b as a}from"../chunks/JKWWY2LJ.js";import"../chunks/P67I4TNQ.js";import"../chunks/6NC5RYCS.js";export{o as AuthUnavailable,b as EVENT_TYPES,c as FieldError,d as Fields,a as PalbaseError,t as ReservationSettled,n as TokenError,q as TokenVerifier,f as Transit,e as TransitRefusal,g as TransitRequest,i as WebhookSignatureError,h as createServer,s as isEntitled,y as loadSecrets,v as pages,x as platformOwn,w as processOwn,r as requestAddress,p as sessionStanding,l as signatureHeader,k as verifySignature,j as verifyWebhook,m as verifyWebhookRequest,u as withReservation};
|
package/dist/server/testing.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.14.
|
|
2
|
-
import{a,b,c,d,e}from"../chunks/
|
|
1
|
+
/*! palbase 0.14.2 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{a,b,c,d,e}from"../chunks/WXNFMEW7.js";import"../chunks/HHZSOYPP.js";import"../chunks/P67I4TNQ.js";import"../chunks/6NC5RYCS.js";export{b as TestApiError,e as api,c as createTestApi,a as testFields,d as testRun};
|
package/dist/web/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.14.
|
|
2
|
-
import{a as M,b as j,c as q,d as G,e as N,f as U,g as D,h as H,i as J,j as B,k as F,l as K,m as W,n as X,o as Y,p as Z,q as ee}from"../chunks/
|
|
1
|
+
/*! palbase 0.14.2 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{a as M,b as j,c as q,d as G,e as N,f as U,g as D,h as H,i as J,j as B,k as F,l as K,m as W,n as X,o as Y,p as Z,q as ee}from"../chunks/4UQ4J7RV.js";import{a as _,b as Q,f as z}from"../chunks/5H7UNNH6.js";import"../chunks/7DQ76T2V.js";import"../chunks/W3OCV3QH.js";import"../chunks/PRJZTG2I.js";import{b as E,c as T,d as x,f as O,g as A,j as R,k as $,l as V,m as v,o as S}from"../chunks/ZZNGA77G.js";import"../chunks/3AENUHVO.js";import"../chunks/OMK2YEDZ.js";import"../chunks/RD5JFDGQ.js";import{b as L}from"../chunks/JKWWY2LJ.js";import"../chunks/P67I4TNQ.js";import"../chunks/6NC5RYCS.js";var te="oai-events";async function ne(e){if(typeof e?.start!="function")throw new TypeError("connectVoice: start(sdp) is the round trip to the app's backend, which starts the voice (chats.voice.start) and answers { id, sdp }");let r=e.rtc??se(),t=e.signal;t?.throwIfAborted();let f=e.audio??ae(),l=e.microphone===void 0,c=e.microphone??await r.getUserMedia({audio:!0});if(t?.aborted){if(l)for(let n of c.getTracks())n.stop();throw t.reason}let o=new r.RTCPeerConnection,s=!1,u=()=>{if(!s){if(s=!0,m.close(),o.close(),l)for(let n of c.getTracks())n.stop();f.srcObject!==null&&(f.srcObject=null)}};o.addEventListener("track",n=>{f.srcObject=n.streams[0]??new MediaStream([n.track]),f.play?.()?.catch?.(()=>{})}),o.addEventListener("connectionstatechange",()=>e.onState?.(o.connectionState));for(let n of c.getAudioTracks())o.addTrack(n,c);let m=o.createDataChannel(te);m.addEventListener("message",n=>{let p=oe(n.data);p!==void 0&&e.onError?.(p)});let d=()=>u();t?.addEventListener("abort",d,{once:!0});try{await o.setLocalDescription(await o.createOffer()),t?.throwIfAborted(),await re(o,e.iceTimeoutMs??1e4,t);let n=o.localDescription?.sdp;if(!n)throw new Error("connectVoice: the peer connection made no offer");let p=await e.start(n);if(t?.throwIfAborted(),typeof p?.id!="string"||p.id===""||typeof p.sdp!="string"||p.sdp==="")throw new TypeError("connectVoice: start answered no voice \u2014 it is { id, sdp }, chats.voice.start's answer as the backend got it");return await o.setRemoteDescription({type:"answer",sdp:p.sdp}),t?.removeEventListener("abort",d),{id:p.id,peer:o,audio:f,microphone:c,get muted(){return c.getAudioTracks().every(h=>!h.enabled)},mute(h){for(let w of c.getAudioTracks())w.enabled=!h},close:u}}catch(n){throw t?.removeEventListener("abort",d),u(),t?.aborted?t.reason:n}}function re(e,r,t){return e.iceGatheringState==="complete"?Promise.resolve():t?.aborted?Promise.reject(t.reason):new Promise((f,l)=>{let c=()=>{clearTimeout(u),e.removeEventListener("icegatheringstatechange",o),t?.removeEventListener("abort",s)},o=()=>{e.iceGatheringState==="complete"&&(c(),f())},s=()=>{c(),l(t?.reason)},u=setTimeout(()=>{c(),l(new Error(`connectVoice: the network candidates were not gathered in ${r} ms`))},r);e.addEventListener("icegatheringstatechange",o),t?.addEventListener("abort",s,{once:!0})})}function oe(e){if(typeof e=="string")try{let r=JSON.parse(e);return r.type!=="error"?void 0:typeof r.error?.message=="string"?r.error.message:typeof r.error?.code=="string"?r.error.code:"the voice failed"}catch{return}}function se(){let e=globalThis;if(typeof e.RTCPeerConnection!="function"||typeof e.navigator?.mediaDevices?.getUserMedia!="function")throw new TypeError("connectVoice: this runtime has no WebRTC (RTCPeerConnection, navigator.mediaDevices): a chat's voice is a browser's");let r=e.navigator.mediaDevices;return{RTCPeerConnection:e.RTCPeerConnection,getUserMedia:t=>r.getUserMedia(t)}}function ae(){let e=globalThis.document;if(!e)throw new TypeError("connectVoice: give audio \u2014 the element the voice plays in \u2014 where there is no document");let r=e.createElement("audio");return r.autoplay=!0,r}var i=e=>typeof e=="object"&&e!==null&&!Array.isArray(e)?e:void 0;function ie(e,r,t){let f=i(i(i(e)?.components)?.schemas)??{},l=(d,n)=>{let p=new Set,h=(C,g,y)=>{let a=i(C);if(!a)return;if(typeof a.$ref=="string"){if(y.has(a.$ref)||!a.$ref.startsWith("#/components/schemas/"))return;h(f[a.$ref.slice(21)],g,new Set(y).add(a.$ref));return}if(a[E]===!0){p.add(g);return}for(let b of["anyOf","oneOf","allOf"]){let k=a[b];if(Array.isArray(k))for(let I of k)h(I,g,y)}let P=i(a.properties);if(P)for(let[b,k]of Object.entries(P))h(k,`${g}/${v(b)}`,y);i(a.items)&&h(a.items,`${g}/*`,y);for(let b of["additionalProperties","patternProperties","prefixItems"])if(a[b]!==void 0&&w(a[b],new Set(y)))throw new Error(`${t}: an encrypted field is a named property \u2014 not every key of a record, nor a tuple's place`)},w=(C,g)=>{if(Array.isArray(C))return C.some(a=>w(a,g));let y=i(C);return y?y[E]===!0?!0:typeof y.$ref=="string"&&!g.has(y.$ref)&&y.$ref.startsWith("#/components/schemas/")?(g.add(y.$ref),w(f[y.$ref.slice(21)],g)):Object.values(y).some(a=>typeof a=="object"&&a!==null&&w(a,g)):!1};return h(d,n,new Set),[...p]},c=d=>i(i(i(d)?.["application/json"])?.schema),o=[];o.push(...l(c(i(r.requestBody)?.content),"/body"));for(let d of Array.isArray(r.parameters)?r.parameters:[]){let n=i(d);if(!n)continue;let p=l(n.schema,`/query/${v(String(n.name))}`);if(p.length!==0){if(n.in!=="query")throw new Error(`${t}: ${String(n.in)} parameter ${String(n.name)} is marked encrypted \u2014 a body's or a query's field is`);if(p.some(h=>h.split("/").length!==3))throw new Error(`${t}: an encrypted query field is one of the query's own names`);o.push(...p)}}let s=i(r.responses)??{},u=Object.keys(s).filter(d=>/^2\d\d$/.test(d)).sort((d,n)=>d==="200"?-1:n==="200"?1:d.localeCompare(n)),m=u.length>0?l(c(i(s[u[0]])?.content),"/response"):[];if(o.length+m.length!==0){if(r["x-palbase-sse"]!==void 0&&m.length>0)throw new Error(`${t}: a streamed answer carries no encrypted field`);if(r["x-palbase-upload"]!==void 0)throw new Error(`${t}: an upload goes through storage, which seals nothing \u2014 it carries no encrypted field`);return{request:o,response:m}}}async function ce(e){let r=`${e.method.toUpperCase()} ${e.path}`,t=i(i(i(i(e.contract)?.paths)?.[e.path])?.[e.method.toLowerCase()]),f=t?ie(e.contract,t,r):void 0;if(!f)return{body:e.body,query:e.query,open:async s=>s};let{key:l,header:c}=await A(e.key.kid,x(e.key.publicKey),O(e.projectId,e.method,e.path,e.params??[])),o=(s,u)=>s==null?s:S(s,u,f.request,(m,d)=>R(l,m,d));return{header:c,body:await o(e.body,"/body"),query:await o(e.query,"/query"),open:s=>s===void 0?Promise.resolve(s):S(s,"/response",f.response,async(u,m)=>{if(!$(m))throw new T("unopenable",`${r}: ${u} came plain where the contract says it is encrypted`);return V(l,u,m)})}}export{D as Analytics,_ as BackendError,G as Channel,H as Consent,Z as Flags,z as GatewayError,F as InApp,J as Inbox,U as Installation,W as Notify,L as PalbaseError,X as Purchases,N as RealtimeSocket,B as SESSION_START,M as SessionChangedError,K as WebPush,ne as connectVoice,ee as createClient,ce as encryptedCall,Q as isBackendError,q as localStore,j as memoryStore,Y as redemptionToken};
|
package/dist/web/message.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.14.
|
|
2
|
-
import{a as i}from"../chunks/
|
|
1
|
+
/*! palbase 0.14.2 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{a as i}from"../chunks/W3OCV3QH.js";import{a as e,b as s,c as t,d as p,e as o,f as a,h as r,j as n,k as y,p as M,q as l,t as g}from"../chunks/PRJZTG2I.js";import"../chunks/6NC5RYCS.js";export{n as MESSAGE_COMPONENTS,a as MESSAGE_ICONS,r as MESSAGE_SCHEMA,s as assetId,y as countdownValues,e as fontFamily,o as htmlDocument,t as prepareAssets,i as presentMessage,g as renderMessage,M as resolveMessage,l as resolveMessageWithPaths,p as unzip};
|
package/dist/web/palbe.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.14.
|
|
2
|
-
import{c as e,d as r,i as t}from"../chunks/
|
|
1
|
+
/*! palbase 0.14.2 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{c as e,d as r,i as t}from"../chunks/5H7UNNH6.js";import"../chunks/ZZNGA77G.js";import"../chunks/3AENUHVO.js";import"../chunks/RD5JFDGQ.js";import"../chunks/JKWWY2LJ.js";import"../chunks/P67I4TNQ.js";import"../chunks/6NC5RYCS.js";export{e as RESERVED_CLIENT_NAMES,t as __registerBackend,r as isClientName};
|
package/dist/web/paywall.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.14.
|
|
2
|
-
import{a as f,b as d,c as m,d as u,e as A,f as c,g as R}from"../chunks/
|
|
1
|
+
/*! palbase 0.14.2 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{a as f,b as d,c as m,d as u,e as A,f as c,g as R}from"../chunks/7DQ76T2V.js";import{a as e,b as a,c as t,d as l,e as r,f as o,g as p,i as y,k as s,l as P,n,o as i,s as w}from"../chunks/PRJZTG2I.js";import"../chunks/JKWWY2LJ.js";import"../chunks/P67I4TNQ.js";import"../chunks/6NC5RYCS.js";export{y as PAYWALL_COMPONENTS,o as PAYWALL_ICONS,p as PAYWALL_SCHEMA,c as Paywall,a as assetId,f as attributesHeader,s as countdownValues,R as defaultPaywall,e as fontFamily,u as formatPeriod,m as formatPrice,r as htmlDocument,A as packageValues,P as packagesOf,d as parseDuration,t as prepareAssets,w as renderPaywall,n as resolvePaywall,i as resolvePaywallWithPaths,l as unzip};
|
package/dist/web/push-sw.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.14.
|
|
1
|
+
/*! palbase 0.14.2 — Palbase SDK License (see LICENSE) */
|
|
2
2
|
"use strict";(()=>{function f(e,s){if(e)try{let i=new URL(e,s);if(i.protocol==="https:"||i.protocol==="http:"&&(i.hostname==="localhost"||i.hostname==="127.0.0.1"))return i.href}catch{}}function g(e){let s=new URL(e.location.href).searchParams,i=s.get("url")??"",l=s.get("key")??"",r=(n,t)=>!n||!i?Promise.resolve():e.fetch(`${i.replace(/\/$/,"")}/notify/receipts`,{method:"POST",headers:{"content-type":"application/json",apikey:l},body:JSON.stringify({receipts:[{receipt:n,status:t}]}),keepalive:!0}).catch(()=>{}),a=async(n,t)=>{for(let o of await e.clients.matchAll({type:"window",includeUncontrolled:!0}))o.postMessage({type:"palbase.push",event:n,url:t.url,data:t.data})};e.addEventListener("push",(n=>{let t={};try{t=n.data?.json()??{}}catch{}let o={url:t.url,receipt:t.receipt,data:t.data};n.waitUntil(e.registration.showNotification(t.title??"",{body:t.body,image:t.image,tag:t.tag,data:o}).then(()=>Promise.all([r(t.receipt,"delivered"),a("received",o)])))})),e.addEventListener("notificationclick",(n=>{n.notification.close();let t=n.notification.data??{},o=f(t.url,e.location.origin),c=async()=>{if(!o)return;let d=(await e.clients.matchAll({type:"window",includeUncontrolled:!0})).find(u=>u.url===o);d?await d.focus():await e.clients.openWindow(o)};n.waitUntil(Promise.all([r(t.receipt,"opened"),c(),a("opened",t)]))})),e.addEventListener("notificationclose",(n=>{n.waitUntil(r(n.notification.data?.receipt,"dismissed"))}))}typeof self<"u"&&typeof self.registration=="object"&&!("document"in self)&&g(self);})();
|
package/dist/web/ssr.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.14.
|
|
2
|
-
import{q as f}from"../chunks/
|
|
1
|
+
/*! palbase 0.14.2 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{q as f}from"../chunks/4UQ4J7RV.js";import"../chunks/5H7UNNH6.js";import"../chunks/7DQ76T2V.js";import"../chunks/W3OCV3QH.js";import"../chunks/PRJZTG2I.js";import"../chunks/ZZNGA77G.js";import"../chunks/3AENUHVO.js";import"../chunks/OMK2YEDZ.js";import"../chunks/RD5JFDGQ.js";import"../chunks/JKWWY2LJ.js";import"../chunks/P67I4TNQ.js";import"../chunks/6NC5RYCS.js";var C=Object.freeze({"Cache-Control":"private, no-cache, no-store, must-revalidate, max-age=0",Expires:"0",Pragma:"no-cache"}),x={path:"/",sameSite:"lax",secure:!0,httpOnly:!1,maxAge:400*24*60*60},u=3180,k=5*6e4;function d(t){let e=/^pb_([a-z0-9]+)_c/.exec(t)?.[1];if(e===void 0)throw new TypeError("publishableKey is the project publishable key (pb_<ref>_c\u2026)");return`pb-${e}-session`}var y=t=>{let e=new TextEncoder().encode(JSON.stringify(t)),o="";for(let s of e)o+=String.fromCharCode(s);return btoa(o).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},b=t=>{try{let e=atob(t.replace(/-/g,"+").replace(/_/g,"/")),o=JSON.parse(new TextDecoder().decode(Uint8Array.from(e,s=>s.charCodeAt(0))));return typeof o.accessToken!="string"||typeof o.refreshToken!="string"||typeof o.expiresAt!="number"||typeof o.userId!="string"?null:o}catch{return null}};function m(t,e,o={},s=!1){let c={...x,...o},g=async()=>new Map((await e.getAll()).map(n=>[n.name,n.value])),S=n=>n===t||n.startsWith(`${t}.`)&&/^\d+$/.test(n.slice(t.length+1)),h=async n=>{if(!e.setAll)return;let i=n===null?[]:n.length<=u?[[t,n]]:Array.from({length:Math.ceil(n.length/u)},(r,l)=>[`${t}.${l}`,n.slice(l*u,(l+1)*u)]),p=new Set(i.map(([r])=>r)),a=i.map(([r,l])=>({name:r,value:l,options:c}));for(let r of(await g()).keys())S(r)&&!p.has(r)&&a.push({name:r,value:"",options:{...c,maxAge:0}});a.length>0&&await e.setAll(a,{...C})};return{async load(){let n=await g(),i=n.get(t);if(i===void 0){let p="";for(let a=0;n.has(`${t}.${a}`);a++)p+=n.get(`${t}.${a}`);i=p}return i?b(i):null},save:n=>h(y(n)),clear:()=>h(null),shared:s}}function A(t){let{cookies:e,cookieOptions:o,...s}=t,c=t.refresh??(e.setAll?"before":"never");return f({...s,refresh:c,storage:m(d(t.publishableKey),e,o)})}function O(){let t=()=>{let e=globalThis.document;if(!e)throw new Error("documentCookies: there is no document here \u2014 a server gives its request's cookies to createServerClient");return e};return{getAll:()=>t().cookie.split(";").map(e=>e.trim()).filter(e=>e.includes("=")).map(e=>{let o=e.indexOf("=");return{name:e.slice(0,o),value:e.slice(o+1)}}),setAll(e){for(let o of e){let s=o.options,c=[`Path=${s.path??"/"}`,s.domain?`Domain=${s.domain}`:"",s.maxAge!==void 0?`Max-Age=${s.maxAge}`:"",s.expires?`Expires=${s.expires.toUTCString()}`:"",s.sameSite?`SameSite=${s.sameSite.charAt(0).toUpperCase()}${s.sameSite.slice(1)}`:"",s.secure?"Secure":""].filter(Boolean);t().cookie=[`${o.name}=${o.value}`,...c].join("; ")}}}}function $(t){let{cookieOptions:e,...o}=t,s=globalThis.location?.protocol==="https:";return f({...o,storage:m(d(t.publishableKey),O(),{secure:s,...e},!0)})}async function v(t){let e=await t.auth.currentSession();if(!e||(e.expiresAt-Date.now()<=k&&await t.auth.refreshSession().catch(()=>{}),!await t.auth.currentSession()))return null;try{return(await t.auth.api.verifyTokenUser()).data}catch(o){if(o.status===401)return null;throw o}}export{C as NO_STORE_HEADERS,x as SESSION_COOKIE_OPTIONS,m as cookieSessionStore,$ as createBrowserClient,A as createServerClient,O as documentCookies,v as keepSession,d as sessionCookieName};
|
package/dist/web/vite.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
/*! palbase 0.14.
|
|
2
|
-
import"../chunks/
|
|
1
|
+
/*! palbase 0.14.2 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import"../chunks/6NC5RYCS.js";import{execFile as $}from"node:child_process";import{existsSync as y,mkdtempSync as k,readFileSync as S,rmSync as x,writeFileSync as P}from"node:fs";import{createRequire as O}from"node:module";import{tmpdir as W}from"node:os";import{dirname as g,join as o,relative as u,resolve as v,sep as d}from"node:path";var E=/\.(?:ts|js|mts|mjs)$/;function F(n){if(!/^[a-z][a-z0-9-]*$/.test(n.app))throw new TypeError(`palbase({ app }): ${JSON.stringify(n.app)} is an app's slug (palbase apps:list)`);let c=process.cwd(),p="",i="",f=()=>v(c,n.dir??"palbase"),m=()=>{let e=n.environments[p];if(!e)throw new Error(`palbase: the mode "${p}" is not built against any environment \u2014 say which in vite.config: palbase({ environments: { ${JSON.stringify(p)}: '<environment slug>' } })`);return e};return{name:"palbase",enforce:"pre",config(e,s){p=s.mode,i=s.command??"";let r=e.build?.rollupOptions?.onwarn;return{build:{rollupOptions:{onwarn(t,a){let l=String(t.exporter??t.id??"");if(t.code==="MISSING_EXPORT"&&l.includes(`${d}environments${d}`))throw new Error(`palbase: ${t.message} \u2014 ${m()}'s backend has no such route (palbase apps:sync brings what it has)`);r?r(t,a):a(t)}}}}},configResolved(e){c=e.root,p=e.mode,i=e.command??i},async buildStart(){i!=="build"||n.typecheck===!1||await j(c,m(),n.tsconfig)},resolveId(e,s){if(!s)return null;let r=f();if(e==="palbase"||e.startsWith("palbase/")){let w=u(r,s);return w.startsWith("..")||w===""?null:this.resolve(e,o(c,"index.html"),{skipSelf:!0})}if(!(e.startsWith(".")||e.startsWith("/")))return null;let t=v(g(s),e);if(E.test(t)||(t+=".ts"),g(t)!==r&&g(t)!==o(r,"palbe"))return null;let a=u(r,t),l=`${n.app}.ts`;if(a!==l&&!a.startsWith(`palbe${d}`))return null;let h=m(),b=o(r,"environments",h,a===l?l:o("palbe",a.slice(`palbe${d}`.length)));if(!y(b))throw new Error(`palbase: ${u(c,b)} is not there \u2014 palbase apps:sync writes it (is ${n.app} set in ${h}, and has ${h} that machine?)`);return b}}}async function j(n,c,p){let i=p?v(n,p):["tsconfig.app.json","tsconfig.json"].map(e=>o(n,e)).find(y);if(!i)return;if(!y(i))throw new Error(`palbase({ tsconfig }): ${u(n,i)} is not there`);let f;try{let e=O(o(n,"package.json")).resolve("typescript/package.json"),s=JSON.parse(S(e,"utf8")).bin?.tsc;if(!s)throw new Error("no tsc");f=o(g(e),s)}catch{throw new Error("palbase: the build type-checks the app against its environment with the app's TypeScript, and the app has none (npm i -D typescript) \u2014 or say palbase({ typecheck: false })")}let m=k(o(W(),"palbase-typecheck-"));try{let e=o(m,"tsconfig.json");P(e,JSON.stringify({extends:i,compilerOptions:{noEmit:!0,composite:!1,incremental:!1,moduleSuffixes:[`.${c}`,""]}}));let s=await new Promise(r=>$(process.execPath,[f,"-p",e,"--pretty","false"],{cwd:n,maxBuffer:16<<20},(t,a,l)=>r({code:t?typeof t.code=="number"?t.code:1:0,text:`${a}${l}`.trim()})));if(s.code!==0)throw new Error(`palbase: the app does not type-check against ${c}, the environment this build is made for \u2014 a route its backend does not have, or a call that does not fit it:
|
|
3
3
|
${s.text}`)}finally{x(m,{recursive:!0,force:!0})}}export{F as palbase};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "palbase",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.2",
|
|
4
4
|
"description": "Palbase for JavaScript: the web client (palbase/web), the server SDK (palbase/server), the backend framework (palbase/backend), AI (palbase/ai) and the CLI (npx palbase).",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"homepage": "https://palbase.studio",
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
"dependencies": {
|
|
136
136
|
"@types/node": "26.6.4",
|
|
137
137
|
"bun-types": "1.4.2",
|
|
138
|
-
"palgres": "0.14.
|
|
138
|
+
"palgres": "0.14.2",
|
|
139
139
|
"reflect-metadata": "^0.2.2",
|
|
140
140
|
"typescript": "~6.0.3",
|
|
141
141
|
"zod": "^4.6.5"
|
|
@@ -52,13 +52,9 @@ export type Agent = {
|
|
|
52
52
|
updated_by?: string;
|
|
53
53
|
};
|
|
54
54
|
/**
|
|
55
|
-
* What an agent is: its instructions, model, tools and subagents, and the shape of its one-shot answers
|
|
55
|
+
* What an agent is: its instructions, model, tools and subagents, and the shape of its one-shot answers.
|
|
56
56
|
*/
|
|
57
57
|
export type AgentDefinition = {
|
|
58
|
-
/**
|
|
59
|
-
* The project's machine that defines the agent at each turn.
|
|
60
|
-
*/
|
|
61
|
-
backend?: string;
|
|
62
58
|
/**
|
|
63
59
|
* The window, in tokens, the turn works in (the model's standard one unless said; more is billed as its provider bills it — GET /ai/models, context_window and max_input_tokens).
|
|
64
60
|
*/
|
|
@@ -2612,7 +2608,7 @@ export declare function client(t: Transport): {
|
|
|
2612
2608
|
/**
|
|
2613
2609
|
* Save an agent's draft
|
|
2614
2610
|
*
|
|
2615
|
-
* Saves the draft of an agent the project keeps — a new one's first. What its chats talk to changes only once the draft is published. revision names the draft the change was made to: when another was saved since, it is refused (409 draft_changed) and nothing is lost; left out, the last save wins. A name its backend's build defines is refused (409 agent_defined_in_code): that agent is changed in the code.
|
|
2611
|
+
* Saves the draft of an agent the project keeps — a new one's first. What its chats talk to changes only once the draft is published. revision names the draft the change was made to: when another was saved since, it is refused (409 draft_changed) and nothing is lost; left out, the last save wins. A name its backend's build defines is refused (409 agent_defined_in_code): that agent is changed in the code.
|
|
2616
2612
|
*/
|
|
2617
2613
|
putAgent(input: {
|
|
2618
2614
|
path: {
|
|
@@ -2627,7 +2623,7 @@ export declare function client(t: Transport): {
|
|
|
2627
2623
|
/**
|
|
2628
2624
|
* Forget an agent
|
|
2629
2625
|
*
|
|
2630
|
-
* An agent the project keeps, its versions with it — an agent made again under its name numbers its versions after them, and a chat on one of them is told it is gone
|
|
2626
|
+
* An agent the project keeps, its versions with it — an agent made again under its name numbers its versions after them, and a chat on one of them is told it is gone. Its chats stay; a message to one of them is refused (agent_not_found) until an agent of that name is there again. One its backend's build declares goes with the code (409 agent_defined_in_code).
|
|
2631
2627
|
*/
|
|
2632
2628
|
deleteAgent(input: {
|
|
2633
2629
|
path: {
|
|
@@ -349,7 +349,7 @@ export declare function client(t: Transport): {
|
|
|
349
349
|
query?: {
|
|
350
350
|
limit?: number; /** The next_cursor of the previous page. Opaque; omit it for the first page. */
|
|
351
351
|
cursor?: string; /** Only this environment's entries. */
|
|
352
|
-
environment?: "development" | "production"; /** Only this secret's entries. */
|
|
352
|
+
environment?: "development" | "production"; /** Only this secret's entries; this encrypted field's (its address: table.column, or schema.table.column); or this key's, a field key's (k2) or a transit key's (t2). */
|
|
353
353
|
name?: string;
|
|
354
354
|
}; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
355
355
|
signal?: AbortSignal;
|
|
@@ -501,6 +501,10 @@ export type AppleHealth = {
|
|
|
501
501
|
* Its App Store versions' terminations, hangs and launches.
|
|
502
502
|
*/
|
|
503
503
|
metrics: HealthMetric[];
|
|
504
|
+
/**
|
|
505
|
+
* The newest builds' TestFlight counts, newest first: what Apple counted of each from its upload, at most a year back.
|
|
506
|
+
*/
|
|
507
|
+
testflight_builds: TestFlightBuildUsage[];
|
|
504
508
|
/**
|
|
505
509
|
* The newest crashes testers sent from TestFlight (read one with its log: GET …/feedback/crash/{id}).
|
|
506
510
|
*/
|
|
@@ -2029,6 +2033,59 @@ export type SubmitRequest = {
|
|
|
2029
2033
|
*/
|
|
2030
2034
|
in_app_purchases?: string[];
|
|
2031
2035
|
};
|
|
2036
|
+
/**
|
|
2037
|
+
* What TestFlight counted of one of an iOS app's builds, as Apple keeps it.
|
|
2038
|
+
*/
|
|
2039
|
+
export type TestFlightBuildUsage = {
|
|
2040
|
+
/**
|
|
2041
|
+
* The build at App Store Connect.
|
|
2042
|
+
*/
|
|
2043
|
+
asc_build_id: string;
|
|
2044
|
+
/**
|
|
2045
|
+
* Its build number (CFBundleVersion).
|
|
2046
|
+
*/
|
|
2047
|
+
build_number: string;
|
|
2048
|
+
/**
|
|
2049
|
+
* Crashes on testers' devices.
|
|
2050
|
+
*/
|
|
2051
|
+
crashes: number;
|
|
2052
|
+
/**
|
|
2053
|
+
* Whether it expired in TestFlight.
|
|
2054
|
+
*/
|
|
2055
|
+
expired: boolean;
|
|
2056
|
+
/**
|
|
2057
|
+
* Feedback testers sent of it.
|
|
2058
|
+
*/
|
|
2059
|
+
feedback: number;
|
|
2060
|
+
/**
|
|
2061
|
+
* The first day Apple counted (absent while Apple keeps no counts of it).
|
|
2062
|
+
*/
|
|
2063
|
+
from?: string;
|
|
2064
|
+
/**
|
|
2065
|
+
* Installs by testers.
|
|
2066
|
+
*/
|
|
2067
|
+
installs: number;
|
|
2068
|
+
/**
|
|
2069
|
+
* Invitations it went out with.
|
|
2070
|
+
*/
|
|
2071
|
+
invites: number;
|
|
2072
|
+
/**
|
|
2073
|
+
* Sessions testers ran it.
|
|
2074
|
+
*/
|
|
2075
|
+
sessions: number;
|
|
2076
|
+
/**
|
|
2077
|
+
* The last day Apple counted.
|
|
2078
|
+
*/
|
|
2079
|
+
to?: string;
|
|
2080
|
+
/**
|
|
2081
|
+
* When it was uploaded.
|
|
2082
|
+
*/
|
|
2083
|
+
uploaded_at: string;
|
|
2084
|
+
/**
|
|
2085
|
+
* Its app version (CFBundleShortVersionString).
|
|
2086
|
+
*/
|
|
2087
|
+
version: string;
|
|
2088
|
+
};
|
|
2032
2089
|
/**
|
|
2033
2090
|
* A person to have in a group.
|
|
2034
2091
|
*/
|
|
@@ -32,11 +32,13 @@ export interface TransitOptions {
|
|
|
32
32
|
fetch: (signal?: AbortSignal) => Promise<TransitKeySet>;
|
|
33
33
|
/** The clock (tests). */
|
|
34
34
|
now?: () => number;
|
|
35
|
+
/** Waits ms on that clock (tests). */
|
|
36
|
+
sleep?: (ms: number) => Promise<void>;
|
|
35
37
|
}
|
|
36
38
|
/**
|
|
37
39
|
* The project's transit keys. `await load()` once at startup: requests are
|
|
38
40
|
* opened with the keys held, fetched again every minute and when a request
|
|
39
|
-
* names a key
|
|
41
|
+
* names a key newer than every one held.
|
|
40
42
|
*/
|
|
41
43
|
export declare class Transit {
|
|
42
44
|
private keys;
|
|
@@ -45,9 +47,12 @@ export declare class Transit {
|
|
|
45
47
|
private project;
|
|
46
48
|
private timer;
|
|
47
49
|
private fetchedAt;
|
|
50
|
+
/** When the fetch whose keys are held began. */
|
|
51
|
+
private heldFrom;
|
|
48
52
|
private fetching;
|
|
49
53
|
private readonly opts;
|
|
50
54
|
private readonly now;
|
|
55
|
+
private readonly sleep;
|
|
51
56
|
constructor(opts: TransitOptions);
|
|
52
57
|
/** Whether the keys are loaded. */
|
|
53
58
|
get loaded(): boolean;
|
|
@@ -60,6 +65,8 @@ export declare class Transit {
|
|
|
60
65
|
/** Stops the refresh. */
|
|
61
66
|
close(): void;
|
|
62
67
|
private refresh;
|
|
68
|
+
/** The newest key the project is known to have made, held or retired. */
|
|
69
|
+
private newest;
|
|
63
70
|
private key;
|
|
64
71
|
/**
|
|
65
72
|
* A request's key, from its Palbase-Encryption header: sealed for this
|
package/dist/chunks/WZLLB24Q.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! palbase 0.14.1 — Palbase SDK License (see LICENSE) */
|
|
2
|
-
import{b as R}from"./7UQMB3JW.js";import{a as m,c as V,d as J,e as Y,f as G,h as X,i as Z,j as A,k as Q,l as ee,o as P}from"./UXURIXBA.js";import{a as te}from"./3CUWIZU2.js";import{a as K,b as U,c as C,d as L,e as $,f as I,g as N,h as D,i as F,j as W,k as B,l as H}from"./GHEORI3H.js";import{a as q,b as z}from"./URK5PA2R.js";import{b as T,d as S}from"./RBDGMOJT.js";var f=class extends Error{status=400;code;data;constructor(e,t,r={}){super(t),this.name="TransitRefusal",this.code=e,this.data=r}},ve=6e4,_e=1e4,k=class{keys=new Map;retired=new Set;order=[];project;timer;fetchedAt=0;fetching;opts;now;constructor(e){this.opts=e,this.now=e.now??Date.now}get loaded(){return this.project!==void 0}get projectId(){if(this.project===void 0)throw new Error("the project's transit keys are not loaded: await palbase.transit.load() at startup");return this.project}current(){return this.order[0]}async load(e){await this.refresh(e),this.timer===void 0&&(this.timer=setInterval(()=>{this.refresh().catch(()=>{})},ve),this.timer.unref?.())}close(){clearInterval(this.timer),this.timer=void 0}refresh(e){return this.fetching??=(async()=>{try{let t=await this.opts.fetch(e),r=new Map;for(let s of t.keys){let i=J(s.key);r.set(s.id,{privateKey:i,publicKey:this.keys.get(s.id)?.publicKey??await Y(i)})}this.keys=r,this.order=t.keys.map(s=>s.id),this.retired=new Set(t.retired),this.project=t.project,this.fetchedAt=this.now()}finally{this.fetching=void 0}})(),this.fetching}async key(e){let t=this.keys.get(e);t===void 0&&!this.retired.has(e)&&this.now()-this.fetchedAt>=_e&&(await this.refresh(),t=this.keys.get(e));let r=this.current();if(this.retired.has(e))throw new f("encryption_key_retired",`the request is sealed to ${e}, retired: fetch the project's keys again`,{current:r});if(t===void 0)throw new f("encryption_key_unknown",`the request is sealed to ${e}, which the project has not made`,{current:r});return t}async request(e){if(e.header===void 0||e.header===null||e.header==="")throw new f("encryption_required",`this route carries encrypted fields: the request names its key in ${m}`,{field:m,current:this.current()});let t;try{t=X(e.header).kid}catch{throw new f("encryption_unopenable",`${m} is not one`,{field:m})}let r=await this.key(t),s;try{s=G(this.projectId,e.method,e.path,e.params??[])}catch{throw new f("encryption_unopenable","the request's path holds a value no key is sealed for",{field:m})}try{return new v(t,await Z(e.header,r.privateKey,r.publicKey,s))}catch(i){throw i instanceof V?new f("encryption_unopenable","the request's key does not open: sealed for another project, route or path, or changed",{field:m}):i}}},v=class{kid;key;constructor(e,t){this.kid=e,this.key=t}async open(e,t,r){return P(e,t,r,async(s,i)=>{if(!Q(i))throw new f("encryption_required",`${s} is an encrypted field: it came plain`,{field:s});try{return await ee(this.key,s,i)}catch{throw new f("encryption_unopenable",`${s} does not open: changed, moved from another field, or another request's`,{field:s})}})}async seal(e,t){return P(e,"/response",t,(r,s)=>A(this.key,r,s))}sealField(e,t){return A(this.key,e,t)}};var Ee=/^pb_[a-z0-9]+_s/;function x(n){if(te())throw new TypeError("palbase/server runs on a server: its secret key never goes into a browser or a mobile app \u2014 apps use palbase/web (or the native SDKs) with the publishable key");if(typeof n.secretKey!="string"||!Ee.test(n.secretKey))throw new TypeError("secretKey is the project secret key (pb_<ref>_s\u2026); a publishable key belongs in palbase/web");let e=z(S({baseUrl:n.url,credentials:{secretKey:n.secretKey},fetch:n.fetch,solveProofOfWork:n.solveProofOfWork??!1}),n.retry??q),t=W.client(e);return{ai:K.client(e),analytics:U.client(e),auth:C.client(e),cache:L.client(e),fields:new R({fetch:async r=>(await t.getFieldKeys({signal:r})).data}),flags:$.client(e),machines:I.client(e),notify:N.client(e),purchases:D.client(e),realtime:F.client(e),secrets:t,storage:B.client(e),stores:H.client(e),transit:new k({fetch:async r=>(await t.getTransitKeys({signal:r})).data}),transport:e,url:new URL(n.url).origin}}var h=class extends Error{code;constructor(e,t){super(t),this.name="WebhookSignatureError",this.code=e}},Ae=300,Pe=/^[0-9]{1,12}$/,Re=/^[0-9a-f]{64}$/,ne=8,xe=/^whsec_[0-9A-Za-z]{32,}$/,Oe=1024*1024;async function re(n){if(typeof n.secret!="string"||!xe.test(n.secret))throw new TypeError("secret is the webhook endpoint secret (whsec_\u2026), not an API key");await se(n);let e;try{e=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(oe(n.body)))}catch{throw new h("invalid_body","the signed body is not JSON")}if(!Le(e))throw new h("invalid_body","the signed body is not a Palbase event (id, type, project_id, created_at, data)");return e}async function se(n){if(typeof n.secret!="string"||n.secret==="")throw new TypeError("secret is the key the request was signed with");let e=oe(n.body),{t,v1:r}=ie(n),s=await crypto.subtle.importKey("raw",new TextEncoder().encode(n.secret),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),i=new Uint8Array(await crypto.subtle.sign("HMAC",s,Ce(new TextEncoder().encode(`${t}.`),e))),a=!1;for(let d of r)Ue(i,Ke(d))&&(a=!0);if(!a)throw new h("signature_mismatch","no v1 in Palbase-Signature is this body signed with this secret")}function ie(n){let e=n.toleranceSeconds??Ae;if(!Number.isFinite(e)||e<0)throw new TypeError(`toleranceSeconds is a number of seconds, 0 or more (got ${String(n.toleranceSeconds)})`);let t=(n.now??Date.now)();if(!Number.isFinite(t))throw new TypeError(`now() returns epoch milliseconds (got ${String(t)})`);let r=n.signature;if(typeof r!="string"||r.trim()==="")throw new h("missing_signature","the request carries no Palbase-Signature header");let s,i=[];for(let a of r.split(",")){let d=a.indexOf("=");if(d<=0)throw new h("malformed_signature","Palbase-Signature is t=<seconds>,v1=<hex>");let c=a.slice(0,d).trim(),o=a.slice(d+1).trim();if(c==="t"){if(s!==void 0||!Pe.test(o))throw new h("malformed_signature","Palbase-Signature carries one t, in unix seconds");s=o}else if(c==="v1"){if(!Re.test(o))throw new h("malformed_signature","a v1 is 64 lowercase hex characters");if(i.length===ne)throw new h("malformed_signature",`Palbase-Signature carries at most ${ne} v1`);i.push(o)}}if(s===void 0||i.length===0)throw new h("malformed_signature","Palbase-Signature is t=<seconds>,v1=<hex>");if(Math.abs(t/1e3-Number(s))>e)throw new h("stale_timestamp",`the signature's time is more than ${e} s from now: an old delivery sent again is not taken`);return{t:s,v1:i}}async function je(n,e,t={}){let r=await Me(n,t.maxBytes??Oe);return re({toleranceSeconds:t.toleranceSeconds,now:t.now,secret:e,signature:n.headers.get("palbase-signature"),body:r})}async function Me(n,e){let t=()=>new h("body_too_large",`the body is larger than ${e} bytes`),r=Number(n.headers.get("content-length")??"NaN");if(Number.isFinite(r)&&r>e)throw t();if(!n.body)return new Uint8Array(0);let s=n.body.getReader(),i=[],a=0;for(;;){let{done:o,value:l}=await s.read();if(o)break;if(a+=l.byteLength,a>e)throw await s.cancel().catch(()=>{}),t();i.push(l)}let d=new Uint8Array(a),c=0;for(let o of i)d.set(o,c),c+=o.byteLength;return d}function oe(n){if(typeof n=="string")return new TextEncoder().encode(n);if(n instanceof Uint8Array)return n;if(n instanceof ArrayBuffer)return new Uint8Array(n);throw new TypeError("body is the raw request body (string or bytes): a parsed object is not what was signed \u2014 read the body before any JSON middleware")}function Ke(n){let e=new Uint8Array(n.length/2);for(let t=0;t<e.length;t++)e[t]=parseInt(n.slice(t*2,t*2+2),16);return e}function Ue(n,e){if(n.byteLength!==e.byteLength)return!1;let t=0;for(let r=0;r<n.byteLength;r++)t|=n[r]^e[r];return t===0}function Ce(n,e){let t=new Uint8Array(n.byteLength+e.byteLength);return t.set(n,0),t.set(e,n.byteLength),t}function Le(n){if(typeof n!="object"||n===null)return!1;let e=n;return typeof e.id=="string"&&typeof e.type=="string"&&typeof e.project_id=="string"&&typeof e.created_at=="string"&&"data"in e}var ae=60,$e=60,Ie=8*1024,Ne=1e5;function O(n){let e=n instanceof Uint8Array?n:new Uint8Array(n),t="";for(let r of e)t+=String.fromCharCode(r);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function ue(n){let e=n.replace(/[\s=]+/g,"");if(!/^[A-Za-z0-9+/_-]*$/.test(e)||e.length%4===1)return;let t=atob(e.replace(/-/g,"+").replace(/_/g,"/").padEnd(Math.ceil(e.length/4)*4,"=")),r=new Uint8Array(t.length);for(let s=0;s<t.length;s++)r[s]=t.charCodeAt(s);return r}function ce(n){let e=ue(n);if(e)try{let t=JSON.parse(new TextDecoder().decode(e));return typeof t=="object"&&t!==null&&!Array.isArray(t)?t:void 0}catch{return}}var _=class{byKey=new Map;held=0;sweptAt=Number.NEGATIVE_INFINITY;max;constructor(e=Ne){this.max=e}spend(e,t){if(t>=e.until)throw new u("proof","the DPoP proof is not taken: it was checked too long ago");let r=this.byKey.get(e.jkt);if(r){this.forgetOld(e.jkt,r,t);let s=r.get(e.jti);if(s!==void 0&&s>t)throw new u("proof","the DPoP proof is not taken: it was used before");s!==void 0&&r.delete(e.jti)&&this.held--}this.held>=this.max&&this.makeRoom(t),r=this.byKey.get(e.jkt),r||(r=new Map,this.byKey.set(e.jkt,r)),r.set(e.jti,e.until),this.held++}forgetOld(e,t,r){for(let[s,i]of t){if(i>r)break;t.delete(s),this.held--}t.size===0&&this.byKey.delete(e)}makeRoom(e){if(e-this.sweptAt>=1e3){this.sweptAt=e;for(let[r,s]of this.byKey){for(let[i,a]of s)a>e||(s.delete(i),this.held--);s.size===0&&this.byKey.delete(r)}this.held=0;for(let r of this.byKey.values())this.held+=r.size}if(this.held<this.max)return;let t=[...this.byKey].sort((r,s)=>s[1].size-r[1].size);for(let[r,s]of t){if(this.held<=this.max*.9)break;this.byKey.delete(r),this.held-=s.size}}};async function De(n,e){let t=`{"crv":"P-256","kty":"EC","x":"${n}","y":"${e}"}`;return O(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(t)))}function de(n){try{let e=new URL(n);return e.username!==""||e.password!==""?void 0:`${e.protocol}//${e.host}${e.pathname}`}catch{return}}async function le(n,e,t,r){let s=Se=>{throw new u("proof",`the DPoP proof is not taken: ${Se}`)},i=t.proof;if(!i)return s("there is none (a DPoP-bound token comes with a DPoP header)");if(i.length>Ie)return s("it is too long");let a=i.split(".");if(a.length!==3)return s("it is not a JWS of three parts");let d=ce(a[0]),c=ce(a[1]);if(!d||!c)return s("its header or claims are not base64url JSON");if(d.typ!=="dpop+jwt")return s("its typ is not dpop+jwt");if(d.alg!=="ES256")return s(`it is signed with ${String(d.alg)}; only ES256 is taken`);let o=d.jwk;if(!o||typeof o!="object"||o.kty!=="EC"||o.crv!=="P-256"||typeof o.x!="string"||typeof o.y!="string")return s("its header carries no P-256 public key");if("d"in o)return s("its header carries a private key");if(await De(o.x,o.y)!==e)return s("it is signed by a key the token does not name");let l;try{l=await crypto.subtle.importKey("jwk",{kty:"EC",crv:"P-256",x:o.x,y:o.y,ext:!0},{name:"ECDSA",namedCurve:"P-256"},!1,["verify"])}catch{return s("its key is not a P-256 point")}let y=ue(a[2]);if(!y||!await crypto.subtle.verify({name:"ECDSA",hash:"SHA-256"},l,y,new TextEncoder().encode(`${a[0]}.${a[1]}`)).catch(()=>!1))return s("its signature does not verify");if(typeof c.htm!="string"||c.htm.toUpperCase()!==t.method.toUpperCase())return s(`it is for ${String(c.htm)}, not ${t.method}`);let p=typeof c.htu=="string"?de(c.htu):void 0,g=de(t.url);if(!p||!g||p!==g)return s(`it is for ${String(c.htu)}, not ${g??t.url}`);let we=r/1e3;if(typeof c.iat!="number"||Math.abs(c.iat-we)>ae)return s("it was not made within a minute of now");let be=O(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(n)));if(c.ath!==be)return s("it is not for this token (ath)");if(typeof c.jti!="string"||c.jti===""||c.jti.length>256)return s("it has no jti (or one longer than 256)");let ke=O(await crypto.subtle.digest("SHA-256",new TextEncoder().encode(c.jti)));return{jkt:e,jti:ke,until:(c.iat+ae+$e)*1e3+1}}var u=class extends Error{reason;constructor(e,t){super(t),this.name="TokenError",this.reason=e}},w=class extends Error{constructor(e,t){super(e,t),this.name="AuthUnavailable"}},Fe=new Set(["invalid_api_key","missing_api_key","secret_key_in_browser"]);function We(n){return async e=>{let t=S({baseUrl:n.url,credentials:{secretKey:n.secretKey,accessToken:()=>e},fetch:n.fetch});try{return await t.send({op:"SessionStanding",method:"GET",path:"/auth/session/standing",auth:[["ApiKeyAuth","userJWT"]],answers:{204:"empty"}}),!0}catch(r){if(r instanceof T&&r.status===401&&!Fe.has(r.code))return!1;throw new w("a session's standing could not be told",{cause:r})}}}var j={ES256:{kty:"EC",import:{name:"ECDSA",namedCurve:"P-256"},verify:{name:"ECDSA",hash:"SHA-256"}},PS256:{kty:"RSA",import:{name:"RSA-PSS",hash:"SHA-256"},verify:{name:"RSA-PSS",saltLength:32}}},he=60,Be=16*1024,He=10*6e4,qe=5e4,fe=n=>typeof n=="string"&&Object.hasOwn(j,n),M=class{issuer;projectId;fetchImpl;now;maxKeyAgeMs;refetchIntervalMs;fetchTimeoutMs;standing;standingTtlMs;standingStaleMs;standings=new Map;asking=new Map;keys=new Map;keysUntil=0;lastFetch=Number.NEGATIVE_INFINITY;lastFailure=void 0;inflight=null;seenProofs=new _;constructor(e){let t=new URL(e.issuer);if(t.origin!==e.issuer.replace(/\/$/,""))throw new TypeError(`issuer is the project's origin (https://<ref>.<domain>), not ${e.issuer}`);if(typeof e.projectId!="string"||e.projectId==="")throw new TypeError("projectId is the project id the tokens carry");if(this.issuer=t.origin,this.projectId=e.projectId,this.fetchImpl=e.fetch??globalThis.fetch,this.now=e.now??Date.now,this.maxKeyAgeMs=e.maxKeyAgeMs??60*6e4,this.refetchIntervalMs=e.refetchIntervalMs??3e4,this.fetchTimeoutMs=e.fetchTimeoutMs??5e3,typeof e.standing!="function")throw new TypeError("standing is how the verifier asks whether a token's session stands");this.standing=e.standing,this.standingTtlMs=e.standingTtlMs??1e3,this.standingStaleMs=e.standingStaleMs??15e3}async verify(e,t){if(typeof e!="string"||e.length===0||e.length>Be)throw new u("malformed","the token is not a JWT");let r=e.split(".");if(r.length!==3)throw new u("malformed","the token is not a JWS of three parts");let s=pe(r[0]),i=pe(r[1]);if(!s||!i)throw new u("malformed","the token header or claims are not base64url JSON");let a=s.alg;if(!fe(a))throw new u("algorithm",`the token is signed with ${String(a)}; only ES256 and PS256 are taken`);let d=s.kid;if(typeof d!="string"||d==="")throw new u("malformed","the token header names no kid");let c=await this.key(d);if(!c)throw new u("unknown_key",`no key ${d} in the project's key set`);if(c.alg!==a)throw new u("algorithm",`key ${d} is ${c.alg}, the token says ${a}`);let o=ge(r[2]);if(!o)throw new u("malformed","the signature is not base64url");let l=new TextEncoder().encode(`${r[0]}.${r[1]}`);if(!await crypto.subtle.verify(j[c.alg].verify,c.key,o,l).catch(()=>!1))throw new u("signature","the signature does not verify");let b=this.check(i),p=i.cnf,g;if(p!==void 0){if(!t)throw new u("bound","the token is bound to a key (DPoP): it comes with the DPoP scheme and a proof, not as a Bearer");if(typeof p!="object"||p===null||typeof p.jkt!="string"||p.jkt==="")throw new u("bound","the token is bound to a key it does not name (cnf.jkt)");g=await le(e,p.jkt,t,this.now())}else if(t)throw new u("not_bound","the DPoP scheme came with a token bound to no key");if(!await this.stands(e,b.sessionId))throw new u("session_ended","the token's session has ended (signed out, revoked, or its user banned)");return g&&this.seenProofs.spend(g,this.now()),b}async verifyRequest(e){let t=e.headers instanceof Headers?e.headers:Ve(e.headers),r=t.get("authorization")??"";if(r==="")return null;let s=/^(bearer|dpop)\s+(\S+)$/i.exec(r);if(!s)throw new u("malformed","the Authorization header is not a Bearer or DPoP token");let i=s[1].toLowerCase()==="dpop",a=new URL(e.url,`http://${t.get("host")??"localhost"}`);return this.verify(s[2],i?{proof:t.get("dpop"),method:e.method,url:ye(t,a)}:void 0)}async stands(e,t){let r=this.now(),s=this.standings.get(t);if(s&&r<s.until)return s.live;let i=this.asking.get(t);i||(i=this.standing(e,t).finally(()=>this.asking.delete(t)),this.asking.set(t,i));let a;try{a=await i}catch(c){let o=this.standings.get(t),l=this.now();if(o&&l<o.at+this.standingStaleMs)return o.until=Math.min(l+this.standingTtlMs,o.at+this.standingStaleMs),o.live;throw new w("a session's standing cannot be read now",{cause:c})}let d=this.now();return this.standings.delete(t),this.standings.set(t,{live:a,at:d,until:d+this.standingTtlMs}),this.standings.size>qe&&this.standings.delete(this.standings.keys().next().value),a}check(e){if(e.iss!==this.issuer)throw new u("issuer",`the token was issued by ${String(e.iss)}, not this project`);if(!(Array.isArray(e.aud)?e.aud:[e.aud]).includes(this.issuer))throw new u("audience","the token is not meant for this project");if(e.project_id!==this.projectId)throw new u("project","the token names another project");let r=this.now()/1e3;if(typeof e.exp!="number"||e.exp+he<=r)throw new u("expired","the token has expired");if(e.nbf!==void 0&&(typeof e.nbf!="number"||e.nbf-he>r))throw new u("not_yet_valid","the token is not valid yet");if(typeof e.sub!="string"||e.sub===""||typeof e.auth_time!="number")throw new u("not_a_user","the token is not a user's");if(typeof e.session_id!="string"||e.session_id==="")throw new u("not_a_session","the token is no session's");let s=e.custom_claims;if(s!==void 0&&(typeof s!="object"||s===null||s.type!==void 0))throw new u("not_a_session","the token is a custom one (an exchange or an approval), not a session's");return{id:e.sub,email:typeof e.email=="string"?e.email:null,emailVerified:e.email_verified===!0,role:typeof e.role=="string"?e.role:null,sessionId:typeof e.session_id=="string"?e.session_id:null,claims:Object.freeze({...e})}}async key(e){let t=this.now();if(t>=this.keysUntil){let s=this.keys.size>0&&t<this.keysUntil+He;if(this.lastFailure!==void 0&&t-this.lastFetch<this.refetchIntervalMs){if(!s)throw new w("the project's key set cannot be read now",{cause:this.lastFailure})}else try{await this.refresh()}catch(i){if(!s)throw i}}let r=this.keys.get(e);return!r&&t-this.lastFetch>=this.refetchIntervalMs&&(await this.refresh(),r=this.keys.get(e)),r}refresh(){if(this.inflight)return this.inflight;let e=this.load().finally(()=>{this.inflight=null});return this.inflight=e,e}async load(){this.lastFetch=this.now();let e,t;try{if(t=await this.fetchImpl(`${this.issuer}/.well-known/jwks.json`,{redirect:"error",headers:{accept:"application/json"},signal:AbortSignal.timeout(this.fetchTimeoutMs)}),!t.ok)throw new Error(`the project's key set answered ${t.status}`);e=await t.json()}catch(i){throw this.lastFailure=i,new w("the project's key set cannot be read now",{cause:i})}this.lastFailure=void 0;let r=new Map;for(let i of Array.isArray(e.keys)?e.keys:[]){let a=i.alg;if(typeof i.kid!="string"||!fe(a))continue;let d=j[a];if(i.kty!==d.kty||i.use!==void 0&&i.use!=="sig")continue;let{d:c,...o}=i;try{r.set(i.kid,{alg:a,key:await crypto.subtle.importKey("jwk",o,d.import,!1,["verify"])})}catch{}}this.keys=r;let s=Je(t.headers.get("cache-control"))??this.maxKeyAgeMs;this.keysUntil=this.now()+Math.min(Math.max(s,this.refetchIntervalMs),this.maxKeyAgeMs)}};function ye(n,e){let t=n.get("x-forwarded-proto")?.split(",")[0]?.trim().toLowerCase(),r=t==="https"||t==="http"?t:e.protocol.slice(0,-1),s=n.get("host")??e.host;return ze.test(s)?`${r}://${s}${e.pathname}`:""}var ze=/^(?:[a-z0-9-]+(?:\.[a-z0-9-]+)*|\[[0-9a-f:.]+\])(?::[0-9]{1,5})?$/i;function Ve(n){let e=new Headers;for(let[t,r]of Object.entries(n))if(r!==void 0)for(let s of Array.isArray(r)?r:[r])e.append(t,s);return e}function Je(n){let e=/(?:^|,)\s*max-age=(\d+)/i.exec(n??"");return e?Number(e[1])*1e3:void 0}function ge(n){if(!/^[A-Za-z0-9_-]*$/.test(n)||n.length%4===1)return null;let e=atob(n.replace(/-/g,"+").replace(/_/g,"/").padEnd(Math.ceil(n.length/4)*4,"=")),t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t}function pe(n){let e=ge(n);if(!e)return null;try{let t=JSON.parse(new TextDecoder("utf-8",{fatal:!0}).decode(e));return typeof t=="object"&&t!==null&&!Array.isArray(t)?t:null}catch{return null}}function Ye(n,e,t=Date.now()){let r=Object.hasOwn(n.entitlements,e)?n.entitlements[e]:void 0;return r?.active?r.expires_at===null?!0:Date.parse(r.expires_at)>(typeof t=="number"?t:t.getTime()):!1}var E=class extends Error{receipt;constructor(e){super(`the reservation ${JSON.stringify(e.idempotency_key)} is ${e.status} already: its job is not run again (a new one is a new Idempotency-Key)`),this.name="ReservationSettled",this.receipt=e}};async function Ge(n,e,t,r){let{idempotencyKey:s,amount:i,ttlSeconds:a,metadata:d}=t;if(typeof s!="string"||s==="")throw new TypeError("idempotencyKey names the reservation for good: a retry with it is the same hold, never a second");let c={amount:i,...t.credits!==void 0?{credits:t.credits}:{limit:t.limit},...a!==void 0?{ttl_seconds:a}:{},...d!==void 0?{metadata:d}:{}},o=(await n.purchases.holdSpend({path:{customer_id:e},headers:{"Idempotency-Key":s},body:c})).data;if(o.status!=="held")throw new E(o);let l={customer_id:o.customer,spend_id:o.id},y;try{y=await r(o)}catch(b){throw await n.purchases.releaseSpend({path:l}).catch(()=>{}),b}return await n.purchases.commitSpend({path:l}),y}async function*Xe(n){let e,t=new Set;do{let r=(await n(e)).data;yield r;let s=r.next_cursor??void 0;if(s!==void 0&&t.has(s))throw new Error(`the listing answered a cursor it had answered before (${s})`);s!==void 0&&t.add(s),e=s}while(e)}var Ze=/^[A-Za-z_][A-Za-z0-9_]{0,127}$/,Qe=/^(PALBASE_|NODE_|BUN_|NPM_|LD_|DYLD_|GIT_|SSH_)|^(PATH|HOME|SHELL|USER|TMPDIR|TMP|TEMP|PWD|IFS|ENV|BASH_ENV|SSL_CERT_FILE|SSL_CERT_DIR|CURL_CA_BUNDLE|REQUESTS_CA_BUNDLE|NO_PROXY|ALL_PROXY|HTTP_PROXY|HTTPS_PROXY|PG\w*)$/i;function me(n){return!Ze.test(n)||Qe.test(n)||/_PROXY$/i.test(n)}var et=/^(PORT|PALBASE_(URL|PROJECT_ID|MACHINE|REPLICAS|SECRET_KEY|WEBHOOK_SECRET|PLATFORM_SECRET|CONTRACT_OUT|SECRETS|DB_[A-Z0-9_]+))$/;function tt(n){return et.test(n)}async function nt(n={}){let e=n.env??process.env,t=e.PALBASE_SECRETS;if(t===void 0||t==="")return;if(t!=="development"&&t!=="production")throw new TypeError(`PALBASE_SECRETS is development or production, not ${t}`);let r=n.url??e.PALBASE_URL??"",s=n.secretKey??e.PALBASE_SECRET_KEY??"";if(r===""||s==="")throw new TypeError("PALBASE_SECRETS reads the project's Secrets with PALBASE_URL and PALBASE_SECRET_KEY: give both (palbase env:pull writes them)");let i=x({url:new URL(r).origin,secretKey:s,fetch:n.fetch}),{data:a}=await i.secrets.getEnvironmentValues({path:{environment:t}}),d=[],c=[],o=[];for(let[l,y]of Object.entries(a.values)){if(me(l)){o.push(l);continue}if(e[l]!==void 0&&e[l]!==""){c.push(l);continue}e[l]=y,d.push(l)}return{set:t,loaded:d.sort(),kept:c.sort(),refused:o.sort()}}export{f as a,k as b,v as c,x as d,h as e,re as f,se as g,ie as h,je as i,u as j,w as k,We as l,M as m,ye as n,Ye as o,E as p,Ge as q,Xe as r,me as s,tt as t,nt as u};
|