palbase 0.15.0 → 0.16.0

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.
Files changed (54) hide show
  1. package/dist/ai/index.js +2 -2
  2. package/dist/backend/engine.js +2 -2
  3. package/dist/backend/env.js +1 -1
  4. package/dist/backend/index.js +3 -3
  5. package/dist/backend/stack.js +1 -1
  6. package/dist/backend/test.js +2 -2
  7. package/dist/chunks/{KPZDHOOU.js → 2JBRAHJV.js} +2 -2
  8. package/dist/chunks/{2JWJOZWB.js → 5W7IKTRI.js} +2 -2
  9. package/dist/chunks/{Y6Q6WCB6.js → 7HYPHYX5.js} +1 -1
  10. package/dist/chunks/{ETHKSFKR.js → A4YMCQOP.js} +1 -1
  11. package/dist/chunks/{3HYGK4KK.js → C5PO7C6L.js} +1 -1
  12. package/dist/chunks/{H7K75EKZ.js → CFGQWDV5.js} +3 -3
  13. package/dist/chunks/{HOZL4MMJ.js → CXZ6WKOI.js} +2 -2
  14. package/dist/chunks/{DMMWR4G3.js → EHWHP4MD.js} +2 -2
  15. package/dist/chunks/{RXQNOOVQ.js → EJHB65XA.js} +2 -2
  16. package/dist/chunks/{U6JA755C.js → HVC5H5HY.js} +2 -2
  17. package/dist/chunks/{EVTELMRJ.js → IA4LTPBJ.js} +2 -2
  18. package/dist/chunks/{KMZHLMVV.js → JOWAWH33.js} +2 -2
  19. package/dist/chunks/L73SEFXF.js +21 -0
  20. package/dist/chunks/LY7D5Q3R.js +2 -0
  21. package/dist/chunks/NQNE5PZW.js +13 -0
  22. package/dist/chunks/{75SLRGIK.js → QN5WMSP7.js} +2 -2
  23. package/dist/chunks/{2L6YDPYE.js → S7WYS4NC.js} +2 -2
  24. package/dist/chunks/{EELNNURM.js → TGVFGW5G.js} +2 -2
  25. package/dist/chunks/{HIVD246W.js → TIC3NMUT.js} +1 -1
  26. package/dist/chunks/{HEBADNJM.js → VNLECYBD.js} +1 -1
  27. package/dist/chunks/{CBY3JE3R.js → VTUZYTKZ.js} +1 -1
  28. package/dist/chunks/{AA6WRVYF.js → WCTVLG4W.js} +2 -2
  29. package/dist/chunks/{332N2H2L.js → YUBOQ3NU.js} +1 -1
  30. package/dist/cli.js +124 -124
  31. package/dist/refuse/ai.js +1 -1
  32. package/dist/refuse/backend.js +1 -1
  33. package/dist/refuse/server.js +1 -1
  34. package/dist/server/index.js +2 -2
  35. package/dist/server/testing.js +2 -2
  36. package/dist/web/index.js +2 -2
  37. package/dist/web/message.js +2 -2
  38. package/dist/web/palbe.js +2 -2
  39. package/dist/web/paywall.js +2 -2
  40. package/dist/web/push-sw.js +1 -1
  41. package/dist/web/ssr.js +2 -2
  42. package/dist/web/vite.js +2 -2
  43. package/package.json +2 -2
  44. package/types/backend/src/decorators.d.ts +20 -0
  45. package/types/backend/src/engine.d.ts +9 -0
  46. package/types/backend/src/openapi.d.ts +3 -0
  47. package/types/backend/src/router.d.ts +2 -0
  48. package/types/internal/src/modules/ai.d.ts +1 -1
  49. package/types/internal/src/modules/auth.d.ts +33 -14
  50. package/types/web/src/backend-error.d.ts +6 -1
  51. package/types/web/src/inapp.d.ts +2 -0
  52. package/dist/chunks/ONG4Z7RY.js +0 -13
  53. package/dist/chunks/PTXC4F7L.js +0 -2
  54. package/dist/chunks/TRTI7CUE.js +0 -21
package/dist/refuse/ai.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! palbase 0.15.0 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.16.0 — 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");
@@ -1,2 +1,2 @@
1
- /*! palbase 0.15.0 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.16.0 — 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)");
@@ -1,2 +1,2 @@
1
- /*! palbase 0.15.0 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.16.0 — 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");
@@ -1,2 +1,2 @@
1
- /*! palbase 0.15.0 — 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/U6JA755C.js";import{a as c,b as d}from"../chunks/HIVD246W.js";import"../chunks/CBY3JE3R.js";import"../chunks/ETHKSFKR.js";import{m as b}from"../chunks/PTXC4F7L.js";import"../chunks/KMZHLMVV.js";import{b as a}from"../chunks/DMMWR4G3.js";import"../chunks/332N2H2L.js";import"../chunks/Y6Q6WCB6.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};
1
+ /*! palbase 0.16.0 — 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/HVC5H5HY.js";import{a as c,b as d}from"../chunks/TIC3NMUT.js";import"../chunks/VTUZYTKZ.js";import"../chunks/A4YMCQOP.js";import{m as b}from"../chunks/LY7D5Q3R.js";import"../chunks/JOWAWH33.js";import{b as a}from"../chunks/EHWHP4MD.js";import"../chunks/YUBOQ3NU.js";import"../chunks/7HYPHYX5.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};
@@ -1,2 +1,2 @@
1
- /*! palbase 0.15.0 — Palbase SDK License (see LICENSE) */
2
- import{a,b,c,d,e}from"../chunks/RXQNOOVQ.js";import"../chunks/HIVD246W.js";import"../chunks/332N2H2L.js";import"../chunks/Y6Q6WCB6.js";export{b as TestApiError,e as api,c as createTestApi,a as testFields,d as testRun};
1
+ /*! palbase 0.16.0 — Palbase SDK License (see LICENSE) */
2
+ import{a,b,c,d,e}from"../chunks/EJHB65XA.js";import"../chunks/TIC3NMUT.js";import"../chunks/YUBOQ3NU.js";import"../chunks/7HYPHYX5.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.15.0 — 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/H7K75EKZ.js";import{a as _,b as Q,f as z}from"../chunks/ONG4Z7RY.js";import"../chunks/2JWJOZWB.js";import"../chunks/75SLRGIK.js";import"../chunks/3HYGK4KK.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/CBY3JE3R.js";import"../chunks/EELNNURM.js";import"../chunks/PTXC4F7L.js";import"../chunks/KMZHLMVV.js";import{b as L}from"../chunks/DMMWR4G3.js";import"../chunks/332N2H2L.js";import"../chunks/Y6Q6WCB6.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};
1
+ /*! palbase 0.16.0 — 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/CFGQWDV5.js";import{a as _,b as Q,f as z}from"../chunks/NQNE5PZW.js";import"../chunks/5W7IKTRI.js";import"../chunks/QN5WMSP7.js";import"../chunks/C5PO7C6L.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/VTUZYTKZ.js";import"../chunks/TGVFGW5G.js";import"../chunks/LY7D5Q3R.js";import"../chunks/JOWAWH33.js";import{b as L}from"../chunks/EHWHP4MD.js";import"../chunks/YUBOQ3NU.js";import"../chunks/7HYPHYX5.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};
@@ -1,2 +1,2 @@
1
- /*! palbase 0.15.0 — Palbase SDK License (see LICENSE) */
2
- import{a as i}from"../chunks/75SLRGIK.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/3HYGK4KK.js";import"../chunks/Y6Q6WCB6.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};
1
+ /*! palbase 0.16.0 — Palbase SDK License (see LICENSE) */
2
+ import{a as i}from"../chunks/QN5WMSP7.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/C5PO7C6L.js";import"../chunks/7HYPHYX5.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.15.0 — Palbase SDK License (see LICENSE) */
2
- import{c as e,d as r,i as t}from"../chunks/ONG4Z7RY.js";import"../chunks/CBY3JE3R.js";import"../chunks/EELNNURM.js";import"../chunks/KMZHLMVV.js";import"../chunks/DMMWR4G3.js";import"../chunks/332N2H2L.js";import"../chunks/Y6Q6WCB6.js";export{e as RESERVED_CLIENT_NAMES,t as __registerBackend,r as isClientName};
1
+ /*! palbase 0.16.0 — Palbase SDK License (see LICENSE) */
2
+ import{c as e,d as r,i as t}from"../chunks/NQNE5PZW.js";import"../chunks/VTUZYTKZ.js";import"../chunks/TGVFGW5G.js";import"../chunks/JOWAWH33.js";import"../chunks/EHWHP4MD.js";import"../chunks/YUBOQ3NU.js";import"../chunks/7HYPHYX5.js";export{e as RESERVED_CLIENT_NAMES,t as __registerBackend,r as isClientName};
@@ -1,2 +1,2 @@
1
- /*! palbase 0.15.0 — 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/2JWJOZWB.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/3HYGK4KK.js";import"../chunks/DMMWR4G3.js";import"../chunks/332N2H2L.js";import"../chunks/Y6Q6WCB6.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};
1
+ /*! palbase 0.16.0 — 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/5W7IKTRI.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/C5PO7C6L.js";import"../chunks/EHWHP4MD.js";import"../chunks/YUBOQ3NU.js";import"../chunks/7HYPHYX5.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};
@@ -1,2 +1,2 @@
1
- /*! palbase 0.15.0 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.16.0 — 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.15.0 — Palbase SDK License (see LICENSE) */
2
- import{q as f}from"../chunks/H7K75EKZ.js";import"../chunks/ONG4Z7RY.js";import"../chunks/2JWJOZWB.js";import"../chunks/75SLRGIK.js";import"../chunks/3HYGK4KK.js";import"../chunks/CBY3JE3R.js";import"../chunks/EELNNURM.js";import"../chunks/PTXC4F7L.js";import"../chunks/KMZHLMVV.js";import"../chunks/DMMWR4G3.js";import"../chunks/332N2H2L.js";import"../chunks/Y6Q6WCB6.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};
1
+ /*! palbase 0.16.0 — Palbase SDK License (see LICENSE) */
2
+ import{q as f}from"../chunks/CFGQWDV5.js";import"../chunks/NQNE5PZW.js";import"../chunks/5W7IKTRI.js";import"../chunks/QN5WMSP7.js";import"../chunks/C5PO7C6L.js";import"../chunks/VTUZYTKZ.js";import"../chunks/TGVFGW5G.js";import"../chunks/LY7D5Q3R.js";import"../chunks/JOWAWH33.js";import"../chunks/EHWHP4MD.js";import"../chunks/YUBOQ3NU.js";import"../chunks/7HYPHYX5.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.15.0 — Palbase SDK License (see LICENSE) */
2
- import"../chunks/Y6Q6WCB6.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:
1
+ /*! palbase 0.16.0 — Palbase SDK License (see LICENSE) */
2
+ import"../chunks/7HYPHYX5.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.15.0",
3
+ "version": "0.16.0",
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.15.0",
138
+ "palgres": "0.16.0",
139
139
  "reflect-metadata": "^0.2.2",
