palbase 0.13.2 → 0.14.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 (53) 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/{DLQT5KPC.js → 22WJEDHI.js} +1 -1
  8. package/dist/chunks/{UMCUTNWL.js → 5LC7GWQ4.js} +2 -2
  9. package/dist/chunks/{B5XYZZDJ.js → 7MGWLEW2.js} +1 -1
  10. package/dist/chunks/{ZOF56QTG.js → AGZIRK5O.js} +2 -2
  11. package/dist/chunks/{QCZJK4GZ.js → DQ4XHMZN.js} +2 -2
  12. package/dist/chunks/FGKFL5W3.js +18 -0
  13. package/dist/chunks/{MWTLLONV.js → FQV5NKI4.js} +2 -2
  14. package/dist/chunks/{B33QXIR5.js → HQTKK3LU.js} +1 -1
  15. package/dist/chunks/{ZT4AKS6D.js → JGUZOLS4.js} +2 -2
  16. package/dist/chunks/{NRWY25JZ.js → KOR6BP5M.js} +1 -1
  17. package/dist/chunks/MDKUD5KF.js +2 -0
  18. package/dist/chunks/{53ZQBGJV.js → OG5U5HFP.js} +2 -2
  19. package/dist/chunks/{JEI4RW55.js → OIKBZFMC.js} +2 -2
  20. package/dist/chunks/{7ZSVOQFN.js → QGGRIABQ.js} +2 -2
  21. package/dist/chunks/{22JG5QKQ.js → R2FKMKIY.js} +1 -1
  22. package/dist/chunks/UUS5URWX.js +21 -0
  23. package/dist/chunks/{66QSZDXV.js → VI7VITLG.js} +2 -2
  24. package/dist/chunks/{X2BWW2WC.js → VYPEK5RA.js} +1 -1
  25. package/dist/chunks/{IYUDOOD7.js → XA7ML545.js} +2 -2
  26. package/dist/chunks/XMJ4WMD2.js +2 -0
  27. package/dist/chunks/{ABRUIWQ3.js → XUX2HR4Z.js} +1 -1
  28. package/dist/chunks/{LDZ7OKNS.js → YX4W5H7Q.js} +2 -2
  29. package/dist/chunks/{JWLK6SLN.js → ZSICMUJY.js} +2 -2
  30. package/dist/cli.js +123 -122
  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/ai/src/ai.d.ts +34 -7
  45. package/types/ai/src/chats.d.ts +73 -7
  46. package/types/ai/src/index.d.ts +3 -3
  47. package/types/ai/src/tools.d.ts +37 -7
  48. package/types/backend/src/openapi.d.ts +22 -0
  49. package/types/internal/src/modules/ai.d.ts +259 -13
  50. package/dist/chunks/2DBSGJ7Z.js +0 -2
  51. package/dist/chunks/WAMYRYDY.js +0 -2
  52. package/dist/chunks/WUYO4O77.js +0 -18
  53. package/dist/chunks/YWEI45Q6.js +0 -21
