palbase 0.10.1 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) 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 +8 -8
  5. package/dist/backend/stack.js +1 -1
  6. package/dist/backend/test.js +2 -2
  7. package/dist/chunks/{IVJCGBYG.js → 5NZGW67E.js} +2 -2
  8. package/dist/chunks/{QC2SDBJD.js → 5TVS7F23.js} +2 -2
  9. package/dist/chunks/{R4OLJRMH.js → 6JUQZ4D4.js} +2 -2
  10. package/dist/chunks/{FHXGE2MX.js → 7PBQ3LI2.js} +1 -1
  11. package/dist/chunks/BMCC423W.js +2 -0
  12. package/dist/chunks/{NGS4ALOE.js → D2UQQWJC.js} +1 -1
  13. package/dist/chunks/{UDAWSJMT.js → I2TY2GLY.js} +2 -2
  14. package/dist/chunks/{NBI5LPMS.js → IW34A4TV.js} +2 -2
  15. package/dist/chunks/{MFMA46HN.js → L4SCG6HT.js} +2 -2
  16. package/dist/chunks/{XYXBDSXW.js → MAPLN2FY.js} +1 -1
  17. package/dist/chunks/{6N3E2XHZ.js → O5CJJFEU.js} +1 -1
  18. package/dist/chunks/{INRWHOEW.js → PKBCMWTM.js} +2 -2
  19. package/dist/chunks/QCKQXIQV.js +20 -0
  20. package/dist/chunks/{RO7ERCT3.js → QTAPRS4Q.js} +2 -2
  21. package/dist/chunks/{PG7BO4MR.js → RYWIWH4U.js} +1 -1
  22. package/dist/chunks/{QD3SPM7D.js → S4F256W2.js} +2 -2
  23. package/dist/chunks/{QW3V2NBT.js → SBVBCENU.js} +2 -2
  24. package/dist/chunks/{RWGEPDRQ.js → SCXHU5B7.js} +2 -2
  25. package/dist/chunks/{Z4A62VQR.js → XJEZB4MI.js} +2 -2
  26. package/dist/chunks/{APTIATSC.js → ZOAWYN6L.js} +2 -2
  27. package/dist/cli.js +165 -123
  28. package/dist/refuse/ai.js +1 -1
  29. package/dist/refuse/backend.js +1 -1
  30. package/dist/refuse/server.js +1 -1
  31. package/dist/server/index.js +2 -2
  32. package/dist/server/testing.js +2 -2
  33. package/dist/web/index.js +2 -2
  34. package/dist/web/message.js +2 -2
  35. package/dist/web/palbe.js +2 -2
  36. package/dist/web/paywall.js +2 -2
  37. package/dist/web/push-sw.js +1 -1
  38. package/dist/web/ssr.js +2 -2
  39. package/dist/web/vite.js +2 -2
  40. package/package.json +2 -2
  41. package/types/backend/src/container.d.ts +2 -0
  42. package/types/backend/src/decorators.d.ts +1 -0
  43. package/types/backend/src/engine.d.ts +6 -1
  44. package/types/backend/src/index.d.ts +1 -0
  45. package/types/backend/src/test-user-templates.d.ts +58 -0
  46. package/types/internal/src/modules/auth.d.ts +19 -5
  47. package/types/internal/src/modules/events.d.ts +2 -2
  48. package/types/internal/src/modules/machines.d.ts +74 -2
  49. package/types/internal/src/modules/stores.d.ts +685 -8
  50. package/dist/chunks/EUI3Y3LO.js +0 -20
  51. package/dist/chunks/YQEM4H7U.js +0 -2
package/dist/refuse/ai.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! palbase 0.10.1 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.10.2 — Palbase SDK License (see LICENSE) */
2
2
  throw new Error("palbase/ai is for servers: it speaks with the project secret key, which never goes into a browser or a mobile app \u2014 call your backend, and let it ask the model");
@@ -1,2 +1,2 @@
1
- /*! palbase 0.10.1 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.10.2 — Palbase SDK License (see LICENSE) */
2
2
  throw new Error("palbase/backend is a server framework: it runs on your backend, never in a browser or a mobile app \u2014 apps use palbase/web (or the native SDKs)");
@@ -1,2 +1,2 @@
1
- /*! palbase 0.10.1 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.10.2 — Palbase SDK License (see LICENSE) */
2
2
  throw new Error("palbase/server is for servers: its secret key never goes into a browser or a mobile app \u2014 apps use palbase/web (or the native SDKs) with the publishable key");
