palbase 0.18.2 → 0.18.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) 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 +6 -6
  5. package/dist/backend/stack.js +1 -1
  6. package/dist/backend/test.js +2 -2
  7. package/dist/chunks/{BZD6DTRS.js → 5BTTH7AT.js} +1 -1
  8. package/dist/chunks/{PQU3TAPP.js → 6CJHLHPT.js} +2 -2
  9. package/dist/chunks/{XQANDC54.js → 6RKQ5ANL.js} +2 -2
  10. package/dist/chunks/{QEBQ452U.js → 7CTORXHD.js} +1 -1
  11. package/dist/chunks/{RFF725G4.js → CHDD73OG.js} +2 -2
  12. package/dist/chunks/{JWBOJ4DZ.js → GF42QGWO.js} +2 -2
  13. package/dist/chunks/{J3GVOUKS.js → GLPFMTZP.js} +2 -2
  14. package/dist/chunks/{6O7HI5DJ.js → HHYRMVWF.js} +2 -2
  15. package/dist/chunks/HKOGKWNU.js +22 -0
  16. package/dist/chunks/{X6FNTEXY.js → KMA7REYL.js} +1 -1
  17. package/dist/chunks/{NWFZYTV4.js → KPTP2RTE.js} +1 -1
  18. package/dist/chunks/{34GIR5XI.js → MAYJWEPM.js} +1 -1
  19. package/dist/chunks/{FWE2RQ74.js → N5WYA3DM.js} +2 -2
  20. package/dist/chunks/{FYEDISVZ.js → NEBALOPJ.js} +1 -1
  21. package/dist/chunks/{J3SSWIXW.js → PIWNLITG.js} +2 -2
  22. package/dist/chunks/{KPB7BB3F.js → Q33BWD44.js} +2 -2
  23. package/dist/chunks/{2MCXKESR.js → RKPLX5YV.js} +1 -1
  24. package/dist/chunks/{TNSIU2CJ.js → SSL3F7OB.js} +2 -2
  25. package/dist/chunks/UPS6BGJD.js +21 -0
  26. package/dist/chunks/{DTILUE3A.js → V4TFN353.js} +2 -2
  27. package/dist/chunks/{TAFRNPVE.js → VUXQEYPQ.js} +2 -2
  28. package/dist/chunks/{PPIZUQG5.js → W65B2VZ3.js} +2 -2
  29. package/dist/chunks/{JK6Y5742.js → XE6LFBDN.js} +2 -2
  30. package/dist/cli.js +141 -141
  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/bootstrap.d.ts +3 -3
  45. package/types/backend/src/decorators.d.ts +7 -2
  46. package/types/backend/src/engine.d.ts +3 -3
  47. package/types/backend/src/index.d.ts +1 -1
  48. package/types/backend/src/openapi.d.ts +1 -1
  49. package/types/internal/src/messaging/engine.d.ts +8 -0
  50. package/types/internal/src/messaging/store.d.ts +13 -0
  51. package/types/internal/src/modules/ai.d.ts +5 -9
  52. package/types/internal/src/modules/messaging.d.ts +30 -5
  53. package/types/internal/src/modules/stores.d.ts +53 -0
  54. package/dist/chunks/N7TLZR3V.js +0 -22
  55. package/dist/chunks/ZFJ7245R.js +0 -21