package/dist/refuse/ai.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! palbase 0.13.2 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.14.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.13.2 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.14.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.13.2 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.14.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.13.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/UMCUTNWL.js";import{a as c,b as d}from"../chunks/ABRUIWQ3.js";import"../chunks/B33QXIR5.js";import"../chunks/X2BWW2WC.js";import{m as b}from"../chunks/WAMYRYDY.js";import"../chunks/ZOF56QTG.js";import{b as a}from"../chunks/7ZSVOQFN.js";import"../chunks/DLQT5KPC.js";import"../chunks/22JG5QKQ.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.14.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/5LC7GWQ4.js";import{a as c,b as d}from"../chunks/XUX2HR4Z.js";import"../chunks/HQTKK3LU.js";import"../chunks/VYPEK5RA.js";import{m as b}from"../chunks/XMJ4WMD2.js";import"../chunks/AGZIRK5O.js";import{b as a}from"../chunks/QGGRIABQ.js";import"../chunks/22WJEDHI.js";import"../chunks/R2FKMKIY.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.13.2 — Palbase SDK License (see LICENSE) */
2
- import{a,b,c,d,e}from"../chunks/53ZQBGJV.js";import"../chunks/ABRUIWQ3.js";import"../chunks/DLQT5KPC.js";import"../chunks/22JG5QKQ.js";export{b as TestApiError,e as api,c as createTestApi,a as testFields,d as testRun};
1
+ /*! palbase 0.14.0 — Palbase SDK License (see LICENSE) */
2
+ import{a,b,c,d,e}from"../chunks/OG5U5HFP.js";import"../chunks/XUX2HR4Z.js";import"../chunks/22WJEDHI.js";import"../chunks/R2FKMKIY.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.13.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/LDZ7OKNS.js";import{a as _,b as Q,f as z}from"../chunks/ZT4AKS6D.js";import"../chunks/QCZJK4GZ.js";import"../chunks/JWLK6SLN.js";import"../chunks/NRWY25JZ.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/B33QXIR5.js";import"../chunks/2DBSGJ7Z.js";import"../chunks/WAMYRYDY.js";import"../chunks/ZOF56QTG.js";import{b as L}from"../chunks/7ZSVOQFN.js";import"../chunks/DLQT5KPC.js";import"../chunks/22JG5QKQ.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.14.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/YX4W5H7Q.js";import{a as _,b as Q,f as z}from"../chunks/JGUZOLS4.js";import"../chunks/DQ4XHMZN.js";import"../chunks/ZSICMUJY.js";import"../chunks/KOR6BP5M.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/HQTKK3LU.js";import"../chunks/MDKUD5KF.js";import"../chunks/XMJ4WMD2.js";import"../chunks/AGZIRK5O.js";import{b as L}from"../chunks/QGGRIABQ.js";import"../chunks/22WJEDHI.js";import"../chunks/R2FKMKIY.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.13.2 — Palbase SDK License (see LICENSE) */
2
- import{a as i}from"../chunks/JWLK6SLN.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/NRWY25JZ.js";import"../chunks/22JG5QKQ.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.14.0 — Palbase SDK License (see LICENSE) */
2
+ import{a as i}from"../chunks/ZSICMUJY.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/KOR6BP5M.js";import"../chunks/R2FKMKIY.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.13.2 — Palbase SDK License (see LICENSE) */
2
- import{c as e,d as r,i as t}from"../chunks/ZT4AKS6D.js";import"../chunks/B33QXIR5.js";import"../chunks/2DBSGJ7Z.js";import"../chunks/ZOF56QTG.js";import"../chunks/7ZSVOQFN.js";import"../chunks/DLQT5KPC.js";import"../chunks/22JG5QKQ.js";export{e as RESERVED_CLIENT_NAMES,t as __registerBackend,r as isClientName};
1
+ /*! palbase 0.14.0 — Palbase SDK License (see LICENSE) */
2
+ import{c as e,d as r,i as t}from"../chunks/JGUZOLS4.js";import"../chunks/HQTKK3LU.js";import"../chunks/MDKUD5KF.js";import"../chunks/AGZIRK5O.js";import"../chunks/QGGRIABQ.js";import"../chunks/22WJEDHI.js";import"../chunks/R2FKMKIY.js";export{e as RESERVED_CLIENT_NAMES,t as __registerBackend,r as isClientName};
@@ -1,2 +1,2 @@
1
- /*! palbase 0.13.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/QCZJK4GZ.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/NRWY25JZ.js";import"../chunks/7ZSVOQFN.js";import"../chunks/DLQT5KPC.js";import"../chunks/22JG5QKQ.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.14.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/DQ4XHMZN.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/KOR6BP5M.js";import"../chunks/QGGRIABQ.js";import"../chunks/22WJEDHI.js";import"../chunks/R2FKMKIY.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.13.2 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.14.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.13.2 — Palbase SDK License (see LICENSE) */
2
- import{q as f}from"../chunks/LDZ7OKNS.js";import"../chunks/ZT4AKS6D.js";import"../chunks/QCZJK4GZ.js";import"../chunks/JWLK6SLN.js";import"../chunks/NRWY25JZ.js";import"../chunks/B33QXIR5.js";import"../chunks/2DBSGJ7Z.js";import"../chunks/WAMYRYDY.js";import"../chunks/ZOF56QTG.js";import"../chunks/7ZSVOQFN.js";import"../chunks/DLQT5KPC.js";import"../chunks/22JG5QKQ.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.14.0 — Palbase SDK License (see LICENSE) */
2
+ import{q as f}from"../chunks/YX4W5H7Q.js";import"../chunks/JGUZOLS4.js";import"../chunks/DQ4XHMZN.js";import"../chunks/ZSICMUJY.js";import"../chunks/KOR6BP5M.js";import"../chunks/HQTKK3LU.js";import"../chunks/MDKUD5KF.js";import"../chunks/XMJ4WMD2.js";import"../chunks/AGZIRK5O.js";import"../chunks/QGGRIABQ.js";import"../chunks/22WJEDHI.js";import"../chunks/R2FKMKIY.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.13.2 — Palbase SDK License (see LICENSE) */
2
- import"../chunks/22JG5QKQ.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.14.0 — Palbase SDK License (see LICENSE) */
2
+ import"../chunks/R2FKMKIY.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.13.2",
3
+ "version": "0.14.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.13.2",
138
+ "palgres": "0.14.0",
139
139
  "reflect-metadata": "^0.2.2",
