@lunora/codegen 1.0.0-alpha.107 → 1.0.0-alpha.109
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 +22 -5
- package/dist/index.d.ts +22 -5
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/AGENTS_FILENAME-CPHo8Se5.mjs +1 -0
- package/dist/packem_shared/{CONTAINERS_FILENAME-DQpyhY6c.mjs → CONTAINERS_FILENAME-Bvn6LZP6.mjs} +1 -1
- package/dist/packem_shared/CodegenDiagnosticError-BUXlG3P-.mjs +1 -0
- package/dist/packem_shared/DEFAULT_TARGET-CIH5PRk1.mjs +1 -0
- package/dist/packem_shared/FLAGS_FILENAME-DtBWyUKq.mjs +1 -0
- package/dist/packem_shared/GENERATED_HEADER-GSCh67g3.mjs +1 -0
- package/dist/packem_shared/{LUNORA_ERROR_CODES-zfAI2OFs.mjs → LUNORA_ERROR_CODES-BYg8Lpgb.mjs} +1 -1
- package/dist/packem_shared/MUTATORS_FILENAME-CRmTpN4y.mjs +1 -0
- package/dist/packem_shared/NOTIFY_FILENAME-BybR3Xbd.mjs +1 -0
- package/dist/packem_shared/OPENRPC_VERSION-DB1PSt8W.mjs +3 -0
- package/dist/packem_shared/QUEUES_FILENAME-BnGLtAIu.mjs +1 -0
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-D9rvsQ0t.mjs +9 -0
- package/dist/packem_shared/SCHEMA_SNAPSHOT_VERSION-DIqnj_32.mjs +2 -0
- package/dist/packem_shared/SDK_LANGUAGES-p7vq4x7B.mjs +320 -0
- package/dist/packem_shared/SHAPES_FILENAME-DxoIrQhA.mjs +1 -0
- package/dist/packem_shared/SchemaSnapshotParseError-Dc1aZAph.mjs +16 -0
- package/dist/packem_shared/WORKFLOWS_FILENAME-B8y51Frf.mjs +1 -0
- package/dist/packem_shared/buildOpenApiDocument-B2mW3f5a.mjs +3 -0
- package/dist/packem_shared/describeErrorLevelFindings-D23VSkFP.mjs +1 -0
- package/dist/packem_shared/discover-ast-D33zP-NZ.mjs +1 -0
- package/dist/packem_shared/discover-queries-Dfj_0WJG.mjs +1 -0
- package/dist/packem_shared/discoverAuthApiCalls-DUjcl0SB.mjs +1 -0
- package/dist/packem_shared/discoverCrons-BUJO2ipU.mjs +1 -0
- package/dist/packem_shared/discoverFunctions-h8i51Mec.mjs +1 -0
- package/dist/packem_shared/discoverHttpRoutes-MX6y-iVE.mjs +1 -0
- package/dist/packem_shared/discoverInserts-YX8AmrzL.mjs +1 -0
- package/dist/packem_shared/discoverMaskProcedures-DhcK-YMG.mjs +1 -0
- package/dist/packem_shared/discoverMigrations-4Jjf5DJE.mjs +1 -0
- package/dist/packem_shared/discoverNondeterministicCalls-CjS2Mznw.mjs +1 -0
- package/dist/packem_shared/discoverQueries-C5S9tFoD.mjs +1 -0
- package/dist/packem_shared/discoverR2sqlCalls-DuTuaSMM.mjs +1 -0
- package/dist/packem_shared/discoverRlsMetadata-BYVq6cVp.mjs +1 -0
- package/dist/packem_shared/{discoverSandboxUsage-DBM98vVh.mjs → discoverSandboxUsage-L0lV17de.mjs} +1 -1
- package/dist/packem_shared/discoverSchema-BtlNz9b_.mjs +1 -0
- package/dist/packem_shared/discoverStorageRulesMetadata-CKPFWHT5.mjs +1 -0
- package/dist/packem_shared/{emit-BbLyaTLJ.mjs → emit-Ba3NiOwK.mjs} +326 -326
- package/dist/packem_shared/{emitApp-DkO-Qvoo.mjs → emitApp-hKEej7rj.mjs} +18 -18
- package/dist/packem_shared/formatAdvisories-BjTV22uR.mjs +2 -0
- package/dist/packem_shared/isTypedSchema-CU-O5qSH.mjs +2 -0
- package/dist/packem_shared/module-specifiers-WF8iAydP.mjs +1 -0
- package/dist/packem_shared/parse-validator-DtALyvid.mjs +1 -0
- package/dist/packem_shared/paths-C-9fwEgQ.mjs +1 -0
- package/dist/packem_shared/readPackageDependencies-C6h6FZuP.mjs +1 -0
- package/dist/packem_shared/redact-Cy14LEnc.mjs +1 -0
- package/dist/packem_shared/schemaFromIr-BWFnvCVg.mjs +1 -0
- package/package.json +5 -5
- package/dist/packem_shared/AGENTS_FILENAME-Dk-k250h.mjs +0 -1
- package/dist/packem_shared/CodegenDiagnosticError-DPezpZTz.mjs +0 -1
- package/dist/packem_shared/DEFAULT_TARGET-CH5disA3.mjs +0 -1
- package/dist/packem_shared/FLAGS_FILENAME-Boqm0YCP.mjs +0 -1
- package/dist/packem_shared/GENERATED_HEADER-CtitJsDk.mjs +0 -1
- package/dist/packem_shared/MUTATORS_FILENAME-Cp_JxLSz.mjs +0 -1
- package/dist/packem_shared/NOTIFY_FILENAME-DwyJ5I4Q.mjs +0 -1
- package/dist/packem_shared/OPENRPC_VERSION-Bzh1vxcl.mjs +0 -3
- package/dist/packem_shared/QUEUES_FILENAME-QpMZsde0.mjs +0 -1
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-DlCvMk66.mjs +0 -9
- package/dist/packem_shared/SCHEMA_SNAPSHOT_VERSION-CFhF_hmg.mjs +0 -2
- package/dist/packem_shared/SDK_LANGUAGES-fIqQtE14.mjs +0 -320
- package/dist/packem_shared/SHAPES_FILENAME-WxXOsYfe.mjs +0 -1
- package/dist/packem_shared/SchemaSnapshotParseError-BkgxjBPQ.mjs +0 -16
- package/dist/packem_shared/WORKFLOWS_FILENAME-Dz80zqeT.mjs +0 -1
- package/dist/packem_shared/buildOpenApiDocument-B8-PH9af.mjs +0 -3
- package/dist/packem_shared/describeErrorLevelFindings-IhNx9gPr.mjs +0 -1
- package/dist/packem_shared/discover-ast-7ABwvTVn.mjs +0 -1
- package/dist/packem_shared/discover-queries-CU9o_j87.mjs +0 -1
- package/dist/packem_shared/discoverAuthApiCalls-XfNbxqlq.mjs +0 -1
- package/dist/packem_shared/discoverCrons-RlATa0_t.mjs +0 -1
- package/dist/packem_shared/discoverFunctions-4TNKUv7P.mjs +0 -1
- package/dist/packem_shared/discoverHttpRoutes-DQivLBqT.mjs +0 -1
- package/dist/packem_shared/discoverInserts-D6szWzrV.mjs +0 -1
- package/dist/packem_shared/discoverMaskProcedures-BBPqLXA5.mjs +0 -1
- package/dist/packem_shared/discoverMigrations-rbjxflR8.mjs +0 -1
- package/dist/packem_shared/discoverNondeterministicCalls-Bxr652Rz.mjs +0 -1
- package/dist/packem_shared/discoverQueries-CIU5dc0u.mjs +0 -1
- package/dist/packem_shared/discoverR2sqlCalls-DMxG6gHr.mjs +0 -1
- package/dist/packem_shared/discoverRlsMetadata-B63ARnKG.mjs +0 -1
- package/dist/packem_shared/discoverSchema-BNr7PVcZ.mjs +0 -1
- package/dist/packem_shared/discoverStorageRulesMetadata-_40MGqRX.mjs +0 -1
- package/dist/packem_shared/formatAdvisories-CQvIhQ04.mjs +0 -2
- package/dist/packem_shared/isTypedSchema-9wiKtXr2.mjs +0 -2
- package/dist/packem_shared/module-specifiers-8FEEiUcv.mjs +0 -1
- package/dist/packem_shared/parse-validator-CusS8QwU.mjs +0 -1
- package/dist/packem_shared/paths-BmX5O1sG.mjs +0 -1
- package/dist/packem_shared/readPackageDependencies-CogJX1Ia.mjs +0 -1
- package/dist/packem_shared/redact-6jD4lAhq.mjs +0 -1
- package/dist/packem_shared/schemaFromIr-R1ZFzVyy.mjs +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{agentComponent as
|
|
1
|
+
import{agentComponent as ot}from"@lunora/agent/component";import{LunoraError as te}from"@lunora/errors";import{serializeSchemaSnapshot as mn,hashSchemaSnapshot as hn}from"./SCHEMA_SNAPSHOT_VERSION-DIqnj_32.mjs";import{s as S}from"./paths-C-9fwEgQ.mjs";const at=[{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,57 +15,57 @@ import{agentComponent as rt}from"@lunora/agent/component";import{LunoraError as
|
|
|
15
15
|
/**
|
|
16
16
|
* R2 SQL over Apache Iceberg tables (window functions, DISTINCT, set operations). Non-deterministic — available only in actions. Reads here are NOT tracked by Lunora live queries.
|
|
17
17
|
*/
|
|
18
|
-
readonly r2sql: import("@lunora/bindings/r2sql").R2SqlClient;`,tier:"action"}},{contextProperty:"scheduler",key:"scheduler",moduleSpecifier:"@lunora/scheduler"},{contextProperty:"storage",key:"storage",moduleSpecifier:"@lunora/storage"},{appMethod:{configKey:"vectors",doc:"Wire the Vectorize index map backing `ctx.vectors`.",method:"vectors"},contextProperty:"vectors",key:"vectors",moduleSpecifier:"@lunora/bindings/vectors"},{contextProperty:"workflows",key:"workflows",moduleSpecifier:"@lunora/workflow"}],gn=at,fn=new Map(gn.flatMap(e=>e.serverCtxField?[[e.key,e.serverCtxField]]:[])),
|
|
19
|
-
`;case"boolean":return`if (typeof ${
|
|
20
|
-
`;case"date":case"number":case"timestamp":return`if (typeof ${
|
|
21
|
-
`;case"null":return`if (${
|
|
22
|
-
`;default:return`if (typeof ${
|
|
23
|
-
`}},
|
|
24
|
-
`}},We=(e,n
|
|
25
|
-
const ${
|
|
26
|
-
for (let ${i} = 0; ${i} < ${
|
|
27
|
-
const ${
|
|
28
|
-
${
|
|
18
|
+
readonly r2sql: import("@lunora/bindings/r2sql").R2SqlClient;`,tier:"action"}},{contextProperty:"scheduler",key:"scheduler",moduleSpecifier:"@lunora/scheduler"},{contextProperty:"storage",key:"storage",moduleSpecifier:"@lunora/storage"},{appMethod:{configKey:"vectors",doc:"Wire the Vectorize index map backing `ctx.vectors`.",method:"vectors"},contextProperty:"vectors",key:"vectors",moduleSpecifier:"@lunora/bindings/vectors"},{contextProperty:"workflows",key:"workflows",moduleSpecifier:"@lunora/workflow"}],gn=at,fn=new Map(gn.flatMap(e=>e.serverCtxField?[[e.key,e.serverCtxField]]:[])),jr=at.flatMap(e=>"appMethod"in e?[{appMethod:e.appMethod,key:e.key}]:[]),st=/^(?:"(?:[^"\\]|\\(?:["\\/bfnrt]|u[0-9A-Fa-f]{4}))*"|'[^'\\]*'|-?\d+(?:\.\d+)?|true|false|null)$/u,yn=new Set(["any","bigint","boolean","date","id","null","number","storage","string","timestamp"]),it=e=>e.column!==void 0,bn=(e,t)=>{switch(e){case"bigint":return`if (typeof ${t} !== "bigint") return DEFER;
|
|
19
|
+
`;case"boolean":return`if (typeof ${t} !== "boolean") return DEFER;
|
|
20
|
+
`;case"date":case"number":case"timestamp":return`if (typeof ${t} !== "number" || !Number.isFinite(${t})) return DEFER;
|
|
21
|
+
`;case"null":return`if (${t} !== null) return DEFER;
|
|
22
|
+
`;default:return`if (typeof ${t} !== "string") return DEFER;
|
|
23
|
+
`}},xn=(e,t)=>{const n=e.literalValue?.trim();if(!(n===void 0||!st.test(n)))return{out:t,pre:`if (${t} !== ${n}) return DEFER;
|
|
24
|
+
`}},We=(e,t,n)=>{if(!it(e)&&!(e.hasRefinement||e.sourceText!==void 0)){if(yn.has(e.kind))return e.kind==="any"?{out:t,pre:""}:{out:t,pre:bn(e.kind,t)};switch(e.kind){case"array":return kn(e,t,n);case"literal":return xn(e,t);case"object":return vn(e,t,n);default:return}}},kn=(e,t,n)=>{const{inner:r}=e;if(!r)return;const o=n.next(),s=`__arr${String(o)}`,i=`__i${String(o)}`,a=`__e${String(o)}`,c=We(r,a,n);if(!c)return;const d=`if (!Array.isArray(${t})) return DEFER;
|
|
25
|
+
const ${s} = new Array(${t}.length);
|
|
26
|
+
for (let ${i} = 0; ${i} < ${t}.length; ${i}++) {
|
|
27
|
+
const ${a} = ${t}[${i}];
|
|
28
|
+
${c.pre}${s}[${i}] = ${c.out};
|
|
29
29
|
}
|
|
30
|
-
`;return{out:
|
|
31
|
-
let ${
|
|
32
|
-
if (${
|
|
33
|
-
${
|
|
34
|
-
${
|
|
30
|
+
`;return{out:s,pre:d}},wn=(e,t,n,r)=>{const o=JSON.stringify(e);if(t.kind==="optional"){if(t.hasRefinement||t.sourceText!==void 0||it(t))return;const{inner:i}=t;if(!i)return;const a=We(i,n,r);if(!a)return;const c=r.next(),d=`__has${String(c)}`,p=`__val${String(c)}`,h=`let ${d} = false;
|
|
31
|
+
let ${p};
|
|
32
|
+
if (${n} !== undefined) {
|
|
33
|
+
${a.pre}${p} = ${a.out};
|
|
34
|
+
${d} = true;
|
|
35
35
|
}
|
|
36
|
-
`;return{entry:`...(${
|
|
37
|
-
${
|
|
38
|
-
`;return{out:i,pre:
|
|
36
|
+
`;return{entry:`...(${d} ? { ${o}: ${p} } : {})`,pre:h}}const s=We(t,n,r);if(s)return{entry:`${o}: ${s.out}`,pre:s.pre}},lt=(e,t,n)=>{let r="";const o=[];for(const s of Object.keys(e)){const i=e[s];if(!i)return;const a=wn(s,i,t(s),n);if(!a)return;r+=a.pre,o.push(a.entry)}return{entries:o.join(", "),pre:r}},vn=(e,t,n)=>{const r=e.shape??{},o=lt(r,c=>`${t}[${JSON.stringify(c)}]`,n);if(!o)return;const s=n.next(),i=`__obj${String(s)}`,a=`if (typeof ${t} !== "object" || ${t} === null || Array.isArray(${t})) return DEFER;
|
|
37
|
+
${o.pre}const ${i} = { ${o.entries} };
|
|
38
|
+
`;return{out:i,pre:a}},$n=e=>{let t=0;const r=lt(e,o=>`source[${JSON.stringify(o)}]`,{next:()=>(t+=1,t)});if(r)return`(source) => {
|
|
39
39
|
if (typeof source !== "object" || source === null || Array.isArray(source)) return DEFER;
|
|
40
|
-
${
|
|
41
|
-
}`},
|
|
40
|
+
${r.pre}return { ${r.entries} };
|
|
41
|
+
}`},R=`// GENERATED by @lunora/codegen — do not edit.
|
|
42
42
|
// Run \`lunora codegen\` to regenerate.
|
|
43
43
|
|
|
44
|
-
`,ne=(e=!1)=>e?{client:"lunorash/client",do:"lunorash/do",flags:"lunorash/flags",server:"lunorash/server",serverDataModel:"lunorash/server/data-model",serverDrizzle:"lunorash/server/drizzle",serverTypes:"lunorash/server/types",values:"lunorash/values"}:{client:"@lunora/client",do:"@lunora/do",flags:"@lunora/flags",server:"@lunora/server",serverDataModel:"@lunora/server/data-model",serverDrizzle:"@lunora/server/drizzle",serverTypes:"@lunora/server/types",values:"@lunora/values"},
|
|
45
|
-
`),t
|
|
46
|
-
${
|
|
44
|
+
`,ne=(e=!1)=>e?{client:"lunorash/client",do:"lunorash/do",flags:"lunorash/flags",server:"lunorash/server",serverDataModel:"lunorash/server/data-model",serverDrizzle:"lunorash/server/drizzle",serverTypes:"lunorash/server/types",values:"lunorash/values"}:{client:"@lunora/client",do:"@lunora/do",flags:"@lunora/flags",server:"@lunora/server",serverDataModel:"@lunora/server/data-model",serverDrizzle:"@lunora/server/drizzle",serverTypes:"@lunora/server/types",values:"@lunora/values"},ct=/^[A-Za-z_$][\w$]*$/u,Rn=/^[\w./-]+$/u,g=(e,t)=>{if(!ct.test(e))throw new te("INTERNAL",`@lunora/codegen: ${t} is not a valid JS identifier: ${JSON.stringify(e)}`)},qe=e=>e.charAt(0).toUpperCase()+e.slice(1),_=e=>ct.test(e)?e:JSON.stringify(e),Sn={any:"unknown",bigint:"bigint",boolean:"boolean",bytes:"ArrayBuffer",date:"number",geoPoint:"{ lat: number; lng: number }",null:"null",number:"number",storage:"string",string:"string",timestamp:"number"},Nn=e=>{if(e===void 0)return"unknown";if(!st.test(e))throw new te("INTERNAL",`@lunora/codegen: v.literal() argument is not a parseable string/number/boolean/null literal: ${JSON.stringify(e)}`);return e},N=e=>{const t=Sn[e.kind];if(t!==void 0)return t;switch(e.kind){case"array":return`Array<${e.inner?N(e.inner):"unknown"}>`;case"from":return e.tsType??"unknown";case"id":{const n=e.tableName??"_unknown_";return g(n,"v.id() table name"),`Id<"${n}">`}case"literal":return Nn(e.literalValue);case"object":return e.shape?`{ ${Object.entries(e.shape).map(([r,o])=>dt(r,o)).join("; ")} }`:"Record<string, unknown>";case"optional":return`${e.inner?N(e.inner):"unknown"} | undefined`;case"record":{const n=e.keyType?N(e.keyType):"string",r=e.valueType?N(e.valueType):"unknown";return`Record<${n}, ${r}>`}case"union":return e.members&&e.members.length>0?e.members.map(n=>N(n)).join(" | "):"never";default:return"unknown"}},dt=(e,t)=>{const n=_(e);if(t.kind==="optional"){const r=t.inner?N(t.inner):"unknown";return`${n}?: ${r}`}return`${n}: ${N(t)}`},xe=e=>{const t=Object.entries(e);return t.length===0?"{}":`{ ${t.map(([n,r])=>dt(n,r)).join("; ")} }`},ut=e=>e.kind==="optional"||!!e.column?.hasDefault,re=e=>e.kind==="optional"&&e.inner?e.inner:e,Tn=e=>{g(e.name,"table name");const t=Object.entries(e.shape).map(([r,o])=>{const s=re(o),i=N(s),a=_(r);return ut(o)?` ${a}?: ${i};`:` ${a}: ${i};`}).join(`
|
|
45
|
+
`),n=t?`
|
|
46
|
+
${t}
|
|
47
47
|
`:"";return`export interface Insert_${e.name} {
|
|
48
48
|
_id?: Id<"${e.name}">;
|
|
49
|
-
_creationTime?: number;${
|
|
49
|
+
_creationTime?: number;${n}}`},Ue="schema",qr=e=>{for(const u of e.tables)g(u.name,"table name");const t=e.tables.map(u=>`"${u.name}"`).join(" | ")||"never",n=e.tables.filter(u=>u.extensionKey===void 0).map(u=>`"${u.name}"`).join(" | ")||"never",r=e.tables.map(u=>{const l=Object.entries(u.shape).map(([k,w])=>{const v=_(k);if(w.kind==="optional"){const I=w.inner?N(w.inner):"unknown";return` ${v}?: ${I};`}return` ${v}: ${N(w)};`}).join(`
|
|
50
50
|
`),f=l?`
|
|
51
51
|
${l}
|
|
52
|
-
`:"";return`export interface Doc_${
|
|
53
|
-
_id: Id<"${
|
|
52
|
+
`:"";return`export interface Doc_${u.name} {
|
|
53
|
+
_id: Id<"${u.name}">;
|
|
54
54
|
_creationTime: number;${f}}`}).join(`
|
|
55
55
|
|
|
56
|
-
`),
|
|
57
|
-
`),
|
|
58
|
-
`),i=e.tables.map(
|
|
59
|
-
`),
|
|
60
|
-
`),
|
|
61
|
-
`),
|
|
56
|
+
`),o=e.tables.map(u=>` ${u.name}: Doc_${u.name};`).join(`
|
|
57
|
+
`),s=e.tables.map(u=>{const l=u.indexes.map(f=>JSON.stringify(f.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
|
|
58
|
+
`),i=e.tables.map(u=>{const l=u.searchIndexes.map(f=>JSON.stringify(f.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
|
|
59
|
+
`),a=e.tables.map(u=>{const l=u.rankIndexes.map(f=>JSON.stringify(f.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
|
|
60
|
+
`),c=e.tables.map(u=>{const l=u.shardMode==="global"?"":(u.geoIndexes??[]).map(f=>JSON.stringify(f.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
|
|
61
|
+
`),d=e.vectorIndexes.map(u=>JSON.stringify(u.name)).join(" | ")||"never",p=e.tables.map(u=>Tn(u)).join(`
|
|
62
62
|
|
|
63
|
-
`),
|
|
64
|
-
`),
|
|
65
|
-
`);return l?` ${
|
|
63
|
+
`),h=e.tables.map(u=>` ${u.name}: Insert_${u.name};`).join(`
|
|
64
|
+
`),y=e.tables.map(u=>{const l=u.relations.map(f=>(g(f.table,"relation target table"),` ${_(f.name)}: ${f.kind==="one"?"OneRelation":"ManyRelation"}<"${f.table}">;`)).join(`
|
|
65
|
+
`);return l?` ${u.name}: {
|
|
66
66
|
${l}
|
|
67
|
-
};`:` ${
|
|
68
|
-
`);return
|
|
67
|
+
};`:` ${u.name}: {};`}).join(`
|
|
68
|
+
`);return E(`${R}export type TableName = ${t};
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
71
|
* The tables **this app declared** — every {@link TableName} except those an add-on
|
|
@@ -82,14 +82,14 @@ ${l}
|
|
|
82
82
|
* const EXPORTED: readonly AppTableName[] = ["nodes", "tagColors"];
|
|
83
83
|
* \`\`\`
|
|
84
84
|
*/
|
|
85
|
-
export type AppTableName = ${
|
|
85
|
+
export type AppTableName = ${n};
|
|
86
86
|
|
|
87
87
|
export type Id<TName extends string> = string & { readonly __table: TName };
|
|
88
88
|
|
|
89
89
|
${r}
|
|
90
90
|
|
|
91
91
|
export interface DataModel {
|
|
92
|
-
${
|
|
92
|
+
${o}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
export type Doc<T extends keyof DataModel> = DataModel[T];
|
|
@@ -99,7 +99,7 @@ export type Doc<T extends keyof DataModel> = DataModel[T];
|
|
|
99
99
|
* Used by \`TableReader.withIndex()\` to constrain callers to declared names.
|
|
100
100
|
*/
|
|
101
101
|
export interface IndexNamesByTable {
|
|
102
|
-
${
|
|
102
|
+
${s}
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
export type IndexName<T extends keyof DataModel> = IndexNamesByTable[T];
|
|
@@ -113,26 +113,26 @@ export type SearchIndexName<T extends keyof DataModel> = SearchIndexNamesByTable
|
|
|
113
113
|
|
|
114
114
|
/** Per-table rank-index name union. \`never\` for tables without a rankIndex. */
|
|
115
115
|
export interface RankIndexNamesByTable {
|
|
116
|
-
${
|
|
116
|
+
${a}
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
export type RankIndexName<T extends keyof DataModel> = RankIndexNamesByTable[T];
|
|
120
120
|
|
|
121
121
|
/** Per-table geo-index name union. \`never\` for tables without a geoIndex. */
|
|
122
122
|
export interface GeoIndexNamesByTable {
|
|
123
|
-
${
|
|
123
|
+
${c}
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
export type GeoIndexName<T extends keyof DataModel> = GeoIndexNamesByTable[T];
|
|
127
127
|
|
|
128
128
|
/** Union of declared vector index names. \`never\` when none are declared. */
|
|
129
|
-
export type VectorIndexName = ${
|
|
129
|
+
export type VectorIndexName = ${d};
|
|
130
130
|
|
|
131
|
-
${
|
|
131
|
+
${p}
|
|
132
132
|
|
|
133
133
|
/** Per-table insert shape, accepted by \`ctx.db.<table>.insert(...)\`. */
|
|
134
134
|
export interface InsertModel {
|
|
135
|
-
${
|
|
135
|
+
${h}
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
export type Insert<T extends keyof DataModel> = InsertModel[T];
|
|
@@ -154,14 +154,14 @@ export interface ManyRelation<Target extends keyof DataModel> {
|
|
|
154
154
|
|
|
155
155
|
/** Per-table relation map keyed by accessor name. \`{}\` for tables with none. */
|
|
156
156
|
export interface Relations {
|
|
157
|
-
${
|
|
157
|
+
${y}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
`,Ue)},
|
|
161
|
-
`);return` ${_(
|
|
162
|
-
${
|
|
163
|
-
};`};return Qe(e).map(t
|
|
164
|
-
`)},
|
|
160
|
+
`,Ue)},An=/import\("(?<spec>(?:\.\.?\/)*_generated\/[^"]+)"\)/gu,pt=/^(?:\.\.?\/)*_generated\//u,mt=/\.[A-Za-z]\w*$/u,On=e=>e.replaceAll(An,(t,n)=>{const r=n.replace(pt,"./");return`import("${mt.test(r)?r:`${r}.js`}")`}),In=/import\("(?<spec>\.\.?\/[^"]+)"\)/gu,Cn=/^(?:\.\.?\/)+/u,Ln=e=>{const t=[];for(const n of e.split("/"))if(!(n===""||n===".")){if(n===".."&&t.length>0&&t.at(-1)!==".."){t.pop();continue}t.push(n)}return t.join("/")},_n=(e,t)=>e.replaceAll(In,(n,r)=>{if(pt.test(r.replace(Cn,"")))return n;const o=t.includes("/")?t.slice(0,t.lastIndexOf("/")):"",i=`../${Ln(`${o}/${r}`)}`;return`import("${mt.test(i)?i:`${i}.js`}")`}),E=(e,t)=>On(_n(e,t)),En=["client","do","errors","flags","observability","platform","ratelimit","runtime","server","values"],Dn=new RegExp(String.raw`import\("@lunora/(?<pkg>${En.join("|")})(?<subpath>/[^"]*)?"\)`,"gu"),Fn={flags:new Set(["/web"]),platform:new Set},ht=(e,t)=>t?e.replaceAll(Dn,(n,r,o)=>{const s=Fn[r];return o&&s&&!s.has(o)?n:`import("lunorash/${r}${o??""}")`}):e,Ke=e=>["Doc","Id"].filter(t=>new RegExp(String.raw`\b${t}<`,"u").test(e)),Pn=e=>e.output===void 0||e.output.kind==="any"?e.returnType:N(e.output),Qe=e=>{const t=new Map;for(const n of e){const r=t.get(n.filePath)??[];r.push(n),t.set(n.filePath,r)}return[...t.entries()].toSorted(([n],[r])=>n.localeCompare(r))},nt=e=>{const t=([n,r])=>{const o=r.toSorted((s,i)=>s.exportName.localeCompare(i.exportName)).map(s=>{const i=E(xe(s.args),s.filePath),a=E(Pn(s),s.filePath);return` ${s.exportName}: FunctionReference<"${s.kind}", ${i}, ${a}>;`}).join(`
|
|
161
|
+
`);return` ${_(S(n))}: {
|
|
162
|
+
${o}
|
|
163
|
+
};`};return Qe(e).map(n=>t(n)).join(`
|
|
164
|
+
`)},Mn=(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+=`
|
|
165
165
|
/** A typed reference to a durable workflow, addressable for \`cronJobs()\` targets. Mirrors \`@lunora/scheduler\`'s \`WorkflowReference\` structurally. */
|
|
166
166
|
export interface WorkflowReference<Params = Record<string, unknown>> {
|
|
167
167
|
readonly isLunoraWorkflow: true;
|
|
@@ -169,32 +169,32 @@ export interface WorkflowReference<Params = Record<string, unknown>> {
|
|
|
169
169
|
readonly binding: string;
|
|
170
170
|
readonly name: string;
|
|
171
171
|
}
|
|
172
|
-
`,e.length>0){const
|
|
173
|
-
`),i=
|
|
172
|
+
`,e.length>0){const o=[...e].toSorted((a,c)=>a.exportName.localeCompare(c.exportName)),s=o.map(a=>` ${a.exportName}: WorkflowReference<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${a.exportName}>>;`).join(`
|
|
173
|
+
`),i=o.map(a=>` ${a.exportName}: { isLunoraWorkflow: true, binding: ${JSON.stringify(a.bindingName)}, name: ${JSON.stringify(a.exportName)} },`).join(`
|
|
174
174
|
`);r+=`
|
|
175
175
|
/** This project's durable workflows, addressable as typed references (e.g. \`crons.daily("digest", …, workflows.digestPipeline, params)\`). */
|
|
176
176
|
export interface WorkflowsRef {
|
|
177
|
-
${
|
|
177
|
+
${s}
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
export const workflows: WorkflowsRef = {
|
|
181
181
|
${i}
|
|
182
182
|
};
|
|
183
|
-
`,
|
|
184
|
-
`)}if(
|
|
185
|
-
`),i=
|
|
183
|
+
`,n.push(`import type * as lunoraWorkflowDefinitions from "../workflows.js";
|
|
184
|
+
`)}if(t.length>0){const o=[...t].toSorted((a,c)=>a.exportName.localeCompare(c.exportName)),s=o.map(a=>` ${a.exportName}: WorkflowReference<AgentRunInput>;`).join(`
|
|
185
|
+
`),i=o.map(a=>` ${a.exportName}: { isLunoraWorkflow: true, binding: ${JSON.stringify(a.bindingName)}, name: ${JSON.stringify(a.name)} },`).join(`
|
|
186
186
|
`);r+=`
|
|
187
187
|
/** This project's durable agents, addressable as typed references for \`cronJobs()\` — each fire starts a fresh agent run (e.g. \`crons.daily("sweep", …, agents.support, { input, threadKey })\`). */
|
|
188
188
|
export interface AgentsRef {
|
|
189
|
-
${
|
|
189
|
+
${s}
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
export const agents: AgentsRef = {
|
|
193
193
|
${i}
|
|
194
194
|
};
|
|
195
|
-
`,
|
|
196
|
-
`)}return{block:r,importLine:
|
|
197
|
-
`,lines:i.map(
|
|
195
|
+
`,n.push(`import type { AgentRunInput } from "@lunora/agent";
|
|
196
|
+
`)}return{block:r,importLine:n.join("")}},Bn=()=>Object.keys(ot().functions).toSorted((e,t)=>e.localeCompare(t)),gt=e=>new Set(e.filter(t=>S(t.filePath)==="agents").map(t=>t.exportName)),jn=()=>new Set(Object.entries(ot().functions).filter(([,e])=>e.visibility==="internal").map(([e])=>e)),qn=(e,t)=>{const n={importLine:"",lines:"",prelude:""};if(e.length===0)return n;const r=gt(t),o=jn(),s=t.find(a=>S(a.filePath)==="agents"&&o.has(a.exportName));if(s)throw new te("INTERNAL",`@lunora/codegen: "agents:${s.exportName}" is reserved for the durable agent loop's internal dispatch — rename the "${s.exportName}" export in ${s.filePath}`);const i=Bn().filter(a=>!r.has(a));return i.length===0?n:{importLine:`import { agentComponent } from "@lunora/agent/component";
|
|
197
|
+
`,lines:i.map(a=>` "agents:${a}": lunoraAgentRuntimeFunctions.${a} as unknown as RegisteredLunoraFunction,`).join(`
|
|
198
198
|
`),prelude:`
|
|
199
199
|
/**
|
|
200
200
|
* The \`@lunora/agent\` runtime component — auto-registered because \`lunora/agents.ts\`
|
|
@@ -202,14 +202,14 @@ ${i}
|
|
|
202
202
|
* subscribe to the public queries (\`agents:agentMessages\` is the live thread view).
|
|
203
203
|
*/
|
|
204
204
|
const lunoraAgentRuntimeFunctions = agentComponent().functions;
|
|
205
|
-
`}},Wn=(e,
|
|
206
|
-
`,lines:' "sandbox:invoke": lunoraSandbox.invoke as unknown as RegisteredLunoraFunction,',prelude:"\n/**\n * The `@lunora/agent` sandbox dispatcher — auto-registered because `lunora/`\n * imports a sandbox tool (`browserTool`/`containerTool`). The batteries-included\n * tools dispatch to this internal action, which runs on an action ctx carrying\n * `ctx.browser` + `ctx.containers` (the durable tool step itself has neither).\n */\nconst lunoraSandbox = sandboxComponent();\n"}},Un=(e,
|
|
207
|
-
`);return` ${_(
|
|
208
|
-
${
|
|
205
|
+
`}},Wn=(e,t)=>{if(!e)return{importLine:"",lines:"",prelude:""};const n=t.find(r=>S(r.filePath)==="sandbox"&&r.exportName==="invoke");if(n)throw new te("INTERNAL",`@lunora/codegen: "sandbox:invoke" is reserved for the batteries-included sandbox tool dispatcher (browserTool/containerTool) — rename the "invoke" export in ${n.filePath}`);return{importLine:`import { sandboxComponent } from "@lunora/agent/component";
|
|
206
|
+
`,lines:' "sandbox:invoke": lunoraSandbox.invoke as unknown as RegisteredLunoraFunction,',prelude:"\n/**\n * The `@lunora/agent` sandbox dispatcher — auto-registered because `lunora/`\n * imports a sandbox tool (`browserTool`/`containerTool`). The batteries-included\n * tools dispatch to this internal action, which runs on an action ctx carrying\n * `ctx.browser` + `ctx.containers` (the durable tool step itself has neither).\n */\nconst lunoraSandbox = sandboxComponent();\n"}},Un=(e,t)=>{if(e.length===0)return[];const n=gt(t),r=[{args:{key:{kind:"string"},limit:{inner:{kind:"number"},kind:"optional"}},exportName:"agentMessages",filePath:"agents",kind:"query",returnType:"Record<string, unknown>[]"},{args:{decision:{kind:"union",members:[{kind:"literal",literalValue:'"approve"'},{kind:"literal",literalValue:'"reject"'}]},instanceId:{kind:"string"},note:{inner:{kind:"string"},kind:"optional"},threadKey:{kind:"string"},toolCallId:{kind:"string"}},exportName:"agentResolveApproval",filePath:"agents",kind:"mutation",returnType:"{ resolved: boolean }"},{args:{agent:{kind:"string"},input:{kind:"string"},threadKey:{kind:"string"},title:{inner:{kind:"string"},kind:"optional"}},exportName:"agentRun",filePath:"agents",kind:"mutation",returnType:"{ id: string; threadKey: string }"},{args:{key:{kind:"string"}},exportName:"agentState",filePath:"agents",kind:"query",returnType:"Record<string, unknown> | undefined"},{args:{key:{kind:"string"}},exportName:"agentThread",filePath:"agents",kind:"query",returnType:"Record<string, unknown> | undefined"}];for(const o of e)o.voice&&r.push({args:{threadKey:{kind:"string"}},exportName:`${o.exportName}Voice`,filePath:"agents",kind:"stream",returnType:"Record<string, unknown>"});return r.filter(o=>!n.has(o.exportName))},Kn=(e,t)=>{if(e.length===0)return[];const n=new Set(t.filter(r=>S(r.filePath)==="mutators").map(r=>r.exportName));return e.filter(r=>!n.has(r.exportName)).map(r=>({args:r.args,exportName:r.exportName,filePath:r.filePath,kind:"mutation",returnType:r.returnType}))},Qn=e=>{const t=e.filter(i=>i.stream);if(t.length===0)return{block:"",body:""};const n=Qe(t),r=n.map(([i,a])=>{const c=a.map(d=>{const p=E(d.chunkType??"unknown",d.filePath),h=E(xe(d.searchParams),d.filePath),y=E(xe(d.params),d.filePath);return` ${_(d.exportName)}: HttpStreamRef<${p}, ${h}, ${y}>;`}).join(`
|
|
207
|
+
`);return` ${_(S(i))}: {
|
|
208
|
+
${c}
|
|
209
209
|
};`}).join(`
|
|
210
|
-
`),
|
|
211
|
-
`);return` ${_(
|
|
212
|
-
${
|
|
210
|
+
`),o=n.map(([i,a])=>{const c=a.map(d=>` ${_(d.exportName)}: { method: ${JSON.stringify(d.method)}, path: ${JSON.stringify(d.path)} },`).join(`
|
|
211
|
+
`);return` ${_(S(i))}: {
|
|
212
|
+
${c}
|
|
213
213
|
},`}).join(`
|
|
214
214
|
`);return{block:`
|
|
215
215
|
/** This project's HTTP-SSE stream routes (\`httpRoute.<verb>(path).stream()\`), addressable as typed references for \`client.httpStream\` / \`useHttpStream\`. */
|
|
@@ -218,28 +218,28 @@ ${r}
|
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
export const httpStreams: HttpStreamsRef = {
|
|
221
|
-
${
|
|
221
|
+
${o}
|
|
222
222
|
};
|
|
223
|
-
`,body:r}},
|
|
224
|
-
${
|
|
225
|
-
${
|
|
223
|
+
`,body:r}},Wr=e=>{const{agents:t=[],functions:n,httpRoutes:r=[],mutators:o=[],useUmbrella:s=!1,workflows:i=[]}=e,a=ne(s),c=[...n.filter($=>$.visibility!=="internal"),...Un(t,n),...Kn(o,n)],d=n.filter($=>$.visibility==="internal"),p=nt(c),h=nt(d),y=Qn(r),u=`${p}
|
|
224
|
+
${h}
|
|
225
|
+
${y.body}`,l=Ke(u),f=l.length>0?`
|
|
226
226
|
import type { ${l.join(", ")} } from "./dataModel.js";
|
|
227
|
-
`:"",
|
|
227
|
+
`:"",k=p?`
|
|
228
|
+
${p}
|
|
229
|
+
`:"",w=h?`
|
|
228
230
|
${h}
|
|
229
|
-
`:"",k
|
|
230
|
-
${g}
|
|
231
|
-
`:"",v=Fn(i,n),L=`export interface ApiTypes {${x}}
|
|
231
|
+
`:"",v=Mn(i,t),I=`export interface ApiTypes {${k}}
|
|
232
232
|
|
|
233
233
|
export const api = anyApi as unknown as ApiTypes;
|
|
234
234
|
|
|
235
235
|
/** Internal functions — callable only server-side via \`ctx.run*\`, never from a client. */
|
|
236
|
-
export interface InternalApiTypes {${
|
|
236
|
+
export interface InternalApiTypes {${w}}
|
|
237
237
|
|
|
238
238
|
export const internal = anyApi as unknown as InternalApiTypes;
|
|
239
|
-
${v.block}${
|
|
240
|
-
`:"";return ht(`${
|
|
239
|
+
${v.block}${y.block}`,P=[...I.includes("FunctionReference<")?["FunctionReference"]:[],...y.block===""?[]:["HttpStreamRef"]],C=P.length>0?`import type { ${P.join(", ")} } from "${a.client}";
|
|
240
|
+
`:"";return ht(`${R}import { anyApi } from "${a.client}";
|
|
241
241
|
${C}${v.importLine}${f}
|
|
242
|
-
${
|
|
242
|
+
${I}`,s)},Ur=e=>e?`${R}import { createSeedClient as createSeedClientBase } from "@lunora/seed";
|
|
243
243
|
import type { SeedClient, SeedClientOptions } from "@lunora/seed";
|
|
244
244
|
|
|
245
245
|
import schema from "../schema.js";
|
|
@@ -256,9 +256,9 @@ import type { InsertModel } from "./dataModel.js";
|
|
|
256
256
|
* const { posts } = await seed.posts((x) => x([10, 20]));
|
|
257
257
|
*/
|
|
258
258
|
export const createSeedClient = (options?: SeedClientOptions): SeedClient<InsertModel> => createSeedClientBase<InsertModel>(schema, options);
|
|
259
|
-
`:"",
|
|
259
|
+
`:"",Kr=(e,t,n=!1)=>{if(e.length===0||!t)return"";const r=ne(n),o=c=>c.table===void 0?"Row":`Doc<${JSON.stringify(c.table)}> & Row`,s=e.map(c=>{g(c.exportName,"shape export name");const d=o(c),p=E(xe(c.args),c.filePath),h=Object.keys(c.args).length>0,y=h?` args: ${p};`:` args?: ${p};`,u=h?`(args: ${p}) => void`:`(args?: ${p}) => void`,l=`${c.exportName}CollectionOptions`;return`/** Options for the \`${c.exportName}\` shape binding. */
|
|
260
260
|
export interface ${qe(l)} {
|
|
261
|
-
${
|
|
261
|
+
${y}
|
|
262
262
|
/**
|
|
263
263
|
* Share the optimistic-overlay gate with other collections + mutators on this
|
|
264
264
|
* shard. Defaults to the shared per-shard registry, which is almost always what
|
|
@@ -268,7 +268,7 @@ ${b}
|
|
|
268
268
|
/** The Lunora client to subscribe through. */
|
|
269
269
|
client: LunoraClient;
|
|
270
270
|
/** Row key extractor — defaults to \`row._id\`. Override when the app keys rows by a natural column. */
|
|
271
|
-
getKey?: (row: ${
|
|
271
|
+
getKey?: (row: ${d}) => string;
|
|
272
272
|
/** \`"eager"\` starts syncing at creation; \`"lazy"\` (default) on the first subscriber. */
|
|
273
273
|
load?: "eager" | "lazy";
|
|
274
274
|
/** Notified when the underlying subscription errors; the collection always leaves \`loading\`. */
|
|
@@ -278,39 +278,39 @@ ${b}
|
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
/**
|
|
281
|
-
* Collection options for the \`${
|
|
281
|
+
* Collection options for the \`${c.exportName}\` replication shape: \`config\` for
|
|
282
282
|
* \`createCollection\`, plus the \`checkpoints\` registry to hand \`bindMutators\` and
|
|
283
283
|
* \`scope\` to re-point the subscription.
|
|
284
284
|
*/
|
|
285
|
-
export const ${
|
|
286
|
-
lunoraCollectionOptions<${
|
|
285
|
+
export const ${c.exportName}CollectionOptions = (options: ${qe(l)}): LunoraCollectionOptions<${d}> =>
|
|
286
|
+
lunoraCollectionOptions<${d}>({
|
|
287
287
|
client: options.client,
|
|
288
288
|
...(options.checkpoints === undefined ? {} : { checkpoints: options.checkpoints }),
|
|
289
289
|
...(options.getKey === undefined ? {} : { getKey: options.getKey }),
|
|
290
290
|
...(options.load === undefined ? {} : { load: options.load }),
|
|
291
291
|
...(options.onError === undefined ? {} : { onError: options.onError }),
|
|
292
292
|
...(options.shardKey === undefined ? {} : { shardKey: options.shardKey }),
|
|
293
|
-
shape: { args: options.args, name: ${JSON.stringify(
|
|
293
|
+
shape: { args: options.args, name: ${JSON.stringify(c.exportName)}, ...(options.shardKey === undefined ? {} : { shardKey: options.shardKey }) },
|
|
294
294
|
});
|
|
295
295
|
|
|
296
|
-
/** Live collection for the \`${
|
|
297
|
-
export const ${
|
|
296
|
+
/** Live collection for the \`${c.exportName}\` shape, with its sync controls. */
|
|
297
|
+
export const ${c.exportName}Collection = (
|
|
298
298
|
options: ${qe(l)},
|
|
299
|
-
): { checkpoints: CheckpointRegistry; collection: Collection<${
|
|
300
|
-
const { checkpoints, config, scope } = ${
|
|
299
|
+
): { checkpoints: CheckpointRegistry; collection: Collection<${d}, string>; scope: ${u} } => {
|
|
300
|
+
const { checkpoints, config, scope } = ${c.exportName}CollectionOptions(options);
|
|
301
301
|
|
|
302
302
|
return { checkpoints, collection: createCollection(config), scope };
|
|
303
303
|
};`}).join(`
|
|
304
304
|
|
|
305
|
-
`),i=Ke(
|
|
306
|
-
`:"";return`${
|
|
305
|
+
`),i=Ke(s),a=i.length>0?`import type { ${i.join(", ")} } from "./dataModel.js";
|
|
306
|
+
`:"";return`${R}import type { LunoraClient, SubscriptionError } from "${r.client}";
|
|
307
307
|
import { lunoraCollectionOptions } from "@lunora/db/collections";
|
|
308
308
|
import type { CheckpointRegistry, LunoraCollectionOptions, Row } from "@lunora/db";
|
|
309
309
|
import type { Collection } from "@tanstack/db";
|
|
310
310
|
import { createCollection } from "@tanstack/db";
|
|
311
|
+
${a}
|
|
311
312
|
${s}
|
|
312
|
-
${
|
|
313
|
-
`},Vn=(e,n)=>`lunora_${R(e)}_${String(n)}`,Hn=`const callRegistered = async <R>(context: CallerCtx, functionPath: string, args: Record<string, unknown> | undefined): Promise<R> => {
|
|
313
|
+
`},Hn=(e,t)=>`lunora_${S(e)}_${String(t)}`,Vn=`const callRegistered = async <R>(context: CallerCtx, functionPath: string, args: Record<string, unknown> | undefined): Promise<R> => {
|
|
314
314
|
const registered = LUNORA_FUNCTIONS[functionPath];
|
|
315
315
|
|
|
316
316
|
if (!registered) {
|
|
@@ -318,45 +318,45 @@ ${o}
|
|
|
318
318
|
}
|
|
319
319
|
|
|
320
320
|
return (await registered.handler(context, args ?? {})) as R;
|
|
321
|
-
};`,
|
|
322
|
-
`),
|
|
323
|
-
`),
|
|
324
|
-
`),
|
|
325
|
-
`),
|
|
326
|
-
`),
|
|
327
|
-
`),
|
|
328
|
-
`);return{dispatchBody:
|
|
329
|
-
${
|
|
321
|
+
};`,Gn=(e,t,n=[],r=[])=>{const o=new Map,s=l=>{o.has(l)||o.set(l,Hn(l,o.size))};for(const l of e)s(l.filePath);for(const l of t)s(l.filePath);for(const l of n)s(l.filePath);for(const l of r)s(l.filePath);const i=[...o.entries()].map(([l,f])=>{if(!Rn.test(l))throw new te("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(l)}`);return`import * as ${f} from "../${l}.js";`}).join(`
|
|
322
|
+
`),a=e.map(l=>` "${S(l.filePath)}:${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredLunoraFunction,`).join(`
|
|
323
|
+
`),c=t.map(l=>` ${JSON.stringify(l.id)}: ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredDataMigration,`).join(`
|
|
324
|
+
`),d=n.map(l=>` "${S(l.filePath)}:${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredLunoraFunction,`).join(`
|
|
325
|
+
`),p=r.map(l=>` "${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredShape,`).join(`
|
|
326
|
+
`),h=n.map(l=>`${S(l.filePath)}:${l.exportName}`),y=[a,d].filter(l=>l.length>0).join(`
|
|
327
|
+
`),u=e.map(l=>{if(l.lifecycle||Object.keys(l.args).length===0)return;const f=$n(l.args);return f===void 0?void 0:`installCompiledValidatorMap(${o.get(l.filePath)??""}.${l.exportName}.args, ${f});`}).filter(l=>l!==void 0).join(`
|
|
328
|
+
`);return{dispatchBody:y.length>0?`
|
|
329
|
+
${y}
|
|
330
330
|
`:"",importBlock:i.length>0?`${i}
|
|
331
331
|
|
|
332
|
-
`:"",installBlock:
|
|
333
|
-
${
|
|
334
|
-
`:"",mutatorPaths:
|
|
335
|
-
${
|
|
336
|
-
`:""}},
|
|
337
|
-
`);return` ${_(
|
|
338
|
-
${o}
|
|
339
|
-
};`}).join(`
|
|
340
|
-
`);return{implementation:n.map(([r,a])=>{const o=R(r),i=a.map(s=>` ${s.exportName}: (args) => callRegistered(context, "${o}:${s.exportName}", args),`).join(`
|
|
341
|
-
`);return` ${_(o)}: {
|
|
332
|
+
`:"",installBlock:u,migrationBody:c.length>0?`
|
|
333
|
+
${c}
|
|
334
|
+
`:"",mutatorPaths:h,shapeBody:p.length>0?`
|
|
335
|
+
${p}
|
|
336
|
+
`:""}},Jn=e=>{const t=Qe(e),n=t.map(([o,s])=>{const i=s.map(a=>{const c=E(xe(a.args),a.filePath),d=c==="{}"?"?":"",p=E(a.returnType,a.filePath);return a.kind==="stream"?` ${a.exportName}: (args${d}: ${c}) => Promise<AsyncIterable<${p}>>;`:` ${a.exportName}: (args${d}: ${c}) => Promise<${p}>;`}).join(`
|
|
337
|
+
`);return` ${_(S(o))}: {
|
|
342
338
|
${i}
|
|
339
|
+
};`}).join(`
|
|
340
|
+
`);return{implementation:t.map(([o,s])=>{const i=S(o),a=s.map(c=>` ${c.exportName}: (args) => callRegistered(context, "${i}:${c.exportName}", args),`).join(`
|
|
341
|
+
`);return` ${_(i)}: {
|
|
342
|
+
${a}
|
|
343
343
|
},`}).join(`
|
|
344
|
-
`),types:
|
|
345
|
-
`:"",
|
|
346
|
-
readonly ai: LunoraAi;`:"",B=
|
|
347
|
-
`:"",
|
|
348
|
-
readonly payments: LunoraPayment;`:"",
|
|
344
|
+
`),types:n}},zn=(e,t=[])=>{const n=new Set;for(const r of e.tables)for(const o of Object.values(r.shape)){const s=re(o);s.kind==="storage"&&typeof s.bucket=="string"&&s.bucket!==""&&n.add(s.bucket)}for(const r of t)r!==""&&r!=="default"&&n.add(r);return["default",...[...n].toSorted((r,o)=>r.localeCompare(o))]},Qr=({agents:e=[],containers:t=[],env:n,hasAccessFacade:r=!1,hasAi:o=!1,hasAnalytics:s=!1,hasBrowser:i=!1,hasFlags:a=!1,hasHyperdrive:c=!1,hasImages:d=!1,hasKv:p=!1,hasNotify:h=!1,hasPayments:y=!1,hasPipelines:u=!1,hasR2sql:l=!1,hasX402:f=!1,identity:k,queues:w=[],schema:v,storageRuleBuckets:I=[],useUmbrella:P=!1,workflows:C=[]}={})=>{const $=ne(P),x=zn(v??{tables:[]},I).map(m=>JSON.stringify(m)).join(" | "),M=o?`import type { LunoraAi } from "@lunora/ai";
|
|
345
|
+
`:"",oe=o?`
|
|
346
|
+
readonly ai: LunoraAi;`:"",B=y?`import type { LunoraPayment } from "@lunora/payment";
|
|
347
|
+
`:"",ae=y?`
|
|
348
|
+
readonly payments: LunoraPayment;`:"",se=f?`import type { X402Pay } from "@lunora/x402/pay";
|
|
349
349
|
`:"",W=f?`
|
|
350
|
-
readonly x402: X402Pay;`:"",
|
|
351
|
-
`:"",
|
|
352
|
-
readonly containers: {${
|
|
353
|
-
readonly ${
|
|
354
|
-
};`:"",O=[...
|
|
355
|
-
readonly ${
|
|
356
|
-
readonly ${
|
|
357
|
-
readonly ${
|
|
358
|
-
readonly ${
|
|
359
|
-
`),
|
|
350
|
+
readonly x402: X402Pay;`:"",A=t.length>0?`import type { ContainerAccessor } from "@lunora/container";
|
|
351
|
+
`:"",X=t.length>0?`
|
|
352
|
+
readonly containers: {${t.map(m=>`
|
|
353
|
+
readonly ${m.exportName}: ContainerAccessor;`).join("")}
|
|
354
|
+
};`:"",O=[...o?[" /** Workers AI binding (the conventional `env.AI`), narrowing `ctx.ai`. */\n readonly AI?: unknown;"]:[],...t.map(m=>(g(m.bindingName,`container binding "${m.bindingName}"`),` /** Durable Object namespace for the \`${m.exportName}\` container. */
|
|
355
|
+
readonly ${m.bindingName}?: unknown;`)),...C.map(m=>(g(m.bindingName,`workflow binding "${m.bindingName}"`),` /** Workflow binding for the \`${m.exportName}\` workflow. */
|
|
356
|
+
readonly ${m.bindingName}?: unknown;`)),...w.map(m=>(g(m.bindingName,`queue binding "${m.bindingName}"`),` /** Queue producer binding for the \`${m.exportName}\` queue. */
|
|
357
|
+
readonly ${m.bindingName}?: unknown;`)),...e.map(m=>(g(m.bindingName,`agent binding "${m.bindingName}"`),` /** Workflow binding for the \`${m.exportName}\` agent. */
|
|
358
|
+
readonly ${m.bindingName}?: unknown;`))].join(`
|
|
359
|
+
`),L=`
|
|
360
360
|
|
|
361
361
|
/**
|
|
362
362
|
* This project's Cloudflare bindings, as far as codegen can discover them from
|
|
@@ -374,21 +374,21 @@ ${O}`:""}
|
|
|
374
374
|
}
|
|
375
375
|
|
|
376
376
|
/** Alias for {@link CloudflareBindings} — the typed shape of \`env\`. */
|
|
377
|
-
export type Env = CloudflareBindings;`,j=(
|
|
378
|
-
readonly vectors: VectorSearch<VectorIndexName>;`:"",
|
|
379
|
-
readonly vectors: VectorSearchReader<VectorIndexName>;`:"",
|
|
377
|
+
export type Env = CloudflareBindings;`,j=(m,Me)=>Me?fn.get(m)?.field??"":"",ie=j("kv",p),le=j("analytics",s),Se=j("hyperdrive",c),Ne=j("browser",i),Te=j("images",d),ce=j("pipelines",u),H=j("r2sql",l),F=(v?.vectorIndexes.length??0)>0,V=F?' | "vectors"':"",Z=F?`
|
|
378
|
+
readonly vectors: VectorSearch<VectorIndexName>;`:"",de=F?`
|
|
379
|
+
readonly vectors: VectorSearchReader<VectorIndexName>;`:"",G=F?`import type { VectorSearch, VectorSearchReader } from "${$.server}";
|
|
380
380
|
import type { VectorIndexName } from "./dataModel.js";
|
|
381
381
|
`:"",U=r?`
|
|
382
382
|
/** Verified Cloudflare Access identity — a synchronous facade over the resolved claims (email / groups / hasGroup / claims). Anonymous when no Access token is present. */
|
|
383
|
-
readonly access: import("@lunora/cloudflare-access/context").AccessFacade;`:"",K=
|
|
383
|
+
readonly access: import("@lunora/cloudflare-access/context").AccessFacade;`:"",K=a?`
|
|
384
384
|
/** Feature-flag evaluation (OpenFeature). Reads are memoized per request; evaluations never throw — a provider error resolves to the supplied default. */
|
|
385
|
-
readonly flags: import("${$.flags}").LunoraFlags;`:"",Q=
|
|
385
|
+
readonly flags: import("${$.flags}").LunoraFlags;`:"",Q=h?`
|
|
386
386
|
/** 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. */
|
|
387
387
|
readonly notify: import("@lunora/notify").LunoraNotify;
|
|
388
388
|
/** Device push sub-facade — the same object as ctx.notify.push (register / send / broadcast). Sends belong in action handlers. */
|
|
389
389
|
readonly push: import("@lunora/notify").LunoraPush;`:"",q=C.length>0,ee=q?`import type { WorkflowHandle } from "@lunora/workflow";
|
|
390
390
|
import type * as lunoraWorkflowDefinitions from "../workflows.js";
|
|
391
|
-
`:"",
|
|
391
|
+
`:"",Ae=q?`
|
|
392
392
|
|
|
393
393
|
/** Params type carried by a \`defineWorkflow\` definition (its phantom \`__params\`). */
|
|
394
394
|
type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params }
|
|
@@ -399,43 +399,43 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
|
|
|
399
399
|
|
|
400
400
|
/** This project's declared workflows, addressable from \`ctx.workflows\` by their \`lunora/workflows.ts\` export name. */
|
|
401
401
|
export interface LunoraWorkflows {
|
|
402
|
-
${C.map(
|
|
402
|
+
${C.map(m=>` get(name: ${JSON.stringify(m.exportName)}): WorkflowHandle<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${m.exportName}>>;`).join(`
|
|
403
403
|
`)}
|
|
404
|
-
}`:"",
|
|
405
|
-
readonly workflows: LunoraWorkflows;`:"",ue=
|
|
404
|
+
}`:"",ke=q?' | "workflows"':"",we=q?`
|
|
405
|
+
readonly workflows: LunoraWorkflows;`:"",ue=w.length>0,Oe=ue?`import type { QueueProducer } from "@lunora/queue";
|
|
406
406
|
import type * as lunoraQueueDefinitions from "../queues.js";
|
|
407
|
-
`:"",
|
|
407
|
+
`:"",Ie=ue?`
|
|
408
408
|
|
|
409
409
|
/** Message body type carried by a \`defineQueue\` definition (its phantom \`__lunoraBody\`). */
|
|
410
410
|
type QueueBodyOf<Definition> = Definition extends { __lunoraBody?: infer Body } ? (unknown extends Body ? unknown : NonNullable<Body>) : unknown;
|
|
411
411
|
|
|
412
412
|
/** This project's declared queues, addressable from \`ctx.queues\` by their \`lunora/queues.ts\` export name. */
|
|
413
413
|
export interface LunoraQueues {
|
|
414
|
-
${
|
|
414
|
+
${w.map(m=>` readonly ${m.exportName}: QueueProducer<QueueBodyOf<typeof lunoraQueueDefinitions.${m.exportName}>>;`).join(`
|
|
415
415
|
`)}
|
|
416
416
|
}`:"",ve=ue?`
|
|
417
417
|
readonly queues: LunoraQueues;`:"",pe=e.length>0,Ce=pe?`import type { AgentHandle } from "@lunora/agent";
|
|
418
|
-
`:"",
|
|
418
|
+
`:"",Le=pe?`
|
|
419
419
|
|
|
420
420
|
/** This project's declared agents, addressable from \`ctx.agents\` by their \`lunora/agents.ts\` export name. */
|
|
421
421
|
export interface LunoraAgents {
|
|
422
|
-
${e.map(
|
|
422
|
+
${e.map(m=>(g(m.exportName,`agent export "${m.exportName}"`),` readonly ${m.exportName}: AgentHandle;`)).join(`
|
|
423
423
|
`)}
|
|
424
424
|
}`:"",$e=pe?`
|
|
425
|
-
readonly agents: LunoraAgents;`:"",_e=
|
|
425
|
+
readonly agents: LunoraAgents;`:"",_e=k?`import type { InferIdentity } from "${$.server}";
|
|
426
426
|
import type * as lunoraIdentityContract from "../identity.js";
|
|
427
|
-
`:"",
|
|
427
|
+
`:"",Ee=k?`
|
|
428
428
|
|
|
429
429
|
/** This app's declared identity claim contract (\`defineIdentity\` in \`lunora/identity.ts\`) — the typed shape of \`ctx.auth.getIdentity()\`, the RLS policy \`ctx.auth.identity\`, and the \`authorizeShard\`/\`authorizeFanOut\` identity argument. */
|
|
430
|
-
export type Identity = InferIdentity<typeof lunoraIdentityContract.${
|
|
430
|
+
export type Identity = InferIdentity<typeof lunoraIdentityContract.${k.exportName}>;
|
|
431
431
|
|
|
432
432
|
/** \`ctx.auth\` narrowed so \`getIdentity()\` resolves the declared {@link Identity} contract instead of the untyped claim bag. */
|
|
433
|
-
type NarrowedAuth = Omit<QueryCtxBase["auth"], "getIdentity"> & { getIdentity: () => Promise<Identity | null> };`:"",
|
|
434
|
-
readonly auth: NarrowedAuth;`:"",
|
|
435
|
-
`:"",
|
|
433
|
+
type NarrowedAuth = Omit<QueryCtxBase["auth"], "getIdentity"> & { getIdentity: () => Promise<Identity | null> };`:"",me=k?' | "auth"':"",he=k?`
|
|
434
|
+
readonly auth: NarrowedAuth;`:"",De=k?", Identity":"",Fe=n?`import type * as lunoraEnvContract from "../env.js";
|
|
435
|
+
`:"",Pe=n?`
|
|
436
436
|
|
|
437
437
|
/** This app's declared env contract (\`defineEnv\` in \`lunora/env.ts\`) — the validated, coercion-aware shape of \`ctx.env\`. */
|
|
438
|
-
export type LunoraEnv = ReturnType<typeof lunoraEnvContract.${
|
|
438
|
+
export type LunoraEnv = ReturnType<typeof lunoraEnvContract.${n.exportName}>;`:"",ge=n?' | "env"':"",fe=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`${R}import { createPolicyDsl, defineMutator as defineMutatorBase, initLunora, v as vBase } from "${$.server}";
|
|
439
439
|
import type {
|
|
440
440
|
ActionBuilder,
|
|
441
441
|
ActionCtx as ActionCtxBase,
|
|
@@ -491,7 +491,7 @@ export type {
|
|
|
491
491
|
} from "${$.serverDataModel}";
|
|
492
492
|
|
|
493
493
|
import type { DataModel, Doc, GeoIndexNamesByTable, Id as IdOfTable, IndexNamesByTable, Insert, InsertModel, RankIndexNamesByTable, Relations, SearchIndexNamesByTable, TableName } from "./dataModel.js";
|
|
494
|
-
${
|
|
494
|
+
${G}${M}${B}${se}${A}${ee}${Oe}${Ce}${_e}${Fe}
|
|
495
495
|
export type { AppTableName, DataModel, Doc, Id, TableName } from "./dataModel.js";
|
|
496
496
|
|
|
497
497
|
/**
|
|
@@ -551,7 +551,7 @@ export interface OrmWriter extends OrmReader {
|
|
|
551
551
|
}
|
|
552
552
|
|
|
553
553
|
/** Storage buckets this schema declares (\`v.storage("name")\`), narrowing \`ctx.storage.bucket(name)\`. */
|
|
554
|
-
export type StorageBucketName = ${
|
|
554
|
+
export type StorageBucketName = ${x};${L}${Ae}${Ie}${Le}${Ee}${Pe}
|
|
555
555
|
|
|
556
556
|
/**
|
|
557
557
|
* Project-typed contexts. The base contexts from \`@lunora/server\` are
|
|
@@ -614,22 +614,22 @@ type AsIdTable<T extends string> = T extends TableName ? T : string extends T ?
|
|
|
614
614
|
*/
|
|
615
615
|
type TypedAsId = <T extends string>(tableName: AsIdTable<T>, id: string) => IdOfTable<T & TableName>;
|
|
616
616
|
|
|
617
|
-
export interface QueryCtx extends Omit<QueryCtxBase, "db" | "storage"${
|
|
617
|
+
export interface QueryCtx extends Omit<QueryCtxBase, "db" | "storage"${V}${me}${ge}> {
|
|
618
618
|
readonly db: Omit<DatabaseReader, "asId" | "query" | "get"> & DatabaseReaderFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
|
|
619
619
|
readonly orm: OrmReader;
|
|
620
|
-
readonly storage: ReadOnlyStorage<StorageBucketName>;${
|
|
620
|
+
readonly storage: ReadOnlyStorage<StorageBucketName>;${de}${U}${ie}${K}${Q}${le}${fe}${he}
|
|
621
621
|
}
|
|
622
622
|
|
|
623
|
-
export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${
|
|
623
|
+
export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${V}${ke}${me}${ge}> {
|
|
624
624
|
readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
|
|
625
625
|
readonly orm: OrmWriter;
|
|
626
|
-
readonly storage: ReadOnlyStorage<StorageBucketName>;${Z}${U}${
|
|
626
|
+
readonly storage: ReadOnlyStorage<StorageBucketName>;${Z}${U}${ie}${K}${Q}${le}${fe}${we}${ve}${$e}${he}
|
|
627
627
|
}
|
|
628
628
|
|
|
629
|
-
export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${
|
|
629
|
+
export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${V}${ke}${me}${ge}> {
|
|
630
630
|
readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
|
|
631
631
|
readonly orm: OrmWriter;
|
|
632
|
-
readonly storage: StorageBase<StorageBucketName>;${Z}${U}${
|
|
632
|
+
readonly storage: StorageBase<StorageBucketName>;${Z}${U}${oe}${ae}${W}${X}${ie}${K}${Q}${Se}${Ne}${Te}${le}${ce}${H}${fe}${we}${ve}${$e}${he}
|
|
633
633
|
}
|
|
634
634
|
|
|
635
635
|
/**
|
|
@@ -687,7 +687,7 @@ export const defineMutator = defineMutatorBase as unknown as <Args extends Recor
|
|
|
687
687
|
* Runtime-identical to \`@lunora/server\`'s \`definePolicy\`; only the types narrow,
|
|
688
688
|
* so the \`rls()\` chain discovers a policy authored either way the same.
|
|
689
689
|
*/
|
|
690
|
-
export const definePolicy = createPolicyDsl<DataModel, Relations${
|
|
690
|
+
export const definePolicy = createPolicyDsl<DataModel, Relations${De}>();
|
|
691
691
|
|
|
692
692
|
/**
|
|
693
693
|
* The validator builder \`v\`, with \`v.id(...)\` constrained to THIS schema's
|
|
@@ -704,13 +704,13 @@ export const definePolicy = createPolicyDsl<DataModel, Relations${Ee}>();
|
|
|
704
704
|
export const v = vBase as unknown as Omit<typeof vBase, "id"> & {
|
|
705
705
|
id: <T extends TableName>(table: T) => ColumnValidator<IdOfTable<T>, IdOfTable<T>>;
|
|
706
706
|
};
|
|
707
|
-
`},
|
|
708
|
-
`);let
|
|
707
|
+
`},Yn=e=>{const t={connect:[],disconnect:[]};for(const n of e)n.lifecycle&&t[n.lifecycle].push(`${S(n.filePath)}:${n.exportName}`);return t},Hr=e=>{const{agents:t=[],functions:n,migrations:r=[],mutators:o=[],shapes:s=[],useUmbrella:i=!1,usesSandbox:a=!1}=e,c=n.length>0,d=ne(i),{dispatchBody:p,importBlock:h,installBlock:y,migrationBody:u,mutatorPaths:l,shapeBody:f}=Gn(n,r,o,s),k=qn(t,n),w=Wn(a,n),v=[k.lines,w.lines].filter(L=>L.length>0).join(`
|
|
708
|
+
`);let I=p;v.length>0&&(I=p.length>0?`${p.trimEnd()}
|
|
709
709
|
${v}
|
|
710
710
|
`:`
|
|
711
711
|
${v}
|
|
712
|
-
`);const
|
|
713
|
-
`:"",$=
|
|
712
|
+
`);const P=Yn(n),C=s.length>0?`import type { RegisteredShape } from "${d.server}";
|
|
713
|
+
`:"",$=s.length>0?`
|
|
714
714
|
/**
|
|
715
715
|
* Replication-shape registry — one entry per \`defineShape\` in \`lunora/shapes.ts\`.
|
|
716
716
|
* The generated ShardDO's \`resolveShape\` override looks a shape up by name and
|
|
@@ -718,31 +718,31 @@ ${v}
|
|
|
718
718
|
* \`shape_subscribe\` (reads-as-permissions).
|
|
719
719
|
*/
|
|
720
720
|
export const LUNORA_SHAPES: Record<string, RegisteredShape> = {${f}};
|
|
721
|
-
`:"",
|
|
721
|
+
`:"",x=l.length>0?`
|
|
722
722
|
/**
|
|
723
723
|
* Custom-mutator function paths — the \`LUNORA_FUNCTIONS\` keys the generated
|
|
724
724
|
* ShardDO's \`isCustomMutator\` override routes through the client-watermark push
|
|
725
725
|
* protocol (\`x-lunora-client-id\`/\`x-lunora-client-seq\` ordering).
|
|
726
726
|
*/
|
|
727
|
-
export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${l.map(
|
|
728
|
-
`:"",
|
|
729
|
-
`:"",
|
|
727
|
+
export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${l.map(L=>JSON.stringify(L)).join(", ")}]);
|
|
728
|
+
`:"",M=y.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${d.values}";
|
|
729
|
+
`:"",oe=y.length>0?`
|
|
730
730
|
/**
|
|
731
731
|
* AOT-compiled argument validators (Worker-safe, no \`eval\`). Each is installed
|
|
732
732
|
* onto its function's live \`.args\` object and consulted by the interpreted
|
|
733
733
|
* parser as a zero-allocation fast path; anything it can't model is deferred.
|
|
734
734
|
*/
|
|
735
|
-
${
|
|
736
|
-
`:"",B=
|
|
735
|
+
${y}
|
|
736
|
+
`:"",B=Jn(n),ae=B.types?`
|
|
737
737
|
${B.types}
|
|
738
|
-
`:"",
|
|
738
|
+
`:"",se=B.implementation?`
|
|
739
739
|
${B.implementation}
|
|
740
|
-
`:"",W=Ke(B.types),
|
|
741
|
-
`:"",
|
|
740
|
+
`:"",W=Ke(B.types),A=W.length>0?`import type { ${W.join(", ")} } from "./dataModel.js";
|
|
741
|
+
`:"",X=c?"context":"_context",O=c?`${Vn}
|
|
742
742
|
|
|
743
|
-
`:"";return ht(`${
|
|
743
|
+
`:"";return ht(`${R}${h}${k.importLine}${w.importLine}${M}${C}import { LunoraError } from "${d.server}";
|
|
744
744
|
import type { ActionCtx, MutationCtx, QueryCtx } from "./server.js";
|
|
745
|
-
${
|
|
745
|
+
${A}
|
|
746
746
|
/**
|
|
747
747
|
* Single registered function, narrowed to the shape \`handleRpc\` needs.
|
|
748
748
|
* The real argument validators / return types are checked elsewhere — at
|
|
@@ -767,13 +767,13 @@ export interface RegisteredLunoraFunction {
|
|
|
767
767
|
/** \`"internal"\` functions are rejected on the external RPC path; absence === public. */
|
|
768
768
|
visibility?: "internal" | "public";
|
|
769
769
|
}
|
|
770
|
-
${
|
|
770
|
+
${k.prelude}${w.prelude}
|
|
771
771
|
/**
|
|
772
772
|
* Static dispatch table. The key matches the \`__lunoraRef\` the client
|
|
773
773
|
* emits (\`api[namespace][fn].__lunoraRef === "namespace:fn"\`).
|
|
774
774
|
*/
|
|
775
|
-
export const LUNORA_FUNCTIONS: Record<string, RegisteredLunoraFunction> = {${
|
|
776
|
-
${
|
|
775
|
+
export const LUNORA_FUNCTIONS: Record<string, RegisteredLunoraFunction> = {${I}};
|
|
776
|
+
${oe}${$}${x}
|
|
777
777
|
/**
|
|
778
778
|
* Connection-lifecycle manifest: the function paths the generated ShardDO
|
|
779
779
|
* dispatches when a client's WebSocket connects (\`connect\`) or disconnects
|
|
@@ -781,8 +781,8 @@ ${ae}${$}${w}
|
|
|
781
781
|
* DO runs every hook under the socket's verified identity via system dispatch.
|
|
782
782
|
*/
|
|
783
783
|
export const LUNORA_LIFECYCLE_HOOKS: { connect: readonly string[]; disconnect: readonly string[] } = {
|
|
784
|
-
connect: [${
|
|
785
|
-
disconnect: [${
|
|
784
|
+
connect: [${P.connect.map(L=>JSON.stringify(L)).join(", ")}],
|
|
785
|
+
disconnect: [${P.disconnect.map(L=>JSON.stringify(L)).join(", ")}],
|
|
786
786
|
};
|
|
787
787
|
|
|
788
788
|
/**
|
|
@@ -813,10 +813,10 @@ export type CallerCtx = ActionCtx | MutationCtx | QueryCtx;
|
|
|
813
813
|
* with the supplied \`context\`, exactly like \`ctx.runQuery\`/\`runMutation\`/
|
|
814
814
|
* \`runAction\` but without re-stating the function path.
|
|
815
815
|
*/
|
|
816
|
-
export interface Caller {${
|
|
816
|
+
export interface Caller {${ae}}
|
|
817
817
|
|
|
818
818
|
${O}/** Build a {@link Caller} bound to \`context\` (typically a handler's \`ctx\`). */
|
|
819
|
-
export const createCaller = (${
|
|
819
|
+
export const createCaller = (${X}: CallerCtx): Caller => ({${se}});
|
|
820
820
|
|
|
821
821
|
/**
|
|
822
822
|
* Single registered data migration, narrowed to the shape the per-shard runner
|
|
@@ -835,8 +835,8 @@ export interface RegisteredDataMigration {
|
|
|
835
835
|
* Registry of online data migrations keyed by \`defineMigration\`'s \`id\`. The
|
|
836
836
|
* shard DO's admin RPC and the CLI resolve migrations to run through this map.
|
|
837
837
|
*/
|
|
838
|
-
export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${
|
|
839
|
-
`,i)},
|
|
838
|
+
export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${u}};
|
|
839
|
+
`,i)},Xn=e=>{const t={};for(const n of e.tables){const r={};for(const[o,s]of Object.entries(n.shape)){const i=re(s);i.kind==="id"&&i.tableName!==void 0&&(r[o]=i.tableName)}Object.keys(r).length>0&&(t[n.name]=r)}return t},Zn=e=>{const t={};for(const n of e.tables){const r=[];for(const[o,s]of Object.entries(n.shape))re(s).kind==="storage"&&r.push(o);r.length>0&&(t[n.name]=r)}return t},er=e=>{const t={};for(const n of e.tables){const r=[...n.indexes.map(o=>({fields:[...o.fields],name:o.name,type:"index",...o.unique===!0?{unique:!0}:{}})),...n.searchIndexes.map(o=>({fields:[o.field,...o.filterFields??[]],name:o.name,type:"search"})),...(n.geoIndexes??[]).map(o=>({fields:[o.field],name:o.name,type:"geo"})),...n.rankIndexes.map(o=>({fields:o.sortBy.map(s=>s.field),name:o.name,type:"rank"})),...n.vectorIndexes.map(o=>({fields:o.field===void 0?[]:[o.field],name:o.name,type:"vector"}))];r.length>0&&(t[n.name]=r)}return t},tr=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},nr=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[o,s]of Object.entries(n.shape)){const i=ut(s),a=re(s),c={name:o,optional:i,type:a.kind};a.kind==="id"&&a.tableName!==void 0&&(c.ref=a.tableName),a.kind==="storage"&&(c.isStorage=!0),r.push(c)}t[n.name]=r}return t},rr=e=>e?{importFragment:"serveRelationFanout, ",override:`
|
|
840
840
|
protected override async runRelationFanoutRead(functionPath: string, args: Record<string, unknown>): Promise<unknown> {
|
|
841
841
|
this.ensureMigrated();
|
|
842
842
|
|
|
@@ -844,7 +844,7 @@ export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${c}}
|
|
|
844
844
|
|
|
845
845
|
return serveRelationFanout(schema as unknown as SchemaLike, db, functionPath, args);
|
|
846
846
|
}
|
|
847
|
-
`}:{importFragment:"",override:""},
|
|
847
|
+
`}:{importFragment:"",override:""},or=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:`
|
|
848
848
|
const aiBinding = config.ai?.(env) ?? (env as Record<string, unknown>).AI;
|
|
849
849
|
// Correlate AI-Gateway-routed calls with the Lunora trace: thread the
|
|
850
850
|
// function path + trace id into createAi, which folds them into the
|
|
@@ -861,64 +861,64 @@ export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${c}}
|
|
|
861
861
|
ai,`,stub:`
|
|
862
862
|
const aiStub: LunoraAi = {
|
|
863
863
|
embeddingModel: () => {
|
|
864
|
-
${
|
|
864
|
+
${t}
|
|
865
865
|
},
|
|
866
866
|
model: () => {
|
|
867
|
-
${
|
|
867
|
+
${t}
|
|
868
868
|
},
|
|
869
869
|
run: async () => {
|
|
870
|
-
${
|
|
870
|
+
${t}
|
|
871
871
|
},
|
|
872
872
|
// workersai is a callable-with-properties; a bare throwing arrow isn't
|
|
873
873
|
// structurally assignable, so cast it. Never invoked (the stub throws first).
|
|
874
874
|
workersai: (() => {
|
|
875
|
-
${
|
|
875
|
+
${t}
|
|
876
876
|
}) as unknown as LunoraAi["workersai"],
|
|
877
877
|
};
|
|
878
|
-
`}},
|
|
879
|
-
${
|
|
878
|
+
`}},T=(e,t,n,{cast:r="",sync:o=[]}={})=>{const s=n.map(i=>` ${i}: ${o.includes(i)?"":"async "}() => {
|
|
879
|
+
${t}
|
|
880
880
|
},`).join(`
|
|
881
881
|
`);return`
|
|
882
882
|
const ${e} = {
|
|
883
|
-
${
|
|
883
|
+
${s}
|
|
884
884
|
}${r};
|
|
885
|
-
`},
|
|
885
|
+
`},D={build:"",configField:"",contextField:"",importLines:[],stub:""},ar=e=>e?{build:`
|
|
886
886
|
const kvBinding = config.kv?.(env) ?? (env as Record<string, unknown>).KV;
|
|
887
887
|
const kv: Kv = kvBinding ? createKv({ namespace: kvBinding as KVNamespaceLike }) : kvStub;
|
|
888
888
|
`,configField:`
|
|
889
889
|
kv?: (env: Record<string, unknown>) => KVNamespaceLike;`,contextField:`
|
|
890
|
-
kv,`,importLines:['import type { Kv, KVNamespaceLike } from "@lunora/bindings/kv";','import { createKv } from "@lunora/bindings/kv";'],stub:
|
|
891
|
-
const flags: import("${
|
|
890
|
+
kv,`,importLines:['import type { Kv, KVNamespaceLike } from "@lunora/bindings/kv";','import { createKv } from "@lunora/bindings/kv";'],stub:T("kvStub: Kv",'throw new Error("ctx.kv: no KV binding found. Add a \\`kv_namespaces\\` binding (env.KV) to wrangler.jsonc, or pass \\`kv\\` to createShardDO().");',["delete","get","getRaw","getWithMetadata","list","put"])}:D,sr=(e,t)=>e?{build:`
|
|
891
|
+
const flags: import("${t}").LunoraFlags = createFlags({
|
|
892
892
|
hooks: flagsConfig.hooks,
|
|
893
893
|
logger: flagsConfig.logger,
|
|
894
894
|
provider: () => config.flags?.(env) ?? flagsConfig.provider(env),
|
|
895
895
|
targetingKey: () => flagsConfig.identify?.({ identity: identity ?? null, userId: userId ?? null }),
|
|
896
896
|
});
|
|
897
897
|
`,configField:`
|
|
898
|
-
flags?: (env: Record<string, unknown>) => import("${
|
|
899
|
-
flags,`,importLines:[`import { createFlags } from "${
|
|
898
|
+
flags?: (env: Record<string, unknown>) => import("${t}").Provider;`,contextField:`
|
|
899
|
+
flags,`,importLines:[`import { createFlags } from "${t}";`,'import flagsConfig from "../flags.js";'],stub:""}:D,ir=e=>e?{build:`
|
|
900
900
|
const { notify, push } = createNotify(notifyConfig, env, { log, metrics });
|
|
901
901
|
`,configField:"",contextField:`
|
|
902
902
|
notify,
|
|
903
|
-
push,`,importLines:['import { createNotify } from "@lunora/notify";','import notifyConfig from "../notify.js";'],stub:""}:
|
|
903
|
+
push,`,importLines:['import { createNotify } from "@lunora/notify";','import notifyConfig from "../notify.js";'],stub:""}:D,lr=e=>e?{build:`
|
|
904
904
|
const envConfig = lunoraEnvContract.${e.exportName}(env);
|
|
905
905
|
`,configField:"",contextField:`
|
|
906
|
-
env: envConfig,`,importLines:['import * as lunoraEnvContract from "../env.js";'],stub:""}:
|
|
906
|
+
env: envConfig,`,importLines:['import * as lunoraEnvContract from "../env.js";'],stub:""}:D,cr=e=>e?{build:`
|
|
907
907
|
const access = accessFacade(identity, userId);
|
|
908
908
|
`,configField:"",contextField:`
|
|
909
|
-
access,`,importLines:['import { accessFacade } from "@lunora/cloudflare-access/context";'],stub:""}:
|
|
909
|
+
access,`,importLines:['import { accessFacade } from "@lunora/cloudflare-access/context";'],stub:""}:D,dr=(e,t,n)=>{if(!t)return{constant:"",evaluateOverride:"",subscriptionOverride:""};const r=a=>`
|
|
910
910
|
const env = (this.env ?? {}) as Record<string, unknown>;
|
|
911
|
-
const flags: import("${
|
|
911
|
+
const flags: import("${n}").LunoraFlags = createFlags({
|
|
912
912
|
hooks: flagsConfig.hooks,
|
|
913
913
|
logger: flagsConfig.logger,
|
|
914
914
|
provider: () => config.flags?.(env) ?? flagsConfig.provider(env),
|
|
915
|
-
targetingKey: ${
|
|
916
|
-
});`,
|
|
915
|
+
targetingKey: ${a},
|
|
916
|
+
});`,o=`
|
|
917
917
|
/** Statically-discovered feature flags (\`ctx.flags.<type>("key")\` reads) served via \`__lunora_admin__:listFlags\` + the reactive \`__lunora_flags__:\` channel. */
|
|
918
918
|
const LUNORA_FLAG_KEYS: ReadonlyArray<{ key: string; type: "boolean" | "number" | "object" | "string" }> = ${JSON.stringify(e,void 0,4)};
|
|
919
|
-
`,
|
|
919
|
+
`,s=`
|
|
920
920
|
protected override async evaluateFlags(context?: Record<string, unknown>): Promise<FlagsResult> {${r("undefined")}
|
|
921
|
-
const evalContext = context as import("${
|
|
921
|
+
const evalContext = context as import("${n}").EvaluationContext | undefined;
|
|
922
922
|
const evaluations: FlagsResult["flags"] = [];
|
|
923
923
|
|
|
924
924
|
for (const entry of LUNORA_FLAG_KEYS) {
|
|
@@ -965,30 +965,30 @@ const LUNORA_FLAG_KEYS: ReadonlyArray<{ key: string; type: "boolean" | "number"
|
|
|
965
965
|
}
|
|
966
966
|
|
|
967
967
|
if (args.type === "object") {
|
|
968
|
-
return flags.object(key, (args.default ?? {}) as import("${
|
|
968
|
+
return flags.object(key, (args.default ?? {}) as import("${n}").JsonValue, context);
|
|
969
969
|
}
|
|
970
970
|
|
|
971
971
|
return flags.boolean(key, typeof args.default === "boolean" ? args.default : false, context);
|
|
972
972
|
}
|
|
973
|
-
`;return{constant:
|
|
973
|
+
`;return{constant:o,evaluateOverride:s,subscriptionOverride:i}},ur=e=>e?{build:`
|
|
974
974
|
const analyticsBinding = config.analytics?.(env) ?? (env as Record<string, unknown>).ANALYTICS;
|
|
975
975
|
const analytics: AnalyticsClient = analyticsBinding ? createAnalytics(analyticsBinding as AnalyticsEngineDatasetLike) : analyticsStub;
|
|
976
976
|
`,configField:`
|
|
977
977
|
analytics?: (env: Record<string, unknown>) => AnalyticsEngineDatasetLike;`,contextField:`
|
|
978
|
-
analytics,`,importLines:['import type { AnalyticsClient, AnalyticsEngineDatasetLike } from "@lunora/bindings/analytics";','import { createAnalytics } from "@lunora/bindings/analytics";'],stub:
|
|
978
|
+
analytics,`,importLines:['import type { AnalyticsClient, AnalyticsEngineDatasetLike } from "@lunora/bindings/analytics";','import { createAnalytics } from "@lunora/bindings/analytics";'],stub:T("analyticsStub: AnalyticsClient",'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().");',["track","writeDataPoint"],{sync:["track","writeDataPoint"]})}:D,pr=e=>e?{build:`
|
|
979
979
|
const imagesBinding = config.images?.(env) ?? (env as Record<string, unknown>).IMAGES;
|
|
980
980
|
const images: Images = imagesBinding ? createImages({ binding: imagesBinding as ImagesBindingLike }) : imagesStub;
|
|
981
981
|
`,configField:`
|
|
982
982
|
images?: (env: Record<string, unknown>) => ImagesBindingLike;`,contextField:`
|
|
983
|
-
images,`,importLines:['import type { Images, ImagesBindingLike } from "@lunora/bindings/images";','import { createImages } from "@lunora/bindings/images";'],stub:
|
|
983
|
+
images,`,importLines:['import type { Images, ImagesBindingLike } from "@lunora/bindings/images";','import { createImages } from "@lunora/bindings/images";'],stub:T("imagesStub: Images",'throw new Error("ctx.images: no Images binding found. Add an \\`images\\` binding (env.IMAGES) to wrangler.jsonc, or pass \\`images\\` to createShardDO().");',["info","transform"])}:D,mr=e=>e?{build:`
|
|
984
984
|
const sql: SqlClient = config.sql ? config.sql(env) : sqlStub;
|
|
985
985
|
`,configField:`
|
|
986
986
|
sql?: (env: Record<string, unknown>) => SqlClient;`,contextField:`
|
|
987
|
-
sql,`,importLines:['import type { SqlClient } from "@lunora/hyperdrive";'],stub:
|
|
987
|
+
sql,`,importLines:['import type { SqlClient } from "@lunora/hyperdrive";'],stub:T("sqlStub: SqlClient",'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))\\`.");',["query"])}:D,hr=e=>e?{build:`
|
|
988
988
|
const browser: Browser = config.browser ? config.browser(env) : browserStub;
|
|
989
989
|
`,configField:`
|
|
990
990
|
browser?: (env: Record<string, unknown>) => Browser;`,contextField:`
|
|
991
|
-
browser,`,importLines:['import type { Browser } from "@lunora/browser";'],stub:
|
|
991
|
+
browser,`,importLines:['import type { Browser } from "@lunora/browser";'],stub:T("browserStub: Browser","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'\\`. Session reuse (connect/sessions) additionally needs those two exports passed the same way.\");",["connect","content","launch","pdf","scrape","screenshot","sessions"])}:D,gr=e=>e?{build:`
|
|
992
992
|
const r2sqlEnv = env as Record<string, unknown>;
|
|
993
993
|
const r2sqlAccountId = (r2sqlEnv.R2_SQL_ACCOUNT_ID ?? r2sqlEnv.CLOUDFLARE_ACCOUNT_ID) as string | undefined;
|
|
994
994
|
const r2sqlToken = r2sqlEnv.R2_SQL_TOKEN as string | undefined;
|
|
@@ -999,18 +999,18 @@ const LUNORA_FLAG_KEYS: ReadonlyArray<{ key: string; type: "boolean" | "number"
|
|
|
999
999
|
? createR2Sql({ accountId: r2sqlAccountId, apiToken: r2sqlToken, bucket: r2sqlBucket })
|
|
1000
1000
|
: r2sqlStub;
|
|
1001
1001
|
`,configField:`
|
|
1002
|
-
r2sql?: (env: Record<string, unknown>) => R2SqlClient;`,contextField:"",importLines:['import type { R2SqlClient } from "@lunora/bindings/r2sql";','import { createR2Sql } from "@lunora/bindings/r2sql";'],stub:
|
|
1002
|
+
r2sql?: (env: Record<string, unknown>) => R2SqlClient;`,contextField:"",importLines:['import type { R2SqlClient } from "@lunora/bindings/r2sql";','import { createR2Sql } from "@lunora/bindings/r2sql";'],stub:T("r2sqlStub: R2SqlClient",'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().");',["describe","explain","from","query","showDatabases","showTables"],{sync:["from"]})}:D,fr=e=>e?{build:`
|
|
1003
1003
|
const pipelinesBinding = config.pipelines?.(env) ?? (env as Record<string, unknown>).PIPELINES;
|
|
1004
1004
|
const pipelines: PipelineClient = pipelinesBinding ? createPipelines({ binding: pipelinesBinding as PipelineBindingLike }) : pipelinesStub;
|
|
1005
1005
|
`,configField:`
|
|
1006
|
-
pipelines?: (env: Record<string, unknown>) => PipelineBindingLike;`,contextField:"",importLines:['import type { PipelineBindingLike, PipelineClient } from "@lunora/bindings/pipelines";','import { createPipelines } from "@lunora/bindings/pipelines";'],stub:
|
|
1007
|
-
export class ${
|
|
1006
|
+
pipelines?: (env: Record<string, unknown>) => PipelineBindingLike;`,contextField:"",importLines:['import type { PipelineBindingLike, PipelineClient } from "@lunora/bindings/pipelines";','import { createPipelines } from "@lunora/bindings/pipelines";'],stub:T("pipelinesStub: PipelineClient",'throw new Error("ctx.pipelines: no Pipelines binding found. Add a \\`pipelines\\` binding (env.PIPELINES) to wrangler.jsonc, or pass \\`pipelines\\` to createShardDO().");',["send"])}:D,Vr=(e,t)=>{if(e.length===0)return"";const n=t?`, ${JSON.stringify(t)}`:"",r=e.map(s=>(g(s.exportName,`container export "${s.exportName}"`),g(s.className,`container class "${s.className}"`),`/** Container DO for the \`${s.exportName}\` definition (binding \`${s.bindingName}\`). */
|
|
1007
|
+
export class ${s.className} extends LunoraContainer {
|
|
1008
1008
|
public constructor(ctx: ConstructorParameters<typeof LunoraContainer>[0], env: Record<string, unknown>) {
|
|
1009
|
-
super(ctx, env, ${
|
|
1009
|
+
super(ctx, env, ${s.exportName}, "${s.exportName}"${n});
|
|
1010
1010
|
}
|
|
1011
1011
|
}
|
|
1012
1012
|
`)).join(`
|
|
1013
|
-
`),
|
|
1013
|
+
`),o=e.map(s=>s.exportName).join(", ");return`${R}/**
|
|
1014
1014
|
* Container-enabled Durable Object classes for the containers declared in
|
|
1015
1015
|
* \`lunora/containers.ts\`. Re-export them from your worker entry — wrangler
|
|
1016
1016
|
* requires each \`containers[].class_name\` to be exported by the worker:
|
|
@@ -1024,27 +1024,27 @@ export class ${o.className} extends LunoraContainer {
|
|
|
1024
1024
|
*/
|
|
1025
1025
|
import { LunoraContainer } from "@lunora/container/do";
|
|
1026
1026
|
|
|
1027
|
-
import { ${
|
|
1027
|
+
import { ${o} } from "../containers.js";
|
|
1028
1028
|
|
|
1029
1029
|
export { ContainerProxy } from "@lunora/container/do";
|
|
1030
1030
|
|
|
1031
|
-
${r}`},
|
|
1031
|
+
${r}`},yr=(e,t)=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const r of e)g(r.exportName,`container export "${r.exportName}"`),g(r.bindingName,`container binding "${r.bindingName}"`);const n=e.map(r=>{const o=r.maxInstances===void 0?"":`, maxInstances: ${String(r.maxInstances)}`;return` { binding: "${r.bindingName}", exportName: "${r.exportName}"${o} },`}).join(`
|
|
1032
1032
|
`);return{build:`
|
|
1033
|
-
const containers = createContainerContext(env, LUNORA_CONTAINERS, ${
|
|
1033
|
+
const containers = createContainerContext(env, LUNORA_CONTAINERS, ${t?JSON.stringify(t):"undefined"}, this.getCurrentTraceparent());
|
|
1034
1034
|
`,contextField:`
|
|
1035
1035
|
containers,`,importLines:['import type { ContainerBindingSpec } from "@lunora/container";','import { createContainerContext } from "@lunora/container";'],specs:`
|
|
1036
1036
|
/** Wiring specs for \`ctx.containers\` (codegen-derived from \`lunora/containers.ts\`). */
|
|
1037
1037
|
const LUNORA_CONTAINERS: ReadonlyArray<ContainerBindingSpec> = [
|
|
1038
|
-
${
|
|
1038
|
+
${n}
|
|
1039
1039
|
];
|
|
1040
|
-
`}},
|
|
1040
|
+
`}},Gr=e=>{if(e.length===0)return"";const t=e.map(r=>(g(r.exportName,`workflow export "${r.exportName}"`),g(r.className,`workflow class "${r.className}"`),`/** WorkflowEntrypoint for the \`${r.exportName}\` definition (binding \`${r.bindingName}\`). */
|
|
1041
1041
|
export class ${r.className} extends LunoraWorkflow<WorkflowParamsOf<typeof ${r.exportName}>, WorkflowOutputOf<typeof ${r.exportName}>> {
|
|
1042
1042
|
public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
|
|
1043
1043
|
super(ctx, env, ${r.exportName}, "${r.exportName}");
|
|
1044
1044
|
}
|
|
1045
1045
|
}
|
|
1046
1046
|
`)).join(`
|
|
1047
|
-
`),
|
|
1047
|
+
`),n=e.map(r=>r.exportName).join(", ");return`${R}/**
|
|
1048
1048
|
* WorkflowEntrypoint classes for the workflows declared in
|
|
1049
1049
|
* \`lunora/workflows.ts\`. Re-export them from your worker entry — wrangler
|
|
1050
1050
|
* requires each \`workflows[].class_name\` to be exported by the worker:
|
|
@@ -1053,7 +1053,7 @@ export class ${r.className} extends LunoraWorkflow<WorkflowParamsOf<typeof ${r.e
|
|
|
1053
1053
|
*/
|
|
1054
1054
|
import LunoraWorkflow from "@lunora/workflow/do";
|
|
1055
1055
|
|
|
1056
|
-
import { ${
|
|
1056
|
+
import { ${n} } from "../workflows.js";
|
|
1057
1057
|
|
|
1058
1058
|
/** Params type carried by a \`defineWorkflow\` definition (its phantom \`__params\`), so each entrypoint keeps the authored \`ctx.params\` type. */
|
|
1059
1059
|
type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params }
|
|
@@ -1065,21 +1065,21 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
|
|
|
1065
1065
|
/** Output type carried by a \`defineWorkflow\` definition (its phantom \`__output\`), so each entrypoint keeps the authored return type. */
|
|
1066
1066
|
type WorkflowOutputOf<Definition> = Definition extends { __output?: infer Output } ? Output : unknown;
|
|
1067
1067
|
|
|
1068
|
-
${
|
|
1068
|
+
${t}`},Jr=e=>{if(e.length===0)return"";const n=e.filter(a=>a.voice).length>0,r=e.map(a=>{g(a.exportName,`agent export "${a.exportName}"`),g(a.className,`agent class "${a.className}"`);const c=`/** WorkflowEntrypoint for the \`${a.exportName}\` agent (binding \`${a.bindingName}\`). */
|
|
1069
1069
|
export class ${a.className} extends LunoraWorkflow<AgentRunInput, AgentRunResult> {
|
|
1070
1070
|
public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
|
|
1071
1071
|
super(ctx, env, compileAgentWorkflow(${a.exportName}, "${a.exportName}"), "${a.exportName}");
|
|
1072
1072
|
}
|
|
1073
1073
|
}
|
|
1074
|
-
`;if(!a.voice)return
|
|
1075
|
-
/** Voice-session Durable Object for the \`${a.exportName}\` agent (binding \`${
|
|
1076
|
-
export class ${
|
|
1074
|
+
`;if(!a.voice)return c;const d=a.voiceClassName??"",p=a.voiceBindingName??"";g(d,`agent voice class "${d}"`);const h=`
|
|
1075
|
+
/** Voice-session Durable Object for the \`${a.exportName}\` agent (binding \`${p}\`). */
|
|
1076
|
+
export class ${d} extends VoiceSessionDO {
|
|
1077
1077
|
public constructor(ctx: ConstructorParameters<typeof VoiceSessionDO>[0], env: Record<string, unknown>) {
|
|
1078
1078
|
super(ctx, env, ${a.exportName}, "${a.exportName}");
|
|
1079
1079
|
}
|
|
1080
1080
|
}
|
|
1081
|
-
`;return`${
|
|
1082
|
-
`),
|
|
1081
|
+
`;return`${c}${h}`}).join(`
|
|
1082
|
+
`),o=e.map(a=>a.exportName).join(", ");return`${R}/**
|
|
1083
1083
|
* WorkflowEntrypoint classes for the agents declared in \`lunora/agents.ts\`.
|
|
1084
1084
|
* Each \`defineAgent\` compiles a replay-safe tool-loop onto a Cloudflare
|
|
1085
1085
|
* Workflow. Re-export them from your worker entry — wrangler requires each
|
|
@@ -1091,10 +1091,10 @@ import LunoraWorkflow from "@lunora/workflow/do";
|
|
|
1091
1091
|
${n?'import { compileAgentWorkflow, VoiceSessionDO } from "@lunora/agent";':'import { compileAgentWorkflow } from "@lunora/agent";'}
|
|
1092
1092
|
import type { AgentRunInput, AgentRunResult } from "@lunora/agent";
|
|
1093
1093
|
|
|
1094
|
-
import { ${
|
|
1094
|
+
import { ${o} } from "../agents.js";
|
|
1095
1095
|
|
|
1096
|
-
${
|
|
1097
|
-
`);return`${
|
|
1096
|
+
${r}`},zr=e=>{const t=e.filter(o=>o.mode==="push");if(t.length===0)return"";for(const o of t)g(o.exportName,`queue export "${o.exportName}"`);const n=t.map(o=>o.exportName).join(", "),r=t.map(o=>` ${JSON.stringify(o.name)}: { definition: ${o.exportName}, exportName: ${JSON.stringify(o.exportName)} },`).join(`
|
|
1097
|
+
`);return`${R}/**
|
|
1098
1098
|
* Push-consumer registry for the queues declared in \`lunora/queues.ts\`. The
|
|
1099
1099
|
* composed worker's \`queue(batch, env, ctx)\` entry routes each delivered batch
|
|
1100
1100
|
* by \`batch.queue\` to the matching \`defineQueue\` handler. Wired automatically
|
|
@@ -1102,61 +1102,61 @@ ${t}`},Qr=e=>{const n=e.filter(a=>a.mode==="push");if(n.length===0)return"";for(
|
|
|
1102
1102
|
*/
|
|
1103
1103
|
import type { QueueRegistry } from "@lunora/queue";
|
|
1104
1104
|
|
|
1105
|
-
import { ${
|
|
1105
|
+
import { ${n} } from "../queues.js";
|
|
1106
1106
|
|
|
1107
1107
|
/** Stable wrangler queue name → { definition, exportName } for batch routing. */
|
|
1108
1108
|
export const LUNORA_QUEUE_REGISTRY: QueueRegistry = {
|
|
1109
1109
|
${r}
|
|
1110
1110
|
};
|
|
1111
|
-
`},
|
|
1111
|
+
`},br=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)g(n.exportName,`workflow export "${n.exportName}"`),g(n.bindingName,`workflow binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}" },`).join(`
|
|
1112
1112
|
`);return{build:`
|
|
1113
1113
|
const workflows = createWorkflowContext(env, LUNORA_WORKFLOWS);
|
|
1114
1114
|
`,contextField:`
|
|
1115
1115
|
workflows,`,importLines:['import type { WorkflowBindingSpec } from "@lunora/workflow";','import { createWorkflowContext } from "@lunora/workflow";'],specs:`
|
|
1116
1116
|
/** Wiring specs for \`ctx.workflows\` (codegen-derived from \`lunora/workflows.ts\`). */
|
|
1117
1117
|
const LUNORA_WORKFLOWS: ReadonlyArray<WorkflowBindingSpec> = [
|
|
1118
|
-
${
|
|
1118
|
+
${t}
|
|
1119
1119
|
];
|
|
1120
|
-
`}},
|
|
1120
|
+
`}},xr=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)g(n.exportName,`queue export "${n.exportName}"`),g(n.bindingName,`queue binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}", name: ${JSON.stringify(n.name)} },`).join(`
|
|
1121
1121
|
`);return{build:`
|
|
1122
1122
|
const queues = createQueueContext(env, LUNORA_QUEUES);
|
|
1123
1123
|
`,contextField:`
|
|
1124
1124
|
queues,`,importLines:['import type { QueueBindingSpec } from "@lunora/queue";','import { createQueueContext } from "@lunora/queue";'],specs:`
|
|
1125
1125
|
/** Wiring specs for \`ctx.queues\` (codegen-derived from \`lunora/queues.ts\`). */
|
|
1126
1126
|
const LUNORA_QUEUES: ReadonlyArray<QueueBindingSpec> = [
|
|
1127
|
-
${
|
|
1127
|
+
${t}
|
|
1128
1128
|
];
|
|
1129
|
-
`}},
|
|
1129
|
+
`}},kr=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)g(n.exportName,`agent export "${n.exportName}"`),g(n.bindingName,`agent binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}"${n.publicRun===!0?", publicRun: true":""} },`).join(`
|
|
1130
1130
|
`);return{build:`
|
|
1131
1131
|
const agents = createAgentContext(env, LUNORA_AGENTS);
|
|
1132
1132
|
`,contextField:`
|
|
1133
1133
|
agents,`,importLines:['import { createAgentContext } from "@lunora/agent";','import type { AgentBindingSpec } from "@lunora/agent";'],specs:`
|
|
1134
1134
|
/** Wiring specs for \`ctx.agents\` (codegen-derived from \`lunora/agents.ts\`). */
|
|
1135
1135
|
const LUNORA_AGENTS: ReadonlyArray<AgentBindingSpec> = [
|
|
1136
|
-
${
|
|
1136
|
+
${t}
|
|
1137
1137
|
];
|
|
1138
|
-
`}},
|
|
1139
|
-
${
|
|
1140
|
-
const ${e}: ${
|
|
1138
|
+
`}},ft=(e,t,n,r,o)=>({constant:`
|
|
1139
|
+
${o}
|
|
1140
|
+
const ${e}: ${t} = ${JSON.stringify(r,void 0,4)};
|
|
1141
1141
|
`,override:`
|
|
1142
|
-
protected override ${
|
|
1142
|
+
protected override ${n}(): ${t} {
|
|
1143
1143
|
return ${e};
|
|
1144
1144
|
}
|
|
1145
|
-
`}),
|
|
1145
|
+
`}),wr=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 ft("LUNORA_WORKFLOWS_INFO","WorkflowsResult","workflowsMetadata",t,"/** Read-only declared-workflow metadata (discovered from `lunora/workflows.ts`) served via `__lunora_admin__:listWorkflows` for the studio's workflows view. */")},vr=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 ft("LUNORA_QUEUES_INFO","QueuesResult","queuesMetadata",t,"/** Read-only declared-queue metadata (discovered from `lunora/queues.ts`) served via `__lunora_admin__:listQueues` for the studio's queues view. */")},$r=e=>e?{imports:['import type { LunoraDatabaseLike as LunoraPaymentDbLike, LunoraPayment, PaymentsFromContextOptions } from "@lunora/payment";','import { paymentsFromContext } from "@lunora/payment";'],build:`
|
|
1146
1146
|
const payments: LunoraPayment = config.payment
|
|
1147
1147
|
? paymentsFromContext({ auth: { userId: userId ?? null }, db: db as unknown as LunoraPaymentDbLike }, config.payment(env))
|
|
1148
1148
|
: paymentStub;
|
|
1149
1149
|
`,configField:`
|
|
1150
1150
|
payment?: (env: Record<string, unknown>) => PaymentsFromContextOptions;`,contextField:`
|
|
1151
|
-
payments,`,stub:
|
|
1151
|
+
payments,`,stub:T("paymentStub: LunoraPayment",'throw new Error("ctx.payments: no payment configured. Pass \\`payment\\` to createShardDO().");',["attach","cancelSubscription","check","createCheckout","createPortalSession","handleWebhook","listBalances","listSubscriptions","track"],{cast:" as unknown as LunoraPayment",sync:["attach","cancelSubscription","check","createCheckout","createPortalSession","handleWebhook","listBalances","listSubscriptions","track"]})}:{build:"",configField:"",contextField:"",imports:[],stub:""},Rr=e=>e?{imports:['import type { X402Pay, X402PayConfig } from "@lunora/x402/pay";','import { lazyX402Pay } from "@lunora/x402/pay";'],build:`
|
|
1152
1152
|
const x402: X402Pay = config.x402
|
|
1153
1153
|
? lazyX402Pay(config.x402(env), { getSecret: (name: string) => secrets.get(name) })
|
|
1154
1154
|
: x402Stub;
|
|
1155
1155
|
`,configField:`
|
|
1156
|
-
x402?: (env: Record<string, unknown>) => X402PayConfig;`,stub:
|
|
1156
|
+
x402?: (env: Record<string, unknown>) => X402PayConfig;`,stub:T("x402Stub: X402Pay",'throw new Error("ctx.x402: no pay rail configured. Pass \\`x402\\` to createShardDO().");',["fetch"],{cast:" as unknown as X402Pay",sync:["fetch"]})}:{build:"",configField:"",imports:[],stub:""},Sr=(e,t,n,r)=>["AdvisorProcedure","AdvisoryFinding","DatabaseWriterLike","DataMigrationLike","ExportRow",...r?["FlagsResult"]:[],"ImportShardResult","KeyRange","MaskPoliciesResult","MigrationRunResult",...n?["QueuesResult"]:[],"RunShardApplyCdcArgs","RunShardExportArgs","RunShardImportArgs","RunShardMigrationArgs","RlsPoliciesResult","RunShardRankBeforeArgs","RunShardRankPageArgs","RunShardWriteArgs","RunShardWriteResult","SchedulerLike","TransactionHeadroomTracker","SchemaLike","ShardDOState","ShardRankPageResult","SqlExec","StorageRulesResult","StudioFeaturesResult","SystemReaderStorageLike","TelemetrySink",...t?["WorkflowsResult"]:[],...e?["WriteHook"]:[]],Yr=({advisories:e=[],advisorProcedures:t=[],agents:n=[],containers:r=[],env:o,flagKeys:s=[],hasAccessFacade:i=!1,hasAi:a=!1,hasAnalytics:c=!1,hasBrowser:d=!1,hasFlags:p=!1,hasHyperdrive:h=!1,hasImages:y=!1,hasKv:u=!1,hasNotify:l=!1,hasPayments:f=!1,hasPipelines:k=!1,hasR2sql:w=!1,hasX402:v=!1,maskMetadata:I,mutators:P=[],queues:C=[],rlsMetadata:$,schema:x,schemaSnapshot:M,shapes:oe=[],storageRules:B,studioFeatures:ae,useUmbrella:se=!1,workflows:W=[]})=>{const A=ne(se),X=P.length>0,O=oe.length>0,L=M===void 0?"":mn(M),j=M===void 0?"":`
|
|
1157
1157
|
/** Structural schema snapshot + its content hash, recorded in the shard's \`__lunora_schema_history\` ledger on cold start so the studio can show a schema-version timeline and diff any two versions. */
|
|
1158
|
-
const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(
|
|
1159
|
-
`,
|
|
1158
|
+
const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(hn(M))}, json: ${JSON.stringify(L)} };
|
|
1159
|
+
`,ie=M===void 0?"":", schemaSnapshot: LUNORA_SCHEMA_SNAPSHOT",{build:le,configField:Se,contextField:Ne,stub:Te}=or(a),ce=cr(i),H=ar(u),F=sr(p,A.flags),V=dr(s,p,A.flags),Z=ir(l),de=lr(o),G=ur(c),U=pr(y),K=mr(h),Q=hr(d),q=gr(w),ee=fr(k),{build:Ae,contextField:ke,importLines:we,specs:ue}=xr(C),{build:Oe,contextField:Ie,importLines:ve,specs:pe}=yr(r,x.jurisdiction),{build:Ce,contextField:Le,importLines:$e,specs:_e}=br(W),{build:Ee,contextField:me,importLines:he,specs:De}=kr(n),{build:Fe,configField:Pe,contextField:ge,imports:fe,stub:Ve}=$r(f),{build:m,configField:Me,imports:bt,stub:xt}=Rr(v),kt=e,wt=t,vt=$??{policies:[],roles:[]},$t=I??{columns:[]},Rt=B??{rules:[]},St=ae??{analytics:!1,auth:!1,containers:!1,flags:!1,kv:!1,mail:!1,notifications:!1,payments:!1,queues:!1,scheduler:!1,storage:!1,vectors:!1,workflows:!1},{constant:Nt,override:Tt}=wr(W),{constant:At,override:Ot}=vr(C),J=x.vectorIndexes.length>0,Ge=new Set(x.tables.filter(b=>typeof b.shardMode=="object"&&b.shardMode.kind==="shardBy").map(b=>b.name)),Re=x.vectorIndexes.some(b=>Ge.has(b.table)),ye=x.tables.some(b=>b.shardMode==="global"),Be=x.tables.some(b=>b.shardMode==="global"&&b.globalBackend==="hyperdrive"),Je=x.tables.some(b=>b.shardMode==="global"&&b.globalBackend!=="hyperdrive"),z=x.tables.some(b=>b.externalSource!==void 0);if(Je&&Be)throw new te("INTERNAL",'lunora codegen: mixing `.global()` (D1) and `.global({ backend: "hyperdrive" })` tables in one app is not supported yet — use a single global backend.');const je=x.tables.length>0,It=Xn(x),Ct=er(x),Lt=nr(x),_t=Zn(x),ze=tr(x),Ye=Sr(J,W.length>0,C.length>0,p);O&&Ye.push("WhereInput");const Xe=rr(ye),Et=O?`
|
|
1160
1160
|
protected override resolveShape(name: string, args: Record<string, unknown>, identity?: { identity?: Record<string, unknown>; userId?: string }): { columns?: readonly string[]; effectiveWhere?: WhereInput; global?: boolean; table: string } | undefined {
|
|
1161
1161
|
const shape = LUNORA_SHAPES[name];
|
|
1162
1162
|
|
|
@@ -1209,30 +1209,30 @@ const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.st
|
|
|
1209
1209
|
|
|
1210
1210
|
return { columns: shape.columns, effectiveWhere, global: isGlobal, table: shape.table };
|
|
1211
1211
|
}
|
|
1212
|
-
`:"",
|
|
1212
|
+
`:"",Dt=X?`
|
|
1213
1213
|
protected override isCustomMutator(functionPath: string): boolean {
|
|
1214
1214
|
return LUNORA_MUTATOR_PATHS.has(functionPath);
|
|
1215
1215
|
}
|
|
1216
|
-
`:"",
|
|
1216
|
+
`:"",Ft=O?"\n/** Per-table RLS read policies (hoisted from `.use(rls(...))` chains) the shape resolver AND-merges into each `defineShape` predicate so partial replication honours read policies. */\nconst LUNORA_RLS_READ_REGISTRY = buildRlsReadRegistry(Object.values(LUNORA_FUNCTIONS));\n":"",Pt=O?"assertShapeShardable, ":"",be=[`import type { ${Ye.join(", ")} } from "${A.do}";`,`import { applyCdcChanges, buildReprojectionMigration, ${Pt}createReadFootprint, createShardCtxDb, exportShardRows, importShardRows, ${z?"isSourceDue, pullExternalSourceIncrementalTick, pullExternalSourceTick, ":""}${Re?"ROOT_SHARD_NAME, ":""}runDataMigration, runShardMigrations, ${Xe.importFragment}ShardDO as ShardDOBase } from "${A.do}";`,...z?[`import type { ExternalSourceLike, SourceClientLike, TraceRefLike } from "${A.do}";`]:[],O?`import { asBucketStorage, buildRlsReadRegistry, composeShapeReadWhere, createSecrets, LunoraError } from "${A.server}";`:`import { asBucketStorage, createSecrets, LunoraError } from "${A.server}";`];je&&be.push(`import { bindOrm, bindTableFacade } from "${A.server}";`),J&&be.push('import type { SchemaLike as VectorSchemaLike, VectorizeIndexLike, VectorSearchLike } from "@lunora/bindings/vectors";','import { createContextVectors, createVectors, createVectorSyncHook } from "@lunora/bindings/vectors";'),a&&be.push('import type { AiBindingLike, LunoraAi } from "@lunora/ai";','import { createAi } from "@lunora/ai";'),be.push(...ce.importLines,...H.importLines,...F.importLines,...Z.importLines,...de.importLines,...G.importLines,...U.importLines,...K.importLines,...Q.importLines,...q.importLines,...ee.importLines,...ve,...$e,...we,...he,...fe,...bt,"",'import schema from "../schema.js";',`import { ${["LUNORA_FUNCTIONS","LUNORA_LIFECYCLE_HOOKS","LUNORA_MIGRATIONS",...X?["LUNORA_MUTATOR_PATHS"]:[],...O?["LUNORA_SHAPES"]:[]].join(", ")} } from "./functions.js";`);const Mt=J?`
|
|
1217
1217
|
vectors?: (env: Record<string, unknown>) => Record<string, VectorizeIndexLike>;`:"",Bt=Je?`
|
|
1218
1218
|
d1?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",jt=Be?`
|
|
1219
|
-
hyperdriveGlobal?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",qt=
|
|
1220
|
-
sourceClient?: (env: Record<string, unknown>, binding: string) => { query: <Row = Record<string, unknown>>(text: string, params?: readonly unknown[]) => Promise<Row[]> } | undefined;`:"",Wt='throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");',Ut='throw new Error("ctx.vectors: no vectors configured. Pass `vectors` to createShardDO().");',Kt='throw new Error("ctx.scheduler: no scheduler configured. Pass `scheduler` to createShardDO().");',Qt='throw new Error("ctx.storage: no storage configured. Pass `storage` to createShardDO().");',
|
|
1219
|
+
hyperdriveGlobal?: (env: Record<string, unknown>, request?: { identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",qt=z?`
|
|
1220
|
+
sourceClient?: (env: Record<string, unknown>, binding: string) => { query: <Row = Record<string, unknown>>(text: string, params?: readonly unknown[]) => Promise<Row[]> } | undefined;`:"",Wt='throw new Error("ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().");',Ut='throw new Error("ctx.vectors: no vectors configured. Pass `vectors` to createShardDO().");',Kt='throw new Error("ctx.scheduler: no scheduler configured. Pass `scheduler` to createShardDO().");',Qt='throw new Error("ctx.storage: no storage configured. Pass `storage` to createShardDO().");',Ht=ye?T("globalDbStub: DatabaseWriterLike",Wt,["aggregate","count","delete","findFirst","findFirstOrThrow","findMany","get","groupBy","insert","normalizeId","patch","query","rank","rankPage","replace"],{sync:["normalizeId","query"]}):"",Vt=J?T("vectorsStub: VectorSearchLike",Ut,["deleteByIds","getByIds","query","upsert","upsertNow"]):"",Gt=Re?`
|
|
1221
1221
|
const vectorShardKey = this.currentShardKey();
|
|
1222
|
-
`:"",
|
|
1222
|
+
`:"",Jt=Re?"namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, ":"",zt=Re?`, { namespace: vectorShardKey === ROOT_SHARD_NAME ? undefined : vectorShardKey, shardedIndexNames: [${x.vectorIndexes.filter(b=>Ge.has(b.table)).map(b=>JSON.stringify(b.name)).join(", ")}] }`:"",Yt=J?`
|
|
1223
1223
|
let vectors: VectorSearchLike;
|
|
1224
1224
|
let onWrite: WriteHook | undefined;
|
|
1225
1225
|
|
|
1226
1226
|
if (config.vectors) {
|
|
1227
1227
|
const lunora = createVectors({ indexes: config.vectors(env) });
|
|
1228
|
-
${
|
|
1229
|
-
vectors = createContextVectors(lunora${
|
|
1230
|
-
onWrite = createVectorSyncHook({ ${
|
|
1228
|
+
${Gt}
|
|
1229
|
+
vectors = createContextVectors(lunora${zt});
|
|
1230
|
+
onWrite = createVectorSyncHook({ ${Jt}schema: schema as unknown as VectorSchemaLike, vectors });
|
|
1231
1231
|
} else {
|
|
1232
1232
|
vectors = vectorsStub;
|
|
1233
1233
|
onWrite = undefined;
|
|
1234
1234
|
}
|
|
1235
|
-
`:"",
|
|
1235
|
+
`:"",Xt=`{
|
|
1236
1236
|
auth: { identity: identity ?? null, userId: userId ?? null },
|
|
1237
1237
|
broadcast: (delta) => {
|
|
1238
1238
|
this.recordChangedTable(delta.table, delta.indexKeys);
|
|
@@ -1242,14 +1242,14 @@ ${Jt}
|
|
|
1242
1242
|
headroom: options.headroom ?? this.transactionHeadroom(),
|
|
1243
1243
|
onIndexUse: this.getCtxDbIndexUseHook(),
|
|
1244
1244
|
onRead: options.onRead ?? this.getCtxDbReadHook(),
|
|
1245
|
-
onReadRange: options.onReadRange,${
|
|
1245
|
+
onReadRange: options.onReadRange,${J?`
|
|
1246
1246
|
onWrite,`:""}
|
|
1247
1247
|
scheduler,
|
|
1248
1248
|
schema: schema as unknown as SchemaLike,
|
|
1249
1249
|
sql: this.sql as SqlExec,
|
|
1250
|
-
storage,${
|
|
1250
|
+
storage,${ye?`
|
|
1251
1251
|
globalDb,`:""}
|
|
1252
|
-
}`,
|
|
1252
|
+
}`,Y=` const env = (this.env ?? {}) as Record<string, unknown>;
|
|
1253
1253
|
const scheduler = (config.scheduler?.(env) ?? schedulerStub) as SchedulerLike;
|
|
1254
1254
|
const writer = createShardCtxDb({
|
|
1255
1255
|
broadcast: (delta) => {
|
|
@@ -1259,13 +1259,13 @@ ${Jt}
|
|
|
1259
1259
|
scheduler,
|
|
1260
1260
|
schema: schema as unknown as SchemaLike,
|
|
1261
1261
|
sql: this.sql as SqlExec,
|
|
1262
|
-
});`,Zt=
|
|
1262
|
+
});`,Zt=J?`
|
|
1263
1263
|
vectors,`:"",en=je?`
|
|
1264
|
-
orm: bindOrm(facade),`:"",
|
|
1265
|
-
`:"",nn=O&&
|
|
1264
|
+
orm: bindOrm(facade),`:"",Ze=Be?"config.hyperdriveGlobal":"config.d1",tn=ye?` const globalDb: DatabaseWriterLike = ${Ze}?.(env, { identity, userId }) ?? globalDbStub;
|
|
1265
|
+
`:"",nn=O&&ye?`
|
|
1266
1266
|
protected override async readGlobalShapeRows(resolved: { columns?: readonly string[]; effectiveWhere?: WhereInput; global?: boolean; table: string }, identity?: { identity?: Record<string, unknown>; userId?: string }): Promise<Array<{ doc: Record<string, unknown>; id: string }>> {
|
|
1267
1267
|
const env = this.env as Record<string, unknown>;
|
|
1268
|
-
const globalDb: DatabaseWriterLike = ${
|
|
1268
|
+
const globalDb: DatabaseWriterLike = ${Ze}?.(env, identity) ?? globalDbStub;
|
|
1269
1269
|
const rows: Array<{ doc: Record<string, unknown>; id: string }> = [];
|
|
1270
1270
|
|
|
1271
1271
|
let cursor: null | string = null;
|
|
@@ -1292,10 +1292,10 @@ ${Jt}
|
|
|
1292
1292
|
|
|
1293
1293
|
return rows;
|
|
1294
1294
|
}
|
|
1295
|
-
`:"",rn=
|
|
1295
|
+
`:"",rn=z?`
|
|
1296
1296
|
const sourceClientCache = new WeakMap<object, Map<string, SourceClientLike>>();
|
|
1297
1297
|
const sourcePollAtCache = new WeakMap<object, Map<string, number>>();
|
|
1298
|
-
`:"",
|
|
1298
|
+
`:"",on=z?`
|
|
1299
1299
|
protected override async pollExternalSources(trace?: TraceRefLike): Promise<number | undefined> {
|
|
1300
1300
|
const env = (this.env ?? {}) as Record<string, unknown>;
|
|
1301
1301
|
const sourced = Object.entries((schema as unknown as SchemaLike).tables)
|
|
@@ -1430,10 +1430,10 @@ const sourcePollAtCache = new WeakMap<object, Map<string, number>>();
|
|
|
1430
1430
|
|
|
1431
1431
|
return nextDueAt;
|
|
1432
1432
|
}
|
|
1433
|
-
`:"",
|
|
1433
|
+
`:"",et=ze.length>0,an=z||et?`
|
|
1434
1434
|
public constructor(state: ShardDOState, env: unknown) {
|
|
1435
1435
|
super(state, env);
|
|
1436
|
-
${
|
|
1436
|
+
${z?`
|
|
1437
1437
|
const autoSourced = Object.values((schema as unknown as SchemaLike).tables).some((definition) => {
|
|
1438
1438
|
const source = (definition as { externalSource?: ExternalSourceLike }).externalSource;
|
|
1439
1439
|
|
|
@@ -1443,27 +1443,27 @@ ${G?`
|
|
|
1443
1443
|
if (autoSourced) {
|
|
1444
1444
|
void this.scheduleSourcePoll();
|
|
1445
1445
|
}
|
|
1446
|
-
`:""}${
|
|
1446
|
+
`:""}${et?`
|
|
1447
1447
|
if (LUNORA_TTL_SWEEPS.length > 0) {
|
|
1448
1448
|
void this.scheduleTtlSweep();
|
|
1449
1449
|
}
|
|
1450
1450
|
`:""} }
|
|
1451
1451
|
`:"",sn=je?`
|
|
1452
1452
|
const facade = db as unknown as Record<string, ReturnType<typeof bindTableFacade>>;
|
|
1453
|
-
${
|
|
1453
|
+
${x.tables.map(b=>` facade[${JSON.stringify(b.name)}] = bindTableFacade(db, ${JSON.stringify(b.name)});`).join(`
|
|
1454
1454
|
`)}
|
|
1455
|
-
`:"",ln=`${
|
|
1455
|
+
`:"",ln=`${ce.build}${H.build}${F.build}${G.build}${de.build}
|
|
1456
1456
|
const secrets = createSecrets(env);
|
|
1457
|
-
`,
|
|
1458
|
-
secrets,`,
|
|
1457
|
+
`,cn=`${ce.contextField}${H.contextField}${F.contextField}${Z.contextField}${G.contextField}${de.contextField}
|
|
1458
|
+
secrets,`,dn=Z.build,tt=y||h||d||w||k||v,un=tt?`
|
|
1459
1459
|
// ActionCtx-only helpers (external, non-deterministic I/O): constructed
|
|
1460
1460
|
// and attached only for an \`action\` so query/mutation ctx never carry them.
|
|
1461
1461
|
if (isAction) {
|
|
1462
|
-
${U.build}${K.build}${Q.build}${q.build}${ee.build}${
|
|
1462
|
+
${U.build}${K.build}${Q.build}${q.build}${ee.build}${m}${[...y?[" ctx.images = images;"]:[],...h?[" ctx.sql = sql;"]:[],...d?[" ctx.browser = browser;"]:[],...w?[" ctx.r2sql = r2sql;"]:[],...k?[" ctx.pipelines = pipelines;"]:[],...v?[" ctx.x402 = x402;"]:[]].join(`
|
|
1463
1463
|
`)}
|
|
1464
1464
|
}
|
|
1465
|
-
`:"",pn=
|
|
1466
|
-
`:"";return`${
|
|
1465
|
+
`:"",pn=tt?` const isAction = LUNORA_FUNCTIONS[options.functionPath ?? ""]?.kind === "action";
|
|
1466
|
+
`:"";return`${R}${be.join(`
|
|
1467
1467
|
`)}
|
|
1468
1468
|
|
|
1469
1469
|
type FunctionKind = "action" | "mutation" | "query";
|
|
@@ -1473,13 +1473,13 @@ interface FunctionReference {
|
|
|
1473
1473
|
}
|
|
1474
1474
|
|
|
1475
1475
|
/** Foreign-key columns per table (\`v.id("target")\` fields) for the data browser. */
|
|
1476
|
-
const LUNORA_TABLE_REFS: Record<string, Record<string, string>> = ${JSON.stringify(
|
|
1476
|
+
const LUNORA_TABLE_REFS: Record<string, Record<string, string>> = ${JSON.stringify(It,void 0,4)};
|
|
1477
1477
|
|
|
1478
1478
|
/** Declared indexes per table (secondary, search, geo, rank, vector) for the schema viewer. */
|
|
1479
1479
|
const LUNORA_TABLE_INDEXES: Record<string, Array<{ fields: string[]; name: string; type: "geo" | "index" | "rank" | "search" | "vector"; unique?: boolean }>> = ${JSON.stringify(Ct,void 0,4)};
|
|
1480
1480
|
|
|
1481
1481
|
/** Columns per table (typed, with PK/FK markers) for the studio's schema diagram, served via \`__lunora_admin__:describeTable\`. */
|
|
1482
|
-
const LUNORA_TABLE_COLUMNS: Record<string, Array<{ isStorage?: boolean; name: string; optional: boolean; pk?: boolean; ref?: string; type: string }>> = ${JSON.stringify(
|
|
1482
|
+
const LUNORA_TABLE_COLUMNS: Record<string, Array<{ isStorage?: boolean; name: string; optional: boolean; pk?: boolean; ref?: string; type: string }>> = ${JSON.stringify(Lt,void 0,4)};
|
|
1483
1483
|
|
|
1484
1484
|
/** Storage-key columns per table (\`v.storage(...)\` fields) for the file browser's records↔files join. */
|
|
1485
1485
|
const LUNORA_STORAGE_COLUMNS: Record<string, string[]> = ${JSON.stringify(_t,void 0,4)};
|
|
@@ -1488,10 +1488,10 @@ const LUNORA_STORAGE_COLUMNS: Record<string, string[]> = ${JSON.stringify(_t,voi
|
|
|
1488
1488
|
const LUNORA_TTL_SWEEPS: Array<{ after?: number; field: string; softDeleteField?: string; table: string }> = ${JSON.stringify(ze,void 0,4)};
|
|
1489
1489
|
|
|
1490
1490
|
/** Static schema advisories (computed by @lunora/advisor at codegen time) served via \`__lunora_admin__:getAdvisories\`. */
|
|
1491
|
-
const LUNORA_ADVISORIES: AdvisoryFinding[] = ${JSON.stringify(
|
|
1491
|
+
const LUNORA_ADVISORIES: AdvisoryFinding[] = ${JSON.stringify(kt,void 0,4)};
|
|
1492
1492
|
|
|
1493
1493
|
/** Every declared procedure (discovered by @lunora/codegen) served via \`__lunora_admin__:getAdvisorProcedures\` — the health map's denominator. */
|
|
1494
|
-
const LUNORA_ADVISOR_PROCEDURES: AdvisorProcedure[] = ${JSON.stringify(
|
|
1494
|
+
const LUNORA_ADVISOR_PROCEDURES: AdvisorProcedure[] = ${JSON.stringify(wt,void 0,4)};
|
|
1495
1495
|
|
|
1496
1496
|
/** Read-only RLS metadata (policies + roles discovered from \`.use(rls(...))\` chains) served via \`__lunora_admin__:rlsPolicies\` for the studio's RLS inspector. */
|
|
1497
1497
|
const LUNORA_RLS_METADATA: RlsPoliciesResult = ${JSON.stringify(vt,void 0,4)};
|
|
@@ -1500,20 +1500,20 @@ const LUNORA_RLS_METADATA: RlsPoliciesResult = ${JSON.stringify(vt,void 0,4)};
|
|
|
1500
1500
|
const LUNORA_MASK_METADATA: MaskPoliciesResult = ${JSON.stringify($t,void 0,4)};
|
|
1501
1501
|
|
|
1502
1502
|
/** Read-only storage access-rule metadata (discovered from \`.use(storageRules(...))\` chains) served via \`__lunora_admin__:storageRules\` for the studio's access-rules view. */
|
|
1503
|
-
const LUNORA_STORAGE_RULES: StorageRulesResult = ${JSON.stringify(
|
|
1503
|
+
const LUNORA_STORAGE_RULES: StorageRulesResult = ${JSON.stringify(Rt,void 0,4)};
|
|
1504
1504
|
|
|
1505
1505
|
/** 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. */
|
|
1506
|
-
const LUNORA_STUDIO_FEATURES: StudioFeaturesResult = ${JSON.stringify(
|
|
1507
|
-
${j}${
|
|
1506
|
+
const LUNORA_STUDIO_FEATURES: StudioFeaturesResult = ${JSON.stringify(St,void 0,4)};
|
|
1507
|
+
${j}${V.constant}${Ft}${Nt}${At}${pe}${_e}${ue}${De}
|
|
1508
1508
|
export interface ShardDOConfig {
|
|
1509
1509
|
/** Opt into change-data-capture: records a post-image to \`__cdc_log\` on every write (backs streaming export + replay-PITR). */
|
|
1510
1510
|
cdc?: boolean;
|
|
1511
1511
|
/** 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. */
|
|
1512
1512
|
observability?: (env: Record<string, unknown>) => TelemetrySink | undefined;
|
|
1513
1513
|
scheduler?: (env: Record<string, unknown>) => unknown;
|
|
1514
|
-
storage?: (env: Record<string, unknown>) => unknown;${
|
|
1514
|
+
storage?: (env: Record<string, unknown>) => unknown;${Mt}${Se}${H.configField}${F.configField}${G.configField}${U.configField}${K.configField}${Q.configField}${q.configField}${ee.configField}${Pe}${Me}${Bt}${jt}${qt}
|
|
1515
1515
|
}
|
|
1516
|
-
${
|
|
1516
|
+
${T("schedulerStub",Kt,["cancel","runAfter","runAt"])}${T("storageStub",Qt,["delete","download","getMetadata","getSignedUrl","getUrl","list","upload"],{sync:["getUrl"]})}${Ht}${rn}${Vt}${Te}${H.stub}${F.stub}${G.stub}${U.stub}${K.stub}${Q.stub}${q.stub}${ee.stub}${Ve}${xt}
|
|
1517
1517
|
// Bound in-process \`ctx.run*\` composition depth so a self- or cyclically-
|
|
1518
1518
|
// referencing call fails loudly with a clear error instead of overflowing the
|
|
1519
1519
|
// stack. Tracked across the awaited handler chain (one DO invocation is
|
|
@@ -1550,7 +1550,7 @@ const dispatchRun = async (expected: FunctionKind, functionPath: string, args: R
|
|
|
1550
1550
|
* from the worker entry so wrangler binds it by name.
|
|
1551
1551
|
*/
|
|
1552
1552
|
export const createShardDO = (config: ShardDOConfig = {}): new (state: ShardDOState, env: unknown) => ShardDOBase =>
|
|
1553
|
-
class extends ShardDOBase {${
|
|
1553
|
+
class extends ShardDOBase {${an}
|
|
1554
1554
|
private migrated = false;
|
|
1555
1555
|
|
|
1556
1556
|
public override async handleRpc(functionPath: string, args: Record<string, unknown>, headroom?: TransactionHeadroomTracker): Promise<unknown> {
|
|
@@ -1635,7 +1635,7 @@ ${Xe.override}
|
|
|
1635
1635
|
iterator: (signal) => (registered.handler as (context: unknown, args: Record<string, unknown>, signal: AbortSignal) => AsyncIterable<unknown>)(this.buildCtx({ functionPath }), args, signal),
|
|
1636
1636
|
};
|
|
1637
1637
|
}
|
|
1638
|
-
${
|
|
1638
|
+
${Dt}${Et}${nn}${on}
|
|
1639
1639
|
protected override lifecycleHookPaths(event: "connect" | "disconnect"): readonly string[] {
|
|
1640
1640
|
return LUNORA_LIFECYCLE_HOOKS[event];
|
|
1641
1641
|
}
|
|
@@ -1675,7 +1675,7 @@ ${Et}${Dt}${nn}${an}
|
|
|
1675
1675
|
protected override studioFeatures(): StudioFeaturesResult {
|
|
1676
1676
|
return LUNORA_STUDIO_FEATURES;
|
|
1677
1677
|
}
|
|
1678
|
-
${
|
|
1678
|
+
${V.evaluateOverride}${V.subscriptionOverride}${Tt}${Ot}
|
|
1679
1679
|
protected override advisories(): AdvisoryFinding[] {
|
|
1680
1680
|
return LUNORA_ADVISORIES;
|
|
1681
1681
|
}
|
|
@@ -1699,7 +1699,7 @@ ${H.evaluateOverride}${H.subscriptionOverride}${At}${Ot}
|
|
|
1699
1699
|
throw new LunoraError("MIGRATION_NOT_FOUND", \`data migration "\${args.id}" is not registered\`, { status: 404 });
|
|
1700
1700
|
}
|
|
1701
1701
|
|
|
1702
|
-
${
|
|
1702
|
+
${Y}
|
|
1703
1703
|
|
|
1704
1704
|
return runDataMigration({
|
|
1705
1705
|
batchSize: args.batchSize,
|
|
@@ -1732,7 +1732,7 @@ ${X}
|
|
|
1732
1732
|
|
|
1733
1733
|
this.ensureMigrated();
|
|
1734
1734
|
|
|
1735
|
-
${
|
|
1735
|
+
${Y}
|
|
1736
1736
|
|
|
1737
1737
|
if (args.op === "insert") {
|
|
1738
1738
|
const id = await writer.insert(args.table, args.doc ?? {});
|
|
@@ -1776,7 +1776,7 @@ ${X}
|
|
|
1776
1776
|
protected override async runShardExport(args: RunShardExportArgs): Promise<ExportRow[]> {
|
|
1777
1777
|
this.ensureMigrated();
|
|
1778
1778
|
|
|
1779
|
-
${
|
|
1779
|
+
${Y}
|
|
1780
1780
|
|
|
1781
1781
|
const rows: ExportRow[] = [];
|
|
1782
1782
|
|
|
@@ -1793,7 +1793,7 @@ ${X}
|
|
|
1793
1793
|
protected override async runShardImport(args: RunShardImportArgs): Promise<ImportShardResult> {
|
|
1794
1794
|
this.ensureMigrated();
|
|
1795
1795
|
|
|
1796
|
-
${
|
|
1796
|
+
${Y}
|
|
1797
1797
|
|
|
1798
1798
|
// \`importShardRows\` inserts with \`allowExplicitId\`, so a source
|
|
1799
1799
|
// database's \`_id\`s carry across verbatim and every foreign key
|
|
@@ -1844,7 +1844,7 @@ ${X}
|
|
|
1844
1844
|
protected override async runShardRankBefore(args: RunShardRankBeforeArgs): Promise<{ before: number; total: number }> {
|
|
1845
1845
|
this.ensureMigrated();
|
|
1846
1846
|
|
|
1847
|
-
${
|
|
1847
|
+
${Y}
|
|
1848
1848
|
|
|
1849
1849
|
// \`rankBefore\` is optional on \`DatabaseWriterLike\` (the D1 twin omits it),
|
|
1850
1850
|
// but the shard writer from \`createShardCtxDb\` always defines it.
|
|
@@ -1862,7 +1862,7 @@ ${X}
|
|
|
1862
1862
|
protected override async runShardRankPage(args: RunShardRankPageArgs): Promise<ShardRankPageResult> {
|
|
1863
1863
|
this.ensureMigrated();
|
|
1864
1864
|
|
|
1865
|
-
${
|
|
1865
|
+
${Y}
|
|
1866
1866
|
|
|
1867
1867
|
// \`rankPageRows\` is optional on \`DatabaseWriterLike\` (the D1 twin omits it),
|
|
1868
1868
|
// but the shard writer from \`createShardCtxDb\` always defines it. The sort
|
|
@@ -1883,7 +1883,7 @@ ${X}
|
|
|
1883
1883
|
protected override async runShardApplyCdc(args: RunShardApplyCdcArgs): Promise<{ applied: number }> {
|
|
1884
1884
|
this.ensureMigrated();
|
|
1885
1885
|
|
|
1886
|
-
${
|
|
1886
|
+
${Y}
|
|
1887
1887
|
|
|
1888
1888
|
await applyCdcChanges(writer, args.changes);
|
|
1889
1889
|
|
|
@@ -1895,7 +1895,7 @@ ${X}
|
|
|
1895
1895
|
return;
|
|
1896
1896
|
}
|
|
1897
1897
|
|
|
1898
|
-
runShardMigrations(this.sql as SqlExec, schema as unknown as SchemaLike, { cdc: config.cdc ?? false${
|
|
1898
|
+
runShardMigrations(this.sql as SqlExec, schema as unknown as SchemaLike, { cdc: config.cdc ?? false${ie} });
|
|
1899
1899
|
this.migrated = true;
|
|
1900
1900
|
}
|
|
1901
1901
|
|
|
@@ -1908,7 +1908,7 @@ ${X}
|
|
|
1908
1908
|
// dispatch path) fall back to the per-request fields as before.
|
|
1909
1909
|
const userId = options.identity ? options.identity.userId : this.getCurrentUserId();
|
|
1910
1910
|
const identity = options.identity ? options.identity.identity : this.getCurrentIdentity();
|
|
1911
|
-
${
|
|
1911
|
+
${Yt}${le}${ln}${Oe}${Ce}${Ae}${Ee}
|
|
1912
1912
|
const scheduler = (config.scheduler?.(env) ?? schedulerStub) as SchedulerLike;
|
|
1913
1913
|
// Build the storage adapter once and share it between \`ctx.storage\`
|
|
1914
1914
|
// and \`ctx.db.system._storage\` so both read the same R2 binding. The
|
|
@@ -1940,8 +1940,8 @@ ${tn} // \`ctx.db\`, wrapped in automatic instrumentation: by default
|
|
|
1940
1940
|
// breakdown) to the wide event rather than a span per call, so a
|
|
1941
1941
|
// handler making hundreds of queries stays readable. See
|
|
1942
1942
|
// \`instrumentDatabase\` for the \`"spans"\` / \`"off"\` levels.
|
|
1943
|
-
const db: DatabaseWriterLike = this.instrumentDb(createShardCtxDb(${
|
|
1944
|
-
${sn}${
|
|
1943
|
+
const db: DatabaseWriterLike = this.instrumentDb(createShardCtxDb(${Xt}), logFunctionPath, traceAnchor, observability);
|
|
1944
|
+
${sn}${Fe}
|
|
1945
1945
|
|
|
1946
1946
|
// \`ctx.trace\` / \`ctx.metrics\`: spans and measurements to the same sink.
|
|
1947
1947
|
// The trace anchor is threaded explicitly for the same reason \`identity\`
|
|
@@ -1949,7 +1949,7 @@ ${sn}${Pe}
|
|
|
1949
1949
|
// writing mutation's trace from the shared per-request field.
|
|
1950
1950
|
const trace = this.makeTracer(logFunctionPath, observability, traceAnchor);
|
|
1951
1951
|
const metrics = this.makeMetrics(logFunctionPath, observability);
|
|
1952
|
-
${
|
|
1952
|
+
${dn}
|
|
1953
1953
|
// \`ctx.now\`: the wall-clock instant (epoch ms) this function began,
|
|
1954
1954
|
// captured ONCE so the whole handler body sees a single stable value.
|
|
1955
1955
|
// Query/mutation handlers must be deterministic (they may be re-run on
|
|
@@ -1976,7 +1976,7 @@ ${cn}
|
|
|
1976
1976
|
scheduler,
|
|
1977
1977
|
span,
|
|
1978
1978
|
storage,
|
|
1979
|
-
trace,${Zt}${Ne}${
|
|
1979
|
+
trace,${Zt}${Ne}${cn}${ge}${Ie}${Le}${ke}${me}
|
|
1980
1980
|
};
|
|
1981
1981
|
${pn}${un}
|
|
1982
1982
|
ctx.runAction = (reference: FunctionReference, fnArgs: Record<string, unknown>) => dispatchRun("action", reference.__lunoraRef, fnArgs, ctx);
|
|
@@ -1986,30 +1986,30 @@ ${pn}${un}
|
|
|
1986
1986
|
return ctx;
|
|
1987
1987
|
}
|
|
1988
1988
|
};
|
|
1989
|
-
`},
|
|
1989
|
+
`},He=e=>{switch(e.kind){case"array":case"object":case"record":case"union":return{builder:"text",mode:"json",notNull:!0,typeAnnotation:N(e)};case"bigint":return{builder:"blob",mode:"bigint",notNull:!0};case"boolean":return{builder:"integer",mode:"boolean",notNull:!0};case"bytes":return{builder:"blob",mode:"buffer",notNull:!0};case"date":case"timestamp":return{builder:"integer",notNull:!0};case"from":return{builder:"text",notNull:!0,typeAnnotation:N(e)};case"id":return{builder:"text",notNull:!0};case"literal":{const t=e.literalValue??"";return t.startsWith('"')||t.startsWith("'")?{builder:"text",notNull:!0}:t==="true"||t==="false"?{builder:"integer",mode:"boolean",notNull:!0}:t==="null"?{builder:"text",notNull:!0}:{builder:"real",notNull:!0}}case"null":return{builder:"text",notNull:!0};case"number":return{builder:"real",notNull:!0};case"optional":return{...e.inner?He(e.inner):{builder:"text",notNull:!1},notNull:!1};case"storage":case"string":return{builder:"text",notNull:!0};default:return{builder:"text",notNull:!0}}},yt=(e,t)=>{const n=re(e);return n.kind==="id"&&n.tableName!==void 0&&t.has(n.tableName)?n.tableName:void 0},Nr=(e,t,n)=>{g(e,"drizzle column name");const r=He(t),o=r.mode?`, { mode: "${r.mode}" }`:"";let s=`${r.builder}("${e}"${o})`;r.typeAnnotation&&(s+=`.$type<${r.typeAnnotation}>()`);const i=yt(t,n);return i!==void 0&&(s+=`.references((): AnySQLiteColumn => ${i}._id)`),r.notNull&&(s+=".notNull()"),s},Tr=e=>{g(e.name,"drizzle index name");const t=e.unique?"uniqueIndex":"index",n=e.fields.map(r=>(g(r,"drizzle index field"),`t.${r}`)).join(", ");return` ${e.name}: ${t}("${e.name}").on(${n}),`},Ar=(e,t)=>{g(e.name,"table name");const n=[' _id: text("_id").primaryKey(),',' _creationTime: integer("_creationTime").notNull(),',...Object.entries(e.shape).map(([o,s])=>` ${o}: ${Nr(o,s,t)},`)].join(`
|
|
1990
1990
|
`),r=e.indexes.length>0?`, (t) => ({
|
|
1991
|
-
${e.indexes.map(
|
|
1991
|
+
${e.indexes.map(o=>Tr(o)).join(`
|
|
1992
1992
|
`)}
|
|
1993
1993
|
})`:"";return`export const ${e.name} = sqliteTable("${e.name}", {
|
|
1994
|
-
${
|
|
1995
|
-
}${r});`},Or=e=>e.typeAnnotation?.includes('Id<"')??!1,
|
|
1996
|
-
`;const
|
|
1994
|
+
${n}
|
|
1995
|
+
}${r});`},Or=e=>e.typeAnnotation?.includes('Id<"')??!1,Ir=(e,t)=>{const n=new Set(["integer","sqliteTable","text"]),r=new Set;let o=!1,s=!1;for(const i of e){for(const a of Object.values(i.shape)){const c=He(a);n.add(c.builder),s=s||Or(c),o=o||yt(a,t)!==void 0}for(const a of i.indexes)r.add(a.unique?"uniqueIndex":"index")}return{columns:[...n].toSorted((i,a)=>i.localeCompare(a)),indexes:[...r].toSorted((i,a)=>i.localeCompare(a)),needsAnyColumn:o,needsId:s}},rt=(e,t=!1)=>{if(e.length===0)return`${R}export {};
|
|
1996
|
+
`;const n=ne(t),r=new Set(e.map(h=>h.name)),{columns:o,indexes:s,needsAnyColumn:i,needsId:a}=Ir(e,r),c=[...s,...o].toSorted((h,y)=>h.localeCompare(y)),d=e.map(h=>Ar(h,r)).join(`
|
|
1997
1997
|
|
|
1998
|
-
`),
|
|
1999
|
-
`:"",
|
|
2000
|
-
`:""].join("");return`${
|
|
2001
|
-
${
|
|
2002
|
-
${u}
|
|
2003
|
-
`},Hr=(e,n=!1)=>{const t=e.tables.filter(a=>a.shardMode==="global"),r=e.tables.filter(a=>a.shardMode!=="global");return{global:D(nt(t,n),Ue),shard:D(nt(r,n),Ue)}},Jr=e=>{const n=new Map;for(const i of e){const s=n.get(i.cron);s?s.push(i):n.set(i.cron,[i])}const t=[...n.keys()].map(i=>` ${JSON.stringify(i)},`).join(`
|
|
2004
|
-
`),r=t.length>0?`
|
|
2005
|
-
${t}
|
|
2006
|
-
`:"",a=[...n.entries()].map(([i,s])=>{const d=s.map(u=>{const h=u.workflow?`workflow: ${JSON.stringify(u.workflow.binding)}`:`functionPath: ${JSON.stringify(u.functionPath)}`;return` { name: ${JSON.stringify(u.name)}, ${h}, args: ${JSON.stringify(u.args)} },`}).join(`
|
|
2007
|
-
`);return` ${JSON.stringify(i)}: [
|
|
1998
|
+
`),p=[i?`import type { AnySQLiteColumn } from "${n.serverDrizzle}";
|
|
1999
|
+
`:"",a?`import type { Id } from "./dataModel.js";
|
|
2000
|
+
`:""].join("");return`${R}import { ${c.join(", ")} } from "${n.serverDrizzle}";
|
|
2001
|
+
${p}
|
|
2008
2002
|
${d}
|
|
2003
|
+
`},Xr=(e,t=!1)=>{const n=e.tables.filter(o=>o.shardMode==="global"),r=e.tables.filter(o=>o.shardMode!=="global");return{global:E(rt(n,t),Ue),shard:E(rt(r,t),Ue)}},Zr=e=>{const t=new Map;for(const i of e){const a=t.get(i.cron);a?a.push(i):t.set(i.cron,[i])}const n=[...t.keys()].map(i=>` ${JSON.stringify(i)},`).join(`
|
|
2004
|
+
`),r=n.length>0?`
|
|
2005
|
+
${n}
|
|
2006
|
+
`:"",o=[...t.entries()].map(([i,a])=>{const c=a.map(d=>{const p=d.workflow?`workflow: ${JSON.stringify(d.workflow.binding)}`:`functionPath: ${JSON.stringify(d.functionPath)}`;return` { name: ${JSON.stringify(d.name)}, ${p}, args: ${JSON.stringify(d.args)} },`}).join(`
|
|
2007
|
+
`);return` ${JSON.stringify(i)}: [
|
|
2008
|
+
${c}
|
|
2009
2009
|
],`}).join(`
|
|
2010
|
-
`),o
|
|
2011
|
-
${
|
|
2012
|
-
`:"";return`${
|
|
2010
|
+
`),s=o.length>0?`
|
|
2011
|
+
${o}
|
|
2012
|
+
`:"";return`${R}/**
|
|
2013
2013
|
* One scheduled cron invocation. Exactly one target is set: \`functionPath\` is
|
|
2014
2014
|
* the \`namespace:fn\` dispatch ref (matches \`__lunoraRef\`), invoked on the
|
|
2015
2015
|
* shard; \`workflow\` is a \`WORKFLOW_*\` binding name whose durable workflow is
|
|
@@ -2033,11 +2033,11 @@ export const LUNORA_CRON_TRIGGERS: ReadonlyArray<string> = [${r}];
|
|
|
2033
2033
|
* Dispatcher map keyed by cron expression. The Worker's \`scheduled()\` handler
|
|
2034
2034
|
* looks up \`event.cron\` here and dispatches every job in the list.
|
|
2035
2035
|
*/
|
|
2036
|
-
export const LUNORA_CRONS: Record<string, ReadonlyArray<LunoraCronJob>> = {${
|
|
2037
|
-
`},
|
|
2038
|
-
`),t
|
|
2039
|
-
${
|
|
2040
|
-
`:"";return`${
|
|
2036
|
+
export const LUNORA_CRONS: Record<string, ReadonlyArray<LunoraCronJob>> = {${s}};
|
|
2037
|
+
`},eo=e=>{const t=[...e].toSorted((r,o)=>r.name.localeCompare(o.name)).map(r=>{const o=[`name: ${JSON.stringify(r.name)}`,`table: ${JSON.stringify(r.table)}`];return r.field!==void 0&&o.push(`field: ${JSON.stringify(r.field)}`),r.dimensions!==void 0&&o.push(`dimensions: ${JSON.stringify(r.dimensions)}`),r.metric!==void 0&&o.push(`metric: ${JSON.stringify(r.metric)}`),r.metadata!==void 0&&o.push(`metadata: ${JSON.stringify(r.metadata)}`),` { ${o.join(", ")} },`}).join(`
|
|
2038
|
+
`),n=t.length>0?`
|
|
2039
|
+
${t}
|
|
2040
|
+
`:"";return`${R}/**
|
|
2041
2041
|
* One vector index declared in \`schema.ts\` — an inline \`.vectorize()\` column
|
|
2042
2042
|
* or a standalone \`defineVectorIndex()\`. \`field\` is the source column (absent
|
|
2043
2043
|
* for a \`select\`-derived Shape B index); \`metadata\` lists the row fields
|
|
@@ -2057,5 +2057,5 @@ export interface LunoraVectorIndex {
|
|
|
2057
2057
|
* Vectorize cannot enumerate indexes at runtime, so the worker passes this to
|
|
2058
2058
|
* \`createWorker({ vectorIntrospector })\` to back the studio's vector browser.
|
|
2059
2059
|
*/
|
|
2060
|
-
export const LUNORA_VECTOR_INDEXES: ReadonlyArray<LunoraVectorIndex> = [${
|
|
2061
|
-
`},
|
|
2060
|
+
export const LUNORA_VECTOR_INDEXES: ReadonlyArray<LunoraVectorIndex> = [${n}];
|
|
2061
|
+
`},to=e=>[...new Set(e.map(t=>t.cron))];export{jr as A,gn as C,R as G,En as U,Wr as a,Kr as b,Vr as c,Zr as d,Jr as e,qr as f,Xr as g,Hr as h,Qr as i,Yr as j,eo as k,Gr as l,to as m,Zn as n,zr as o,Ur as p};
|