@lunora/codegen 1.0.0-alpha.114 → 1.0.0-alpha.115
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/index.mjs +1 -1
- package/dist/packem_shared/{GENERATED_HEADER-GSCh67g3.mjs → GENERATED_HEADER-hlnTcuPd.mjs} +1 -1
- package/dist/packem_shared/{MUTATORS_FILENAME-CRmTpN4y.mjs → MUTATORS_FILENAME-sGAt-yC1.mjs} +1 -1
- package/dist/packem_shared/{NOTIFY_FILENAME-BybR3Xbd.mjs → NOTIFY_FILENAME-CTZI61e3.mjs} +1 -1
- package/dist/packem_shared/{OPENRPC_VERSION-DB1PSt8W.mjs → OPENRPC_VERSION-DpRms_jN.mjs} +1 -1
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-CGCzlXbr.mjs +9 -0
- package/dist/packem_shared/{SHAPES_FILENAME-DxoIrQhA.mjs → SHAPES_FILENAME-DTp6VI6K.mjs} +1 -1
- package/dist/packem_shared/{buildOpenApiDocument-B2mW3f5a.mjs → buildOpenApiDocument-ClEtrbbS.mjs} +1 -1
- package/dist/packem_shared/{discoverFunctions-h8i51Mec.mjs → discoverFunctions-4eSpCR6m.mjs} +1 -1
- package/dist/packem_shared/{discoverHttpRoutes-MX6y-iVE.mjs → discoverHttpRoutes-DOirwCWw.mjs} +1 -1
- package/dist/packem_shared/{discoverMaskProcedures-DhcK-YMG.mjs → discoverMaskProcedures-D-09Qb8S.mjs} +1 -1
- package/dist/packem_shared/{discoverNondeterministicCalls-CjS2Mznw.mjs → discoverNondeterministicCalls-DhNToI6C.mjs} +1 -1
- package/dist/packem_shared/{discoverR2sqlCalls-DuTuaSMM.mjs → discoverR2sqlCalls-B6e4j4rD.mjs} +1 -1
- package/dist/packem_shared/{discoverRlsMetadata-BYVq6cVp.mjs → discoverRlsMetadata-Pw0_c1aS.mjs} +1 -1
- package/dist/packem_shared/discoverSchema-D_wHstA-.mjs +1 -0
- package/dist/packem_shared/{discoverStorageRulesMetadata-CKPFWHT5.mjs → discoverStorageRulesMetadata-DthHu3mC.mjs} +1 -1
- package/dist/packem_shared/{emit-Ba3NiOwK.mjs → emit-CV6JjAt9.mjs} +78 -64
- package/dist/packem_shared/{emitApp-CXeJ0y98.mjs → emitApp-BBcZ_fPU.mjs} +41 -26
- package/dist/packem_shared/parse-validator-C5ycrhR3.mjs +1 -0
- package/package.json +6 -6
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-DgAbfC_h.mjs +0 -9
- package/dist/packem_shared/discoverSchema-BtlNz9b_.mjs +0 -1
- package/dist/packem_shared/parse-validator-DtALyvid.mjs +0 -1
|
@@ -15,13 +15,13 @@ import{agentComponent as ot}from"@lunora/agent/component";import{LunoraError as
|
|
|
15
15
|
/**
|
|
16
16
|
* R2 SQL over Apache Iceberg tables (window functions, DISTINCT, set operations). Non-deterministic — available only in actions. Reads here are NOT tracked by Lunora live queries.
|
|
17
17
|
*/
|
|
18
|
-
readonly r2sql: import("@lunora/bindings/r2sql").R2SqlClient;`,tier:"action"}},{contextProperty:"scheduler",key:"scheduler",moduleSpecifier:"@lunora/scheduler"},{contextProperty:"storage",key:"storage",moduleSpecifier:"@lunora/storage"},{appMethod:{configKey:"vectors",doc:"Wire the Vectorize index map backing `ctx.vectors`.",method:"vectors"},contextProperty:"vectors",key:"vectors",moduleSpecifier:"@lunora/bindings/vectors"},{contextProperty:"workflows",key:"workflows",moduleSpecifier:"@lunora/workflow"}],gn=at,fn=new Map(gn.flatMap(e=>e.serverCtxField?[[e.key,e.serverCtxField]]:[])),jr=at.flatMap(e=>"appMethod"in e?[{appMethod:e.appMethod,key:e.key}]:[]),st=/^(?:"(?:[^"\\]|\\(?:["\\/bfnrt]|u[0-9A-Fa-f]{4}))*"|'[^'\\]*'|-?\d+(?:\.\d+)?|true|false|null)$/u,
|
|
18
|
+
readonly r2sql: import("@lunora/bindings/r2sql").R2SqlClient;`,tier:"action"}},{contextProperty:"scheduler",key:"scheduler",moduleSpecifier:"@lunora/scheduler"},{contextProperty:"storage",key:"storage",moduleSpecifier:"@lunora/storage"},{appMethod:{configKey:"vectors",doc:"Wire the Vectorize index map backing `ctx.vectors`.",method:"vectors"},contextProperty:"vectors",key:"vectors",moduleSpecifier:"@lunora/bindings/vectors"},{contextProperty:"workflows",key:"workflows",moduleSpecifier:"@lunora/workflow"}],gn=at,fn=new Map(gn.flatMap(e=>e.serverCtxField?[[e.key,e.serverCtxField]]:[])),jr=at.flatMap(e=>"appMethod"in e?[{appMethod:e.appMethod,key:e.key}]:[]),st=/^(?:"(?:[^"\\]|\\(?:["\\/bfnrt]|u[0-9A-Fa-f]{4}))*"|'[^'\\]*'|-?\d+(?:\.\d+)?|true|false|null)$/u,bn=new Set(["any","bigint","boolean","date","id","null","number","storage","string","timestamp"]),it=e=>e.column!==void 0,yn=(e,t)=>{switch(e){case"bigint":return`if (typeof ${t} !== "bigint") return DEFER;
|
|
19
19
|
`;case"boolean":return`if (typeof ${t} !== "boolean") return DEFER;
|
|
20
20
|
`;case"date":case"number":case"timestamp":return`if (typeof ${t} !== "number" || !Number.isFinite(${t})) return DEFER;
|
|
21
21
|
`;case"null":return`if (${t} !== null) return DEFER;
|
|
22
22
|
`;default:return`if (typeof ${t} !== "string") return DEFER;
|
|
23
|
-
`}},
|
|
24
|
-
`}},We=(e,t,n)=>{if(!it(e)&&!(e.hasRefinement||e.sourceText!==void 0)){if(
|
|
23
|
+
`}},kn=(e,t)=>{const n=e.literalValue?.trim();if(!(n===void 0||!st.test(n)))return{out:t,pre:`if (${t} !== ${n}) return DEFER;
|
|
24
|
+
`}},We=(e,t,n)=>{if(!it(e)&&!(e.hasRefinement||e.sourceText!==void 0)){if(bn.has(e.kind))return e.kind==="any"?{out:t,pre:""}:{out:t,pre:yn(e.kind,t)};switch(e.kind){case"array":return xn(e,t,n);case"literal":return kn(e,t);case"object":return vn(e,t,n);default:return}}},xn=(e,t,n)=>{const{inner:r}=e;if(!r)return;const o=n.next(),s=`__arr${String(o)}`,i=`__i${String(o)}`,a=`__e${String(o)}`,c=We(r,a,n);if(!c)return;const d=`if (!Array.isArray(${t})) return DEFER;
|
|
25
25
|
const ${s} = new Array(${t}.length);
|
|
26
26
|
for (let ${i} = 0; ${i} < ${t}.length; ${i}++) {
|
|
27
27
|
const ${a} = ${t}[${i}];
|
|
@@ -41,12 +41,12 @@ ${r.pre}return { ${r.entries} };
|
|
|
41
41
|
}`},R=`// GENERATED by @lunora/codegen — do not edit.
|
|
42
42
|
// Run \`lunora codegen\` to regenerate.
|
|
43
43
|
|
|
44
|
-
`,ne=(e=!1)=>e?{client:"lunorash/client",do:"lunorash/do",flags:"lunorash/flags",server:"lunorash/server",serverDataModel:"lunorash/server/data-model",serverDrizzle:"lunorash/server/drizzle",serverTypes:"lunorash/server/types",values:"lunorash/values"}:{client:"@lunora/client",do:"@lunora/do",flags:"@lunora/flags",server:"@lunora/server",serverDataModel:"@lunora/server/data-model",serverDrizzle:"@lunora/server/drizzle",serverTypes:"@lunora/server/types",values:"@lunora/values"},ct=/^[A-Za-z_$][\w$]*$/u,Rn=/^[\w./-]+$/u,g=(e,t)=>{if(!ct.test(e))throw new te("INTERNAL",`@lunora/codegen: ${t} is not a valid JS identifier: ${JSON.stringify(e)}`)},qe=e=>e.charAt(0).toUpperCase()+e.slice(1),_=e=>ct.test(e)?e:JSON.stringify(e),Sn={any:"unknown",bigint:"bigint",boolean:"boolean",bytes:"ArrayBuffer",date:"number",geoPoint:"{ lat: number; lng: number }",null:"null",number:"number",storage:"string",string:"string",timestamp:"number"},Nn=e=>{if(e===void 0)return"unknown";if(!st.test(e))throw new te("INTERNAL",`@lunora/codegen: v.literal() argument is not a parseable string/number/boolean/null literal: ${JSON.stringify(e)}`);return e},N=e=>{const t=Sn[e.kind];if(t!==void 0)return t;switch(e.kind){case"array":return`Array<${e.inner?N(e.inner):"unknown"}>`;case"from":return e.tsType??"unknown";case"id":{const n=e.tableName??"_unknown_";return g(n,"v.id() table name"),`Id<"${n}">`}case"literal":return Nn(e.literalValue);case"object":return e.shape?`{ ${Object.entries(e.shape).map(([r,o])=>dt(r,o)).join("; ")} }`:"Record<string, unknown>";case"optional":return`${e.inner?N(e.inner):"unknown"} | undefined`;case"record":{const n=e.keyType?N(e.keyType):"string",r=e.valueType?N(e.valueType):"unknown";return`Record<${n}, ${r}>`}case"union":return e.members&&e.members.length>0?e.members.map(n=>N(n)).join(" | "):"never";default:return"unknown"}},dt=(e,t)=>{const n=_(e);if(t.kind==="optional"){const r=t.inner?N(t.inner):"unknown";return`${n}?: ${r}`}return`${n}: ${N(t)}`},
|
|
44
|
+
`,ne=(e=!1)=>e?{client:"lunorash/client",do:"lunorash/do",flags:"lunorash/flags",server:"lunorash/server",serverDataModel:"lunorash/server/data-model",serverDrizzle:"lunorash/server/drizzle",serverTypes:"lunorash/server/types",values:"lunorash/values"}:{client:"@lunora/client",do:"@lunora/do",flags:"@lunora/flags",server:"@lunora/server",serverDataModel:"@lunora/server/data-model",serverDrizzle:"@lunora/server/drizzle",serverTypes:"@lunora/server/types",values:"@lunora/values"},ct=/^[A-Za-z_$][\w$]*$/u,Rn=/^[\w./-]+$/u,g=(e,t)=>{if(!ct.test(e))throw new te("INTERNAL",`@lunora/codegen: ${t} is not a valid JS identifier: ${JSON.stringify(e)}`)},qe=e=>e.charAt(0).toUpperCase()+e.slice(1),_=e=>ct.test(e)?e:JSON.stringify(e),Sn={any:"unknown",bigint:"bigint",boolean:"boolean",bytes:"ArrayBuffer",date:"number",geoPoint:"{ lat: number; lng: number }",null:"null",number:"number",storage:"string",string:"string",timestamp:"number"},Nn=e=>{if(e===void 0)return"unknown";if(!st.test(e))throw new te("INTERNAL",`@lunora/codegen: v.literal() argument is not a parseable string/number/boolean/null literal: ${JSON.stringify(e)}`);return e},N=e=>{const t=Sn[e.kind];if(t!==void 0)return t;switch(e.kind){case"array":return`Array<${e.inner?N(e.inner):"unknown"}>`;case"from":return e.tsType??"unknown";case"id":{const n=e.tableName??"_unknown_";return g(n,"v.id() table name"),`Id<"${n}">`}case"literal":return Nn(e.literalValue);case"object":return e.shape?`{ ${Object.entries(e.shape).map(([r,o])=>dt(r,o)).join("; ")} }`:"Record<string, unknown>";case"optional":return`${e.inner?N(e.inner):"unknown"} | undefined`;case"record":{const n=e.keyType?N(e.keyType):"string",r=e.valueType?N(e.valueType):"unknown";return`Record<${n}, ${r}>`}case"union":return e.members&&e.members.length>0?e.members.map(n=>N(n)).join(" | "):"never";default:return"unknown"}},dt=(e,t)=>{const n=_(e);if(t.kind==="optional"){const r=t.inner?N(t.inner):"unknown";return`${n}?: ${r}`}return`${n}: ${N(t)}`},ke=e=>{const t=Object.entries(e);return t.length===0?"{}":`{ ${t.map(([n,r])=>dt(n,r)).join("; ")} }`},ut=e=>e.kind==="optional"||!!e.column?.hasDefault,re=e=>e.kind==="optional"&&e.inner?e.inner:e,Tn=e=>{g(e.name,"table name");const t=Object.entries(e.shape).map(([r,o])=>{const s=re(o),i=N(s),a=_(r);return ut(o)?` ${a}?: ${i};`:` ${a}: ${i};`}).join(`
|
|
45
45
|
`),n=t?`
|
|
46
46
|
${t}
|
|
47
47
|
`:"";return`export interface Insert_${e.name} {
|
|
48
48
|
_id?: Id<"${e.name}">;
|
|
49
|
-
_creationTime?: number;${n}}`},Ue="schema",qr=e=>{for(const u of e.tables)g(u.name,"table name");const t=e.tables.map(u=>`"${u.name}"`).join(" | ")||"never",n=e.tables.filter(u=>u.extensionKey===void 0).map(u=>`"${u.name}"`).join(" | ")||"never",r=e.tables.map(u=>{const l=Object.entries(u.shape).map(([
|
|
49
|
+
_creationTime?: number;${n}}`},Ue="schema",qr=e=>{for(const u of e.tables)g(u.name,"table name");const t=e.tables.map(u=>`"${u.name}"`).join(" | ")||"never",n=e.tables.filter(u=>u.extensionKey===void 0).map(u=>`"${u.name}"`).join(" | ")||"never",r=e.tables.map(u=>{const l=Object.entries(u.shape).map(([x,w])=>{const v=_(x);if(w.kind==="optional"){const I=w.inner?N(w.inner):"unknown";return` ${v}?: ${I};`}return` ${v}: ${N(w)};`}).join(`
|
|
50
50
|
`),f=l?`
|
|
51
51
|
${l}
|
|
52
52
|
`:"";return`export interface Doc_${u.name} {
|
|
@@ -61,7 +61,7 @@ ${l}
|
|
|
61
61
|
`),d=e.vectorIndexes.map(u=>JSON.stringify(u.name)).join(" | ")||"never",p=e.tables.map(u=>Tn(u)).join(`
|
|
62
62
|
|
|
63
63
|
`),h=e.tables.map(u=>` ${u.name}: Insert_${u.name};`).join(`
|
|
64
|
-
`),
|
|
64
|
+
`),b=e.tables.map(u=>{const l=u.relations.map(f=>(g(f.table,"relation target table"),` ${_(f.name)}: ${f.kind==="one"?"OneRelation":"ManyRelation"}<"${f.table}">;`)).join(`
|
|
65
65
|
`);return l?` ${u.name}: {
|
|
66
66
|
${l}
|
|
67
67
|
};`:` ${u.name}: {};`}).join(`
|
|
@@ -154,10 +154,10 @@ export interface ManyRelation<Target extends keyof DataModel> {
|
|
|
154
154
|
|
|
155
155
|
/** Per-table relation map keyed by accessor name. \`{}\` for tables with none. */
|
|
156
156
|
export interface Relations {
|
|
157
|
-
${
|
|
157
|
+
${b}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
`,Ue)},An=/import\("(?<spec>(?:\.\.?\/)*_generated\/[^"]+)"\)/gu,pt=/^(?:\.\.?\/)*_generated\//u,mt=/\.[A-Za-z]\w*$/u,On=e=>e.replaceAll(An,(t,n)=>{const r=n.replace(pt,"./");return`import("${mt.test(r)?r:`${r}.js`}")`}),In=/import\("(?<spec>\.\.?\/[^"]+)"\)/gu,Cn=/^(?:\.\.?\/)+/u,Ln=e=>{const t=[];for(const n of e.split("/"))if(!(n===""||n===".")){if(n===".."&&t.length>0&&t.at(-1)!==".."){t.pop();continue}t.push(n)}return t.join("/")},_n=(e,t)=>e.replaceAll(In,(n,r)=>{if(pt.test(r.replace(Cn,"")))return n;const o=t.includes("/")?t.slice(0,t.lastIndexOf("/")):"",i=`../${Ln(`${o}/${r}`)}`;return`import("${mt.test(i)?i:`${i}.js`}")`}),E=(e,t)=>On(_n(e,t)),En=["client","do","errors","flags","observability","platform","ratelimit","runtime","server","values"],Dn=new RegExp(String.raw`import\("@lunora/(?<pkg>${En.join("|")})(?<subpath>/[^"]*)?"\)`,"gu"),Fn={flags:new Set(["/web"]),platform:new Set},ht=(e,t)=>t?e.replaceAll(Dn,(n,r,o)=>{const s=Fn[r];return o&&s&&!s.has(o)?n:`import("lunorash/${r}${o??""}")`}):e,Ke=e=>["Doc","Id"].filter(t=>new RegExp(String.raw`\b${t}<`,"u").test(e)),Pn=e=>e.output===void 0||e.output.kind==="any"?e.returnType:N(e.output),Qe=e=>{const t=new Map;for(const n of e){const r=t.get(n.filePath)??[];r.push(n),t.set(n.filePath,r)}return[...t.entries()].toSorted(([n],[r])=>n.localeCompare(r))},nt=e=>{const t=([n,r])=>{const o=r.toSorted((s,i)=>s.exportName.localeCompare(i.exportName)).map(s=>{const i=E(
|
|
160
|
+
`,Ue)},An=/import\("(?<spec>(?:\.\.?\/)*_generated\/[^"]+)"\)/gu,pt=/^(?:\.\.?\/)*_generated\//u,mt=/\.[A-Za-z]\w*$/u,On=e=>e.replaceAll(An,(t,n)=>{const r=n.replace(pt,"./");return`import("${mt.test(r)?r:`${r}.js`}")`}),In=/import\("(?<spec>\.\.?\/[^"]+)"\)/gu,Cn=/^(?:\.\.?\/)+/u,Ln=e=>{const t=[];for(const n of e.split("/"))if(!(n===""||n===".")){if(n===".."&&t.length>0&&t.at(-1)!==".."){t.pop();continue}t.push(n)}return t.join("/")},_n=(e,t)=>e.replaceAll(In,(n,r)=>{if(pt.test(r.replace(Cn,"")))return n;const o=t.includes("/")?t.slice(0,t.lastIndexOf("/")):"",i=`../${Ln(`${o}/${r}`)}`;return`import("${mt.test(i)?i:`${i}.js`}")`}),E=(e,t)=>On(_n(e,t)),En=["client","do","errors","flags","observability","platform","ratelimit","runtime","server","values"],Dn=new RegExp(String.raw`import\("@lunora/(?<pkg>${En.join("|")})(?<subpath>/[^"]*)?"\)`,"gu"),Fn={flags:new Set(["/web"]),platform:new Set},ht=(e,t)=>t?e.replaceAll(Dn,(n,r,o)=>{const s=Fn[r];return o&&s&&!s.has(o)?n:`import("lunorash/${r}${o??""}")`}):e,Ke=e=>["Doc","Id"].filter(t=>new RegExp(String.raw`\b${t}<`,"u").test(e)),Pn=e=>e.output===void 0||e.output.kind==="any"?e.returnType:N(e.output),Qe=e=>{const t=new Map;for(const n of e){const r=t.get(n.filePath)??[];r.push(n),t.set(n.filePath,r)}return[...t.entries()].toSorted(([n],[r])=>n.localeCompare(r))},nt=e=>{const t=([n,r])=>{const o=r.toSorted((s,i)=>s.exportName.localeCompare(i.exportName)).map(s=>{const i=E(ke(s.args),s.filePath),a=E(Pn(s),s.filePath);return` ${s.exportName}: FunctionReference<"${s.kind}", ${i}, ${a}>;`}).join(`
|
|
161
161
|
`);return` ${_(S(n))}: {
|
|
162
162
|
${o}
|
|
163
163
|
};`};return Qe(e).map(n=>t(n)).join(`
|
|
@@ -203,7 +203,7 @@ ${i}
|
|
|
203
203
|
*/
|
|
204
204
|
const lunoraAgentRuntimeFunctions = agentComponent().functions;
|
|
205
205
|
`}},Wn=(e,t)=>{if(!e)return{importLine:"",lines:"",prelude:""};const n=t.find(r=>S(r.filePath)==="sandbox"&&r.exportName==="invoke");if(n)throw new te("INTERNAL",`@lunora/codegen: "sandbox:invoke" is reserved for the batteries-included sandbox tool dispatcher (browserTool/containerTool) — rename the "invoke" export in ${n.filePath}`);return{importLine:`import { sandboxComponent } from "@lunora/agent/component";
|
|
206
|
-
`,lines:' "sandbox:invoke": lunoraSandbox.invoke as unknown as RegisteredLunoraFunction,',prelude:"\n/**\n * The `@lunora/agent` sandbox dispatcher — auto-registered because `lunora/`\n * imports a sandbox tool (`browserTool`/`containerTool`). The batteries-included\n * tools dispatch to this internal action, which runs on an action ctx carrying\n * `ctx.browser` + `ctx.containers` (the durable tool step itself has neither).\n */\nconst lunoraSandbox = sandboxComponent();\n"}},Un=(e,t)=>{if(e.length===0)return[];const n=gt(t),r=[{args:{key:{kind:"string"},limit:{inner:{kind:"number"},kind:"optional"}},exportName:"agentMessages",filePath:"agents",kind:"query",returnType:"Record<string, unknown>[]"},{args:{decision:{kind:"union",members:[{kind:"literal",literalValue:'"approve"'},{kind:"literal",literalValue:'"reject"'}]},instanceId:{kind:"string"},note:{inner:{kind:"string"},kind:"optional"},threadKey:{kind:"string"},toolCallId:{kind:"string"}},exportName:"agentResolveApproval",filePath:"agents",kind:"mutation",returnType:"{ resolved: boolean }"},{args:{agent:{kind:"string"},input:{kind:"string"},threadKey:{kind:"string"},title:{inner:{kind:"string"},kind:"optional"}},exportName:"agentRun",filePath:"agents",kind:"mutation",returnType:"{ id: string; threadKey: string }"},{args:{key:{kind:"string"}},exportName:"agentState",filePath:"agents",kind:"query",returnType:"Record<string, unknown> | undefined"},{args:{key:{kind:"string"}},exportName:"agentThread",filePath:"agents",kind:"query",returnType:"Record<string, unknown> | undefined"}];for(const o of e)o.voice&&r.push({args:{threadKey:{kind:"string"}},exportName:`${o.exportName}Voice`,filePath:"agents",kind:"stream",returnType:"Record<string, unknown>"});return r.filter(o=>!n.has(o.exportName))},Kn=(e,t)=>{if(e.length===0)return[];const n=new Set(t.filter(r=>S(r.filePath)==="mutators").map(r=>r.exportName));return e.filter(r=>!n.has(r.exportName)).map(r=>({args:r.args,exportName:r.exportName,filePath:r.filePath,kind:"mutation",returnType:r.returnType}))},Qn=e=>{const t=e.filter(i=>i.stream);if(t.length===0)return{block:"",body:""};const n=Qe(t),r=n.map(([i,a])=>{const c=a.map(d=>{const p=E(d.chunkType??"unknown",d.filePath),h=E(
|
|
206
|
+
`,lines:' "sandbox:invoke": lunoraSandbox.invoke as unknown as RegisteredLunoraFunction,',prelude:"\n/**\n * The `@lunora/agent` sandbox dispatcher — auto-registered because `lunora/`\n * imports a sandbox tool (`browserTool`/`containerTool`). The batteries-included\n * tools dispatch to this internal action, which runs on an action ctx carrying\n * `ctx.browser` + `ctx.containers` (the durable tool step itself has neither).\n */\nconst lunoraSandbox = sandboxComponent();\n"}},Un=(e,t)=>{if(e.length===0)return[];const n=gt(t),r=[{args:{key:{kind:"string"},limit:{inner:{kind:"number"},kind:"optional"}},exportName:"agentMessages",filePath:"agents",kind:"query",returnType:"Record<string, unknown>[]"},{args:{decision:{kind:"union",members:[{kind:"literal",literalValue:'"approve"'},{kind:"literal",literalValue:'"reject"'}]},instanceId:{kind:"string"},note:{inner:{kind:"string"},kind:"optional"},threadKey:{kind:"string"},toolCallId:{kind:"string"}},exportName:"agentResolveApproval",filePath:"agents",kind:"mutation",returnType:"{ resolved: boolean }"},{args:{agent:{kind:"string"},input:{kind:"string"},threadKey:{kind:"string"},title:{inner:{kind:"string"},kind:"optional"}},exportName:"agentRun",filePath:"agents",kind:"mutation",returnType:"{ id: string; threadKey: string }"},{args:{key:{kind:"string"}},exportName:"agentState",filePath:"agents",kind:"query",returnType:"Record<string, unknown> | undefined"},{args:{key:{kind:"string"}},exportName:"agentThread",filePath:"agents",kind:"query",returnType:"Record<string, unknown> | undefined"}];for(const o of e)o.voice&&r.push({args:{threadKey:{kind:"string"}},exportName:`${o.exportName}Voice`,filePath:"agents",kind:"stream",returnType:"Record<string, unknown>"});return r.filter(o=>!n.has(o.exportName))},Kn=(e,t)=>{if(e.length===0)return[];const n=new Set(t.filter(r=>S(r.filePath)==="mutators").map(r=>r.exportName));return e.filter(r=>!n.has(r.exportName)).map(r=>({args:r.args,exportName:r.exportName,filePath:r.filePath,kind:"mutation",returnType:r.returnType}))},Qn=e=>{const t=e.filter(i=>i.stream);if(t.length===0)return{block:"",body:""};const n=Qe(t),r=n.map(([i,a])=>{const c=a.map(d=>{const p=E(d.chunkType??"unknown",d.filePath),h=E(ke(d.searchParams),d.filePath),b=E(ke(d.params),d.filePath);return` ${_(d.exportName)}: HttpStreamRef<${p}, ${h}, ${b}>;`}).join(`
|
|
207
207
|
`);return` ${_(S(i))}: {
|
|
208
208
|
${c}
|
|
209
209
|
};`}).join(`
|
|
@@ -220,15 +220,15 @@ ${r}
|
|
|
220
220
|
export const httpStreams: HttpStreamsRef = {
|
|
221
221
|
${o}
|
|
222
222
|
};
|
|
223
|
-
`,body:r}},Wr=e=>{const{agents:t=[],functions:n,httpRoutes:r=[],mutators:o=[],useUmbrella:s=!1,workflows:i=[]}=e,a=ne(s),c=[...n.filter($=>$.visibility!=="internal"),...Un(t,n),...Kn(o,n)],d=n.filter($=>$.visibility==="internal"),p=nt(c),h=nt(d),
|
|
223
|
+
`,body:r}},Wr=e=>{const{agents:t=[],functions:n,httpRoutes:r=[],mutators:o=[],useUmbrella:s=!1,workflows:i=[]}=e,a=ne(s),c=[...n.filter($=>$.visibility!=="internal"),...Un(t,n),...Kn(o,n)],d=n.filter($=>$.visibility==="internal"),p=nt(c),h=nt(d),b=Qn(r),u=`${p}
|
|
224
224
|
${h}
|
|
225
|
-
${
|
|
225
|
+
${b.body}`,l=Ke(u),f=l.length>0?`
|
|
226
226
|
import type { ${l.join(", ")} } from "./dataModel.js";
|
|
227
|
-
`:"",
|
|
227
|
+
`:"",x=p?`
|
|
228
228
|
${p}
|
|
229
229
|
`:"",w=h?`
|
|
230
230
|
${h}
|
|
231
|
-
`:"",v=Mn(i,t),I=`export interface ApiTypes {${
|
|
231
|
+
`:"",v=Mn(i,t),I=`export interface ApiTypes {${x}}
|
|
232
232
|
|
|
233
233
|
export const api = anyApi as unknown as ApiTypes;
|
|
234
234
|
|
|
@@ -236,7 +236,7 @@ export const api = anyApi as unknown as ApiTypes;
|
|
|
236
236
|
export interface InternalApiTypes {${w}}
|
|
237
237
|
|
|
238
238
|
export const internal = anyApi as unknown as InternalApiTypes;
|
|
239
|
-
${v.block}${
|
|
239
|
+
${v.block}${b.block}`,P=[...I.includes("FunctionReference<")?["FunctionReference"]:[],...b.block===""?[]:["HttpStreamRef"]],C=P.length>0?`import type { ${P.join(", ")} } from "${a.client}";
|
|
240
240
|
`:"";return ht(`${R}import { anyApi } from "${a.client}";
|
|
241
241
|
${C}${v.importLine}${f}
|
|
242
242
|
${I}`,s)},Ur=e=>e?`${R}import { createSeedClient as createSeedClientBase } from "@lunora/seed";
|
|
@@ -256,9 +256,9 @@ import type { InsertModel } from "./dataModel.js";
|
|
|
256
256
|
* const { posts } = await seed.posts((x) => x([10, 20]));
|
|
257
257
|
*/
|
|
258
258
|
export const createSeedClient = (options?: SeedClientOptions): SeedClient<InsertModel> => createSeedClientBase<InsertModel>(schema, options);
|
|
259
|
-
`:"",Kr=(e,t,n=!1)=>{if(e.length===0||!t)return"";const r=ne(n),o=c=>c.table===void 0?"Row":`Doc<${JSON.stringify(c.table)}> & Row`,s=e.map(c=>{g(c.exportName,"shape export name");const d=o(c),p=E(
|
|
259
|
+
`:"",Kr=(e,t,n=!1)=>{if(e.length===0||!t)return"";const r=ne(n),o=c=>c.table===void 0?"Row":`Doc<${JSON.stringify(c.table)}> & Row`,s=e.map(c=>{g(c.exportName,"shape export name");const d=o(c),p=E(ke(c.args),c.filePath),h=Object.keys(c.args).length>0,b=h?` args: ${p};`:` args?: ${p};`,u=h?`(args: ${p}) => void`:`(args?: ${p}) => void`,l=`${c.exportName}CollectionOptions`;return`/** Options for the \`${c.exportName}\` shape binding. */
|
|
260
260
|
export interface ${qe(l)} {
|
|
261
|
-
${
|
|
261
|
+
${b}
|
|
262
262
|
/**
|
|
263
263
|
* Share the optimistic-overlay gate with other collections + mutators on this
|
|
264
264
|
* shard. Defaults to the shared per-shard registry, which is almost always what
|
|
@@ -323,17 +323,17 @@ ${s}
|
|
|
323
323
|
`),c=t.map(l=>` ${JSON.stringify(l.id)}: ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredDataMigration,`).join(`
|
|
324
324
|
`),d=n.map(l=>` "${S(l.filePath)}:${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredLunoraFunction,`).join(`
|
|
325
325
|
`),p=r.map(l=>` "${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredShape,`).join(`
|
|
326
|
-
`),h=n.map(l=>`${S(l.filePath)}:${l.exportName}`),
|
|
326
|
+
`),h=n.map(l=>`${S(l.filePath)}:${l.exportName}`),b=[a,d].filter(l=>l.length>0).join(`
|
|
327
327
|
`),u=e.map(l=>{if(l.lifecycle||Object.keys(l.args).length===0)return;const f=$n(l.args);return f===void 0?void 0:`installCompiledValidatorMap(${o.get(l.filePath)??""}.${l.exportName}.args, ${f});`}).filter(l=>l!==void 0).join(`
|
|
328
|
-
`);return{dispatchBody:
|
|
329
|
-
${
|
|
328
|
+
`);return{dispatchBody:b.length>0?`
|
|
329
|
+
${b}
|
|
330
330
|
`:"",importBlock:i.length>0?`${i}
|
|
331
331
|
|
|
332
332
|
`:"",installBlock:u,migrationBody:c.length>0?`
|
|
333
333
|
${c}
|
|
334
334
|
`:"",mutatorPaths:h,shapeBody:p.length>0?`
|
|
335
335
|
${p}
|
|
336
|
-
`:""}},Jn=e=>{const t=Qe(e),n=t.map(([o,s])=>{const i=s.map(a=>{const c=E(
|
|
336
|
+
`:""}},Jn=e=>{const t=Qe(e),n=t.map(([o,s])=>{const i=s.map(a=>{const c=E(ke(a.args),a.filePath),d=c==="{}"?"?":"",p=E(a.returnType,a.filePath);return a.kind==="stream"?` ${a.exportName}: (args${d}: ${c}) => Promise<AsyncIterable<${p}>>;`:` ${a.exportName}: (args${d}: ${c}) => Promise<${p}>;`}).join(`
|
|
337
337
|
`);return` ${_(S(o))}: {
|
|
338
338
|
${i}
|
|
339
339
|
};`}).join(`
|
|
@@ -341,10 +341,10 @@ ${i}
|
|
|
341
341
|
`);return` ${_(i)}: {
|
|
342
342
|
${a}
|
|
343
343
|
},`}).join(`
|
|
344
|
-
`),types:n}},zn=(e,t=[])=>{const n=new Set;for(const r of e.tables)for(const o of Object.values(r.shape)){const s=re(o);s.kind==="storage"&&typeof s.bucket=="string"&&s.bucket!==""&&n.add(s.bucket)}for(const r of t)r!==""&&r!=="default"&&n.add(r);return["default",...[...n].toSorted((r,o)=>r.localeCompare(o))]},Qr=({agents:e=[],containers:t=[],env:n,hasAccessFacade:r=!1,hasAi:o=!1,hasAnalytics:s=!1,hasBrowser:i=!1,hasFlags:a=!1,hasHyperdrive:c=!1,hasImages:d=!1,hasKv:p=!1,hasNotify:h=!1,hasPayments:
|
|
344
|
+
`),types:n}},zn=(e,t=[])=>{const n=new Set;for(const r of e.tables)for(const o of Object.values(r.shape)){const s=re(o);s.kind==="storage"&&typeof s.bucket=="string"&&s.bucket!==""&&n.add(s.bucket)}for(const r of t)r!==""&&r!=="default"&&n.add(r);return["default",...[...n].toSorted((r,o)=>r.localeCompare(o))]},Qr=({agents:e=[],containers:t=[],env:n,hasAccessFacade:r=!1,hasAi:o=!1,hasAnalytics:s=!1,hasBrowser:i=!1,hasFlags:a=!1,hasHyperdrive:c=!1,hasImages:d=!1,hasKv:p=!1,hasNotify:h=!1,hasPayments:b=!1,hasPipelines:u=!1,hasR2sql:l=!1,hasX402:f=!1,identity:x,queues:w=[],schema:v,storageRuleBuckets:I=[],useUmbrella:P=!1,workflows:C=[]}={})=>{const $=ne(P),k=zn(v??{tables:[]},I).map(m=>JSON.stringify(m)).join(" | "),M=o?`import type { LunoraAi } from "@lunora/ai";
|
|
345
345
|
`:"",oe=o?`
|
|
346
|
-
readonly ai: LunoraAi;`:"",B=
|
|
347
|
-
`:"",ae=
|
|
346
|
+
readonly ai: LunoraAi;`:"",B=b?`import type { LunoraPayment } from "@lunora/payment";
|
|
347
|
+
`:"",ae=b?`
|
|
348
348
|
readonly payments: LunoraPayment;`:"",se=f?`import type { X402Pay } from "@lunora/x402/pay";
|
|
349
349
|
`:"",W=f?`
|
|
350
350
|
readonly x402: X402Pay;`:"",A=t.length>0?`import type { ContainerAccessor } from "@lunora/container";
|
|
@@ -401,7 +401,7 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
|
|
|
401
401
|
export interface LunoraWorkflows {
|
|
402
402
|
${C.map(m=>` get(name: ${JSON.stringify(m.exportName)}): WorkflowHandle<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${m.exportName}>>;`).join(`
|
|
403
403
|
`)}
|
|
404
|
-
}`:"",
|
|
404
|
+
}`:"",xe=q?' | "workflows"':"",we=q?`
|
|
405
405
|
readonly workflows: LunoraWorkflows;`:"",ue=w.length>0,Oe=ue?`import type { QueueProducer } from "@lunora/queue";
|
|
406
406
|
import type * as lunoraQueueDefinitions from "../queues.js";
|
|
407
407
|
`:"",Ie=ue?`
|
|
@@ -422,16 +422,16 @@ export interface LunoraAgents {
|
|
|
422
422
|
${e.map(m=>(g(m.exportName,`agent export "${m.exportName}"`),` readonly ${m.exportName}: AgentHandle;`)).join(`
|
|
423
423
|
`)}
|
|
424
424
|
}`:"",$e=pe?`
|
|
425
|
-
readonly agents: LunoraAgents;`:"",_e=
|
|
425
|
+
readonly agents: LunoraAgents;`:"",_e=x?`import type { InferIdentity } from "${$.server}";
|
|
426
426
|
import type * as lunoraIdentityContract from "../identity.js";
|
|
427
|
-
`:"",Ee=
|
|
427
|
+
`:"",Ee=x?`
|
|
428
428
|
|
|
429
429
|
/** This app's declared identity claim contract (\`defineIdentity\` in \`lunora/identity.ts\`) — the typed shape of \`ctx.auth.getIdentity()\`, the RLS policy \`ctx.auth.identity\`, and the \`authorizeShard\`/\`authorizeFanOut\` identity argument. */
|
|
430
|
-
export type Identity = InferIdentity<typeof lunoraIdentityContract.${
|
|
430
|
+
export type Identity = InferIdentity<typeof lunoraIdentityContract.${x.exportName}>;
|
|
431
431
|
|
|
432
432
|
/** \`ctx.auth\` narrowed so \`getIdentity()\` resolves the declared {@link Identity} contract instead of the untyped claim bag. */
|
|
433
|
-
type NarrowedAuth = Omit<QueryCtxBase["auth"], "getIdentity"> & { getIdentity: () => Promise<Identity | null> };`:"",me=
|
|
434
|
-
readonly auth: NarrowedAuth;`:"",De=
|
|
433
|
+
type NarrowedAuth = Omit<QueryCtxBase["auth"], "getIdentity"> & { getIdentity: () => Promise<Identity | null> };`:"",me=x?' | "auth"':"",he=x?`
|
|
434
|
+
readonly auth: NarrowedAuth;`:"",De=x?", Identity":"",Fe=n?`import type * as lunoraEnvContract from "../env.js";
|
|
435
435
|
`:"",Pe=n?`
|
|
436
436
|
|
|
437
437
|
/** This app's declared env contract (\`defineEnv\` in \`lunora/env.ts\`) — the validated, coercion-aware shape of \`ctx.env\`. */
|
|
@@ -551,7 +551,7 @@ export interface OrmWriter extends OrmReader {
|
|
|
551
551
|
}
|
|
552
552
|
|
|
553
553
|
/** Storage buckets this schema declares (\`v.storage("name")\`), narrowing \`ctx.storage.bucket(name)\`. */
|
|
554
|
-
export type StorageBucketName = ${
|
|
554
|
+
export type StorageBucketName = ${k};${L}${Ae}${Ie}${Le}${Ee}${Pe}
|
|
555
555
|
|
|
556
556
|
/**
|
|
557
557
|
* Project-typed contexts. The base contexts from \`@lunora/server\` are
|
|
@@ -620,13 +620,13 @@ export interface QueryCtx extends Omit<QueryCtxBase, "db" | "storage"${V}${me}${
|
|
|
620
620
|
readonly storage: ReadOnlyStorage<StorageBucketName>;${de}${U}${ie}${K}${Q}${le}${fe}${he}
|
|
621
621
|
}
|
|
622
622
|
|
|
623
|
-
export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${V}${
|
|
623
|
+
export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${V}${xe}${me}${ge}> {
|
|
624
624
|
readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
|
|
625
625
|
readonly orm: OrmWriter;
|
|
626
626
|
readonly storage: ReadOnlyStorage<StorageBucketName>;${Z}${U}${ie}${K}${Q}${le}${fe}${we}${ve}${$e}${he}
|
|
627
627
|
}
|
|
628
628
|
|
|
629
|
-
export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${V}${
|
|
629
|
+
export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${V}${xe}${me}${ge}> {
|
|
630
630
|
readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
|
|
631
631
|
readonly orm: OrmWriter;
|
|
632
632
|
readonly storage: StorageBase<StorageBucketName>;${Z}${U}${oe}${ae}${W}${X}${ie}${K}${Q}${Se}${Ne}${Te}${le}${ce}${H}${fe}${we}${ve}${$e}${he}
|
|
@@ -704,7 +704,7 @@ export const definePolicy = createPolicyDsl<DataModel, Relations${De}>();
|
|
|
704
704
|
export const v = vBase as unknown as Omit<typeof vBase, "id"> & {
|
|
705
705
|
id: <T extends TableName>(table: T) => ColumnValidator<IdOfTable<T>, IdOfTable<T>>;
|
|
706
706
|
};
|
|
707
|
-
`},Yn=e=>{const t={connect:[],disconnect:[]};for(const n of e)n.lifecycle&&t[n.lifecycle].push(`${S(n.filePath)}:${n.exportName}`);return t},Hr=e=>{const{agents:t=[],functions:n,migrations:r=[],mutators:o=[],shapes:s=[],useUmbrella:i=!1,usesSandbox:a=!1}=e,c=n.length>0,d=ne(i),{dispatchBody:p,importBlock:h,installBlock:
|
|
707
|
+
`},Yn=e=>{const t={connect:[],disconnect:[]};for(const n of e)n.lifecycle&&t[n.lifecycle].push(`${S(n.filePath)}:${n.exportName}`);return t},Hr=e=>{const{agents:t=[],functions:n,migrations:r=[],mutators:o=[],shapes:s=[],useUmbrella:i=!1,usesSandbox:a=!1}=e,c=n.length>0,d=ne(i),{dispatchBody:p,importBlock:h,installBlock:b,migrationBody:u,mutatorPaths:l,shapeBody:f}=Gn(n,r,o,s),x=qn(t,n),w=Wn(a,n),v=[x.lines,w.lines].filter(L=>L.length>0).join(`
|
|
708
708
|
`);let I=p;v.length>0&&(I=p.length>0?`${p.trimEnd()}
|
|
709
709
|
${v}
|
|
710
710
|
`:`
|
|
@@ -718,21 +718,21 @@ ${v}
|
|
|
718
718
|
* \`shape_subscribe\` (reads-as-permissions).
|
|
719
719
|
*/
|
|
720
720
|
export const LUNORA_SHAPES: Record<string, RegisteredShape> = {${f}};
|
|
721
|
-
`:"",
|
|
721
|
+
`:"",k=l.length>0?`
|
|
722
722
|
/**
|
|
723
723
|
* Custom-mutator function paths — the \`LUNORA_FUNCTIONS\` keys the generated
|
|
724
724
|
* ShardDO's \`isCustomMutator\` override routes through the client-watermark push
|
|
725
725
|
* protocol (\`x-lunora-client-id\`/\`x-lunora-client-seq\` ordering).
|
|
726
726
|
*/
|
|
727
727
|
export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${l.map(L=>JSON.stringify(L)).join(", ")}]);
|
|
728
|
-
`:"",M=
|
|
729
|
-
`:"",oe=
|
|
728
|
+
`:"",M=b.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${d.values}";
|
|
729
|
+
`:"",oe=b.length>0?`
|
|
730
730
|
/**
|
|
731
731
|
* AOT-compiled argument validators (Worker-safe, no \`eval\`). Each is installed
|
|
732
732
|
* onto its function's live \`.args\` object and consulted by the interpreted
|
|
733
733
|
* parser as a zero-allocation fast path; anything it can't model is deferred.
|
|
734
734
|
*/
|
|
735
|
-
${
|
|
735
|
+
${b}
|
|
736
736
|
`:"",B=Jn(n),ae=B.types?`
|
|
737
737
|
${B.types}
|
|
738
738
|
`:"",se=B.implementation?`
|
|
@@ -740,7 +740,7 @@ ${B.implementation}
|
|
|
740
740
|
`:"",W=Ke(B.types),A=W.length>0?`import type { ${W.join(", ")} } from "./dataModel.js";
|
|
741
741
|
`:"",X=c?"context":"_context",O=c?`${Vn}
|
|
742
742
|
|
|
743
|
-
`:"";return ht(`${R}${h}${
|
|
743
|
+
`:"";return ht(`${R}${h}${x.importLine}${w.importLine}${M}${C}import { LunoraError } from "${d.server}";
|
|
744
744
|
import type { ActionCtx, MutationCtx, QueryCtx } from "./server.js";
|
|
745
745
|
${A}
|
|
746
746
|
/**
|
|
@@ -767,13 +767,13 @@ export interface RegisteredLunoraFunction {
|
|
|
767
767
|
/** \`"internal"\` functions are rejected on the external RPC path; absence === public. */
|
|
768
768
|
visibility?: "internal" | "public";
|
|
769
769
|
}
|
|
770
|
-
${
|
|
770
|
+
${x.prelude}${w.prelude}
|
|
771
771
|
/**
|
|
772
772
|
* Static dispatch table. The key matches the \`__lunoraRef\` the client
|
|
773
773
|
* emits (\`api[namespace][fn].__lunoraRef === "namespace:fn"\`).
|
|
774
774
|
*/
|
|
775
775
|
export const LUNORA_FUNCTIONS: Record<string, RegisteredLunoraFunction> = {${I}};
|
|
776
|
-
${oe}${$}${
|
|
776
|
+
${oe}${$}${k}
|
|
777
777
|
/**
|
|
778
778
|
* Connection-lifecycle manifest: the function paths the generated ShardDO
|
|
779
779
|
* dispatches when a client's WebSocket connects (\`connect\`) or disconnects
|
|
@@ -1028,7 +1028,7 @@ import { ${o} } from "../containers.js";
|
|
|
1028
1028
|
|
|
1029
1029
|
export { ContainerProxy } from "@lunora/container/do";
|
|
1030
1030
|
|
|
1031
|
-
${r}`},
|
|
1031
|
+
${r}`},br=(e,t)=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const r of e)g(r.exportName,`container export "${r.exportName}"`),g(r.bindingName,`container binding "${r.bindingName}"`);const n=e.map(r=>{const o=r.maxInstances===void 0?"":`, maxInstances: ${String(r.maxInstances)}`;return` { binding: "${r.bindingName}", exportName: "${r.exportName}"${o} },`}).join(`
|
|
1032
1032
|
`);return{build:`
|
|
1033
1033
|
const containers = createContainerContext(env, LUNORA_CONTAINERS, ${t?JSON.stringify(t):"undefined"}, this.getCurrentTraceparent());
|
|
1034
1034
|
`,contextField:`
|
|
@@ -1108,7 +1108,7 @@ import { ${n} } from "../queues.js";
|
|
|
1108
1108
|
export const LUNORA_QUEUE_REGISTRY: QueueRegistry = {
|
|
1109
1109
|
${r}
|
|
1110
1110
|
};
|
|
1111
|
-
`},
|
|
1111
|
+
`},yr=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)g(n.exportName,`workflow export "${n.exportName}"`),g(n.bindingName,`workflow binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}" },`).join(`
|
|
1112
1112
|
`);return{build:`
|
|
1113
1113
|
const workflows = createWorkflowContext(env, LUNORA_WORKFLOWS);
|
|
1114
1114
|
`,contextField:`
|
|
@@ -1117,7 +1117,7 @@ ${r}
|
|
|
1117
1117
|
const LUNORA_WORKFLOWS: ReadonlyArray<WorkflowBindingSpec> = [
|
|
1118
1118
|
${t}
|
|
1119
1119
|
];
|
|
1120
|
-
`}},
|
|
1120
|
+
`}},kr=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)g(n.exportName,`queue export "${n.exportName}"`),g(n.bindingName,`queue binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}", name: ${JSON.stringify(n.name)} },`).join(`
|
|
1121
1121
|
`);return{build:`
|
|
1122
1122
|
const queues = createQueueContext(env, LUNORA_QUEUES);
|
|
1123
1123
|
`,contextField:`
|
|
@@ -1126,7 +1126,7 @@ ${t}
|
|
|
1126
1126
|
const LUNORA_QUEUES: ReadonlyArray<QueueBindingSpec> = [
|
|
1127
1127
|
${t}
|
|
1128
1128
|
];
|
|
1129
|
-
`}},
|
|
1129
|
+
`}},xr=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)g(n.exportName,`agent export "${n.exportName}"`),g(n.bindingName,`agent binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}"${n.publicRun===!0?", publicRun: true":""} },`).join(`
|
|
1130
1130
|
`);return{build:`
|
|
1131
1131
|
const agents = createAgentContext(env, LUNORA_AGENTS);
|
|
1132
1132
|
`,contextField:`
|
|
@@ -1153,10 +1153,10 @@ const ${e}: ${t} = ${JSON.stringify(r,void 0,4)};
|
|
|
1153
1153
|
? lazyX402Pay(config.x402(env), { getSecret: (name: string) => secrets.get(name) })
|
|
1154
1154
|
: x402Stub;
|
|
1155
1155
|
`,configField:`
|
|
1156
|
-
x402?: (env: Record<string, unknown>) => X402PayConfig;`,stub:T("x402Stub: X402Pay",'throw new Error("ctx.x402: no pay rail configured. Pass \\`x402\\` to createShardDO().");',["fetch"],{cast:" as unknown as X402Pay",sync:["fetch"]})}:{build:"",configField:"",imports:[],stub:""},Sr=(e,t,n,r)=>["AdvisorProcedure","AdvisoryFinding","DatabaseWriterLike","DataMigrationLike","ExportRow",...r?["FlagsResult"]:[],"ImportShardResult","KeyRange","MaskPoliciesResult","MigrationRunResult",...n?["QueuesResult"]:[],"RunShardApplyCdcArgs","RunShardExportArgs","RunShardImportArgs","RunShardMigrationArgs","RlsPoliciesResult","RunShardRankBeforeArgs","RunShardRankPageArgs","RunShardWriteArgs","RunShardWriteResult","SchedulerLike","TransactionHeadroomTracker","SchemaLike","ShardDOState","ShardRankPageResult","SqlExec","StorageRulesResult","StudioFeaturesResult","SystemReaderStorageLike","TelemetrySink",...t?["WorkflowsResult"]:[],...e?["WriteHook"]:[]],Yr=({advisories:e=[],advisorProcedures:t=[],agents:n=[],containers:r=[],env:o,flagKeys:s=[],hasAccessFacade:i=!1,hasAi:a=!1,hasAnalytics:c=!1,hasBrowser:d=!1,hasFlags:p=!1,hasHyperdrive:h=!1,hasImages:
|
|
1156
|
+
x402?: (env: Record<string, unknown>) => X402PayConfig;`,stub:T("x402Stub: X402Pay",'throw new Error("ctx.x402: no pay rail configured. Pass \\`x402\\` to createShardDO().");',["fetch"],{cast:" as unknown as X402Pay",sync:["fetch"]})}:{build:"",configField:"",imports:[],stub:""},Sr=(e,t,n,r)=>["AdvisorProcedure","AdvisoryFinding","DatabaseWriterLike","DataMigrationLike","ExportRow",...r?["FlagsResult"]:[],"ImportShardResult","KeyRange","MaskPoliciesResult","MigrationRunResult",...n?["QueuesResult"]:[],"RunShardApplyCdcArgs","RunShardExportArgs","RunShardImportArgs","RunShardMigrationArgs","RlsPoliciesResult","RunShardRankBeforeArgs","RunShardRankPageArgs","RunShardWriteArgs","RunShardWriteResult","SchedulerLike","TransactionHeadroomTracker","SchemaLike","ShardDOState","ShardRankPageResult","SqlExec","StorageRulesResult","StudioFeaturesResult","SystemReaderStorageLike","TelemetrySink",...t?["WorkflowsResult"]:[],...e?["WriteHook"]:[]],Yr=({advisories:e=[],advisorProcedures:t=[],agents:n=[],containers:r=[],env:o,flagKeys:s=[],hasAccessFacade:i=!1,hasAi:a=!1,hasAnalytics:c=!1,hasBrowser:d=!1,hasFlags:p=!1,hasHyperdrive:h=!1,hasImages:b=!1,hasKv:u=!1,hasNotify:l=!1,hasPayments:f=!1,hasPipelines:x=!1,hasR2sql:w=!1,hasX402:v=!1,maskMetadata:I,mutators:P=[],queues:C=[],rlsMetadata:$,schema:k,schemaSnapshot:M,shapes:oe=[],storageRules:B,studioFeatures:ae,useUmbrella:se=!1,workflows:W=[]})=>{const A=ne(se),X=P.length>0,O=oe.length>0,L=M===void 0?"":mn(M),j=M===void 0?"":`
|
|
1157
1157
|
/** Structural schema snapshot + its content hash, recorded in the shard's \`__lunora_schema_history\` ledger on cold start so the studio can show a schema-version timeline and diff any two versions. */
|
|
1158
1158
|
const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(hn(M))}, json: ${JSON.stringify(L)} };
|
|
1159
|
-
`,ie=M===void 0?"":", schemaSnapshot: LUNORA_SCHEMA_SNAPSHOT",{build:le,configField:Se,contextField:Ne,stub:Te}=or(a),ce=cr(i),H=ar(u),F=sr(p,A.flags),V=dr(s,p,A.flags),Z=ir(l),de=lr(o),G=ur(c),U=pr(
|
|
1159
|
+
`,ie=M===void 0?"":", schemaSnapshot: LUNORA_SCHEMA_SNAPSHOT",{build:le,configField:Se,contextField:Ne,stub:Te}=or(a),ce=cr(i),H=ar(u),F=sr(p,A.flags),V=dr(s,p,A.flags),Z=ir(l),de=lr(o),G=ur(c),U=pr(b),K=mr(h),Q=hr(d),q=gr(w),ee=fr(x),{build:Ae,contextField:xe,importLines:we,specs:ue}=kr(C),{build:Oe,contextField:Ie,importLines:ve,specs:pe}=br(r,k.jurisdiction),{build:Ce,contextField:Le,importLines:$e,specs:_e}=yr(W),{build:Ee,contextField:me,importLines:he,specs:De}=xr(n),{build:Fe,configField:Pe,contextField:ge,imports:fe,stub:Ve}=$r(f),{build:m,configField:Me,imports:yt,stub:kt}=Rr(v),xt=e,wt=t,vt=$??{policies:[],roles:[]},$t=I??{columns:[]},Rt=B??{rules:[]},St=ae??{analytics:!1,auth:!1,containers:!1,flags:!1,kv:!1,mail:!1,notifications:!1,payments:!1,queues:!1,scheduler:!1,storage:!1,vectors:!1,workflows:!1},{constant:Nt,override:Tt}=wr(W),{constant:At,override:Ot}=vr(C),J=k.vectorIndexes.length>0,Ge=new Set(k.tables.filter(y=>typeof y.shardMode=="object"&&y.shardMode.kind==="shardBy").map(y=>y.name)),Re=k.vectorIndexes.some(y=>Ge.has(y.table)),be=k.tables.some(y=>y.shardMode==="global"),Be=k.tables.some(y=>y.shardMode==="global"&&y.globalBackend==="hyperdrive"),Je=k.tables.some(y=>y.shardMode==="global"&&y.globalBackend!=="hyperdrive"),z=k.tables.some(y=>y.externalSource!==void 0);if(Je&&Be)throw new te("INTERNAL",'lunora codegen: mixing `.global()` (D1) and `.global({ backend: "hyperdrive" })` tables in one app is not supported yet — use a single global backend.');const je=k.tables.length>0,It=Xn(k),Ct=er(k),Lt=nr(k),_t=Zn(k),ze=tr(k),Ye=Sr(J,W.length>0,C.length>0,p);O&&Ye.push("WhereInput");const Xe=rr(be),Et=O?`
|
|
1160
1160
|
protected override resolveShape(name: string, args: Record<string, unknown>, identity?: { identity?: Record<string, unknown>; userId?: string }): { columns?: readonly string[]; effectiveWhere?: WhereInput; global?: boolean; table: string } | undefined {
|
|
1161
1161
|
const shape = LUNORA_SHAPES[name];
|
|
1162
1162
|
|
|
@@ -1213,13 +1213,13 @@ const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.st
|
|
|
1213
1213
|
protected override isCustomMutator(functionPath: string): boolean {
|
|
1214
1214
|
return LUNORA_MUTATOR_PATHS.has(functionPath);
|
|
1215
1215
|
}
|
|
1216
|
-
`:"",Ft=O?"\n/** Per-table RLS read policies (hoisted from `.use(rls(...))` chains) the shape resolver AND-merges into each `defineShape` predicate so partial replication honours read policies. */\nconst LUNORA_RLS_READ_REGISTRY = buildRlsReadRegistry(Object.values(LUNORA_FUNCTIONS));\n":"",Pt=O?"assertShapeShardable, ":"",
|
|
1216
|
+
`:"",Ft=O?"\n/** Per-table RLS read policies (hoisted from `.use(rls(...))` chains) the shape resolver AND-merges into each `defineShape` predicate so partial replication honours read policies. */\nconst LUNORA_RLS_READ_REGISTRY = buildRlsReadRegistry(Object.values(LUNORA_FUNCTIONS));\n":"",Pt=O?"assertShapeShardable, ":"",ye=[`import type { ${Ye.join(", ")} } from "${A.do}";`,`import { applyCdcChanges, buildReprojectionMigration, ${Pt}createReadFootprint, createShardCtxDb, exportShardRows, importShardRows, ${z?"isSourceDue, pullExternalSourceIncrementalTick, pullExternalSourceTick, ":""}${Re?"ROOT_SHARD_NAME, ":""}runDataMigration, runShardMigrations, ${Xe.importFragment}ShardDO as ShardDOBase } from "${A.do}";`,...z?[`import type { ExternalSourceLike, SourceClientLike, TraceRefLike } from "${A.do}";`]:[],O?`import { asBucketStorage, buildRlsReadRegistry, composeShapeReadWhere, createSecrets, LunoraError } from "${A.server}";`:`import { asBucketStorage, createSecrets, LunoraError } from "${A.server}";`];je&&ye.push(`import { bindOrm, bindTableFacade } from "${A.server}";`),J&&ye.push('import type { SchemaLike as VectorSchemaLike, VectorizeIndexLike, VectorSearchLike } from "@lunora/bindings/vectors";','import { createContextVectors, createVectors, createVectorSyncHook } from "@lunora/bindings/vectors";'),a&&ye.push('import type { AiBindingLike, LunoraAi } from "@lunora/ai";','import { createAi } from "@lunora/ai";'),ye.push(...ce.importLines,...H.importLines,...F.importLines,...Z.importLines,...de.importLines,...G.importLines,...U.importLines,...K.importLines,...Q.importLines,...q.importLines,...ee.importLines,...ve,...$e,...we,...he,...fe,...yt,"",'import schema from "../schema.js";',`import { ${["LUNORA_FUNCTIONS","LUNORA_LIFECYCLE_HOOKS","LUNORA_MIGRATIONS",...X?["LUNORA_MUTATOR_PATHS"]:[],...O?["LUNORA_SHAPES"]:[]].join(", ")} } from "./functions.js";`);const Mt=J?`
|
|
1217
1217
|
vectors?: (env: Record<string, unknown>) => Record<string, VectorizeIndexLike>;`:"",Bt=Je?`
|
|
1218
|
-
d1?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",jt=Be?`
|
|
1218
|
+
d1?: (env: Record<string, unknown>, request?: { bookmark?: string; identity?: Record<string, unknown>; onBookmark?: (bookmark: string | undefined) => void; userId?: string }) => DatabaseWriterLike | undefined;`:"",jt=Be?`
|
|
1219
1219
|
hyperdriveGlobal?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",qt=z?`
|
|
1220
|
-
sourceClient?: (env: Record<string, unknown>, binding: string) => { query: <Row = Record<string, unknown>>(text: string, params?: readonly unknown[]) => Promise<Row[]> } | undefined;`:"",Wt='throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");',Ut='throw new Error("ctx.vectors: no vectors configured. Pass `vectors` to createShardDO().");',Kt='throw new Error("ctx.scheduler: no scheduler configured. Pass `scheduler` to createShardDO().");',Qt='throw new Error("ctx.storage: no storage configured. Pass `storage` to createShardDO().");',Ht=
|
|
1220
|
+
sourceClient?: (env: Record<string, unknown>, binding: string) => { query: <Row = Record<string, unknown>>(text: string, params?: readonly unknown[]) => Promise<Row[]> } | undefined;`:"",Wt='throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");',Ut='throw new Error("ctx.vectors: no vectors configured. Pass `vectors` to createShardDO().");',Kt='throw new Error("ctx.scheduler: no scheduler configured. Pass `scheduler` to createShardDO().");',Qt='throw new Error("ctx.storage: no storage configured. Pass `storage` to createShardDO().");',Ht=be?T("globalDbStub: DatabaseWriterLike",Wt,["aggregate","count","delete","findFirst","findFirstOrThrow","findMany","get","groupBy","insert","normalizeId","patch","query","rank","rankPage","replace"],{sync:["normalizeId","query"]}):"",Vt=J?T("vectorsStub: VectorSearchLike",Ut,["deleteByIds","getByIds","query","upsert","upsertNow"]):"",Gt=Re?`
|
|
1221
1221
|
const vectorShardKey = this.currentShardKey();
|
|
1222
|
-
`:"",Jt=Re?"namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, ":"",zt=Re?`, { namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, shardedIndexNames: [${
|
|
1222
|
+
`:"",Jt=Re?"namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, ":"",zt=Re?`, { namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, shardedIndexNames: [${k.vectorIndexes.filter(y=>Ge.has(y.table)).map(y=>JSON.stringify(y.name)).join(", ")}] }`:"",Yt=J?`
|
|
1223
1223
|
let vectors: VectorSearchLike;
|
|
1224
1224
|
let onWrite: WriteHook | undefined;
|
|
1225
1225
|
|
|
@@ -1247,7 +1247,7 @@ ${Gt}
|
|
|
1247
1247
|
scheduler,
|
|
1248
1248
|
schema: schema as unknown as SchemaLike,
|
|
1249
1249
|
sql: this.sql as SqlExec,
|
|
1250
|
-
storage,${
|
|
1250
|
+
storage,${be?`
|
|
1251
1251
|
globalDb,`:""}
|
|
1252
1252
|
}`,Y=` const env = (this.env ?? {}) as Record<string, unknown>;
|
|
1253
1253
|
const scheduler = (config.scheduler?.(env) ?? schedulerStub) as SchedulerLike;
|
|
@@ -1261,11 +1261,16 @@ ${Gt}
|
|
|
1261
1261
|
sql: this.sql as SqlExec,
|
|
1262
1262
|
});`,Zt=J?`
|
|
1263
1263
|
vectors,`:"",en=je?`
|
|
1264
|
-
orm: bindOrm(facade),`:"",Ze=Be?"config.hyperdriveGlobal":"config.d1",tn=
|
|
1265
|
-
|
|
1264
|
+
orm: bindOrm(facade),`:"",Ze=Be?"config.hyperdriveGlobal":"config.d1",tn=be?` const globalRequest = { bookmark: this.getInboundBookmark(), identity, onBookmark: (bookmarkValue: string | undefined) => { this.setOutboundBookmark(bookmarkValue); }, userId };
|
|
1265
|
+
const globalDb: DatabaseWriterLike = ${Ze}?.(env, globalRequest) ?? globalDbStub;
|
|
1266
|
+
`:"",nn=O&&be?`
|
|
1266
1267
|
protected override async readGlobalShapeRows(resolved: { columns?: readonly string[]; effectiveWhere?: WhereInput; global?: boolean; table: string }, identity?: { identity?: Record<string, unknown>; userId?: string }): Promise<Array<{ doc: Record<string, unknown>; id: string }>> {
|
|
1267
1268
|
const env = this.env as Record<string, unknown>;
|
|
1268
|
-
|
|
1269
|
+
// A shape read performs no writes, so the widened request only needs
|
|
1270
|
+
// the inbound bookmark (pin the membership drain to the caller's own
|
|
1271
|
+
// prior writes) — no \`onBookmark\` here.
|
|
1272
|
+
const globalRequest = { ...identity, bookmark: this.getInboundBookmark() };
|
|
1273
|
+
const globalDb: DatabaseWriterLike = ${Ze}?.(env, globalRequest) ?? globalDbStub;
|
|
1269
1274
|
const rows: Array<{ doc: Record<string, unknown>; id: string }> = [];
|
|
1270
1275
|
|
|
1271
1276
|
let cursor: null | string = null;
|
|
@@ -1450,20 +1455,20 @@ ${z?`
|
|
|
1450
1455
|
`:""} }
|
|
1451
1456
|
`:"",sn=je?`
|
|
1452
1457
|
const facade = db as unknown as Record<string, ReturnType<typeof bindTableFacade>>;
|
|
1453
|
-
${
|
|
1458
|
+
${k.tables.map(y=>` facade[${JSON.stringify(y.name)}] = bindTableFacade(db, ${JSON.stringify(y.name)});`).join(`
|
|
1454
1459
|
`)}
|
|
1455
1460
|
`:"",ln=`${ce.build}${H.build}${F.build}${G.build}${de.build}
|
|
1456
1461
|
const secrets = createSecrets(env);
|
|
1457
1462
|
`,cn=`${ce.contextField}${H.contextField}${F.contextField}${Z.contextField}${G.contextField}${de.contextField}
|
|
1458
|
-
secrets,`,dn=Z.build,tt=
|
|
1463
|
+
secrets,`,dn=Z.build,tt=b||h||d||w||x||v,un=tt?`
|
|
1459
1464
|
// ActionCtx-only helpers (external, non-deterministic I/O): constructed
|
|
1460
1465
|
// and attached only for an \`action\` so query/mutation ctx never carry them.
|
|
1461
1466
|
if (isAction) {
|
|
1462
|
-
${U.build}${K.build}${Q.build}${q.build}${ee.build}${m}${[...
|
|
1467
|
+
${U.build}${K.build}${Q.build}${q.build}${ee.build}${m}${[...b?[" ctx.images = images;"]:[],...h?[" ctx.sql = sql;"]:[],...d?[" ctx.browser = browser;"]:[],...w?[" ctx.r2sql = r2sql;"]:[],...x?[" ctx.pipelines = pipelines;"]:[],...v?[" ctx.x402 = x402;"]:[]].join(`
|
|
1463
1468
|
`)}
|
|
1464
1469
|
}
|
|
1465
1470
|
`:"",pn=tt?` const isAction = LUNORA_FUNCTIONS[options.functionPath ?? ""]?.kind === "action";
|
|
1466
|
-
`:"";return`${R}${
|
|
1471
|
+
`:"";return`${R}${ye.join(`
|
|
1467
1472
|
`)}
|
|
1468
1473
|
|
|
1469
1474
|
type FunctionKind = "action" | "mutation" | "query";
|
|
@@ -1488,7 +1493,7 @@ const LUNORA_STORAGE_COLUMNS: Record<string, string[]> = ${JSON.stringify(_t,voi
|
|
|
1488
1493
|
const LUNORA_TTL_SWEEPS: Array<{ after?: number; field: string; softDeleteField?: string; table: string }> = ${JSON.stringify(ze,void 0,4)};
|
|
1489
1494
|
|
|
1490
1495
|
/** Static schema advisories (computed by @lunora/advisor at codegen time) served via \`__lunora_admin__:getAdvisories\`. */
|
|
1491
|
-
const LUNORA_ADVISORIES: AdvisoryFinding[] = ${JSON.stringify(
|
|
1496
|
+
const LUNORA_ADVISORIES: AdvisoryFinding[] = ${JSON.stringify(xt,void 0,4)};
|
|
1492
1497
|
|
|
1493
1498
|
/** Every declared procedure (discovered by @lunora/codegen) served via \`__lunora_admin__:getAdvisorProcedures\` — the health map's denominator. */
|
|
1494
1499
|
const LUNORA_ADVISOR_PROCEDURES: AdvisorProcedure[] = ${JSON.stringify(wt,void 0,4)};
|
|
@@ -1513,7 +1518,7 @@ export interface ShardDOConfig {
|
|
|
1513
1518
|
scheduler?: (env: Record<string, unknown>) => unknown;
|
|
1514
1519
|
storage?: (env: Record<string, unknown>) => unknown;${Mt}${Se}${H.configField}${F.configField}${G.configField}${U.configField}${K.configField}${Q.configField}${q.configField}${ee.configField}${Pe}${Me}${Bt}${jt}${qt}
|
|
1515
1520
|
}
|
|
1516
|
-
${T("schedulerStub",Kt,["cancel","runAfter","runAt"])}${T("storageStub",Qt,["delete","download","getMetadata","getSignedUrl","getUrl","list","upload"],{sync:["getUrl"]})}${Ht}${rn}${Vt}${Te}${H.stub}${F.stub}${G.stub}${U.stub}${K.stub}${Q.stub}${q.stub}${ee.stub}${Ve}${
|
|
1521
|
+
${T("schedulerStub",Kt,["cancel","runAfter","runAt"])}${T("storageStub",Qt,["delete","download","getMetadata","getSignedUrl","getUrl","list","upload"],{sync:["getUrl"]})}${Ht}${rn}${Vt}${Te}${H.stub}${F.stub}${G.stub}${U.stub}${K.stub}${Q.stub}${q.stub}${ee.stub}${Ve}${kt}
|
|
1517
1522
|
// Bound in-process \`ctx.run*\` composition depth so a self- or cyclically-
|
|
1518
1523
|
// referencing call fails loudly with a clear error instead of overflowing the
|
|
1519
1524
|
// stack. Tracked across the awaited handler chain (one DO invocation is
|
|
@@ -1599,6 +1604,15 @@ export const createShardDO = (config: ShardDOConfig = {}): new (state: ShardDOSt
|
|
|
1599
1604
|
|
|
1600
1605
|
return registered.handler(ctx, args);
|
|
1601
1606
|
}
|
|
1607
|
+
|
|
1608
|
+
// Only a \`mutation\` may enter the base class's single-writer gate for
|
|
1609
|
+
// mutation-replay dedup — it is \`blockConcurrencyWhile\`, so gating an
|
|
1610
|
+
// action would stall every other dispatch on the shard for the length of
|
|
1611
|
+
// its outbound I/O, on nothing but a caller-supplied header. Unregistered
|
|
1612
|
+
// paths answer \`false\`; \`handleRpc\` above rejects them anyway.
|
|
1613
|
+
protected override isMutationFunction(functionPath: string): boolean {
|
|
1614
|
+
return LUNORA_FUNCTIONS[functionPath]?.kind === "mutation";
|
|
1615
|
+
}
|
|
1602
1616
|
${Xe.override}
|
|
1603
1617
|
protected override async executeSubscription(functionPath: string, args: Record<string, unknown>, identity?: { identity?: Record<string, unknown>; userId?: string }): Promise<{ ranges?: Map<string, KeyRange[]>; result: unknown; tables: Set<string> } | null> {
|
|
1604
1618
|
const registered = LUNORA_FUNCTIONS[functionPath];
|
|
@@ -1976,7 +1990,7 @@ ${dn}
|
|
|
1976
1990
|
scheduler,
|
|
1977
1991
|
span,
|
|
1978
1992
|
storage,
|
|
1979
|
-
trace,${Zt}${Ne}${cn}${ge}${Ie}${Le}${
|
|
1993
|
+
trace,${Zt}${Ne}${cn}${ge}${Ie}${Le}${xe}${me}
|
|
1980
1994
|
};
|
|
1981
1995
|
${pn}${un}
|
|
1982
1996
|
ctx.runAction = (reference: FunctionReference, fnArgs: Record<string, unknown>) => dispatchRun("action", reference.__lunoraRef, fnArgs, ctx);
|
|
@@ -1986,14 +2000,14 @@ ${pn}${un}
|
|
|
1986
2000
|
return ctx;
|
|
1987
2001
|
}
|
|
1988
2002
|
};
|
|
1989
|
-
`},He=e=>{switch(e.kind){case"array":case"object":case"record":case"union":return{builder:"text",mode:"json",notNull:!0,typeAnnotation:N(e)};case"bigint":return{builder:"blob",mode:"bigint",notNull:!0};case"boolean":return{builder:"integer",mode:"boolean",notNull:!0};case"bytes":return{builder:"blob",mode:"buffer",notNull:!0};case"date":case"timestamp":return{builder:"integer",notNull:!0};case"from":return{builder:"text",notNull:!0,typeAnnotation:N(e)};case"id":return{builder:"text",notNull:!0};case"literal":{const t=e.literalValue??"";return t.startsWith('"')||t.startsWith("'")?{builder:"text",notNull:!0}:t==="true"||t==="false"?{builder:"integer",mode:"boolean",notNull:!0}:t==="null"?{builder:"text",notNull:!0}:{builder:"real",notNull:!0}}case"null":return{builder:"text",notNull:!0};case"number":return{builder:"real",notNull:!0};case"optional":return{...e.inner?He(e.inner):{builder:"text",notNull:!1},notNull:!1};case"storage":case"string":return{builder:"text",notNull:!0};default:return{builder:"text",notNull:!0}}},
|
|
2003
|
+
`},He=e=>{switch(e.kind){case"array":case"object":case"record":case"union":return{builder:"text",mode:"json",notNull:!0,typeAnnotation:N(e)};case"bigint":return{builder:"blob",mode:"bigint",notNull:!0};case"boolean":return{builder:"integer",mode:"boolean",notNull:!0};case"bytes":return{builder:"blob",mode:"buffer",notNull:!0};case"date":case"timestamp":return{builder:"integer",notNull:!0};case"from":return{builder:"text",notNull:!0,typeAnnotation:N(e)};case"id":return{builder:"text",notNull:!0};case"literal":{const t=e.literalValue??"";return t.startsWith('"')||t.startsWith("'")?{builder:"text",notNull:!0}:t==="true"||t==="false"?{builder:"integer",mode:"boolean",notNull:!0}:t==="null"?{builder:"text",notNull:!0}:{builder:"real",notNull:!0}}case"null":return{builder:"text",notNull:!0};case"number":return{builder:"real",notNull:!0};case"optional":return{...e.inner?He(e.inner):{builder:"text",notNull:!1},notNull:!1};case"storage":case"string":return{builder:"text",notNull:!0};default:return{builder:"text",notNull:!0}}},bt=(e,t)=>{const n=re(e);return n.kind==="id"&&n.tableName!==void 0&&t.has(n.tableName)?n.tableName:void 0},Nr=(e,t,n)=>{g(e,"drizzle column name");const r=He(t),o=r.mode?`, { mode: "${r.mode}" }`:"";let s=`${r.builder}("${e}"${o})`;r.typeAnnotation&&(s+=`.$type<${r.typeAnnotation}>()`);const i=bt(t,n);return i!==void 0&&(s+=`.references((): AnySQLiteColumn => ${i}._id)`),r.notNull&&(s+=".notNull()"),s},Tr=e=>{g(e.name,"drizzle index name");const t=e.unique?"uniqueIndex":"index",n=e.fields.map(r=>(g(r,"drizzle index field"),`t.${r}`)).join(", ");return` ${e.name}: ${t}("${e.name}").on(${n}),`},Ar=(e,t)=>{g(e.name,"table name");const n=[' _id: text("_id").primaryKey(),',' _creationTime: integer("_creationTime").notNull(),',...Object.entries(e.shape).map(([o,s])=>` ${o}: ${Nr(o,s,t)},`)].join(`
|
|
1990
2004
|
`),r=e.indexes.length>0?`, (t) => ({
|
|
1991
2005
|
${e.indexes.map(o=>Tr(o)).join(`
|
|
1992
2006
|
`)}
|
|
1993
2007
|
})`:"";return`export const ${e.name} = sqliteTable("${e.name}", {
|
|
1994
2008
|
${n}
|
|
1995
|
-
}${r});`},Or=e=>e.typeAnnotation?.includes('Id<"')??!1,Ir=(e,t)=>{const n=new Set(["integer","sqliteTable","text"]),r=new Set;let o=!1,s=!1;for(const i of e){for(const a of Object.values(i.shape)){const c=He(a);n.add(c.builder),s=s||Or(c),o=o||
|
|
1996
|
-
`;const n=ne(t),r=new Set(e.map(h=>h.name)),{columns:o,indexes:s,needsAnyColumn:i,needsId:a}=Ir(e,r),c=[...s,...o].toSorted((h,
|
|
2009
|
+
}${r});`},Or=e=>e.typeAnnotation?.includes('Id<"')??!1,Ir=(e,t)=>{const n=new Set(["integer","sqliteTable","text"]),r=new Set;let o=!1,s=!1;for(const i of e){for(const a of Object.values(i.shape)){const c=He(a);n.add(c.builder),s=s||Or(c),o=o||bt(a,t)!==void 0}for(const a of i.indexes)r.add(a.unique?"uniqueIndex":"index")}return{columns:[...n].toSorted((i,a)=>i.localeCompare(a)),indexes:[...r].toSorted((i,a)=>i.localeCompare(a)),needsAnyColumn:o,needsId:s}},rt=(e,t=!1)=>{if(e.length===0)return`${R}export {};
|
|
2010
|
+
`;const n=ne(t),r=new Set(e.map(h=>h.name)),{columns:o,indexes:s,needsAnyColumn:i,needsId:a}=Ir(e,r),c=[...s,...o].toSorted((h,b)=>h.localeCompare(b)),d=e.map(h=>Ar(h,r)).join(`
|
|
1997
2011
|
|
|
1998
2012
|
`),p=[i?`import type { AnySQLiteColumn } from "${n.serverDrizzle}";
|
|
1999
2013
|
`:"",a?`import type { Id } from "./dataModel.js";
|