140
140
  "typescript": "~6.0.3",
141
141
  "zod": "^4.6.5"
@@ -3,7 +3,7 @@ import { type RetryPolicy } from '../../internal/src/retry.js';
3
3
  import * as modules from '../../internal/src/modules/index.js';
4
4
  import { type Infer, type PreparedSchema, type StandardSchema } from './schema.js';
5
5
  import { type Agents, type Chats, type Endpoints, type Repos, type Settings } from './chats.js';
6
- import { type AgentContext, type BackendAgent, type BackendRepo, type BackendTool, type BackendToolOptions, type DeferredAnswer, type RepoTokenContext, type RepoTokens, type ClientTool, type ClientToolOptions, type HttpsToolRef, type McpToolRef, type TurnDefinition } from './tools.js';
6
+ import { type AgentContext, type BackendAgent, type BackendAgentOptions, type BackendRepo, type BackendTool, type BackendToolOptions, type DeferredAnswer, type RepoTokenContext, type RepoTokens, type ClientTool, type ClientToolOptions, type HttpsToolRef, type McpToolRef, type TurnDefinition } from './tools.js';
7
7
  type Module = ReturnType<typeof modules.ai.client>;
8
8
  export type Response = Awaited<ReturnType<Module['getResponse']>>['data'];
9
9
  export type Usage = Awaited<ReturnType<Module['listUsage']>>['data']['usage'][number];
