palbase 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +7 -7
- package/dist/backend/stack.js +1 -1
- package/dist/backend/test.js +2 -2
- package/dist/chunks/{3AUBDHV2.js → 4ZVJ62A3.js} +1 -1
- package/dist/chunks/{FSXD7MN3.js → 5G3URQAW.js} +2 -2
- package/dist/chunks/{32RCJNOH.js → 6I6CETZY.js} +3 -3
- package/dist/chunks/{EHJKMDP3.js → EDVRVUCJ.js} +2 -2
- package/dist/chunks/{DNHDO6AJ.js → FNUO6DSY.js} +1 -1
- package/dist/chunks/{B45UFKBR.js → HLYQRT7O.js} +2 -2
- package/dist/chunks/{7BA7LGEM.js → JHQDWDV3.js} +2 -2
- package/dist/chunks/{A7EL6JKQ.js → K2LVOEW3.js} +2 -2
- package/dist/chunks/{R43DXJZE.js → LHLMCQKI.js} +2 -2
- package/dist/chunks/{TTZRGQWF.js → MYNCDAKM.js} +1 -1
- package/dist/chunks/{ZXYDN6NA.js → NQA7ZLGD.js} +1 -1
- package/dist/chunks/{AWHTWL65.js → QHJ4OPPI.js} +2 -2
- package/dist/chunks/{PALOWH6U.js → QHPZF7VM.js} +2 -2
- package/dist/chunks/{PFSUOVTB.js → TPBWIRHS.js} +1 -1
- package/dist/chunks/{KSJ6AMCG.js → XRW7YOUQ.js} +2 -2
- package/dist/chunks/{QIN2NQPN.js → ZJOO2XZ2.js} +2 -2
- package/dist/cli.js +2 -2
- 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/palbe.js +2 -2
- package/dist/web/paywall.js +2 -2
- package/dist/web/vite.js +2 -2
- package/package.json +2 -2
- package/types/backend/src/database.d.ts +3 -3
package/dist/ai/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! palbase 0.5.
|
|
2
|
-
import{a as le,b as pe,c as ue,d as me,f as J,g as fe,h as z}from"../chunks/
|
|
1
|
+
/*! palbase 0.5.2 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{a as le,b as pe,c as ue,d as me,f as J,g as fe,h as z}from"../chunks/QHPZF7VM.js";import{a as ge}from"../chunks/NQA7ZLGD.js";import{a as se}from"../chunks/QHJ4OPPI.js";import{a as ie,b as de,c as ce}from"../chunks/5G3URQAW.js";import{b as $,d as oe}from"../chunks/HLYQRT7O.js";import"../chunks/TPBWIRHS.js";import"../chunks/MYNCDAKM.js";var Oe=/\s/;function L(e,t){for(;t<e.length&&Oe.test(e[t]);)t++;return t}function he(e,t){let r="";for(let n=t+1;n<e.length;n++){let i=e[n];if(i==='"')return{value:r,complete:!0,empty:!1,at:n+1};if(i!=="\\"){r+=i;continue}let u=e[n+1];if(u===void 0)break;if(u==="u"){let c=e.slice(n+2,n+6);if(c.length<4)break;r+=String.fromCharCode(Number.parseInt(c,16)),n+=5;continue}r+={n:`
|
|
3
3
|
`,t:" ",r:"\r",b:"\b",f:"\f"}[u]??u,n++}return{value:r,complete:!1,empty:!1,at:e.length}}function W(e,t){t=L(e,t);let r=e[t];if(r===void 0)return{value:void 0,complete:!1,empty:!0,at:t};if(r==='"')return he(e,t);if(r==="{")return Me(e,t);if(r==="[")return Be(e,t);let n=t;for(;n<e.length&&/[-+0-9.A-Za-z]/.test(e[n]);)n++;if(n===e.length)return{value:void 0,complete:!1,empty:!0,at:n};try{return{value:JSON.parse(e.slice(t,n)),complete:!0,empty:!1,at:n}}catch{return{value:void 0,complete:!1,empty:!0,at:e.length}}}function Me(e,t){let r={},n=t+1;for(;;){if(n=L(e,n),e[n]==="}")return{value:r,complete:!0,empty:!1,at:n+1};if(e[n]===","){n++;continue}if(e[n]!=='"')return{value:r,complete:!1,empty:!1,at:e.length};let i=he(e,n);if(!i.complete)return{value:r,complete:!1,empty:!1,at:e.length};if(n=L(e,i.at),e[n]!==":")return{value:r,complete:!1,empty:!1,at:e.length};let u=W(e,n+1);if(u.empty||Object.defineProperty(r,i.value,{value:u.value,enumerable:!0,writable:!0,configurable:!0}),!u.complete)return{value:r,complete:!1,empty:!1,at:e.length};n=u.at}}function Be(e,t){let r=[],n=t+1;for(;;){if(n=L(e,n),e[n]==="]")return{value:r,complete:!0,empty:!1,at:n+1};if(e[n]===","){n++;continue}if(n>=e.length)return{value:r,complete:!1,empty:!1,at:n};let i=W(e,n);if(i.empty||r.push(i.value),!i.complete)return{value:r,complete:!1,empty:!1,at:e.length};n=i.at}}function Y(e){let t=W(e,0);return t.empty?void 0:t.value}var w=class extends Error{path;constructor(t,r){super(`${t}: ${r}`),this.name="AISchemaError",this.path=t}},je=new Set(["type","properties","required","additionalProperties","items","enum","description","title","minimum","maximum","minLength","maxLength","minItems","maxItems"]),De=new Set(["format","pattern","exclusiveMinimum","exclusiveMaximum","multipleOf","uniqueItems","contentEncoding","contentMediaType","default","examples","readOnly","writeOnly","deprecated","$comment"]),Ne=new Set(["object","array","string","integer","number","boolean"]),ye=12,we=512,Ue=/^[A-Za-z][A-Za-z0-9_-]{0,63}$/;function q(e,t="answer"){if(!Ue.test(t))throw new w(t||"(name)","a schema name starts with a letter and holds letters, digits, _ and -, 64 at most");let r=e?.["~standard"];if(!r||r.version!==1||typeof r.validate!="function")throw new w(t,"not a Standard Schema: pass a zod (4.2+), valibot or arktype schema");if(!r.jsonSchema||typeof r.jsonSchema.output!="function")throw new w(t,`${r.vendor}'s schema cannot say itself as JSON Schema; use a version that implements Standard JSON Schema`);let n;try{n=r.jsonSchema.output({target:"draft-2020-12",libraryOptions:{unrepresentable:"throw"}})}catch(c){throw new w(t,`the schema has a part JSON Schema cannot say (${c.message}): a function, a transform, a date \u2014 give the model a string and convert it after`)}if(n.type!=="object")throw new w(t,"the answer is an object: wrap the value in z.object({ \u2026 })");let u=V(n,t,0,{properties:0});return{name:t,json:u,async check(c){let g=await r.validate(c);if(g.issues){let a=g.issues[0],o=(a?.path??[]).map(s=>String(typeof s=="object"?s.key:s)).join(".");throw new w(o?`${t}.${o}`:t,`the model's answer does not match the schema: ${a?.message??"invalid"}`)}return g.value}}}function V(e,t,r,n){if(r>ye)throw new w(t,`nests deeper than ${ye} levels, the most the provider takes`);for(let c of["anyOf","oneOf","allOf"])if(c in e)throw new w(t,Je(e[c])??"is a union of several shapes: the provider holds a model to one shape per field \u2014 use an enum, or one object with every field");for(let c of["$ref","$defs","definitions","$dynamicRef"])if(c in e)throw new w(t,"refers to another schema (a recursive or shared type): the provider takes no references \u2014 write the shape out, a bounded number of levels deep");if(e.type==="object"&&("propertyNames"in e||"patternProperties"in e||e.additionalProperties!==void 0&&e.additionalProperties!==!1))throw new w(t,"accepts fields it does not name (a record, passthrough or catchall): the provider holds a model only to the fields named \u2014 name them");for(let c of["prefixItems","patternProperties","propertyNames","not","if","then","else","dependentRequired","dependentSchemas","const","minProperties","maxProperties","contains","unevaluatedProperties","unevaluatedItems"])if(c in e)throw new w(t,`uses ${c}, which the provider cannot hold a model to`);if(Array.isArray(e.type))throw new w(t,`may be ${e.type.join(" or ")}: one type per field \u2014 a nullable field is not expressible; give it a value that means "none" (an empty string, an enum member)`);let i=e.type;if(typeof i!="string"&&!("enum"in e))throw new w(t,"has no type: the provider holds a model only to a typed value");if(typeof i=="string"&&!Ne.has(i))throw new w(t,`is of type ${i}, which the provider does not take`);let u={};for(let[c,g]of Object.entries(e))if(!(c==="$schema"||c==="id"||c==="$id")&&!De.has(c)){if(!je.has(c))throw new w(t,`uses ${c}, which the provider cannot hold a model to`);u[c]=g}if("enum"in e&&typeof i!="string"){let c=e.enum,g=new Set(c.map(a=>a===null?"null":typeof a));if(g.size!==1||g.has("null"))throw new w(t,"an enum of values of several types (or with null): one type per field");u.type=g.has("string")?"string":g.has("boolean")?"boolean":"number"}if(i==="object"){let c=e.properties??{},g=Object.keys(c);if(g.length===0)throw new w(t,"is an object with no fields (a record, or any object): the provider holds a model only to named fields \u2014 name them");if(e.additionalProperties!==void 0&&e.additionalProperties!==!1)throw new w(t,"accepts fields it does not name (passthrough, catchall, record): the provider holds a model only to the fields named");if(n.properties+=g.length,n.properties>we)throw new w(t,`the schema has more than ${we} fields in all, the most the provider takes`);let a=new Set(e.required??[]),o={};for(let s of g){if(!a.has(s))throw new w(`${t}.${s}`,'is optional: the provider makes the model write every field \u2014 make it required (give it a value that means "none"), or leave it out of the schema');o[s]=V(c[s],`${t}.${s}`,r+1,n)}u.properties=o,u.required=g,u.additionalProperties=!1}if(i==="array"){let c=e.items;if(!c||typeof c!="object"||Array.isArray(c))throw new w(t,"is a list with no one shape for its items: the provider takes a list of one shape");u.items=V(c,`${t}[]`,r+1,n)}return u}function Je(e){if(Array.isArray(e)&&e.length===2&&e.some(t=>t?.type==="null"))return'is nullable: the provider makes the model write a value of one type \u2014 drop .nullable() and give it a value that means "none"'}var ze=Symbol.for("palbase.ai.declared"),Le=Symbol.for("palbase.ai.tool_error"),X=class extends Error{constructor(t){super(t),this.name="ToolError",Object.defineProperty(this,Le,{value:!0})}};function G(){let e=globalThis,t=e[ze]??={tools:new Map,agents:new Map,repos:new Map,twice:new Set};return t.repos??=new Map,t}function Q(e,t,r,n){let i=e.get(r);i===void 0?e.set(r,n):i!==n&&G().twice.add(`${t}:${r}`)}var be=/^[A-Za-z][A-Za-z0-9_-]{0,63}$/,R=/^[a-z][a-z0-9_-]{0,63}$/;function Se(e,t){if(e===void 0)return{type:"object",properties:{}};let r=e?.["~standard"];if(!r||r.version!==1||typeof r.validate!="function")throw new TypeError(`${t}: input is a Standard Schema \u2014 a zod (4.2+), valibot or arktype object schema`);if(!r.jsonSchema||typeof r.jsonSchema.output!="function")throw new TypeError(`${t}: ${r.vendor}'s schema cannot say itself as JSON Schema; use a version that implements Standard JSON Schema`);let n;try{n=r.jsonSchema.output({target:"draft-2020-12",libraryOptions:{unrepresentable:"throw"}})}catch(g){throw new TypeError(`${t}: the input has a part JSON Schema cannot say (${g.message}) \u2014 a function, a transform, a date: take a string and convert it in run`)}if(n.type!=="object")throw new TypeError(`${t}: a tool takes an object \u2014 wrap the input in z.object({ \u2026 })`);let i=JSON.stringify(n);if(/"\$(ref|defs|dynamicRef)"/.test(i))throw new TypeError(`${t}: the input refers to another schema (a recursive or shared type) \u2014 write the shape out`);let{$schema:u,...c}=n;return c}function ke(e){let t=`ai.tool(${JSON.stringify(e?.name??null)})`;if(typeof e?.name!="string"||!be.test(e.name))throw new TypeError(`${t}: name is letters, digits, _ and -, starting with a letter, at most 64`);if(typeof e.description!="string"||e.description.trim()==="")throw new TypeError(`${t}: description says what it does \u2014 the agent reads it to choose`);if(typeof e.run!="function")throw new TypeError(`${t}: run(input, ctx) is what a call does`);if(e.machine!==void 0&&!R.test(e.machine))throw new TypeError(`${t}: machine is the name of one of the project's machines`);if(e.input===void 0)throw new TypeError(`${t}: input is what it takes \u2014 z.object({}) for nothing`);let r=Se(e.input,t),n=e.input["~standard"],i=e.run,u={source:"backend",name:e.name,description:e.description,input:e.input,parameters:r,approval:e.approval===!0,...e.machine!==void 0?{machine:e.machine}:{},async call(c,g){let a=await n.validate(c);if(a.issues){let o=a.issues[0],s=(o?.path??[]).map(l=>String(typeof l=="object"?l.key:l)).join(".");return{output:[{type:"text",text:`the input does not match ${e.name}'s schema${s?` at ${s}`:""}: ${o?.message??"invalid"}`}],is_error:!0}}return{output:z(await i(a.value,g)),is_error:!1}}};return Object.freeze(u),Q(G().tools,"tool",u.name,u),u}function Te(e){let t=`ai.clientTool(${JSON.stringify(e?.name??null)})`;if(typeof e?.name!="string"||!be.test(e.name))throw new TypeError(`${t}: name is letters, digits, _ and -, starting with a letter, at most 64`);if(typeof e.description!="string"||e.description.trim()==="")throw new TypeError(`${t}: description says what it does \u2014 the agent reads it to choose`);return Object.freeze({source:"client",name:e.name,description:e.description,parameters:Se(e.input,t),approval:e.approval===!0})}var qe=/^[A-Za-z0-9_.-]{1,100}\/[A-Za-z0-9_.-]{1,100}$/;function Ae(e){let t=e??{};if(typeof t.name!="string"||!R.test(t.name))throw new TypeError("ai.repo: name is lowercase letters, digits, _ and -, starting with a letter, at most 64");if(typeof t.repository!="string"||!qe.test(t.repository))throw new TypeError(`ai.repo(${JSON.stringify(t.name)}): repository is a GitHub repository, owner/name`);if(typeof t.token!="function")throw new TypeError(`ai.repo(${JSON.stringify(t.name)}): token is the function that gives a token for one clone or push`);if(t.machine!==void 0&&!R.test(t.machine))throw new TypeError(`ai.repo(${JSON.stringify(t.name)}): machine is the project's machine that gives its tokens`);let r=t.token,n={kind:"repo",name:t.name,repository:t.repository,defaultBranch:t.defaultBranch??"main",...t.machine!==void 0?{machine:t.machine}:{},async token(i){return await r(i)}};return Q(G().repos,"repo",t.name,n),n}function xe(e,t,r={}){let n=`ai.agent(${JSON.stringify(e??null)})`;if(typeof e!="string"||!R.test(e))throw new TypeError(`${n}: name is lowercase letters, digits, _ and -, starting with a letter, at most 64`);if(typeof t!="function")throw new TypeError(`${n}: the agent is a function of the turn's context that returns its definition`);if(r.machine!==void 0&&!R.test(r.machine))throw new TypeError(`${n}: machine is the name of one of the project's machines`);let i={kind:"agent",name:e,...r.machine!==void 0?{machine:r.machine}:{},clients:r.clients===!0,async resolve(u){let c=await t(u),g=F(c,`${n} for chat ${u.chatId}`);if(g.backend!==void 0)throw new TypeError(`${n}: a backend's agent is its definition \u2014 it names no other backend`);return delete g.clients,{definition:g,tools:Ke(c)}}};return Object.freeze(i),Q(G().agents,"agent",e,i),i}function Ke(e){return[...e.tools??[],...(e.subagents??[]).flatMap(r=>r.tools??[])].filter(r=>r.source==="backend")}function K(e,t){if(typeof e!="object"||e===null)throw new TypeError(`${t}: a tool is ai.tool(\u2026), ai.clientTool(\u2026), { source: 'https', name } or { source: 'mcp', name }`);let r=e.approval===!0?{approval:!0}:{};switch(e.source){case"backend":if(typeof e.call!="function")throw new TypeError(`${t}: a backend tool is made with ai.tool({ name, description, input, run })`);return{source:"backend",name:e.name,description:e.description,parameters:e.parameters,...r,...e.machine!==void 0?{machine:e.machine}:{}};case"client":return{source:"client",name:e.name,description:e.description,parameters:e.parameters,...r};case"https":if(typeof e.name!="string"||!R.test(e.name))throw new TypeError(`${t}: { source: 'https', name } names an endpoint the project put`);return{source:"https",name:e.name,...r};case"mcp":if(typeof e.name!="string"||!R.test(e.name))throw new TypeError(`${t}: { source: 'mcp', name } names an MCP server the project put`);return{source:"mcp",name:e.name,...r,...e.only!==void 0?{only:[...e.only]}:{}};default:throw new TypeError(`${t}: a tool's source is backend, client, https or mcp (got ${JSON.stringify(e.source)})`)}}function F(e,t){if(typeof e!="object"||e===null)throw new TypeError(`${t}: a definition is { instructions, model, tools, subagents, maxToolCalls }`);let r={};return e.instructions!==void 0&&(r.instructions=e.instructions),e.model!==void 0&&(r.model=e.model),e.maxToolCalls!==void 0&&(r.max_tool_calls=e.maxToolCalls),e.clients!==void 0&&(r.clients=e.clients),e.tools!==void 0&&(r.tools=e.tools.map(n=>K(n,t))),e.subagents!==void 0&&(r.subagents=e.subagents.map(n=>({name:n.name,description:n.description,...n.instructions!==void 0?{instructions:n.instructions}:{},...n.model!==void 0?{model:n.model}:{},...n.required!==void 0?{required:n.required}:{},...n.tools!==void 0?{tools:n.tools.map(i=>K(i,`${t} subagent ${n.name}`))}:{}}))),r}function ve(){return"cm_"+crypto.randomUUID()}async function ee(e,t,r=4){for(let n=1;;n++)try{return await e()}catch(i){if(n>=r||!(i instanceof $)||i.status===429||t?.aborted)throw i;let u=ce(i,n,30);if(u===void 0)throw i;await new Promise((c,g)=>{let a=setTimeout(c,u*1e3);t?.addEventListener("abort",()=>(clearTimeout(a),g(t.reason)),{once:!0})})}}function Re(e){return{clients:e.clients,userMessagesPerMinute:e.user_messages_per_minute,historyLimitBytes:e.history_limit_bytes,historyBytes:e.history_bytes}}function Ge(e){return new Proxy(e,{get(t,r){let n=t[r];return typeof n=="function"?(...i)=>J(n.apply(t,i)):n}})}function Pe(e){let t=Ge(e),r={async create(a){let o=typeof a.agent=="object"&&a.agent!==null?a.agent.name:a.agent;if(o===void 0&&a.definition===void 0)throw new TypeError("chats.create: an agent (a named agent of the project) or a definition of the chat's own");let s={agent:o??"assistant"};return a.definition!==void 0&&(s.definition=F(a.definition,"chats.create")),a.title!==void 0&&(s.title=a.title),a.metadata!==void 0&&(s.metadata=a.metadata),a.members!==void 0&&(s.members=a.members.map(l=>({user_id:l.userId,...l.name!==void 0?{name:l.name}:{},...l.owner!==void 0?{owner:l.owner}:{}}))),a.workspace!==void 0&&(s.workspace={repos:a.workspace.repos.map(l=>({repo:typeof l.repo=="string"?l.repo:l.repo.name,...l.branch!==void 0?{branch:l.branch}:{}})),...a.workspace.autoPush!==void 0?{auto_push:a.workspace.autoPush}:{}}),(await t.createChat({body:s,signal:a.signal})).data},async get(a,o={}){return(await t.getChat({path:{chat_id:a},signal:o.signal})).data},async list(a={}){return(await t.listChats({query:{member:a.member},signal:a.signal})).data.chats},async delete(a){await t.deleteChat({path:{chat_id:a}})},members:{async put(a,o,s){let l={};return s.name!==void 0&&(l.name=s.name),s.owner!==void 0&&(l.owner=s.owner),(await t.putChatMember({path:{chat_id:a,user_id:o},body:l})).data},async delete(a,o){await t.deleteChatMember({path:{chat_id:a,user_id:o}})}},async send(a,o){let s={client_id:o.clientId??ve(),text:o.text};return o.delivery!==void 0&&(s.delivery=o.delivery),o.as!==void 0&&(s.as=o.as),o.budget!==void 0&&(s.budget={max_cost_usd:o.budget.maxCostUsd}),ee(async()=>(await t.sendChatMessage({path:{chat_id:a},body:s,signal:o.signal})).data,o.signal)},async turnCost(a,o,s={}){let l=(await t.getChatTurnCost({path:{chat_id:a,response_id:o},signal:s.signal})).data;return{chatId:l.chat_id,responseId:l.response_id,inputTokens:l.input_tokens,outputTokens:l.output_tokens,costNanoUsd:l.cost_nano_usd,unpriced:l.unpriced,final:l.final}},async artifacts(a,o,s={}){return(await t.listChatTurnArtifacts({path:{chat_id:a,response_id:o},signal:s.signal})).data.artifacts.map(T=>({id:T.id,mediaType:T.media_type,...T.logical_type?{logicalType:T.logical_type}:{},sizeBytes:T.size_bytes,checksum:T.checksum,createdAt:T.created_at}))},async artifact(a,o,s,l={}){return(await t.getChatTurnArtifact({path:{chat_id:a,response_id:o,artifact_id:s},signal:l.signal})).data},async messages(a,o={}){let s=(await t.listChatMessages({path:{chat_id:a},query:{limit:o.limit,cursor:o.cursor},signal:o.signal})).data;return s.next_cursor===void 0?{messages:s.messages}:{messages:s.messages,nextCursor:s.next_cursor}},stream(a,o={}){return fe(async(s,l)=>(await t.followChat({path:{chat_id:a},query:s,signal:l})).data,o)},async stop(a){return(await t.stopChat({path:{chat_id:a}})).data.stopped},async approve(a,o,s){return(await t.decideChatApproval({path:{chat_id:a,approval_id:o},body:s===void 0?{approve:!0}:{approve:!0,reason:s}})).data},async deny(a,o,s){return(await t.decideChatApproval({path:{chat_id:a,approval_id:o},body:s===void 0?{approve:!1}:{approve:!1,reason:s}})).data},async answer(a,o,s,l={}){let T={output:z(s)};l.isError&&(T.is_error=!0);try{return await ee(()=>t.answerChatToolCall({path:{chat_id:a,call_id:o},body:T})),!0}catch(v){if(v instanceof $&&v.status===409)return!1;throw v}},async sendToSubagent(a,o,s,l={}){let T={client_id:l.clientId??ve(),text:s},v=await ee(async()=>(await t.sendSubagentMessage({path:{chat_id:a,run_id:o},body:T})).data);return{runId:v.run_id,clientId:v.client_id}}},n={async put(a,o){let s=typeof a=="string"?a:a.name,l=typeof a=="string"?o:a;if(typeof s!="string"||!R.test(s))throw new TypeError("agents.put: name is lowercase letters, digits, _ and -, starting with a letter, at most 64");if(l===void 0)throw new TypeError(`agents.put(${JSON.stringify(s)}): its definition, or a backend's ai.agent`);let T;if(l.kind==="agent"){let v=l;if(v.name!==s)throw new TypeError(`agents.put(${JSON.stringify(s)}): the backend's agent is named ${JSON.stringify(v.name)} \u2014 its machine is asked for it by that name`);T=v.clients?{backend:v.machine??"backend",clients:!0}:{backend:v.machine??"backend"}}else T=F(l,`agents.put(${JSON.stringify(s)})`);return(await t.putAgent({path:{name:s},body:T})).data},async list(){return(await t.listAgents({})).data.agents},async delete(a){await t.deleteAgent({path:{name:a}})}},i={async put(a,o){let s={kind:o.kind,url:o.url};return o.description!==void 0&&(s.description=o.description),o.parameters!==void 0&&(s.parameters=o.parameters),o.approval!==void 0&&(s.approval=o.approval),(await t.putEndpoint({path:{name:a},body:s})).data},async list(){return(await t.listEndpoints({})).data.endpoints},async delete(a){await t.deleteEndpoint({path:{name:a}})}},u={async get(){return Re((await t.getSettings({})).data)},async put(a){let o={};return a.clients!==void 0&&(o.clients=a.clients),a.userMessagesPerMinute!==void 0&&(o.user_messages_per_minute=a.userMessagesPerMinute),a.historyLimitBytes!==void 0&&(o.history_limit_bytes=a.historyLimitBytes),Re((await t.putSettings({body:o})).data)}},c=a=>({name:a.name,repository:a.repository,defaultBranch:a.default_branch,backend:a.backend,createdAt:a.created_at});return{chats:r,agents:n,endpoints:i,settings:u,repos:{async put(a,o){let s=typeof a=="string"?a:a.name;if(typeof s!="string"||!R.test(s))throw new TypeError("repos.put: name is lowercase letters, digits, _ and -, starting with a letter, at most 64");let l=typeof a=="string"?{repository:o?.repository??"",...o?.defaultBranch?{default_branch:o.defaultBranch}:{},...o?.backend?{backend:o.backend}:{}}:{repository:a.repository,default_branch:a.defaultBranch,...a.machine?{backend:a.machine}:{}};return c((await t.putRepo({path:{name:s},body:l})).data)},async list(){return(await t.listRepos({})).data.repos.map(c)},async delete(a){await t.deleteRepo({path:{name:a}})}}}}var Fe=/^pb_[a-z0-9]+_s/;function Ee(e){let t=globalThis;return t.process?.env?.[e]??t.Deno?.env?.get(e)}function te(){return"ai_"+crypto.randomUUID()}function ne(e){if(e.prepared)return e;let t=e;return{name:"answer",schema:t,prepared:q(t,"answer")}}var _e=4,He=/^[a-z][a-z0-9-]{1,62}$/;function Ze(e){if(!Array.isArray(e))throw new TypeError("images is a list of { bucket, path } (a file of the project's storage) or { url } (an https address)");if(e.length>_e)throw new TypeError(`a question takes ${_e} pictures at most (got ${e.length})`);return e.map((t,r)=>{let n=t??{};if("data"in n||"bytes"in n||t instanceof Uint8Array)throw new TypeError(`images[${r}]: a picture is given where it is, not as its bytes \u2014 upload it to the project's storage (storage.from(bucket).upload(path, file)) and give { bucket, path }, or give { url }`);if(typeof n.url=="string"){if(n.bucket!==void 0||n.path!==void 0)throw new TypeError(`images[${r}] is { bucket, path } or { url }, not both`);let i;try{i=new URL(n.url)}catch{throw new TypeError(`images[${r}].url is not an address: ${JSON.stringify(n.url.slice(0,80))}`)}if(i.protocol!=="https:"||n.url.length>2048)throw new TypeError(`images[${r}].url is an https address of 2048 characters at most`);return{url:n.url}}if(typeof n.bucket!="string"||!He.test(n.bucket)||typeof n.path!="string"||n.path==="")throw new TypeError(`images[${r}] is { bucket, path } \u2014 a file of the project's storage \u2014 or { url }`);return{bucket:n.bucket,path:n.path}})}function H(e,t={},r){if(e.prompt===void 0&&e.messages===void 0)throw new TypeError("ask a model something: prompt, or messages");let n={...t};if(e.prompt!==void 0&&(n.input=e.prompt),e.messages!==void 0&&(n.messages=e.messages),e.instructions!==void 0&&(n.instructions=e.instructions),e.model!==void 0&&(n.model=e.model),e.metadata!==void 0&&(n.metadata=e.metadata),e.images!==void 0&&(n.images=Ze(e.images)),e.tools!==void 0&&(n.tools=e.tools.map((i,u)=>{if(i?.source==="client")throw new TypeError(`tools[${u}]: ${i.name} is a client tool \u2014 an app answers it, in a chat; a one-shot answer has no app to wait for`);let c=K(i,`tools[${u}]`);return c.source==="backend"&&c.machine===void 0&&r!==void 0&&(c.machine=r),c})),e.maxToolCalls!==void 0){if(!e.tools?.length)throw new TypeError("maxToolCalls bounds the calls of the tools given: give tools");if(!Number.isInteger(e.maxToolCalls)||e.maxToolCalls<1||e.maxToolCalls>200)throw new TypeError(`maxToolCalls is a whole number, 1 to 200 (got ${String(e.maxToolCalls)})`);n.max_tool_calls=e.maxToolCalls}return n}var I=class extends Error{code;response;constructor(t){super(t.error?.message??`the response ended ${t.status}`),this.name="AIResponseError",this.code=t.error?.code??t.status,this.response=t}};function We(e){let t=Uint8Array.from(atob(e),i=>i.charCodeAt(0)),r=new DataView(t.buffer,t.byteOffset,t.byteLength),n=new Array(t.byteLength/4);for(let i=0;i<n.length;i++)n[i]=r.getFloat32(i*4,!0);return n}async function Ce(e){let t,r;e instanceof Uint8Array?(t=e,r=Ie(t)):typeof Blob<"u"&&e instanceof Blob?(t=new Uint8Array(await e.arrayBuffer()),r=e.type||Ie(t)):(t=e.bytes,r=e.mediaType);let n="";for(let i=0;i<t.length;i+=32768)n+=String.fromCharCode(...t.subarray(i,i+32768));return{media_type:r,data:btoa(n)}}function Ie(e){return e[0]===137&&e[1]===80?"image/png":e[0]===255&&e[1]===216?"image/jpeg":e[8]===87&&e[9]===69&&e[10]===66&&e[11]===80?"image/webp":"application/octet-stream"}function Ye(e){let t=e.url??Ee("PALBASE_URL"),r=e.secretKey??Ee("PALBASE_SECRET_KEY");if(typeof t!="string"||t==="")throw new TypeError("url is the project address (https://<ref>.<domain>) \u2014 or set PALBASE_URL");if(typeof r!="string"||!Fe.test(r))throw new TypeError("secretKey is the project secret key (pb_<ref>_s\u2026) \u2014 or set PALBASE_SECRET_KEY; a model call is billed to the project, so it is never made with a publishable key");let n=de(oe({baseUrl:t,credentials:{secretKey:r},fetch:e.fetch}),e.retry??ie);return se.client(n)}function Ve(e){return new Proxy({},{get:(t,r)=>e.ai[r]})}function Xe(e={}){if(ge())throw new TypeError("palbase/ai runs on a server: it speaks with the project secret key, which never goes into a browser or a mobile app \u2014 call your backend, and let it ask the model");if(e.machine!==void 0&&!R.test(e.machine))throw new TypeError("machine is the name of one of the project's machines");let t=e.server?Ve(e.server):Ye(e),r=e.resumeFor??12e4;async function n(d,p,f=te()){return J(t.createResponse({headers:{"Idempotency-Key":f},body:d,signal:p}))}async function i(d,p={}){return(await t.getResponse({path:{response_id:d},signal:p.signal})).data}async function u(d,p,f,h,b){let S=0,A=d,P=te(),M=()=>Date.now()+r,B=M();for(let j=0;;j++)try{if(A||(p===null?A=(await n({...b,stream:!0},h,P)).data:A=(await t.followResponse({path:{response_id:p},query:{offset:S},signal:h})).data),!A.body)throw new Error("the stream has no body");for await(let y of le(A.body)){let x=JSON.parse(y.data);switch(y.event){case"response":p===null&&(p=x.id,f.admitted(x));break;case"delta":{let O=x.offset+pe(x.text);if(O>S){let Z=x.offset>=S?x.text:me(x.text,S-x.offset);f.delta(S,Z),S=O}B=M();break}case"reset":x.offset<S&&(S=x.offset,f.reset(S));break;case"terminal":return x}}throw new Error("the stream ended before its answer did")}catch(y){if(A=null,h?.aborted||y instanceof $&&y.status>0&&y.status<500&&y.status!==429||p===null&&!(y instanceof $)||Date.now()>B)throw y;await new Promise(x=>setTimeout(x,Math.min(250*2**Math.min(j,4),4e3)))}}function c(d){if(d.status!=="completed")throw new I(d);return d.text??""}function g(d,p){let f=H(d,p?{schema:p.prepared.json,schema_name:p.name}:{},e.machine),h=[],b=!1,S,A=null,P=()=>{let m=A;A=null,m?.()},M,B,j=new Promise((m,k)=>{M=m,B=k});j.catch(()=>{});let y="",x=u(null,null,{admitted:m=>M(m.id),delta:(m,k)=>{y+=k,h.push(k),P()},reset:m=>{let k=ue(y,m);y=y.slice(0,k),h.push("\0reset:"+k),P()}},d.signal,f).then(m=>{let k=m.status==="completed"?m.text??"":"";return k.length>y.length&&k.startsWith(y)&&(h.push(k.slice(y.length)),y=k),b=!0,P(),m},m=>{throw b=!0,S=m,B(m),P(),m});x.catch(()=>{});async function*O(){for(let m=0;;m++){for(;m>=h.length;){if(b){if(S)throw S;return}await new Promise(k=>A=k)}yield h[m]}}async function*Z(){for await(let m of O())m.startsWith("\0reset:")||(yield m)}async function*$e(){let m="",k="";for await(let N of O()){N.startsWith("\0reset:")?m=m.slice(0,Number(N.slice(7))):m+=N;let _=Y(m);if(_===void 0)continue;let C=JSON.stringify(_);C!==k&&(k=C,yield _)}}let D=x.then(m=>{if(m.status!=="completed")throw new I(m);return m});D.catch(()=>{});let re=p?D.then(m=>p.prepared.check(m.output)):Promise.reject(new TypeError("object is a schema stream's"));re.catch(()=>{});let ae=D.then(m=>m.text??y);return ae.catch(()=>{}),{id:j,response:D,text:ae,get textStream(){return Z()},get partialObjectStream(){return $e()},object:re,toResponse(m={}){let k=new TextEncoder,N=new ReadableStream({async start(C){try{for await(let U of O())U.startsWith("\0reset:")?C.enqueue(k.encode(`event: reset
|
|
4
4
|
data: ${JSON.stringify({offset:Number(U.slice(7))})}
|
|
5
5
|
|
package/dist/backend/engine.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.5.
|
|
2
|
-
import{ha as h,ka as d}from"../chunks/
|
|
1
|
+
/*! palbase 0.5.2 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{ha as h,ka as d}from"../chunks/K2LVOEW3.js";import"../chunks/FNUO6DSY.js";import"../chunks/XRW7YOUQ.js";import"../chunks/NQA7ZLGD.js";import"../chunks/QHJ4OPPI.js";import"../chunks/5G3URQAW.js";import"../chunks/HLYQRT7O.js";import"../chunks/TPBWIRHS.js";import"../chunks/MYNCDAKM.js";import{binding as R,createDatabase as v}from"palgres";var b=new WeakMap;function q(l,e,n){if(!n?.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=n.schemas,s=b.get(l);s||b.set(l,s=new Map);let r=s.get(u);r||s.set(u,r=new Map);let o=e.role===e.serviceRole?"service":e.role==="anon"?"anon":"authenticated",f=o==="service"?{service:e.serviceRole}:{[o]:e.role,service:e.serviceRole},g=`${o}\0${e.role}\0${e.serviceRole}`,i=r.get(g);i||(i=v({sql:l,schemas:u,binding:R(0,!0),roles:f}),r.set(g,i));let w=JSON.parse(e.claimsJson),m=i.then(a=>a.request({role:o,claims:w},{diagnostics:n.diagnostics,signal:n.signal})),y=a=>new Proxy(()=>{},{apply:async(t,D,c)=>{let p=(await m).client;return a(p).apply(p,c)}});return{client:new Proxy({},{get(a,t){if(t!=="then")return t==="diagnostics"?()=>null:t==="asService"?()=>new Proxy({},{get:(D,c)=>c==="then"?void 0:y(p=>p.asService()[c])}):y(D=>D[t])}}),commit:async()=>(await m).commit(),rollback:async a=>(await m).rollback(a)}}export{h as createApp,q as createRequestDatabase,d as makeMemoryCache};
|
package/dist/backend/env.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
/*! palbase 0.5.
|
|
1
|
+
/*! palbase 0.5.2 — Palbase SDK License (see LICENSE) */
|
package/dist/backend/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
/*! palbase 0.5.
|
|
2
|
-
import{$ as Bt,A as C,B as ot,C as it,D as ct,E as dt,F as ut,G as pt,H as ht,I as gt,J as bt,K as
|
|
1
|
+
/*! palbase 0.5.2 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{$ as Bt,A as C,B as ot,C as it,D as ct,E as dt,F as ut,G as pt,H as ht,I as gt,J as bt,K as ft,L as mt,M as yt,N as wt,O as Pt,P as St,Q as vt,R as kt,S as At,T as Rt,U as Et,V as xt,W as _t,X as ee,Y as Tt,Z as Ot,_ as Ct,a as Y,aa as Ft,b as J,ba as Mt,c as Q,ca as It,d as Le,da as $t,e as De,ea as Lt,f as Ue,fa as B,g as je,ga as Ut,h as Ne,ha as F,i as qe,ia as jt,j as Ve,ja as Nt,k as We,l as Ke,m as ze,n as Ge,o as He,p as Ye,q as Je,r as Qe,s as Xe,t as Ze,u as et,v as tt,w as rt,x as st,y as nt,z as at}from"../chunks/K2LVOEW3.js";import{a as re}from"../chunks/4ZVJ62A3.js";import{a as E,b as X,c as Z,e as g,f as lt,g as d,i as te,j as Dt}from"../chunks/FNUO6DSY.js";import{a as V,g as Ie,h as $e,i as z,j as O,q as G,r as H}from"../chunks/XRW7YOUQ.js";import"../chunks/NQA7ZLGD.js";import{m as Me}from"../chunks/QHJ4OPPI.js";import"../chunks/5G3URQAW.js";import{b as T}from"../chunks/HLYQRT7O.js";import"../chunks/TPBWIRHS.js";import"../chunks/MYNCDAKM.js";import"reflect-metadata";import{existsSync as W,writeFileSync as fr,writeSync as we}from"node:fs";import{createServer as mr}from"node:http";import{dirname as k,join as K,resolve as Ae}from"node:path";import{Readable as yr}from"node:stream";var qt=2e3,Vt=1e4,Wt=/^[A-Za-z0-9_-]{1,64}$/,Kt=512,M=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??Vt,this.shutdownMs=r.shutdownMs??qt,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&&d.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&&(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=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;d[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:Wt.test(e.requestId)?e.requestId:e.requestId.replace(/[^A-Za-z0-9_-]/g,"_").slice(0,64)||"unnamed",source:"backend",endpoint:e.endpoint.slice(0,Kt),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 l=a.status,o=l??(s.call.signal.aborted?`no answer in ${this.sendMs} ms`:"unreachable"),c=a.retryAfter;this.pausedUntil=this.now()+(typeof c=="number"&&c>0?c*1e3:l===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 zt}from"node:crypto";import{bind as Gt,bunDriver as Ht,createDatabase as Yt,createSearchWorker as Jt,cutOff as Qt,forgetUser as Xt,MigrationOpen as Zt,MigrationRefused as er,Migrator as oe,renewingBunPool as se,VersionNotMigrated as tr}from"palgres";import{toModel as ie}from"palgres/dsl";var rr=["start","complete","rollback","plan","status"],sr=/^(deploy|cli:[^\u0000-\u001f\u007f]{1,200})$/u;function le(t){let e=t.PALBASE_DB_MIGRATE;if(!(e===void 0||e==="")){if(!rr.includes(e))throw new Error(`[palbase] PALBASE_DB_MIGRATE is start, complete, rollback, plan or status, not ${e}`);return e}}function ce(t){let e=Array.isArray(t.schemas)?t.schemas:[t.schemas];for(let r of e)if(r.name===B.name)throw new Error(`[palbase] db.schemas: the ${B.name} schema is the framework's own (its tables are migrated with the app's) \u2014 name the app's schema otherwise`);return[...e,B]}function L(t){return ie(ce(t))}function nr(t){return t.tables.some(e=>e.search!==void 0)}function D(t){return t.tables.some(e=>!e.ignored&&e.columns.some(r=>r.user!==void 0&&!r.ignored))}function de(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 ar(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 ne=5;function ue(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=se(()=>new r.SQL({url:n,prepare:!1,max:s})),l=se(()=>new r.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:Ht(a,l),poolSize:s,close:async()=>{await a.close({timeout:ne}),await l.close({timeout:ne})}}}}function pe(t){return t==="rollback"?(d.info("[palbase] migrate rollback: this app declares no database; nothing of it to take back"),I(t,{state:"none"}),0):(d.error(`[palbase] migrate ${t}: this app declares no database \u2014 PalbaseFactory.create(\u2026, { db: { schemas } })`),1)}async function he(t,e,r){let s=e.PALBASE_DB_OWNER_URL;if(!s)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(!sr.test(n))return d.error("[palbase] PALBASE_DB_MIGRATION_BY is deploy, or cli:<who>"),1;let a=ue(t,de(e)),l=a(s),o,c=i=>d.error(`[palbase] migrate ${r}: ${i}`);try{let i=L(t),u=new oe(l.pool,{log:h=>{/ is held by others | held by writers/.test(h)&&(o=h.trim()),d.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(i);return I(r,h),h.refusals.length>0?1:0}if(r==="status")return I(r,await u.status()),0;let p=r==="start"?await or(u,i,n):r==="complete"?await u.complete():await u.rollback();return d.info(`[palbase] migrate ${r}: done`,{result:p}),I(r,p),0}catch(i){return i instanceof er?(d.error(`[palbase] migrate ${r}: refused`,{refusals:i.refusals}),c(`refused \u2014 ${i.refusals.join("; ")}`),1):Qt(i)?(d.error(`[palbase] migrate ${r}: cut off; run again, it goes on from where it stopped`,{error:i}),c(`cut off \u2014 ${o??ae(i)}`),75):(d.error(`[palbase] migrate ${r}: failed`,{error:i}),c(`failed \u2014 ${ae(i)}`),1)}finally{await l.close().catch(()=>{})}}async function or(t,e,r){try{return await t.start(e)}catch(s){if(!(s instanceof Zt)||r!=="deploy"||!s.openedBy?.startsWith("cli:"))throw s;return d.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)}}function I(t,e){process.stdout.write(`${JSON.stringify({palbase_migrate:t,result:e})}
|
|
3
3
|
`)}function ae(t){return(t instanceof Error?t.message:String(t)).split(`
|
|
4
4
|
`)[0].slice(0,300)||(t instanceof Error?t.name:"unknown")}async function ir(t,e){try{return await new oe(t).plan(e)}catch{return}}var $=class extends Error{digest;plan;constructor(e,r){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>)`,...r?lr(r):[" palbase db:plan says what it would change"]].join(`
|
|
5
|
-
`)),this.name="SchemaNotPushed",this.digest=e,this.plan=r}};function lr(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 r of t.changes)e.push(` + ${r}`);for(let r of t.refusals)e.push(` \u2717 ${r}`);return e}async function ge(t,e,r,s){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=ce(t),l=ie(a),o=ue(t,de(e))(n);try{let c=await Gt(o.engine,l,{waitMs:s.onPlatform?
|
|
5
|
+
`)),this.name="SchemaNotPushed",this.digest=e,this.plan=r}};function lr(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 r of t.changes)e.push(` + ${r}`);for(let r of t.refusals)e.push(` \u2717 ${r}`);return e}var cr=8e4;async function ge(t,e,r,s){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=ce(t),l=ie(a),o=ue(t,de(e))(n);try{let c=!1,i=f=>{c||(c=!0,d.warn(`[palbase] database: not answering yet (${f instanceof Error?f.message:String(f)}) \u2014 waiting for it, as one waking does`))},u=await Gt(o.engine,l,{waitMs:s.onPlatform?cr:0,onUnreachable:i}).catch(async f=>{throw s.onPlatform||!(f instanceof tr)?f:new $(f.digest,await ir(o.pool,l))}),p=zt("sha256",r).update("palgres page cursor").digest("hex"),h=t.embed??s.embed,y=await Yt({sql:o.engine,schemas:a,binding:u,cursorSecret:p,admission:ar(o.poolSize),embed:h,log:f=>d.warn(`[palbase] ${f}`)}),b=nr(l)?Jt({sql:o.engine,embed:h,log:f=>d.info(`[palbase] ${f}`)}):void 0;return{model:l,binding:u,app:y,requests:t.requests??"caller",forget:f=>Xt(o.engine,u,l,f),...b?{search:b}:{},close:()=>o.close()}}catch(c){throw await o.close(),c}}function dr(t){let e=Buffer.from(t,"base64"),r=new Array(e.byteLength/4);for(let s=0;s<r.length;s++)r[s]=e.readFloatLE(s*4);return r}function be(t){return async({texts:e,model:r,dimensions:s})=>{let{data:n}=await t.ai.createEmbeddings({body:{input:e,model:r,dimensions:s}});return{model:n.model,vectors:n.vectors.map(dr)}}}var ur=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;function fe(t,e,r){let s=[],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"&&s.push("palbase.url / PALBASE_URL is https://<ref>.<domain>"),(u.pathname!=="/"||u.search||u.hash)&&s.push("palbase.url / PALBASE_URL is the project origin alone")}catch{s.push("palbase.url / PALBASE_URL is the project address, https://<ref>.<domain>")}let l=t.projectId??e.PALBASE_PROJECT_ID??"";ur.test(l)||s.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)||s.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)&&s.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 i=(t.webhookSecret??e.PALBASE_WEBHOOK_SECRET)||void 0;if(r.needsWebhookSecret&&(c!==void 0||i!==void 0)&&!/^whsec_[0-9a-f]{64}$/.test(i??"")&&s.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"),s.length>0)throw new Error(`[palbase] the app cannot start:
|
|
6
6
|
- ${s.join(`
|
|
7
|
-
- `)}`);return{url:a,projectId:l,secretKey:o,webhookSecret:r.needsWebhookSecret?i:void 0,platformSecret:c}}import{createHash as
|
|
7
|
+
- `)}`);return{url:a,projectId:l,secretKey:o,webhookSecret:r.needsWebhookSecret?i:void 0,platformSecret:c}}import{createHash as pr}from"node:crypto";import{gzipSync as hr}from"node:zlib";var gr="palbase-contract-v1 begin",br="palbase-contract-v1 end",me=76;function ye(t){let e=Buffer.from(t,"utf8"),r=hr(e).toString("base64"),s=[`${gr} ${pr("sha256").update(e).digest("hex")} ${e.length}`];for(let n=0;n<r.length;n+=me)s.push(r.slice(n,n+me));return s.push(br),`
|
|
8
8
|
${s.join(`
|
|
9
9
|
`)}
|
|
10
|
-
`}var Pe=2e4,Se=5e3,
|
|
11
|
-
`),process.exit(1),new x}throw a==="/dev/stdout"?we(1,ye(
|
|
12
|
-
`),process.exit(0),new x}let l=ve(s),o=await ke(l);o&&d.info(`[palbase] strings: ${o.source} and ${o.locales.length-1} other language(s), ${Object.keys(o.strings).length} sentence(s), from ${l}/palbase/strings`),te(o?void 0:l);let c=e.db?L(e.db):void 0,i=await H({env:s,url:e.palbase?.url,secretKey:e.palbase?.secretKey});i&&d.info(`[palbase] secrets: ${i.loaded.length} from the project's ${i.set} set${i.kept.length>0?`; ${i.kept.join(", ")} kept as the environment gives them`:""}`),i&&i.refused.length>0&&d.warn(`[palbase] secrets not set \u2014 names a process reads as its own, not the app's: ${i.refused.map(y=>JSON.stringify(y)).join(", ")}`);let u=Pr(r)||c!==void 0&&D(c),p=me(e.palbase??{},s,{needsWebhookSecret:u});u&&p.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 h=V({url:p.url,secretKey:p.secretKey}),b=e.port??Number(s.PORT??"8080");if(!Number.isInteger(b)||b<0||b>65535)throw new Error(`[palbase] PORT is a port number, not ${String(e.port??s.PORT)}`);let f=e.db?await ge(e.db,s,p.secretKey,{onPlatform:p.platformSecret!==void 0,embed:be(h)}):void 0;f&&d.info(`[palbase] database: version ${f.binding.version}`);let v=f&&D(f.model)?{"user.deleted":[y=>kr(f,y)]}:void 0,m=p.platformSecret===void 0?void 0:{secret:p.platformSecret},P=e.requestTelemetry===!1?void 0:new M(h.analytics),_=()=>F({modules:r,verifier:new T({issuer:p.url,projectId:p.projectId,standing:z({url:p.url,secretKey:p.secretKey})}),server:h,webhookSecret:p.webhookSecret,env:s,projectId:p.projectId,telemetry:P,auth:e.auth,tokens:e.tokens,rateLimit:e.rateLimit,maxBodyBytes:e.bodyLimit,cors:e.cors,platform:m,events:v,database:f&&{app:f.app,requests:f.requests},strings:o}),R=_(),N=e.boot?.attempts??5,q=e.boot?.backoffMs??1e3;for(let y=1;;y++)try{await R.start();break}catch(S){if(y>=N)throw d.error(`[palbase] the app did not start after ${N} attempts`,{error:S}),S;d.warn(`[palbase] the app did not start (attempt ${y} of ${N}); trying again in ${q} ms`,{error:S}),await new Promise(Fe=>setTimeout(Fe,q)),q*=2,R=_()}return Ar(R,h,b,e.host??"0.0.0.0",e.exitOnFatal??!0,f)}};function ve(t){let e=t.PALBASE_CONTRACT_ENTRY??process.argv[1];if(!e)return process.cwd();let r=k(Ae(e));for(;!W(K(r,"package.json"))&&k(r)!==r;)r=k(r);return W(K(r,"package.json"))?r:process.cwd()}async function ke(t){try{return await re(t)}catch(e){throw new Error(`[palbase] the app's strings: ${e instanceof Error?e.message:String(e)}`)}}async function vr(t,e,r){let s=Ae(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(;!W(K(n,"package.json"))&&k(n)!==n;)n=k(n);let{analyzeProject:a}=await import("../chunks/EHJKMDP3.js"),{routeContracts:l}=await import("../chunks/R43DXJZE.js"),o=a(n,s);for(let u of o.warnings)d.warn(`[palbase] the contract: ${u}`);let c="https://contract.palbase.invalid",i=F({modules:t,verifier:new T({issuer:c,projectId:"contract",standing:()=>Promise.reject(new Error("the contract run serves nothing"))}),server:V({url:c,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 l(o.routes),errors:ee()},events:e.db&&D(L(e.db))?{"user.deleted":[]}:void 0});return JSON.stringify(i.contract(),null,2)}var x=class extends Error{constructor(){super("[palbase] the contract run ended"),this.name="ContractRunEnded"}},U=class extends Error{code;constructor(e){super(`[palbase] the migration run ended with ${e}`),this.name="MigrationRunEnded",this.code=e}};async function kr(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);d.info(`[palbase] user ${r} deleted: ${s.deleted} row(s) gone, ${s.detached} forgot them`)}async function Ar(t,e,r,s,n,a){let l,o={on:!1},c=(m,P)=>new URL(m.url).pathname===wr&&m.method==="GET"?Promise.resolve(o.on?Response.json({ok:!1,stopping:!0},{status:503}):Response.json({ok:!0})):t.handle(m,P),i=mr((m,P)=>{Rr(c,m,P,o).finally(()=>{o.on&&i.closeIdleConnections()})});i.keepAliveTimeout=29e4,i.headersTimeout=3e5;try{await new Promise((m,P)=>{i.once("error",P),i.listen(r,s,()=>m())})}catch(m){throw await t.stop(),await a?.close(),m}let u=i.address().port;d.info(`[palbase] serving ${t.routes.length} route(s) on :${u}`,{routes:t.routes}),a?.search?.start();let p=m=>l??=(async()=>{d.info("[palbase] stopping: finishing the requests in flight"),o.on=!0;let P=new Promise(R=>i.close(()=>R()));i.closeIdleConnections();let _=setTimeout(()=>i.closeAllConnections(),m);await P,clearTimeout(_),process.off("SIGINT",f),process.off("uncaughtException",v),process.off("unhandledRejection",v);try{await t.stop(),await a?.search?.stop(),await a?.close()}finally{process.off("SIGTERM",f)}})(),h=()=>p(Pe),b=!1,f=()=>{if(b){d.info("[palbase] stopping: told to stop again; the requests in flight are still being finished");return}b=!0;let m=setTimeout(()=>{d.error("[palbase] stopping took longer than it is given; the process ends"),process.exit(1)},Pe+yr);m.unref(),h().then(()=>{clearTimeout(m),process.exit(0)},P=>{clearTimeout(m),d.error("[palbase] stopping failed; the process ends",{error:P}),process.exit(1)})},v=m=>{d.error("[palbase] the app crashed; stopping so the machine starts it again",{error:m});let P=setTimeout(()=>process.exit(1),Se+1e3);p(Se).finally(()=>{clearTimeout(P),process.exit(1)})};return process.on("SIGTERM",f),process.once("SIGINT",f),n&&(process.on("uncaughtException",v),process.on("unhandledRejection",v)),{routes:t.routes,palbase:e,port:u,handle:c,close:h}}async function Rr(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 l=new Headers;for(let[p,h]of Object.entries(e.headers))if(h!==void 0)if(Array.isArray(h))for(let b of h)l.append(p,b);else l.set(p,h);let o=e.method!=="GET"&&e.method!=="HEAD",c=new AbortController;r.on("close",()=>{r.writableFinished||c.abort(new Error("the client closed the connection"))});let i=new Request(a,{method:e.method,headers:l,body:o?fr.toWeb(e):void 0,duplex:"half",signal:c.signal}),u=await t(i,{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){d.error("[palbase] the request could not be answered",{error:n}),r.headersSent||(r.statusCode=500),r.end()}}import{bigint as Bs,boolean as Fs,check as Ms,date as Is,defineSchema as $s,defineTable as Ls,enumType as Ds,foreignKey as Us,index as js,integer as Ns,jsonb as qs,numeric as Vs,ownedByUser as Ws,policy as Ks,raw as zs,sqlType as Gs,text as Hs,timestamp as Ys,userRef as Js,uuid as Qs}from"palgres/dsl";import{increment as Zs,now as en}from"palgres";function A(t){if(t instanceof O)return{data:null,error:{code:t.code,message:t.message},status:t.status};throw t}async function w(t,e){try{let r=await t();return{data:await e(r.data),error:null,status:r.status}}catch(r){return A(r)}}var Er=E("Secrets",{async get(t){if(G(t))return null;let e=process.env[t];return typeof e=="string"&&e!==""?e:null}}),xr=100,_r=1e3,Or=168*3600,Tr={s:1,m:60,h:3600,d:86400};function Cr(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)*Tr[n]*1e3);return Math.ceil(r/1e3)}function Ce(t,e,r){let s=`${g.url}/storage/public/${encodeURIComponent(t)}/${encodeURIComponent(e)}`;return r?`${s}?variant=${encodeURIComponent(r)}`:s}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,Ce(t.bucket,t.path,e)]))}}function Br(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:Re(a.data),error:null,status:a.status}}catch(a){return a instanceof O&&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}:A(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 A(r)}},getPublicUrl(e,r){return Ce(t,e,r?.variant)},async createSignedUrl(e,r){let s=Cr(r?.expiresIn);return s===void 0||s<1||s>Or?{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}:w(()=>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??xr,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=[],l,o=200;try{for(;a.length<s;){let c=Math.max(1,Math.min(_r,n+s-a.length)),i=await g.storage.listObjects({path:{bucket:t},query:{...e?{prefix:e}:{},limit:c,...l?{cursor:l}:{}}});o=i.status;for(let u of i.data.objects)n>0?n--:a.length<s&&a.push(Re(u));if(l=i.data.next_cursor,!l)break}}catch(c){return A(c)}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 A(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 w(()=>g.storage.moveObject({path:{bucket:t},body:{from:e,to:r}}),()=>{})},copy(e,r){return w(()=>g.storage.copyObject({path:{bucket:t},body:{from:e,to:r}}),()=>{})}}}var Fr={bucket:Br},Ee=t=>X("Storage",t,Fr),Mr={bucket:t=>Ee("bucket").bucket(t),buckets:new Proxy({},{get:(t,e)=>typeof e=="string"?Ee("buckets").bucket(e):void 0})},Ir=E("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 w(()=>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 w(()=>g.notify.sendEmail({body:{...n,to:e}}),o=>({...o.message_id!==void 0?{message_id:o.message_id}:{},...o.skipped?{skipped:!0}:{}}));let a=[],l=202;for(let o of e)try{let c=await g.notify.sendEmail({body:{...n,to:o}});l=c.status,a.push(c.data.message_id??null)}catch(c){return A(c)}return{data:{message_ids:a},error:null,status:l}}}}),xe=t=>typeof t=="boolean"?t:t!=null&&t!==0&&t!=="",_e=t=>typeof t=="string"?{name:t}:null,Oe=t=>t==="override"?"user":"system",$r=t=>t!==null&&typeof t=="object"&&!Array.isArray(t)&&("userId"in t||"properties"in t);function Be(){return Z.getStore()?.userId}function j(t){let e=t&&"userId"in t?t.userId??void 0:Be();return w(()=>e?g.flags.getUserValues({path:{user_id:e}}):g.flags.getValues(),r=>r.values??{})}var Te={setOverrideForUser:(t,e,r)=>w(()=>g.flags.putUserValue({path:{user_id:t,key:e},body:{value:r}}),s=>({key:s.key,value:s.value,source:Oe(s.source)})),setOverridesForUser:(t,e)=>w(()=>g.flags.putUserValues({path:{user_id:t},body:{values:e}}),r=>({values:r.values??{}})),clearOverrideForUser:(t,e)=>w(()=>g.flags.deleteUserValue({path:{user_id:t,key:e}}),r=>({key:r.key,value:r.value,source:Oe(r.source)})),clearAllOverridesForUser:t=>w(()=>g.flags.deleteUserValues({path:{user_id:t}}),e=>({deleted:e.deleted})),batchSetOverrides:t=>w(()=>g.flags.batchUserValues({body:{operations:t.map(e=>({user_id:e.userId,values:e.values}))}}),e=>({applied:e.applied}))},Lr=E("Flags",{async isEnabled(t,e){let r=s=>(d.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}`):xe(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:_e(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=_e(s);return{name:r,enabled:xe(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):$r(e)?a=e:e!==void 0&&(s=e,n=!0);let l=await j(a);if(l.error)return n?{data:s??null,error:null,status:l.status}:{data:null,error:l.error,status:l.status};let o=l.data[t];return{data:o===void 0?s??null:o,error:null,status:l.status}},async setOverride(t,e){let r=Be();return r?Te.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 Te}}),Dr=E("Realtime",{broadcast(t,e,r){return w(()=>g.realtime.broadcast({body:{messages:[{topic:t,event:e,payload:r??{}}]}}),()=>{})},state:{set(t,e,r){return w(()=>g.realtime.writeState({body:{ops:[{topic:t,key:e,value:r}]}}),()=>{})},clear(t,e){return w(()=>g.realtime.writeState({body:{ops:[{topic:t,key:e,delete:!0}]}}),()=>{})}}});import{z as cn}from"zod";export{$e as AuthUnavailable,Tt as BadRequest,We as Body,jt as CACHE_MAX_TTL,Nt as Cache,Ze as Client,Ct as Conflict,x as ContractRunEnded,Le as Controller,nt as Cron,lt as Database,Bt as DeadlockDetected,qe as Delete,Rt as DiError,Me as EVENT_TYPES,Lr as Flags,_t as Forbidden,De as Get,ze as Headers,Ft as HttpError,tt as Injectable,d as Log,Ut as MAX_BODY_BYTES,U as MigrationRunEnded,rt as Module,Mt as NotFound,Ir as Notifications,st as On,ht as OnAuthorize,ft as OnEmpty,gt as OnFirst,bt as OnJoin,mt as OnLeave,yt as OnMessage,Ye as OptionalUser,Et as PalError,g as Palbase,O as PalbaseError,Sr as PalbaseFactory,Ge as Param,Ne as Patch,Ue as Post,je as Put,Ve as Query,Ke as QueryParams,Dr as Realtime,Je as Req,Qe as RequestId,et as Resolve,pt as Room,$ as SchemaNotPushed,Er as Secrets,It as SerializationFailure,Mr as Storage,dt as Task,ct as TaskFailure,ut as Tasks,Ie as TokenError,T as TokenVerifier,$t as TooManyRequests,Xe as TraceId,xt as Unauthorized,Lt as UniqueViolation,vt as Upload,kt as UploadedObject,He as User,at as Webhook,Bs as bigint,Fs as boolean,Ms as check,F as createApp,Is as date,St as defineChannels,Ot as defineError,$s as defineSchema,Ls as defineTable,Ds as enumType,Us as foreignKey,ot as getRegisteredControllers,it as getRoutes,At as getWebhookManifest,Zs as increment,js as index,Ns as integer,qs as jsonb,en as now,Vs as numeric,Ws as ownedByUser,wt as ownerOnly,Ks as policy,Pt as publicChannel,zs as raw,Gs as sqlType,Dt as t,Hs as text,Ys as timestamp,Js as userRef,Qs as uuid,cn as z};
|
|
10
|
+
`}var Pe=2e4,Se=5e3,wr=15e3,Pr="/_palbase/health";function Sr(t){let e=new Set,r=s=>{if(e.has(s))return!1;e.add(s);let n=C(s,Y);return n?n.providers.some(a=>C(a,J)!==void 0&&C(a,Q)===void 0)||n.imports.some(r):!1};return t.some(r)}var vr={async create(t,e={}){let r=Array.isArray(t)?t:[t],s=e.env??process.env,n=le(s);if(n!==void 0){let w=e.db?await he(e.db,s,n):pe(n);throw process.exit(w),new U(w)}let a=s.PALBASE_CONTRACT_OUT;if(a){let w;try{await ke(ve(s)),w=await kr(r,e,s)}catch(v){throw we(2,`[palbase] the contract: ${v instanceof Error?v.message:String(v)}
|
|
11
|
+
`),process.exit(1),new x}throw a==="/dev/stdout"?we(1,ye(w)):fr(a,`${w}
|
|
12
|
+
`),process.exit(0),new x}let l=ve(s),o=await ke(l);o&&d.info(`[palbase] strings: ${o.source} and ${o.locales.length-1} other language(s), ${Object.keys(o.strings).length} sentence(s), from ${l}/palbase/strings`),te(o?void 0:l);let c=e.db?L(e.db):void 0,i=await H({env:s,url:e.palbase?.url,secretKey:e.palbase?.secretKey});i&&d.info(`[palbase] secrets: ${i.loaded.length} from the project's ${i.set} set${i.kept.length>0?`; ${i.kept.join(", ")} kept as the environment gives them`:""}`),i&&i.refused.length>0&&d.warn(`[palbase] secrets not set \u2014 names a process reads as its own, not the app's: ${i.refused.map(w=>JSON.stringify(w)).join(", ")}`);let u=Sr(r)||c!==void 0&&D(c),p=fe(e.palbase??{},s,{needsWebhookSecret:u});u&&p.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 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 ge(e.db,s,p.secretKey,{onPlatform:p.platformSecret!==void 0,embed:be(h)}):void 0;b&&d.info(`[palbase] database: version ${b.binding.version}`);let f=b&&D(b.model)?{"user.deleted":[w=>Ar(b,w)]}:void 0,m=p.platformSecret===void 0?void 0:{secret:p.platformSecret},S=e.requestTelemetry===!1?void 0:new M(h.analytics),_=()=>F({modules:r,verifier:new O({issuer:p.url,projectId:p.projectId,standing:z({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:e.cors,platform:m,events:f,database:b&&{app:b.app,requests:b.requests},strings:o}),R=_(),N=e.boot?.attempts??5,q=e.boot?.backoffMs??1e3;for(let w=1;;w++)try{await R.start();break}catch(v){if(w>=N)throw d.error(`[palbase] the app did not start after ${N} attempts`,{error:v}),v;d.warn(`[palbase] the app did not start (attempt ${w} of ${N}); trying again in ${q} ms`,{error:v}),await new Promise(Fe=>setTimeout(Fe,q)),q*=2,R=_()}return Rr(R,h,y,e.host??"0.0.0.0",e.exitOnFatal??!0,b)}};function ve(t){let e=t.PALBASE_CONTRACT_ENTRY??process.argv[1];if(!e)return process.cwd();let r=k(Ae(e));for(;!W(K(r,"package.json"))&&k(r)!==r;)r=k(r);return W(K(r,"package.json"))?r:process.cwd()}async function ke(t){try{return await re(t)}catch(e){throw new Error(`[palbase] the app's strings: ${e instanceof Error?e.message:String(e)}`)}}async function kr(t,e,r){let s=Ae(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(;!W(K(n,"package.json"))&&k(n)!==n;)n=k(n);let{analyzeProject:a}=await import("../chunks/EDVRVUCJ.js"),{routeContracts:l}=await import("../chunks/LHLMCQKI.js"),o=a(n,s);for(let u of o.warnings)d.warn(`[palbase] the contract: ${u}`);let c="https://contract.palbase.invalid",i=F({modules:t,verifier:new O({issuer:c,projectId:"contract",standing:()=>Promise.reject(new Error("the contract run serves nothing"))}),server:V({url:c,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 l(o.routes),errors:ee()},events:e.db&&D(L(e.db))?{"user.deleted":[]}:void 0});return JSON.stringify(i.contract(),null,2)}var x=class extends Error{constructor(){super("[palbase] the contract run ended"),this.name="ContractRunEnded"}},U=class extends Error{code;constructor(e){super(`[palbase] the migration run ended with ${e}`),this.name="MigrationRunEnded",this.code=e}};async function Ar(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);d.info(`[palbase] user ${r} deleted: ${s.deleted} row(s) gone, ${s.detached} forgot them`)}async function Rr(t,e,r,s,n,a){let l,o={on:!1},c=(m,S)=>new URL(m.url).pathname===Pr&&m.method==="GET"?Promise.resolve(o.on?Response.json({ok:!1,stopping:!0},{status:503}):Response.json({ok:!0})):t.handle(m,S),i=mr((m,S)=>{Er(c,m,S,o).finally(()=>{o.on&&i.closeIdleConnections()})});i.keepAliveTimeout=29e4,i.headersTimeout=3e5;try{await new Promise((m,S)=>{i.once("error",S),i.listen(r,s,()=>m())})}catch(m){throw await t.stop(),await a?.close(),m}let u=i.address().port;d.info(`[palbase] serving ${t.routes.length} route(s) on :${u}`,{routes:t.routes}),a?.search?.start();let p=m=>l??=(async()=>{d.info("[palbase] stopping: finishing the requests in flight"),o.on=!0;let S=new Promise(R=>i.close(()=>R()));i.closeIdleConnections();let _=setTimeout(()=>i.closeAllConnections(),m);await S,clearTimeout(_),process.off("SIGINT",b),process.off("uncaughtException",f),process.off("unhandledRejection",f);try{await t.stop(),await a?.search?.stop(),await a?.close()}finally{process.off("SIGTERM",b)}})(),h=()=>p(Pe),y=!1,b=()=>{if(y){d.info("[palbase] stopping: told to stop again; the requests in flight are still being finished");return}y=!0;let m=setTimeout(()=>{d.error("[palbase] stopping took longer than it is given; the process ends"),process.exit(1)},Pe+wr);m.unref(),h().then(()=>{clearTimeout(m),process.exit(0)},S=>{clearTimeout(m),d.error("[palbase] stopping failed; the process ends",{error:S}),process.exit(1)})},f=m=>{d.error("[palbase] the app crashed; stopping so the machine starts it again",{error:m});let S=setTimeout(()=>process.exit(1),Se+1e3);p(Se).finally(()=>{clearTimeout(S),process.exit(1)})};return process.on("SIGTERM",b),process.once("SIGINT",b),n&&(process.on("uncaughtException",f),process.on("unhandledRejection",f)),{routes:t.routes,palbase:e,port:u,handle:c,close:h}}async function Er(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 l=new Headers;for(let[p,h]of Object.entries(e.headers))if(h!==void 0)if(Array.isArray(h))for(let y of h)l.append(p,y);else l.set(p,h);let o=e.method!=="GET"&&e.method!=="HEAD",c=new AbortController;r.on("close",()=>{r.writableFinished||c.abort(new Error("the client closed the connection"))});let i=new Request(a,{method:e.method,headers:l,body:o?yr.toWeb(e):void 0,duplex:"half",signal:c.signal}),u=await t(i,{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){d.error("[palbase] the request could not be answered",{error:n}),r.headersSent||(r.statusCode=500),r.end()}}import{bigint as Fs,boolean as Ms,check as Is,date as $s,defineSchema as Ls,defineTable as Ds,enumType as Us,foreignKey as js,index as Ns,integer as qs,jsonb as Vs,numeric as Ws,ownedByUser as Ks,policy as zs,raw as Gs,sqlType as Hs,text as Ys,timestamp as Js,userRef as Qs,uuid as Xs}from"palgres/dsl";import{increment as en,now as tn}from"palgres";function A(t){if(t instanceof T)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 A(r)}}var xr=E("Secrets",{async get(t){if(G(t))return null;let e=process.env[t];return typeof e=="string"&&e!==""?e:null}}),_r=100,Tr=1e3,Or=168*3600,Cr={s:1,m:60,h:3600,d:86400};function Br(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)*Cr[n]*1e3);return Math.ceil(r/1e3)}function Ce(t,e,r){let s=`${g.url}/storage/public/${encodeURIComponent(t)}/${encodeURIComponent(e)}`;return r?`${s}?variant=${encodeURIComponent(r)}`:s}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,Ce(t.bucket,t.path,e)]))}}function Fr(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:Re(a.data),error:null,status:a.status}}catch(a){return a instanceof T&&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}:A(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 A(r)}},getPublicUrl(e,r){return Ce(t,e,r?.variant)},async createSignedUrl(e,r){let s=Br(r?.expiresIn);return s===void 0||s<1||s>Or?{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??_r,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=[],l,o=200;try{for(;a.length<s;){let c=Math.max(1,Math.min(Tr,n+s-a.length)),i=await g.storage.listObjects({path:{bucket:t},query:{...e?{prefix:e}:{},limit:c,...l?{cursor:l}:{}}});o=i.status;for(let u of i.data.objects)n>0?n--:a.length<s&&a.push(Re(u));if(l=i.data.next_cursor,!l)break}}catch(c){return A(c)}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 A(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 Mr={bucket:Fr},Ee=t=>X("Storage",t,Mr),Ir={bucket:t=>Ee("bucket").bucket(t),buckets:new Proxy({},{get:(t,e)=>typeof e=="string"?Ee("buckets").bucket(e):void 0})},$r=E("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=[],l=202;for(let o of e)try{let c=await g.notify.sendEmail({body:{...n,to:o}});l=c.status,a.push(c.data.message_id??null)}catch(c){return A(c)}return{data:{message_ids:a},error:null,status:l}}}}),xe=t=>typeof t=="boolean"?t:t!=null&&t!==0&&t!=="",_e=t=>typeof t=="string"?{name:t}:null,Te=t=>t==="override"?"user":"system",Lr=t=>t!==null&&typeof t=="object"&&!Array.isArray(t)&&("userId"in t||"properties"in t);function Be(){return Z.getStore()?.userId}function j(t){let e=t&&"userId"in t?t.userId??void 0:Be();return P(()=>e?g.flags.getUserValues({path:{user_id:e}}):g.flags.getValues(),r=>r.values??{})}var Oe={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:Te(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:Te(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}))},Dr=E("Flags",{async isEnabled(t,e){let r=s=>(d.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}`):xe(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:_e(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=_e(s);return{name:r,enabled:xe(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):Lr(e)?a=e:e!==void 0&&(s=e,n=!0);let l=await j(a);if(l.error)return n?{data:s??null,error:null,status:l.status}:{data:null,error:l.error,status:l.status};let o=l.data[t];return{data:o===void 0?s??null:o,error:null,status:l.status}},async setOverride(t,e){let r=Be();return r?Oe.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 Oe}}),Ur=E("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 dn}from"zod";export{$e as AuthUnavailable,Ot as BadRequest,We as Body,jt as CACHE_MAX_TTL,Nt as Cache,Ze as Client,Ct as Conflict,x as ContractRunEnded,Le as Controller,nt as Cron,lt as Database,Bt as DeadlockDetected,qe as Delete,Rt as DiError,Me as EVENT_TYPES,Dr as Flags,_t as Forbidden,De as Get,ze as Headers,Ft as HttpError,tt as Injectable,d as Log,Ut as MAX_BODY_BYTES,U as MigrationRunEnded,rt as Module,Mt as NotFound,$r as Notifications,st as On,ht as OnAuthorize,mt as OnEmpty,gt as OnFirst,bt as OnJoin,ft as OnLeave,yt as OnMessage,Ye as OptionalUser,Et as PalError,g as Palbase,T as PalbaseError,vr as PalbaseFactory,Ge as Param,Ne as Patch,Ue as Post,je as Put,Ve as Query,Ke as QueryParams,Ur as Realtime,Je as Req,Qe as RequestId,et as Resolve,pt as Room,$ as SchemaNotPushed,xr as Secrets,It as SerializationFailure,Ir as Storage,dt as Task,ct as TaskFailure,ut as Tasks,Ie as TokenError,O as TokenVerifier,$t as TooManyRequests,Xe as TraceId,xt as Unauthorized,Lt as UniqueViolation,vt as Upload,kt as UploadedObject,He as User,at as Webhook,Fs as bigint,Ms as boolean,Is as check,F as createApp,$s as date,St as defineChannels,Tt as defineError,Ls as defineSchema,Ds as defineTable,Us as enumType,js as foreignKey,ot as getRegisteredControllers,it as getRoutes,At as getWebhookManifest,en as increment,Ns as index,qs as integer,Vs as jsonb,tn as now,Ws as numeric,Ks as ownedByUser,wt as ownerOnly,zs as policy,Pt as publicChannel,Gs as raw,Hs as sqlType,Dt as t,Ys as text,Js as timestamp,Qs as userRef,Xs as uuid,dn as z};
|
package/dist/backend/stack.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
/*! palbase 0.5.
|
|
1
|
+
/*! palbase 0.5.2 — Palbase SDK License (see LICENSE) */
|
package/dist/backend/test.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.5.
|
|
2
|
-
import{a as l,b as g,c as f,d as m}from"../chunks/
|
|
1
|
+
/*! palbase 0.5.2 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{a as l,b as g,c as f,d as m}from"../chunks/ZJOO2XZ2.js";import{a as u}from"../chunks/4ZVJ62A3.js";import{c as p,h as c}from"../chunks/FNUO6DSY.js";import"../chunks/TPBWIRHS.js";import"../chunks/MYNCDAKM.js";import"reflect-metadata";import{randomUUID as y}from"node:crypto";import{createFakeClient as T,typedDatabase as d}from"palgres/testing";function w(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_${y()}`,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=T();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,m as api,g as createTestApi,h as fakeDatabase,b as isolated,u as loadStringsTable,f as testRun,w as withServices};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.5.
|
|
1
|
+
/*! palbase 0.5.2 — Palbase SDK License (see LICENSE) */
|
|
2
2
|
import{lstat as j,mkdir as F,readdir as M,readFile as N,rename as J,rm as T,writeFile as v}from"node:fs/promises";import{join as E}from"node:path";var o="palbase/strings",f="_meta.json",p=3,y=2,$=r=>typeof r=="object"&&r!==null&&!Array.isArray(r);function m(r){try{return Intl.getCanonicalLocales(r)[0]}catch{return}}function b(r,n){try{return JSON.parse(r)}catch(t){throw new Error(`${n} is not JSON: ${t.message}`)}}async function x(r){let n=E(r,o);try{if(!(await j(n)).isDirectory())throw new Error(`${o} is not a directory: the strings live in a directory of their own`)}catch(e){if(e.code==="ENOENT")return;throw e}let t=new Map;for(let e of await M(n,{withFileTypes:!0}))if(!(e.name.startsWith(".")||!e.name.endsWith(".json"))){if(!e.isFile())throw new Error(`${o}/${e.name} is not a regular file`);t.set(e.name,await N(E(n,e.name),"utf8"))}return t.size===0?void 0:t}async function R(r,n=[p,y]){let t=await x(r);if(t===void 0)return;let e=t.get(f);if(e===void 0)throw new Error(`${o}/${f} is missing: it names the source language, and without it the language files are not a table`);let u=b(e,`${o}/${f}`);if(!$(u))throw new Error(`${o}/${f}: not a JSON object`);let s=u.version;if(s===y&&!n.includes(y))throw new Error(`${o}/${f}: version 2 is the earlier format ({"value", "state"} for each sentence) \u2014 run \`npx palbase strings\` once, and it writes the table as version ${p}`);if(typeof s!="number"||!n.includes(s))throw new Error(`${o}/${f}: version ${JSON.stringify(s)} is not one this reads (${n.join(" or ")})`);let a=u.source;if(typeof a!="string"||m(a)!==a)throw new Error(`${o}/${f}: source ${JSON.stringify(a)} is not a language tag as it is written (${m(String(a))??"en, en-US, zh-Hans"})`);let S=new Map;for(let w of[...t.keys()].sort()){if(w===f)continue;let i=w.slice(0,-5),g=`${o}/${w}`,d=m(i);if(d===void 0)throw new Error(`${g}: ${JSON.stringify(i)} is not a language tag`);if(d!==i)throw new Error(`${g}: the language is written ${d} \u2014 name the file ${d}.json`);if(i===a)throw new Error(`${g}: ${i} is the source language \u2014 its text is the key itself, and it has no file`);if(i==="und"||i==="root"||i.startsWith("x-"))throw new Error(`${g}: ${i} is no language a request names \u2014 name the file for one (en, de, pt-BR)`);let O=b(t.get(w),g);if(!$(O))throw new Error(`${g}: not a JSON object of "sentence": "translation"`);let h=new Map;for(let[l,c]of Object.entries(O))if(s===p){if(typeof c!="string")throw new Error(`${g}: the translation of ${JSON.stringify(l)} is not a string`);h.set(l,c)}else if(typeof c=="string")h.set(l,c);else{if(!$(c)||typeof c.value!="string")throw new Error(`${g}: key ${JSON.stringify(l)} is not {"value": string, "state": string}`);h.set(l,c.state==="missing"?"":c.value)}S.set(i,h)}return{format:s,source:a,languages:S}}async function A(r){let n=await R(r,[p]);if(n===void 0)return;let t={};Object.setPrototypeOf(t,null);for(let[e,u]of n.languages)for(let[s,a]of u)Object.hasOwn(t,s)||(t[s]={},Object.setPrototypeOf(t[s],null)),t[s][e]=a;return{source:n.source,locales:[n.source,...n.languages.keys()],strings:t}}export{A as a};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! palbase 0.5.
|
|
2
|
-
import{b as c,f as u}from"./
|
|
1
|
+
/*! palbase 0.5.2 — Palbase SDK License (see LICENSE) */
|
|
2
|
+
import{b as c,f as u}from"./HLYQRT7O.js";var l={attempts:3,maxWaitSeconds:30},y=new Set([429,502,503,504]);function x(e,t=l){let r=t.sleep??h;return{async send(o){let n=p(o),a=n.body,m=!a||a.kind!=="raw"||u(a.value),f=(n.method==="GET"||n.method==="HEAD"||n.idempotent===!0)&&m;for(let i=1;;i++)try{return await e.send(n)}catch(s){if(!f||i>=t.attempts||!(s instanceof c)||n.signal?.aborted)throw s;let d=b(s,i,t.maxWaitSeconds);if(d===void 0)throw s;await r(d*1e3,n.signal)}}}}function p(e){return e.idempotent?Object.entries(e.headers??{}).some(([r,o])=>r.toLowerCase()==="idempotency-key"&&o!==void 0&&o!==null&&o!=="")?e:{...e,headers:{...e.headers,"Idempotency-Key":w()}}:e}function b(e,t,r){return y.has(e.status)||e.code==="network_error"?e.retryAfter!==void 0?e.retryAfter<=r?e.retryAfter:void 0:Math.min(.5*2**(t-1),r)*(.8+Math.random()*.4):void 0}function h(e,t){return new Promise((r,o)=>{if(t?.aborted)return o(t.reason);let n=()=>{clearTimeout(a),o(t?.reason)},a=setTimeout(()=>{t?.removeEventListener("abort",n),r()},e);t?.addEventListener("abort",n,{once:!0})})}function w(){if(typeof crypto.randomUUID=="function")return crypto.randomUUID();let e=crypto.getRandomValues(new Uint8Array(16));e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=[...e].map(r=>r.toString(16).padStart(2,"0")).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}export{l as a,x as b,b as c,w as d};
|