package/dist/refuse/ai.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! palbase 0.18.2 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.18.4 — 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.18.2 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.18.4 — 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.18.2 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.18.4 — 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.18.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/PQU3TAPP.js";import{a as c,b as d}from"../chunks/NWFZYTV4.js";import"../chunks/QEBQ452U.js";import"../chunks/BZD6DTRS.js";import{n as b}from"../chunks/6O7HI5DJ.js";import"../chunks/FWE2RQ74.js";import{b as a}from"../chunks/PPIZUQG5.js";import"../chunks/34GIR5XI.js";import"../chunks/X6FNTEXY.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.18.4 — 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/6CJHLHPT.js";import{a as c,b as d}from"../chunks/KPTP2RTE.js";import"../chunks/7CTORXHD.js";import"../chunks/5BTTH7AT.js";import{n as b}from"../chunks/HHYRMVWF.js";import"../chunks/N5WYA3DM.js";import{b as a}from"../chunks/W65B2VZ3.js";import"../chunks/MAYJWEPM.js";import"../chunks/KMA7REYL.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.18.2 — Palbase SDK License (see LICENSE) */
2
- import{a,b,c,d,e}from"../chunks/JK6Y5742.js";import"../chunks/NWFZYTV4.js";import"../chunks/34GIR5XI.js";import"../chunks/X6FNTEXY.js";export{b as TestApiError,e as api,c as createTestApi,a as testFields,d as testRun};
1
+ /*! palbase 0.18.4 — Palbase SDK License (see LICENSE) */
2
+ import{a,b,c,d,e}from"../chunks/XE6LFBDN.js";import"../chunks/KPTP2RTE.js";import"../chunks/MAYJWEPM.js";import"../chunks/KMA7REYL.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.18.2 — Palbase SDK License (see LICENSE) */
2
- import{a as L,b as j,c as q,d as G,e as D,f as N,g as U,h as F,i as B,j as H,k as J,l as K,m as W,n as X,o as Y,p as Z,q as ee,r as te,s as ne,t as re,u as oe,v as se,w as ae}from"../chunks/N7TLZR3V.js";import{a as _,b as Q,f as z}from"../chunks/J3SSWIXW.js";import"../chunks/TAFRNPVE.js";import"../chunks/TNSIU2CJ.js";import"../chunks/FYEDISVZ.js";import{b as E,c as T,d as O,f as x,g as A,j as R,k as V,l as $,m as S,o as v}from"../chunks/QEBQ452U.js";import"../chunks/JWBOJ4DZ.js";import"../chunks/6O7HI5DJ.js";import"../chunks/FWE2RQ74.js";import{b as I}from"../chunks/PPIZUQG5.js";import"../chunks/34GIR5XI.js";import"../chunks/X6FNTEXY.js";var ie="oai-events";async function ce(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??ye(),t=e.signal;t?.throwIfAborted();let f=e.audio??fe(),u=e.microphone===void 0,c=e.microphone??await r.getUserMedia({audio:!0});if(t?.aborted){if(u)for(let n of c.getTracks())n.stop();throw t.reason}let o=new r.RTCPeerConnection,s=!1,l=()=>{if(!s){if(s=!0,m.close(),o.close(),u)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(ie);m.addEventListener("message",n=>{let p=pe(n.data);p!==void 0&&e.onError?.(p)});let d=()=>l();t?.addEventListener("abort",d,{once:!0});try{await o.setLocalDescription(await o.createOffer()),t?.throwIfAborted(),await de(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:l}}catch(n){throw t?.removeEventListener("abort",d),l(),t?.aborted?t.reason:n}}function de(e,r,t){return e.iceGatheringState==="complete"?Promise.resolve():t?.aborted?Promise.reject(t.reason):new Promise((f,u)=>{let c=()=>{clearTimeout(l),e.removeEventListener("icegatheringstatechange",o),t?.removeEventListener("abort",s)},o=()=>{e.iceGatheringState==="complete"&&(c(),f())},s=()=>{c(),u(t?.reason)},l=setTimeout(()=>{c(),u(new Error(`connectVoice: the network candidates were not gathered in ${r} ms`))},r);e.addEventListener("icegatheringstatechange",o),t?.addEventListener("abort",s,{once:!0})})}function pe(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 ye(){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 fe(){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 le(e,r,t){let f=i(i(i(e)?.components)?.schemas)??{},u=(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 M of k)h(M,g,y)}let P=i(a.properties);if(P)for(let[b,k]of Object.entries(P))h(k,`${g}/${S(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(...u(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=u(n.schema,`/query/${S(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)??{},l=Object.keys(s).filter(d=>/^2\d\d$/.test(d)).sort((d,n)=>d==="200"?-1:n==="200"?1:d.localeCompare(n)),m=l.length>0?u(c(i(s[l[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 ue(e){let r=`${e.method.toUpperCase()} ${e.path}`,t=i(i(i(i(e.contract)?.paths)?.[e.path])?.[e.method.toLowerCase()]),f=t?le(e.contract,t,r):void 0;if(!f)return{body:e.body,query:e.query,open:async s=>s};let{key:u,header:c}=await A(e.key.kid,O(e.key.publicKey),x(e.projectId,e.method,e.path,e.params??[])),o=(s,l)=>s==null?s:v(s,l,f.request,(m,d)=>R(u,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):v(s,"/response",f.response,async(l,m)=>{if(!V(m))throw new T("unopenable",`${r}: ${l} came plain where the contract says it is encrypted`);return $(u,l,m)})}}export{U as Analytics,_ as BackendError,G as Channel,F as Consent,ne as ConversationList,re as ConversationView,Z as Flags,z as GatewayError,J as InApp,B as Inbox,N as Installation,te as Messaging,W as Notify,I as PalbaseError,X as Purchases,D as RealtimeSocket,H as SESSION_START,se as ScheduledList,L as SessionChangedError,oe as ThreadView,K as WebPush,ce as connectVoice,ae as createClient,ue as encryptedCall,ee as indexedDBKeyValue,Q as isBackendError,q as localStore,j as memoryStore,Y as redemptionToken};
1
+ /*! palbase 0.18.4 — Palbase SDK License (see LICENSE) */
2
+ import{a as L,b as j,c as q,d as G,e as D,f as N,g as U,h as F,i as B,j as H,k as J,l as K,m as W,n as X,o as Y,p as Z,q as ee,r as te,s as ne,t as re,u as oe,v as se,w as ae}from"../chunks/HKOGKWNU.js";import{a as _,b as Q,f as z}from"../chunks/PIWNLITG.js";import"../chunks/VUXQEYPQ.js";import"../chunks/SSL3F7OB.js";import"../chunks/NEBALOPJ.js";import{b as E,c as T,d as O,f as x,g as A,j as R,k as V,l as $,m as S,o as v}from"../chunks/7CTORXHD.js";import"../chunks/GF42QGWO.js";import"../chunks/HHYRMVWF.js";import"../chunks/N5WYA3DM.js";import{b as I}from"../chunks/W65B2VZ3.js";import"../chunks/MAYJWEPM.js";import"../chunks/KMA7REYL.js";var ie="oai-events";async function ce(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??ye(),t=e.signal;t?.throwIfAborted();let f=e.audio??fe(),u=e.microphone===void 0,c=e.microphone??await r.getUserMedia({audio:!0});if(t?.aborted){if(u)for(let n of c.getTracks())n.stop();throw t.reason}let o=new r.RTCPeerConnection,s=!1,l=()=>{if(!s){if(s=!0,m.close(),o.close(),u)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(ie);m.addEventListener("message",n=>{let p=pe(n.data);p!==void 0&&e.onError?.(p)});let d=()=>l();t?.addEventListener("abort",d,{once:!0});try{await o.setLocalDescription(await o.createOffer()),t?.throwIfAborted(),await de(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:l}}catch(n){throw t?.removeEventListener("abort",d),l(),t?.aborted?t.reason:n}}function de(e,r,t){return e.iceGatheringState==="complete"?Promise.resolve():t?.aborted?Promise.reject(t.reason):new Promise((f,u)=>{let c=()=>{clearTimeout(l),e.removeEventListener("icegatheringstatechange",o),t?.removeEventListener("abort",s)},o=()=>{e.iceGatheringState==="complete"&&(c(),f())},s=()=>{c(),u(t?.reason)},l=setTimeout(()=>{c(),u(new Error(`connectVoice: the network candidates were not gathered in ${r} ms`))},r);e.addEventListener("icegatheringstatechange",o),t?.addEventListener("abort",s,{once:!0})})}function pe(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 ye(){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 fe(){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 le(e,r,t){let f=i(i(i(e)?.components)?.schemas)??{},u=(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 M of k)h(M,g,y)}let P=i(a.properties);if(P)for(let[b,k]of Object.entries(P))h(k,`${g}/${S(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(...u(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=u(n.schema,`/query/${S(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)??{},l=Object.keys(s).filter(d=>/^2\d\d$/.test(d)).sort((d,n)=>d==="200"?-1:n==="200"?1:d.localeCompare(n)),m=l.length>0?u(c(i(s[l[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 ue(e){let r=`${e.method.toUpperCase()} ${e.path}`,t=i(i(i(i(e.contract)?.paths)?.[e.path])?.[e.method.toLowerCase()]),f=t?le(e.contract,t,r):void 0;if(!f)return{body:e.body,query:e.query,open:async s=>s};let{key:u,header:c}=await A(e.key.kid,O(e.key.publicKey),x(e.projectId,e.method,e.path,e.params??[])),o=(s,l)=>s==null?s:v(s,l,f.request,(m,d)=>R(u,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):v(s,"/response",f.response,async(l,m)=>{if(!V(m))throw new T("unopenable",`${r}: ${l} came plain where the contract says it is encrypted`);return $(u,l,m)})}}export{U as Analytics,_ as BackendError,G as Channel,F as Consent,ne as ConversationList,re as ConversationView,Z as Flags,z as GatewayError,J as InApp,B as Inbox,N as Installation,te as Messaging,W as Notify,I as PalbaseError,X as Purchases,D as RealtimeSocket,H as SESSION_START,se as ScheduledList,L as SessionChangedError,oe as ThreadView,K as WebPush,ce as connectVoice,ae as createClient,ue as encryptedCall,ee as indexedDBKeyValue,Q as isBackendError,q as localStore,j as memoryStore,Y as redemptionToken};
@@ -1,2 +1,2 @@
1
- /*! palbase 0.18.2 — Palbase SDK License (see LICENSE) */
2
- import{a as i}from"../chunks/TNSIU2CJ.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/FYEDISVZ.js";import"../chunks/X6FNTEXY.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.18.4 — Palbase SDK License (see LICENSE) */
2
+ import{a as i}from"../chunks/SSL3F7OB.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/NEBALOPJ.js";import"../chunks/KMA7REYL.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.18.2 — Palbase SDK License (see LICENSE) */
2
- import{c as e,d as r,i as t}from"../chunks/J3SSWIXW.js";import"../chunks/QEBQ452U.js";import"../chunks/JWBOJ4DZ.js";import"../chunks/FWE2RQ74.js";import"../chunks/PPIZUQG5.js";import"../chunks/34GIR5XI.js";import"../chunks/X6FNTEXY.js";export{e as RESERVED_CLIENT_NAMES,t as __registerBackend,r as isClientName};
1
+ /*! palbase 0.18.4 — Palbase SDK License (see LICENSE) */
2
+ import{c as e,d as r,i as t}from"../chunks/PIWNLITG.js";import"../chunks/7CTORXHD.js";import"../chunks/GF42QGWO.js";import"../chunks/N5WYA3DM.js";import"../chunks/W65B2VZ3.js";import"../chunks/MAYJWEPM.js";import"../chunks/KMA7REYL.js";export{e as RESERVED_CLIENT_NAMES,t as __registerBackend,r as isClientName};
@@ -1,2 +1,2 @@
1
- /*! palbase 0.18.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/TAFRNPVE.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/FYEDISVZ.js";import"../chunks/PPIZUQG5.js";import"../chunks/34GIR5XI.js";import"../chunks/X6FNTEXY.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.18.4 — 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/VUXQEYPQ.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/NEBALOPJ.js";import"../chunks/W65B2VZ3.js";import"../chunks/MAYJWEPM.js";import"../chunks/KMA7REYL.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.18.2 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.18.4 — Palbase SDK License (see LICENSE) */
2
2
  "use strict";(()=>{function g(n,s){if(n)try{let i=new URL(n,s);if(i.protocol==="https:"||i.protocol==="http:"&&(i.hostname==="localhost"||i.hostname==="127.0.0.1"))return i.href}catch{}}function p(n){let s=new URL(n.location.href).searchParams,i=s.get("url")??"",u=s.get("key")??"",a=(t,e)=>!t||!i?Promise.resolve():n.fetch(`${i.replace(/\/$/,"")}/notify/receipts`,{method:"POST",headers:{"content-type":"application/json",apikey:u},body:JSON.stringify({receipts:[{receipt:t,status:e}]}),keepalive:!0}).catch(()=>{}),l=async(t,e)=>{for(let o of await n.clients.matchAll({type:"window",includeUncontrolled:!0}))o.postMessage({type:"palbase.push",event:t,url:e.url,data:e.data})};n.addEventListener("push",(t=>{let e={};try{e=t.data?.json()??{}}catch{}let o={url:e.url,receipt:e.receipt,data:e.data},d=async()=>e.data?.type==="messaging.message"&&(await n.clients.matchAll({type:"window",includeUncontrolled:!0})).some(r=>r.focused===!0);t.waitUntil(d().then(r=>r?void 0:n.registration.showNotification(e.title??"",{body:e.body,image:e.image,tag:e.tag,data:o})).then(()=>Promise.all([a(e.receipt,"delivered"),l("received",o)])))})),n.addEventListener("notificationclick",(t=>{t.notification.close();let e=t.notification.data??{},o=g(e.url,n.location.origin),d=async()=>{if(!o)return;let c=(await n.clients.matchAll({type:"window",includeUncontrolled:!0})).find(f=>f.url===o);c?await c.focus():await n.clients.openWindow(o)};t.waitUntil(Promise.all([a(e.receipt,"opened"),d(),l("opened",e)]))})),n.addEventListener("notificationclose",(t=>{t.waitUntil(a(t.notification.data?.receipt,"dismissed"))}))}typeof self<"u"&&typeof self.registration=="object"&&!("document"in self)&&p(self);})();
package/dist/web/ssr.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! palbase 0.18.2 — Palbase SDK License (see LICENSE) */
2
- import{w as f}from"../chunks/N7TLZR3V.js";import"../chunks/J3SSWIXW.js";import"../chunks/TAFRNPVE.js";import"../chunks/TNSIU2CJ.js";import"../chunks/FYEDISVZ.js";import"../chunks/QEBQ452U.js";import"../chunks/JWBOJ4DZ.js";import"../chunks/6O7HI5DJ.js";import"../chunks/FWE2RQ74.js";import"../chunks/PPIZUQG5.js";import"../chunks/34GIR5XI.js";import"../chunks/X6FNTEXY.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.18.4 — Palbase SDK License (see LICENSE) */
2
+ import{w as f}from"../chunks/HKOGKWNU.js";import"../chunks/PIWNLITG.js";import"../chunks/VUXQEYPQ.js";import"../chunks/SSL3F7OB.js";import"../chunks/NEBALOPJ.js";import"../chunks/7CTORXHD.js";import"../chunks/GF42QGWO.js";import"../chunks/HHYRMVWF.js";import"../chunks/N5WYA3DM.js";import"../chunks/W65B2VZ3.js";import"../chunks/MAYJWEPM.js";import"../chunks/KMA7REYL.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.18.2 — Palbase SDK License (see LICENSE) */
2
- import"../chunks/X6FNTEXY.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.18.4 — Palbase SDK License (see LICENSE) */
2
+ import"../chunks/KMA7REYL.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.18.2",
3
+ "version": "0.18.4",
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.18.2",
138
+ "palgres": "0.18.4",
139
139
  "reflect-metadata": "^0.2.2",
140
140
  "typescript": "~6.0.3",
141
141
  "zod": "^4.6.5"
@@ -1,5 +1,5 @@
1
1
  import { type PalbaseServer } from '../../server/src/index.js';
2
- import { type AuthSpec, type RateLimitConfig } from './decorators.js';
2
+ import { type AuthSpec, type RateLimit } from './decorators.js';
3
3
  import { type AppTokens, type CorsOptions } from './engine.js';
4
4
  import { type DatabaseConfig } from './database.js';
5
5
  import { type PalbaseConnection } from './env.js';
@@ -16,8 +16,8 @@ export interface AppConfig {
16
16
  * request's), or null to refuse it.
17
17
  */
18
18
  tokens?: AppTokens;
19
- /** Every route's limit unless it says otherwise (default 300 a minute per caller); false for none. */
20
- rateLimit?: RateLimitConfig | false;
19
+ /** Every route's limit unless it says otherwise (default 300 a minute per caller) — one window or several; false for none. */
20
+ rateLimit?: RateLimit | false;
21
21
  /** Bytes a request body may be (default 1 MiB). */
22
22
  bodyLimit?: number;
23
23
  /** Off unless given: a backend browsers call names their origins. */
@@ -50,6 +50,11 @@ export interface RateLimitConfig {
50
50
  /** Seconds. */
51
51
  window: number;
52
52
  }
53
+ /**
54
+ * One window, or several each call spends — a burst's and an hour's: `[{ max: 10, window: 10 }, { max: 300, window: 3600 }]`.
55
+ * A call over any of them is refused, told to wait the longest of their waits.
56
+ */
57
+ export type RateLimit = RateLimitConfig | readonly RateLimitConfig[];
53
58
  export interface ControllerOptions {
54
59
  auth?: AuthSpec;
55
60
  /** Every route of the controller asks for device attestation (RouteOptions.attest), unless a route says false. */
@@ -57,8 +62,8 @@ export interface ControllerOptions {
57
62
  }
58
63
  export interface RouteOptions {
59
64
  auth?: AuthSpec;
60
- /** A limit for this route; false for none. */
61
- rateLimit?: RateLimitConfig | false;
65
+ /** A limit for this route — one window or several (RateLimit); false for none. */
66
+ rateLimit?: RateLimit | false;
62
67
  /**
63
68
  * Only the app's own build on a genuine device calls this route: App Attest
64
69
  * on iOS, a Keystore key attested by Google on Android — Palbase's iOS and
@@ -1,5 +1,5 @@
1
1
  import { type PalbaseServer, type TokenUser, type TokenVerifier, type WebhookEvent } from '../../server/src/index.js';
2
- import { type AuthSpec, type RateLimitConfig } from './decorators.js';
2
+ import { type AuthSpec, type RateLimit } from './decorators.js';
3
3
  import { type KeptAnswers } from './idempotency.js';
4
4
  import { type ContractOptions } from './openapi.js';
5
5
  import { type StringsTable } from './i18n.js';
@@ -66,8 +66,8 @@ export interface AppOptions {
66
66
  auth?: AuthSpec;
67
67
  /** The app's own API tokens (a CI's, an agent's): AppTokens. */
68
68
  tokens?: AppTokens;
69
- /** Every route's limit unless it says otherwise (default 300 a minute per caller); false for none. */
70
- rateLimit?: RateLimitConfig | false;
69
+ /** Every route's limit unless it says otherwise (default 300 a minute per caller) — one window or several; false for none. */
70
+ rateLimit?: RateLimit | false;
71
71
  /** Off unless given: a backend called from browsers names their origins. */
72
72
  cors?: CorsOptions;
73
73
  /** The framework's own handlers of the platform's events (user.deleted → forget), run before the app's @On. */
@@ -1,5 +1,5 @@
1
1
  import 'reflect-metadata';
2
- export { AttestedDevice, Body, Client, Controller, Delete, Get, getRegisteredControllers, getRoutes, Headers, Cron, Injectable, Module, On, OptionalUser, Param, Patch, Post, Put, Query, QueryParams, Req, RequestId, Resolve, TraceId, User, Webhook, type AuthConfig, type AuthSpec, type ControllerOptions, type EventHandler, type CronMeta, type CronOptions, type ModuleDef, type OnOptions, type ParamResolver, type RateLimitConfig, type ResolveContext, type RouteInfo, type RouteOptions, type SignatureSpec, type StandardSchemaV1, type Token, type WebhookOptions, type WebhookProvider, } from './decorators.js';
2
+ export { AttestedDevice, Body, Client, Controller, Delete, Get, getRegisteredControllers, getRoutes, Headers, Cron, Injectable, Module, On, OptionalUser, Param, Patch, Post, Put, Query, QueryParams, Req, RequestId, Resolve, TraceId, User, Webhook, type AuthConfig, type AuthSpec, type ControllerOptions, type EventHandler, type CronMeta, type CronOptions, type ModuleDef, type OnOptions, type ParamResolver, type RateLimit, type RateLimitConfig, type ResolveContext, type RouteInfo, type RouteOptions, type SignatureSpec, type StandardSchemaV1, type Token, type WebhookOptions, type WebhookProvider, } from './decorators.js';
3
3
  export { Task, TaskFailure, Tasks, type EnqueueOptions, type PayloadOf, type QueuedTask, type TaskClass, type TaskMeta, type TaskOptions, type TasksService } from './tasks.js';
4
4
  export { TestUserTemplate, type TemplateMeta, type TemplateUser, type TestUserTemplateClass, type TestUserTemplateOptions } from './test-user-templates.js';
5
5
  export { Upload, UploadedObject, type UploadConfig } from './upload.js';
@@ -12,7 +12,7 @@ export interface RouteFacts {
12
12
  aal: 'aal1' | 'aal2' | 'aal3';
13
13
  };
14
14
  /** The limit the route spends, or false when it has none. */
15
- limit: RateLimitConfig | false;
15
+ limit: readonly RateLimitConfig[] | false;
16
16
  /** The route asks for the device's attestation (when the environment's switch is on). */
17
17
  attest: boolean;
18
18
  }
@@ -19,6 +19,14 @@ export declare class Engine {
19
19
  private settled;
20
20
  /** A message to send, on its way: drawn at once, sent by the next flush. */
21
21
  write(conversationId: string, request: api.SendRequest, now: string): OutboxItem;
22
+ /**
23
+ * The person read a conversation (a thread of it) up to seq — its last message (answer) the store has, unless given:
24
+ * read on the device at once. Answers how far, what the server is told, and what of the store it touched.
25
+ */
26
+ read(conversationId: string, seq?: number, threadId?: string): {
27
+ upTo: number;
28
+ touched: Touched;
29
+ };
22
30
  /** What the server made of a send, applied. */
23
31
  sent(outcome: SendOutcome): Touched | null;
24
32
  /** A conversation's timeline: its messages, the oldest first, then what is on its way to it. */
@@ -34,6 +34,8 @@ export interface Touched {
34
34
  scheduled: boolean;
35
35
  }
36
36
  export declare class Store {
37
+ /** Whose conversations they are: their own messages are never unread to them. */
38
+ readonly reader: string;
37
39
  cursor: string | null;
38
40
  readonly conversations: Map<string, api.Conversation>;
39
41
  /** By conversation, then person. */
@@ -43,6 +45,7 @@ export declare class Store {
43
45
  /** By the thread's root. */
44
46
  readonly threads: Map<string, api.ThreadState>;
45
47
  readonly scheduled: Map<string, api.ScheduledMessage>;
48
+ constructor(reader: string);
46
49
  /** Applies what changed; answers what of the store it touched. */
47
50
  apply(ch: Changes): Touched;
48
51
  /** A sync that starts again (reset): what the store kept goes, then the page is applied. */
@@ -53,6 +56,16 @@ export declare class Store {
53
56
  private putMessage;
54
57
  private putThread;
55
58
  private putScheduled;
59
+ /**
60
+ * The reader read a conversation (a thread of it: threadId) up to upTo on this device: their unread count goes
61
+ * down at once, before the server says — a read moves forward only, and no further than the conversation's last
62
+ * message.
63
+ */
64
+ read(conversationId: string, upTo: number, threadId?: string): Touched;
65
+ /** The reader's place me, read up to `to`: up to the conversation's last message, nothing is unread; else what the store has of the messages up to there is read. */
66
+ private readTo;
67
+ /** The reader's place in a thread, read up to `to`: what the store has of its answers up to there is read. */
68
+ private threadReadTo;
56
69
  /** A message removed where the reader is (its timer ran out, it vanished): gone from the store at once, before the server says. */
57
70
  expire(conversationId: string, messageId: string): boolean;
58
71
  /** The conversations, the latest first. */
@@ -1806,17 +1806,13 @@ export type SettingsRequest = {
1806
1806
  user_messages_per_minute?: number;
1807
1807
  };
1808
1808
  /**
1809
- * What the project's use of Palbase's models (the platform's provider keys) has cost this month, and what it may still spend. A month brings a dollar of it free: a Free project's own, a paying account's once for all its projects. Past it a Free project uses its own provider keys; a Pay as you go one pays from its balance, at the provider's price and 10%.
1809
+ * What the project's use of Palbase's models (the platform's provider keys) has cost this month, and what it may still spend. A month brings every project a dollar of it free. Past it a Free project uses its own provider keys; a Pay as you go one pays from its balance, at the provider's price and 10%.
1810
1810
  */
1811
1811
  export type Spend = {
1812
1812
  /**
1813
- * What is left of a Free project's free dollar this month; null on a paying one (its account's free dollar is its bill's).
1813
+ * What is left of a Free project's free dollar this month; null on a paying one (its free dollar is its bill's).
1814
1814
  */
1815
1815
  free_left_usd: number | null;
1816
- /**
1817
- * Whose the free dollar is: the project's own (project) or its account's, all its projects together (account).
1818
- */
1819
- free_scope: "project" | "account";
1820
1816
  /**
1821
1817
  * The month's free use of Palbase's models, in US dollars.
1822
1818
  */
@@ -1830,7 +1826,7 @@ export type Spend = {
1830
1826
  */
1831
1827
  monthly_budget_usd: number | null;
1832
1828
  /**
1833
- * free (no paid rights: its free dollar, then its own keys), pay_as_you_go (its account's balance pays past the free dollar) or exempt (measured, not charged).
1829
+ * free (no paid rights: its free dollar, then its own keys), pay_as_you_go (its balance pays past the free dollar) or exempt (measured, not charged).
1834
1830
  */
1835
1831
  plan: "free" | "pay_as_you_go" | "exempt";
1836
1832
  /**
@@ -1838,7 +1834,7 @@ export type Spend = {
1838
1834
  */
1839
1835
  platform_keys: boolean;
1840
1836
  /**
1841
- * Why Palbase's models serve it no more this month: budget (its monthly budget is spent) or payment (its free dollar is spent and it has no payment account with a balance).
1837
+ * Why Palbase's models serve it no more this month: budget (its monthly budget is spent) or payment (its free dollar is spent and it has no balance to pay past it).
1842
1838
  */
1843
1839
  reason?: "budget" | "payment";
1844
1840
  /**
@@ -2475,7 +2471,7 @@ export type VoiceSession = {
2475
2471
  */
2476
2472
  chat_id: string;
2477
2473
  /**
2478
- * 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.
2474
+ * 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 balance can pay is spent, and it ran on Palbase's models), or the provider's word.
2479
2475
  */
2480
2476
  close_reason?: string;
2481
2477
  /**
@@ -1,14 +1,14 @@
1
1
  import { type Reply, type Transport } from '../transport.js';
2
2
  /**
3
- * One time the project's server read or removed people's messages.
3
+ * One time people's messages were read or removed: by the project's server, or by an owner or admin from Studio or the CLI.
4
4
  */
5
5
  export type AccessEntry = {
6
6
  /**
7
- * read_messages, read_report, delete_message, delete_conversation or send_message.
7
+ * read_messages, read_report, read_file, delete_message, delete_conversation or send_message.
8
8
  */
9
9
  action: string;
10
10
  /**
11
- * The key that made the call.
11
+ * Who: the developer whose call it was from Studio or the CLI (their user id, usr_…), or the key or token the call was made with.
12
12
  */
13
13
  actor: string;
14
14
  /**
@@ -1728,7 +1728,7 @@ export declare function client(t: Transport): {
1728
1728
  /**
1729
1729
  * What a conversation said
1730
1730
  *
1731
- * What the conversation said, the newest first — every read in the access log.
1731
+ * What the conversation said, the newest first — every read in the access log. An owner's or an admin's read from Studio or with a token: a member sees the conversations and the reports, not what was said.
1732
1732
  */
1733
1733
  adminListMessages(input: {
1734
1734
  path: {
@@ -1764,6 +1764,19 @@ export declare function client(t: Transport): {
1764
1764
  }; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
1765
1765
  signal?: AbortSignal;
1766
1766
  }): Promise<Reply<204, undefined>>;
1767
+ /**
1768
+ * Where a message's file is read
1769
+ *
1770
+ * A URL reading one of a message's files (encrypted: its key is in the message), a while. In the access log. An owner's or an admin's read from Studio or with a token: a member sees the conversations and the reports, not what was said.
1771
+ */
1772
+ adminFileUrl(input: {
1773
+ path: {
1774
+ conversation_id: string; /** The message. */
1775
+ message_id: string; /** The file. */
1776
+ attachment_id: string;
1777
+ }; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
1778
+ signal?: AbortSignal;
1779
+ }): Promise<Reply<200, FileURL>>;
1767
1780
  /**
1768
1781
  * A person's name and picture
1769
1782
  *
@@ -1792,7 +1805,7 @@ export declare function client(t: Transport): {
1792
1805
  /**
1793
1806
  * One report, with what it carries
1794
1807
  *
1795
- * A report with its reporter's note and what the messages it names said when reported (their files with the keys that open them). In the access log.
1808
+ * A report with its reporter's note and what the messages it names said when reported (their files with the keys that open them; a message already gone from its reader's screen — seen once, its time up, vanish mode, taken back — as it was kept for reports, 14 days). In the access log. An owner's or an admin's read from Studio or with a token: a member sees the conversations and the reports, not what was said. A report is kept 180 days once resolved, two years never resolved.
1796
1809
  */
1797
1810
  adminGetReport(input: {
1798
1811
  path: {
@@ -1800,6 +1813,18 @@ export declare function client(t: Transport): {
1800
1813
  }; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
1801
1814
  signal?: AbortSignal;
1802
1815
  }): Promise<Reply<200, Report>>;
1816
+ /**
1817
+ * Where a report's file is read
1818
+ *
1819
+ * A URL reading one of a report's files (encrypted: its key is in the report), a while — kept while the report is, whatever became of its message. In the access log. An owner's or an admin's read from Studio or with a token: a member sees the conversations and the reports, not what was said.
1820
+ */
1821
+ adminReportFileUrl(input: {
1822
+ path: {
1823
+ report_id: string; /** The file. */
1824
+ attachment_id: string;
1825
+ }; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
1826
+ signal?: AbortSignal;
1827
+ }): Promise<Reply<200, FileURL>>;
1803
1828
  /**
1804
1829
  * Resolve a report
1805
1830
  *
@@ -3009,6 +3009,31 @@ export type AppleKeyRevokedEvent = {
3009
3009
  */
3010
3010
  module?: string;
3011
3011
  };
3012
+ /**
3013
+ * An environment an Apple ID's session is shared with.
3014
+ */
3015
+ export type AppleSessionShare = {
3016
+ /**
3017
+ * The environment's project id.
3018
+ */
3019
+ project_id: string;
3020
+ /**
3021
+ * The environment's ref.
3022
+ */
3023
+ ref: string;
3024
+ /**
3025
+ * The environment's name, as its owner gave it.
3026
+ */
3027
+ name?: string;
3028
+ /**
3029
+ * The person who shared it.
3030
+ */
3031
+ shared_by: string;
3032
+ /**
3033
+ * When it was shared.
3034
+ */
3035
+ shared_at: string;
3036
+ };
3012
3037
  /** The events this module sends the project's webhooks (x-palbase-events), by type: each one's payload, the event's data. */
3013
3038
  export interface Events {
3014
3039
  /**
@@ -4080,5 +4105,33 @@ export declare function client(t: Transport): {
4080
4105
  }; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
4081
4106
  signal?: AbortSignal;
4082
4107
  }): Promise<Reply<200, MadeKey>>;
4108
+ /**
4109
+ * Share the Apple ID's session with another environment
4110
+ *
4111
+ * Shares the environment's own Apple ID session with another environment of its Studio project, which uses it from then on while it has no session of its own: no other environment uses it — of another project of the organization, of the Apple team or not. A person's call, an owner or an admin of both environments (403 `person_required` for a key, `admin_required` for one who is not, `other_project` for an environment of another project); not an environment token's. The environment's App Store Connect key or iOS apps, if it has any, are of the session's team (422 `apple_team_mismatch`). The share holds this sign-in: signed out, or signed in anew, the session serves no environment it was shared with before. The environment it is shared with is lent it for a person who is an owner or an admin of this environment.
4112
+ */
4113
+ shareAppleSession(input: {
4114
+ path: {
4115
+ environment: string;
4116
+ };
4117
+ headers?: {
4118
+ "Idempotency-Key"?: string;
4119
+ }; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
4120
+ signal?: AbortSignal;
4121
+ }): Promise<Reply<200, AppleSessionShare>>;
4122
+ /**
4123
+ * Take the Apple ID's session back from an environment
4124
+ *
4125
+ * Takes the environment's Apple ID session back from an environment it was shared with: that environment uses it no more. An owner's or an admin's, or the project's secret key's (403 `admin_required` for a member); 404 `share_not_found` when it is not shared with it.
4126
+ */
4127
+ unshareAppleSession(input: {
4128
+ path: {
4129
+ environment: string;
4130
+ };
4131
+ headers?: {
4132
+ "Idempotency-Key"?: string;
4133
+ }; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
4134
+ signal?: AbortSignal;
4135
+ }): Promise<Reply<204, undefined>>;
4083
4136
  };
4084
4137
  export type Client = ReturnType<typeof client>;