@@ -69,6 +69,12 @@ export interface Ask {
69
69
  /** The question; or `messages`, the conversation so far. */
70
70
  prompt?: string;
71
71
  messages?: Message[];
72
+ /**
73
+ * One of the project's agents answers: its name (the version published), name@N (version N), or a backend's
74
+ * ai.agent. Its instructions, model, tools and output shape the answer; a field this request names (instructions,
75
+ * model, tools, a schema) replaces the agent's for this answer alone — the agent is not changed.
76
+ */
77
+ agent?: string | BackendAgent;
72
78
  instructions?: string;
73
79
  model?: Model;
74
80
  /** Pictures the question is about (4 at most): in the project's storage ({ bucket, path }), at an https address ({ url }), or their bytes ({ mediaType, data }) — a user's own file, checked by you (AskImage). */
@@ -84,6 +90,15 @@ export interface Ask {
84
90
  export interface Generate<S extends StandardSchema> extends Ask {
85
91
  schema: S | Schema<S>;
86
92
  }
93
+ /**
94
+ * A document of the shape of an agent's one-shot answers (its definition's output), checked by the platform against
95
+ * it: generate({ agent: 'classify', prompt }). Typed as T (unknown unless said); give a schema to have it typed and
96
+ * checked here as well — the call's schema then replaces the agent's output.
97
+ */
98
+ export interface AgentGenerate extends Ask {
99
+ agent: string | BackendAgent;
100
+ schema?: undefined;
101
+ }
87
102
  /** A schema checked against what the provider holds a model to: ai.schema(name, zod). */
88
103
  export interface Schema<S extends StandardSchema> {
89
104
  readonly name: string;
@@ -172,6 +187,13 @@ export interface AI {
172
187
  generate<S extends StandardSchema>(request: Generate<S> & {
173
188
  background: true;
174
189
  }): Promise<Job>;
190
+ /** A document of the shape of the agent's one-shot answers (its output), as the platform checked it. */
191
+ generate<T = unknown>(request: AgentGenerate & {
192
+ background?: false;
193
+ }): Promise<T>;
194
+ generate(request: AgentGenerate & {
195
+ background: true;
196
+ }): Promise<Job>;
175
197
  /** The answer as the model writes it: text, or with a schema the document as far as it has got. */
176
198
  stream(request: Ask): TextStream;
177
199
  stream<S extends StandardSchema>(request: Generate<S>): ObjectStream<Infer<S>>;
@@ -185,6 +207,8 @@ export interface AI {
185
207
  }): Promise<Response>;
186
208
  /** The document of a schema's response started in the background, checked. */
187
209
  result<S extends StandardSchema>(id: string, schema: S | Schema<S>): Promise<Infer<S>>;
210
+ /** The document of an agent's response started in the background (generate({ agent, background: true })), as the platform checked it against the agent's output. */
211
+ result<T = unknown>(id: string): Promise<T>;
188
212
  cancel(id: string): Promise<Response>;
189
213
  /** One vector per text, in order. */
190
214
  embed(texts: string[], options?: Embed): Promise<number[][]>;
@@ -219,7 +243,10 @@ export interface AI {
219
243
  disconnectProvider(provider: string): Promise<void>;
220
244
  /** The project's chats: started, written to, followed as typed parts, stopped; a tool call approved or answered. */
221
245
  readonly chats: Chats;
222
- /** The project's named agents: a chat started from the app, or by name from the server, talks to one. */
246
+ /**
247
+ * The project's agents: its backend's (ai.agent — its build's contract names them) and those it keeps, a draft and
248
+ * published versions; a chat, or a one-shot answer, talks to one by name.
249
+ */
223
250
  readonly agents: Agents;
224
251
  /** The project's HTTPS tools and MCP servers, which an agent may be given by name. */
225
252
  readonly endpoints: Endpoints;
@@ -243,12 +270,12 @@ export interface AI {
243
270
  }): DeferredAnswer;
244
271
  /**
245
272
  * An agent the backend defines at each turn's start, from the turn's
246
- * context: put it with ai.agents.put(agent), and its chats' turns ask the
247
- * machine for it. Made once, at a module's top level.
273
+ * context. It lives in the code: the build's contract names it
274
+ * (x-palbase-agents, with its description), and a chat started by its
275
+ * name asks the machine for it at each turn — nothing puts it anywhere.
276
+ * Made once, at a module's top level.
248
277
  */
249
- agent(name: string, define: (ctx: AgentContext) => TurnDefinition | Promise<TurnDefinition>, options?: {
250
- machine?: string;
251
- }): BackendAgent;
278
+ agent(name: string, define: (ctx: AgentContext) => TurnDefinition | Promise<TurnDefinition>, options?: BackendAgentOptions): BackendAgent;
252
279
  /**
253
280
  * A GitHub repository a chat's workspace works in, whose tokens this
254
281
  * backend gives (token, asked at each clone and each push): put it with
@@ -4,7 +4,16 @@ import { type AgentDefinitionInput, type BackendAgent, type BackendRepo } from '
4
4
  type Module = ReturnType<typeof modules.ai.client>;
5
5
  export type Chat = modules.ai.Chat;
6
6
  export type ChatMessage = modules.ai.ChatMessage;
7
+ /**
8
+ * An agent of the project's: one its backend's code defines (source code — changed in the code; its machine, and what
9
+ * its last turn was defined as), or one it keeps (source platform — a draft, and the version published that its chats
10
+ * talk to).
11
+ */
7
12
  export type Agent = modules.ai.Agent;
13
+ /** A published version of an agent the project keeps: it never changes. */
14
+ export type AgentVersion = modules.ai.AgentVersion;
15
+ /** A tool an agent of the project's may be given: the backend's (its build's contract), the project's endpoints, the platform's. */
16
+ export type AgentTool = modules.ai.Tool;
8
17
  export type Endpoint = modules.ai.Endpoint;
9
18
  export type Decision = modules.ai.Decision;
10
19
  /** What the project allows its chats. */
@@ -56,7 +65,11 @@ export interface CommitTrailer {
56
65
  value: string;
57
66
  }
58
67
  export interface CreateChat {
59
- /** A named agent of the project (or a backend's ai.agent, put); with a definition, the chat's name for it (default assistant). */
68
+ /**
69
+ * One of the project's agents by name — its backend's (a backend's ai.agent itself names it), or one it keeps, whose
70
+ * published version each turn takes; name@N stays on version N. With a definition, the chat's name for it (default
71
+ * assistant).
72
+ */
60
73
  agent?: string | BackendAgent;
61
74
  /** A definition of the chat's own, in place of a named agent. */
62
75
  definition?: AgentDefinitionInput;
@@ -649,13 +662,66 @@ export interface ChatEvents {
649
662
  signal?: AbortSignal;
650
663
  }): Promise<void>;
651
664
  }
665
+ /**
666
+ * The project's agents. Its backend's (ai.agent) are its code's: the build's contract names them, and they change
667
+ * with the code — nothing here puts them. The others the project keeps (made here, in Studio or with the CLI): a
668
+ * draft, saved as often as it changes, and versions, each one a publish made of the draft — its chats talk to the
669
+ * version published, by name ("support"), or stay on one ("support@3").
670
+ */
652
671
  export interface Agents {
653
- /** Names an agent: its definition, or a backend's ai.agent (its chats' turns ask the backend's machine). */
654
- put(name: string, definition: AgentDefinitionInput | BackendAgent): Promise<Agent>;
655
- put(agent: BackendAgent): Promise<Agent>;
656
- list(): Promise<Agent[]>;
657
- /** Its chats stay; a message to one is refused (agent_not_found) until it is put again. */
658
- delete(name: string): Promise<void>;
672
+ /** Every agent of the project's, by name: its backend's (in the builds that serve) and those it keeps. */
673
+ list(options?: {
674
+ signal?: AbortSignal;
675
+ }): Promise<Agent[]>;
676
+ /** One agent: a kept one's draft, revision and version published; a backend's machine, and what its last turn was. */
677
+ get(name: string, options?: {
678
+ signal?: AbortSignal;
679
+ }): Promise<Agent>;
680
+ /**
681
+ * Saves the draft of an agent the project keeps — a new one's first. Its chats go on talking to the version
682
+ * published: the draft is theirs once published. revision is the draft's revision the change was made on (Agent's
683
+ * revision, as read): when another was saved since, the save is refused (409 draft_changed) and nothing is lost;
684
+ * left out, the last save wins. A name the backend's code defines is refused (409 agent_defined_in_code).
685
+ */
686
+ saveDraft(name: string, definition: AgentDefinitionInput, options?: {
687
+ revision?: number;
688
+ signal?: AbortSignal;
689
+ }): Promise<Agent>;
690
+ /**
691
+ * Makes the draft a version — the next number — and the one its chats talk to from their next turn on. revision: the
692
+ * draft as it was looked at (409 draft_changed when another was saved since). A draft that is the version published
693
+ * already is refused (409 nothing_to_publish).
694
+ */
695
+ publish(name: string, options?: {
696
+ revision?: number;
697
+ signal?: AbortSignal;
698
+ }): Promise<Agent>;
699
+ /** Makes a version it had the one its chats talk to, and its draft that version: a change not published is dropped. */
700
+ rollback(name: string, version: number, options?: {
701
+ signal?: AbortSignal;
702
+ }): Promise<Agent>;
703
+ /** Its versions, newest first, a page at a time (20 unless said, at most 100), and the one published: nextCursor pages on. */
704
+ versions(name: string, options?: {
705
+ limit?: number;
706
+ cursor?: string;
707
+ signal?: AbortSignal;
708
+ }): Promise<{
709
+ versions: AgentVersion[];
710
+ publishedVersion: number | null;
711
+ nextCursor?: string;
712
+ }>;
713
+ /**
714
+ * Forgets an agent the project keeps, its versions with it. Its chats stay; a message to one is refused
715
+ * (agent_not_found) until an agent of that name is there again. One the backend's code defines goes with the code
716
+ * (409 agent_defined_in_code).
717
+ */
718
+ delete(name: string, options?: {
719
+ signal?: AbortSignal;
720
+ }): Promise<void>;
721
+ /** The tools an agent may be given: the backend's (as its build's contract declares them), the project's endpoints, the platform's. */
722
+ tools(options?: {
723
+ signal?: AbortSignal;
724
+ }): Promise<AgentTool[]>;
659
725
  }
660
726
  export interface Endpoints {
661
727
  /** An HTTPS tool or an MCP server; the answer says an https tool's signing secret, this once (putting it again makes a new one). */
@@ -1,10 +1,10 @@
1
1
  export { createAI, AIResponseError } from './ai.js';
2
- export type { AI, AIOptions, Ask, AskImage, AskTool, ChatModel, DeepPartial, Embed, Generate, ImageRequest, Images, Job, Message, Model, Models, ObjectStream, Picture, Response, Schema, TextStream, Uploader, Usage, } from './ai.js';
2
+ export type { AI, AIOptions, AgentGenerate, Ask, AskImage, AskTool, ChatModel, DeepPartial, Embed, Generate, ImageRequest, Images, Job, Message, Model, Models, ObjectStream, Picture, Response, Schema, TextStream, Uploader, Usage, } from './ai.js';
3
3
  export { AISchemaError, prepare } from './schema.js';
4
4
  export { ToolError } from './tools.js';
5
5
  export type { Infer, StandardSchema } from './schema.js';
6
6
  export { partial } from './partial.js';
7
- export type { AISettings, Agent, Agents, Chat, ChatEvents, ChatGoal, ChatMessage, ChatStreamPart, ChatToolCall, ChatVoice, Chats, CommitTrailer, CreateChat, Decision, Endpoint, EndpointInput, Endpoints, ForkChat, GoalChange, Goals, MemberInput, MessageAttachment, MessageFile, MessageImage, Repo, Repos, SendMessage, SetGoal, Settings, StartVoice, TurnArtifact, TurnCost, TurnRunCost, TurnToolCall, VoiceCommand, Voices, Workspaces, } from './chats.js';
8
- export type { AgentContext, AgentDefinitionInput, BackendAgent, BackendRepo, BackendTool, BackendToolOptions, ChatContext, ClientTool, ClientToolOptions, DeferredAnswer, Effort, HttpsToolRef, McpToolRef, PlatformToolName, PlatformToolRef, RepoTokenContext, RepoTokens, SubagentDefinition, Thinking, Tool, ToolAnswer, ToolContext, TurnDefinition, TurnMessage, } from './tools.js';
7
+ export type { AISettings, Agent, AgentTool, AgentVersion, Agents, Chat, ChatEvents, ChatGoal, ChatMessage, ChatStreamPart, ChatToolCall, ChatVoice, Chats, CommitTrailer, CreateChat, Decision, Endpoint, EndpointInput, Endpoints, ForkChat, GoalChange, Goals, MemberInput, MessageAttachment, MessageFile, MessageImage, Repo, Repos, SendMessage, SetGoal, Settings, StartVoice, TurnArtifact, TurnCost, TurnRunCost, TurnToolCall, VoiceCommand, Voices, Workspaces, } from './chats.js';
8
+ export type { AgentContext, AgentDefinitionInput, BackendAgent, BackendAgentOptions, BackendRepo, BackendTool, BackendToolOptions, ChatContext, ClientTool, ClientToolOptions, DeferredAnswer, Effort, HttpsToolRef, McpToolRef, PlatformToolName, PlatformToolRef, PreparedOutput, RepoTokenContext, RepoTokens, SubagentDefinition, Thinking, Tool, ToolAnswer, ToolContext, TurnDefinition, TurnMessage, } from './tools.js';
9
9
  export type { AgentEvent, ChatEvent, GoalEvent, GoalKind, HistoryEvent, HistoryItem, MessageEvent, Publication, ResetEvent, TextEvent, ThinkingEvent, ToolEvent, ToolStatus, TranscriptEvent, TurnEnd, TurnEvent, TurnStatus, VoiceEvent, WaitingReason, } from '../../internal/src/chat.js';
10
10
  export type { ToolPart, ToolResult } from '../../internal/src/tool-output.js';
@@ -3,7 +3,7 @@ type AgentDefinition = wire.AgentDefinition;
3
3
  type ToolContent = wire.ToolContent;
4
4
  type ToolRef = wire.ToolRef;
5
5
  import { type ToolResult } from '../../internal/src/tool-output.js';
6
- import type { Infer, StandardSchema } from './schema.js';
6
+ import { type Infer, type PreparedSchema, type StandardSchema } from './schema.js';
7
7
  /** A role, or a catalogue model as provider:model. */
8
8
  type Model = 'fast' | 'default' | 'strong' | (string & {});
9
9
  /** The chat a tool call or a turn is of, as the platform names it in its signed call. */
@@ -198,8 +198,18 @@ export interface SubagentDefinition {
198
198
  /** Left out: the agent's. Its reasoning is never in the chat's stream: only the turn's own is. */
199
199
  thinking?: Thinking;
200
200
  }
201
- /** What an agent is for a turn. */
201
+ /** A schema already checked against what the provider holds a model to: ai.schema(name, zod). */
202
+ export interface PreparedOutput {
203
+ readonly name: string;
204
+ readonly prepared: PreparedSchema<unknown>;
205
+ }
206
+ /** What an agent is: for a chat's turn, and for its one-shot answers (ai.generate({ agent })). */
202
207
  export interface AgentDefinitionInput {
208
+ /**
209
+ * What it is for, in a sentence or two (1024 characters at most): the people who pick an agent read it, and so
210
+ * does the agent a subagent works for.
211
+ */
212
+ description?: string;
203
213
  instructions?: string;
204
214
  model?: Model;
205
215
  /** 64 at most, with its MCP servers'. */
@@ -222,13 +232,24 @@ export interface AgentDefinitionInput {
222
232
  thinking?: Thinking;
223
233
  /** The language of the person the turn works for, a BCP 47 tag (tr, en-GB): the model writes to them in it on every step, and so do its subagents. */
224
234
  language?: string;
235
+ /**
236
+ * The shape of its one-shot answers (ai.generate({ agent, prompt })): a zod (valibot, arktype) object schema, or
237
+ * ai.schema(name, schema) — checked as generate's schema is, here, when the definition is written. A chat's turns
238
+ * answer in text.
239
+ */
240
+ output?: StandardSchema | PreparedOutput;
225
241
  }
226
242
  /** What a backend's agent is for one turn. */
227
243
  export type TurnDefinition = AgentDefinitionInput;
228
- /** An agent the backend defines at each turn's start: put with ai.agents.put(agent), its chats' turns ask its machine. */
244
+ /**
245
+ * An agent the backend defines at each turn's start: its build's contract names it (x-palbase-agents), and a chat
246
+ * started by its name asks its machine for it at each turn. It lives in the code alone — nothing puts it anywhere.
247
+ */
229
248
  export interface BackendAgent {
230
249
  readonly kind: 'agent';
231
250
  readonly name: string;
251
+ /** What it is for, as the people who pick an agent read it (its contract says it). */
252
+ readonly description?: string;
232
253
  /** The project's machine that defines it (default backend). */
233
254
  readonly machine?: string;
234
255
  /** The definition for a turn, said as the platform takes it, with the backend tools it hands out. */
@@ -267,14 +288,16 @@ export interface BackendRepo {
267
288
  /** A token for one clone or one push of it: asked at each — a GitHub App's installation token, minted then. */
268
289
  token(ctx: RepoTokenContext): Promise<string>;
269
290
  }
270
- /** What this process declared, for the framework to serve. */
291
+ /** What this process declared, for the framework to serve and to write into its build's contract. */
271
292
  export interface DeclaredAI {
272
293
  tools: Map<string, BackendTool>;
294
+ /** The app's client tools: in its contract, answered by the app — never served here. */
295
+ clientTools: Map<string, ClientTool>;
273
296
  agents: Map<string, BackendAgent>;
274
297
  repos: Map<string, BackendRepo>;
275
298
  /** The tokens of a repository put by name at run time, which no ai.repo of this process names. */
276
299
  repoTokens?: RepoTokens;
277
- /** Names declared twice (tool:<name>, agent:<name>, repoTokens): the framework refuses to start with one. */
300
+ /** Names declared twice (tool:<name> — a backend tool's or a client tool's —, agent:<name>, repoTokens): the framework refuses to start with one, and to write its contract. */
278
301
  twice: Set<string>;
279
302
  }
280
303
  /**
@@ -315,9 +338,14 @@ export declare function backendRepo(options: {
315
338
  * repository first. Given once, at a module's top level.
316
339
  */
317
340
  export declare function repoTokens(give: RepoTokens): void;
318
- export declare function backendAgent(name: string, define: (ctx: AgentContext) => TurnDefinition | Promise<TurnDefinition>, options?: {
341
+ /** What an agent of the code says of itself beside its function: what it is for, and the machine that defines it. */
342
+ export interface BackendAgentOptions {
343
+ /** What it is for, in a sentence or two (1024 characters at most): its build's contract says it, and Studio shows it. */
344
+ description?: string;
345
+ /** The project's machine that defines it (default backend). */
319
346
  machine?: string;
320
- }): BackendAgent;
347
+ }
348
+ export declare function backendAgent(name: string, define: (ctx: AgentContext) => TurnDefinition | Promise<TurnDefinition>, options?: BackendAgentOptions): BackendAgent;
321
349
  /** A backend's agent (an ai.agent's value) — its name and machine — or undefined for anything else. */
322
350
  export declare function backendAgentOf(v: unknown): {
323
351
  readonly name: string;
@@ -327,6 +355,8 @@ export declare function backendAgentOf(v: unknown): {
327
355
  export declare function toolRef(t: Tool, what: string): ToolRef;
328
356
  /** The most tool calls a turn or a one-shot answer makes: the engine's own bound. */
329
357
  export declare const MAX_TOOL_CALLS = 10000;
358
+ /** The shape of an agent's one-shot answers as the module takes it: the JSON Schema generate's schema is sent as. */
359
+ export declare function outputOf(v: StandardSchema | PreparedOutput, what: string): Record<string, unknown>;
330
360
  /** A definition's bound on its tool calls, refused here as the module would refuse it. */
331
361
  export declare function maxToolCallsOf(n: unknown, what: string): number;
332
362
  /** A definition as the platform takes it (AgentDefinition). */
@@ -34,6 +34,28 @@ export interface ContractOptions {
34
34
  errors?: ReadonlyMap<string, RegisteredError>;
35
35
  /** The app's @Gateway classes, as their decorators declare them. */
36
36
  gateways?: readonly GatewayDeclaration[];
37
+ /** The app's ai agents and tools (@palbase/ai's, declared in this process when it was made). */
38
+ ai?: {
39
+ agents: readonly AgentFacts[];
40
+ tools: readonly AiToolFacts[];
41
+ };
42
+ }
43
+ /** An ai.agent as its contract says it. */
44
+ export interface AgentFacts {
45
+ name: string;
46
+ description?: string;
47
+ /** The machine it names (ai.agent(…, { machine })): it is that machine's build's alone. */
48
+ machine?: string;
49
+ }
50
+ /** An ai.tool (backend: run on the machine) or an ai.clientTool (client: the app answers it), as its contract says it. */
51
+ export interface AiToolFacts {
52
+ name: string;
53
+ kind: 'backend' | 'client';
54
+ description: string;
55
+ parameters: Record<string, unknown>;
56
+ approval: boolean;
57
+ /** A backend tool's machine, when it names one (ai.tool({ machine })): the one that serves it. */
58
+ machine?: string;
37
59
  }
38
60
  /** What a route answers and throws, as its source declares. */
39
61
  export interface RouteContract {