palbase 0.10.2 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/index.js +2 -2
- package/dist/backend/engine.js +2 -2
- package/dist/backend/env.js +1 -1
- package/dist/backend/index.js +11 -11
- package/dist/backend/stack.js +1 -1
- package/dist/backend/test.js +2 -2
- package/dist/chunks/26UTOC32.js +2 -0
- package/dist/chunks/{IW34A4TV.js → 3453XVQL.js} +2 -2
- package/dist/chunks/{7PBQ3LI2.js → 3VY3ZZCI.js} +1 -1
- package/dist/chunks/{MAPLN2FY.js → 43VM626B.js} +1 -1
- package/dist/chunks/{BMCC423W.js → 7WIMZTYB.js} +2 -2
- package/dist/chunks/{ZOAWYN6L.js → AFFE3Q5O.js} +2 -2
- package/dist/chunks/{RYWIWH4U.js → BUAGC2PT.js} +1 -1
- package/dist/chunks/{5TVS7F23.js → BUYFMLTF.js} +2 -2
- package/dist/chunks/{O5CJJFEU.js → EEWP43KI.js} +1 -1
- package/dist/chunks/EWBRYA7P.js +2 -0
- package/dist/chunks/{S4F256W2.js → FVLHT7UQ.js} +2 -2
- package/dist/chunks/{SCXHU5B7.js → KNPQNBC2.js} +2 -2
- package/dist/chunks/{D2UQQWJC.js → KW6ODEYS.js} +1 -1
- package/dist/chunks/{5NZGW67E.js → LYEEW4UG.js} +2 -2
- package/dist/chunks/{SBVBCENU.js → NGE3D2K4.js} +2 -2
- package/dist/chunks/Q3S76MYJ.js +2 -0
- package/dist/chunks/{QTAPRS4Q.js → R3EIGCWV.js} +2 -2
- package/dist/chunks/{XJEZB4MI.js → S2KRJF6J.js} +2 -2
- package/dist/chunks/{6JUQZ4D4.js → V2FEPVVD.js} +2 -2
- package/dist/chunks/WLAO2QSR.js +20 -0
- package/dist/chunks/{L4SCG6HT.js → ZZG7ICDG.js} +2 -2
- package/dist/cli.js +124 -122
- package/dist/refuse/ai.js +1 -1
- package/dist/refuse/backend.js +1 -1
- package/dist/refuse/server.js +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/testing.js +2 -2
- package/dist/web/index.js +2 -2
- package/dist/web/message.js +2 -2
- package/dist/web/palbe.js +2 -2
- package/dist/web/paywall.js +2 -2
- package/dist/web/push-sw.js +1 -1
- package/dist/web/ssr.js +2 -2
- package/dist/web/vite.js +2 -2
- package/package.json +2 -2
- package/types/backend/src/database.d.ts +8 -1
- package/types/backend/src/engine-db.d.ts +3 -1
- package/types/backend/src/engine.d.ts +2 -0
- package/types/backend/src/idempotency.d.ts +136 -0
- package/types/internal/src/modules/auth.d.ts +25 -8
- package/types/internal/src/modules/purchases.d.ts +39 -3
- package/types/internal/src/modules/secrets.d.ts +138 -3
- package/types/internal/src/modules/stores.d.ts +30 -1
- package/types/server/src/fields.d.ts +62 -0
- package/types/server/src/index.d.ts +1 -0
- package/types/server/src/server.d.ts +8 -0
- package/types/server/src/testing.d.ts +8 -0
- package/dist/chunks/I2TY2GLY.js +0 -2
- package/dist/chunks/PKBCMWTM.js +0 -2
- package/dist/chunks/QCKQXIQV.js +0 -20
package/dist/ai/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.
|
|
2
|
-
import{a,b,c,d,e,f}from"../chunks/
|
|
1
|
+
/*! palbase 0.11.1 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{a,b,c,d,e,f}from"../chunks/NGE3D2K4.js";import"../chunks/LYEEW4UG.js";import"../chunks/EEWP43KI.js";import"../chunks/7WIMZTYB.js";import"../chunks/R3EIGCWV.js";import"../chunks/KNPQNBC2.js";import"../chunks/BUAGC2PT.js";import"../chunks/43VM626B.js";export{e as AIResponseError,b as AISchemaError,d as ToolError,f as createAI,a as partial,c as prepare};
|
package/dist/backend/engine.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.
|
|
2
|
-
import{ha as
|
|
1
|
+
/*! palbase 0.11.1 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{ha as w,la as h}from"../chunks/WLAO2QSR.js";import"../chunks/S2KRJF6J.js";import"../chunks/Q3S76MYJ.js";import"../chunks/26UTOC32.js";import"../chunks/NGE3D2K4.js";import"../chunks/LYEEW4UG.js";import"../chunks/EEWP43KI.js";import"../chunks/7WIMZTYB.js";import"../chunks/R3EIGCWV.js";import"../chunks/KNPQNBC2.js";import"../chunks/BUAGC2PT.js";import"../chunks/43VM626B.js";import{binding as R,createDatabase as v}from"palgres";var y=new WeakMap;function q(p,e,a){if(!a?.schemas?.length)throw new TypeError("createRequestDatabase(sql, identity, { schemas }): the engine compiles each call against the app's schemas \u2014 pass the schema files' default exports");let u=a.schemas,n=y.get(p);n||y.set(p,n=new Map);let r=n.get(u);r||n.set(u,r=new Map);let o=e.role===e.serviceRole?"service":e.role==="anon"?"anon":"authenticated",g=o==="service"?{service:e.serviceRole}:{[o]:e.role,service:e.serviceRole},f=`${o}\0${e.role}\0${e.serviceRole}`,i=r.get(f);i||(i=v({sql:p,schemas:u,binding:R(0,!0),roles:g,...a.fields!==void 0?{fields:a.fields}:{}}),r.set(f,i));let b=JSON.parse(e.claimsJson),m=i.then(s=>s.request({role:o,claims:b},{diagnostics:a.diagnostics,signal:a.signal})),d=s=>new Proxy(()=>{},{apply:async(t,D,c)=>{let l=(await m).client;return s(l).apply(l,c)}});return{client:new Proxy({},{get(s,t){if(t!=="then")return t==="diagnostics"?()=>null:t==="asService"?()=>new Proxy({},{get:(D,c)=>c==="then"?void 0:d(l=>l.asService()[c])}):d(D=>D[t])}}),commit:async()=>(await m).commit(),rollback:async s=>(await m).rollback(s)}}export{w as createApp,q as createRequestDatabase,h as makeMemoryCache};
|
package/dist/backend/env.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
/*! palbase 0.
|
|
1
|
+
/*! palbase 0.11.1 — Palbase SDK License (see LICENSE) */
|
package/dist/backend/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
/*! palbase 0.
|
|
2
|
-
import{$ as $t,A as B,B as ct,C as dt,D as pt,E as ht,F as gt,G as bt,H as mt,I as ft,J as yt,K as wt,L as Pt,M as St,N as vt,O as At,P as kt,Q as Et,R as xt,S as Tt,T as Ot,U as _t,V as Rt,W as Ct,X as re,Y as Bt,Z as Ft,_ as Mt,a as Q,aa as It,b as X,ba as Ut,c as Z,ca as Lt,d as je,da as Dt,e as Ne,ea as jt,f as qe,fa as F,g as We,ga as qt,h as Ve,ha as M,i as Ge,ia as G,j as Ke,ja as Wt,k as ze,ka as Vt,l as He,m as Ye,n as Je,o as Qe,p as Xe,q as Ze,r as et,s as tt,t as rt,u as st,v as nt,w as at,x as ot,y as it,z as lt}from"../chunks/QCKQXIQV.js";import{a as ne}from"../chunks/D2UQQWJC.js";import{a as T,b as ee,c as te,f as g,g as ut,h as c,j as se,k as Nt}from"../chunks/XJEZB4MI.js";import{a as V,g as Le,h as De,i as H,j as C,q as Y,r as J}from"../chunks/PKBCMWTM.js";import"../chunks/SBVBCENU.js";import"../chunks/5NZGW67E.js";import"../chunks/O5CJJFEU.js";import{m as Ue}from"../chunks/BMCC423W.js";import"../chunks/QTAPRS4Q.js";import{b as A,c as W}from"../chunks/SCXHU5B7.js";import"../chunks/RYWIWH4U.js";import"../chunks/MAPLN2FY.js";import"reflect-metadata";import{existsSync as K,writeFileSync as vr,writeSync as Ar}from"node:fs";import{createServer as kr}from"node:http";import{dirname as k,join as z,resolve as Te}from"node:path";import{Readable as Er}from"node:stream";var Gt=2e3,Kt=1e4,zt=/^[A-Za-z0-9_-]{1,64}$/,Ht=512,$=class{linesPerSecond;batchSize;flushMs;maxPending;sendMs;shutdownMs;now;tokens;refilled;unlogged=0;unloggedSince;pending=[];timer;sending;inFlight;pausedUntil=0;lastSendWarning=0;sink;constructor(e,r={}){this.sink=e,this.linesPerSecond=r.linesPerSecond??10,this.batchSize=Math.min(100,r.batchSize??100),this.flushMs=r.flushMs??2e3,this.maxPending=r.maxPending??2e3,this.sendMs=r.sendMs??Kt,this.shutdownMs=r.shutdownMs??Gt,this.now=r.now??Date.now,this.tokens=this.linesPerSecond,this.refilled=this.now(),this.unloggedSince=this.refilled}record(e){this.log(e),this.sink&&this.trace(e)}async flush(){this.timer&&clearTimeout(this.timer),this.timer=void 0;let e=!1,r,s=new Promise(a=>r=a),n=setTimeout(()=>{e=!0,r()},this.shutdownMs);try{for(;!e&&(this.pending.length>0||this.sending)&&(await Promise.race([this.sending??this.send(),s]),!(this.now()<this.pausedUntil)););}finally{clearTimeout(n)}e&&this.letGo()}letGo(){let e=this.inFlight,r=(e?.traces??0)+this.pending.length;this.pending=[],e&&(e.letGo=!0,e.call.abort(new Error(`analytics did not answer within the ${this.shutdownMs} ms a flush waits`))),r>0&&c.warn(`[palbase] request traces were not sent to analytics within the ${this.shutdownMs} ms a flush waits; ${r} dropped`)}log(e){let r=this.now();if(this.tokens=Math.min(this.linesPerSecond,this.tokens+(r-this.refilled)/1e3*this.linesPerSecond),this.refilled=r,this.unlogged>0&&r-this.unloggedSince>=6e4&&(c.info(`[palbase] ${this.unlogged} more requests answered in the last minute than the log keeps a line for (Analytics \u203A Network has every one)`),this.unlogged=0,this.unloggedSince=r),this.tokens<1){this.unlogged===0&&(this.unloggedSince=r),this.unlogged++;return}this.tokens-=1;let s=e.status>=500?"error":e.status>=400&&e.status!==499?"warn":"info",n=Math.round(e.durationMs*10)/10;c[s](`${e.method} ${e.path} ${e.status} ${n}ms`,{route:e.endpoint,status:e.status,duration_ms:n,...e.userId?{user_id:e.userId}:{}})}trace(e){this.pending.length>=this.maxPending&&this.pending.shift(),this.pending.push({request_id:zt.test(e.requestId)?e.requestId:e.requestId.replace(/[^A-Za-z0-9_-]/g,"_").slice(0,64)||"unnamed",source:"backend",endpoint:e.endpoint.slice(0,Ht),method:e.method,status:e.status,duration_ms:Math.max(0,Math.round(e.durationMs)),timestamp:this.now(),...e.userId?{distinct_id:e.userId}:{}}),this.pending.length>=this.batchSize&&!this.sending?this.send():!this.timer&&!this.sending&&this.schedule(this.flushMs)}schedule(e){this.timer=setTimeout(()=>{this.send()},e),this.timer.unref?.()}send(){if(this.timer&&clearTimeout(this.timer),this.timer=void 0,this.sending||this.pending.length===0||this.now()<this.pausedUntil||!this.sink)return this.sending??Promise.resolve();let e=this.pending.splice(0,this.batchSize),r=this.sink,s={call:new AbortController,traces:e.length,letGo:!1};this.inFlight=s;let n=setTimeout(()=>s.call.abort(new Error(`analytics did not answer in ${this.sendMs} ms`)),this.sendMs);return n.unref?.(),this.sending=(async()=>{try{await r.sendTraceBatch({body:{traces:e},signal:s.call.signal})}catch(a){if(s.letGo)return;let i=a.status,o=i??(s.call.signal.aborted?`no answer in ${this.sendMs} ms`:"unreachable"),d=a.retryAfter;this.pausedUntil=this.now()+(typeof d=="number"&&d>0?d*1e3:i===429?1e3:5e3),this.now()-this.lastSendWarning>6e4&&(this.lastSendWarning=this.now(),c.warn(`[palbase] request traces were not sent to analytics (${o}); ${e.length} dropped`,{error:a}))}finally{if(clearTimeout(n),this.sending=void 0,this.inFlight=void 0,this.pending.length>0){let a=Math.max(0,this.pausedUntil-this.now());this.schedule(this.pending.length>=this.batchSize?a:Math.max(a,this.flushMs))}}})(),this.sending}};import{createHmac as Yt}from"node:crypto";import{bind as Jt,bunDriver as Qt,createDatabase as Xt,envBlock as Zt,createSearchWorker as er,cutOff as tr,forgetUser as rr,MigrationOpen as sr,MigrationRefused as nr,Migrator as le,renewingBunPool as ae,VersionNotMigrated as ar}from"palgres";import{toModel as ce}from"palgres/dsl";var or=["start","complete","rollback","plan","status","types"],ir=/^(deploy|cli:[^\u0000-\u001f\u007f]{1,200})$/u;function de(t){let e=t.PALBASE_DB_MIGRATE;if(!(e===void 0||e==="")){if(!or.includes(e))throw new Error(`[palbase] PALBASE_DB_MIGRATE is start, complete, rollback, plan, status or types, not ${e}`);return e}}function ue(t){let e=Array.isArray(t.schemas)?t.schemas:[t.schemas];for(let r of e)if(r.name===F.name)throw new Error(`[palbase] db.schemas: the ${F.name} schema is the framework's own (its tables are migrated with the app's) \u2014 name the app's schema otherwise`);return[...e,F]}function U(t){return ce(ue(t))}function lr(t){return t.tables.some(e=>e.search!==void 0)}function L(t){return t.tables.some(e=>!e.ignored&&e.columns.some(r=>r.user!==void 0&&!r.ignored))}function pe(t){let e=t.PALBASE_DB_CONNECTIONS;if(e===void 0||e==="")return 31;let r=Number(e);if(!Number.isSafeInteger(r)||r<4)throw new Error(`[palbase] PALBASE_DB_CONNECTIONS is how many connections the app may hold to its database, 4 at least (a request's transaction, the two further ones it may hold, one to cancel with) \u2014 not ${e}`);return r}function cr(t){if(!Number.isSafeInteger(t)||t<3)throw new Error(`[palbase] db.driver: a pool of ${t} connection(s) \u2014 the engine needs at least 3: one request's transaction and the two further ones it may hold`);let e=Math.floor(t/3);return{concurrency:e,nestedConcurrency:e*2}}var oe=5;function he(t,e){if(t.driver)return t.driver;let r=globalThis.Bun;if(!r)throw new Error("[palbase] db.driver: off Bun there is no SQL client built in \u2014 give one: postgres.js with { types: POSTGRES_JS_TYPES }, its engine postgresJsDriver(pool, control)");let s=e-1;return n=>{let a=ae(()=>new r.SQL({url:n,prepare:!1,max:s})),i=ae(()=>new r.SQL({url:n,prepare:!1,max:1}));return{pool:{reserve:()=>a.reserve(),unsafe:(o,d)=>a.unsafe(o,d),begin:o=>a.current.begin(o)},engine:Qt(a,i),poolSize:s,close:async()=>{await a.close({timeout:oe}),await i.close({timeout:oe})}}}}async function ge(t){return t==="rollback"?(c.info("[palbase] migrate rollback: this app declares no database; nothing of it to take back"),await O(t,{state:"none"}),0):(c.error(`[palbase] migrate ${t}: this app declares no database \u2014 PalbaseFactory.create(\u2026, { db: { schemas } })`),1)}async function be(t,e){if(!t)return c.error("[palbase] db types: this app declares no database \u2014 PalbaseFactory.create(\u2026, { db: { schemas } })"),1;let r=Array.isArray(t.schemas)?t.schemas:[t.schemas];return await O("types",Zt(r,{module:"palbase/backend/env"}),e),0}async function me(t,e,r){let s=e.PALBASE_DB_OWNER_URL;if(!s)return c.error("[palbase] PALBASE_DB_MIGRATE without PALBASE_DB_OWNER_URL: a migration runs as the tables' owner"),1;let n=e.PALBASE_DB_MIGRATION_BY||"deploy";if(!ir.test(n))return c.error("[palbase] PALBASE_DB_MIGRATION_BY is deploy, or cli:<who>"),1;let a=he(t,pe(e)),i=a(s),o,d=l=>c.error(`[palbase] migrate ${r}: ${l}`);try{let l=U(t),u=new le(i.pool,{log:h=>{/ is held by others | held by writers/.test(h)&&(o=h.trim()),c.info(h)},shadow:h=>{let y=new URL(s);y.pathname=`/${h}`;let b=a(y.toString());return{reserve:()=>b.pool.reserve(),end:()=>b.close()}},openedBy:n});if(r==="plan"){let h=await u.plan(l);return await O(r,h),h.refusals.length>0?1:0}if(r==="status")return await O(r,await u.status()),0;let p=r==="start"?await dr(u,l,n):r==="complete"?await u.complete():await u.rollback();return c.info(`[palbase] migrate ${r}: done`,{result:p}),await O(r,p),0}catch(l){return l instanceof nr?(c.error(`[palbase] migrate ${r}: refused`,{refusals:l.refusals}),d(`refused \u2014 ${l.refusals.join("; ")}`),1):tr(l)?(c.error(`[palbase] migrate ${r}: cut off; run again, it goes on from where it stopped`,{error:l}),d(`cut off \u2014 ${o??ie(l)}`),75):(c.error(`[palbase] migrate ${r}: failed`,{error:l}),d(`failed \u2014 ${ie(l)}`),1)}finally{await i.close().catch(()=>{})}}async function dr(t,e,r){try{return await t.start(e)}catch(s){if(!(s instanceof sr)||r!=="deploy"||!s.openedBy?.startsWith("cli:"))throw s;return c.warn(`[palbase] migrate start: the migration ${s.openedBy} opened (version ${s.to}) gives way to this release \u2014 rolled back first`),await t.rollback(),await t.start(e)}}var ur=(t,e)=>{process.stdout.write(t,()=>e())};function O(t,e,r=ur){return new Promise(s=>r(`${JSON.stringify({palbase_migrate:t,result:e})}
|
|
3
|
-
`,
|
|
4
|
-
`)[0].slice(0,300)||(t instanceof Error?t.name:"unknown")}async function
|
|
5
|
-
`)),this.name="SchemaNotPushed",this.digest=e,this.plan=
|
|
6
|
-
- ${
|
|
7
|
-
- `)}`);return{url:a,projectId:i,secretKey:o,webhookSecret:
|
|
8
|
-
${
|
|
1
|
+
/*! palbase 0.11.1 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{$ as It,A as F,B as dt,C as ut,D as ht,E as ft,F as gt,G as bt,H as mt,I as yt,J as wt,K as Pt,L as St,M as vt,N as At,O as kt,P as Et,Q as Tt,R as _t,S as xt,T as Rt,U as Ot,V as Ct,W as Bt,X as se,Y as Ft,Z as Mt,_ as $t,a as Q,aa as Lt,b as X,ba as Ut,c as Z,ca as Dt,d as Ne,da as jt,e as qe,ea as Nt,f as We,fa as M,g as Ke,ga as Wt,h as Ve,ha as $,i as Ge,ia as V,j as ze,ja as Kt,k as He,ka as Vt,l as Ye,m as Je,n as Qe,o as Xe,p as Ze,q as et,r as tt,s as st,t as rt,u as nt,v as at,w as ot,x as it,y as lt,z as ct}from"../chunks/WLAO2QSR.js";import{a as ne}from"../chunks/KW6ODEYS.js";import{a as x,b as ee,c as te,f as b,g as pt,h as d,j as re,k as qt}from"../chunks/S2KRJF6J.js";import{a as _,g as De,h as je,i as H,j as B,q as Y,r as J}from"../chunks/Q3S76MYJ.js";import"../chunks/26UTOC32.js";import"../chunks/NGE3D2K4.js";import"../chunks/LYEEW4UG.js";import"../chunks/EEWP43KI.js";import{m as Ue}from"../chunks/7WIMZTYB.js";import"../chunks/R3EIGCWV.js";import{b as A,c as K}from"../chunks/KNPQNBC2.js";import"../chunks/BUAGC2PT.js";import"../chunks/43VM626B.js";import"reflect-metadata";import{existsSync as G,writeFileSync as Es,writeSync as Ts}from"node:fs";import{createServer as _s}from"node:http";import{dirname as k,join as z,resolve as xe}from"node:path";import{Readable as xs}from"node:stream";var Gt=2e3,zt=1e4,Ht=/^[A-Za-z0-9_-]{1,64}$/,Yt=512,I=class{linesPerSecond;batchSize;flushMs;maxPending;sendMs;shutdownMs;now;tokens;refilled;unlogged=0;unloggedSince;pending=[];timer;sending;inFlight;pausedUntil=0;lastSendWarning=0;sink;constructor(e,s={}){this.sink=e,this.linesPerSecond=s.linesPerSecond??10,this.batchSize=Math.min(100,s.batchSize??100),this.flushMs=s.flushMs??2e3,this.maxPending=s.maxPending??2e3,this.sendMs=s.sendMs??zt,this.shutdownMs=s.shutdownMs??Gt,this.now=s.now??Date.now,this.tokens=this.linesPerSecond,this.refilled=this.now(),this.unloggedSince=this.refilled}record(e){this.log(e),this.sink&&this.trace(e)}async flush(){this.timer&&clearTimeout(this.timer),this.timer=void 0;let e=!1,s,r=new Promise(a=>s=a),n=setTimeout(()=>{e=!0,s()},this.shutdownMs);try{for(;!e&&(this.pending.length>0||this.sending)&&(await Promise.race([this.sending??this.send(),r]),!(this.now()<this.pausedUntil)););}finally{clearTimeout(n)}e&&this.letGo()}letGo(){let e=this.inFlight,s=(e?.traces??0)+this.pending.length;this.pending=[],e&&(e.letGo=!0,e.call.abort(new Error(`analytics did not answer within the ${this.shutdownMs} ms a flush waits`))),s>0&&d.warn(`[palbase] request traces were not sent to analytics within the ${this.shutdownMs} ms a flush waits; ${s} dropped`)}log(e){let s=this.now();if(this.tokens=Math.min(this.linesPerSecond,this.tokens+(s-this.refilled)/1e3*this.linesPerSecond),this.refilled=s,this.unlogged>0&&s-this.unloggedSince>=6e4&&(d.info(`[palbase] ${this.unlogged} more requests answered in the last minute than the log keeps a line for (Analytics \u203A Network has every one)`),this.unlogged=0,this.unloggedSince=s),this.tokens<1){this.unlogged===0&&(this.unloggedSince=s),this.unlogged++;return}this.tokens-=1;let r=e.status>=500?"error":e.status>=400&&e.status!==499?"warn":"info",n=Math.round(e.durationMs*10)/10;d[r](`${e.method} ${e.path} ${e.status} ${n}ms`,{route:e.endpoint,status:e.status,duration_ms:n,...e.userId?{user_id:e.userId}:{}})}trace(e){this.pending.length>=this.maxPending&&this.pending.shift(),this.pending.push({request_id:Ht.test(e.requestId)?e.requestId:e.requestId.replace(/[^A-Za-z0-9_-]/g,"_").slice(0,64)||"unnamed",source:"backend",endpoint:e.endpoint.slice(0,Yt),method:e.method,status:e.status,duration_ms:Math.max(0,Math.round(e.durationMs)),timestamp:this.now(),...e.userId?{distinct_id:e.userId}:{}}),this.pending.length>=this.batchSize&&!this.sending?this.send():!this.timer&&!this.sending&&this.schedule(this.flushMs)}schedule(e){this.timer=setTimeout(()=>{this.send()},e),this.timer.unref?.()}send(){if(this.timer&&clearTimeout(this.timer),this.timer=void 0,this.sending||this.pending.length===0||this.now()<this.pausedUntil||!this.sink)return this.sending??Promise.resolve();let e=this.pending.splice(0,this.batchSize),s=this.sink,r={call:new AbortController,traces:e.length,letGo:!1};this.inFlight=r;let n=setTimeout(()=>r.call.abort(new Error(`analytics did not answer in ${this.sendMs} ms`)),this.sendMs);return n.unref?.(),this.sending=(async()=>{try{await s.sendTraceBatch({body:{traces:e},signal:r.call.signal})}catch(a){if(r.letGo)return;let i=a.status,o=i??(r.call.signal.aborted?`no answer in ${this.sendMs} ms`:"unreachable"),c=a.retryAfter;this.pausedUntil=this.now()+(typeof c=="number"&&c>0?c*1e3:i===429?1e3:5e3),this.now()-this.lastSendWarning>6e4&&(this.lastSendWarning=this.now(),d.warn(`[palbase] request traces were not sent to analytics (${o}); ${e.length} dropped`,{error:a}))}finally{if(clearTimeout(n),this.sending=void 0,this.inFlight=void 0,this.pending.length>0){let a=Math.max(0,this.pausedUntil-this.now());this.schedule(this.pending.length>=this.batchSize?a:Math.max(a,this.flushMs))}}})(),this.sending}};import{createHmac as Jt}from"node:crypto";import{bind as Qt,bunDriver as Xt,createDatabase as Zt,envBlock as es,createSearchWorker as ts,cutOff as ss,forgetUser as rs,MigrationOpen as ns,MigrationRefused as as,Migrator as ce,renewingBunPool as ae,VersionNotMigrated as os}from"palgres";import{toModel as de}from"palgres/dsl";var is=["start","complete","rollback","plan","status","types"],ls=/^(deploy|cli:[^\u0000-\u001f\u007f]{1,200})$/u;function ue(t){let e=t.PALBASE_DB_MIGRATE;if(!(e===void 0||e==="")){if(!is.includes(e))throw new Error(`[palbase] PALBASE_DB_MIGRATE is start, complete, rollback, plan, status or types, not ${e}`);return e}}function pe(t){let e=Array.isArray(t.schemas)?t.schemas:[t.schemas];for(let s of e)if(s.name===M.name)throw new Error(`[palbase] db.schemas: the ${M.name} schema is the framework's own (its tables are migrated with the app's) \u2014 name the app's schema otherwise`);return[...e,M]}function U(t){return de(pe(t))}function cs(t){return t.tables.some(e=>e.search!==void 0)}function D(t){return t.tables.some(e=>!e.ignored&&e.columns.some(s=>s.user!==void 0&&!s.ignored))}function he(t){let e=t.PALBASE_DB_CONNECTIONS;if(e===void 0||e==="")return 31;let s=Number(e);if(!Number.isSafeInteger(s)||s<4)throw new Error(`[palbase] PALBASE_DB_CONNECTIONS is how many connections the app may hold to its database, 4 at least (a request's transaction, the two further ones it may hold, one to cancel with) \u2014 not ${e}`);return s}function ds(t){if(!Number.isSafeInteger(t)||t<3)throw new Error(`[palbase] db.driver: a pool of ${t} connection(s) \u2014 the engine needs at least 3: one request's transaction and the two further ones it may hold`);let e=Math.floor(t/3);return{concurrency:e,nestedConcurrency:e*2}}var oe=5;function fe(t,e){if(t.driver)return t.driver;let s=globalThis.Bun;if(!s)throw new Error("[palbase] db.driver: off Bun there is no SQL client built in \u2014 give one: postgres.js with { types: POSTGRES_JS_TYPES }, its engine postgresJsDriver(pool, control)");let r=e-1;return n=>{let a=ae(()=>new s.SQL({url:n,prepare:!1,max:r})),i=ae(()=>new s.SQL({url:n,prepare:!1,max:1}));return{pool:{reserve:()=>a.reserve(),unsafe:(o,c)=>a.unsafe(o,c),begin:o=>a.current.begin(o)},engine:Xt(a,i),poolSize:r,close:async()=>{await a.close({timeout:oe}),await i.close({timeout:oe})}}}}async function ge(t){return t==="rollback"?(d.info("[palbase] migrate rollback: this app declares no database; nothing of it to take back"),await R(t,{state:"none"}),0):(d.error(`[palbase] migrate ${t}: this app declares no database \u2014 PalbaseFactory.create(\u2026, { db: { schemas } })`),1)}async function be(t,e){if(!t)return d.error("[palbase] db types: this app declares no database \u2014 PalbaseFactory.create(\u2026, { db: { schemas } })"),1;let s=Array.isArray(t.schemas)?t.schemas:[t.schemas];return await R("types",es(s,{module:"palbase/backend/env"}),e),0}async function me(t,e,s){let r=e.PALBASE_DB_OWNER_URL;if(!r)return d.error("[palbase] PALBASE_DB_MIGRATE without PALBASE_DB_OWNER_URL: a migration runs as the tables' owner"),1;let n=e.PALBASE_DB_MIGRATION_BY||"deploy";if(!ls.test(n))return d.error("[palbase] PALBASE_DB_MIGRATION_BY is deploy, or cli:<who>"),1;let a=fe(t,he(e)),i=a(r),o,c=l=>d.error(`[palbase] migrate ${s}: ${l}`);try{let l=U(t),u=new ce(i.pool,{log:f=>{/ is held by others | held by writers/.test(f)&&(o=f.trim()),d.info(f)},shadow:f=>{let g=new URL(r);g.pathname=`/${f}`;let y=a(g.toString());return{reserve:()=>y.pool.reserve(),end:()=>y.close()}},openedBy:n,fields:()=>us(e)});if(s==="plan"){let f=await u.plan(l);return await R(s,f),f.refusals.length>0?1:0}if(s==="status")return await R(s,await u.status()),0;let h=s==="start"?await ps(u,l,n):s==="complete"?await u.complete():await u.rollback();return d.info(`[palbase] migrate ${s}: done`,{result:h}),await R(s,h),0}catch(l){return l instanceof as?(d.error(`[palbase] migrate ${s}: refused`,{refusals:l.refusals}),c(`refused \u2014 ${l.refusals.join("; ")}`),1):ss(l)?(d.error(`[palbase] migrate ${s}: cut off; run again, it goes on from where it stopped`,{error:l}),c(`cut off \u2014 ${o??ie(l)}`),75):(d.error(`[palbase] migrate ${s}: failed`,{error:l}),c(`failed \u2014 ${ie(l)}`),1)}finally{await i.close().catch(()=>{})}}async function us(t){let e=t.PALBASE_URL,s=t.PALBASE_SECRET_KEY;if(!e||!s)throw new Error("[palbase] this migration seals or opens an encrypted column's rows: it reads the project's field keys with PALBASE_URL and PALBASE_SECRET_KEY");let r=_({url:e,secretKey:s}).fields;return await r.load(),r.close(),r}async function ps(t,e,s){try{return await t.start(e)}catch(r){if(!(r instanceof ns)||s!=="deploy"||!r.openedBy?.startsWith("cli:"))throw r;return d.warn(`[palbase] migrate start: the migration ${r.openedBy} opened (version ${r.to}) gives way to this release \u2014 rolled back first`),await t.rollback(),await t.start(e)}}var hs=(t,e)=>{process.stdout.write(t,()=>e())};function R(t,e,s=hs){return new Promise(r=>s(`${JSON.stringify({palbase_migrate:t,result:e})}
|
|
3
|
+
`,r))}function ie(t){return(t instanceof Error?t.message:String(t)).split(`
|
|
4
|
+
`)[0].slice(0,300)||(t instanceof Error?t.name:"unknown")}async function fs(t,e){try{return await new ce(t).plan(e)}catch{return}}var le="palbase.idempotency_keys.response_body";function gs(t,e){let s=null,r=!1,n=async()=>{let o=e.currentKey();if(!(r||o===s)){r=!0;try{let c=await t.reseal();s=o;let l=c.reduce((u,h)=>u+h.resealed,0);l>0&&d.info(`[palbase] fields: ${l} value(s) sealed again with key ${o}`,{report:c})}catch(c){d.warn(`[palbase] fields: sealing again with key ${o} stopped; tried again in a minute`,{error:c})}finally{r=!1}}},a=setTimeout(n,1e4),i=setInterval(n,6e4);for(let o of[a,i])o.unref?.();return()=>{clearTimeout(a),clearInterval(i)}}var L=class extends Error{digest;plan;constructor(e,s){super([`[palbase] this schema (${e}) has no version in the database yet: palbase db:push tries it there (a database of your own: palbase db:push --url <its address>)`,...s?bs(s):[" palbase db:plan says what it would change"]].join(`
|
|
5
|
+
`)),this.name="SchemaNotPushed",this.digest=e,this.plan=s}};function bs(t){let e=[t.adoption?` takes the database over as version 1${t.to>1?`, then version 1 \u2192 ${t.to}`:""}`:` version ${t.from??"none"} \u2192 ${t.to}`];t.changes.length===0&&t.refusals.length===0&&e.push(" nothing to change");for(let s of t.changes)e.push(` + ${s}`);for(let s of t.refusals)e.push(` \u2717 ${s}`);return e}var ms=8e4;async function ye(t,e,s,r){let n=t.url??e.PALBASE_DB_URL;if(!n)throw new Error("[palbase] db.url / PALBASE_DB_URL is the database the app connects to");let a=pe(t),i=de(a),o=fe(t,he(e))(n);try{let c=!1,l=p=>{c||(c=!0,d.warn(`[palbase] database: not answering yet (${p instanceof Error?p.message:String(p)}) \u2014 waiting for it, as one waking does`))},u=await Qt(o.engine,i,{waitMs:r.onPlatform?ms:0,onUnreachable:l}).catch(async p=>{throw r.onPlatform||!(p instanceof os)?p:new L(p.digest,await fs(o.pool,i))}),h=Jt("sha256",s).update("palgres page cursor").digest("hex"),f=t.embed??r.embed,g=r.fields,y=await Zt({sql:o.engine,schemas:a,binding:u,cursorSecret:h,admission:ds(o.poolSize),embed:f,log:p=>d.warn(`[palbase] ${p}`),fields:async()=>(await g.load(),g)}),S=g.loaded?gs(y,g):()=>{},m=cs(i)?ts({sql:o.engine,embed:f,log:p=>d.info(`[palbase] ${p}`)}):void 0;return{model:i,binding:u,app:y,requests:t.requests??"caller",forget:p=>rs(o.engine,u,i,p),...m?{search:m}:{},keptAnswers:{seal:p=>g.loaded?g.encrypt(le,p):p,open:async p=>g.isEncrypted(p)?(g.loaded||await g.load(),g.decrypt(le,p)):p},close:async()=>{S(),g.close(),await o.close()}}}catch(c){throw await o.close(),c}}function ys(t){let e=Buffer.from(t,"base64"),s=new Array(e.byteLength/4);for(let r=0;r<s.length;r++)s[r]=e.readFloatLE(r*4);return s}function we(t){return async({texts:e,model:s,dimensions:r})=>{let{data:n}=await t.ai.createEmbeddings({body:{input:e,model:s,dimensions:r}});return{model:n.model,vectors:n.vectors.map(ys)}}}var ws=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;function Pe(t,e,s){let r=[],n=t.url??e.PALBASE_URL??"",a="";try{let u=new URL(n);a=u.origin,u.protocol!=="https:"&&u.hostname!=="localhost"&&u.hostname!=="127.0.0.1"&&r.push("palbase.url / PALBASE_URL is https://<ref>.<domain>"),(u.pathname!=="/"||u.search||u.hash)&&r.push("palbase.url / PALBASE_URL is the project origin alone")}catch{r.push("palbase.url / PALBASE_URL is the project address, https://<ref>.<domain>")}let i=t.projectId??e.PALBASE_PROJECT_ID??"";ws.test(i)||r.push("palbase.projectId / PALBASE_PROJECT_ID is the project id (a UUID)");let o=t.secretKey??e.PALBASE_SECRET_KEY??"";/^pb_[a-z0-9]+_s/.test(o)||r.push("palbase.secretKey / PALBASE_SECRET_KEY is the project secret key (pb_<ref>_s\u2026), kept in the project's Secrets");let c=(t.platformSecret??e.PALBASE_PLATFORM_SECRET)||void 0;c!==void 0&&!/^[0-9a-f]{64}$/.test(c)&&r.push("palbase.platformSecret / PALBASE_PLATFORM_SECRET is the key the platform signs its calls to this machine with (64 hex characters): the platform sets it, unset off the platform");let l=(t.webhookSecret??e.PALBASE_WEBHOOK_SECRET)||void 0;if(s.needsWebhookSecret&&(c!==void 0||l!==void 0)&&!/^whsec_[0-9a-f]{64}$/.test(l??"")&&r.push("palbase.webhookSecret / PALBASE_WEBHOOK_SECRET is the project's webhook endpoint secret (whsec_\u2026): the platform delivers this app events \u2014 its @On handlers', or user.deleted for the users its tables keep"),r.length>0)throw new Error(`[palbase] the app cannot start:
|
|
6
|
+
- ${r.join(`
|
|
7
|
+
- `)}`);return{url:a,projectId:i,secretKey:o,webhookSecret:s.needsWebhookSecret?l:void 0,platformSecret:c}}import{createHash as Ps}from"node:crypto";import{writeSync as Ss}from"node:fs";import{gzipSync as vs}from"node:zlib";var As="palbase-contract-v1 begin",ks="palbase-contract-v1 end",Se=76;function ve(t){let e=Buffer.from(t,"utf8"),s=vs(e).toString("base64"),r=[`${As} ${Ps("sha256").update(e).digest("hex")} ${e.length}`];for(let n=0;n<s.length;n+=Se)r.push(s.slice(n,n+Se));return r.push(ks),`
|
|
8
|
+
${r.join(`
|
|
9
9
|
`)}
|
|
10
|
-
`}function
|
|
11
|
-
`),process.exit(1),new
|
|
12
|
-
`),process.exit(0),new _}let i=Ee(s),o=await xe(i);o&&c.info(`[palbase] strings: ${o.source} and ${o.locales.length-1} other language(s), ${Object.keys(o.strings).length} sentence(s), from ${i}/palbase/strings`),se(o?void 0:i);let d=e.db?U(e.db):void 0,l=await J({env:s,url:e.palbase?.url,secretKey:e.palbase?.secretKey});l&&c.info(`[palbase] secrets: ${l.loaded.length} from the project's ${l.set} set${l.kept.length>0?`; ${l.kept.join(", ")} kept as the environment gives them`:""}`),l&&l.refused.length>0&&c.warn(`[palbase] secrets not set \u2014 names a process reads as its own, not the app's: ${l.refused.map(w=>JSON.stringify(w)).join(", ")}`);let u=Or(r)||d!==void 0&&L(d),p=we(e.palbase??{},s,{needsWebhookSecret:u});u&&p.webhookSecret===void 0&&c.warn("[palbase] events: none is delivered here \u2014 the platform delivers them to the app's machine, not to this computer; its @On handlers (and forgetting a deleted user's rows) run there. Set PALBASE_WEBHOOK_SECRET to take a delivery forwarded here");let h=V({url:p.url,secretKey:p.secretKey}),y=e.port??Number(s.PORT??"8080");if(!Number.isInteger(y)||y<0||y>65535)throw new Error(`[palbase] PORT is a port number, not ${String(e.port??s.PORT)}`);let b=e.db?await fe(e.db,s,p.secretKey,{onPlatform:p.platformSecret!==void 0,embed:ye(h)}):void 0;b&&c.info(`[palbase] database: version ${b.binding.version}`);let m=b&&L(b.model)?{"user.deleted":[w=>Cr(b,w)]}:void 0,f=p.platformSecret===void 0?void 0:{secret:p.platformSecret},S=e.requestTelemetry===!1?void 0:new $(h.analytics),R=()=>M({modules:r,verifier:new C({issuer:p.url,projectId:p.projectId,standing:H({url:p.url,secretKey:p.secretKey})}),server:h,webhookSecret:p.webhookSecret,env:s,projectId:p.projectId,telemetry:S,auth:e.auth,tokens:e.tokens,rateLimit:e.rateLimit,maxBodyBytes:e.bodyLimit,cors:Mr(e.cors,s.PALBASE_WEB_ORIGINS),platform:f,events:m,database:b&&{app:b.app,requests:b.requests},strings:o}),x=R(),N=e.boot?.attempts??5,q=e.boot?.backoffMs??1e3;for(let w=1;;w++)try{await x.start();break}catch(v){if(w>=N)throw c.error(`[palbase] the app did not start after ${N} attempts`,{error:v}),v;c.warn(`[palbase] the app did not start (attempt ${w} of ${N}); trying again in ${q} ms`,{error:v}),await new Promise(Ie=>setTimeout(Ie,q)),q*=2,x=R()}return Br(x,h,y,e.host??"0.0.0.0",e.exitOnFatal??!0,b)}};function Ee(t){let e=t.PALBASE_CONTRACT_ENTRY??process.argv[1];if(!e)return process.cwd();let r=k(Te(e));for(;!K(z(r,"package.json"))&&k(r)!==r;)r=k(r);return K(z(r,"package.json"))?r:process.cwd()}async function xe(t){try{return await ne(t)}catch(e){throw new Error(`[palbase] the app's strings: ${e instanceof Error?e.message:String(e)}`)}}async function Rr(t,e,r){let s=Te(r.PALBASE_CONTRACT_ENTRY??process.argv[1]??"");if(!/\.[cm]?tsx?$/.test(s))throw new Error(`the contract is read from the app's TypeScript source, and this run's entry is ${s||"none"}: start it from its source (bun run src/main.ts), or name the source's entry in PALBASE_CONTRACT_ENTRY`);let n=k(s);for(;!K(z(n,"package.json"))&&k(n)!==n;)n=k(n);let{analyzeProject:a}=await import("../chunks/ZOAWYN6L.js"),{routeContracts:i}=await import("../chunks/5TVS7F23.js"),o=a(n,s);for(let u of o.warnings)c.warn(`[palbase] the contract: ${u}`);let d="https://contract.palbase.invalid",l=M({modules:t,verifier:new C({issuer:d,projectId:"contract",standing:()=>Promise.reject(new Error("the contract run serves nothing"))}),server:V({url:d,secretKey:"pb_contract_s"}),env:r,projectId:"contract",auth:e.auth,tokens:e.tokens,rateLimit:e.rateLimit,maxBodyBytes:e.bodyLimit,cors:e.cors,contractOnly:{database:e.db!==void 0,routes:await i(o.routes),errors:re()},events:e.db&&L(U(e.db))?{"user.deleted":[]}:void 0});return JSON.stringify(l.contract())}var _=class extends Error{constructor(){super("[palbase] the contract run ended"),this.name="ContractRunEnded"}},D=class extends Error{code;constructor(e){super(`[palbase] the migration run ended with ${e}`),this.name="MigrationRunEnded",this.code=e}};async function Cr(t,e){let r=e.data?.user_id;if(typeof r!="string"||r==="")throw new Error("[palbase] user.deleted without a user_id");let s=await t.forget(r);c.info(`[palbase] user ${r} deleted: ${s.deleted} row(s) gone, ${s.detached} forgot them`)}async function Br(t,e,r,s,n,a){let i,o={on:!1},d=(f,S)=>new URL(f.url).pathname===Tr&&f.method==="GET"?Promise.resolve(o.on?Response.json({ok:!1,stopping:!0},{status:503}):Response.json({ok:!0})):t.handle(f,S),l=kr((f,S)=>{Fr(d,f,S,o).finally(()=>{o.on&&l.closeIdleConnections()})});l.keepAliveTimeout=29e4,l.headersTimeout=3e5;try{await new Promise((f,S)=>{l.once("error",S),l.listen(r,s,()=>f())})}catch(f){throw await t.stop(),await a?.close(),f}let u=l.address().port;c.info(`[palbase] serving ${t.routes.length} route(s) on :${u}`,{routes:t.routes}),a?.search?.start();let p=f=>i??=(async()=>{c.info("[palbase] stopping: finishing the requests in flight"),o.on=!0;let S=new Promise(x=>l.close(()=>x()));l.closeIdleConnections();let R=setTimeout(()=>l.closeAllConnections(),f);await S,clearTimeout(R),process.off("SIGINT",b),process.off("uncaughtException",m),process.off("unhandledRejection",m);try{await t.stop(),await a?.search?.stop(),await a?.close()}finally{process.off("SIGTERM",b)}})(),h=()=>p(Ae),y=!1,b=()=>{if(y){c.info("[palbase] stopping: told to stop again; the requests in flight are still being finished");return}y=!0;let f=setTimeout(()=>{c.error("[palbase] stopping took longer than it is given; the process ends"),process.exit(1)},Ae+xr);f.unref(),h().then(()=>{clearTimeout(f),process.exit(0)},S=>{clearTimeout(f),c.error("[palbase] stopping failed; the process ends",{error:S}),process.exit(1)})},m=f=>{c.error("[palbase] the app crashed; stopping so the machine starts it again",{error:f});let S=setTimeout(()=>process.exit(1),ke+1e3);p(ke).finally(()=>{clearTimeout(S),process.exit(1)})};return process.on("SIGTERM",b),process.once("SIGINT",b),n&&(process.on("uncaughtException",m),process.on("unhandledRejection",m)),{routes:t.routes,palbase:e,port:u,handle:d,close:h}}async function Fr(t,e,r,s){try{let n=e.url??"/",a;try{if(!n.startsWith("/"))throw new TypeError("the request target is not a path");a=new URL(`http://localhost${n}`)}catch{r.statusCode=400,r.end();return}let i=new Headers;for(let[p,h]of Object.entries(e.headers))if(h!==void 0)if(Array.isArray(h))for(let y of h)i.append(p,y);else i.set(p,h);let o=e.method!=="GET"&&e.method!=="HEAD",d=new AbortController;r.on("close",()=>{r.writableFinished||d.abort(new Error("the client closed the connection"))});let l=new Request(a,{method:e.method,headers:i,body:o?Er.toWeb(e):void 0,duplex:"half",signal:d.signal}),u=await t(l,{remoteAddress:e.socket.remoteAddress});if(r.statusCode=u.status,u.headers.forEach((p,h)=>r.setHeader(h,p)),s.on&&r.setHeader("connection","close"),u.body)for await(let p of u.body)r.write(p);r.end()}catch(n){c.error("[palbase] the request could not be answered",{error:n}),r.headersSent||(r.statusCode=500),r.end()}}function Mr(t,e,r=s=>console.warn(s)){let s=(e??"").split(",").map(o=>o.trim()).filter(o=>o!=="");if(s.length===0||t?.origins==="*")return t;let n=s.filter(o=>G(o)),a=s.filter(o=>!G(o));a.length>0&&r(`[palbase] the project's web origins ${a.map(o=>JSON.stringify(o)).join(", ")} are not CORS origins (https://host[:port], http only for localhost): browsers there are not let in`);let i=[...new Set([...t?.origins??[],...n])];return i.length===0?t:{...t,origins:i}}import{bigint as Ws,boolean as Vs,check as Gs,date as Ks,defineSchema as zs,defineTable as Hs,enumType as Ys,foreignKey as Js,index as Qs,integer as Xs,jsonb as Zs,numeric as en,ownedByUser as tn,policy as rn,raw as sn,sqlType as nn,text as an,timestamp as on,userRef as ln,uuid as cn}from"palgres/dsl";import{increment as un,now as pn}from"palgres";function E(t){if(t instanceof A)return{data:null,error:{code:t.code,message:t.message},status:t.status};throw t}async function P(t,e){try{let r=await t();return{data:await e(r.data),error:null,status:r.status}}catch(r){return E(r)}}var $r=T("Secrets",{async get(t){if(Y(t))return null;let e=process.env[t];return typeof e=="string"&&e!==""?e:null}}),Ir=100,Ur=1e3,Lr=168*3600,Dr={s:1,m:60,h:3600,d:86400};function jr(t){let e=String(t).trim();if(!/^(\d+(\.\d+)?[dhms])+$/.test(e))return;let r=0;for(let[,s,,n]of e.matchAll(/(\d+(\.\d+)?)([dhms])/g))r+=Math.round(Number(s)*Dr[n]*1e3);return Math.ceil(r/1e3)}function Me(t,e,r){let s="getPublicUrl",n;try{n=String(e).split("/").map(i=>W(s,"path",i)).join("%2F")}catch(i){throw i instanceof A&&i.code==="invalid_path_parameter"?new A({op:s,status:0,code:"invalid_path_parameter",message:`${s}: the object path ${JSON.stringify(e)} has an empty, "." or ".." segment: storage keeps no such object`}):i}let a=`${g.url}/storage/public/${W(s,"bucket",t)}/${n}`;return r?`${a}?variant=${encodeURIComponent(r)}`:a}function Oe(t){return{path:t.path,name:t.path,bucket:t.bucket,size:t.size,contentType:t.content_type,checksum:t.checksum_sha256,...t.width!==void 0?{width:t.width}:{},...t.height!==void 0?{height:t.height}:{},...t.thumbhash!==void 0?{thumbhash:t.thumbhash}:{},variants:Object.fromEntries(Object.keys(t.variants??{}).map(e=>[e,Me(t.bucket,t.path,e)]))}}function Nr(t){return{async upload(e,r,s){let n=s?.contentType??(r instanceof Blob&&r.type!==""?r.type:void 0);try{let a=await g.storage.putObject({path:{bucket:t,path:e},headers:s?.upsert?void 0:{"If-None-Match":"*"},body:r,contentType:n});return{data:Oe(a.data),error:null,status:a.status}}catch(a){return a instanceof A&&a.status===412&&a.code==="object_exists"?{data:null,error:{code:"already_exists",message:"An object already exists at that path: upload with { upsert: true } to replace it"},status:409}:E(a)}},async download(e){try{let r=await g.storage.getObject({path:{bucket:t,path:e}});if(r.status===304)throw new Error("storage answered 304 to a read that sent no entity tag");let s=r.data;try{return{data:await s.blob(),error:null,status:r.status}}catch(n){return{data:null,error:{code:"network_error",message:`the object's bytes stopped arriving: ${n instanceof Error?n.message:String(n)}`},status:0}}}catch(r){return E(r)}},getPublicUrl(e,r){return Me(t,e,r?.variant)},async createSignedUrl(e,r){let s=jr(r?.expiresIn);return s===void 0||s<1||s>Lr?{data:null,error:{code:"bad_request",message:`expiresIn is a duration from 1s to 7d, like "15m", "1h" or "7d" (got ${JSON.stringify(r?.expiresIn)})`},status:400}:P(()=>g.storage.createSignedUrl({path:{bucket:t},body:{path:e,expires_in:s}}),n=>({signedUrl:n.url,expiresAt:n.expires_at}))},async list(e,r){let s=r?.limit??Ir,n=r?.offset??0;if(!Number.isInteger(s)||s<0||!Number.isInteger(n)||n<0)return{data:null,error:{code:"bad_request",message:"limit and offset are whole numbers, 0 or more"},status:400};let a=[],i,o=200;try{for(;a.length<s;){let d=Math.max(1,Math.min(Ur,n+s-a.length)),l=await g.storage.listObjects({path:{bucket:t},query:{...e?{prefix:e}:{},limit:d,...i?{cursor:i}:{}}});o=l.status;for(let u of l.data.objects)n>0?n--:a.length<s&&a.push(Oe(u));if(i=l.data.next_cursor,!i)break}}catch(d){return E(d)}return{data:a,error:null,status:o}},async remove(e){let r=[];for(let s of e){try{await g.storage.deleteObject({path:{bucket:t,path:s}})}catch(n){return E(n)}r.push({path:s,name:s,bucket:t,size:0,contentType:"",checksum:"",variants:{}})}return{data:r,error:null,status:200}},move(e,r){return P(()=>g.storage.moveObject({path:{bucket:t},body:{from:e,to:r}}),()=>{})},copy(e,r){return P(()=>g.storage.copyObject({path:{bucket:t},body:{from:e,to:r}}),()=>{})}}}var qr={bucket:Nr},_e=t=>ee("Storage",t,qr),Wr={bucket:t=>_e("bucket").bucket(t),buckets:new Proxy({},{get:(t,e)=>typeof e=="string"?_e("buckets").bucket(e):void 0})},Vr=T("Notifications",{push:{send(t){let{to:e,...r}=t,s=typeof e=="string"?{user_ids:[e]}:Array.isArray(e)?{user_ids:e}:{topic:e.topic};return P(()=>g.notify.sendPush({body:{...r,to:s}}),n=>({message_ids:n.message_ids,recipients:n.message_ids.length,skipped_user_ids:n.skipped_user_ids}))}},email:{async send(t){let{to:e,templateSlug:r,...s}=t,n={...s,...r!==void 0?{template:r}:{}};if(!Array.isArray(e))return P(()=>g.notify.sendEmail({body:{...n,to:e}}),o=>({...o.message_id!==void 0?{message_id:o.message_id}:{},...o.skipped?{skipped:!0}:{}}));let a=[],i=202;for(let o of e)try{let d=await g.notify.sendEmail({body:{...n,to:o}});i=d.status,a.push(d.data.message_id??null)}catch(d){return E(d)}return{data:{message_ids:a},error:null,status:i}}}}),Re=t=>typeof t=="boolean"?t:t!=null&&t!==0&&t!=="",Ce=t=>typeof t=="string"?{name:t}:null,Be=t=>t==="override"?"user":t,Gr=t=>t!==null&&typeof t=="object"&&!Array.isArray(t)&&"userId"in t;function $e(){return te.getStore()?.userId}function j(t){let e=t&&"userId"in t?t.userId??void 0:$e();return P(()=>e?g.flags.getUserValues({path:{user_id:e}}):g.flags.getValues(),r=>r.values??{})}var Fe={setOverrideForUser:(t,e,r)=>P(()=>g.flags.putUserValue({path:{user_id:t,key:e},body:{value:r}}),s=>({key:s.key,value:s.value,source:Be(s.source)})),setOverridesForUser:(t,e)=>P(()=>g.flags.putUserValues({path:{user_id:t},body:{values:e}}),r=>({values:r.values??{}})),clearOverrideForUser:(t,e)=>P(()=>g.flags.deleteUserValue({path:{user_id:t,key:e}}),r=>({key:r.key,value:r.value,source:Be(r.source)})),clearAllOverridesForUser:t=>P(()=>g.flags.deleteUserValues({path:{user_id:t}}),e=>({deleted:e.deleted})),batchSetOverrides:t=>P(()=>g.flags.batchUserValues({body:{operations:t.map(e=>({user_id:e.userId,values:e.values}))}}),e=>({applied:e.applied}))},Kr=T("Flags",{async isEnabled(t,e){let r=s=>(c.warn(`[palbase] flag "${t}" could not be read (${s}): treating it as off`),!1);try{let s=await j(e);return s.error?r(`${s.error.code}: ${s.error.message}`):Re(s.data[t])}catch(s){return r(s instanceof Error?s.message:String(s))}},async getVariant(t,e){let r=await j(e);return r.error?{data:null,error:r.error,status:r.status}:{data:Ce(r.data[t]),error:null,status:r.status}},async getAll(t){let e=await j(t);return e.error?{data:null,error:e.error,status:e.status}:{data:Object.entries(e.data).map(([r,s])=>{let n=Ce(s);return{name:r,enabled:Re(s),...n?{variant:n}:{}}}),error:null,status:e.status}},async get(t,e,r){let s,n=!1,a;r!==void 0?(s=e,n=!0,a=r):Gr(e)?a=e:e!==void 0&&(s=e,n=!0);let i=await j(a);if(i.error)return n?{data:s??null,error:null,status:i.status}:{data:null,error:i.error,status:i.status};let o=i.data[t];return{data:o===void 0?s??null:o,error:null,status:i.status}},async setOverride(t,e){let r=$e();return r?Fe.setOverrideForUser(r,t,e):{data:null,error:{code:"no_user",message:"Flags.setOverride writes the signed-in user's value: this request has none \u2014 Flags.$asService().setOverrideForUser(userId, key, value) writes anyone's"},status:400}},$asService(){return Fe}}),zr=T("Realtime",{broadcast(t,e,r){return P(()=>g.realtime.broadcast({body:{messages:[{topic:t,event:e,payload:r??{}}]}}),()=>{})},state:{set(t,e,r){return P(()=>g.realtime.writeState({body:{ops:[{topic:t,key:e,value:r}]}}),()=>{})},clear(t,e){return P(()=>g.realtime.writeState({body:{ops:[{topic:t,key:e,delete:!0}]}}),()=>{})}}});import{z as Pn}from"zod";export{De as AuthUnavailable,St as Authorize,Ft as BadRequest,ze as Body,Wt as CACHE_MAX_TTL,Vt as Cache,yt as ChatPart,rt as Client,Mt as Conflict,_ as ContractRunEnded,je as Controller,it as Cron,ut as Database,$t as DeadlockDetected,Ge as Delete,Ot as DiError,Ue as EVENT_TYPES,Kr as Flags,Ct as Forbidden,Pt as Gateway,wt as GatewayRefusal,Ne as Get,Ye as Headers,It as HttpError,nt as Injectable,c as Log,qt as MAX_BODY_BYTES,D as MigrationRunEnded,at as Module,Ut as NotFound,Vr as Notifications,ot as On,At as OnConnect,kt as OnDisconnect,Et as OnEmpty,vt as OnFirst,Xe as OptionalUser,_t as PalError,g as Palbase,A as PalbaseError,_r as PalbaseFactory,Je as Param,Ve as Patch,qe as Post,We as Put,Ke as Query,He as QueryParams,zr as Realtime,Ze as Req,et as RequestId,st as Resolve,I as SchemaNotPushed,$r as Secrets,Lt as SerializationFailure,Wr as Storage,xt as Subscribe,ht as Task,pt as TaskFailure,gt as Tasks,bt as TestUserTemplate,Le as TokenError,C as TokenVerifier,Dt as TooManyRequests,tt as TraceId,Rt as Unauthorized,jt as UniqueViolation,mt as Upload,ft as UploadedObject,Qe as User,lt as Webhook,Ws as bigint,Vs as boolean,Gs as check,M as createApp,Ks as date,Bt as defineError,zs as defineSchema,Hs as defineTable,Ys as enumType,Js as foreignKey,ct as getRegisteredControllers,dt as getRoutes,Tt as getWebhookManifest,un as increment,Qs as index,Xs as integer,Zs as jsonb,pn as now,en as numeric,tn as ownedByUser,rn as policy,sn as raw,nn as sqlType,Nt as t,an as text,on as timestamp,ln as userRef,cn as uuid,Pn as z};
|
|
10
|
+
`}function Ae(t,e,s=Ss){let r=Buffer.from(e,"utf8"),n=new Int32Array(new SharedArrayBuffer(4));for(let a=0;a<r.length;)try{a+=s(t,r,a,r.length-a)}catch(i){if(i.code!=="EAGAIN")throw i;Atomics.wait(n,0,0,5)}}var ke=2e4,Ee=5e3,Rs=15e3,Os="/_palbase/health";function Cs(t){let e=new Set,s=r=>{if(e.has(r))return!1;e.add(r);let n=F(r,Q);return n?n.providers.some(a=>F(a,X)!==void 0&&F(a,Z)===void 0)||n.imports.some(s):!1};return t.some(s)}var Bs={async create(t,e={}){let s=Array.isArray(t)?t:[t],r=e.env??process.env,n=ue(r);if(n!==void 0){let w=n==="types"?await be(e.db):e.db?await me(e.db,r,n):await ge(n);throw process.exit(w),new j(w)}let a=r.PALBASE_CONTRACT_OUT;if(a){let w;try{await _e(Te(r)),w=await Fs(s,e,r)}catch(v){throw Ts(2,`[palbase] the contract: ${v instanceof Error?v.message:String(v)}
|
|
11
|
+
`),process.exit(1),new O}throw a==="/dev/stdout"?Ae(1,ve(w)):Es(a,`${w}
|
|
12
|
+
`),process.exit(0),new O}let i=Te(r),o=await _e(i);o&&d.info(`[palbase] strings: ${o.source} and ${o.locales.length-1} other language(s), ${Object.keys(o.strings).length} sentence(s), from ${i}/palbase/strings`),re(o?void 0:i);let c=e.db?U(e.db):void 0,l=await J({env:r,url:e.palbase?.url,secretKey:e.palbase?.secretKey});l&&d.info(`[palbase] secrets: ${l.loaded.length} from the project's ${l.set} set${l.kept.length>0?`; ${l.kept.join(", ")} kept as the environment gives them`:""}`),l&&l.refused.length>0&&d.warn(`[palbase] secrets not set \u2014 names a process reads as its own, not the app's: ${l.refused.map(w=>JSON.stringify(w)).join(", ")}`);let u=Cs(s)||c!==void 0&&D(c),h=Pe(e.palbase??{},r,{needsWebhookSecret:u});u&&h.webhookSecret===void 0&&d.warn("[palbase] events: none is delivered here \u2014 the platform delivers them to the app's machine, not to this computer; its @On handlers (and forgetting a deleted user's rows) run there. Set PALBASE_WEBHOOK_SECRET to take a delivery forwarded here");let f=_({url:h.url,secretKey:h.secretKey}),g=e.port??Number(r.PORT??"8080");if(!Number.isInteger(g)||g<0||g>65535)throw new Error(`[palbase] PORT is a port number, not ${String(e.port??r.PORT)}`);let y=e.db?await ye(e.db,r,h.secretKey,{onPlatform:h.platformSecret!==void 0,embed:we(f),fields:f.fields}):void 0;y&&d.info(`[palbase] database: version ${y.binding.version}`);let S=y&&D(y.model)?{"user.deleted":[w=>Ms(y,w)]}:void 0,m=h.platformSecret===void 0?void 0:{secret:h.platformSecret},p=e.requestTelemetry===!1?void 0:new I(f.analytics),C=()=>$({modules:s,verifier:new B({issuer:h.url,projectId:h.projectId,standing:H({url:h.url,secretKey:h.secretKey})}),server:f,webhookSecret:h.webhookSecret,env:r,projectId:h.projectId,telemetry:p,auth:e.auth,tokens:e.tokens,rateLimit:e.rateLimit,maxBodyBytes:e.bodyLimit,cors:Ls(e.cors,r.PALBASE_WEB_ORIGINS),platform:m,events:S,database:y&&{app:y.app,requests:y.requests,keptAnswers:y.keptAnswers},strings:o}),T=C(),q=e.boot?.attempts??5,W=e.boot?.backoffMs??1e3;for(let w=1;;w++)try{await T.start();break}catch(v){if(w>=q)throw d.error(`[palbase] the app did not start after ${q} attempts`,{error:v}),v;d.warn(`[palbase] the app did not start (attempt ${w} of ${q}); trying again in ${W} ms`,{error:v}),await new Promise(Le=>setTimeout(Le,W)),W*=2,T=C()}return $s(T,f,g,e.host??"0.0.0.0",e.exitOnFatal??!0,y)}};function Te(t){let e=t.PALBASE_CONTRACT_ENTRY??process.argv[1];if(!e)return process.cwd();let s=k(xe(e));for(;!G(z(s,"package.json"))&&k(s)!==s;)s=k(s);return G(z(s,"package.json"))?s:process.cwd()}async function _e(t){try{return await ne(t)}catch(e){throw new Error(`[palbase] the app's strings: ${e instanceof Error?e.message:String(e)}`)}}async function Fs(t,e,s){let r=xe(s.PALBASE_CONTRACT_ENTRY??process.argv[1]??"");if(!/\.[cm]?tsx?$/.test(r))throw new Error(`the contract is read from the app's TypeScript source, and this run's entry is ${r||"none"}: start it from its source (bun run src/main.ts), or name the source's entry in PALBASE_CONTRACT_ENTRY`);let n=k(r);for(;!G(z(n,"package.json"))&&k(n)!==n;)n=k(n);let{analyzeProject:a}=await import("../chunks/AFFE3Q5O.js"),{routeContracts:i}=await import("../chunks/BUYFMLTF.js"),o=a(n,r);for(let u of o.warnings)d.warn(`[palbase] the contract: ${u}`);let c="https://contract.palbase.invalid",l=$({modules:t,verifier:new B({issuer:c,projectId:"contract",standing:()=>Promise.reject(new Error("the contract run serves nothing"))}),server:_({url:c,secretKey:"pb_contract_s"}),env:s,projectId:"contract",auth:e.auth,tokens:e.tokens,rateLimit:e.rateLimit,maxBodyBytes:e.bodyLimit,cors:e.cors,contractOnly:{database:e.db!==void 0,routes:await i(o.routes),errors:se()},events:e.db&&D(U(e.db))?{"user.deleted":[]}:void 0});return JSON.stringify(l.contract())}var O=class extends Error{constructor(){super("[palbase] the contract run ended"),this.name="ContractRunEnded"}},j=class extends Error{code;constructor(e){super(`[palbase] the migration run ended with ${e}`),this.name="MigrationRunEnded",this.code=e}};async function Ms(t,e){let s=e.data?.user_id;if(typeof s!="string"||s==="")throw new Error("[palbase] user.deleted without a user_id");let r=await t.forget(s);d.info(`[palbase] user ${s} deleted: ${r.deleted} row(s) gone, ${r.detached} forgot them`)}async function $s(t,e,s,r,n,a){let i,o={on:!1},c=(m,p)=>new URL(m.url).pathname===Os&&m.method==="GET"?Promise.resolve(o.on?Response.json({ok:!1,stopping:!0},{status:503}):Response.json({ok:!0})):t.handle(m,p),l=_s((m,p)=>{Is(c,m,p,o).finally(()=>{o.on&&l.closeIdleConnections()})});l.keepAliveTimeout=29e4,l.headersTimeout=3e5;try{await new Promise((m,p)=>{l.once("error",p),l.listen(s,r,()=>m())})}catch(m){throw await t.stop(),await a?.close(),m}let u=l.address().port;d.info(`[palbase] serving ${t.routes.length} route(s) on :${u}`,{routes:t.routes}),a?.search?.start();let h=m=>i??=(async()=>{d.info("[palbase] stopping: finishing the requests in flight"),o.on=!0;let p=new Promise(T=>l.close(()=>T()));l.closeIdleConnections();let C=setTimeout(()=>l.closeAllConnections(),m);await p,clearTimeout(C),process.off("SIGINT",y),process.off("uncaughtException",S),process.off("unhandledRejection",S);try{await t.stop(),await a?.search?.stop(),await a?.close()}finally{process.off("SIGTERM",y)}})(),f=()=>h(ke),g=!1,y=()=>{if(g){d.info("[palbase] stopping: told to stop again; the requests in flight are still being finished");return}g=!0;let m=setTimeout(()=>{d.error("[palbase] stopping took longer than it is given; the process ends"),process.exit(1)},ke+Rs);m.unref(),f().then(()=>{clearTimeout(m),process.exit(0)},p=>{clearTimeout(m),d.error("[palbase] stopping failed; the process ends",{error:p}),process.exit(1)})},S=m=>{d.error("[palbase] the app crashed; stopping so the machine starts it again",{error:m});let p=setTimeout(()=>process.exit(1),Ee+1e3);h(Ee).finally(()=>{clearTimeout(p),process.exit(1)})};return process.on("SIGTERM",y),process.once("SIGINT",y),n&&(process.on("uncaughtException",S),process.on("unhandledRejection",S)),{routes:t.routes,palbase:e,port:u,handle:c,close:f}}async function Is(t,e,s,r){try{let n=e.url??"/",a;try{if(!n.startsWith("/"))throw new TypeError("the request target is not a path");a=new URL(`http://localhost${n}`)}catch{s.statusCode=400,s.end();return}let i=new Headers;for(let[h,f]of Object.entries(e.headers))if(f!==void 0)if(Array.isArray(f))for(let g of f)i.append(h,g);else i.set(h,f);let o=e.method!=="GET"&&e.method!=="HEAD",c=new AbortController;s.on("close",()=>{s.writableFinished||c.abort(new Error("the client closed the connection"))});let l=new Request(a,{method:e.method,headers:i,body:o?xs.toWeb(e):void 0,duplex:"half",signal:c.signal}),u=await t(l,{remoteAddress:e.socket.remoteAddress});if(s.statusCode=u.status,u.headers.forEach((h,f)=>s.setHeader(f,h)),r.on&&s.setHeader("connection","close"),u.body)for await(let h of u.body)s.write(h);s.end()}catch(n){d.error("[palbase] the request could not be answered",{error:n}),s.headersSent||(s.statusCode=500),s.end()}}function Ls(t,e,s=r=>console.warn(r)){let r=(e??"").split(",").map(o=>o.trim()).filter(o=>o!=="");if(r.length===0||t?.origins==="*")return t;let n=r.filter(o=>V(o)),a=r.filter(o=>!V(o));a.length>0&&s(`[palbase] the project's web origins ${a.map(o=>JSON.stringify(o)).join(", ")} are not CORS origins (https://host[:port], http only for localhost): browsers there are not let in`);let i=[...new Set([...t?.origins??[],...n])];return i.length===0?t:{...t,origins:i}}import{bigint as zr,boolean as Hr,check as Yr,date as Jr,defineSchema as Qr,defineTable as Xr,enumType as Zr,foreignKey as en,index as tn,integer as sn,jsonb as rn,numeric as nn,ownedByUser as an,policy as on,raw as ln,sqlType as cn,text as dn,timestamp as un,userRef as pn,uuid as hn}from"palgres/dsl";import{increment as gn,now as bn}from"palgres";function E(t){if(t instanceof A)return{data:null,error:{code:t.code,message:t.message},status:t.status};throw t}async function P(t,e){try{let s=await t();return{data:await e(s.data),error:null,status:s.status}}catch(s){return E(s)}}var Us=x("Secrets",{async get(t){if(Y(t))return null;let e=process.env[t];return typeof e=="string"&&e!==""?e:null}}),Ds=100,js=1e3,Ns=168*3600,qs={s:1,m:60,h:3600,d:86400};function Ws(t){let e=String(t).trim();if(!/^(\d+(\.\d+)?[dhms])+$/.test(e))return;let s=0;for(let[,r,,n]of e.matchAll(/(\d+(\.\d+)?)([dhms])/g))s+=Math.round(Number(r)*qs[n]*1e3);return Math.ceil(s/1e3)}function $e(t,e,s){let r="getPublicUrl",n;try{n=String(e).split("/").map(i=>K(r,"path",i)).join("%2F")}catch(i){throw i instanceof A&&i.code==="invalid_path_parameter"?new A({op:r,status:0,code:"invalid_path_parameter",message:`${r}: the object path ${JSON.stringify(e)} has an empty, "." or ".." segment: storage keeps no such object`}):i}let a=`${b.url}/storage/public/${K(r,"bucket",t)}/${n}`;return s?`${a}?variant=${encodeURIComponent(s)}`:a}function Re(t){return{path:t.path,name:t.path,bucket:t.bucket,size:t.size,contentType:t.content_type,checksum:t.checksum_sha256,...t.width!==void 0?{width:t.width}:{},...t.height!==void 0?{height:t.height}:{},...t.thumbhash!==void 0?{thumbhash:t.thumbhash}:{},variants:Object.fromEntries(Object.keys(t.variants??{}).map(e=>[e,$e(t.bucket,t.path,e)]))}}function Ks(t){return{async upload(e,s,r){let n=r?.contentType??(s instanceof Blob&&s.type!==""?s.type:void 0);try{let a=await b.storage.putObject({path:{bucket:t,path:e},headers:r?.upsert?void 0:{"If-None-Match":"*"},body:s,contentType:n});return{data:Re(a.data),error:null,status:a.status}}catch(a){return a instanceof A&&a.status===412&&a.code==="object_exists"?{data:null,error:{code:"already_exists",message:"An object already exists at that path: upload with { upsert: true } to replace it"},status:409}:E(a)}},async download(e){try{let s=await b.storage.getObject({path:{bucket:t,path:e}});if(s.status===304)throw new Error("storage answered 304 to a read that sent no entity tag");let r=s.data;try{return{data:await r.blob(),error:null,status:s.status}}catch(n){return{data:null,error:{code:"network_error",message:`the object's bytes stopped arriving: ${n instanceof Error?n.message:String(n)}`},status:0}}}catch(s){return E(s)}},getPublicUrl(e,s){return $e(t,e,s?.variant)},async createSignedUrl(e,s){let r=Ws(s?.expiresIn);return r===void 0||r<1||r>Ns?{data:null,error:{code:"bad_request",message:`expiresIn is a duration from 1s to 7d, like "15m", "1h" or "7d" (got ${JSON.stringify(s?.expiresIn)})`},status:400}:P(()=>b.storage.createSignedUrl({path:{bucket:t},body:{path:e,expires_in:r}}),n=>({signedUrl:n.url,expiresAt:n.expires_at}))},async list(e,s){let r=s?.limit??Ds,n=s?.offset??0;if(!Number.isInteger(r)||r<0||!Number.isInteger(n)||n<0)return{data:null,error:{code:"bad_request",message:"limit and offset are whole numbers, 0 or more"},status:400};let a=[],i,o=200;try{for(;a.length<r;){let c=Math.max(1,Math.min(js,n+r-a.length)),l=await b.storage.listObjects({path:{bucket:t},query:{...e?{prefix:e}:{},limit:c,...i?{cursor:i}:{}}});o=l.status;for(let u of l.data.objects)n>0?n--:a.length<r&&a.push(Re(u));if(i=l.data.next_cursor,!i)break}}catch(c){return E(c)}return{data:a,error:null,status:o}},async remove(e){let s=[];for(let r of e){try{await b.storage.deleteObject({path:{bucket:t,path:r}})}catch(n){return E(n)}s.push({path:r,name:r,bucket:t,size:0,contentType:"",checksum:"",variants:{}})}return{data:s,error:null,status:200}},move(e,s){return P(()=>b.storage.moveObject({path:{bucket:t},body:{from:e,to:s}}),()=>{})},copy(e,s){return P(()=>b.storage.copyObject({path:{bucket:t},body:{from:e,to:s}}),()=>{})}}}var Vs={bucket:Ks},Oe=t=>ee("Storage",t,Vs),Gs={bucket:t=>Oe("bucket").bucket(t),buckets:new Proxy({},{get:(t,e)=>typeof e=="string"?Oe("buckets").bucket(e):void 0})},zs=x("Notifications",{push:{send(t){let{to:e,...s}=t,r=typeof e=="string"?{user_ids:[e]}:Array.isArray(e)?{user_ids:e}:{topic:e.topic};return P(()=>b.notify.sendPush({body:{...s,to:r}}),n=>({message_ids:n.message_ids,recipients:n.message_ids.length,skipped_user_ids:n.skipped_user_ids}))}},email:{async send(t){let{to:e,templateSlug:s,...r}=t,n={...r,...s!==void 0?{template:s}:{}};if(!Array.isArray(e))return P(()=>b.notify.sendEmail({body:{...n,to:e}}),o=>({...o.message_id!==void 0?{message_id:o.message_id}:{},...o.skipped?{skipped:!0}:{}}));let a=[],i=202;for(let o of e)try{let c=await b.notify.sendEmail({body:{...n,to:o}});i=c.status,a.push(c.data.message_id??null)}catch(c){return E(c)}return{data:{message_ids:a},error:null,status:i}}}}),Ce=t=>typeof t=="boolean"?t:t!=null&&t!==0&&t!=="",Be=t=>typeof t=="string"?{name:t}:null,Fe=t=>t==="override"?"user":t,Hs=t=>t!==null&&typeof t=="object"&&!Array.isArray(t)&&"userId"in t;function Ie(){return te.getStore()?.userId}function N(t){let e=t&&"userId"in t?t.userId??void 0:Ie();return P(()=>e?b.flags.getUserValues({path:{user_id:e}}):b.flags.getValues(),s=>s.values??{})}var Me={setOverrideForUser:(t,e,s)=>P(()=>b.flags.putUserValue({path:{user_id:t,key:e},body:{value:s}}),r=>({key:r.key,value:r.value,source:Fe(r.source)})),setOverridesForUser:(t,e)=>P(()=>b.flags.putUserValues({path:{user_id:t},body:{values:e}}),s=>({values:s.values??{}})),clearOverrideForUser:(t,e)=>P(()=>b.flags.deleteUserValue({path:{user_id:t,key:e}}),s=>({key:s.key,value:s.value,source:Fe(s.source)})),clearAllOverridesForUser:t=>P(()=>b.flags.deleteUserValues({path:{user_id:t}}),e=>({deleted:e.deleted})),batchSetOverrides:t=>P(()=>b.flags.batchUserValues({body:{operations:t.map(e=>({user_id:e.userId,values:e.values}))}}),e=>({applied:e.applied}))},Ys=x("Flags",{async isEnabled(t,e){let s=r=>(d.warn(`[palbase] flag "${t}" could not be read (${r}): treating it as off`),!1);try{let r=await N(e);return r.error?s(`${r.error.code}: ${r.error.message}`):Ce(r.data[t])}catch(r){return s(r instanceof Error?r.message:String(r))}},async getVariant(t,e){let s=await N(e);return s.error?{data:null,error:s.error,status:s.status}:{data:Be(s.data[t]),error:null,status:s.status}},async getAll(t){let e=await N(t);return e.error?{data:null,error:e.error,status:e.status}:{data:Object.entries(e.data).map(([s,r])=>{let n=Be(r);return{name:s,enabled:Ce(r),...n?{variant:n}:{}}}),error:null,status:e.status}},async get(t,e,s){let r,n=!1,a;s!==void 0?(r=e,n=!0,a=s):Hs(e)?a=e:e!==void 0&&(r=e,n=!0);let i=await N(a);if(i.error)return n?{data:r??null,error:null,status:i.status}:{data:null,error:i.error,status:i.status};let o=i.data[t];return{data:o===void 0?r??null:o,error:null,status:i.status}},async setOverride(t,e){let s=Ie();return s?Me.setOverrideForUser(s,t,e):{data:null,error:{code:"no_user",message:"Flags.setOverride writes the signed-in user's value: this request has none \u2014 Flags.$asService().setOverrideForUser(userId, key, value) writes anyone's"},status:400}},$asService(){return Me}}),Js=x("Realtime",{broadcast(t,e,s){return P(()=>b.realtime.broadcast({body:{messages:[{topic:t,event:e,payload:s??{}}]}}),()=>{})},state:{set(t,e,s){return P(()=>b.realtime.writeState({body:{ops:[{topic:t,key:e,value:s}]}}),()=>{})},clear(t,e){return P(()=>b.realtime.writeState({body:{ops:[{topic:t,key:e,delete:!0}]}}),()=>{})}}});import{z as kn}from"zod";export{je as AuthUnavailable,vt as Authorize,Mt as BadRequest,He as Body,Kt as CACHE_MAX_TTL,Vt as Cache,wt as ChatPart,rt as Client,$t as Conflict,O as ContractRunEnded,Ne as Controller,lt as Cron,pt as Database,It as DeadlockDetected,Ge as Delete,Rt as DiError,Ue as EVENT_TYPES,Ys as Flags,Bt as Forbidden,St as Gateway,Pt as GatewayRefusal,qe as Get,Je as Headers,Lt as HttpError,at as Injectable,d as Log,Wt as MAX_BODY_BYTES,j as MigrationRunEnded,ot as Module,Ut as NotFound,zs as Notifications,it as On,kt as OnConnect,Et as OnDisconnect,Tt as OnEmpty,At as OnFirst,Ze as OptionalUser,Ot as PalError,b as Palbase,A as PalbaseError,Bs as PalbaseFactory,Qe as Param,Ve as Patch,We as Post,Ke as Put,ze as Query,Ye as QueryParams,Js as Realtime,et as Req,tt as RequestId,nt as Resolve,L as SchemaNotPushed,Us as Secrets,Dt as SerializationFailure,Gs as Storage,_t as Subscribe,ft as Task,ht as TaskFailure,gt as Tasks,bt as TestUserTemplate,De as TokenError,B as TokenVerifier,jt as TooManyRequests,st as TraceId,Ct as Unauthorized,Nt as UniqueViolation,mt as Upload,yt as UploadedObject,Xe as User,ct as Webhook,zr as bigint,Hr as boolean,Yr as check,$ as createApp,Jr as date,Ft as defineError,Qr as defineSchema,Xr as defineTable,Zr as enumType,en as foreignKey,dt as getRegisteredControllers,ut as getRoutes,xt as getWebhookManifest,gn as increment,tn as index,sn as integer,rn as jsonb,bn as now,nn as numeric,an as ownedByUser,on as policy,ln as raw,cn as sqlType,qt as t,dn as text,un as timestamp,pn as userRef,hn as uuid,kn as z};
|
package/dist/backend/stack.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
/*! palbase 0.
|
|
1
|
+
/*! palbase 0.11.1 — Palbase SDK License (see LICENSE) */
|
package/dist/backend/test.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.
|
|
2
|
-
import{a as u}from"../chunks/
|
|
1
|
+
/*! palbase 0.11.1 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{a as u}from"../chunks/KW6ODEYS.js";import{c as p,i as c}from"../chunks/S2KRJF6J.js";import{b as l,c as g,d as f,e as y}from"../chunks/EWBRYA7P.js";import"../chunks/26UTOC32.js";import"../chunks/NGE3D2K4.js";import"../chunks/LYEEW4UG.js";import"../chunks/EEWP43KI.js";import"../chunks/7WIMZTYB.js";import"../chunks/R3EIGCWV.js";import"../chunks/KNPQNBC2.js";import"../chunks/BUAGC2PT.js";import"../chunks/43VM626B.js";import"reflect-metadata";import{randomUUID as m}from"node:crypto";import{createFakeClient as w,typedDatabase as d}from"palgres/testing";function T(t,n,a){if(a?.acceptLanguage!==void 0&&a.strings===void 0)throw new TypeError("withServices: acceptLanguage chooses among the languages of a strings table, and none was given \u2014 { strings: await loadStringsTable(appRoot), acceptLanguage }");let{Database:r,...o}=t,e=a?.strings;return p.run({requestId:`test_${m()}`,database:r===void 0?void 0:d(r),services:o,...e!==void 0?{strings:e,locales:c(a?.acceptLanguage??null,e.source),usedLocales:[]}:{}},n)}function b(){let t=new Map,n=new Map,a=[],r=e=>{if(t.has(e))return t.get(e);if(n.has(e))return n.get(e);if(a.includes(e)){let s=[...a.slice(a.indexOf(e)),e].map(i=>i.name??String(i));throw new TypeError(`isolated(): ${s.join(" \u2192 ")} needs itself to be built \u2014 give one of them with .with(Token, value)`)}a.push(e);try{let s=Reflect.getMetadata("design:paramtypes",e)??[],i=new e(...s.map(r));return n.set(e,i),i}finally{a.pop()}},o={with(e,s){return t.set(e,s),o},get:e=>r(e)};return o}function h(){let t=w();return{db:d(t),raw:t,queries:t.queries,seed:(n,a)=>t.seed(n,a),inserted:n=>t.inserted(n),updated:n=>t.updated(n),deleted:n=>t.deleted(n)}}export{l as TestApiError,y as api,g as createTestApi,h as fakeDatabase,b as isolated,u as loadStringsTable,f as testRun,T as withServices};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! palbase 0.11.1 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
var s=class extends Error{code;constructor(t,e){super(e),this.name="FieldError",this.code=t}},f="pbe1.",g="pbl1.",k=6e4,p="[A-Za-z_][A-Za-z0-9_$]{0,62}",w=new RegExp(`^${p}\\.${p}(\\.${p})?$`);function v(o){return w.test(o)}var h=class{crypto;keys=new Map;lookupKey;timer;opts;now;constructor(t){this.opts=t,this.now=t.now??Date.now}get loaded(){return this.lookupKey!==void 0}async load(t){this.crypto??=await import("node:crypto"),this.take(await this.opts.fetch(t)),this.timer===void 0&&(this.timer=setInterval(()=>{this.opts.fetch().then(e=>this.take(e),()=>{})},k),this.timer.unref?.())}close(){clearInterval(this.timer),this.timer=void 0}take(t){let e=new Map;for(let r of t.keys)e.set(r.id,{id:r.id,key:Buffer.from(r.key,"base64url"),activatesAt:Date.parse(r.activates_at)});this.keys=e,this.lookupKey=Buffer.from(t.lookup,"base64url")}ready(){if(this.crypto===void 0||this.lookupKey===void 0)throw new s("not_loaded","the project's field keys are not loaded: await palbase.fields.load() at startup");return this.crypto}currentKey(){this.ready();let t;for(let e of this.keys.values())e.activatesAt<=this.now()&&(t===void 0||e.activatesAt>=t.activatesAt)&&(t=e);if(t===void 0)throw new s("unknown_key","the project has no field key in force");return t.id}encrypt(t,e){let r=this.ready();l(t);let n=this.currentKey(),i=r.randomBytes(12);return b(r,this.keys.get(n).key,i,n,t,e)}decrypt(t,e){let r=this.ready();if(l(t),!e.startsWith(f))throw new s("not_encrypted",`${t} holds a value that is not encrypted`);let n=e.slice(f.length),i=n.indexOf("."),a=i<0?n:n.slice(0,i),u=this.keys.get(a);if(u===void 0)throw new s("unknown_key",`${t} was sealed with field key ${a}, which this project does not hold`);let c=Buffer.from(n.slice(i+1),"base64url");if(i<0||c.length<28||c.toString("base64url")!==n.slice(i+1))throw new s("unopenable",`${t} holds a value that does not open here`);try{let d=r.createDecipheriv("aes-256-gcm",u.key,c.subarray(0,12));return d.setAAD(y(t)),d.setAuthTag(c.subarray(c.length-16)),Buffer.concat([d.update(c.subarray(12,c.length-16)),d.final()]).toString("utf8")}catch{throw new s("unopenable",`${t} holds a value that does not open here: tampered, or another column's`)}}isEncrypted(t){return t.startsWith(f)}lookup(t,e){let r=this.ready();return l(t),m(r,this.lookupKey,t,e)}};function l(o){if(!v(o))throw new TypeError(`a field's address is table.column, or schema.table.column, not ${JSON.stringify(o)}`)}function y(o){return Buffer.from(`pbe1\0${o}`,"utf8")}function b(o,t,e,r,n,i){let a=o.createCipheriv("aes-256-gcm",t,e);a.setAAD(y(n));let u=Buffer.concat([e,a.update(i,"utf8"),a.final(),a.getAuthTag()]);return`${f}${r}.${u.toString("base64url")}`}function m(o,t,e,r){let n=o.createHmac("sha256",t);return n.update(`pbl1\0${e}\0`,"utf8"),n.update(r,"utf8"),`${g}${n.digest("base64url")}`}export{s as a,h as b};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! palbase 0.
|
|
2
|
-
import{p as R,t as k,u as H}from"./
|
|
1
|
+
/*! palbase 0.11.1 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{p as R,t as k,u as H}from"./3VY3ZZCI.js";var N=40,V=`
|
|
3
3
|
:host{display:contents}
|
|
4
4
|
.pm-modal,.pm-full{position:fixed;inset:0;width:100%;height:100%;max-width:none;max-height:none;margin:0;border:0;background:transparent;color:inherit;overflow:hidden;display:flex;flex-direction:column}
|
|
5
5
|
.pm-modal::backdrop,.pm-full::backdrop{background:transparent}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! palbase 0.
|
|
1
|
+
/*! palbase 0.11.1 — Palbase SDK License (see LICENSE) */
|
|
2
2
|
var Rt=d=>[...new Uint8Array(d)].map(t=>t.toString(16).padStart(2,"0")).join(""),At=d=>`pw-font-${d}`;function ne(d){return(typeof d=="string"?/^asset:([0-9a-f-]{36})$/.exec(d):null)?.[1]}async function an(d,t={}){let a={},l=t.fetch??((c,p)=>globalThis.fetch(c,p));return await Promise.all(d.map(async c=>{try{if(!/^https:\/\//.test(c.url))return;let p=await l(c.url,{signal:t.signal,credentials:"omit"});if(!p.ok)return;let g=await p.arrayBuffer();if(g.byteLength!==c.bytes&&c.bytes>0||Rt(await globalThis.crypto.subtle.digest("SHA-256",g))!==c.sha256.toLowerCase())return;let w=_t(c.kind,new Uint8Array(g));if(w===void 0)return;let y=await Et(c,g,w,t);y&&(a[c.id]=y)}catch{}})),a}var C=(d,t,a=0)=>d.length>=a+t.length&&t.every((l,c)=>d[a+c]===l),W=d=>[...d].map(t=>t.charCodeAt(0));function _t(d,t){switch(d){case"image":return C(t,[137,80,78,71,13,10,26,10])?"image/png":C(t,[255,216,255])?"image/jpeg":C(t,W("RIFF"))&&C(t,W("WEBP"),8)?"image/webp":void 0;case"video":return C(t,W("ftyp"),4)?C(t,W("qt "),8)?"video/quicktime":"video/mp4":C(t,[26,69,223,163])?"video/webm":void 0;case"font":return C(t,W("wOF2"))?"font/woff2":C(t,W("wOFF"))?"font/woff":C(t,W("OTTO"))?"font/otf":C(t,[0,1,0,0])||C(t,W("true"))?"font/ttf":void 0;case"html":return C(t,[80,75,3,4])||C(t,[80,75,5,6])?"application/zip":void 0;default:return}}async function Et(d,t,a,l){switch(d.kind){case"image":case"video":return{kind:d.kind,url:URL.createObjectURL(new Blob([t],{type:a}))};case"font":{let c=At(d.id),p=globalThis.FontFace,g=l.fonts??globalThis.document?.fonts;if(!p||!g)return;let h=new p(c,t,{display:"block"});return await h.load(),g.add(h),{kind:"font",url:"",family:c}}case"html":{let c=await Lt(new Uint8Array(t)),p=Ot(c);return p===void 0?void 0:{kind:"html",url:"",html:p}}}}async function Lt(d){let t=new DataView(d.buffer,d.byteOffset,d.byteLength),a=-1;for(let h=d.length-22;h>=Math.max(0,d.length-22-65535);h--)if(t.getUint32(h,!0)===101010256){a=h;break}if(a<0)throw new Error("not a zip");let l=t.getUint16(a+10,!0),c=t.getUint32(a+16,!0),p=new Map,g=0;for(let h=0;h<l;h++){if(t.getUint32(c,!0)!==33639248)throw new Error("a broken zip");let w=t.getUint16(c+10,!0),y=t.getUint32(c+20,!0),m=t.getUint32(c+24,!0),v=t.getUint16(c+28,!0),_=t.getUint16(c+30,!0),P=t.getUint16(c+32,!0),R=t.getUint32(c+42,!0),x=new TextDecoder().decode(d.subarray(c+46,c+46+v));if(c+=46+v+_+P,x.endsWith("/"))continue;if(x.startsWith("/")||x.split("/").includes(".."))throw new Error("a path leaving the zip");if(g+=m,p.size>=200||g>20971520)throw new Error("a zip too large");let T=R+30+t.getUint16(R+26,!0)+t.getUint16(R+28,!0),O=d.subarray(T,T+y);if(w===0)p.set(x,O);else if(w===8)p.set(x,await Pt(O));else throw new Error("a zip entry compressed another way")}return p}async function Pt(d){let t=new Response(new Uint8Array(d)).body.pipeThrough(new DecompressionStream("deflate-raw"));return new Uint8Array(await new Response(t).arrayBuffer())}var Tt={html:"text/html",css:"text/css",js:"text/javascript",mjs:"text/javascript",json:"application/json",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",webp:"image/webp",gif:"image/gif",svg:"image/svg+xml",mp4:"video/mp4",webm:"video/webm",woff2:"font/woff2",woff:"font/woff",ttf:"font/ttf",otf:"font/otf"};function qe(d,t){let a=Tt[d.split(".").pop()?.toLowerCase()??""]??"application/octet-stream",l="";for(let c=0;c<t.length;c+=32768)l+=String.fromCharCode(...t.subarray(c,c+32768));return`data:${a};base64,${btoa(l)}`}var $t="default-src 'none'; img-src data:; media-src data:; font-src data:; style-src 'unsafe-inline' data:; script-src 'unsafe-inline' data:";function Ot(d){let t=d.get("index.html");if(!t)return;let a=new TextDecoder().decode(t),l=y=>new TextDecoder().decode(d.get(y)),c=y=>{let m=y.replace(/^\.\//,"").split(/[?#]/)[0];return d.has(m)?m:void 0},p=y=>y.replace(/url\(\s*(['"]?)([^'")]+)\1\s*\)/g,(m,v,_)=>{let P=c(_);return P?`url("${qe(P,d.get(P))}")`:m}),g=globalThis.DOMParser;if(!g)return;let h=new g().parseFromString(a,"text/html");for(let y of[...h.querySelectorAll('link[rel~="stylesheet"][href]')]){let m=c(y.getAttribute("href")),v=h.createElement("style");v.textContent=m?p(l(m)):"",y.replaceWith(v)}for(let y of[...h.querySelectorAll("style")])y.textContent=p(y.textContent??"");for(let y of[...h.querySelectorAll("[src], [href], [poster]")])for(let m of["src","href","poster"]){let v=y.getAttribute(m);if(v===null)continue;let _=c(v);_?y.setAttribute(m,qe(_,d.get(_))):/^(https?:)?\/\//i.test(v)&&y.removeAttribute(m)}for(let y of[...h.querySelectorAll("[style]")])y.setAttribute("style",p(y.getAttribute("style")??""));let w=h.createElement("meta");return w.setAttribute("http-equiv","Content-Security-Policy"),w.setAttribute("content",$t),h.head.prepend(w),`<!doctype html>${h.documentElement.outerHTML}`}var K=(d,t,a)=>`M${d-a} ${t}a${a} ${a} 0 1 0 ${2*a} 0a${a} ${a} 0 1 0 ${-2*a} 0`,de={ad_free:["M3 7h18v10H3z","M4 4l16 16"],bell:["M6 16v-5a6 6 0 0 1 12 0v5l2 2H4z","M10 21a2 2 0 0 0 4 0"],bolt:["M13 2L4 14h7l-1 8 9-12h-7z"],book:["M5 4h11a3 3 0 0 1 3 3v13H8a3 3 0 0 1-3-3z","M5 17a3 3 0 0 1 3-3h11"],chart:["M3 20h18","M6 20v-8","M11 20V5","M16 20v-6","M21 20V9"],chat:["M4 5h16v11H9l-5 4z"],check:["M5 12l5 5 9-10"],check_circle:[K(12,12,9),"M8 12l3 3 5-6"],clock:[K(12,12,9),"M12 7v5l3 2"],cloud:["M7 18a4 4 0 0 1-.5-7.97A6 6 0 0 1 18 9a4.5 4.5 0 0 1-.5 9z"],crown:["M3 8l4 4 5-7 5 7 4-4-2 11H5z"],download:["M12 4v11","M7 10l5 5 5-5","M4 20h16"],gift:["M3 9h18v4H3z","M5 13v8h14v-8","M12 9v12","M12 9C10 5 6 5 6 7.5S12 9 12 9zm0 0c2-4 6-4 6-1.5S12 9 12 9z"],globe:[K(12,12,9),"M3 12h18","M12 3a14 14 0 0 1 0 18a14 14 0 0 1 0-18z"],heart:["M12 20s-7-4.5-9-9a4.5 4.5 0 0 1 9-3 4.5 4.5 0 0 1 9 3c-2 4.5-9 9-9 9z"],infinity:["M7 9a3 3 0 1 0 0 6c3 0 7-6 10-6a3 3 0 1 1 0 6c-3 0-7-6-10-6z"],lock_open:["M5 11h14v10H5z","M8 11V7a4 4 0 0 1 7.5-2"],music:["M9 18V5l11-2v13",K(6,18,3),K(17,16,3)],people:[K(9,8,3.5),"M2 20a7 7 0 0 1 14 0","M16 4.5a3.5 3.5 0 0 1 0 7","M18 14a6 6 0 0 1 4 6"],person:[K(12,8,4),"M4 21a8 8 0 0 1 16 0"],photo:["M3 5h18v14H3z",K(8.5,9.5,1.5),"M3 17l5-5 4 4 3-3 6 6"],shield:["M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6z"],sparkles:["M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8z","M19 15l.8 2.2L22 18l-2.2.8L19 21l-.8-2.2L16 18l2.2-.8z"],star:["M12 3l2.8 5.7 6.2.9-4.5 4.4 1 6.2L12 17.3l-5.5 2.9 1-6.2L3 9.6l6.2-.9z"],video:["M3 6h12v12H3z","M15 10l6-3v10l-6-3z"],arrow_right:["M4 12h15","M13 6l6 6-6 6"],calendar:["M4 6h16v15H4z","M4 10h16","M8 3v5","M16 3v5"],close:["M6 6l12 12","M18 6L6 18"],lock:["M5 11h14v10H5z","M8 11V7a4 4 0 0 1 8 0v4"],play:["M7 4l13 8-13 8z"],quote:["M5 17c3 0 4-2 4-5V7H4v5h3","M15 17c3 0 4-2 4-5V7h-5v5h3"],trophy:["M7 4h10v5a5 5 0 0 1-10 0z","M7 6H4v2a3 3 0 0 0 3 3","M17 6h3v2a3 3 0 0 1-3 3","M12 14v4","M8 21h8","M9 18h6v3H9z"]};var Be="http://www.w3.org/2000/svg";function pe(d,t,a){let l=d.createElementNS(Be,"svg");l.setAttribute("viewBox","0 0 24 24"),l.setAttribute("width",String(a)),l.setAttribute("height",String(a)),l.setAttribute("fill","none"),l.setAttribute("stroke","currentColor"),l.setAttribute("stroke-width","2"),l.setAttribute("stroke-linecap","round"),l.setAttribute("stroke-linejoin","round"),l.setAttribute("aria-hidden","true"),l.setAttribute("focusable","false");for(let c of t){let p=d.createElementNS(Be,"path");p.setAttribute("d",c),l.append(p)}return l}var dn=2,pn=2,f=(d,t=!1)=>({kind:"value",value:"plain",def:d,required:t}),j=d=>({kind:"value",value:"color",def:d}),We=d=>({kind:"value",value:"spacing",def:d}),zt=d=>({kind:"value",value:"radius",def:d}),X=(d=!1)=>({kind:"text",required:d}),Me=(d,t=!1)=>({kind:"list",item:d,required:t}),se=(d,t=!1)=>({kind:"object",item:d,required:t}),Ke=(d=!1)=>({kind:"component",required:d}),Re={kind:"components"},Ge={stack:{axis:f("vertical"),spacing:We(0),align:f("center"),distribution:f("start"),scroll:f(!1),children:Re},text:{text:X(),spans:Me("span"),font:f(),size:f(),weight:f(),line_height:f(),letter_spacing:f(),color:{kind:"value",value:"textColor",def:"text"},align:f("center"),max_lines:f(),uppercase:f(!1)},image:{src:f(void 0,!0),fit:f("fit"),aspect:f(),mask:se("mask"),overlay:{kind:"value",value:"textColor"},alt:X(),decorative:f(!1)},icon:{name:f(void 0,!0),color:j("accent"),size:f(24)},video:{src:f(void 0,!0),poster:f(),autoplay:f(!0),loop:f(!0),mute:f(!0),controls:f(!1),fit:f("fill"),aspect:f(),alt:X()},button:{action:se("action",!0),content:Ke(!0)},purchase_button:{content:Ke(!0),package:f()},package:{product:f(void 0,!0),plan:f(void 0,!0),selected:f(!1),offer:f(),children:Re},tabs:{},switch:{},carousel:{pages:Re,peek:f(0),spacing:f(8),loop:f(!1),auto_advance_ms:f(),indicator:se("indicator"),height:f("")},countdown:{},timeline:{items:Me("timeline_item",!0),line_color:j("accent"),line_width:f(2),icon_color:j("on_accent"),color:j("text"),spacing:f(16)},features:{items:Me("feature",!0),icon_color:j("accent"),color:j("text"),spacing:f(12)},spacer:{size:We()},divider:{color:j("muted"),thickness:f(1)},custom_html:{src:f(void 0,!0),height:f("",!0)}},Ht={style:{padding:{kind:"edges"},margin:{kind:"edges"},width:f(""),height:f(""),max_width:f(),background:{kind:"fill"},border:se("border"),corners:{kind:"corners"},shadow:se("shadow"),opacity:f(1)},border:{width:f(),color:j("")},shadow:{color:j(""),radius:f(0),x:f(0),y:f(0)},linear:{type:f(""),angle:f(180),stops:f()},radial:{type:f(""),center_x:f(.5),center_y:f(.5),radius:f(.5),stops:f()},image_fill:{type:f(""),src:f(),fit:f("fill")},video_fill:{type:f(""),src:f(),poster:f(),loop:f(!0)},animation:{type:f(""),duration_ms:f(300),delay_ms:f(0),easing:f("ease_out")},action:{type:f(""),url:f(),sheet:f(),package:f()},mask:{shape:f(""),radius:zt(0),depth:f(16)},span:{text:X(!0),bold:f(!1),italic:f(!1),underline:f(!1),strikethrough:f(!1),color:j(""),link:f()},timeline_item:{icon:f(void 0,!0),title:X(!0),text:X(),color:j("")},feature:{icon:f(void 0,!0),text:X(!0)},indicator:{style:f("dots"),color:j("muted"),active_color:j("accent"),size:f(8),spacing:f(6)},typography:{font:f("system"),size:f(),weight:f(400),line_height:f(),letter_spacing:f(0),text_style:f("body")}},Xe=new Set(["package","purchase_button"]),Ct={action:{type:f(""),url:f(),link:f(),sheet:f(),placement:f(),name:f(),value:f(),offer:f(),dismiss:f(!0)},presentation:{type:f(""),position:f("bottom"),auto_dismiss_seconds:f(),dismissible:f(!0),backdrop:j("#00000080")}},jt={modal:["type","dismissible","backdrop"],fullscreen:["type"],banner:["type","position","auto_dismiss_seconds","dismissible"],card:["type"]},Ft={linear:"linear",radial:"radial",image:"image_fill",video:"video_fill"},Nt=["top","bottom","leading","trailing"],Dt=["top_leading","top_trailing","bottom_leading","bottom_trailing"],Jt=Object.keys(Ge),un=Jt.filter(d=>!Xe.has(d)),Ye=/\{\{\s*([^{}]*?)\s*\}\}/g,Q=(d,t)=>typeof d=="object"&&d!==null&&Object.hasOwn(d,t),M=d=>typeof d=="object"&&d!==null&&!Array.isArray(d)?d:{},I=d=>Array.isArray(d)?d:[],G=(d,t)=>d??t;function It(d){let t="";for(let a of new TextEncoder().encode(d)){let l=String.fromCharCode(a);t+=/^[A-Za-z0-9._~-]$/.test(l)?l:`%${a.toString(16).toUpperCase().padStart(2,"0")}`}return t}function Vt(d){let t=Math.floor(d/86400),a=Math.floor(d%86400/3600),l=Math.floor(d%3600/60),c=d%60,p=h=>String(h).padStart(2,"0");return{countdown:t>0?`${t}d ${p(a)}:${p(l)}:${p(c)}`:a>0?`${a}:${p(l)}:${p(c)}`:`${p(l)}:${p(c)}`,days:String(t),hours:p(a),minutes:p(l),seconds:p(c)}}function fn(d){let t=[],a=c=>{if(Array.isArray(c))return c.forEach(a);if(typeof c!="object"||c===null)return;let p=c;if(p.type==="package"&&typeof p.product=="string"&&typeof p.plan=="string"){let g=`${p.product}.${p.plan}`;t.includes(g)||t.push(g)}for(let g of Object.keys(p).sort())a(p[g])},l=d;for(let c of["header","root","footer"])a(l[c]);for(let c of Object.keys(M(l.sheets)).sort())a(M(M(l.sheets)[c]).root);return t}function Ut(d){let t=new Map,a=c=>{if(Array.isArray(c))return c.forEach(a);if(typeof c!="object"||c===null)return;let p=c;if(p.type==="package"&&typeof p.offer=="string"){let g=`${p.product}.${p.plan}`;t.has(g)||t.set(g,p.offer)}for(let g of Object.keys(p).sort())a(p[g])},l=d;for(let c of["header","root","footer","sheets"])a(l[c]);return t}function gn(d,t){return _e(d,t).tree}function _e(d,t){return new ue("paywall",d,t).resolve()}function hn(d,t){return Ee(d,t).tree}function Ee(d,t){let{variables:a,...l}=t;return new ue("message",d,{...l,packages:{"":{...a}}}).resolve()}var ue=class{kind;d;opts;lang;texts={};palette;typography={};radii;spacing;packages;offers;selected="";tab="";paths=new WeakMap;tabsShown={};switchesOn={};countdowns={};constructor(t,a,l){this.kind=t,this.d=a,this.opts=l,this.offers=Ut(a);let c={};for(let[y,m]of Object.entries(l.packages??{})){let v={...m};this.open(y)||(m.price!==void 0?v.offer_price=m.price:delete v.offer_price),c[y]=v}this.packages=c;let p=M(this.d.locales),g=String(this.d.default_locale??""),h=l.locale;Q(p,h)||(h=h.split("-")[0]??"",Q(p,h)||(h=g)),this.lang=h;for(let y of[g,h])for(let[m,v]of Object.entries(M(p[y])))typeof v=="string"&&(this.texts[m]=v);let w=M(this.d.theme);this.palette=M(M(w.colors)[l.appearance]);for(let[y,m]of Object.entries(M(w.typography))){let v={};for(let[_,P]of Object.entries(this.objectFields("typography"))){let R=G(M(m)[_],P.def);R!=null&&(v[_]=R)}this.typography[y]=v}this.radii=M(w.radii),this.spacing=M(w.spacing)}open(t){let a=this.offers.get(t);return a!==void 0&&(this.opts.offers??[]).includes(a)}fields(t){if(!(this.kind==="message"&&Xe.has(t)))return Ge[t]}objectFields(t){return(this.kind==="message"?Ct[t]:void 0)??Ht[t]??{}}resolve(){let[t,a]=this.initialState();this.tab=t,this.selected=this.kind==="paywall"?a:"";let l={theme:{colors:this.palette,typography:this.typography,radii:this.radii,spacing:this.spacing}};this.kind==="paywall"&&(l.selected=a);let c=this.d.presentation;if(typeof c=="object"&&c!==null){let g=this.item("presentation",M(c),void 0)??{},h=jt[String(M(c).type)]??[];for(let w of Object.keys(g))h.includes(w)||delete g[w];l.presentation=g}for(let g of["header","root","footer"]){let h=this.d[g];if(typeof h=="object"&&h!==null){let w=this.component(M(h),g,"",!1);w&&(l[g]=w)}}let p={};if(typeof this.d.sheets=="object"&&this.d.sheets!==null){let g={};for(let[h,w]of Object.entries(M(this.d.sheets))){let y=this.component(M(M(w).root),`sheets.${h}.root`,"",!1);y&&(g[h]=y);let m=this.text(M(w).title,this.packages[this.selected]);m!==null&&(p[h]=m)}l.sheets=g}return{tree:l,pathOf:g=>this.paths.get(g),tabs:this.tabsShown,switches:this.switchesOn,sheetTitles:p,countdowns:this.countdowns,language:this.lang}}switchOn(t,a){return this.opts.switches&&Object.hasOwn(this.opts.switches,a)?this.opts.switches[a]:this.opts.switch?this.opts.switch==="on":t.default===!0}tabShown(t,a){let c=I(t.tabs).map(M).map(g=>String(g.id)),p=this.opts.tabs?.[a];return p!==void 0&&c.includes(p)?p:this.opts.tab?this.opts.tab:typeof t.default=="string"&&t.default!==""?t.default:c[0]??""}initialState(){let t="",a="",l="",c="",p=(h,w)=>{if(Array.isArray(h)){h.forEach((m,v)=>p(m,`${w}[${v}]`));return}if(typeof h!="object"||h===null)return;let y=h;switch(y.type){case"package":{let m=`${y.product}.${y.plan}`;l===""&&(l=m),y.selected===!0&&a===""&&(a=m);break}case"switch":{let m=this.switchOn(y,w),v=m?y.on_package:y.off_package;typeof v=="string"&&c===""&&(c=v),p(m?y.on:y.off,`${w}.${m?"on":"off"}`);return}case"tabs":{let m=this.tabShown(y,w);t===""&&(t=m),I(y.tabs).forEach((v,_)=>{let P=M(v);P.id===m&&(typeof P.package=="string"&&c===""&&(c=P.package),p(P.content,`${w}.tabs[${_}].content`))});return}}for(let m of Object.keys(y).sort())m!=="sheets"&&p(y[m],w===""?m:`${w}.${m}`)};for(let h of["header","root","footer"])p(this.d[h],h);let g=this.opts.selected||c||a||l;return[t,g]}holds(t,a){let l=a||this.selected;for(let[c,p]of Object.entries(t))switch(c){case"selected_package":if(!I(p).includes(this.selected))return!1;break;case"intro_eligible":if((this.opts.eligible??[]).includes(l)!==p)return!1;break;case"offer_open":if(this.open(l)!==p)return!1;break;case"platform":if(!I(p).includes(this.opts.platform))return!1;break;case"locale":if(!I(p).includes(this.opts.locale)&&!I(p).includes(this.lang))return!1;break;case"appearance":if(p!==this.opts.appearance)return!1;break;case"tab":if(p!==this.tab)return!1;break}return!0}component(t,a,l,c){if(typeof t.visible=="object"&&t.visible!==null&&!this.holds(M(t.visible),l))return null;let p=String(t.type),g=l,h=c;p==="package"&&(g=`${t.product}.${t.plan}`,h=g===this.selected);let w={type:p};this.paths.set(w,a),Q(t,"id")&&(w.id=t.id);let y={...M(t.style)};h&&Object.assign(y,M(M(t.states).selected)),Object.keys(y).length>0&&(w.style=this.style(y)),typeof t.animation=="object"&&t.animation!==null&&(w.animation=this.defaults(M(t.animation),this.objectFields("animation")));let m=this.packages[g||this.selected];switch(p){case"tabs":return this.tabs(t,w,a,g);case"switch":return this.switchOf(t,w,a,g,h);case"countdown":return this.countdown(t,w,a,g,h);case"purchase_button":{let v=typeof t.package=="string"?t.package:this.selected;w.package=v,this.open(v)&&(w.offer=this.offers.get(v));let _=this.component(M(t.content),`${a}.content`,v,h);return _?(w.content=_,w):null}case"package":w.product=t.product,w.plan=t.plan,w.selected=h,typeof t.offer=="string"&&(this.opts.offers??[]).includes(t.offer)&&(w.offer=t.offer)}for(let[v,_]of Object.entries(this.fields(p)??{})){if(p==="package"&&(v==="product"||v==="plan"||v==="selected"||v==="offer"))continue;let P=t[v],R=Q(t,v);switch(_.kind){case"component":{if(!R)continue;let x=this.component(M(P),`${a}.${v}`,g,h);if(!x&&_.required)return null;x&&(w[v]=x);break}case"components":{let x=[];I(P).forEach((T,O)=>{let V=this.component(M(T),`${a}.${v}[${O}]`,g,h);V&&x.push(V)}),w[v]=x;break}case"text":{let x=this.text(P,m);if(x!==null)w[v]=x;else if(_.required||p==="text"&&v==="text"&&R)return null;break}case"list":{let x=[];for(let T of I(P)){let O=this.item(_.item,M(T),m);O&&x.push(O)}if(p==="text"&&x.length===0&&R)return null;R&&(w[v]=x);break}case"object":{if(R){let x=this.object(M(P),_.item,m);if(x===null&&_.required)return null;w[v]=x}else v==="indicator"&&(w[v]=this.object({},_.item,m));break}case"value":{let x=this.value(G(P,_.def),_);x!=null&&x!==""&&(w[v]=x);break}}}return p==="text"&&this.typeStyle(w),w}typeStyle(t){if(typeof t.size!="string"){t.size!==void 0&&t.size!==null&&(t.text_style="body");return}let a=this.typography[t.size];for(let l of["font","weight","line_height","letter_spacing","text_style"])!Q(t,l)&&a?.[l]!==void 0&&a?.[l]!==null&&(t[l]=a[l]);t.size=a?.size??null}tabs(t,a,l,c){let p=this.tabShown(t,l);this.tabsShown[l]=p;let g=[];return I(t.tabs).forEach((h,w)=>{let y=M(h),m=y.id===p,v=this.component(M(y.label),`${l}.tabs[${w}].label`,c,m);if(g.push({id:y.id,selected:m,label:v}),m){let _=this.component(M(y.content),`${l}.tabs[${w}].content`,c,!1);_&&(a.content=_)}}),a.tabs=g,typeof t.bar=="object"&&t.bar!==null&&(a.bar=this.style(M(t.bar))),a}switchOf(t,a,l,c,p){let g=this.switchOn(t,l);this.switchesOn[l]=g,a.on=g;let h=this.text(t.label,this.packages[c||this.selected]);h!==null&&(a.label=h),a.tint=this.color(String(G(t.tint,"accent")));let w=g?"on":"off",y=this.component(M(t[w]),`${l}.${w}`,c,p);return y&&(a.content=y),a}countdown(t,a,l,c,p){let g=M(t.target),h=this.opts.now??Date.now(),w;if(typeof g.after_open_seconds=="number"?w=Math.trunc(g.after_open_seconds)-(this.opts.openedSecondsAgo??0):w=Math.trunc((Date.parse(String(g.at))-h)/1e3),w>0){a.state="counting",a.remaining_seconds=w,this.countdowns[l]=w;let y=this.packages,m={};for(let[_,P]of Object.entries(y))m[_]={...P,...Vt(w)};this.packages=m;let v=this.component(M(t.counting),`${l}.counting`,c,p);return v&&(a.content=v),this.packages=y,a}if(a.state="ended",a.remaining_seconds=0,typeof t.ended=="object"&&t.ended!==null){let y=this.component(M(t.ended),`${l}.ended`,c,p);y&&(a.content=y)}return a}item(t,a,l){let c={};for(let[p,g]of Object.entries(this.objectFields(t))){let h=a[p];if(g.kind==="text"){let w=this.text(h,l);if(w!==null)c[p]=w;else if(g.required)return null}else{let w=g.def,y=this.value(G(h,w),g);y!=null&&(Q(a,p)||w!=null&&w!=="")&&(c[p]=y)}}return c}object(t,a,l){if(a==="style")return this.style(t);let c=this.item(a,t,l)??{};if(a==="action")for(let p of["url","link"]){if(typeof c[p]!="string")continue;let g=qt(c[p],l);if(g===null)return null;c[p]=g}return c}defaults(t,a){let l={};for(let[c,p]of Object.entries(a)){let g=G(t[c],p.def);g!=null&&g!==""&&(l[c]=g)}return l}style(t){let a={};for(let[l,c]of Object.entries(t)){let p=this.objectFields("style")[l];if(!p){a[l]=c;continue}switch(p.kind){case"edges":a[l]=this.sides(c,Nt,this.spacing);break;case"corners":a[l]=this.sides(c,Dt,this.radii);break;case"fill":a[l]=this.fill(c);break;case"object":{let g=M(c),h={};for(let[w,y]of Object.entries(this.objectFields(p.item))){let m=G(g[w],y.def);m!=null&&m!==""&&(h[w]=this.value(m,y))}a[l]=h;break}default:a[l]=c}}return a}sides(t,a,l){let c={};for(let p of a){let g=typeof t=="object"&&t!==null?G(M(t)[p],0):t;c[p]=Ae(g,l)}return c}fill(t){if(typeof t=="string")return{type:"color",color:this.color(t)};let a=M(t),l=this.defaults(a,this.objectFields(Ft[String(a.type)]??""));return Array.isArray(a.stops)&&(l.stops=a.stops.map(c=>({color:this.color(String(M(c).color)),at:M(c).at}))),l}value(t,a){if(a.kind!=="value")return t;switch(a.value){case"color":return typeof t=="string"&&t!==""?this.color(t):t;case"textColor":return typeof t=="string"?this.color(t):t==null?t:this.fill(t);case"spacing":return Ae(t,this.spacing);case"radius":return Ae(t,this.radii);default:return t}}color(t){let a=Object.hasOwn(this.palette,t)?this.palette[t]:void 0;return typeof a=="string"?a:t}text(t,a){let l;if(typeof t=="string")l=t;else if(typeof t=="object"&&t!==null&&!Array.isArray(t)){let p=t.t;l=typeof p=="string"&&Object.hasOwn(this.texts,p)?this.texts[p]:""}else return null;let c=!1;return l=l.replace(Ye,(p,g)=>{let h=a&&Object.hasOwn(a,g)?a[g]:void 0;return typeof h!="string"||h===""?(c=!0,""):h}),c||l.trim()===""?null:l}};function qt(d,t){let a=!1,l=d.replace(Ye,(c,p)=>{let g=t&&Object.hasOwn(t,p)?t[p]:void 0;return typeof g!="string"||g===""?(a=!0,""):It(g)});return a?null:l}function Ae(d,t){return typeof d=="string"?Object.hasOwn(t,d)?t[d]:null:d}var Bt={packages:"Choose a plan",close:"Close",restore:"Restore purchases",page:(d,t)=>`${d} of ${t}`},ee={system:'-apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',rounded:'ui-rounded, "SF Pro Rounded", Nunito, "Varela Round", system-ui, -apple-system, sans-serif',serif:'ui-serif, "New York", "Iowan Old Style", Georgia, "Times New Roman", serif',mono:'ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace'},Wt=1.35,Ze=20,Kt=new Set(["button","purchase_button","package","text"]),Gt=new Set(["ar","he","fa","ur","ps","yi","dv","ug","ku","sd"]),Qe={ease_out:"cubic-bezier(0.16, 1, 0.3, 1)",ease_in_out:"cubic-bezier(0.65, 0, 0.35, 1)",spring:"cubic-bezier(0.34, 1.56, 0.64, 1)"},Xt={start:"flex-start",center:"center",end:"flex-end",stretch:"stretch"},Yt={start:"flex-start",center:"center",end:"flex-end",space_between:"space-between",space_around:"space-around",space_evenly:"space-evenly"},Zt={stack:["children"],package:["children"],button:["content"],purchase_button:["content"],tabs:["tabs","content"],switch:["content"],carousel:["pages"],countdown:["content"]},Qt={package:["selected"],purchase_button:["package"],switch:["on"],countdown:["state","remaining_seconds"]},en=`
|
|
3
3
|
:host{display:block;height:100%}
|
|
4
4
|
.pw2{position:relative;box-sizing:border-box;display:flex;flex-direction:column;height:100%;overflow:hidden;font-family:${ee.system};font-size:1rem;line-height:1.3;-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;text-rendering:optimizeLegibility}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.
|
|
1
|
+
/*! palbase 0.11.1 — Palbase SDK License (see LICENSE) */
|
|
2
2
|
var d=Object.defineProperty;var e=(c,a)=>{for(var b in a)d(c,b,{get:a[b],enumerable:!0})};export{e as a};
|