140
140
  "typescript": "~6.0.3",
141
141
  "zod": "^4.6.5"
@@ -28,6 +28,14 @@ export type StandardResult<Output> = {
28
28
  export interface AuthConfig {
29
29
  required: boolean;
30
30
  verifiedEmail?: boolean;
31
+ /**
32
+ * How the user signed in, at least: 'aal2' — with a second factor (a passkey
33
+ * that verifies its user, an authenticator code, a step-up). A token below it
34
+ * is refused with 401 insufficient_user_authentication and WWW-Authenticate's
35
+ * acr_values (RFC 9470): the app steps the user up and calls again. Implies
36
+ * a signed-in user.
37
+ */
38
+ aal?: 'aal1' | 'aal2' | 'aal3';
31
39
  /**
32
40
  * Palbase checks no role or permission: a route naming one is refused at
33
41
  * boot, so none runs believing it was checked — check the role in the service.
@@ -43,11 +51,23 @@ export interface RateLimitConfig {
43
51
  }
44
52
  export interface ControllerOptions {
45
53
  auth?: AuthSpec;
54
+ /** Every route of the controller asks for device attestation (RouteOptions.attest), unless a route says false. */
55
+ attest?: boolean;
46
56
  }
47
57
  export interface RouteOptions {
48
58
  auth?: AuthSpec;
49
59
  /** A limit for this route; false for none. */
50
60
  rateLimit?: RateLimitConfig | false;
61
+ /**
62
+ * Only the app's own build on a genuine device calls this route: App Attest
63
+ * on iOS, a Keystore key attested by Google on Android — Palbase's iOS and
64
+ * Android SDKs attach the proof by themselves. Whether it is asked is the
65
+ * environment's switch (Studio's Device trust, app_attest_mode): off,
66
+ * monitor (verified and counted, nobody refused) or enforce (a call without
67
+ * a proof that verifies is refused: 401 app_attest_required). A browser
68
+ * cannot attest: under enforce, a web app's calls to the route are refused.
69
+ */
70
+ attest?: boolean;
51
71
  }
52
72
  export type ParamKind = 'body' | 'query' | 'param' | 'user' | 'optionalUser' | 'headers' | 'req' | 'requestId' | 'client' | 'resolve' | 'uploadedObject';
53
73
  export interface ParamMeta {
@@ -14,6 +14,15 @@ export interface UserT {
14
14
  sessionId: string | null;
15
15
  /** A test user of the project (made with its secret key; the token says test: true). */
16
16
  test: boolean;
17
+ /**
18
+ * How the user signed in, as the token says (acr): 'aal1' a first factor alone, 'aal2' with a second one (a passkey that
19
+ * verified its user, an authenticator code, a step-up) — null where no token says it (a platform's call naming the user).
20
+ */
21
+ acr: 'aal1' | 'aal2' | 'aal3' | null;
22
+ /** The methods the sign-in used (amr: pwd, otp, hwk, …), as the token says; empty where none says it. */
23
+ amr: string[];
24
+ /** When the user signed in, in Unix seconds (auth_time) — a step-up moves it; null where no token says it. */
25
+ authTime: number | null;
17
26
  }
18
27
  export interface ClientInfo {
19
28
  sdkVersion: string | null;
@@ -9,9 +9,12 @@ export interface RouteFacts {
9
9
  auth: {
10
10
  required: boolean;
11
11
  verifiedEmail: boolean;
12
+ aal: 'aal1' | 'aal2' | 'aal3';
12
13
  };
13
14
  /** The limit the route spends, or false when it has none. */
14
15
  limit: RateLimitConfig | false;
16
+ /** The route asks for the device's attestation (when the environment's switch is on). */
17
+ attest: boolean;
15
18
  }
16
19
  export interface ContractOptions {
17
20
  /** The app's database runs each request as its caller's identity (or keeps its claims). */
@@ -11,6 +11,8 @@ export interface Route {
11
11
  params: ParamMeta[];
12
12
  meta: RouteMeta;
13
13
  controllerAuth: AuthSpec | undefined;
14
+ /** The controller's attest: true, which a route's own option overrides. */
15
+ controllerAttest: boolean | undefined;
14
16
  }
15
17
  export declare function routeTable(controllers: Function[]): Route[];
16
18
  export type Match = {
@@ -2445,7 +2445,7 @@ export type VoiceSession = {
2445
2445
  */
2446
2446
  chat_id: string;
2447
2447
  /**
2448
- * Why it ended: close_requested, member_removed, chat_deleted, replaced (its member started another), lost (the engine no longer holds it), or the provider's word.
2448
+ * Why it ended: close_requested, member_removed, chat_deleted, replaced (its member started another), lost (the engine no longer holds it), ai_limit_reached (its project's free AI, monthly AI budget or what its account can pay is spent, and it ran on Palbase's models), or the provider's word.
2449
2449
  */
2450
2450
  close_reason?: string;
2451
2451
  /**
@@ -790,7 +790,7 @@ export type AssetLinkTarget = {
790
790
  */
791
791
  export type AssetLinks = AssetLinkStatement[];
792
792
  /**
793
- * One request's App Attest evidence and the request it claims to be bound to.
793
+ * One request's device attestation evidence (App Attest on iOS, a Keystore signature on Android) and the request it claims to be bound to.
794
794
  */
795
795
  export type AttestAssertionCheck = {
796
796
  /**
@@ -812,11 +812,11 @@ export type AttestAssertionCheck = {
812
812
  */
813
813
  path?: string;
814
814
  /**
815
- * authenticatorData (37 bytes) followed by clientDataHash (32 bytes), base64.
815
+ * iOS: authenticatorData (37 bytes) followed by clientDataHash (32 bytes). Android: 0x01, the device's counter (8 bytes, big-endian) and clientDataHash (32 bytes). Base64.
816
816
  */
817
817
  payload?: string;
818
818
  /**
819
- * DER-encoded ECDSA signature, base64.
819
+ * DER-encoded ECDSA signature, base64: App Attest's on iOS; on Android, ECDSA-SHA256 over the payload by the enrolled key.
820
820
  */
821
821
  signature?: string;
822
822
  };
@@ -846,9 +846,17 @@ export type AttestObservationBatch = {
846
846
  incapable?: number;
847
847
  no_sdk?: number;
848
848
  unknown?: number;
849
+ /**
850
+ * Requests with evidence that verified: they pass under enforce.
851
+ */
852
+ verified?: number;
853
+ /**
854
+ * Requests with evidence that would be refused under enforce.
855
+ */
856
+ refused?: number;
849
857
  };
850
858
  /**
851
- * What the customer runtime saw in the window, by device capability, and the mode in force.
859
+ * What the customer runtime saw in the window: callers by device capability, what the evidence it verified came to, and the mode in force.
852
860
  */
853
861
  export type AttestObservationSummary = {
854
862
  capable: number;
@@ -856,6 +864,14 @@ export type AttestObservationSummary = {
856
864
  mode: "off" | "monitor" | "enforce";
857
865
  no_sdk: number;
858
866
  unknown: number;
867
+ /**
868
+ * Requests with evidence that verified: they pass under enforce.
869
+ */
870
+ verified: number;
871
+ /**
872
+ * Requests with evidence that would be refused under enforce.
873
+ */
874
+ refused: number;
859
875
  };
860
876
  export type AttestPolicy = {
861
877
  mode: "off" | "monitor" | "enforce";
@@ -1454,18 +1470,18 @@ export type Device = {
1454
1470
  trusted: boolean;
1455
1471
  };
1456
1472
  /**
1457
- * A Play Integrity verdict to enrol an Android device with.
1473
+ * An Android Keystore key's attestation to verify.
1458
1474
  */
1459
1475
  export type DeviceAttestAndroidRequest = {
1460
- device_name?: string;
1461
1476
  /**
1462
- * The app's package name, whose Play Console project issued the token.
1477
+ * The key's attestation certificate chain from `KeyStore.getCertificateChain`, leaf first, each certificate DER in base64.
1463
1478
  */
1464
- package_name: string;
1479
+ certificate_chain: string[];
1465
1480
  /**
1466
- * The Play Integrity token.
1481
+ * The challenge from `POST /auth/devices/challenge`, base64, exactly as received.
1467
1482
  */
1468
- verdict_token: string;
1483
+ challenge: string;
1484
+ device_name?: string;
1469
1485
  };
1470
1486
  /**
1471
1487
  * An App Attest attestation to verify.
@@ -4625,11 +4641,14 @@ export declare function client(t: Transport): {
4625
4641
  signal?: AbortSignal;
4626
4642
  }): Promise<Reply<200, DeviceList>>;
4627
4643
  /**
4628
- * Enrol an Android device with Play Integrity
4644
+ * Enrol an Android device with Key Attestation
4629
4645
  *
4630
- * Decodes a Play Integrity verdict token for the named package and, when the verdict passes, stores the device as verified under the signed-in user. A verdict that fails is refused with 403 and its reason (`emulator_detected`, `device_integrity_failed`) and stores nothing. A token this project cannot decode answers 400 `invalid_verdict_token`. 409 `play_integrity_not_configured`: this project has no Play Integrity integration. 503 `integrity_service_unavailable`: Google could not be reached; retry after `Retry-After`. The device has no key yet: bind the app's key with `POST /auth/devices/bind`.
4646
+ * Verifies an Android Keystore key's attestation and stores the key as a verified device, so the device can sign its requests to a backend route that requires attestation. The app generates an EC P-256 signing key in the Android Keystore with the challenge from `POST /auth/devices/challenge` as its attestation challenge and sends the key's certificate chain. The chain must end in one of Google's hardware attestation roots with no certificate on Google's revocation list; the key must be in the TEE or StrongBox and generated there; the device must be locked with a verified boot; and the attesting app's package and signing certificate must be those of an Android app registered with this environment. No session is required: with a valid user token the device is enrolled under that user, otherwise under the installation anchor in `X-Palbase-Installation-Anchor` (the anchor the challenge was issued for). A caller with neither is refused with 401. The challenge is spent by this call. 400: the request cannot be evaluated (`missing_fields`, `invalid_certificate_chain`, `invalid_challenge` — not issued for this anchor or already spent, `invalid_installation_anchor`). 403: the chain was evaluated and refused, the reason being the code (`untrusted_root`, `software_key` — an emulator or a software keystore, `device_not_locked`, `unverified_boot`, `package_mismatch`, `signature_mismatch`, `certificate_revoked`, `certificate_expired`, `challenge_mismatch`, `key_not_generated`, `invalid_key`). 409 `android_app_not_configured`: no Android app is registered with this environment. 503: the challenge store (`challenge_unavailable`) or Google's revocation list (`revocation_list_unavailable`) cannot be reached; retry after `Retry-After`. Rate limited per IP address.
4631
4647
  */
4632
4648
  attestAndroidDevice(input: {
4649
+ headers?: {
4650
+ "X-Palbase-Installation-Anchor"?: string;
4651
+ };
4633
4652
  body: DeviceAttestAndroidRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
4634
4653
  signal?: AbortSignal;
4635
4654
  }): Promise<Reply<200, Device>>;
@@ -4648,7 +4667,7 @@ export declare function client(t: Transport): {
4648
4667
  /**
4649
4668
  * Bind a public key to a device
4650
4669
  *
4651
- * Stores the signing key of one of the signed-in user's devices — once. The device must be `verified` and have no key yet: an Android device after `POST /auth/devices/attest/android`, whose Play Integrity verdict certifies no key. A device that already has a key (every App Attest device: attestation establishes its key) answers 409 `device_key_bound`; to use a new key, enrol a new device and delete the old one. A device that is not verified answers 400 `device_not_verified`. `public_key` must be a DER SubjectPublicKeyInfo holding an ECDSA key, or the call answers 400 `invalid_public_key`.
4670
+ * Stores the signing key of one of the signed-in user's devices — once. The device must be `verified` and have no key yet. A device that already has a key — every device enrolled with App Attest or Android Key Attestation: enrolment establishes its key — answers 409 `device_key_bound`; to use a new key, enrol a new device and delete the old one. A device that is not verified answers 400 `device_not_verified`. `public_key` must be a DER SubjectPublicKeyInfo holding an ECDSA key, or the call answers 400 `invalid_public_key`.
4652
4671
  */
4653
4672
  bindDeviceKey(input: {
4654
4673
  body: DeviceBindRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
@@ -4657,7 +4676,7 @@ export declare function client(t: Transport): {
4657
4676
  /**
4658
4677
  * Get a single-use enrolment challenge
4659
4678
  *
4660
- * Issues a single-use challenge, valid for 5 minutes, that the device embeds in its App Attest attestation and sends back to `POST /auth/devices/attest/ios`. No session is required. When a valid user token is sent, the challenge is scoped to that user; otherwise it is scoped to the installation anchor in `X-Palbase-Installation-Anchor`. A caller with neither gets a freshly minted anchor in `installation_anchor` and must send it back in `X-Palbase-Installation-Anchor` on the attest call. An anchor header that is not an issued `ins_…` anchor answers 400 `invalid_installation_anchor`. Rate limited per IP address. Takes no request body.
4679
+ * Issues a single-use challenge, valid for 5 minutes, that the device embeds in its attestation — App Attest's, or an Android Keystore key's — and sends back to `POST /auth/devices/attest/ios` or `POST /auth/devices/attest/android`. No session is required. When a valid user token is sent, the challenge is scoped to that user; otherwise it is scoped to the installation anchor in `X-Palbase-Installation-Anchor`. A caller with neither gets a freshly minted anchor in `installation_anchor` and must send it back in `X-Palbase-Installation-Anchor` on the attest call. An anchor header that is not an issued `ins_…` anchor answers 400 `invalid_installation_anchor`. Rate limited per IP address. Takes no request body.
4661
4680
  */
4662
4681
  createDeviceChallenge(input?: {
4663
4682
  headers?: {
@@ -3,7 +3,12 @@ export interface FieldError {
3
3
  field: string;
4
4
  message: string;
5
5
  }
6
- export type BackendErrorKind = 'validation' | 'unauthorized' | 'rateLimited' | 'server' | 'network' | 'decode';
6
+ /**
7
+ * stepUpRequired: the route asks for a stronger sign-in than the user's (401 insufficient_user_authentication, RFC
8
+ * 9470; `data.acr_values` names the level, e.g. 'aal2'). The session is fine: step the user up (pb.auth's step-up)
9
+ * and call again.
10
+ */
11
+ export type BackendErrorKind = 'validation' | 'unauthorized' | 'stepUpRequired' | 'rateLimited' | 'server' | 'network' | 'decode';
7
12
  interface BackendErrorParams {
8
13
  code: string;
9
14
  message: string;
@@ -71,6 +71,8 @@ export declare class InApp {
71
71
  private limits;
72
72
  private shown;
73
73
  private loaded;
74
+ /** The page went out of view since the campaigns were last asked for. */
75
+ private away;
74
76
  private memorySession;
75
77
  private memoryPending;
76
78
  private showing;
@@ -1,13 +0,0 @@
1
- /*! palbase 0.15.0 — Palbase SDK License (see LICENSE) */
2
- import{a as z,f as Q,g as Y,j as Z,k as X,l as ee,o as G,p as te,q as ne}from"./CBY3JE3R.js";import{b as M,c as N,d as T}from"./EELNNURM.js";import{d as A}from"./KMZHLMVV.js";import{a as b,b as V,c as _,e as j}from"./DMMWR4G3.js";var l=class extends Error{kind;code;status;requestId;fields;retryAfter;data;constructor(e,n){super(n.message,n.cause===void 0?void 0:{cause:n.cause}),this.name="BackendError",this.kind=e,this.code=n.code,this.status=n.status??0,this.requestId=n.requestId,this.fields=n.fields,this.retryAfter=n.retryAfter,this.data=n.data}};function oe(t){return t instanceof l||typeof t=="object"&&t!==null&&t.name==="BackendError"&&typeof t.kind=="string"}function q(t){let e=t.body,n={code:t.code,message:t.message,status:t.status,requestId:t.requestId??qe(e,"request_id"),data:E(e,"data"),cause:t};if(t.code==="network_error")return new l("network",n);if(t.status===401)return new l("unauthorized",n);if(t.status===429)return new l("rateLimited",{...n,retryAfter:Ne(e)??t.retryAfter});let s=Me(e);return t.status===400&&s?new l("validation",{...n,fields:s}):new l("server",n)}function R(t){return t instanceof V||t instanceof Error&&t.name==="PalbaseError"}function se(t){return Array.isArray(t)&&t.length>0&&t.every(e=>typeof e=="object"&&e!==null&&typeof e.field=="string"&&typeof e.message=="string")}function Me(t){let e=E(E(t,"data"),"fields");if(se(e))return e;let n=E(t,"fields");return se(n)?n:void 0}function Ne(t){return re(t,"retry_after")??re(E(t,"data"),"retryAfter")}function E(t,e){if(typeof t=="object"&&t!==null)return t[e]}function re(t,e){let n=E(t,e);return typeof n=="number"?n:void 0}function qe(t,e){let n=E(t,e);return typeof n=="string"?n:void 0}var De=/^[A-Za-z_$][A-Za-z0-9_$]*$/,Ke=Object.freeze(["adoptSession","analytics","appContext","appVersion","auth","callOnSignOut","cancelCallOnSignOut","configuration","consent","currentSession","flags","installation","module","moduleDirectory","notify","onSessionChange","onSignOut","preferences","realtime","scope","send","socket","storage","storedUserId","telemetry","transport","version","palbe","data","stores","purchases","messaging","notifications","perf","debug","equals","hashCode","toString","self","Type","init","deinit","subscript","then","constructor","__proto__"]),Be=new Set(Ke),Le=new Set(["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf","__proto__","__defineGetter__","__defineSetter__","__lookupGetter__","__lookupSetter__"]);function P(t){return t==="then"||t==="toJSON"||Le.has(t)}function ae(t){return t==="call"||t==="join"||P(t)}function ie(t){return typeof t=="string"&&De.test(t)&&!Be.has(t)&&!P(t)}function de(t){return typeof t=="string"&&/^[a-z][a-z0-9-]{0,62}$/.test(t)}function le(t){j(t)}function ce(t){return j(t).origin}var I=class{me;reader;messages=new Map;responses=new Map;order=[];turn=null;goal=null;goalWords=new Set;voiceWords=new Set;voice=null;history=new Map;forkedFrom=null;calls=new Map;taken=[];older=[];oldestLive;olderCursor;olderLeft=!0;loading;chatId;listeners=new Set;enders=new Set;snapshot;told=!1;ended=!1;constructor(e=()=>{},n,s){this.me=e,this.reader=n,this.chatId=s}get hasOlder(){return this.olderLeft}loadOlder(e={}){return this.loading??=this.readOlder(e).finally(()=>this.loading=void 0),this.loading}async readOlder(e){if(!this.olderLeft)return!1;let s={...this.olderCursor!==void 0?{cursor:this.olderCursor}:this.oldestLive!==void 0?{before:this.oldestLive}:{},...e.limit!==void 0?{limit:e.limit}:{},...e.signal?{signal:e.signal}:{}},r;if(e.load)r=await e.load(s);else{let a=this.idFor("loadOlder",e.chatId);if(!this.reader)throw new TypeError("loadOlder: this chat reads its past through the app's way: give load");r=await this.reader.parts(a,s)}if(this.ended)return!1;let o=(r?.parts??[]).map(a=>M(a)).filter(a=>a!==void 0);return this.older=[...o,...this.older],this.olderCursor=r?.nextCursor,this.olderLeft=typeof r?.nextCursor=="string"&&r.nextCursor!=="",this.refold(),this.olderLeft}idFor(e,n){let s=n??this.chatId;if(typeof s!="string"||s==="")throw new TypeError(`${e}: the chat's id is not known yet (no chatId in the join, no message heard): give { chatId }`);return s}refold(){this.messages.clear(),this.responses.clear(),this.order.length=0,this.turn=null,this.goal=null,this.goalWords.clear(),this.voiceWords.clear(),this.voice=null,this.history.clear(),this.forkedFrom=null,this.calls.clear();for(let e of this.older)this.fold(e);for(let e of this.taken)this.fold(e);this.changed()}get state(){return this.snapshot??=this.build()}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}async*[Symbol.asyncIterator](){let e,n,s=this.subscribe(()=>e?.()),r=()=>e?.();this.enders.add(r);try{for(;;){let o=this.state;if(o!==n){n=o,yield o;continue}if(this.ended)return;await new Promise(a=>e=a)}}finally{s(),this.enders.delete(r)}}end(){if(!this.ended){this.ended=!0;for(let e of[...this.enders])e()}}takePayload(e){let n=M(e);n&&this.take(n)}take(e){if(this.ended)return;this.taken.push(e);let n=e.seq;typeof n=="number"&&n>0&&(this.oldestLive===void 0||n<this.oldestLive)&&(this.oldestLive=n),this.fold(e)&&this.changed()}fold(e){switch(e.type){case"message":return this.chatId===void 0&&typeof e.message.chat_id=="string"&&e.message.chat_id!==""&&(this.chatId=e.message.chat_id),this.heard(e.message),!1;case"turn":{let n=this.response(e.response_id);n.status=e.status,n.waiting=e.waiting,n.error=e.error,n.end=typeof e.end=="string"?e.end:null,e.user_id!==void 0&&(n.startedBy=e.user_id),e.goal&&(n.goal={goalId:e.goal.goal_id,role:e.goal.role,seq:e.goal.seq}),this.turn=e;break}case"thinking":{let n=this.response(e.response_id);if(e.seq>0){if(n.thought.has(e.seq))return!1;n.thought.add(e.seq)}if(e.unavailable){n.marks.set("thinking:unavailable",{type:"thinking",text_offset:N(n.text),thinking:{stepId:null,runId:e.run_id,text:"",unavailable:!0,model:e.model??null,reason:e.reason??null}});break}let s=`thinking:${e.step_id??`seq:${e.seq}`}`,r=n.marks.get(s);r?r.thinking={...r.thinking,text:r.thinking.text+e.text}:n.marks.set(s,{type:"thinking",text_offset:N(n.text),thinking:{stepId:e.step_id??null,runId:e.run_id,text:e.text,unavailable:!1,model:null,reason:null}});break}case"goal":if(e.seq>0){if(this.goalWords.has(e.seq))return!1;this.goalWords.add(e.seq)}this.goalSaid(e),this.order.push({type:"goal",event:e});break;case"voice":{let n=`${e.voice_id}\0${e.status}`;if(this.voiceWords.has(n))return!1;this.voiceWords.add(n),(e.status==="closed"?this.voice===null||this.voice.voice_id===e.voice_id:!this.voiceWords.has(`${e.voice_id}\0closed`))&&(this.voice=e),this.order.push({type:"voice",event:e});break}case"transcript":return this.said(e),!1;case"history":e.forked_from&&(this.forkedFrom={chatId:e.forked_from.chat_id,beforeMessage:e.forked_from.before_message}),this.history.set(e.part,e.items);break;case"text":{let n=this.response(e.response_id);n.text=n.text.slice(0,T(n.text,e.offset))+e.text;break}case"reset":{let n=this.response(e.response_id);n.text=n.text.slice(0,T(n.text,e.offset));break}case"tool":{this.response(typeof e.agent_response_id=="string"&&e.agent_response_id!==""?e.agent_response_id:e.response_id).marks.set(`tool:${e.call_id}`,e),this.calls.set(e.call_id,e);break}case"agent":{if(this.response(e.parent_response_id).marks.set(e.run_id?`agent:${e.run_id}`:`agent:seq:${e.seq}`,e),!e.response_id)break;let n=this.response(e.response_id);if(n.runId=e.run_id,n.agent=e.name,n.parentId===null){n.parentId=e.parent_response_id;let s=this.order.findIndex(r=>r.type==="response"&&r.key===e.response_id);s>=0&&this.order.splice(s,1)}break}}return!0}goalSaid(e){if(e.kind==="set"&&e.goal){this.goal={id:e.goal_id,objective:e.goal.objective,rubric:e.goal.rubric,status:e.goal.status,stopCode:e.goal.stop_code,stopReason:e.goal.stop_reason,phase:e.goal.phase,maxTurns:e.goal.max_turns??null,maxCostUsd:e.goal.max_cost_usd??null,events:[e]};return}let n=this.goal;if(!n||n.id!==e.goal_id)return;let s={...n,events:[...n.events,e]};e.kind==="updated"&&e.goal?Object.assign(s,{objective:e.goal.objective,rubric:e.goal.rubric,status:e.goal.status,stopCode:e.goal.stop_code,stopReason:e.goal.stop_reason,phase:e.goal.phase,maxTurns:e.goal.max_turns??null,maxCostUsd:e.goal.max_cost_usd??null}):e.kind==="status_changed"&&typeof e.to=="string"?Object.assign(s,{status:e.to,stopCode:e.code??"",stopReason:e.reason??""}):e.kind==="cleared"&&Object.assign(s,{status:"cleared",stopReason:e.reason??""}),this.goal=s}heard(e){let n=Fe(e),s=this.messages.get(n),r=e.status==="delivered"||e.status==="failed"?e.status:"pending";this.messages.set(n,{clientId:e.client_id,id:e.id??s?.id??null,text:e.text,author:e.author??null,authorName:e.author_name??"",delivery:e.delivery??"next",status:s?.status==="delivered"?"delivered":r,error:e.error??null,responseId:e.response_id??s?.responseId??null,createdAt:e.created_at??s?.createdAt??"",mine:!1,metadata:e.metadata??s?.metadata??{},history:!1,truncated:!1,kind:e.kind??s?.kind??"text",voice:e.voice?{id:e.voice.id,role:e.voice.role}:s?.voice??null,attachments:e.attachments?ue(e.attachments):s?.attachments??[]}),s||this.place(e,n),this.changed()}said(e){let n=`voice\0${e.id}`,s=this.messages.get(n);this.messages.set(n,{clientId:"",id:e.id,text:e.text,author:e.user_id,authorName:e.author_name,delivery:"next",status:"delivered",error:null,responseId:null,createdAt:e.created_at,mine:!1,metadata:{},history:!1,truncated:!1,kind:"voice",voice:{id:e.voice_id,role:e.role},attachments:[]}),s||this.order.push({type:"message",key:n}),this.changed()}place(e,n){let s=e.response_id??null,o=s!==null&&![...this.messages.entries()].some(([a,i])=>a!==n&&i.responseId===s)?this.order.findIndex(a=>a.type==="response"&&a.key===s):-1;o>=0?this.order.splice(o,0,{type:"message",key:n}):this.order.push({type:"message",key:n})}response(e){let n=this.responses.get(e);return n||(n={id:e,status:null,waiting:null,end:null,error:null,text:"",marks:new Map,thought:new Set,runId:null,agent:null,parentId:null,startedBy:void 0,goal:null},this.responses.set(e,n),this.order.push({type:"response",key:e})),n}changed(){this.snapshot=void 0,!this.told&&(this.told=!0,queueMicrotask(()=>{this.told=!1;let e=this.state;for(let n of[...this.listeners])try{n(e)}catch{}}))}build(){let e=this.me(),n=d=>e!==void 0&&d.startedBy===e,s=new Map;for(let d of this.responses.values()){let u=d.parentId!==null?this.responses.get(d.parentId)??d:d;s.set(d.id,We(d,u.startedBy??null,n(u),d.goal??u.goal))}let r=new Map([...this.messages].map(([d,u])=>[d,e!==void 0&&u.author===e?{...u,mine:!0}:u])),o=[...this.history.entries()].sort(([d],[u])=>d-u).flatMap(([d,u])=>u.map((f,m)=>He(f,`${d}:${m}`,e))),a=[...o];for(let d of this.order)d.type==="goal"?a.push({type:"goal",goal:d.event}):d.type==="voice"?a.push({type:"voice",voice:d.event}):d.type==="message"?a.push({type:"message",message:r.get(d.key)}):this.responses.get(d.key).parentId===null&&a.push({type:"response",response:s.get(d.key)});let i=o.flatMap(d=>d.type==="message"?[d.message]:[]),c=o.flatMap(d=>d.type==="response"?[d.response]:[]),p=[...this.calls.values()].filter(d=>s.get(d.response_id)?.mine===!0);return{items:a,messages:[...i,...r.values()],responses:[...c,...s.values()],turn:this.turn,waiting:{approvals:p.filter(d=>d.status==="awaiting_approval"),outputs:p.filter(d=>d.status==="awaiting_output")},goal:this.goal,forkedFrom:this.forkedFrom,voice:this.voice?Je(this.voice,e):null}}};function Je(t,e){return{id:t.voice_id,userId:t.user_id,mine:e!==void 0&&t.user_id===e,delegation:t.delegation,status:t.status,seconds:typeof t.seconds=="number"?t.seconds:null,closeReason:t.close_reason??""}}function ue(t){return t.map((e,n)=>({kind:e.kind,name:e.name,contentType:e.content_type,size:e.size,sha256:e.sha256,position:n,bucket:e.bucket,path:e.path,workspacePath:e.workspace_path??null}))}function Fe(t){return`${t.author??""}\0${t.client_id}`}function We(t,e,n,s){let r=[...t.marks.values()].map((c,p)=>({m:c,i:p,at:T(t.text,Math.max(0,Number(c.text_offset)||0))}));r.sort((c,p)=>c.at-p.at||c.i-p.i);let o=[],a=[],i=0;for(let{m:c,at:p}of r)p>i&&o.push({type:"text",text:t.text.slice(i,p)}),i=Math.max(i,p),c.type==="thinking"?(o.push({type:"thinking",thinking:c.thinking}),a.push(c.thinking)):o.push(c.type==="tool"?{type:"tool",tool:c}:{type:"agent",agent:c});return i<t.text.length&&o.push({type:"text",text:t.text.slice(i)}),{id:t.id,status:t.status,waiting:t.waiting,end:t.end,error:t.error,text:t.text,parts:o,runId:t.runId,agent:t.agent,parentId:t.parentId,startedBy:e,mine:n,thinking:a,goal:s,history:!1,truncated:!1}}function He(t,e,n){let s=t.text_truncated===!0;if(t.role==="user"){let r=t.author??null;return{type:"message",message:{clientId:t.client_id??"",id:t.message_id??null,text:t.text,author:r,authorName:t.author_name??"",delivery:"next",status:"delivered",error:null,responseId:null,createdAt:t.created_at??"",mine:n!==void 0&&r===n,metadata:t.metadata??{},history:!0,truncated:s,kind:"text",voice:null,attachments:ue(t.attachments??[])}}}return{type:"response",response:{id:t.response_id??`history:${e}`,status:"completed",waiting:null,end:"completed",error:null,text:t.text,parts:t.text===""?[]:[{type:"text",text:t.text}],runId:null,agent:null,parentId:null,startedBy:null,mine:!1,thinking:[],goal:null,history:!0,truncated:s}}}var D=[["ApiKeyAuth","userJWT"]];function pe(t){return{async parts(e,n){let s={};n.limit!==void 0&&(s.limit=n.limit),n.cursor!==void 0?s.cursor=n.cursor:n.before!==void 0&&(s.before=n.before);let r=(await t.send({op:"ListChatParts",method:"GET",path:`/ai/chats/${_("ListChatParts","chat_id",e)}/parts`,auth:D,answers:{200:"json"},query:s,signal:n.signal})).data;return r.next_cursor===void 0?{parts:r.parts}:{parts:r.parts,nextCursor:r.next_cursor}},async toolCall(e,n,s){if(typeof n!="string"||n==="")throw new TypeError("chatToolCall: callId is a tool part's call_id");let r=(await t.send({op:"GetChatToolCall",method:"GET",path:`/ai/chats/${_("GetChatToolCall","chat_id",e)}/tool-calls/${_("GetChatToolCall","call_id",n)}`,auth:D,answers:{200:"json"},signal:s})).data;return{callId:r.call_id,name:r.name,status:r.status,runId:r.run_id,responseId:r.response_id,input:r.input,output:r.output,outputBytes:r.output_bytes,imageCount:r.image_count,isError:r.is_error}},async workspaceFile(e,n,s,r){if(typeof n!="string"||n==="")throw new TypeError("chatWorkspaceFile: path is the file as the workspace's tree names it, relative to its root");let o={path:n};return s!==void 0&&(o.manifest=s),(await t.send({op:"GetChatWorkspaceFile",method:"GET",path:`/ai/chats/${_("GetChatWorkspaceFile","chat_id",e)}/workspace/files`,auth:D,answers:{200:"raw"},query:o,signal:r})).data.blob()}}}var $=class extends Error{reason;constructor(e,n){super(e),this.name="GatewayError",this.reason=n}},he=new WeakMap;async function fe(t,e,n,s={},r=()=>{},o){let{pattern:a,events:i,messages:c,durable:p,chat:d}=Ue(e),u=Ve(a,n),f=he.get(t);f||he.set(t,f=new Map);let m=f,g=m.get(u)??{count:0};m.set(u,g),g.count++;let y=t.channel(u,p&&s.history!==!1?{after:0}:{});if(d&&!g.chat){let h=n.chatId,k=new I(r,o,typeof h=="string"&&h!==""?h:void 0);g.chat=k,g.unchat=y.on("broadcast",w=>{w.event==="chat"&&k.takePayload(w.payload)})}let x=()=>{--g.count>0||(m.delete(u),g.unchat?.(),g.chat?.end(),y.leave())};try{await y.join()}catch{let h=y.state==="refused"?ge(y.refusal,"unavailable"):"socket closed";throw x(),new $(`gateway ${JSON.stringify(u)} was not joined: ${h}`,h)}let C=!1,S=new Set,W=()=>{if(!C){C=!0,Ge();for(let h of[...S])h();x()}},Ge=y.onClosed(W),H=h=>{if(C)return()=>{};let k=y.on("broadcast",v=>{typeof v.event=="string"&&i.has(v.event)&&h(v.event,b(v.payload))}),w=()=>{S.delete(w),k()};return S.add(w),w},U={topic:u,get seq(){return y.logSeq},on(h,k){if(typeof h=="function")return H((w,v)=>h({event:w,payload:v}));if(!i.has(h))throw new TypeError(`gateway ${JSON.stringify(a)} declares no event ${JSON.stringify(String(h))}`);if(typeof k!="function")throw new TypeError(`gateway ${JSON.stringify(a)}: on(${JSON.stringify(h)}, \u2026) takes the function the event is handed to`);return H((w,v)=>{w===h&&k(v)})},off(h){S.has(h)&&h()},async send(h,k){if(!c.has(h))throw new TypeError(`gateway ${JSON.stringify(a)} declares no message ${JSON.stringify(String(h))}`);let w=C?{status:"error",response:{reason:"not joined"}}:await y.push("broadcast",{type:"broadcast",event:h,payload:k});if(w.status==="ok")return b(w.response.reply);let v=ge(w.response,"unavailable");throw new $(`gateway ${JSON.stringify(u)} did not take ${JSON.stringify(h)}: ${v}`,v)},leave:W};return d&&Object.defineProperty(U,"chat",{value:g.chat,enumerable:!0}),U}function Ue(t){let e=typeof t=="object"&&t!==null?t:{},n=s=>Array.isArray(s)&&s.every(r=>typeof r=="string");if(typeof e.pattern!="string"||e.pattern===""||!n(e.events)||!n(e.messages))throw new TypeError("join takes a gateway of the backend's generated module: its pattern, its events and its messages");return{pattern:e.pattern,events:new Set(e.events),messages:new Set(e.messages),durable:e.durable===!0,chat:e.chat===!0}}function Ve(t,e){let n=typeof e=="object"&&e!==null?e:{};return t.split(":").map(s=>{if(!(s.startsWith("{")&&s.endsWith("}")&&s.length>2))return s;let r=s.slice(1,-1),o=Object.hasOwn(n,r)?n[r]:void 0;if(typeof o!="string"||o==="")throw new TypeError(`gateway ${JSON.stringify(t)} needs a value for ${JSON.stringify(r)}`);if(o.includes(":"))throw new TypeError(`gateway ${JSON.stringify(t)}: the value of ${JSON.stringify(r)} is one segment of the channel's name and cannot hold ":"`);return o}).join(":")}function ge(t,e){let n=t?.reason;return typeof n=="string"&&n!==""?n:e}var ze=3600*1e3,O=new Map;function Qe(t,e,n=!1){let s=`${e.projectId}\0${e.signer}`,r=O.get(s);if(!n&&r&&Date.now()-r.at<ze)return r.list;let o=(async()=>{let a=te(),i;try{i=(await t.send({op:"GetTransitPublicKeys",method:"GET",path:"/secrets/transit/public",query:{nonce:a},auth:[["ApiKeyAuth"]],answers:{200:"json"}})).data}catch(c){throw new l("network",{code:"encryption_keys_unavailable",message:"the project's encryption keys could not be fetched: no encrypted field is sent without them",cause:c})}try{return await ne(i,e.signer,e.projectId,a)}catch(c){throw new l("decode",{code:"encryption_keys_unverified",message:"the project's list of encryption keys does not verify with the key this app was built with: nothing is sealed to it",cause:c})}})();return O.set(s,{list:o,at:Date.now()}),o.catch(()=>{O.get(s)?.list===o&&O.delete(s)}),o}async function ye(t,e,n,s,r,o){let i=(await Qe(t,e,o)).keys[0];return Y(i.kid,i.key,Q(e.projectId,n,s,r))}function K(t,e,n,s){return e==null||!s||s.length===0?Promise.resolve(e):G(e,n,s,(r,o)=>Z(t.key,r,o))}function me(t,e,n,s){return e===void 0||!n||n.length===0?Promise.resolve(e):G(e,"/response",n,async(r,o)=>{if(!X(o))throw new l("decode",{code:"field_not_encrypted",message:`${s}: ${r} came plain where the backend's contract says it is encrypted`});try{return await ee(t.key,r,o)}catch(a){throw new l("decode",{code:"field_unopenable",message:`${s}: ${r} does not open with this call's key`,cause:a})}})}function we(t){return t instanceof l&&(t.code==="encryption_key_retired"||t.code==="encryption_key_unknown")}var B=class{pending="";dataLines=[];eventName;consume(e){this.pending+=e.replace(/\r\n/g,`
3
- `);let n=[],s=this.pending.indexOf(`
4
- `);for(;s!==-1;){let r=this.pending.slice(0,s);this.pending=this.pending.slice(s+1);let o=r.endsWith("\r")?r.slice(0,-1):r;if(o==="")this.dataLines.length>0&&n.push({event:this.eventName,payload:this.dataLines.join(`
5
- `)}),this.dataLines=[],this.eventName=void 0;else if(!o.startsWith(":")){if(o.startsWith("data:")){let a=o.slice(5);this.dataLines.push(a.startsWith(" ")?a.slice(1):a)}else if(o.startsWith("event:")){let a=o.slice(6);this.eventName=a.startsWith(" ")?a.slice(1):a}}s=this.pending.indexOf(`
6
- `)}return n}};async function*ve(t,e){let n=t.getReader(),s=new TextDecoder,r=new B;try{for(;;){let{done:o,value:a}=await n.read();if(o)break;for(let i of r.consume(s.decode(a,{stream:!0}))){if(i.event==="error")throw new l("network",{code:"stream_failed",message:`stream failed: ${i.payload}`});let c;try{c=JSON.parse(i.payload)}catch{throw new l("decode",{code:"invalid_frame",message:`stream frame is not valid JSON: ${i.payload.slice(0,120)}`})}yield b(c)}}}finally{e.abort();try{await n.cancel()}catch{}}}var Ye={},be=new WeakMap;function Nt(t,e,n,s,r,o=()=>{}){be.set(t,{project:e,machine:n,storage:s,socket:r,me:o})}var _e=new Map,ke=new WeakMap;function qt(t,e,n,s,r,o){if(!ie(e))throw new l("validation",{code:"reserved_namespace",message:`Cannot register backend ${JSON.stringify(String(e))}: a backend's name is an identifier the client does not keep.`});let a=ce(t);if(!de(n))throw new TypeError(`${JSON.stringify(String(n))} is not a machine's name: a lowercase letter, then lowercase letters, digits and -`);le(s),Ce(r);for(let i of Object.keys(r))if(ae(i))throw Ee(i);if(o!==void 0)nt(o);else if(xe(r))throw new l("validation",{code:"invalid_namespace_tree",message:`Backend ${e}: its routes carry encrypted fields, and its module holds no project id and signing key to seal them with \u2014 generate it again with palbase apps:sync`});(_e.get(e)??Ze(e)).set(a,{machine:n,url:s,tree:r,...o?{transit:{...o}}:{}})}function Ze(t){let e=new Map;return _e.set(t,e),Object.defineProperty(Ye,t,{configurable:!0,get(){return Xe(this,t,e)}}),e}function Xe(t,e,n){let s=be.get(t);if(!s)return;let r=n.get(s.project);if(!r)throw new TypeError(`pb.${e} is the backend of ${[...n.keys()].join(" and ")}: this client is ${s.project}'s, and its user's session never goes to another project's machine`);let o=ke.get(t);o||ke.set(t,o=new Map);let a=o.get(e);if(a?.registration===r)return a.ns;let i={machine:()=>s.machine(r.url),storage:s.storage,name:r.machine,...r.transit?{transit:{project:s.storage,config:r.transit}}:{}},c=Object.assign({call:(p,d,u)=>dt(i.machine,p,d,u),join:(p,d,u)=>fe(s.socket,p,d,u,s.me,pe(s.storage))},Se(r.tree,i));return o.set(e,{registration:r,ns:c}),c}function Ee(t){return new l("validation",{code:"reserved_namespace",message:`Cannot register endpoint namespace ${JSON.stringify(t)}: the name is reserved.`})}function L(t){return typeof t.path=="string"&&typeof t.method=="string"}function et(t,e){if(t.pathParams!==void 0){if(!Array.isArray(t.pathParams)||!t.pathParams.every(n=>typeof n=="string"))throw new l("validation",{code:"invalid_namespace_tree",message:`Descriptor '${e}': pathParams must be an array of strings.`});for(let n of t.pathParams)if(!t.path.includes(`{${n}}`))throw new l("validation",{code:"invalid_namespace_tree",message:`Descriptor '${e}': pathParams entry '${n}' has no '{${n}}' placeholder in the path.`})}if(t.sse!==void 0&&typeof t.sse!="boolean")throw new l("validation",{code:"invalid_namespace_tree",message:`Descriptor '${e}': sse must be a boolean.`});if(t.idempotent!==void 0&&typeof t.idempotent!="boolean")throw new l("validation",{code:"invalid_namespace_tree",message:`Descriptor '${e}': idempotent must be a boolean.`});if(t.upload!==void 0&&typeof t.upload!="boolean")throw new l("validation",{code:"invalid_namespace_tree",message:`Descriptor '${e}': upload must be a boolean.`});if(t.upload===!0&&(t.method!=="POST"||t.sse===!0))throw new l("validation",{code:"invalid_namespace_tree",message:`Descriptor '${e}': an upload endpoint is a POST, and no stream.`});if(t.sse===!0&&t.input==="query")throw new l("validation",{code:"invalid_namespace_tree",message:`Descriptor '${e}': an sse endpoint cannot take query input.`});if(t.input!==void 0&&t.input!=="body"&&t.input!=="query"&&t.input!=="none")throw new l("validation",{code:"invalid_namespace_tree",message:`Descriptor '${e}': input must be 'body', 'query' or 'none'.`});if(t.encryption!==void 0&&tt(t,e),t.errors!==void 0){for(let[n,s]of Object.entries(t.errors))if(typeof s!="function")throw new l("validation",{code:"invalid_namespace_tree",message:`Descriptor '${e}': errors['${n}'] must be a function.`})}}function tt(t,e){let n=t.encryption,s=r=>new l("validation",{code:"invalid_namespace_tree",message:`Descriptor '${e}': encryption ${r}.`});if(typeof n!="object"||n===null)throw s("is { request, response }");for(let[r,o]of[["request",["/body/","/query/"]],["response",["/response"]]]){let a=n[r];if(a!==void 0&&(!Array.isArray(a)||!a.every(i=>typeof i=="string"&&o.some(c=>i===c||i.startsWith(c.endsWith("/")?c:`${c}/`)))))throw s(`${r} is a list of places under ${o.join(" or ")}`)}if(t.upload===!0)throw s("is no upload\u2019s: storage seals nothing");if(t.sse===!0&&(n.response?.length??0)>0)throw s("of a streamed answer is none")}function xe(t){return L(t)?t.encryption!==void 0:Object.values(t).some(e=>xe(e))}function nt(t){if(typeof t!="object"||t===null||typeof t.projectId!="string"||!/^[0-9a-f-]{36}$/.test(t.projectId)||typeof t.signer!="string"||!/^[A-Za-z0-9_-]{43}$/.test(t.signer))throw new l("validation",{code:"invalid_namespace_tree",message:"The backend's encryption is { projectId, signer }: the project's id and its Ed25519 signing key, base64url"})}function Ce(t){if(typeof t!="object"||t===null)throw new l("validation",{code:"invalid_namespace_tree",message:"Namespace tree nodes must be plain objects."});let e=Object.getPrototypeOf(t);if(e!==Object.prototype&&e!==null)throw new l("validation",{code:"invalid_namespace_tree",message:"Namespace tree nodes must be plain objects."});for(let[n,s]of Object.entries(t)){if(P(n))throw Ee(n);typeof s=="object"&&s!==null&&L(s)?(s.method=s.method.toUpperCase(),et(s,s.path)):Ce(s)}}function Se(t,e){if(L(t))return t.upload===!0?async(...s)=>at(e,t,s):async(...s)=>Pe(e.machine(),t,s,e.transit);let n={};for(let[s,r]of Object.entries(t))n[s]=Se(r,e);return n}function J(t){if(t==null)return"";let e=Object.entries(t).filter(([,s])=>s!=null).sort(([s],[r])=>s<r?-1:s>r?1:0);return e.length===0?"":`?${e.map(([s,r])=>{if(typeof r!="string"&&typeof r!="number"&&typeof r!="boolean")throw new l("validation",{code:"invalid_query_value",message:`Query parameter '${s}' must be a string, number, or boolean.`});return`${encodeURIComponent(s)}=${encodeURIComponent(String(r))}`}).join("&")}`}function Te(t,e,n){try{return _(t.path,e,n)}catch(s){if(!R(s)||s.code!=="invalid_path_parameter")throw s;let r=String(n);throw new l("validation",{code:"invalid_path_parameter",message:`${t.path}: ${e} cannot be ${r===""?"empty":JSON.stringify(r)}`})}}function Re(t,e){let n=t.pathParams??[],s=t.path;for(let r=0;r<n.length;r++){let o=e[r];if(typeof o!="string"&&typeof o!="number")throw new l("validation",{code:"missing_path_param",message:`${t.path}: path parameter '${n[r]}' must be a string or number`});s=s.replace(`{${n[r]}}`,Te(t,`path parameter '${n[r]}'`,o))}return s}var st=new Set(["POST","PUT","PATCH","DELETE"]);async function Pe(t,e,n,s){let r=e.pathParams??[],o=Re(e,n),a=o;if(e.input==="none"&&n.length>r.length+1)throw new l("validation",{code:"unexpected_argument",message:`${e.path}: endpoint takes no input \u2014 pass only path params and options`});let i=e.input==="none"?void 0:n[r.length],c=e.input==="none"?r.length:r.length+1,p=n[c],d;if(e.input==="query")a+=J(i);else if(e.input!=="none")if(e.method==="GET"){if(i!==void 0)throw new l("validation",{code:"unsupported_get_input",message:`${e.path}: GET endpoints take no body input`})}else d=i;let u={...p?.headers};if(st.has(e.method)&&!Object.keys(u).some(f=>f.toLowerCase()==="idempotency-key")&&(u["Idempotency-Key"]=A()),e.encryption!==void 0){if(!s)throw new l("validation",{code:"encryption_unconfigured",message:`${e.method} ${e.path}: the route carries encrypted fields, and this backend's module holds no key to seal them with`});return rt(t,e,o,i,d,u,p?.signal,r.map((f,m)=>String(n[m])),s)}try{return e.sse===!0?await Ae(t,e,a,d,u,p?.signal):await Oe(t,e,a,d,u,p?.signal)}catch(f){throw F(e,f)}}async function rt(t,e,n,s,r,o,a,i,c){let p=e.encryption;for(let d=0;;d++){let u=await ye(c.project,c.config,e.method,e.path,i,d>0);try{let f=e.input==="query"?n+J(await K(u,s,"/query",p.request)):n,m=await K(u,r,"/body",p.request),g={...o,[z]:u.header};return e.sse===!0?await Ae(t,e,f,m,g,a):b(await me(u,await Oe(t,e,f,m,g,a),p.response,`${e.method} ${e.path}`))}catch(f){if(d===0&&we(f))continue;throw F(e,f)}}}function F(t,e){return t.errors&&oe(e)&&Object.hasOwn(t.errors,e.code)?t.errors[e.code](e):e}var ot=[["ApiKeyAuth","userJWT"],["ApiKeyAuth"]];async function at(t,e,n){let s=e.pathParams??[],r=Re(e,n),o=e.input==="none"?s.length:s.length+1;if(n.length>o+2)throw new l("validation",{code:"unexpected_argument",message:`${e.path}: an upload takes its path params, ${e.input==="none"?"":"its input, "}the file and options`});let a=e.input==="none"?void 0:n[s.length],i=n[o],c=n[o+1];if(!(i instanceof Blob))throw new l("validation",{code:"invalid_file",message:`${e.path}: the file is a Blob (a File is one)`});let p=`/storage/upload/${t.name}/${Te(e,"the route",r.slice(1))}`;e.input==="query"&&(p+=J(a));let d=it(e.input==="query"?void 0:a,i),u=d.body.size,f=0,m=g=>{f=g;try{c?.onProgress?.({loaded:g,total:u})}catch{}};c?.onProgress&&m(0);try{let g;try{let y={op:`Upload ${e.path}`,method:"POST",path:p,auth:ot,answers:Ie,body:{kind:"raw",contentType:d.type,value:d.body},signal:c?.signal,...c?.onProgress?{onUploadProgress:x=>m(x)}:{}};g=(await t.storage.send(y)).data}catch(y){throw R(y)?q(y):y}return c?.onProgress&&f<u&&m(u),await je(e,g,c?.signal)}catch(g){throw F(e,g)}}function it(t,e){let n=`Palbase-${A()}`,s=i=>i.replaceAll('"',"_").replace(/[\r\n]/g,""),r=typeof e.name=="string"?e.name:"blob",o=(i,c)=>`--${n}\r
7
- Content-Disposition: form-data; ${i}\r
8
- Content-Type: ${c}\r
9
- \r
10
- `,a=[];return t!==void 0&&a.push(o('name="body"',"application/json"),JSON.stringify(t),`\r
11
- `),a.push(o(`name="file"; filename="${s(r)}"`,s(e.type)||"application/octet-stream"),e,`\r
12
- --${n}--\r
13
- `),{body:new Blob(a),type:`multipart/form-data; boundary=${n}`}}async function dt(t,e,n,s){if(typeof e!="string"||e===""||e==="/")throw new l("validation",{code:"invalid_endpoint_name",message:'Endpoint name must be a non-empty path like "todos/create"'});let r=e.startsWith("/")?e:`/${e}`;return Pe(t(),{method:"POST",path:r},[n,s])}var Ie=Object.fromEntries(Array.from({length:100},(t,e)=>[200+e,"raw"])),lt=[["userJWT"],[]];async function $e(t,e,n,s,r,o){let a={op:`${e.method} ${e.path}`,method:e.method,path:n,auth:lt,answers:Ie,headers:r,...s===void 0?{}:{body:{kind:"json",contentType:"application/json",value:s}},idempotent:e.idempotent===!0,signal:o};try{return(await t.send(a)).data}catch(i){throw R(i)?q(i):i}}async function Oe(t,e,n,s,r,o){return je(e,await $e(t,e,n,s,r,o),o)}async function je(t,e,n){let s=e.headers.get("x-request-id")??void 0,r;try{r=await e.text()}catch(o){throw n?.aborted?o:new l("network",{code:"network_error",message:`${t.method} ${t.path}: the answer did not arrive whole`,status:e.status,requestId:s,cause:o})}if(r!=="")try{return b(JSON.parse(r))}catch(o){throw new l("decode",{code:"invalid_json",message:`${t.method} ${t.path}: the answer is not JSON`,status:e.status,requestId:s,cause:o})}}async function Ae(t,e,n,s,r,o){let a=new AbortController;o&&(o.aborted?a.abort():o.addEventListener("abort",()=>a.abort(),{once:!0}));let i=await $e(t,e,n,s,{accept:"text/event-stream",...r},a.signal);if(!i.body)throw new l("network",{code:"empty_stream",message:"the server answered a streaming route with no body",status:i.status});return ve(i.body,a)}export{l as a,oe as b,Ke as c,ie as d,pe as e,$ as f,Ye as g,Nt as h,qt as i};