@lunora/codegen 1.0.0-alpha.77 → 1.0.0-alpha.79
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.d.mts +308 -21
- package/dist/index.d.ts +308 -21
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/DEFAULT_TARGET-BYPEwgZu.mjs +1 -0
- package/dist/packem_shared/GENERATED_HEADER-bdSyaxCS.mjs +1 -0
- package/dist/packem_shared/{OPENRPC_VERSION-67sJ7JrS.mjs → OPENRPC_VERSION-BPT6vyLU.mjs} +1 -1
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-FjKlVIV5.mjs +5 -0
- package/dist/packem_shared/{buildOpenApiDocument-DeMEuKaw.mjs → buildOpenApiDocument-D6xm3JqM.mjs} +1 -1
- package/dist/packem_shared/discover-queries-LfER8HbK.mjs +1 -0
- package/dist/packem_shared/discoverQueries-B_2Ciq7P.mjs +1 -0
- package/dist/packem_shared/{emit-sQzv_a8t.mjs → emit-BtiV37rG.mjs} +190 -183
- package/dist/packem_shared/{emitApp-D5X1S54W.mjs → emitApp-Bc3G4eki.mjs} +1 -1
- package/dist/packem_shared/formatAdvisories-BCEfzLT0.mjs +2 -0
- package/package.json +7 -5
- package/dist/packem_shared/GENERATED_HEADER-CQRdzwf9.mjs +0 -1
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-x_pw6Agi.mjs +0 -3
- package/dist/packem_shared/discoverQueries-DENx_T6c.mjs +0 -1
- package/dist/packem_shared/formatAdvisories-DZvv-0MG.mjs +0 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{agentComponent as Ye}from"@lunora/agent/component";import{LunoraError as
|
|
1
|
+
import{agentComponent as Ye}from"@lunora/agent/component";import{LunoraError as Z}from"@lunora/errors";import{serializeSchemaSnapshot as Ht,hashSchemaSnapshot as zt}from"./SCHEMA_SNAPSHOT_VERSION-CFhF_hmg.mjs";import{n as v}from"./paths-BmX5O1sG.mjs";const Ze=[{contextProperty:"access",key:"access",moduleSpecifier:"@lunora/cloudflare-access"},{appMethod:{configKey:"ai",doc:"Override the Workers AI binding backing `ctx.ai` (defaults to `env.AI`).",method:"ai"},contextProperty:"ai",key:"ai",moduleSpecifier:"@lunora/ai"},{appMethod:{configKey:"analytics",doc:"Override the Analytics Engine dataset backing `ctx.analytics` (defaults to `env.ANALYTICS`).",method:"analytics"},contextProperty:"analytics",key:"analytics",moduleSpecifier:"@lunora/bindings/analytics",serverCtxField:{field:`
|
|
2
2
|
/** Analytics Engine telemetry sink. Fire-and-forget and sampled; do not read it back in-handler. */
|
|
3
3
|
readonly analytics: import("@lunora/bindings/analytics").AnalyticsClient;`,tier:"every"}},{appMethod:{configKey:"browser",doc:"Override the Browser Rendering binding backing `ctx.browser` (defaults to `env.BROWSER`).",method:"browser"},contextProperty:"browser",key:"browser",moduleSpecifier:"@lunora/browser",serverCtxField:{field:`
|
|
4
4
|
/** Browser Rendering (screenshots/PDF/scrape). Non-deterministic — available only in actions. */
|
|
@@ -15,38 +15,38 @@ import{agentComponent as Ye}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"}],
|
|
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"}],Xt=Ze,Yt=new Map(Xt.flatMap(e=>e.serverCtxField?[[e.key,e.serverCtxField]]:[])),pr=Ze.flatMap(e=>"appMethod"in e?[{appMethod:e.appMethod,key:e.key}]:[]),et=/^(?:"(?:[^"\\]|\\(?:["\\/bfnrt]|u[0-9A-Fa-f]{4}))*"|'[^'\\]*'|-?\d+(?:\.\d+)?|true|false|null)$/u,Zt=new Set(["any","bigint","boolean","date","id","null","number","storage","string","timestamp"]),tt=e=>e.column!==void 0,en=(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
|
-
`}},Fe=(e,t,n)=>{if(!tt(e)&&!(e.hasRefinement||e.sourceText!==void 0)){if(
|
|
23
|
+
`}},tn=(e,t)=>{const n=e.literalValue?.trim();if(!(n===void 0||!et.test(n)))return{out:t,pre:`if (${t} !== ${n}) return DEFER;
|
|
24
|
+
`}},Fe=(e,t,n)=>{if(!tt(e)&&!(e.hasRefinement||e.sourceText!==void 0)){if(Zt.has(e.kind))return e.kind==="any"?{out:t,pre:""}:{out:t,pre:en(e.kind,t)};switch(e.kind){case"array":return nn(e,t,n);case"literal":return tn(e,t);case"object":return an(e,t,n);default:return}}},nn=(e,t,n)=>{const{inner:r}=e;if(!r)return;const a=n.next(),o=`__arr${String(a)}`,s=`__i${String(a)}`,i=`__e${String(a)}`,l=Fe(r,i,n);if(!l)return;const u=`if (!Array.isArray(${t})) return DEFER;
|
|
25
25
|
const ${o} = new Array(${t}.length);
|
|
26
26
|
for (let ${s} = 0; ${s} < ${t}.length; ${s}++) {
|
|
27
27
|
const ${i} = ${t}[${s}];
|
|
28
28
|
${l.pre}${o}[${s}] = ${l.out};
|
|
29
29
|
}
|
|
30
|
-
`;return{out:o,pre:u}},
|
|
30
|
+
`;return{out:o,pre:u}},rn=(e,t,n,r)=>{const a=JSON.stringify(e);if(t.kind==="optional"){if(t.hasRefinement||t.sourceText!==void 0||tt(t))return;const{inner:s}=t;if(!s)return;const i=Fe(s,n,r);if(!i)return;const l=r.next(),u=`__has${String(l)}`,p=`__val${String(l)}`,b=`let ${u} = false;
|
|
31
31
|
let ${p};
|
|
32
32
|
if (${n} !== undefined) {
|
|
33
33
|
${i.pre}${p} = ${i.out};
|
|
34
34
|
${u} = true;
|
|
35
35
|
}
|
|
36
|
-
`;return{entry:`...(${u} ? { ${a}: ${p} } : {})`,pre:b}}const o=Fe(t,n,r);if(o)return{entry:`${a}: ${o.out}`,pre:o.pre}},nt=(e,t,n)=>{let r="";const a=[];for(const o of Object.keys(e)){const s=e[o];if(!s)return;const i=
|
|
36
|
+
`;return{entry:`...(${u} ? { ${a}: ${p} } : {})`,pre:b}}const o=Fe(t,n,r);if(o)return{entry:`${a}: ${o.out}`,pre:o.pre}},nt=(e,t,n)=>{let r="";const a=[];for(const o of Object.keys(e)){const s=e[o];if(!s)return;const i=rn(o,s,t(o),n);if(!i)return;r+=i.pre,a.push(i.entry)}return{entries:a.join(", "),pre:r}},an=(e,t,n)=>{const r=e.shape??{},a=nt(r,l=>`${t}[${JSON.stringify(l)}]`,n);if(!a)return;const o=n.next(),s=`__obj${String(o)}`,i=`if (typeof ${t} !== "object" || ${t} === null || Array.isArray(${t})) return DEFER;
|
|
37
37
|
${a.pre}const ${s} = { ${a.entries} };
|
|
38
|
-
`;return{out:s,pre:i}},
|
|
38
|
+
`;return{out:s,pre:i}},on=e=>{let t=0;const n=nt(e,r=>`source[${JSON.stringify(r)}]`,{next:()=>(t+=1,t)});if(n)return`(source) => {
|
|
39
39
|
if (typeof source !== "object" || source === null || Array.isArray(source)) return DEFER;
|
|
40
40
|
${n.pre}return { ${n.entries} };
|
|
41
41
|
}`},k=`// GENERATED by @lunora/codegen — do not edit.
|
|
42
42
|
// Run \`lunora codegen\` to regenerate.
|
|
43
43
|
|
|
44
|
-
`,H=(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"},rt=/^[A-Za-z_$][\w$]*$/u,
|
|
44
|
+
`,H=(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"},rt=/^[A-Za-z_$][\w$]*$/u,sn=/^[\w./-]+$/u,m=(e,t)=>{if(!rt.test(e))throw new Z("INTERNAL",`@lunora/codegen: ${t} is not a valid JS identifier: ${JSON.stringify(e)}`)},Ee=e=>e.charAt(0).toUpperCase()+e.slice(1),L=e=>rt.test(e)?e:JSON.stringify(e),ln={any:"unknown",bigint:"bigint",boolean:"boolean",bytes:"ArrayBuffer",date:"number",from:"unknown",geoPoint:"{ lat: number; lng: number }",null:"null",number:"number",storage:"string",string:"string",timestamp:"number"},dn=e=>{if(e===void 0)return"unknown";if(!et.test(e))throw new Z("INTERNAL",`@lunora/codegen: v.literal() argument is not a parseable string/number/boolean/null literal: ${JSON.stringify(e)}`);return e},T=e=>{const t=ln[e.kind];if(t!==void 0)return t;switch(e.kind){case"array":return`Array<${e.inner?T(e.inner):"unknown"}>`;case"id":{const n=e.tableName??"_unknown_";return m(n,"v.id() table name"),`Id<"${n}">`}case"literal":return dn(e.literalValue);case"object":return e.shape?`{ ${Object.entries(e.shape).map(([n,r])=>`${L(n)}: ${T(r)}`).join("; ")} }`:"Record<string, unknown>";case"optional":return`${e.inner?T(e.inner):"unknown"} | undefined`;case"record":{const n=e.keyType?T(e.keyType):"string",r=e.valueType?T(e.valueType):"unknown";return`Record<${n}, ${r}>`}case"union":return e.members&&e.members.length>0?e.members.map(n=>T(n)).join(" | "):"never";default:return"unknown"}},me=e=>{const t=Object.entries(e);return t.length===0?"{}":`{ ${t.map(([n,r])=>{const a=L(n);if(r.kind==="optional"){const o=r.inner?T(r.inner):"unknown";return`${a}?: ${o}`}return`${a}: ${T(r)}`}).join("; ")} }`},cn=e=>e.kind==="optional"||!!e.column?.hasDefault,un=e=>{m(e.name,"table name");const t=Object.entries(e.shape).map(([r,a])=>{const o=a.kind==="optional"&&a.inner?a.inner:a,s=T(o),i=L(r);return cn(a)?` ${i}?: ${s};`:` ${i}: ${s};`}).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}}`},
|
|
49
|
+
_creationTime?: number;${n}}`},hr=(e,t=!1)=>{const n=H(t);for(const c of e.tables)m(c.name,"table name");const r=e.tables.map(c=>`"${c.name}"`).join(" | ")||"never",a=e.tables.filter(c=>c.extensionKey===void 0).map(c=>`"${c.name}"`).join(" | ")||"never",o=e.tables.map(c=>{const g=Object.entries(c.shape).map(([x,S])=>{const R=L(x);if(S.kind==="optional"){const C=S.inner?T(S.inner):"unknown";return` ${R}?: ${C};`}return` ${R}: ${T(S)};`}).join(`
|
|
50
50
|
`),f=g?`
|
|
51
51
|
${g}
|
|
52
52
|
`:"";return`export interface Doc_${c.name} {
|
|
@@ -58,10 +58,10 @@ ${g}
|
|
|
58
58
|
`),l=e.tables.map(c=>{const g=c.searchIndexes.map(f=>JSON.stringify(f.name)).join(" | ");return` ${c.name}: ${g||"never"};`}).join(`
|
|
59
59
|
`),u=e.tables.map(c=>{const g=c.rankIndexes.map(f=>JSON.stringify(f.name)).join(" | ");return` ${c.name}: ${g||"never"};`}).join(`
|
|
60
60
|
`),p=e.tables.map(c=>{const g=c.shardMode==="global"?"":(c.geoIndexes??[]).map(f=>JSON.stringify(f.name)).join(" | ");return` ${c.name}: ${g||"never"};`}).join(`
|
|
61
|
-
`),b=e.vectorIndexes.map(c=>JSON.stringify(c.name)).join(" | ")||"never",
|
|
61
|
+
`),b=e.vectorIndexes.map(c=>JSON.stringify(c.name)).join(" | ")||"never",y=e.tables.map(c=>un(c)).join(`
|
|
62
62
|
|
|
63
63
|
`),$=e.tables.map(c=>` ${c.name}: Insert_${c.name};`).join(`
|
|
64
|
-
`),d=e.tables.map(c=>{const g=c.relations.map(f=>(m(f.table,"relation target table"),` ${
|
|
64
|
+
`),d=e.tables.map(c=>{const g=c.relations.map(f=>(m(f.table,"relation target table"),` ${L(f.name)}: ${f.kind==="one"?"OneRelation":"ManyRelation"}<"${f.table}">;`)).join(`
|
|
65
65
|
`);return g?` ${c.name}: {
|
|
66
66
|
${g}
|
|
67
67
|
};`:` ${c.name}: {};`}).join(`
|
|
@@ -160,7 +160,7 @@ export type GeoIndexName<T extends keyof DataModel> = GeoIndexNamesByTable[T];
|
|
|
160
160
|
/** Union of declared vector index names. \`never\` when none are declared. */
|
|
161
161
|
export type VectorIndexName = ${b};
|
|
162
162
|
|
|
163
|
-
${
|
|
163
|
+
${y}
|
|
164
164
|
|
|
165
165
|
/** Per-table insert shape, accepted by \`ctx.db.<table>.insert(...)\`. */
|
|
166
166
|
export interface InsertModel {
|
|
@@ -234,11 +234,11 @@ export interface OrmWriter extends OrmReader {
|
|
|
234
234
|
replace: <T extends keyof DataModel>(table: T, id: Id<T>) => OrmReplaceBuilder<T>;
|
|
235
235
|
update: <T extends keyof DataModel>(table: T, id: Id<T>) => OrmUpdateBuilder<T>;
|
|
236
236
|
}
|
|
237
|
-
`},
|
|
238
|
-
`);return` ${
|
|
237
|
+
`},pn=/import\("(?<spec>(?:\.\.?\/)*_generated\/[^"]+)"\)/gu,hn=/^(?:\.\.?\/)*_generated\//u,gn=/\.[A-Za-z]\w*$/u,Me=e=>e.replaceAll(pn,(t,n)=>{const r=n.replace(hn,"./");return`import("${gn.test(r)?r:`${r}.js`}")`}),mn=/import\("@lunora\/(?<pkg>client|do|runtime|server|values)(?<subpath>\/[^"]*)?"\)/gu,at=(e,t)=>t?e.replaceAll(mn,(n,r,a)=>`import("lunorash/${r}${a??""}")`):e,qe=e=>["Doc","Id"].filter(t=>new RegExp(String.raw`\b${t}<`,"u").test(e)),ze=e=>{const t=new Map;for(const r of e){const a=t.get(r.filePath)??[];a.push(r),t.set(r.filePath,a)}const n=([r,a])=>{const o=a.toSorted((s,i)=>s.exportName.localeCompare(i.exportName)).map(s=>{const i=me(s.args),l=Me(s.returnType);return` ${s.exportName}: FunctionReference<"${s.kind}", ${i}, ${l}>;`}).join(`
|
|
238
|
+
`);return` ${L(v(r))}: {
|
|
239
239
|
${o}
|
|
240
240
|
};`};return[...t.entries()].toSorted(([r],[a])=>r.localeCompare(a)).map(r=>n(r)).join(`
|
|
241
|
-
`)},
|
|
241
|
+
`)},fn=(e,t)=>{if(e.length===0&&t.length===0)return{block:"",importLine:""};const n=[];let r="";if(e.length>0&&(r+="\n/** Params type carried by a `defineWorkflow` definition (its phantom `__params`). */\ntype WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params } ? (unknown extends Params ? Record<string, unknown> : Params) : Record<string, unknown>;\n"),r+=`
|
|
242
242
|
/** A typed reference to a durable workflow, addressable for \`cronJobs()\` targets. Mirrors \`@lunora/scheduler\`'s \`WorkflowReference\` structurally. */
|
|
243
243
|
export interface WorkflowReference<Params = Record<string, unknown>> {
|
|
244
244
|
readonly isLunoraWorkflow: true;
|
|
@@ -270,7 +270,7 @@ export const agents: AgentsRef = {
|
|
|
270
270
|
${s}
|
|
271
271
|
};
|
|
272
272
|
`,n.push(`import type { AgentRunInput } from "@lunora/agent";
|
|
273
|
-
`)}return{block:r,importLine:n.join("")}},
|
|
273
|
+
`)}return{block:r,importLine:n.join("")}},bn=()=>Object.keys(Ye().functions).toSorted((e,t)=>e.localeCompare(t)),ot=e=>new Set(e.filter(t=>v(t.filePath)==="agents").map(t=>t.exportName)),yn=()=>new Set(Object.entries(Ye().functions).filter(([,e])=>e.visibility==="internal").map(([e])=>e)),wn=(e,t)=>{const n={importLine:"",lines:"",prelude:""};if(e.length===0)return n;const r=ot(t),a=yn(),o=t.find(i=>v(i.filePath)==="agents"&&a.has(i.exportName));if(o)throw new Z("INTERNAL",`@lunora/codegen: "agents:${o.exportName}" is reserved for the durable agent loop's internal dispatch — rename the "${o.exportName}" export in ${o.filePath}`);const s=bn().filter(i=>!r.has(i));return s.length===0?n:{importLine:`import { agentComponent } from "@lunora/agent/component";
|
|
274
274
|
`,lines:s.map(i=>` "agents:${i}": lunoraAgentRuntimeFunctions.${i} as unknown as RegisteredLunoraFunction,`).join(`
|
|
275
275
|
`),prelude:`
|
|
276
276
|
/**
|
|
@@ -279,13 +279,13 @@ ${s}
|
|
|
279
279
|
* subscribe to the public queries (\`agents:agentMessages\` is the live thread view).
|
|
280
280
|
*/
|
|
281
281
|
const lunoraAgentRuntimeFunctions = agentComponent().functions;
|
|
282
|
-
`}},
|
|
283
|
-
`,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"}},
|
|
284
|
-
`);return` ${
|
|
282
|
+
`}},xn=(e,t)=>{if(!e)return{importLine:"",lines:"",prelude:""};const n=t.find(r=>v(r.filePath)==="sandbox"&&r.exportName==="invoke");if(n)throw new Z("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";
|
|
283
|
+
`,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"}},kn=(e,t)=>{if(e.length===0)return[];const n=ot(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 a of e)a.voice&&r.push({args:{threadKey:{kind:"string"}},exportName:`${a.exportName}Voice`,filePath:"agents",kind:"stream",returnType:"Record<string, unknown>"});return r.filter(a=>!n.has(a.exportName))},vn=(e,t)=>{if(e.length===0)return[];const n=new Set(t.filter(r=>v(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}))},$n=e=>{const t=e.filter(s=>s.stream);if(t.length===0)return{block:"",body:""};const n=new Map;for(const s of t){const i=n.get(s.filePath)??[];i.push(s),n.set(s.filePath,i)}const r=[...n.entries()].toSorted(([s],[i])=>s.localeCompare(i)),a=r.map(([s,i])=>{const l=i.map(u=>{const p=Me(u.chunkType??"unknown");return` ${L(u.exportName)}: HttpStreamRef<${p}, ${me(u.searchParams)}, ${me(u.params)}>;`}).join(`
|
|
284
|
+
`);return` ${L(v(s))}: {
|
|
285
285
|
${l}
|
|
286
286
|
};`}).join(`
|
|
287
|
-
`),o=r.map(([s,i])=>{const l=i.map(u=>` ${
|
|
288
|
-
`);return` ${
|
|
287
|
+
`),o=r.map(([s,i])=>{const l=i.map(u=>` ${L(u.exportName)}: { method: ${JSON.stringify(u.method)}, path: ${JSON.stringify(u.path)} },`).join(`
|
|
288
|
+
`);return` ${L(v(s))}: {
|
|
289
289
|
${l}
|
|
290
290
|
},`}).join(`
|
|
291
291
|
`);return{block:`
|
|
@@ -297,17 +297,17 @@ ${a}
|
|
|
297
297
|
export const httpStreams: HttpStreamsRef = {
|
|
298
298
|
${o}
|
|
299
299
|
};
|
|
300
|
-
`,body:a}},
|
|
300
|
+
`,body:a}},gr=e=>{const{agents:t=[],functions:n,httpRoutes:r=[],mutators:a=[],useUmbrella:o=!1,workflows:s=[]}=e,i=H(o),l=[...n.filter(R=>R.visibility!=="internal"),...kn(t,n),...vn(a,n)],u=n.filter(R=>R.visibility==="internal"),p=ze(l),b=ze(u),y=$n(r),$=`${p}
|
|
301
301
|
${b}
|
|
302
|
-
${
|
|
302
|
+
${y.body}`,d=qe($),c=d.length>0?`
|
|
303
303
|
import type { ${d.join(", ")} } from "./dataModel.js";
|
|
304
304
|
`:"",g=p?`
|
|
305
305
|
${p}
|
|
306
306
|
`:"",f=b?`
|
|
307
307
|
${b}
|
|
308
|
-
`:"",
|
|
309
|
-
import type { ${
|
|
310
|
-
${
|
|
308
|
+
`:"",x=fn(s,t),S=y.block===""?"FunctionReference":"FunctionReference, HttpStreamRef";return at(`${k}import { anyApi } from "${i.serverTypes}";
|
|
309
|
+
import type { ${S} } from "${i.client}";
|
|
310
|
+
${x.importLine}${c}
|
|
311
311
|
export interface ApiTypes {${g}}
|
|
312
312
|
|
|
313
313
|
export const api = anyApi as unknown as ApiTypes;
|
|
@@ -316,7 +316,7 @@ export const api = anyApi as unknown as ApiTypes;
|
|
|
316
316
|
export interface InternalApiTypes {${f}}
|
|
317
317
|
|
|
318
318
|
export const internal = anyApi as unknown as InternalApiTypes;
|
|
319
|
-
${
|
|
319
|
+
${x.block}${y.block}`,o)},mr=e=>e?`${k}import { createSeedClient as createSeedClientBase } from "@lunora/seed";
|
|
320
320
|
import type { SeedClient, SeedClientOptions } from "@lunora/seed";
|
|
321
321
|
|
|
322
322
|
import schema from "../schema.js";
|
|
@@ -333,9 +333,9 @@ import type { InsertModel } from "./dataModel.js";
|
|
|
333
333
|
* const { posts } = await seed.posts((x) => x([10, 20]));
|
|
334
334
|
*/
|
|
335
335
|
export const createSeedClient = (options?: SeedClientOptions): SeedClient<InsertModel> => createSeedClientBase<InsertModel>(schema, options);
|
|
336
|
-
`:"",
|
|
336
|
+
`:"",fr=(e,t,n=!1)=>{if(e.length===0||!t)return"";const r=H(n),a=l=>l.table===void 0?"Row":`Doc<${JSON.stringify(l.table)}> & Row`,o=e.map(l=>{m(l.exportName,"shape export name");const u=a(l),p=me(l.args),b=Object.keys(l.args).length>0,y=b?` args: ${p};`:` args?: ${p};`,$=b?`(args: ${p}) => void`:`(args?: ${p}) => void`,d=`${l.exportName}CollectionOptions`;return`/** Options for the \`${l.exportName}\` shape binding. */
|
|
337
337
|
export interface ${Ee(d)} {
|
|
338
|
-
${
|
|
338
|
+
${y}
|
|
339
339
|
/**
|
|
340
340
|
* Share the optimistic-overlay gate with other collections + mutators on this
|
|
341
341
|
* shard. Defaults to the shared per-shard registry, which is almost always what
|
|
@@ -387,7 +387,7 @@ import type { Collection } from "@tanstack/db";
|
|
|
387
387
|
import { createCollection } from "@tanstack/db";
|
|
388
388
|
${i}
|
|
389
389
|
${o}
|
|
390
|
-
`},
|
|
390
|
+
`},Sn=(e,t)=>`lunora_${v(e)}_${String(t)}`,Rn=`const callRegistered = async <R>(context: CallerCtx, functionPath: string, args: Record<string, unknown> | undefined): Promise<R> => {
|
|
391
391
|
const registered = LUNORA_FUNCTIONS[functionPath];
|
|
392
392
|
|
|
393
393
|
if (!registered) {
|
|
@@ -395,45 +395,45 @@ ${o}
|
|
|
395
395
|
}
|
|
396
396
|
|
|
397
397
|
return (await registered.handler(context, args ?? {})) as R;
|
|
398
|
-
};`,
|
|
398
|
+
};`,Nn=(e,t,n=[],r=[])=>{const a=new Map,o=d=>{a.has(d)||a.set(d,Sn(d,a.size))};for(const d of e)o(d.filePath);for(const d of t)o(d.filePath);for(const d of n)o(d.filePath);for(const d of r)o(d.filePath);const s=[...a.entries()].map(([d,c])=>{if(!sn.test(d))throw new Z("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(d)}`);return`import * as ${c} from "../${d}.js";`}).join(`
|
|
399
399
|
`),i=e.map(d=>` "${v(d.filePath)}:${d.exportName}": ${a.get(d.filePath)??""}.${d.exportName} as unknown as RegisteredLunoraFunction,`).join(`
|
|
400
400
|
`),l=t.map(d=>` ${JSON.stringify(d.id)}: ${a.get(d.filePath)??""}.${d.exportName} as unknown as RegisteredDataMigration,`).join(`
|
|
401
401
|
`),u=n.map(d=>` "${v(d.filePath)}:${d.exportName}": ${a.get(d.filePath)??""}.${d.exportName} as unknown as RegisteredLunoraFunction,`).join(`
|
|
402
402
|
`),p=r.map(d=>` "${d.exportName}": ${a.get(d.filePath)??""}.${d.exportName} as unknown as RegisteredShape,`).join(`
|
|
403
|
-
`),b=n.map(d=>`${v(d.filePath)}:${d.exportName}`),
|
|
404
|
-
`),$=e.map(d=>{if(d.lifecycle||Object.keys(d.args).length===0)return;const c=
|
|
405
|
-
`);return{dispatchBody:
|
|
406
|
-
${
|
|
403
|
+
`),b=n.map(d=>`${v(d.filePath)}:${d.exportName}`),y=[i,u].filter(d=>d.length>0).join(`
|
|
404
|
+
`),$=e.map(d=>{if(d.lifecycle||Object.keys(d.args).length===0)return;const c=on(d.args);return c===void 0?void 0:`installCompiledValidatorMap(${a.get(d.filePath)??""}.${d.exportName}.args, ${c});`}).filter(d=>d!==void 0).join(`
|
|
405
|
+
`);return{dispatchBody:y.length>0?`
|
|
406
|
+
${y}
|
|
407
407
|
`:"",importBlock:s.length>0?`${s}
|
|
408
408
|
|
|
409
409
|
`:"",installBlock:$,migrationBody:l.length>0?`
|
|
410
410
|
${l}
|
|
411
411
|
`:"",mutatorPaths:b,shapeBody:p.length>0?`
|
|
412
412
|
${p}
|
|
413
|
-
`:""}},
|
|
414
|
-
`);return` ${
|
|
413
|
+
`:""}},On=e=>{const t=new Map;for(const a of e){const o=t.get(a.filePath)??[];o.push(a),t.set(a.filePath,o)}const n=[...t.entries()].toSorted(([a],[o])=>a.localeCompare(o)),r=n.map(([a,o])=>{const s=o.map(i=>{const l=me(i.args),u=l==="{}"?"?":"",p=Me(i.returnType);return i.kind==="stream"?` ${i.exportName}: (args${u}: ${l}) => Promise<AsyncIterable<${p}>>;`:` ${i.exportName}: (args${u}: ${l}) => Promise<${p}>;`}).join(`
|
|
414
|
+
`);return` ${L(v(a))}: {
|
|
415
415
|
${s}
|
|
416
416
|
};`}).join(`
|
|
417
417
|
`);return{implementation:n.map(([a,o])=>{const s=v(a),i=o.map(l=>` ${l.exportName}: (args) => callRegistered(context, "${s}:${l.exportName}", args),`).join(`
|
|
418
|
-
`);return` ${
|
|
418
|
+
`);return` ${L(s)}: {
|
|
419
419
|
${i}
|
|
420
420
|
},`}).join(`
|
|
421
|
-
`),types:r}},
|
|
422
|
-
`:"",
|
|
423
|
-
readonly ai: LunoraAi;`:"",
|
|
424
|
-
`:"",
|
|
425
|
-
readonly payments: LunoraPayment;`:"",
|
|
426
|
-
`:"",
|
|
427
|
-
readonly x402: X402Pay;`:"",
|
|
428
|
-
`:"",
|
|
421
|
+
`),types:r}},An=(e,t=[])=>{const n=new Set;for(const r of e.tables)for(const a of Object.values(r.shape)){const o=a.kind==="optional"&&a.inner?a.inner:a;o.kind==="storage"&&typeof o.bucket=="string"&&o.bucket!==""&&n.add(o.bucket)}for(const r of t)r!==""&&r!=="default"&&n.add(r);return["default",...[...n].toSorted((r,a)=>r.localeCompare(a))]},br=({agents:e=[],containers:t=[],env:n,hasAccessFacade:r=!1,hasAi:a=!1,hasAnalytics:o=!1,hasBrowser:s=!1,hasFlags:i=!1,hasHyperdrive:l=!1,hasImages:u=!1,hasKv:p=!1,hasNotify:b=!1,hasPayments:y=!1,hasPipelines:$=!1,hasR2sql:d=!1,hasX402:c=!1,identity:g,queues:f=[],schema:x,storageRuleBuckets:S=[],useUmbrella:R=!1,workflows:C=[]}={})=>{const I=H(R),w=An(x??{tables:[]},S).map(h=>JSON.stringify(h)).join(" | "),E=a?`import type { LunoraAi } from "@lunora/ai";
|
|
422
|
+
`:"",ee=a?`
|
|
423
|
+
readonly ai: LunoraAi;`:"",F=y?`import type { LunoraPayment } from "@lunora/payment";
|
|
424
|
+
`:"",te=y?`
|
|
425
|
+
readonly payments: LunoraPayment;`:"",ne=c?`import type { X402Pay } from "@lunora/x402/pay";
|
|
426
|
+
`:"",B=c?`
|
|
427
|
+
readonly x402: X402Pay;`:"",N=t.length>0?`import type { ContainerAccessor } from "@lunora/container";
|
|
428
|
+
`:"",z=t.length>0?`
|
|
429
429
|
readonly containers: {${t.map(h=>`
|
|
430
430
|
readonly ${h.exportName}: ContainerAccessor;`).join("")}
|
|
431
|
-
};`:"",
|
|
432
|
-
readonly ${h.bindingName}?: unknown;`)),...
|
|
431
|
+
};`:"",O=[...a?[" /** Workers AI binding (the conventional `env.AI`), narrowing `ctx.ai`. */\n readonly AI?: unknown;"]:[],...t.map(h=>(m(h.bindingName,`container binding "${h.bindingName}"`),` /** Durable Object namespace for the \`${h.exportName}\` container. */
|
|
432
|
+
readonly ${h.bindingName}?: unknown;`)),...C.map(h=>(m(h.bindingName,`workflow binding "${h.bindingName}"`),` /** Workflow binding for the \`${h.exportName}\` workflow. */
|
|
433
433
|
readonly ${h.bindingName}?: unknown;`)),...f.map(h=>(m(h.bindingName,`queue binding "${h.bindingName}"`),` /** Queue producer binding for the \`${h.exportName}\` queue. */
|
|
434
434
|
readonly ${h.bindingName}?: unknown;`)),...e.map(h=>(m(h.bindingName,`agent binding "${h.bindingName}"`),` /** Workflow binding for the \`${h.exportName}\` agent. */
|
|
435
435
|
readonly ${h.bindingName}?: unknown;`))].join(`
|
|
436
|
-
`),
|
|
436
|
+
`),D=`
|
|
437
437
|
|
|
438
438
|
/**
|
|
439
439
|
* This project's Cloudflare bindings, as far as codegen can discover them from
|
|
@@ -446,26 +446,26 @@ ${i}
|
|
|
446
446
|
* surface, so treat them as \`Fetcher\`/\`Service<unknown>\` and cast.
|
|
447
447
|
*/
|
|
448
448
|
export interface CloudflareBindings {
|
|
449
|
-
readonly [binding: string]: unknown;${
|
|
450
|
-
${
|
|
449
|
+
readonly [binding: string]: unknown;${O?`
|
|
450
|
+
${O}`:""}
|
|
451
451
|
}
|
|
452
452
|
|
|
453
453
|
/** Alias for {@link CloudflareBindings} — the typed shape of \`env\`. */
|
|
454
|
-
export type Env = CloudflareBindings;`,
|
|
455
|
-
readonly vectors: VectorSearch<VectorIndexName>;`:"",
|
|
456
|
-
readonly vectors: VectorSearchReader<VectorIndexName>;`:"",
|
|
454
|
+
export type Env = CloudflareBindings;`,M=(h,_e)=>_e?Yt.get(h)?.field??"":"",re=M("kv",p),ae=M("analytics",o),xe=M("hyperdrive",l),ke=M("browser",s),ve=M("images",u),oe=M("pipelines",$),K=M("r2sql",d),P=(x?.vectorIndexes.length??0)>0,Q=P?' | "vectors"':"",X=P?`
|
|
455
|
+
readonly vectors: VectorSearch<VectorIndexName>;`:"",ie=P?`
|
|
456
|
+
readonly vectors: VectorSearchReader<VectorIndexName>;`:"",V=P?`import type { VectorSearch, VectorSearchReader } from "${I.server}";
|
|
457
457
|
import type { VectorIndexName } from "./dataModel.js";
|
|
458
|
-
`:"",
|
|
458
|
+
`:"",j=r?`
|
|
459
459
|
/** Verified Cloudflare Access identity — a synchronous facade over the resolved claims (email / groups / hasGroup / claims). Anonymous when no Access token is present. */
|
|
460
|
-
readonly access: import("@lunora/cloudflare-access/context").AccessFacade;`:"",
|
|
460
|
+
readonly access: import("@lunora/cloudflare-access/context").AccessFacade;`:"",W=i?`
|
|
461
461
|
/** Feature-flag evaluation (OpenFeature). Reads are memoized per request; evaluations never throw — a provider error resolves to the supplied default. */
|
|
462
|
-
readonly flags: import("${
|
|
462
|
+
readonly flags: import("${I.flags}").LunoraFlags;`:"",U=b?`
|
|
463
463
|
/** Multi-channel notifications (@lunora/notify): send / chat / inApp / webhook plus the push device sub-facade. Sends are external I/O — confine them to action handlers. */
|
|
464
464
|
readonly notify: import("@lunora/notify").LunoraNotify;
|
|
465
465
|
/** Device push sub-facade — the same object as ctx.notify.push (register / send / broadcast). Sends belong in action handlers. */
|
|
466
|
-
readonly push: import("@lunora/notify").LunoraPush;`:"",
|
|
466
|
+
readonly push: import("@lunora/notify").LunoraPush;`:"",q=C.length>0,Y=q?`import type { WorkflowHandle } from "@lunora/workflow";
|
|
467
467
|
import type * as lunoraWorkflowDefinitions from "../workflows.js";
|
|
468
|
-
`:"",$e=
|
|
468
|
+
`:"",$e=q?`
|
|
469
469
|
|
|
470
470
|
/** Params type carried by a \`defineWorkflow\` definition (its phantom \`__params\`). */
|
|
471
471
|
type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params }
|
|
@@ -476,9 +476,9 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
|
|
|
476
476
|
|
|
477
477
|
/** This project's declared workflows, addressable from \`ctx.workflows\` by their \`lunora/workflows.ts\` export name. */
|
|
478
478
|
export interface LunoraWorkflows {
|
|
479
|
-
${
|
|
479
|
+
${C.map(h=>` get(name: ${JSON.stringify(h.exportName)}): WorkflowHandle<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${h.exportName}>>;`).join(`
|
|
480
480
|
`)}
|
|
481
|
-
}`:"",fe=
|
|
481
|
+
}`:"",fe=q?' | "workflows"':"",be=q?`
|
|
482
482
|
readonly workflows: LunoraWorkflows;`:"",se=f.length>0,Se=se?`import type { QueueProducer } from "@lunora/queue";
|
|
483
483
|
import type * as lunoraQueueDefinitions from "../queues.js";
|
|
484
484
|
`:"",Re=se?`
|
|
@@ -499,9 +499,9 @@ export interface LunoraAgents {
|
|
|
499
499
|
${e.map(h=>(m(h.exportName,`agent export "${h.exportName}"`),` readonly ${h.exportName}: AgentHandle;`)).join(`
|
|
500
500
|
`)}
|
|
501
501
|
}`:"",we=le?`
|
|
502
|
-
readonly agents: LunoraAgents;`:"",
|
|
502
|
+
readonly agents: LunoraAgents;`:"",Ae=g?`import type { InferIdentity } from "${I.server}";
|
|
503
503
|
import type * as lunoraIdentityContract from "../identity.js";
|
|
504
|
-
`:"",
|
|
504
|
+
`:"",Te=g?`
|
|
505
505
|
|
|
506
506
|
/** 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. */
|
|
507
507
|
export type Identity = InferIdentity<typeof lunoraIdentityContract.${g.exportName}>;
|
|
@@ -512,7 +512,7 @@ type NarrowedAuth = Omit<QueryCtxBase["auth"], "getIdentity"> & { getIdentity: (
|
|
|
512
512
|
`:"",De=n?`
|
|
513
513
|
|
|
514
514
|
/** This app's declared env contract (\`defineEnv\` in \`lunora/env.ts\`) — the validated, coercion-aware shape of \`ctx.env\`. */
|
|
515
|
-
export type LunoraEnv = ReturnType<typeof lunoraEnvContract.${n.exportName}>;`:"",ue=n?' | "env"':"",pe=n?"\n /** Validated, typed environment declared by `defineEnv` in `lunora/env.ts` — parsed & coercion-aware config values (`ctx.env.STRIPE_KEY`); a missing or invalid value throws at read time. */\n readonly env: LunoraEnv;":"";return`${k}import { createPolicyDsl, defineMutator as defineMutatorBase, initLunora, v as vBase } from "${
|
|
515
|
+
export type LunoraEnv = ReturnType<typeof lunoraEnvContract.${n.exportName}>;`:"",ue=n?' | "env"':"",pe=n?"\n /** Validated, typed environment declared by `defineEnv` in `lunora/env.ts` — parsed & coercion-aware config values (`ctx.env.STRIPE_KEY`); a missing or invalid value throws at read time. */\n readonly env: LunoraEnv;":"";return`${k}import { createPolicyDsl, defineMutator as defineMutatorBase, initLunora, v as vBase } from "${I.server}";
|
|
516
516
|
import type {
|
|
517
517
|
ActionBuilder,
|
|
518
518
|
ActionCtx as ActionCtxBase,
|
|
@@ -533,14 +533,14 @@ import type {
|
|
|
533
533
|
Storage as StorageBase,
|
|
534
534
|
TableReader,
|
|
535
535
|
Validator,
|
|
536
|
-
} from "${
|
|
536
|
+
} from "${I.server}";
|
|
537
537
|
|
|
538
538
|
import type { DataModel, DatabaseReaderFacade, DatabaseWriterFacade, Doc, Id as IdOfTable, OrmReader, OrmWriter, Relations, TableName } from "./dataModel.js";
|
|
539
|
-
${
|
|
539
|
+
${V}${E}${F}${ne}${N}${Y}${Se}${Ne}${Ae}${Ce}
|
|
540
540
|
export type { AppTableName, DataModel, Doc, Id, TableName } from "./dataModel.js";
|
|
541
541
|
|
|
542
542
|
/** Storage buckets this schema declares (\`v.storage("name")\`), narrowing \`ctx.storage.bucket(name)\`. */
|
|
543
|
-
export type StorageBucketName = ${
|
|
543
|
+
export type StorageBucketName = ${w};${D}${$e}${Re}${Oe}${Te}${De}
|
|
544
544
|
|
|
545
545
|
/**
|
|
546
546
|
* Project-typed contexts. The base contexts from \`@lunora/server\` are
|
|
@@ -597,19 +597,19 @@ type TypedAsId = <T extends string>(tableName: AsIdTable<T>, id: string) => IdOf
|
|
|
597
597
|
export interface QueryCtx extends Omit<QueryCtxBase, "db" | "storage"${Q}${de}${ue}> {
|
|
598
598
|
readonly db: Omit<DatabaseReader, "asId" | "query" | "get"> & DatabaseReaderFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
|
|
599
599
|
readonly orm: OrmReader;
|
|
600
|
-
readonly storage: ReadOnlyStorage<StorageBucketName>;${
|
|
600
|
+
readonly storage: ReadOnlyStorage<StorageBucketName>;${ie}${j}${re}${W}${U}${ae}${pe}${ce}
|
|
601
601
|
}
|
|
602
602
|
|
|
603
603
|
export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${Q}${fe}${de}${ue}> {
|
|
604
604
|
readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
|
|
605
605
|
readonly orm: OrmWriter;
|
|
606
|
-
readonly storage: ReadOnlyStorage<StorageBucketName>;${
|
|
606
|
+
readonly storage: ReadOnlyStorage<StorageBucketName>;${X}${j}${re}${W}${U}${ae}${pe}${be}${ye}${we}${ce}
|
|
607
607
|
}
|
|
608
608
|
|
|
609
609
|
export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${Q}${fe}${de}${ue}> {
|
|
610
610
|
readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
|
|
611
611
|
readonly orm: OrmWriter;
|
|
612
|
-
readonly storage: StorageBase<StorageBucketName>;${
|
|
612
|
+
readonly storage: StorageBase<StorageBucketName>;${X}${j}${ee}${te}${B}${z}${re}${W}${U}${xe}${ke}${ve}${ae}${oe}${K}${pe}${be}${ye}${we}${ce}
|
|
613
613
|
}
|
|
614
614
|
|
|
615
615
|
/**
|
|
@@ -642,7 +642,7 @@ export const internalAction = lunoraBuilders.internalAction as unknown as Intern
|
|
|
642
642
|
/**
|
|
643
643
|
* \`defineMutator\` bound to this project's typed {@link MutationCtx} — declare
|
|
644
644
|
* custom mutators (\`lunora/mutators.ts\`) with it instead of importing from
|
|
645
|
-
* \`${
|
|
645
|
+
* \`${I.server}\`, and the authoritative \`server\` impl's \`ctx\` carries the
|
|
646
646
|
* schema-typed \`ctx.db\` (\`ctx.db.query("nodes")\` resolves \`Doc<"nodes">\`,
|
|
647
647
|
* \`ctx.db.patch(id, …)\` takes an \`Id<"nodes">\`) with no hand-written ctx type and
|
|
648
648
|
* no \`as unknown as\` cast. Runtime-identical to the package export; only the
|
|
@@ -684,13 +684,13 @@ export const definePolicy = createPolicyDsl<DataModel, Relations${Le}>();
|
|
|
684
684
|
export const v = vBase as unknown as Omit<typeof vBase, "id"> & {
|
|
685
685
|
id: <T extends TableName>(table: T) => ColumnValidator<IdOfTable<T>, IdOfTable<T>>;
|
|
686
686
|
};
|
|
687
|
-
`},
|
|
688
|
-
`);let
|
|
689
|
-
${
|
|
687
|
+
`},Tn=e=>{const t={connect:[],disconnect:[]};for(const n of e)n.lifecycle&&t[n.lifecycle].push(`${v(n.filePath)}:${n.exportName}`);return t},yr=e=>{const{agents:t=[],functions:n,migrations:r=[],mutators:a=[],shapes:o=[],useUmbrella:s=!1,usesSandbox:i=!1}=e,l=n.length>0,u=H(s),{dispatchBody:p,importBlock:b,installBlock:y,migrationBody:$,mutatorPaths:d,shapeBody:c}=Nn(n,r,a,o),g=wn(t,n),f=xn(i,n),x=[g.lines,f.lines].filter(D=>D.length>0).join(`
|
|
688
|
+
`);let S=p;x.length>0&&(S=p.length>0?`${p.trimEnd()}
|
|
689
|
+
${x}
|
|
690
690
|
`:`
|
|
691
|
-
${
|
|
692
|
-
`);const
|
|
693
|
-
`:"",
|
|
691
|
+
${x}
|
|
692
|
+
`);const R=Tn(n),C=o.length>0?`import type { RegisteredShape } from "${u.server}";
|
|
693
|
+
`:"",I=o.length>0?`
|
|
694
694
|
/**
|
|
695
695
|
* Replication-shape registry — one entry per \`defineShape\` in \`lunora/shapes.ts\`.
|
|
696
696
|
* The generated ShardDO's \`resolveShape\` override looks a shape up by name and
|
|
@@ -698,31 +698,31 @@ ${S}
|
|
|
698
698
|
* \`shape_subscribe\` (reads-as-permissions).
|
|
699
699
|
*/
|
|
700
700
|
export const LUNORA_SHAPES: Record<string, RegisteredShape> = {${c}};
|
|
701
|
-
`:"",
|
|
701
|
+
`:"",w=d.length>0?`
|
|
702
702
|
/**
|
|
703
703
|
* Custom-mutator function paths — the \`LUNORA_FUNCTIONS\` keys the generated
|
|
704
704
|
* ShardDO's \`isCustomMutator\` override routes through the client-watermark push
|
|
705
705
|
* protocol (\`x-lunora-client-id\`/\`x-lunora-client-seq\` ordering).
|
|
706
706
|
*/
|
|
707
|
-
export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${d.map(
|
|
708
|
-
`:"",
|
|
709
|
-
`:"",
|
|
707
|
+
export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${d.map(D=>JSON.stringify(D)).join(", ")}]);
|
|
708
|
+
`:"",E=y.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${u.values}";
|
|
709
|
+
`:"",ee=y.length>0?`
|
|
710
710
|
/**
|
|
711
711
|
* AOT-compiled argument validators (Worker-safe, no \`eval\`). Each is installed
|
|
712
712
|
* onto its function's live \`.args\` object and consulted by the interpreted
|
|
713
713
|
* parser as a zero-allocation fast path; anything it can't model is deferred.
|
|
714
714
|
*/
|
|
715
|
-
${
|
|
716
|
-
`:"",
|
|
717
|
-
${
|
|
718
|
-
`:"",
|
|
719
|
-
${
|
|
720
|
-
`:"",
|
|
721
|
-
`:"",
|
|
722
|
-
|
|
723
|
-
`:"";return at(`${k}${b}${g.importLine}${f.importLine}${
|
|
715
|
+
${y}
|
|
716
|
+
`:"",F=On(n),te=F.types?`
|
|
717
|
+
${F.types}
|
|
718
|
+
`:"",ne=F.implementation?`
|
|
719
|
+
${F.implementation}
|
|
720
|
+
`:"",B=qe(F.types),N=B.length>0?`import type { ${B.join(", ")} } from "./dataModel.js";
|
|
721
|
+
`:"",z=l?"context":"_context",O=l?`${Rn}
|
|
722
|
+
|
|
723
|
+
`:"";return at(`${k}${b}${g.importLine}${f.importLine}${E}${C}import { LunoraError } from "${u.server}";
|
|
724
724
|
import type { ActionCtx, MutationCtx, QueryCtx } from "./server.js";
|
|
725
|
-
${
|
|
725
|
+
${N}
|
|
726
726
|
/**
|
|
727
727
|
* Single registered function, narrowed to the shape \`handleRpc\` needs.
|
|
728
728
|
* The real argument validators / return types are checked elsewhere — at
|
|
@@ -746,8 +746,8 @@ ${g.prelude}${f.prelude}
|
|
|
746
746
|
* Static dispatch table. The key matches the \`__lunoraRef\` the client
|
|
747
747
|
* emits (\`api[namespace][fn].__lunoraRef === "namespace:fn"\`).
|
|
748
748
|
*/
|
|
749
|
-
export const LUNORA_FUNCTIONS: Record<string, RegisteredLunoraFunction> = {${
|
|
750
|
-
${
|
|
749
|
+
export const LUNORA_FUNCTIONS: Record<string, RegisteredLunoraFunction> = {${S}};
|
|
750
|
+
${ee}${I}${w}
|
|
751
751
|
/**
|
|
752
752
|
* Connection-lifecycle manifest: the function paths the generated ShardDO
|
|
753
753
|
* dispatches when a client's WebSocket connects (\`connect\`) or disconnects
|
|
@@ -755,8 +755,8 @@ ${ne}${y}${I}
|
|
|
755
755
|
* DO runs every hook under the socket's verified identity via system dispatch.
|
|
756
756
|
*/
|
|
757
757
|
export const LUNORA_LIFECYCLE_HOOKS: { connect: readonly string[]; disconnect: readonly string[] } = {
|
|
758
|
-
connect: [${
|
|
759
|
-
disconnect: [${
|
|
758
|
+
connect: [${R.connect.map(D=>JSON.stringify(D)).join(", ")}],
|
|
759
|
+
disconnect: [${R.disconnect.map(D=>JSON.stringify(D)).join(", ")}],
|
|
760
760
|
};
|
|
761
761
|
|
|
762
762
|
/**
|
|
@@ -787,10 +787,10 @@ export type CallerCtx = ActionCtx | MutationCtx | QueryCtx;
|
|
|
787
787
|
* with the supplied \`context\`, exactly like \`ctx.runQuery\`/\`runMutation\`/
|
|
788
788
|
* \`runAction\` but without re-stating the function path.
|
|
789
789
|
*/
|
|
790
|
-
export interface Caller {${
|
|
790
|
+
export interface Caller {${te}}
|
|
791
791
|
|
|
792
|
-
${
|
|
793
|
-
export const createCaller = (${
|
|
792
|
+
${O}/** Build a {@link Caller} bound to \`context\` (typically a handler's \`ctx\`). */
|
|
793
|
+
export const createCaller = (${z}: CallerCtx): Caller => ({${ne}});
|
|
794
794
|
|
|
795
795
|
/**
|
|
796
796
|
* Single registered data migration, narrowed to the shape the per-shard runner
|
|
@@ -810,7 +810,7 @@ export interface RegisteredDataMigration {
|
|
|
810
810
|
* shard DO's admin RPC and the CLI resolve migrations to run through this map.
|
|
811
811
|
*/
|
|
812
812
|
export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${$}};
|
|
813
|
-
`,s)},
|
|
813
|
+
`,s)},Ln=e=>{const t={};for(const n of e.tables){const r={};for(const[a,o]of Object.entries(n.shape)){const s=o.kind==="optional"&&o.inner?o.inner:o;s.kind==="id"&&s.tableName!==void 0&&(r[a]=s.tableName)}Object.keys(r).length>0&&(t[n.name]=r)}return t},Cn=e=>{const t={};for(const n of e.tables){const r=[];for(const[a,o]of Object.entries(n.shape))(o.kind==="optional"&&o.inner?o.inner:o).kind==="storage"&&r.push(a);r.length>0&&(t[n.name]=r)}return t},Dn=e=>{const t={};for(const n of e.tables){const r=[...n.indexes.map(a=>({fields:[...a.fields],name:a.name,type:"index",...a.unique===!0?{unique:!0}:{}})),...n.searchIndexes.map(a=>({fields:[a.field,...a.filterFields??[]],name:a.name,type:"search"})),...(n.geoIndexes??[]).map(a=>({fields:[a.field],name:a.name,type:"geo"})),...n.rankIndexes.map(a=>({fields:a.sortBy.map(o=>o.field),name:a.name,type:"rank"})),...n.vectorIndexes.map(a=>({fields:a.field===void 0?[]:[a.field],name:a.name,type:"vector"}))];r.length>0&&(t[n.name]=r)}return t},_n=e=>{const t=[];for(const n of e.tables)!n.ttl||n.shardMode==="global"||t.push({...n.ttl.after===void 0?{}:{after:n.ttl.after},field:n.ttl.field,...n.softDelete?{softDeleteField:n.softDelete.field}:{},table:n.name});return t},In=e=>{const t={};for(const n of e.tables){const r=[{name:"_id",optional:!1,pk:!0,type:"id"},{name:"_creationTime",optional:!1,type:"number"}];for(const[a,o]of Object.entries(n.shape)){const s=o.kind==="optional"||!!o.column?.hasDefault,i=o.kind==="optional"&&o.inner?o.inner:o,l={name:a,optional:s,type:i.kind};i.kind==="id"&&i.tableName!==void 0&&(l.ref=i.tableName),i.kind==="storage"&&(l.isStorage=!0),r.push(l)}t[n.name]=r}return t},Pn=e=>e?{importFragment:"serveRelationFanout, ",override:`
|
|
814
814
|
protected override async runRelationFanoutRead(functionPath: string, args: Record<string, unknown>): Promise<unknown> {
|
|
815
815
|
this.ensureMigrated();
|
|
816
816
|
|
|
@@ -818,7 +818,7 @@ export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${$}}
|
|
|
818
818
|
|
|
819
819
|
return serveRelationFanout(schema as unknown as SchemaLike, db, functionPath, args);
|
|
820
820
|
}
|
|
821
|
-
`}:{importFragment:"",override:""},
|
|
821
|
+
`}:{importFragment:"",override:""},En=e=>{if(!e)return{build:"",configField:"",contextField:"",stub:""};const t='throw new Error("ctx.ai: no AI binding found. Add an \\`ai\\` binding (env.AI) to wrangler.jsonc, or pass \\`ai\\` to createShardDO().");';return{build:`
|
|
822
822
|
const aiBinding = config.ai?.(env) ?? (env as Record<string, unknown>).AI;
|
|
823
823
|
// Correlate AI-Gateway-routed calls with the Lunora trace: thread the
|
|
824
824
|
// function path + trace id into createAi, which folds them into the
|
|
@@ -849,7 +849,7 @@ const aiStub: LunoraAi = {
|
|
|
849
849
|
${t}
|
|
850
850
|
}) as unknown as LunoraAi["workersai"],
|
|
851
851
|
};
|
|
852
|
-
`}},
|
|
852
|
+
`}},_={build:"",configField:"",contextField:"",importLines:[],stub:""},Fn=e=>{if(!e)return _;const t='throw new Error("ctx.kv: no KV binding found. Add a \\`kv_namespaces\\` binding (env.KV) to wrangler.jsonc, or pass \\`kv\\` to createShardDO().");';return{build:`
|
|
853
853
|
const kvBinding = config.kv?.(env) ?? (env as Record<string, unknown>).KV;
|
|
854
854
|
const kv: Kv = kvBinding ? createKv({ namespace: kvBinding as KVNamespaceLike }) : kvStub;
|
|
855
855
|
`,configField:`
|
|
@@ -875,7 +875,7 @@ const kvStub: Kv = {
|
|
|
875
875
|
${t}
|
|
876
876
|
},
|
|
877
877
|
};
|
|
878
|
-
`}},
|
|
878
|
+
`}},Mn=(e,t)=>e?{build:`
|
|
879
879
|
const flags: import("${t}").LunoraFlags = createFlags({
|
|
880
880
|
hooks: flagsConfig.hooks,
|
|
881
881
|
logger: flagsConfig.logger,
|
|
@@ -884,17 +884,17 @@ const kvStub: Kv = {
|
|
|
884
884
|
});
|
|
885
885
|
`,configField:`
|
|
886
886
|
flags?: (env: Record<string, unknown>) => import("${t}").Provider;`,contextField:`
|
|
887
|
-
flags,`,importLines:[`import { createFlags } from "${t}";`,'import flagsConfig from "../flags.js";'],stub:""}:
|
|
887
|
+
flags,`,importLines:[`import { createFlags } from "${t}";`,'import flagsConfig from "../flags.js";'],stub:""}:_,qn=e=>e?{build:`
|
|
888
888
|
const { notify, push } = createNotify(notifyConfig, env, { log, metrics });
|
|
889
889
|
`,configField:"",contextField:`
|
|
890
890
|
notify,
|
|
891
|
-
push,`,importLines:['import { createNotify } from "@lunora/notify";','import notifyConfig from "../notify.js";'],stub:""}:
|
|
891
|
+
push,`,importLines:['import { createNotify } from "@lunora/notify";','import notifyConfig from "../notify.js";'],stub:""}:_,Bn=e=>e?{build:`
|
|
892
892
|
const envConfig = lunoraEnvContract.${e.exportName}(env);
|
|
893
893
|
`,configField:"",contextField:`
|
|
894
|
-
env: envConfig,`,importLines:['import * as lunoraEnvContract from "../env.js";'],stub:""}:
|
|
894
|
+
env: envConfig,`,importLines:['import * as lunoraEnvContract from "../env.js";'],stub:""}:_,jn=e=>e?{build:`
|
|
895
895
|
const access = accessFacade(identity, userId);
|
|
896
896
|
`,configField:"",contextField:`
|
|
897
|
-
access,`,importLines:['import { accessFacade } from "@lunora/cloudflare-access/context";'],stub:""}:
|
|
897
|
+
access,`,importLines:['import { accessFacade } from "@lunora/cloudflare-access/context";'],stub:""}:_,Wn=(e,t,n)=>{if(!t)return{constant:"",evaluateOverride:"",subscriptionOverride:""};const r=i=>`
|
|
898
898
|
const env = (this.env ?? {}) as Record<string, unknown>;
|
|
899
899
|
const flags: import("${n}").LunoraFlags = createFlags({
|
|
900
900
|
hooks: flagsConfig.hooks,
|
|
@@ -958,7 +958,7 @@ const LUNORA_FLAG_KEYS: ReadonlyArray<{ key: string; type: "boolean" | "number"
|
|
|
958
958
|
|
|
959
959
|
return flags.boolean(key, typeof args.default === "boolean" ? args.default : false, context);
|
|
960
960
|
}
|
|
961
|
-
`;return{constant:a,evaluateOverride:o,subscriptionOverride:s}},
|
|
961
|
+
`;return{constant:a,evaluateOverride:o,subscriptionOverride:s}},Un=e=>{if(!e)return _;const t='throw new Error("ctx.analytics: no Analytics Engine binding found. Add an \\`analytics_engine_datasets\\` binding (env.ANALYTICS) to wrangler.jsonc, or pass \\`analytics\\` to createShardDO().");';return{build:`
|
|
962
962
|
const analyticsBinding = config.analytics?.(env) ?? (env as Record<string, unknown>).ANALYTICS;
|
|
963
963
|
const analytics: AnalyticsClient = analyticsBinding ? createAnalytics(analyticsBinding as AnalyticsEngineDatasetLike) : analyticsStub;
|
|
964
964
|
`,configField:`
|
|
@@ -972,7 +972,7 @@ const analyticsStub: AnalyticsClient = {
|
|
|
972
972
|
${t}
|
|
973
973
|
},
|
|
974
974
|
};
|
|
975
|
-
`}},
|
|
975
|
+
`}},Kn=e=>{if(!e)return _;const t='throw new Error("ctx.images: no Images binding found. Add an \\`images\\` binding (env.IMAGES) to wrangler.jsonc, or pass \\`images\\` to createShardDO().");';return{build:`
|
|
976
976
|
const imagesBinding = config.images?.(env) ?? (env as Record<string, unknown>).IMAGES;
|
|
977
977
|
const images: Images = imagesBinding ? createImages({ binding: imagesBinding as ImagesBindingLike }) : imagesStub;
|
|
978
978
|
`,configField:`
|
|
@@ -986,7 +986,7 @@ const imagesStub: Images = {
|
|
|
986
986
|
${t}
|
|
987
987
|
},
|
|
988
988
|
};
|
|
989
|
-
`}},
|
|
989
|
+
`}},Qn=e=>e?{build:`
|
|
990
990
|
const sql: SqlClient = config.sql ? config.sql(env) : sqlStub;
|
|
991
991
|
`,configField:`
|
|
992
992
|
sql?: (env: Record<string, unknown>) => SqlClient;`,contextField:`
|
|
@@ -996,7 +996,7 @@ const sqlStub: SqlClient = {
|
|
|
996
996
|
throw new Error("ctx.sql: provide a \\\`sql\\\` config thunk that builds a SqlClient from your driver, e.g. \\\`sql: (env) => fromPostgresJs(postgres(env.HYPERDRIVE.connectionString))\\\`.");
|
|
997
997
|
},
|
|
998
998
|
};
|
|
999
|
-
`}:
|
|
999
|
+
`}:_,Vn=e=>{if(!e)return _;const t="throw new Error(\"ctx.browser: provide a \\`browser\\` config thunk, e.g. \\`browser: (env) => createBrowser({ binding: env.BROWSER, launch })\\` with \\`import { launch } from '@cloudflare/playwright'\\`.\");";return{build:`
|
|
1000
1000
|
const browser: Browser = config.browser ? config.browser(env) : browserStub;
|
|
1001
1001
|
`,configField:`
|
|
1002
1002
|
browser?: (env: Record<string, unknown>) => Browser;`,contextField:`
|
|
@@ -1018,7 +1018,7 @@ const browserStub: Browser = {
|
|
|
1018
1018
|
${t}
|
|
1019
1019
|
},
|
|
1020
1020
|
};
|
|
1021
|
-
`}},
|
|
1021
|
+
`}},Jn=e=>{if(!e)return _;const t='throw new Error("ctx.r2sql: no R2 SQL credentials found. Set \\`R2_SQL_TOKEN\\`, \\`R2_SQL_ACCOUNT_ID\\` (or \\`CLOUDFLARE_ACCOUNT_ID\\`), and \\`R2_SQL_BUCKET\\` in your env/.dev.vars, or pass an \\`r2sql\\` config thunk to createShardDO().");';return{build:`
|
|
1022
1022
|
const r2sqlEnv = env as Record<string, unknown>;
|
|
1023
1023
|
const r2sqlAccountId = (r2sqlEnv.R2_SQL_ACCOUNT_ID ?? r2sqlEnv.CLOUDFLARE_ACCOUNT_ID) as string | undefined;
|
|
1024
1024
|
const r2sqlToken = r2sqlEnv.R2_SQL_TOKEN as string | undefined;
|
|
@@ -1050,7 +1050,7 @@ const r2sqlStub: R2SqlClient = {
|
|
|
1050
1050
|
${t}
|
|
1051
1051
|
},
|
|
1052
1052
|
};
|
|
1053
|
-
`}},
|
|
1053
|
+
`}},Gn=e=>e?{build:`
|
|
1054
1054
|
const pipelinesBinding = config.pipelines?.(env) ?? (env as Record<string, unknown>).PIPELINES;
|
|
1055
1055
|
const pipelines: PipelineClient = pipelinesBinding ? createPipelines({ binding: pipelinesBinding as PipelineBindingLike }) : pipelinesStub;
|
|
1056
1056
|
`,configField:`
|
|
@@ -1060,7 +1060,7 @@ const pipelinesStub: PipelineClient = {
|
|
|
1060
1060
|
throw new Error("ctx.pipelines: no Pipelines binding found. Add a \\\`pipelines\\\` binding (env.PIPELINES) to wrangler.jsonc, or pass \\\`pipelines\\\` to createShardDO().");
|
|
1061
1061
|
},
|
|
1062
1062
|
};
|
|
1063
|
-
`}:
|
|
1063
|
+
`}:_,wr=(e,t)=>{if(e.length===0)return"";const n=t?`, ${JSON.stringify(t)}`:"",r=e.map(o=>(m(o.exportName,`container export "${o.exportName}"`),m(o.className,`container class "${o.className}"`),`/** Container DO for the \`${o.exportName}\` definition (binding \`${o.bindingName}\`). */
|
|
1064
1064
|
export class ${o.className} extends LunoraContainer {
|
|
1065
1065
|
public constructor(ctx: ConstructorParameters<typeof LunoraContainer>[0], env: Record<string, unknown>) {
|
|
1066
1066
|
super(ctx, env, ${o.exportName}, "${o.exportName}"${n});
|
|
@@ -1085,7 +1085,7 @@ import { ${a} } from "../containers.js";
|
|
|
1085
1085
|
|
|
1086
1086
|
export { ContainerProxy } from "@lunora/container/do";
|
|
1087
1087
|
|
|
1088
|
-
${r}`},
|
|
1088
|
+
${r}`},Hn=(e,t)=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const r of e)m(r.exportName,`container export "${r.exportName}"`),m(r.bindingName,`container binding "${r.bindingName}"`);const n=e.map(r=>{const a=r.maxInstances===void 0?"":`, maxInstances: ${String(r.maxInstances)}`;return` { binding: "${r.bindingName}", exportName: "${r.exportName}"${a} },`}).join(`
|
|
1089
1089
|
`);return{build:`
|
|
1090
1090
|
const containers = createContainerContext(env, LUNORA_CONTAINERS, ${t?JSON.stringify(t):"undefined"}, this.getCurrentTraceparent());
|
|
1091
1091
|
`,contextField:`
|
|
@@ -1094,7 +1094,7 @@ ${r}`},Vn=(e,t)=>{if(e.length===0)return{build:"",contextField:"",importLines:[]
|
|
|
1094
1094
|
const LUNORA_CONTAINERS: ReadonlyArray<ContainerBindingSpec> = [
|
|
1095
1095
|
${n}
|
|
1096
1096
|
];
|
|
1097
|
-
`}},
|
|
1097
|
+
`}},xr=e=>{if(e.length===0)return"";const t=e.map(r=>(m(r.exportName,`workflow export "${r.exportName}"`),m(r.className,`workflow class "${r.className}"`),`/** WorkflowEntrypoint for the \`${r.exportName}\` definition (binding \`${r.bindingName}\`). */
|
|
1098
1098
|
export class ${r.className} extends LunoraWorkflow<WorkflowParamsOf<typeof ${r.exportName}>, WorkflowOutputOf<typeof ${r.exportName}>> {
|
|
1099
1099
|
public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
|
|
1100
1100
|
super(ctx, env, ${r.exportName}, "${r.exportName}");
|
|
@@ -1122,7 +1122,7 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
|
|
|
1122
1122
|
/** Output type carried by a \`defineWorkflow\` definition (its phantom \`__output\`), so each entrypoint keeps the authored return type. */
|
|
1123
1123
|
type WorkflowOutputOf<Definition> = Definition extends { __output?: infer Output } ? Output : unknown;
|
|
1124
1124
|
|
|
1125
|
-
${t}`},
|
|
1125
|
+
${t}`},kr=e=>{if(e.length===0)return"";const t=e.filter(a=>a.voice).length>0,n=e.map(a=>{m(a.exportName,`agent export "${a.exportName}"`),m(a.className,`agent class "${a.className}"`);const o=`/** WorkflowEntrypoint for the \`${a.exportName}\` agent (binding \`${a.bindingName}\`). */
|
|
1126
1126
|
export class ${a.className} extends LunoraWorkflow<AgentRunInput, AgentRunResult> {
|
|
1127
1127
|
public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
|
|
1128
1128
|
super(ctx, env, compileAgentWorkflow(${a.exportName}, "${a.exportName}"), "${a.exportName}");
|
|
@@ -1150,7 +1150,7 @@ import type { AgentRunInput, AgentRunResult } from "@lunora/agent";
|
|
|
1150
1150
|
|
|
1151
1151
|
import { ${r} } from "../agents.js";
|
|
1152
1152
|
|
|
1153
|
-
${n}`},
|
|
1153
|
+
${n}`},vr=e=>{const t=e.filter(a=>a.mode==="push");if(t.length===0)return"";for(const a of t)m(a.exportName,`queue export "${a.exportName}"`);const n=t.map(a=>a.exportName).join(", "),r=t.map(a=>` ${JSON.stringify(a.name)}: { definition: ${a.exportName}, exportName: ${JSON.stringify(a.exportName)} },`).join(`
|
|
1154
1154
|
`);return`${k}/**
|
|
1155
1155
|
* Push-consumer registry for the queues declared in \`lunora/queues.ts\`. The
|
|
1156
1156
|
* composed worker's \`queue(batch, env, ctx)\` entry routes each delivered batch
|
|
@@ -1165,7 +1165,7 @@ import { ${n} } from "../queues.js";
|
|
|
1165
1165
|
export const LUNORA_QUEUE_REGISTRY: QueueRegistry = {
|
|
1166
1166
|
${r}
|
|
1167
1167
|
};
|
|
1168
|
-
`},
|
|
1168
|
+
`},zn=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)m(n.exportName,`workflow export "${n.exportName}"`),m(n.bindingName,`workflow binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}" },`).join(`
|
|
1169
1169
|
`);return{build:`
|
|
1170
1170
|
const workflows = createWorkflowContext(env, LUNORA_WORKFLOWS);
|
|
1171
1171
|
`,contextField:`
|
|
@@ -1174,7 +1174,7 @@ ${r}
|
|
|
1174
1174
|
const LUNORA_WORKFLOWS: ReadonlyArray<WorkflowBindingSpec> = [
|
|
1175
1175
|
${t}
|
|
1176
1176
|
];
|
|
1177
|
-
`}},
|
|
1177
|
+
`}},Xn=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)m(n.exportName,`queue export "${n.exportName}"`),m(n.bindingName,`queue binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}", name: ${JSON.stringify(n.name)} },`).join(`
|
|
1178
1178
|
`);return{build:`
|
|
1179
1179
|
const queues = createQueueContext(env, LUNORA_QUEUES);
|
|
1180
1180
|
`,contextField:`
|
|
@@ -1183,7 +1183,7 @@ ${t}
|
|
|
1183
1183
|
const LUNORA_QUEUES: ReadonlyArray<QueueBindingSpec> = [
|
|
1184
1184
|
${t}
|
|
1185
1185
|
];
|
|
1186
|
-
`}},
|
|
1186
|
+
`}},Yn=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)m(n.exportName,`agent export "${n.exportName}"`),m(n.bindingName,`agent binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}"${n.publicRun===!0?", publicRun: true":""} },`).join(`
|
|
1187
1187
|
`);return{build:`
|
|
1188
1188
|
const agents = createAgentContext(env, LUNORA_AGENTS);
|
|
1189
1189
|
`,contextField:`
|
|
@@ -1192,21 +1192,21 @@ ${t}
|
|
|
1192
1192
|
const LUNORA_AGENTS: ReadonlyArray<AgentBindingSpec> = [
|
|
1193
1193
|
${t}
|
|
1194
1194
|
];
|
|
1195
|
-
`}},
|
|
1195
|
+
`}},Zn=e=>{if(e.length===0)return{constant:"",override:""};const t={workflows:e.map(n=>({binding:n.bindingName,className:n.className,exportName:n.exportName,name:n.name}))};return{constant:`
|
|
1196
1196
|
/** Read-only declared-workflow metadata (discovered from \`lunora/workflows.ts\`) served via \`__lunora_admin__:listWorkflows\` for the studio's workflows view. */
|
|
1197
1197
|
const LUNORA_WORKFLOWS_INFO: WorkflowsResult = ${JSON.stringify(t,void 0,4)};
|
|
1198
1198
|
`,override:`
|
|
1199
1199
|
protected override workflowsMetadata(): WorkflowsResult {
|
|
1200
1200
|
return LUNORA_WORKFLOWS_INFO;
|
|
1201
1201
|
}
|
|
1202
|
-
`}},
|
|
1202
|
+
`}},er=e=>{if(e.length===0)return{constant:"",override:""};const t={queues:e.map(n=>({binding:n.bindingName,...n.tuning.deadLetterQueue===void 0?{}:{deadLetterQueue:n.tuning.deadLetterQueue},exportName:n.exportName,mode:n.mode,name:n.name}))};return{constant:`
|
|
1203
1203
|
/** Read-only declared-queue metadata (discovered from \`lunora/queues.ts\`) served via \`__lunora_admin__:listQueues\` for the studio's queues view. */
|
|
1204
1204
|
const LUNORA_QUEUES_INFO: QueuesResult = ${JSON.stringify(t,void 0,4)};
|
|
1205
1205
|
`,override:`
|
|
1206
1206
|
protected override queuesMetadata(): QueuesResult {
|
|
1207
1207
|
return LUNORA_QUEUES_INFO;
|
|
1208
1208
|
}
|
|
1209
|
-
`}},
|
|
1209
|
+
`}},tr=e=>{if(!e)return{build:"",configField:"",contextField:"",imports:[],stub:""};const t='throw new Error("ctx.payments: no payment configured. Pass \\`payment\\` to createShardDO().");';return{imports:['import type { LunoraDatabaseLike as LunoraPaymentDbLike, LunoraPayment, PaymentsFromContextOptions } from "@lunora/payment";','import { paymentsFromContext } from "@lunora/payment";'],build:`
|
|
1210
1210
|
const payments: LunoraPayment = config.payment
|
|
1211
1211
|
? paymentsFromContext({ auth: { userId: userId ?? null }, db: db as unknown as LunoraPaymentDbLike }, config.payment(env))
|
|
1212
1212
|
: paymentStub;
|
|
@@ -1242,7 +1242,7 @@ const paymentStub: LunoraPayment = {
|
|
|
1242
1242
|
${t}
|
|
1243
1243
|
},
|
|
1244
1244
|
} as unknown as LunoraPayment;
|
|
1245
|
-
`}},
|
|
1245
|
+
`}},nr=e=>e?{imports:['import type { X402Pay, X402PayConfig } from "@lunora/x402/pay";','import { lazyX402Pay } from "@lunora/x402/pay";'],build:`
|
|
1246
1246
|
const x402: X402Pay = config.x402
|
|
1247
1247
|
? lazyX402Pay(config.x402(env), { getSecret: (name: string) => secrets.get(name) })
|
|
1248
1248
|
: x402Stub;
|
|
@@ -1254,10 +1254,10 @@ const x402Stub: X402Pay = {
|
|
|
1254
1254
|
throw new Error("ctx.x402: no pay rail configured. Pass \\\`x402\\\` to createShardDO().");
|
|
1255
1255
|
},
|
|
1256
1256
|
} as unknown as X402Pay;
|
|
1257
|
-
`}:{build:"",configField:"",contextField:"",imports:[],stub:""},
|
|
1257
|
+
`}:{build:"",configField:"",contextField:"",imports:[],stub:""},rr=(e,t,n,r)=>["AdvisorProcedure","AdvisoryFinding","DatabaseWriterLike","DataMigrationLike",...r?["FlagsResult"]:[],"MaskPoliciesResult","MigrationRunResult",...n?["QueuesResult"]:[],"RunShardApplyCdcArgs","RunShardMigrationArgs","RlsPoliciesResult","RunShardRankBeforeArgs","RunShardRankPageArgs","RunShardWriteArgs","RunShardWriteResult","SchedulerLike","SchemaLike","ShardDOState","ShardRankPageResult","SqlExec","StorageRulesResult","StudioFeaturesResult","SystemReaderStorageLike","TelemetrySink",...t?["WorkflowsResult"]:[],...e?["WriteHook"]:[]],$r=({advisories:e=[],advisorProcedures:t=[],agents:n=[],containers:r=[],env:a,flagKeys:o=[],hasAccessFacade:s=!1,hasAi:i=!1,hasAnalytics:l=!1,hasBrowser:u=!1,hasFlags:p=!1,hasHyperdrive:b=!1,hasImages:y=!1,hasKv:$=!1,hasNotify:d=!1,hasPayments:c=!1,hasPipelines:g=!1,hasR2sql:f=!1,hasX402:x=!1,maskMetadata:S,mutators:R=[],queues:C=[],rlsMetadata:I,schema:w,schemaSnapshot:E,shapes:ee=[],storageRules:F,studioFeatures:te,useUmbrella:ne=!1,workflows:B=[]})=>{const N=H(ne),z=R.length>0,O=ee.length>0,D=E===void 0?"":Ht(E),M=E===void 0?"":`
|
|
1258
1258
|
/** 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. */
|
|
1259
|
-
const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(
|
|
1260
|
-
`,E
|
|
1259
|
+
const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(zt(E))}, json: ${JSON.stringify(D)} };
|
|
1260
|
+
`,re=E===void 0?"":", schemaSnapshot: LUNORA_SCHEMA_SNAPSHOT",{build:ae,configField:xe,contextField:ke,stub:ve}=En(i),oe=jn(s),K=Fn($),P=Mn(p,N.flags),Q=Wn(o,p,N.flags),X=qn(d),ie=Bn(a),V=Un(l),j=Kn(y),W=Qn(b),U=Vn(u),q=Jn(f),Y=Gn(g),{build:$e,contextField:fe,importLines:be,specs:se}=Xn(C),{build:Se,contextField:Re,importLines:ye,specs:le}=Hn(r,w.jurisdiction),{build:Ne,contextField:Oe,importLines:we,specs:Ae}=zn(B),{build:Te,contextField:de,importLines:ce,specs:Le}=Yn(n),{build:Ce,configField:De,contextField:ue,imports:pe,stub:h}=tr(c),{build:_e,configField:it,imports:st,stub:lt}=nr(x),dt=e,ct=t,ut=I??{policies:[],roles:[]},pt=S??{columns:[]},ht=F??{rules:[]},gt=te??{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:mt,override:ft}=Zn(B),{constant:bt,override:yt}=er(C),J=w.vectorIndexes.length>0,he=w.tables.some(A=>A.shardMode==="global"),Ie=w.tables.some(A=>A.shardMode==="global"&&A.globalBackend==="hyperdrive"),je=w.tables.some(A=>A.shardMode==="global"&&A.globalBackend!=="hyperdrive"),G=w.tables.some(A=>A.externalSource!==void 0);if(je&&Ie)throw new Z("INTERNAL",'lunora codegen: mixing `.global()` (D1) and `.global({ backend: "hyperdrive" })` tables in one app is not supported yet — use a single global backend.');const Pe=w.tables.length>0,wt=Ln(w),xt=Dn(w),kt=In(w),vt=Cn(w),We=_n(w),Ue=rr(J,B.length>0,C.length>0,p);O&&Ue.push("WhereInput");const Ke=Pn(he),$t=O?`
|
|
1261
1261
|
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 {
|
|
1262
1262
|
const shape = LUNORA_SHAPES[name];
|
|
1263
1263
|
|
|
@@ -1310,15 +1310,15 @@ const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.st
|
|
|
1310
1310
|
|
|
1311
1311
|
return { columns: shape.columns, effectiveWhere, global: isGlobal, table: shape.table };
|
|
1312
1312
|
}
|
|
1313
|
-
`:"",
|
|
1313
|
+
`:"",St=z?`
|
|
1314
1314
|
protected override isCustomMutator(functionPath: string): boolean {
|
|
1315
1315
|
return LUNORA_MUTATOR_PATHS.has(functionPath);
|
|
1316
1316
|
}
|
|
1317
|
-
`:""
|
|
1318
|
-
vectors?: (env: Record<string, unknown>) => Record<string, VectorizeIndexLike>;`:"",
|
|
1319
|
-
d1?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",
|
|
1320
|
-
hyperdriveGlobal?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",
|
|
1321
|
-
sourceClient?: (env: Record<string, unknown>, binding: string) => { query: <Row = Record<string, unknown>>(text: string, params?: readonly unknown[]) => Promise<Row[]> } | undefined;`:"",
|
|
1317
|
+
`:"",Rt=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":"",Nt=O?"assertShapeShardable, ":"",ge=[`import type { ${Ue.join(", ")} } from "${N.do}";`,`import { applyCdcChanges, ${Nt}createShardCtxDb, ${G?"isSourceDue, pullExternalSourceIncrementalTick, pullExternalSourceTick, ":""}runDataMigration, runShardMigrations, ${Ke.importFragment}ShardDO as ShardDOBase } from "${N.do}";`,...G?[`import type { ExternalSourceLike, SourceClientLike } from "${N.do}";`]:[],O?`import { asBucketStorage, buildRlsReadRegistry, composeShapeReadWhere, createSecrets, LunoraError } from "${N.server}";`:`import { asBucketStorage, createSecrets, LunoraError } from "${N.server}";`];Pe&&ge.push(`import { bindOrm, bindTableFacade } from "${N.server}";`),J&&ge.push('import type { SchemaLike as VectorSchemaLike, VectorizeIndexLike, VectorSearchLike } from "@lunora/bindings/vectors";','import { createContextVectors, createVectors, createVectorSyncHook } from "@lunora/bindings/vectors";'),i&&ge.push('import type { AiBindingLike, LunoraAi } from "@lunora/ai";','import { createAi } from "@lunora/ai";'),ge.push(...oe.importLines,...K.importLines,...P.importLines,...X.importLines,...ie.importLines,...V.importLines,...j.importLines,...W.importLines,...U.importLines,...q.importLines,...Y.importLines,...ye,...we,...be,...ce,...pe,...st,"",'import schema from "../schema.js";',`import { ${["LUNORA_FUNCTIONS","LUNORA_LIFECYCLE_HOOKS","LUNORA_MIGRATIONS",...z?["LUNORA_MUTATOR_PATHS"]:[],...O?["LUNORA_SHAPES"]:[]].join(", ")} } from "./functions.js";`);const Ot=J?`
|
|
1318
|
+
vectors?: (env: Record<string, unknown>) => Record<string, VectorizeIndexLike>;`:"",At=je?`
|
|
1319
|
+
d1?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",Tt=Ie?`
|
|
1320
|
+
hyperdriveGlobal?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",Lt=G?`
|
|
1321
|
+
sourceClient?: (env: Record<string, unknown>, binding: string) => { query: <Row = Record<string, unknown>>(text: string, params?: readonly unknown[]) => Promise<Row[]> } | undefined;`:"",Ct=he?'\nconst globalDbStub: DatabaseWriterLike = {\n aggregate: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n count: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n delete: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n findFirst: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n findFirstOrThrow: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n findMany: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n get: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n groupBy: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n insert: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n normalizeId: () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n patch: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n query: () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n rank: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n rankPage: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n replace: async () => {\n throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");\n },\n};\n':"",Dt=J?`
|
|
1322
1322
|
const vectorsStub: VectorSearchLike = {
|
|
1323
1323
|
deleteByIds: async () => {
|
|
1324
1324
|
throw new Error("ctx.vectors: no vectors configured. Pass \`vectors\` to createShardDO().");
|
|
@@ -1336,7 +1336,7 @@ const vectorsStub: VectorSearchLike = {
|
|
|
1336
1336
|
throw new Error("ctx.vectors: no vectors configured. Pass \`vectors\` to createShardDO().");
|
|
1337
1337
|
},
|
|
1338
1338
|
};
|
|
1339
|
-
`:"",
|
|
1339
|
+
`:"",_t=J?`
|
|
1340
1340
|
let vectors: VectorSearchLike;
|
|
1341
1341
|
let onWrite: WriteHook | undefined;
|
|
1342
1342
|
|
|
@@ -1350,8 +1350,8 @@ const vectorsStub: VectorSearchLike = {
|
|
|
1350
1350
|
onWrite = undefined;
|
|
1351
1351
|
}
|
|
1352
1352
|
`:"",Qe=he?`
|
|
1353
|
-
globalDb,`:"",
|
|
1354
|
-
auth: { identity: identity ?? null, userId: userId ?? null },`,
|
|
1353
|
+
globalDb,`:"",Ve=`
|
|
1354
|
+
auth: { identity: identity ?? null, userId: userId ?? null },`,It=J?`{${Ve}
|
|
1355
1355
|
broadcast: (delta) => {
|
|
1356
1356
|
this.recordChangedTable(delta.table);
|
|
1357
1357
|
},
|
|
@@ -1364,7 +1364,7 @@ const vectorsStub: VectorSearchLike = {
|
|
|
1364
1364
|
schema: schema as unknown as SchemaLike,
|
|
1365
1365
|
sql: this.sql as SqlExec,
|
|
1366
1366
|
storage,${Qe}
|
|
1367
|
-
}`:`{${
|
|
1367
|
+
}`:`{${Ve}
|
|
1368
1368
|
broadcast: (delta) => {
|
|
1369
1369
|
this.recordChangedTable(delta.table);
|
|
1370
1370
|
},
|
|
@@ -1376,13 +1376,13 @@ const vectorsStub: VectorSearchLike = {
|
|
|
1376
1376
|
schema: schema as unknown as SchemaLike,
|
|
1377
1377
|
sql: this.sql as SqlExec,
|
|
1378
1378
|
storage,${Qe}
|
|
1379
|
-
}`,
|
|
1380
|
-
vectors,`:"",
|
|
1381
|
-
orm: bindOrm(facade),`:"",
|
|
1382
|
-
`:"",
|
|
1379
|
+
}`,Pt=J?`
|
|
1380
|
+
vectors,`:"",Et=Pe?`
|
|
1381
|
+
orm: bindOrm(facade),`:"",Ft="",Je=Ie?"config.hyperdriveGlobal":"config.d1",Mt=he?` const globalDb: DatabaseWriterLike = ${Je}?.(env, { identity, userId }) ?? globalDbStub;
|
|
1382
|
+
`:"",qt=O&&he?`
|
|
1383
1383
|
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 }>> {
|
|
1384
1384
|
const env = this.env as Record<string, unknown>;
|
|
1385
|
-
const globalDb: DatabaseWriterLike = ${
|
|
1385
|
+
const globalDb: DatabaseWriterLike = ${Je}?.(env, identity) ?? globalDbStub;
|
|
1386
1386
|
const rows: Array<{ doc: Record<string, unknown>; id: string }> = [];
|
|
1387
1387
|
|
|
1388
1388
|
let cursor: null | string = null;
|
|
@@ -1409,10 +1409,10 @@ const vectorsStub: VectorSearchLike = {
|
|
|
1409
1409
|
|
|
1410
1410
|
return rows;
|
|
1411
1411
|
}
|
|
1412
|
-
`:"",
|
|
1412
|
+
`:"",Bt=G?`
|
|
1413
1413
|
const sourceClientCache = new WeakMap<object, Map<string, SourceClientLike>>();
|
|
1414
1414
|
const sourcePollAtCache = new WeakMap<object, Map<string, number>>();
|
|
1415
|
-
`:"",
|
|
1415
|
+
`:"",jt=G?`
|
|
1416
1416
|
protected override async pollExternalSources(): Promise<number | undefined> {
|
|
1417
1417
|
const env = (this.env ?? {}) as Record<string, unknown>;
|
|
1418
1418
|
const sourced = Object.entries((schema as unknown as SchemaLike).tables)
|
|
@@ -1513,7 +1513,7 @@ const sourcePollAtCache = new WeakMap<object, Map<string, number>>();
|
|
|
1513
1513
|
|
|
1514
1514
|
return nextDueAt;
|
|
1515
1515
|
}
|
|
1516
|
-
`:"",Ge=We.length>0,
|
|
1516
|
+
`:"",Ge=We.length>0,Wt=G||Ge?`
|
|
1517
1517
|
public constructor(state: ShardDOState, env: unknown) {
|
|
1518
1518
|
super(state, env);
|
|
1519
1519
|
${G?`
|
|
@@ -1531,21 +1531,21 @@ ${G?`
|
|
|
1531
1531
|
void this.scheduleTtlSweep();
|
|
1532
1532
|
}
|
|
1533
1533
|
`:""} }
|
|
1534
|
-
`:"",
|
|
1534
|
+
`:"",Ut=Pe?`
|
|
1535
1535
|
const facade = db as unknown as Record<string, ReturnType<typeof bindTableFacade>>;
|
|
1536
|
-
${
|
|
1536
|
+
${w.tables.map(A=>` facade[${JSON.stringify(A.name)}] = bindTableFacade(db, ${JSON.stringify(A.name)});`).join(`
|
|
1537
1537
|
`)}
|
|
1538
|
-
`:"",
|
|
1538
|
+
`:"",Kt=`${oe.build}${K.build}${P.build}${V.build}${ie.build}
|
|
1539
1539
|
const secrets = createSecrets(env);
|
|
1540
|
-
`,
|
|
1541
|
-
secrets,`,
|
|
1540
|
+
`,Qt=`${oe.contextField}${K.contextField}${P.contextField}${X.contextField}${V.contextField}${ie.contextField}
|
|
1541
|
+
secrets,`,Vt=X.build,He=y||b||u||f||g||x,Jt=He?`
|
|
1542
1542
|
// ActionCtx-only helpers (external, non-deterministic I/O): constructed
|
|
1543
1543
|
// and attached only for an \`action\` so query/mutation ctx never carry them.
|
|
1544
1544
|
if (isAction) {
|
|
1545
|
-
${
|
|
1545
|
+
${j.build}${W.build}${U.build}${q.build}${Y.build}${_e}${[...y?[" ctx.images = images;"]:[],...b?[" ctx.sql = sql;"]:[],...u?[" ctx.browser = browser;"]:[],...f?[" ctx.r2sql = r2sql;"]:[],...g?[" ctx.pipelines = pipelines;"]:[],...x?[" ctx.x402 = x402;"]:[]].join(`
|
|
1546
1546
|
`)}
|
|
1547
1547
|
}
|
|
1548
|
-
`:"",
|
|
1548
|
+
`:"",Gt=He?` const isAction = LUNORA_FUNCTIONS[options.functionPath ?? ""]?.kind === "action";
|
|
1549
1549
|
`:"";return`${k}${ge.join(`
|
|
1550
1550
|
`)}
|
|
1551
1551
|
|
|
@@ -1556,42 +1556,45 @@ interface FunctionReference {
|
|
|
1556
1556
|
}
|
|
1557
1557
|
|
|
1558
1558
|
/** Foreign-key columns per table (\`v.id("target")\` fields) for the data browser. */
|
|
1559
|
-
const LUNORA_TABLE_REFS: Record<string, Record<string, string>> = ${JSON.stringify(
|
|
1559
|
+
const LUNORA_TABLE_REFS: Record<string, Record<string, string>> = ${JSON.stringify(wt,void 0,4)};
|
|
1560
1560
|
|
|
1561
1561
|
/** Declared indexes per table (secondary, search, geo, rank, vector) for the schema viewer. */
|
|
1562
|
-
const LUNORA_TABLE_INDEXES: Record<string, Array<{ fields: string[]; name: string; type: "geo" | "index" | "rank" | "search" | "vector"; unique?: boolean }>> = ${JSON.stringify(
|
|
1562
|
+
const LUNORA_TABLE_INDEXES: Record<string, Array<{ fields: string[]; name: string; type: "geo" | "index" | "rank" | "search" | "vector"; unique?: boolean }>> = ${JSON.stringify(xt,void 0,4)};
|
|
1563
1563
|
|
|
1564
1564
|
/** Columns per table (typed, with PK/FK markers) for the studio's schema diagram, served via \`__lunora_admin__:describeTable\`. */
|
|
1565
|
-
const LUNORA_TABLE_COLUMNS: Record<string, Array<{ isStorage?: boolean; name: string; optional: boolean; pk?: boolean; ref?: string; type: string }>> = ${JSON.stringify(
|
|
1565
|
+
const LUNORA_TABLE_COLUMNS: Record<string, Array<{ isStorage?: boolean; name: string; optional: boolean; pk?: boolean; ref?: string; type: string }>> = ${JSON.stringify(kt,void 0,4)};
|
|
1566
1566
|
|
|
1567
1567
|
/** Storage-key columns per table (\`v.storage(...)\` fields) for the file browser's records↔files join. */
|
|
1568
|
-
const LUNORA_STORAGE_COLUMNS: Record<string, string[]> = ${JSON.stringify(
|
|
1568
|
+
const LUNORA_STORAGE_COLUMNS: Record<string, string[]> = ${JSON.stringify(vt,void 0,4)};
|
|
1569
1569
|
|
|
1570
1570
|
/** Declarative TTL policies (\`.ttl(field, { after? })\`) the DO alarm sweep auto-expires rows for. */
|
|
1571
1571
|
const LUNORA_TTL_SWEEPS: Array<{ after?: number; field: string; softDeleteField?: string; table: string }> = ${JSON.stringify(We,void 0,4)};
|
|
1572
1572
|
|
|
1573
1573
|
/** Static schema advisories (computed by @lunora/advisor at codegen time) served via \`__lunora_admin__:getAdvisories\`. */
|
|
1574
|
-
const LUNORA_ADVISORIES: AdvisoryFinding[] = ${JSON.stringify(
|
|
1574
|
+
const LUNORA_ADVISORIES: AdvisoryFinding[] = ${JSON.stringify(dt,void 0,4)};
|
|
1575
|
+
|
|
1576
|
+
/** Every declared procedure (discovered by @lunora/codegen) served via \`__lunora_admin__:getAdvisorProcedures\` — the health map's denominator. */
|
|
1577
|
+
const LUNORA_ADVISOR_PROCEDURES: AdvisorProcedure[] = ${JSON.stringify(ct,void 0,4)};
|
|
1575
1578
|
|
|
1576
1579
|
/** Read-only RLS metadata (policies + roles discovered from \`.use(rls(...))\` chains) served via \`__lunora_admin__:rlsPolicies\` for the studio's RLS inspector. */
|
|
1577
|
-
const LUNORA_RLS_METADATA: RlsPoliciesResult = ${JSON.stringify(
|
|
1580
|
+
const LUNORA_RLS_METADATA: RlsPoliciesResult = ${JSON.stringify(ut,void 0,4)};
|
|
1578
1581
|
|
|
1579
1582
|
/** Read-only masking metadata (table + column + strategy discovered from \`.use(mask(...))\` chains) served via \`__lunora_admin__:maskPolicies\` for the studio's data-browser mask preview. */
|
|
1580
|
-
const LUNORA_MASK_METADATA: MaskPoliciesResult = ${JSON.stringify(
|
|
1583
|
+
const LUNORA_MASK_METADATA: MaskPoliciesResult = ${JSON.stringify(pt,void 0,4)};
|
|
1581
1584
|
|
|
1582
1585
|
/** Read-only storage access-rule metadata (discovered from \`.use(storageRules(...))\` chains) served via \`__lunora_admin__:storageRules\` for the studio's access-rules view. */
|
|
1583
|
-
const LUNORA_STORAGE_RULES: StorageRulesResult = ${JSON.stringify(
|
|
1586
|
+
const LUNORA_STORAGE_RULES: StorageRulesResult = ${JSON.stringify(ht,void 0,4)};
|
|
1584
1587
|
|
|
1585
1588
|
/** Which optional package-backed features this app wires up (discovered from imports / \`ctx.*\` reads / schema signals) served via \`__lunora_admin__:studioFeatures\` so the studio hides nav pages whose package isn't enabled. */
|
|
1586
|
-
const LUNORA_STUDIO_FEATURES: StudioFeaturesResult = ${JSON.stringify(
|
|
1587
|
-
${
|
|
1589
|
+
const LUNORA_STUDIO_FEATURES: StudioFeaturesResult = ${JSON.stringify(gt,void 0,4)};
|
|
1590
|
+
${M}${Q.constant}${Rt}${mt}${bt}${le}${Ae}${se}${Le}
|
|
1588
1591
|
export interface ShardDOConfig {
|
|
1589
1592
|
/** Opt into change-data-capture: records a post-image to \`__cdc_log\` on every write (backs streaming export + replay-PITR). */
|
|
1590
1593
|
cdc?: boolean;
|
|
1591
1594
|
/** Optional telemetry sink. When supplied, each \`ctx.log.*\` call is forwarded to \`sink.onLog\`. Pass the SAME sink you give \`createWorker({ observability })\` (which drives \`onRpc\`) to route both RPC and log events. */
|
|
1592
1595
|
observability?: (env: Record<string, unknown>) => TelemetrySink | undefined;
|
|
1593
1596
|
scheduler?: (env: Record<string, unknown>) => unknown;
|
|
1594
|
-
storage?: (env: Record<string, unknown>) => unknown;${
|
|
1597
|
+
storage?: (env: Record<string, unknown>) => unknown;${Ot}${xe}${K.configField}${P.configField}${V.configField}${j.configField}${W.configField}${U.configField}${q.configField}${Y.configField}${De}${it}${At}${Tt}${Lt}
|
|
1595
1598
|
}
|
|
1596
1599
|
|
|
1597
1600
|
const schedulerStub = {
|
|
@@ -1629,7 +1632,7 @@ const storageStub = {
|
|
|
1629
1632
|
throw new Error("ctx.storage: no storage configured. Pass \`storage\` to createShardDO().");
|
|
1630
1633
|
},
|
|
1631
1634
|
};
|
|
1632
|
-
${
|
|
1635
|
+
${Ct}${Bt}${Dt}${ve}${K.stub}${P.stub}${V.stub}${j.stub}${W.stub}${U.stub}${q.stub}${Y.stub}${h}${lt}${Ft}
|
|
1633
1636
|
// Bound in-process \`ctx.run*\` composition depth so a self- or cyclically-
|
|
1634
1637
|
// referencing call fails loudly with a clear error instead of overflowing the
|
|
1635
1638
|
// stack. Tracked across the awaited handler chain (one DO invocation is
|
|
@@ -1666,7 +1669,7 @@ const dispatchRun = async (expected: FunctionKind, functionPath: string, args: R
|
|
|
1666
1669
|
* from the worker entry so wrangler binds it by name.
|
|
1667
1670
|
*/
|
|
1668
1671
|
export const createShardDO = (config: ShardDOConfig = {}): new (state: ShardDOState, env: unknown) => ShardDOBase =>
|
|
1669
|
-
class extends ShardDOBase {${
|
|
1672
|
+
class extends ShardDOBase {${Wt}
|
|
1670
1673
|
private migrated = false;
|
|
1671
1674
|
|
|
1672
1675
|
public override async handleRpc(functionPath: string, args: Record<string, unknown>): Promise<unknown> {
|
|
@@ -1742,7 +1745,7 @@ ${Ke.override}
|
|
|
1742
1745
|
iterator: (signal) => (registered.handler as (context: unknown, args: Record<string, unknown>, signal: AbortSignal) => AsyncIterable<unknown>)(this.buildCtx({ functionPath }), args, signal),
|
|
1743
1746
|
};
|
|
1744
1747
|
}
|
|
1745
|
-
${
|
|
1748
|
+
${St}${$t}${qt}${jt}
|
|
1746
1749
|
protected override lifecycleHookPaths(event: "connect" | "disconnect"): readonly string[] {
|
|
1747
1750
|
return LUNORA_LIFECYCLE_HOOKS[event];
|
|
1748
1751
|
}
|
|
@@ -1782,11 +1785,15 @@ ${vt}${kt}${Ft}${qt}
|
|
|
1782
1785
|
protected override studioFeatures(): StudioFeaturesResult {
|
|
1783
1786
|
return LUNORA_STUDIO_FEATURES;
|
|
1784
1787
|
}
|
|
1785
|
-
${
|
|
1788
|
+
${Q.evaluateOverride}${Q.subscriptionOverride}${ft}${yt}
|
|
1786
1789
|
protected override advisories(): AdvisoryFinding[] {
|
|
1787
1790
|
return LUNORA_ADVISORIES;
|
|
1788
1791
|
}
|
|
1789
1792
|
|
|
1793
|
+
protected override advisorProcedures(): AdvisorProcedure[] {
|
|
1794
|
+
return LUNORA_ADVISOR_PROCEDURES;
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1790
1797
|
protected override async runShardDataMigration(args: RunShardMigrationArgs): Promise<MigrationRunResult> {
|
|
1791
1798
|
const migration = LUNORA_MIGRATIONS[args.id];
|
|
1792
1799
|
|
|
@@ -1991,7 +1998,7 @@ ${M.evaluateOverride}${M.subscriptionOverride}${gt}${ft}
|
|
|
1991
1998
|
return;
|
|
1992
1999
|
}
|
|
1993
2000
|
|
|
1994
|
-
runShardMigrations(this.sql as SqlExec, schema as unknown as SchemaLike, { cdc: config.cdc ?? false${
|
|
2001
|
+
runShardMigrations(this.sql as SqlExec, schema as unknown as SchemaLike, { cdc: config.cdc ?? false${re} });
|
|
1995
2002
|
this.migrated = true;
|
|
1996
2003
|
}
|
|
1997
2004
|
|
|
@@ -2004,7 +2011,7 @@ ${M.evaluateOverride}${M.subscriptionOverride}${gt}${ft}
|
|
|
2004
2011
|
// dispatch path) fall back to the per-request fields as before.
|
|
2005
2012
|
const userId = options.identity ? options.identity.userId : this.getCurrentUserId();
|
|
2006
2013
|
const identity = options.identity ? options.identity.identity : this.getCurrentIdentity();
|
|
2007
|
-
${
|
|
2014
|
+
${_t}${ae}${Kt}${Se}${Ne}${$e}${Te}
|
|
2008
2015
|
const scheduler = (config.scheduler?.(env) ?? schedulerStub) as SchedulerLike;
|
|
2009
2016
|
// Build the storage adapter once and share it between \`ctx.storage\`
|
|
2010
2017
|
// and \`ctx.db.system._storage\` so both read the same R2 binding. The
|
|
@@ -2031,13 +2038,13 @@ ${Ct}${ae}${Wt}${se}${le}${ve}${Te}
|
|
|
2031
2038
|
// so both write to the same trace.
|
|
2032
2039
|
const span = this.makeDispatchSpan(traceAnchor, observability);
|
|
2033
2040
|
|
|
2034
|
-
${
|
|
2041
|
+
${Mt} // \`ctx.db\`, wrapped in automatic instrumentation: by default this
|
|
2035
2042
|
// adds aggregate counters (call count, total time, per-operation
|
|
2036
2043
|
// breakdown) to the wide event rather than a span per call, so a
|
|
2037
2044
|
// handler making hundreds of queries stays readable. See
|
|
2038
2045
|
// \`instrumentDatabase\` for the \`"spans"\` / \`"off"\` levels.
|
|
2039
|
-
const db: DatabaseWriterLike = this.instrumentDb(createShardCtxDb(${
|
|
2040
|
-
${
|
|
2046
|
+
const db: DatabaseWriterLike = this.instrumentDb(createShardCtxDb(${It}), logFunctionPath, traceAnchor, observability);
|
|
2047
|
+
${Ut}${Ce}
|
|
2041
2048
|
|
|
2042
2049
|
// \`ctx.trace\` / \`ctx.metrics\`: spans and measurements to the same sink.
|
|
2043
2050
|
// The trace anchor is threaded explicitly for the same reason \`identity\`
|
|
@@ -2045,7 +2052,7 @@ ${jt}${Le}
|
|
|
2045
2052
|
// writing mutation's trace from the shared per-request field.
|
|
2046
2053
|
const trace = this.makeTracer(logFunctionPath, observability, traceAnchor);
|
|
2047
2054
|
const metrics = this.makeMetrics(logFunctionPath, observability);
|
|
2048
|
-
${
|
|
2055
|
+
${Vt}
|
|
2049
2056
|
// \`ctx.now\`: the wall-clock instant (epoch ms) this function began,
|
|
2050
2057
|
// captured ONCE so the whole handler body sees a single stable value.
|
|
2051
2058
|
// Query/mutation handlers must be deterministic (they may be re-run on
|
|
@@ -2068,13 +2075,13 @@ ${Kt}
|
|
|
2068
2075
|
ip: this.getCurrentIp(),
|
|
2069
2076
|
log,
|
|
2070
2077
|
metrics,
|
|
2071
|
-
now,${
|
|
2078
|
+
now,${Et}
|
|
2072
2079
|
scheduler,
|
|
2073
2080
|
span,
|
|
2074
2081
|
storage,
|
|
2075
|
-
trace,${
|
|
2082
|
+
trace,${Pt}${ke}${Qt}${ue}${Re}${Oe}${fe}${de}
|
|
2076
2083
|
};
|
|
2077
|
-
${
|
|
2084
|
+
${Gt}${Jt}
|
|
2078
2085
|
ctx.runAction = (reference: FunctionReference, fnArgs: Record<string, unknown>) => dispatchRun("action", reference.__lunoraRef, fnArgs, ctx);
|
|
2079
2086
|
ctx.runMutation = (reference: FunctionReference, fnArgs: Record<string, unknown>) => dispatchRun("mutation", reference.__lunoraRef, fnArgs, ctx);
|
|
2080
2087
|
ctx.runQuery = (reference: FunctionReference, fnArgs: Record<string, unknown>) => dispatchRun("query", reference.__lunoraRef, fnArgs, ctx);
|
|
@@ -2082,19 +2089,19 @@ ${Jt}${Qt}
|
|
|
2082
2089
|
return ctx;
|
|
2083
2090
|
}
|
|
2084
2091
|
};
|
|
2085
|
-
`},Be=e=>{switch(e.kind){case"array":case"object":case"record":case"union":return{builder:"text",mode:"json",notNull:!0,typeAnnotation:T(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"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?Be(e.inner):{builder:"text",notNull:!1},notNull:!1};case"storage":case"string":return{builder:"text",notNull:!0};default:return{builder:"text",notNull:!0}}},
|
|
2092
|
+
`},Be=e=>{switch(e.kind){case"array":case"object":case"record":case"union":return{builder:"text",mode:"json",notNull:!0,typeAnnotation:T(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"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?Be(e.inner):{builder:"text",notNull:!1},notNull:!1};case"storage":case"string":return{builder:"text",notNull:!0};default:return{builder:"text",notNull:!0}}},ar=(e,t,n)=>{m(e,"drizzle column name");const r=Be(t),a=t.kind==="optional"&&t.inner?t.inner:t,o=r.mode?`, { mode: "${r.mode}" }`:"";let s=`${r.builder}("${e}"${o})`;return r.typeAnnotation&&(s+=`.$type<${r.typeAnnotation}>()`),a.kind==="id"&&a.tableName&&n.has(a.tableName)&&(s+=`.references(() => ${a.tableName}._id)`),r.notNull&&(s+=".notNull()"),s},or=e=>{m(e.name,"drizzle index name");const t=e.unique?"uniqueIndex":"index",n=e.fields.map(r=>(m(r,"drizzle index field"),`t.${r}`)).join(", ");return` ${e.name}: ${t}("${e.name}").on(${n}),`},ir=(e,t)=>{m(e.name,"table name");const n=[' _id: text("_id").primaryKey(),',' _creationTime: integer("_creationTime").notNull(),',...Object.entries(e.shape).map(([a,o])=>` ${a}: ${ar(a,o,t)},`)].join(`
|
|
2086
2093
|
`),r=e.indexes.length>0?`, (t) => ({
|
|
2087
|
-
${e.indexes.map(a=>
|
|
2094
|
+
${e.indexes.map(a=>or(a)).join(`
|
|
2088
2095
|
`)}
|
|
2089
2096
|
})`:"";return`export const ${e.name} = sqliteTable("${e.name}", {
|
|
2090
2097
|
${n}
|
|
2091
|
-
}${r});`},
|
|
2092
|
-
`;const n=H(t),{columns:r,indexes:a}=
|
|
2098
|
+
}${r});`},sr=e=>{const t=new Set,n=new Set;t.add("text"),t.add("integer"),t.add("sqliteTable");for(const r of e){for(const a of Object.values(r.shape)){const o=Be(a);t.add(o.builder)}for(const a of r.indexes)n.add(a.unique?"uniqueIndex":"index")}return{columns:[...t].toSorted((r,a)=>r.localeCompare(a)),indexes:[...n].toSorted((r,a)=>r.localeCompare(a))}},Xe=(e,t=!1)=>{if(e.length===0)return`${k}export {};
|
|
2099
|
+
`;const n=H(t),{columns:r,indexes:a}=sr(e),o=[...a,...r].toSorted((l,u)=>l.localeCompare(u)),s=new Set(e.map(l=>l.name)),i=e.map(l=>ir(l,s)).join(`
|
|
2093
2100
|
|
|
2094
2101
|
`);return`${k}import { ${o.join(", ")} } from "${n.serverDrizzle}";
|
|
2095
2102
|
|
|
2096
2103
|
${i}
|
|
2097
|
-
`},
|
|
2104
|
+
`},Sr=(e,t=!1)=>{const n=e.tables.filter(a=>a.shardMode==="global"),r=e.tables.filter(a=>a.shardMode!=="global");return{global:Xe(n,t),shard:Xe(r,t)}},Rr=e=>{const t=[],n=new Map;for(const i of e){const l=n.get(i.cron);l?l.push(i):(n.set(i.cron,[i]),t.push(i.cron))}const r=t.map(i=>` ${JSON.stringify(i)},`).join(`
|
|
2098
2105
|
`),a=r.length>0?`
|
|
2099
2106
|
${r}
|
|
2100
2107
|
`:"",o=[...n.entries()].map(([i,l])=>{const u=l.map(p=>{const b=p.workflow?`workflow: ${JSON.stringify(p.workflow.binding)}`:`functionPath: ${JSON.stringify(p.functionPath)}`;return` { name: ${JSON.stringify(p.name)}, ${b}, args: ${JSON.stringify(p.args)} },`}).join(`
|
|
@@ -2128,7 +2135,7 @@ export const LUNORA_CRON_TRIGGERS: ReadonlyArray<string> = [${a}];
|
|
|
2128
2135
|
* looks up \`event.cron\` here and dispatches every job in the list.
|
|
2129
2136
|
*/
|
|
2130
2137
|
export const LUNORA_CRONS: Record<string, ReadonlyArray<LunoraCronJob>> = {${s}};
|
|
2131
|
-
`},
|
|
2138
|
+
`},Nr=e=>{const t=[...e].toSorted((r,a)=>r.name.localeCompare(a.name)).map(r=>{const a=[`name: ${JSON.stringify(r.name)}`,`table: ${JSON.stringify(r.table)}`];return r.field!==void 0&&a.push(`field: ${JSON.stringify(r.field)}`),r.dimensions!==void 0&&a.push(`dimensions: ${JSON.stringify(r.dimensions)}`),r.metric!==void 0&&a.push(`metric: ${JSON.stringify(r.metric)}`),r.metadata!==void 0&&a.push(`metadata: ${JSON.stringify(r.metadata)}`),` { ${a.join(", ")} },`}).join(`
|
|
2132
2139
|
`),n=t.length>0?`
|
|
2133
2140
|
${t}
|
|
2134
2141
|
`:"";return`${k}/**
|
|
@@ -2152,4 +2159,4 @@ export interface LunoraVectorIndex {
|
|
|
2152
2159
|
* \`createWorker({ vectorIntrospector })\` to back the studio's vector browser.
|
|
2153
2160
|
*/
|
|
2154
2161
|
export const LUNORA_VECTOR_INDEXES: ReadonlyArray<LunoraVectorIndex> = [${n}];
|
|
2155
|
-
`},
|
|
2162
|
+
`},Or=e=>{const t=new Set,n=[];for(const r of e)t.has(r.cron)||(t.add(r.cron),n.push(r.cron));return n};export{yr as $,vr as G,kr as H,xr as K,wr as Q,Xt as a,fr as b,Rr as c,Nr as d,pr as e,mr as f,gr as h,Sr as l,Cn as n,$r as r,hr as t,Or as u,br as v,k as w};
|