@@ -1,2 +1,2 @@
1
- /*! palbase 0.10.1 — Palbase SDK License (see LICENSE) */
2
- import{a as c,b as d,c as e,d as f,e as g,f as h,g as i,h as j,i as k,j as l,k as m,l as n,m as o,n as p,o as q,p as r,q as s,r as t}from"../chunks/INRWHOEW.js";import"../chunks/6N3E2XHZ.js";import{m as b}from"../chunks/YQEM4H7U.js";import"../chunks/RO7ERCT3.js";import{b as a}from"../chunks/RWGEPDRQ.js";import"../chunks/PG7BO4MR.js";import"../chunks/XYXBDSXW.js";export{j as AuthUnavailable,b as EVENT_TYPES,a as PalbaseError,o as ReservationSettled,i as TokenError,l as TokenVerifier,d as WebhookSignatureError,c as createServer,n as isEntitled,t as loadSecrets,q as pages,s as platformOwn,r as processOwn,m as requestAddress,k as sessionStanding,g as signatureHeader,f as verifySignature,e as verifyWebhook,h as verifyWebhookRequest,p as withReservation};
1
+ /*! palbase 0.10.2 — Palbase SDK License (see LICENSE) */
2
+ import{a as c,b as d,c as e,d as f,e as g,f as h,g as i,h as j,i as k,j as l,k as m,l as n,m as o,n as p,o as q,p as r,q as s,r as t}from"../chunks/PKBCMWTM.js";import"../chunks/O5CJJFEU.js";import{m as b}from"../chunks/BMCC423W.js";import"../chunks/QTAPRS4Q.js";import{b as a}from"../chunks/SCXHU5B7.js";import"../chunks/RYWIWH4U.js";import"../chunks/MAPLN2FY.js";export{j as AuthUnavailable,b as EVENT_TYPES,a as PalbaseError,o as ReservationSettled,i as TokenError,l as TokenVerifier,d as WebhookSignatureError,c as createServer,n as isEntitled,t as loadSecrets,q as pages,s as platformOwn,r as processOwn,m as requestAddress,k as sessionStanding,g as signatureHeader,f as verifySignature,e as verifyWebhook,h as verifyWebhookRequest,p as withReservation};
@@ -1,2 +1,2 @@
1
- /*! palbase 0.10.1 — Palbase SDK License (see LICENSE) */
2
- import{a,b,c,d}from"../chunks/UDAWSJMT.js";import"../chunks/PG7BO4MR.js";import"../chunks/XYXBDSXW.js";export{a as TestApiError,d as api,b as createTestApi,c as testRun};
1
+ /*! palbase 0.10.2 — Palbase SDK License (see LICENSE) */
2
+ import{a,b,c,d}from"../chunks/I2TY2GLY.js";import"../chunks/RYWIWH4U.js";import"../chunks/MAPLN2FY.js";export{a as TestApiError,d as api,b as createTestApi,c as testRun};
package/dist/web/index.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! palbase 0.10.1 — Palbase SDK License (see LICENSE) */
2
- import{a as h,b as g,c as C,d as w,e as v,f as b,g as E,h as T,i as P,j as S,k as x,l as k,m as R,n as I,o as L,p as M,q as G}from"../chunks/QD3SPM7D.js";import{a as V,b as O,f as A}from"../chunks/R4OLJRMH.js";import"../chunks/MFMA46HN.js";import"../chunks/NBI5LPMS.js";import"../chunks/FHXGE2MX.js";import"../chunks/IVJCGBYG.js";import"../chunks/YQEM4H7U.js";import"../chunks/RO7ERCT3.js";import{b as u}from"../chunks/RWGEPDRQ.js";import"../chunks/PG7BO4MR.js";import"../chunks/XYXBDSXW.js";var D="oai-events";async function N(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 o=e.rtc??B(),t=e.signal;t?.throwIfAborted();let s=e.audio??F(),c=e.microphone===void 0,a=e.microphone??await o.getUserMedia({audio:!0});if(t?.aborted){if(c)for(let r of a.getTracks())r.stop();throw t.reason}let n=new o.RTCPeerConnection,p=!1,d=()=>{if(!p){if(p=!0,f.close(),n.close(),c)for(let r of a.getTracks())r.stop();s.srcObject!==null&&(s.srcObject=null)}};n.addEventListener("track",r=>{s.srcObject=r.streams[0]??new MediaStream([r.track]),s.play?.()?.catch?.(()=>{})}),n.addEventListener("connectionstatechange",()=>e.onState?.(n.connectionState));for(let r of a.getAudioTracks())n.addTrack(r,a);let f=n.createDataChannel(D);f.addEventListener("message",r=>{let i=U(r.data);i!==void 0&&e.onError?.(i)});let y=()=>d();t?.addEventListener("abort",y,{once:!0});try{await n.setLocalDescription(await n.createOffer()),t?.throwIfAborted(),await H(n,e.iceTimeoutMs??1e4,t);let r=n.localDescription?.sdp;if(!r)throw new Error("connectVoice: the peer connection made no offer");let i=await e.start(r);if(t?.throwIfAborted(),typeof i?.id!="string"||i.id===""||typeof i.sdp!="string"||i.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 n.setRemoteDescription({type:"answer",sdp:i.sdp}),t?.removeEventListener("abort",y),{id:i.id,peer:n,audio:s,microphone:a,get muted(){return a.getAudioTracks().every(l=>!l.enabled)},mute(l){for(let m of a.getAudioTracks())m.enabled=!l},close:d}}catch(r){throw t?.removeEventListener("abort",y),d(),t?.aborted?t.reason:r}}function H(e,o,t){return e.iceGatheringState==="complete"?Promise.resolve():t?.aborted?Promise.reject(t.reason):new Promise((s,c)=>{let a=()=>{clearTimeout(d),e.removeEventListener("icegatheringstatechange",n),t?.removeEventListener("abort",p)},n=()=>{e.iceGatheringState==="complete"&&(a(),s())},p=()=>{a(),c(t?.reason)},d=setTimeout(()=>{a(),c(new Error(`connectVoice: the network candidates were not gathered in ${o} ms`))},o);e.addEventListener("icegatheringstatechange",n),t?.addEventListener("abort",p,{once:!0})})}function U(e){if(typeof e=="string")try{let o=JSON.parse(e);return o.type!=="error"?void 0:typeof o.error?.message=="string"?o.error.message:typeof o.error?.code=="string"?o.error.code:"the voice failed"}catch{return}}function B(){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 o=e.navigator.mediaDevices;return{RTCPeerConnection:e.RTCPeerConnection,getUserMedia:t=>o.getUserMedia(t)}}function F(){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 o=e.createElement("audio");return o.autoplay=!0,o}export{E as Analytics,V as BackendError,w as Channel,T as Consent,M as Flags,A as GatewayError,x as InApp,P as Inbox,b as Installation,R as Notify,u as PalbaseError,I as Purchases,v as RealtimeSocket,S as SESSION_START,h as SessionChangedError,k as WebPush,N as connectVoice,G as createClient,O as isBackendError,C as localStore,g as memoryStore,L as redemptionToken};
1
+ /*! palbase 0.10.2 — Palbase SDK License (see LICENSE) */
2
+ import{a as h,b as g,c as C,d as w,e as v,f as b,g as E,h as T,i as P,j as S,k as x,l as k,m as R,n as I,o as L,p as M,q as G}from"../chunks/S4F256W2.js";import{a as V,b as O,f as A}from"../chunks/6JUQZ4D4.js";import"../chunks/L4SCG6HT.js";import"../chunks/IW34A4TV.js";import"../chunks/7PBQ3LI2.js";import"../chunks/5NZGW67E.js";import"../chunks/BMCC423W.js";import"../chunks/QTAPRS4Q.js";import{b as u}from"../chunks/SCXHU5B7.js";import"../chunks/RYWIWH4U.js";import"../chunks/MAPLN2FY.js";var D="oai-events";async function N(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 o=e.rtc??B(),t=e.signal;t?.throwIfAborted();let s=e.audio??F(),c=e.microphone===void 0,a=e.microphone??await o.getUserMedia({audio:!0});if(t?.aborted){if(c)for(let r of a.getTracks())r.stop();throw t.reason}let n=new o.RTCPeerConnection,p=!1,d=()=>{if(!p){if(p=!0,f.close(),n.close(),c)for(let r of a.getTracks())r.stop();s.srcObject!==null&&(s.srcObject=null)}};n.addEventListener("track",r=>{s.srcObject=r.streams[0]??new MediaStream([r.track]),s.play?.()?.catch?.(()=>{})}),n.addEventListener("connectionstatechange",()=>e.onState?.(n.connectionState));for(let r of a.getAudioTracks())n.addTrack(r,a);let f=n.createDataChannel(D);f.addEventListener("message",r=>{let i=U(r.data);i!==void 0&&e.onError?.(i)});let y=()=>d();t?.addEventListener("abort",y,{once:!0});try{await n.setLocalDescription(await n.createOffer()),t?.throwIfAborted(),await H(n,e.iceTimeoutMs??1e4,t);let r=n.localDescription?.sdp;if(!r)throw new Error("connectVoice: the peer connection made no offer");let i=await e.start(r);if(t?.throwIfAborted(),typeof i?.id!="string"||i.id===""||typeof i.sdp!="string"||i.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 n.setRemoteDescription({type:"answer",sdp:i.sdp}),t?.removeEventListener("abort",y),{id:i.id,peer:n,audio:s,microphone:a,get muted(){return a.getAudioTracks().every(l=>!l.enabled)},mute(l){for(let m of a.getAudioTracks())m.enabled=!l},close:d}}catch(r){throw t?.removeEventListener("abort",y),d(),t?.aborted?t.reason:r}}function H(e,o,t){return e.iceGatheringState==="complete"?Promise.resolve():t?.aborted?Promise.reject(t.reason):new Promise((s,c)=>{let a=()=>{clearTimeout(d),e.removeEventListener("icegatheringstatechange",n),t?.removeEventListener("abort",p)},n=()=>{e.iceGatheringState==="complete"&&(a(),s())},p=()=>{a(),c(t?.reason)},d=setTimeout(()=>{a(),c(new Error(`connectVoice: the network candidates were not gathered in ${o} ms`))},o);e.addEventListener("icegatheringstatechange",n),t?.addEventListener("abort",p,{once:!0})})}function U(e){if(typeof e=="string")try{let o=JSON.parse(e);return o.type!=="error"?void 0:typeof o.error?.message=="string"?o.error.message:typeof o.error?.code=="string"?o.error.code:"the voice failed"}catch{return}}function B(){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 o=e.navigator.mediaDevices;return{RTCPeerConnection:e.RTCPeerConnection,getUserMedia:t=>o.getUserMedia(t)}}function F(){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 o=e.createElement("audio");return o.autoplay=!0,o}export{E as Analytics,V as BackendError,w as Channel,T as Consent,M as Flags,A as GatewayError,x as InApp,P as Inbox,b as Installation,R as Notify,u as PalbaseError,I as Purchases,v as RealtimeSocket,S as SESSION_START,h as SessionChangedError,k as WebPush,N as connectVoice,G as createClient,O as isBackendError,C as localStore,g as memoryStore,L as redemptionToken};
@@ -1,2 +1,2 @@
1
- /*! palbase 0.10.1 — Palbase SDK License (see LICENSE) */
2
- import{a as i}from"../chunks/NBI5LPMS.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/FHXGE2MX.js";import"../chunks/XYXBDSXW.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.10.2 — Palbase SDK License (see LICENSE) */
2
+ import{a as i}from"../chunks/IW34A4TV.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/7PBQ3LI2.js";import"../chunks/MAPLN2FY.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.10.1 — Palbase SDK License (see LICENSE) */
2
- import{c as e,d as r,i as t}from"../chunks/R4OLJRMH.js";import"../chunks/IVJCGBYG.js";import"../chunks/RO7ERCT3.js";import"../chunks/RWGEPDRQ.js";import"../chunks/PG7BO4MR.js";import"../chunks/XYXBDSXW.js";export{e as RESERVED_CLIENT_NAMES,t as __registerBackend,r as isClientName};
1
+ /*! palbase 0.10.2 — Palbase SDK License (see LICENSE) */
2
+ import{c as e,d as r,i as t}from"../chunks/6JUQZ4D4.js";import"../chunks/5NZGW67E.js";import"../chunks/QTAPRS4Q.js";import"../chunks/SCXHU5B7.js";import"../chunks/RYWIWH4U.js";import"../chunks/MAPLN2FY.js";export{e as RESERVED_CLIENT_NAMES,t as __registerBackend,r as isClientName};
@@ -1,2 +1,2 @@
1
- /*! palbase 0.10.1 — 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/MFMA46HN.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/FHXGE2MX.js";import"../chunks/RWGEPDRQ.js";import"../chunks/PG7BO4MR.js";import"../chunks/XYXBDSXW.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.10.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/L4SCG6HT.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/7PBQ3LI2.js";import"../chunks/SCXHU5B7.js";import"../chunks/RYWIWH4U.js";import"../chunks/MAPLN2FY.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.10.1 — Palbase SDK License (see LICENSE) */
1
+ /*! palbase 0.10.2 — Palbase SDK License (see LICENSE) */
2
2
  "use strict";(()=>{function f(e,s){if(e)try{let i=new URL(e,s);if(i.protocol==="https:"||i.protocol==="http:"&&(i.hostname==="localhost"||i.hostname==="127.0.0.1"))return i.href}catch{}}function g(e){let s=new URL(e.location.href).searchParams,i=s.get("url")??"",l=s.get("key")??"",r=(n,t)=>!n||!i?Promise.resolve():e.fetch(`${i.replace(/\/$/,"")}/notify/receipts`,{method:"POST",headers:{"content-type":"application/json",apikey:l},body:JSON.stringify({receipts:[{receipt:n,status:t}]}),keepalive:!0}).catch(()=>{}),a=async(n,t)=>{for(let o of await e.clients.matchAll({type:"window",includeUncontrolled:!0}))o.postMessage({type:"palbase.push",event:n,url:t.url,data:t.data})};e.addEventListener("push",(n=>{let t={};try{t=n.data?.json()??{}}catch{}let o={url:t.url,receipt:t.receipt,data:t.data};n.waitUntil(e.registration.showNotification(t.title??"",{body:t.body,image:t.image,tag:t.tag,data:o}).then(()=>Promise.all([r(t.receipt,"delivered"),a("received",o)])))})),e.addEventListener("notificationclick",(n=>{n.notification.close();let t=n.notification.data??{},o=f(t.url,e.location.origin),c=async()=>{if(!o)return;let d=(await e.clients.matchAll({type:"window",includeUncontrolled:!0})).find(u=>u.url===o);d?await d.focus():await e.clients.openWindow(o)};n.waitUntil(Promise.all([r(t.receipt,"opened"),c(),a("opened",t)]))})),e.addEventListener("notificationclose",(n=>{n.waitUntil(r(n.notification.data?.receipt,"dismissed"))}))}typeof self<"u"&&typeof self.registration=="object"&&!("document"in self)&&g(self);})();
package/dist/web/ssr.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! palbase 0.10.1 — Palbase SDK License (see LICENSE) */
2
- import{q as f}from"../chunks/QD3SPM7D.js";import"../chunks/R4OLJRMH.js";import"../chunks/MFMA46HN.js";import"../chunks/NBI5LPMS.js";import"../chunks/FHXGE2MX.js";import"../chunks/IVJCGBYG.js";import"../chunks/YQEM4H7U.js";import"../chunks/RO7ERCT3.js";import"../chunks/RWGEPDRQ.js";import"../chunks/PG7BO4MR.js";import"../chunks/XYXBDSXW.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.10.2 — Palbase SDK License (see LICENSE) */
2
+ import{q as f}from"../chunks/S4F256W2.js";import"../chunks/6JUQZ4D4.js";import"../chunks/L4SCG6HT.js";import"../chunks/IW34A4TV.js";import"../chunks/7PBQ3LI2.js";import"../chunks/5NZGW67E.js";import"../chunks/BMCC423W.js";import"../chunks/QTAPRS4Q.js";import"../chunks/SCXHU5B7.js";import"../chunks/RYWIWH4U.js";import"../chunks/MAPLN2FY.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.10.1 — Palbase SDK License (see LICENSE) */
2
- import"../chunks/XYXBDSXW.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.10.2 — Palbase SDK License (see LICENSE) */
2
+ import"../chunks/MAPLN2FY.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.10.1",
3
+ "version": "0.10.2",
4
4
  "description": "Palbase for JavaScript: the web client (palbase/web), the server SDK (palbase/server), the backend framework (palbase/backend), AI (palbase/ai) and the CLI (npx palbase).",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://palbase.studio",
@@ -135,7 +135,7 @@
135
135
  "dependencies": {
136
136
  "@types/node": "26.6.4",
137
137
  "bun-types": "1.4.2",
138
- "palgres": "0.10.1",
138
+ "palgres": "0.10.2",
139
139
  "reflect-metadata": "^0.2.2",
140
140
  "typescript": "~6.0.3",
141
141
  "zod": "^4.6.5"
@@ -30,6 +30,8 @@ export declare class Container {
30
30
  readonly cronProviders: Ctor[];
31
31
  /** The providers that are @Task classes: the platform runs them as their tasks come due. */
32
32
  readonly taskProviders: Ctor[];
33
+ /** The providers that are @TestUserTemplate classes: the platform calls them for the test users made with their names. */
34
+ readonly templateProviders: Ctor[];
33
35
  /** The providers that are @Gateway classes. */
34
36
  readonly gateways: Ctor[];
35
37
  constructor(modules: Function[]);
@@ -88,6 +88,7 @@ export declare const EVENTS: unique symbol;
88
88
  export declare const WEBHOOK: unique symbol;
89
89
  export declare const CRONS: unique symbol;
90
90
  export declare const TASKS: unique symbol;
91
+ export declare const TEST_USER_TEMPLATES: unique symbol;
91
92
  export declare function declared(): Set<Function>;
92
93
  export declare const RESERVED: Set<string>;
93
94
  export declare function Controller(basePath: string, options?: ControllerOptions): ClassDecorator;
@@ -106,7 +106,12 @@ export interface AppOptions {
106
106
  * - its ai tools and agents (@palbase/ai's ai.tool and ai.agent), from the
107
107
  * ai module: POST /_palbase/ai/tools runs the tool an agent called (its
108
108
  * body's tool), POST /_palbase/ai/agents answers the definition of the
109
- * agent a turn is of (its body's agent) — ai-calls.ts.
109
+ * agent a turn is of (its body's agent) — ai-calls.ts;
110
+ * - its @TestUserTemplate classes, from the machines module, for a test
111
+ * user it made through auth: POST /_palbase/test-user-templates/<name>
112
+ * writes the template for the user its body names — a test user, auth
113
+ * says, or 403 — and answers {rows: {table: n}}; …/<name>/undo takes it
114
+ * away (404: the template has none) — test-user-templates.ts.
110
115
  */
111
116
  platform?: {
112
117
  secret: string;
@@ -1,6 +1,7 @@
1
1
  import 'reflect-metadata';
2
2
  export { 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';
3
3
  export { Task, TaskFailure, Tasks, type EnqueueOptions, type PayloadOf, type QueuedTask, type TaskClass, type TaskMeta, type TaskOptions, type TasksService } from './tasks.js';
4
+ export { TestUserTemplate, type TemplateMeta, type TemplateUser, type TestUserTemplateClass, type TestUserTemplateOptions } from './test-user-templates.js';
4
5
  export { Upload, UploadedObject, type UploadConfig } from './upload.js';
5
6
  export { Authorize, ChatPart, Gateway, GatewayRefusal, OnConnect, OnDisconnect, OnEmpty, OnFirst, Subscribe, type GatewayAuthorizeContext, type GatewayContext, type GatewayEvents, type GatewayGrant, type GatewayMessageContext, type GatewayOptions, type GatewayUser, type PipeSource, } from './gateways.js';
6
7
  export type { GatewaysApi, GatewayTarget } from './runtime.js';
@@ -0,0 +1,58 @@
1
+ import type { PalbaseServer } from '../../server/src/index.js';
2
+ export declare const TEST_USER_TEMPLATES_PATH = "/_palbase/test-user-templates";
3
+ /** A template's name, as the platform takes it: lowercase letters, digits, '_' and '-', a letter first, at most 64. */
4
+ export declare const TEMPLATE_NAME: RegExp;
5
+ export interface TestUserTemplateOptions {
6
+ /** What `palbase auth:test-users:create --template <name>` names it by. */
7
+ name: string;
8
+ }
9
+ export interface TestUserTemplateDeclaration {
10
+ name: string;
11
+ }
12
+ /** The test user a template writes for, as the platform names it: auth made it, and says it is a test user. */
13
+ export interface TemplateUser {
14
+ id: string;
15
+ email: string;
16
+ }
17
+ /** What seed() and undo() are given beside the user. */
18
+ export interface TemplateMeta {
19
+ /** The app's environment variables, as it started (its keys left out). */
20
+ env: Record<string, string>;
21
+ /** The project the app belongs to (its id). */
22
+ environmentId: string;
23
+ /** The template's name. */
24
+ template: string;
25
+ }
26
+ /** A @TestUserTemplate class: seed(user, meta) writes what the screen shows, undo(user, meta) — when it has one — takes it away. */
27
+ export type TestUserTemplateClass = abstract new (...args: never[]) => {
28
+ seed(user: TemplateUser, meta: TemplateMeta): unknown;
29
+ undo?(user: TemplateUser, meta: TemplateMeta): unknown;
30
+ };
31
+ /**
32
+ * A provider whose seed(user, meta) writes the data a test account needs —
33
+ * the rows behind the screen a person or an agent signs in to see — for test
34
+ * users alone: the platform calls it for each test user made with its name
35
+ * (palbase auth:test-users:create --template <name>), and the framework asks
36
+ * auth first that the user is a test user. It runs in one transaction, as the
37
+ * service role: all of it written, or none. An undo(user, meta) takes away
38
+ * what seed wrote that the user's deletion does not (user.deleted forgets
39
+ * what ownedByUser() owns). Its module lists it in its providers, as any other.
40
+ */
41
+ export declare function TestUserTemplate(options: TestUserTemplateOptions): ClassDecorator;
42
+ /** What the platform's call names, or why it is not one: the template the path names, and its test user. */
43
+ export declare function templateCallOf(name: string, body: unknown): {
44
+ user: TemplateUser;
45
+ } | string;
46
+ /**
47
+ * Whether auth says the user is a test user: false for one it does not say
48
+ * is, or does not know (404). Anything else — auth not answering — throws: a
49
+ * template is never run, nor refused, on a guess.
50
+ */
51
+ export declare function isTestUser(server: PalbaseServer, id: string): Promise<boolean>;
52
+ /**
53
+ * The rows the transaction wrote, by table — public's by name, any other
54
+ * schema's as <schema>.<table> — as Postgres counts them for it
55
+ * (pg_stat_xact_user_tables: its inserts and updates). An app with no
56
+ * database wrote none.
57
+ */
58
+ export declare function rowsWritten(database: object | undefined): Promise<Record<string, number>>;
@@ -627,7 +627,7 @@ export type AdminUserImportError = {
627
627
  */
628
628
  export type AdminUserImportHash = {
629
629
  /**
630
- * palbase-argon2id: Argon2id (PHC string) over HMAC-SHA256(pepper, secret) — Palbase's own scheme, before and now.
630
+ * palbase-argon2id: Argon2id (PHC string) over HMAC-SHA256(pepper, secret) — Palbase's own scheme.
631
631
  */
632
632
  algorithm: "palbase-argon2id";
633
633
  /**
@@ -635,7 +635,7 @@ export type AdminUserImportHash = {
635
635
  */
636
636
  pepper: string;
637
637
  /**
638
- * What the source put before a recovery code it hashed (the platform before used palauth-rc:). This platform's own, palbase-rc:, when absent.
638
+ * What the source put before a recovery code it hashed. This platform's own, palbase-rc:, when absent.
639
639
  */
640
640
  recovery_code_prefix?: string;
641
641
  };
@@ -1021,6 +1021,10 @@ export type AuthSettings = {
1021
1021
  * Bind each session to the device it was opened on: a refresh from another device fingerprint, browser or operating system ends the session; a network change is recorded in the audit log. Default false.
1022
1022
  */
1023
1023
  session_device_binding?: boolean;
1024
+ /**
1025
+ * Let clients create new users — the project's sign-up switch. Default true; off, every way a client opens an account answers 403 `signups_closed`: `POST /auth/signup`, a passkey signup, a guest, a phone's first code and a provider's first sign-in. Accounts sign in as before, and the admin API (`POST /admin/users`, imports, test users) still creates users.
1026
+ */
1027
+ signups_enabled?: boolean;
1024
1028
  /**
1025
1029
  * Base URL for the links in auth emails (reset, verify, magic link). Empty: the Palbase-hosted default.
1026
1030
  */
@@ -1100,6 +1104,10 @@ export type AuthSettingsUpdateRequest = {
1100
1104
  * Bind each session to the device it was opened on: a refresh from another device fingerprint, browser or operating system ends the session; a network change is recorded in the audit log. Default false.
1101
1105
  */
1102
1106
  session_device_binding?: boolean;
1107
+ /**
1108
+ * Let clients create new users — the project's sign-up switch. Default true; off, every way a client opens an account answers 403 `signups_closed`: `POST /auth/signup`, a passkey signup, a guest, a phone's first code and a provider's first sign-in. Accounts sign in as before, and the admin API (`POST /admin/users`, imports, test users) still creates users.
1109
+ */
1110
+ signups_enabled?: boolean;
1103
1111
  /**
1104
1112
  * Absolute http(s) URL without a fragment, at most 2048 characters; empty clears it.
1105
1113
  */
@@ -4521,7 +4529,7 @@ export declare function client(t: Transport): {
4521
4529
  *
4522
4530
  * Opens a guest account and its session: an account with no address, password or credential, whose id stays when it becomes an account — by `POST /auth/anonymous/convert` (an address and a password), by adding a passkey (`POST /auth/webauthn/register/begin`, with `user_name`), or by linking a provider (`POST /auth/oauth/transactions` with the guest's session). What the visitor does as a guest is kept under that id.
4523
4531
  *
4524
- * The project must have turned guests on (`anonymous_sign_ins`; 403 `anonymous_sign_ins_disabled` otherwise). Held to what holds signup: the project's user ceiling (403 `signups_closed`), proof of work (403 `pow_required`, with the challenge), the risk engine and the project's `before.user.create` hook (told `is_anonymous`) — and to 30 guests an hour from one address (429). The access token carries `is_anonymous: true`; a native client that sends a DPoP proof gets the session and its tokens bound to that key, as a sign-in does. Send an `Idempotency-Key`: a retry then gets the same guest back, not a second one.
4532
+ * The project must have turned guests on (`anonymous_sign_ins`; 403 `anonymous_sign_ins_disabled` otherwise). Held to what holds signup: the project's sign-up switch and user ceiling (`signups_enabled`, 403 `signups_closed`), proof of work (403 `pow_required`, with the challenge), the risk engine and the project's `before.user.create` hook (told `is_anonymous`) — and to 30 guests an hour from one address (429). The access token carries `is_anonymous: true`; a native client that sends a DPoP proof gets the session and its tokens bound to that key, as a sign-in does. Send an `Idempotency-Key`: a retry then gets the same guest back, not a second one.
4525
4533
  */
4526
4534
  signInAnonymously(input?: {
4527
4535
  headers?: {
@@ -5098,7 +5106,7 @@ export declare function client(t: Transport): {
5098
5106
  /**
5099
5107
  * Complete a social sign-in
5100
5108
  *
5101
- * Finishes a sign-in with the provider's answer: signs the user in (or asks for a second factor), or links the identity. Retrying with the same body answers the same result.
5109
+ * Finishes a sign-in with the provider's answer: signs the user in (or asks for a second factor), or links the identity. Retrying with the same body answers the same result. A first sign-in that would open an account answers 403 `signups_closed` while the project takes no new users.
5102
5110
  */
5103
5111
  socialComplete(input: {
5104
5112
  path: {
@@ -5119,7 +5127,7 @@ export declare function client(t: Transport): {
5119
5127
  /**
5120
5128
  * Sign in with an SMS code
5121
5129
  *
5122
- * Checks the code sent by `POST /auth/otp`. A correct code signs the phone's owner in; an unknown number gets a new account when the project allows phone sign-ups (403 `signup_disabled` otherwise). A user with a second factor enrolled gets the `mfa_required` envelope instead of tokens and finishes with `mfa_token` at `/auth/mfa/*`. Codes are single-use; too many wrong attempts (`otp_max_attempts`) or an expired code (`otp_expired`) means requesting a new one.
5130
+ * Checks the code sent by `POST /auth/otp`. A correct code signs the phone's owner in; an unknown number gets a new account when the project allows phone sign-ups (403 `signup_disabled` otherwise) and takes new users at all (403 `signups_closed` otherwise). A user with a second factor enrolled gets the `mfa_required` envelope instead of tokens and finishes with `mfa_token` at `/auth/mfa/*`. Codes are single-use; too many wrong attempts (`otp_max_attempts`) or an expired code (`otp_expired`) means requesting a new one.
5123
5131
  */
5124
5132
  verifyPhoneOtp(input: {
5125
5133
  body: PhoneOTPVerifyRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
@@ -5411,6 +5419,8 @@ export declare function client(t: Transport): {
5411
5419
  * IP-based rate limiting. Pepper + Argon2id is applied server-side;
5412
5420
  * the plaintext password never reaches storage.
5413
5421
  *
5422
+ * 403 `signups_closed` while the project takes no new users (its `signups_enabled` is off, or its user ceiling is reached).
5423
+ *
5414
5424
  */
5415
5425
  signup(input: {
5416
5426
  headers?: {
@@ -5762,6 +5772,8 @@ export declare function client(t: Transport): {
5762
5772
  * Finish the ceremony at `/auth/webauthn/signup/finish` carrying
5763
5773
  * the returned `user_id` as a query parameter.
5764
5774
  *
5775
+ * 403 `signups_closed` while the project takes no new users.
5776
+ *
5765
5777
  */
5766
5778
  webauthnSignupBegin(input: {
5767
5779
  body: WebAuthnSignupBeginRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
@@ -5774,6 +5786,8 @@ export declare function client(t: Transport): {
5774
5786
  * attestation for the user returned by
5775
5787
  * `/auth/webauthn/signup/begin`.
5776
5788
  *
5789
+ * 403 `signups_closed` while the project takes no new users.
5790
+ *
5777
5791
  */
5778
5792
  webauthnSignupFinish(input: {
5779
5793
  query: {
@@ -13,11 +13,11 @@ export interface PlatformEvents extends AiEvents, AnalyticsEvents, AuthEvents, F
13
13
  /** A platform event's type: one a module's contract declares. */
14
14
  export type EventType = keyof PlatformEvents;
15
15
  /** Every platform event's type, as the contracts declare them. */
16
- export declare const EVENT_TYPES: readonly ["ai.goal.updated", "ai.response.completed", "ai.response.failed", "ai.response.started", "ai.voice.closed", "ai.voice.delegated", "ai.voice.started", "ai.workspace.published", "ai.workspace.pushed", "audience.entered", "audience.exited", "consent.changed", "device.revoked", "file.deleted", "file.moved", "file.uploaded", "flag.changed", "flag.override_changed", "notification.action", "notification.bounced", "notification.complained", "notification.delivered", "notification.dismissed", "notification.expired", "notification.failed", "notification.not_shown", "notification.opened", "notification.read", "notification.received", "notification.rejected", "notification.sent", "notification.unconfirmed", "notification.undelivered", "notification.uninstalled", "purchases.catalog.applied", "purchases.catalog.changed", "purchases.coupon.redeemed", "purchases.credits.depleted", "purchases.credits.low", "purchases.customer.changed", "purchases.customer.erased", "purchases.customer.merged", "purchases.entitlement.changed", "purchases.offer.redeemed", "purchases.ownership.transferred", "purchases.paywall.published", "purchases.purchase.completed", "purchases.quota.exhausted", "purchases.quota.threshold", "purchases.refund.changed", "purchases.store.changed", "purchases.subscription.changed", "session.ended", "stores.action.changed", "stores.app.changed", "stores.apple.changed", "stores.delivery.changed", "stores.delivery.requested", "stores.google.changed", "stores.group.changed", "stores.package.changed", "user.converted", "user.deleted", "user.locale_changed", "user.permissions_changed"];
16
+ export declare const EVENT_TYPES: readonly ["ai.goal.updated", "ai.response.completed", "ai.response.failed", "ai.response.started", "ai.voice.closed", "ai.voice.delegated", "ai.voice.started", "ai.workspace.published", "ai.workspace.pushed", "audience.entered", "audience.exited", "consent.changed", "device.revoked", "file.deleted", "file.moved", "file.uploaded", "flag.changed", "flag.override_changed", "notification.action", "notification.bounced", "notification.complained", "notification.delivered", "notification.dismissed", "notification.expired", "notification.failed", "notification.not_shown", "notification.opened", "notification.read", "notification.received", "notification.rejected", "notification.sent", "notification.unconfirmed", "notification.undelivered", "notification.uninstalled", "purchases.catalog.applied", "purchases.catalog.changed", "purchases.coupon.redeemed", "purchases.credits.depleted", "purchases.credits.low", "purchases.customer.changed", "purchases.customer.erased", "purchases.customer.merged", "purchases.entitlement.changed", "purchases.offer.redeemed", "purchases.ownership.transferred", "purchases.paywall.published", "purchases.purchase.completed", "purchases.quota.exhausted", "purchases.quota.threshold", "purchases.refund.changed", "purchases.store.changed", "purchases.subscription.changed", "session.ended", "stores.action.changed", "stores.app.changed", "stores.apple.changed", "stores.delivery.changed", "stores.delivery.requested", "stores.google.changed", "stores.group.changed", "stores.package.changed", "stores.version.changed", "stores.version.reviewed", "user.converted", "user.deleted", "user.locale_changed", "user.permissions_changed"];
17
17
  /**
18
18
  * A platform event as delivered: one member per type the contracts declare,
19
19
  * its data that type's payload, so a switch on its type narrows it. An
20
20
  * event of a type none of them declares (one a newer platform sends) is no
21
21
  * member: at run time it reaches the switch's default, which takes it.
22
22
  */
23
- export type PalbaseEvent = WebhookEvent<PlatformEvents["ai.goal.updated"], "ai.goal.updated"> | WebhookEvent<PlatformEvents["ai.response.completed"], "ai.response.completed"> | WebhookEvent<PlatformEvents["ai.response.failed"], "ai.response.failed"> | WebhookEvent<PlatformEvents["ai.response.started"], "ai.response.started"> | WebhookEvent<PlatformEvents["ai.voice.closed"], "ai.voice.closed"> | WebhookEvent<PlatformEvents["ai.voice.delegated"], "ai.voice.delegated"> | WebhookEvent<PlatformEvents["ai.voice.started"], "ai.voice.started"> | WebhookEvent<PlatformEvents["ai.workspace.published"], "ai.workspace.published"> | WebhookEvent<PlatformEvents["ai.workspace.pushed"], "ai.workspace.pushed"> | WebhookEvent<PlatformEvents["audience.entered"], "audience.entered"> | WebhookEvent<PlatformEvents["audience.exited"], "audience.exited"> | WebhookEvent<PlatformEvents["consent.changed"], "consent.changed"> | WebhookEvent<PlatformEvents["device.revoked"], "device.revoked"> | WebhookEvent<PlatformEvents["file.deleted"], "file.deleted"> | WebhookEvent<PlatformEvents["file.moved"], "file.moved"> | WebhookEvent<PlatformEvents["file.uploaded"], "file.uploaded"> | WebhookEvent<PlatformEvents["flag.changed"], "flag.changed"> | WebhookEvent<PlatformEvents["flag.override_changed"], "flag.override_changed"> | WebhookEvent<PlatformEvents["notification.action"], "notification.action"> | WebhookEvent<PlatformEvents["notification.bounced"], "notification.bounced"> | WebhookEvent<PlatformEvents["notification.complained"], "notification.complained"> | WebhookEvent<PlatformEvents["notification.delivered"], "notification.delivered"> | WebhookEvent<PlatformEvents["notification.dismissed"], "notification.dismissed"> | WebhookEvent<PlatformEvents["notification.expired"], "notification.expired"> | WebhookEvent<PlatformEvents["notification.failed"], "notification.failed"> | WebhookEvent<PlatformEvents["notification.not_shown"], "notification.not_shown"> | WebhookEvent<PlatformEvents["notification.opened"], "notification.opened"> | WebhookEvent<PlatformEvents["notification.read"], "notification.read"> | WebhookEvent<PlatformEvents["notification.received"], "notification.received"> | WebhookEvent<PlatformEvents["notification.rejected"], "notification.rejected"> | WebhookEvent<PlatformEvents["notification.sent"], "notification.sent"> | WebhookEvent<PlatformEvents["notification.unconfirmed"], "notification.unconfirmed"> | WebhookEvent<PlatformEvents["notification.undelivered"], "notification.undelivered"> | WebhookEvent<PlatformEvents["notification.uninstalled"], "notification.uninstalled"> | WebhookEvent<PlatformEvents["purchases.catalog.applied"], "purchases.catalog.applied"> | WebhookEvent<PlatformEvents["purchases.catalog.changed"], "purchases.catalog.changed"> | WebhookEvent<PlatformEvents["purchases.coupon.redeemed"], "purchases.coupon.redeemed"> | WebhookEvent<PlatformEvents["purchases.credits.depleted"], "purchases.credits.depleted"> | WebhookEvent<PlatformEvents["purchases.credits.low"], "purchases.credits.low"> | WebhookEvent<PlatformEvents["purchases.customer.changed"], "purchases.customer.changed"> | WebhookEvent<PlatformEvents["purchases.customer.erased"], "purchases.customer.erased"> | WebhookEvent<PlatformEvents["purchases.customer.merged"], "purchases.customer.merged"> | WebhookEvent<PlatformEvents["purchases.entitlement.changed"], "purchases.entitlement.changed"> | WebhookEvent<PlatformEvents["purchases.offer.redeemed"], "purchases.offer.redeemed"> | WebhookEvent<PlatformEvents["purchases.ownership.transferred"], "purchases.ownership.transferred"> | WebhookEvent<PlatformEvents["purchases.paywall.published"], "purchases.paywall.published"> | WebhookEvent<PlatformEvents["purchases.purchase.completed"], "purchases.purchase.completed"> | WebhookEvent<PlatformEvents["purchases.quota.exhausted"], "purchases.quota.exhausted"> | WebhookEvent<PlatformEvents["purchases.quota.threshold"], "purchases.quota.threshold"> | WebhookEvent<PlatformEvents["purchases.refund.changed"], "purchases.refund.changed"> | WebhookEvent<PlatformEvents["purchases.store.changed"], "purchases.store.changed"> | WebhookEvent<PlatformEvents["purchases.subscription.changed"], "purchases.subscription.changed"> | WebhookEvent<PlatformEvents["session.ended"], "session.ended"> | WebhookEvent<PlatformEvents["stores.action.changed"], "stores.action.changed"> | WebhookEvent<PlatformEvents["stores.app.changed"], "stores.app.changed"> | WebhookEvent<PlatformEvents["stores.apple.changed"], "stores.apple.changed"> | WebhookEvent<PlatformEvents["stores.delivery.changed"], "stores.delivery.changed"> | WebhookEvent<PlatformEvents["stores.delivery.requested"], "stores.delivery.requested"> | WebhookEvent<PlatformEvents["stores.google.changed"], "stores.google.changed"> | WebhookEvent<PlatformEvents["stores.group.changed"], "stores.group.changed"> | WebhookEvent<PlatformEvents["stores.package.changed"], "stores.package.changed"> | WebhookEvent<PlatformEvents["user.converted"], "user.converted"> | WebhookEvent<PlatformEvents["user.deleted"], "user.deleted"> | WebhookEvent<PlatformEvents["user.locale_changed"], "user.locale_changed"> | WebhookEvent<PlatformEvents["user.permissions_changed"], "user.permissions_changed">;
23
+ export type PalbaseEvent = WebhookEvent<PlatformEvents["ai.goal.updated"], "ai.goal.updated"> | WebhookEvent<PlatformEvents["ai.response.completed"], "ai.response.completed"> | WebhookEvent<PlatformEvents["ai.response.failed"], "ai.response.failed"> | WebhookEvent<PlatformEvents["ai.response.started"], "ai.response.started"> | WebhookEvent<PlatformEvents["ai.voice.closed"], "ai.voice.closed"> | WebhookEvent<PlatformEvents["ai.voice.delegated"], "ai.voice.delegated"> | WebhookEvent<PlatformEvents["ai.voice.started"], "ai.voice.started"> | WebhookEvent<PlatformEvents["ai.workspace.published"], "ai.workspace.published"> | WebhookEvent<PlatformEvents["ai.workspace.pushed"], "ai.workspace.pushed"> | WebhookEvent<PlatformEvents["audience.entered"], "audience.entered"> | WebhookEvent<PlatformEvents["audience.exited"], "audience.exited"> | WebhookEvent<PlatformEvents["consent.changed"], "consent.changed"> | WebhookEvent<PlatformEvents["device.revoked"], "device.revoked"> | WebhookEvent<PlatformEvents["file.deleted"], "file.deleted"> | WebhookEvent<PlatformEvents["file.moved"], "file.moved"> | WebhookEvent<PlatformEvents["file.uploaded"], "file.uploaded"> | WebhookEvent<PlatformEvents["flag.changed"], "flag.changed"> | WebhookEvent<PlatformEvents["flag.override_changed"], "flag.override_changed"> | WebhookEvent<PlatformEvents["notification.action"], "notification.action"> | WebhookEvent<PlatformEvents["notification.bounced"], "notification.bounced"> | WebhookEvent<PlatformEvents["notification.complained"], "notification.complained"> | WebhookEvent<PlatformEvents["notification.delivered"], "notification.delivered"> | WebhookEvent<PlatformEvents["notification.dismissed"], "notification.dismissed"> | WebhookEvent<PlatformEvents["notification.expired"], "notification.expired"> | WebhookEvent<PlatformEvents["notification.failed"], "notification.failed"> | WebhookEvent<PlatformEvents["notification.not_shown"], "notification.not_shown"> | WebhookEvent<PlatformEvents["notification.opened"], "notification.opened"> | WebhookEvent<PlatformEvents["notification.read"], "notification.read"> | WebhookEvent<PlatformEvents["notification.received"], "notification.received"> | WebhookEvent<PlatformEvents["notification.rejected"], "notification.rejected"> | WebhookEvent<PlatformEvents["notification.sent"], "notification.sent"> | WebhookEvent<PlatformEvents["notification.unconfirmed"], "notification.unconfirmed"> | WebhookEvent<PlatformEvents["notification.undelivered"], "notification.undelivered"> | WebhookEvent<PlatformEvents["notification.uninstalled"], "notification.uninstalled"> | WebhookEvent<PlatformEvents["purchases.catalog.applied"], "purchases.catalog.applied"> | WebhookEvent<PlatformEvents["purchases.catalog.changed"], "purchases.catalog.changed"> | WebhookEvent<PlatformEvents["purchases.coupon.redeemed"], "purchases.coupon.redeemed"> | WebhookEvent<PlatformEvents["purchases.credits.depleted"], "purchases.credits.depleted"> | WebhookEvent<PlatformEvents["purchases.credits.low"], "purchases.credits.low"> | WebhookEvent<PlatformEvents["purchases.customer.changed"], "purchases.customer.changed"> | WebhookEvent<PlatformEvents["purchases.customer.erased"], "purchases.customer.erased"> | WebhookEvent<PlatformEvents["purchases.customer.merged"], "purchases.customer.merged"> | WebhookEvent<PlatformEvents["purchases.entitlement.changed"], "purchases.entitlement.changed"> | WebhookEvent<PlatformEvents["purchases.offer.redeemed"], "purchases.offer.redeemed"> | WebhookEvent<PlatformEvents["purchases.ownership.transferred"], "purchases.ownership.transferred"> | WebhookEvent<PlatformEvents["purchases.paywall.published"], "purchases.paywall.published"> | WebhookEvent<PlatformEvents["purchases.purchase.completed"], "purchases.purchase.completed"> | WebhookEvent<PlatformEvents["purchases.quota.exhausted"], "purchases.quota.exhausted"> | WebhookEvent<PlatformEvents["purchases.quota.threshold"], "purchases.quota.threshold"> | WebhookEvent<PlatformEvents["purchases.refund.changed"], "purchases.refund.changed"> | WebhookEvent<PlatformEvents["purchases.store.changed"], "purchases.store.changed"> | WebhookEvent<PlatformEvents["purchases.subscription.changed"], "purchases.subscription.changed"> | WebhookEvent<PlatformEvents["session.ended"], "session.ended"> | WebhookEvent<PlatformEvents["stores.action.changed"], "stores.action.changed"> | WebhookEvent<PlatformEvents["stores.app.changed"], "stores.app.changed"> | WebhookEvent<PlatformEvents["stores.apple.changed"], "stores.apple.changed"> | WebhookEvent<PlatformEvents["stores.delivery.changed"], "stores.delivery.changed"> | WebhookEvent<PlatformEvents["stores.delivery.requested"], "stores.delivery.requested"> | WebhookEvent<PlatformEvents["stores.google.changed"], "stores.google.changed"> | WebhookEvent<PlatformEvents["stores.group.changed"], "stores.group.changed"> | WebhookEvent<PlatformEvents["stores.package.changed"], "stores.package.changed"> | WebhookEvent<PlatformEvents["stores.version.changed"], "stores.version.changed"> | WebhookEvent<PlatformEvents["stores.version.reviewed"], "stores.version.reviewed"> | WebhookEvent<PlatformEvents["user.converted"], "user.converted"> | WebhookEvent<PlatformEvents["user.deleted"], "user.deleted"> | WebhookEvent<PlatformEvents["user.locale_changed"], "user.locale_changed"> | WebhookEvent<PlatformEvents["user.permissions_changed"], "user.permissions_changed">;
@@ -123,7 +123,7 @@ export type InstallationLink = {
123
123
  user_token: string;
124
124
  };
125
125
  /**
126
- * Connects an installation another project of the same organization connected, on Studio's word that both are one organization's (the X-Palbase-Studio-Share header, which Studio's backend alone signs; Studio's call that connects an organization's installation asks it) — no GitHub user's token. The project reaches what that project's GitHub user can push to, as it does.
126
+ * Connects an installation another project of the same organization connected, on the registry's word that both are one organization's (the X-Palbase-Studio-Share header, which the registry alone signs, for an admin of both; Studio's call that connects an organization's installation asks it) — no GitHub user's token. The project reaches what that project's GitHub user can push to, as it does.
127
127
  */
128
128
  export type InstallationShare = {
129
129
  installation_id: number;
@@ -1345,6 +1345,41 @@ export type TaskType = {
1345
1345
  export type TaskTypeList = {
1346
1346
  types: TaskType[];
1347
1347
  };
1348
+ /**
1349
+ * A template written for a test user — its rows by table, as the machine's program said — or why it was not (error: no_template, not_a_test_user, template_failed, template_timeout, machine_unavailable, then a colon and why). again: answered from what was kept when it was written before; the machine was not asked again.
1350
+ */
1351
+ export type TemplateOutcome = {
1352
+ name: string;
1353
+ rows?: {
1354
+ [key: string]: number;
1355
+ };
1356
+ error?: string;
1357
+ again?: boolean;
1358
+ };
1359
+ /**
1360
+ * A test user made with a template: its sign-in, shown this once, and what became of the template. The user is made whatever came of the template.
1361
+ */
1362
+ export type TemplatedUser = {
1363
+ user_id: string;
1364
+ email: string;
1365
+ /**
1366
+ * Its password, shown this once (a test fixture).
1367
+ */
1368
+ password: string;
1369
+ /**
1370
+ * With with_tokens: an access token for it (a test fixture).
1371
+ */
1372
+ access_token?: string;
1373
+ template: TemplateOutcome;
1374
+ };
1375
+ export type TemplatedUserList = {
1376
+ users: TemplatedUser[];
1377
+ };
1378
+ export type TemplatedUsersAsked = {
1379
+ count?: number;
1380
+ template: string;
1381
+ with_tokens?: boolean;
1382
+ };
1348
1383
  /** Palbase Machines */
1349
1384
  export declare function client(t: Transport): {
1350
1385
  /**
@@ -1412,7 +1447,7 @@ export declare function client(t: Transport): {
1412
1447
  /**
1413
1448
  * Share an installation of the organization
1414
1449
  *
1415
- * Connects an installation of Palbase Cloud that another project of the same organization connected, on Studio's word (X-Palbase-Studio-Share): a program that opens a project for each product connects its own installation to each, with no person's GitHub token. The project reaches the repositories of it the GitHub user who connected it there can push to — and, as with every connection, one created or added to the installation later once that user can push to it (asked when a machine is built from it, and when GitHub says repositories were added). Refused without Studio's word, or when that project has not connected the installation; and when this project connected it otherwise — for other repositories, for all of them where this names some (or some where this names none), or by another GitHub user: linking again never widens, narrows or hands over a connection, so it is disconnected and connected anew. The same share again is as it was.
1450
+ * Connects an installation of Palbase Cloud that another project of the same organization connected, on the registry's word (X-Palbase-Studio-Share), which Studio asks the registry for an admin of both projects: a program that opens a project for each product connects its own installation to each, with no person's GitHub token. The project reaches the repositories of it the GitHub user who connected it there can push to — and, as with every connection, one created or added to the installation later once that user can push to it (asked when a machine is built from it, and when GitHub says repositories were added). Refused without the registry's word, or when that project has not connected the installation; and when this project connected it otherwise — for other repositories, for all of them where this names some (or some where this names none), or by another GitHub user: linking again never widens, narrows or hands over a connection, so it is disconnected and connected anew. The same share again is as it was.
1416
1451
  */
1417
1452
  shareInstallation(input: {
1418
1453
  body: InstallationShare; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
@@ -1877,5 +1912,42 @@ export declare function client(t: Transport): {
1877
1912
  }; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
1878
1913
  signal?: AbortSignal;
1879
1914
  }): Promise<Reply<200, TaskTypeList>>;
1915
+ /**
1916
+ * Make test users with a template's data
1917
+ *
1918
+ * Makes 1 to 10 test users (auth's: their tokens say test: true) and has the machine's own program write a template's data for each — the backend's seed for one account (palbase/backend's @TestUserTemplate), for a person or an agent to sign in and see a screen with its data. The platform calls the program for each user — POST /_palbase/test-user-templates/<template> on the machine's own port, with {"user": {"id", "email"}, "template"}, signed as a cron's call is, waking the machine for it; the program writes the template in one transaction and answers {"rows": {table: count}}, or refuses a user auth does not say is a test user (403). A user is made whatever came of its template: its template answers its error by name. The same user and template asked again (POST …/test-users/{user}/templates/{template}) answers what was kept, the machine not asked again. The users' passwords (and with with_tokens their access tokens) are test fixtures, shown this once, as auth's test users' are. 409 when auth makes no more test users for the project; 429 quota_exceeded, and no user made, when the project's machines are not run now (its machine time for the period used up, or the project deleted).
1919
+ */
1920
+ makeTemplatedTestUsers(input: {
1921
+ path: {
1922
+ name: string;
1923
+ };
1924
+ body: TemplatedUsersAsked; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
1925
+ signal?: AbortSignal;
1926
+ }): Promise<Reply<201, TemplatedUserList>>;
1927
+ /**
1928
+ * Write a template for a test user
1929
+ *
1930
+ * Has the machine's program write a template for a test user this machine made with one (POST /machines/{name}/test-users) — answered from what was kept when it wrote that template for that user before, the machine not asked again (again: true). 429 quota_exceeded when the project's machines are not run now and the template was not written before. 404 when the user is no test user this machine made with a template: a test user is the machine's that made it, another machine of the project neither writes for it nor deletes it.
1931
+ */
1932
+ templateTestUser(input: {
1933
+ path: {
1934
+ name: string; /** The test user's id, as the users made with a template were answered. */
1935
+ user: string; /** The template's name, as the machine's program names it (@TestUserTemplate): lowercase letters, digits, _ and -, starting with a letter, 64 at most. */
1936
+ template: string;
1937
+ }; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
1938
+ signal?: AbortSignal;
1939
+ }): Promise<Reply<200, TemplateOutcome>>;
1940
+ /**
1941
+ * Delete a test user made with a template
1942
+ *
1943
+ * Has the machine's program undo each template the user was written with — POST /_palbase/test-user-templates/<template>/undo, signed as the template's call; a program with no undo (404) leaves it to its user.deleted — then deletes the user. 502 undo_failed when the program did not undo one: the user is kept, for the delete to be asked again. 429 quota_exceeded, the user kept, when the project's machines are not run now. 404 when the user is no test user this machine made with a template: a test user is the machine's that made it, another machine of the project neither writes for it nor deletes it.
1944
+ */
1945
+ deleteTemplatedTestUser(input: {
1946
+ path: {
1947
+ name: string; /** The test user's id, as the users made with a template were answered. */
1948
+ user: string;
1949
+ }; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
1950
+ signal?: AbortSignal;
1951
+ }): Promise<Reply<204, undefined>>;
1880
1952
  };
1881
1953
  export type Client = ReturnType<typeof client>;