@lunora/codegen 1.0.0-alpha.272 → 1.0.0-alpha.274

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.
@@ -1,11 +1,11 @@
1
- import{relative as ve,isAbsolute as ke,sep as we}from"node:path";import{LunoraError as V}from"@lunora/errors";import{CAPABILITIES as Ie}from"./CAPABILITY_PROBES-brcmKenl.mjs";import{p as $e}from"./ir-DBSvhNa-.mjs";import{a as p,G as Be,u as Re,d as Oe}from"./shared-BXUKWh7t.mjs";const Ne=/\.([cm]?)tsx?$/u,Me=(d,l=[])=>{const r=new Set;for(const t of d.tables)for(const i of Object.values(t.shape)){const n=Re(i);n.kind==="storage"&&typeof n.bucket=="string"&&n.bucket!==""&&r.add(n.bucket)}for(const t of l)t!==""&&t!=="default"&&r.add(t);return["default",...[...r].toSorted((t,i)=>t.localeCompare(i))]},Qe=({agents:d=[],capabilities:l=new Set,containers:r=[],env:t,hasVectors:i=!0,hasFlags:n=!1,hasNotify:_=!1,identity:s,queues:R=[],schema:O,generatedDirectory:N="",services:y=[],storageRuleBuckets:H=[],topics:M=[],useUmbrella:z=!1,workflows:C=[]}={})=>{const o=Oe(z),U=Me(O??{tables:[]},H).map(e=>JSON.stringify(e)).join(" | "),D=e=>e.sandbox===!0?"SandboxContainerAccessor":"ContainerAccessor",J=[...new Set(r.map(e=>D(e)))].toSorted((e,a)=>e.localeCompare(a)),K=r.length>0?`import type { ${J.join(", ")} } from "@lunora/container";
2
- `:"",Y=r.length>0?`
3
- readonly containers: {${r.map(e=>`
4
- readonly ${e.exportName}: ${D(e)};`).join("")}
5
- };`:"",A=[...l.has("ai")?[" /** Workers AI binding (the conventional `env.AI`), narrowing `ctx.ai`. */\n readonly AI?: unknown;"]:[],...r.map(e=>(p(e.bindingName,`container binding "${e.bindingName}"`),` /** Durable Object namespace for the \`${e.exportName}\` container. */
6
- readonly ${e.bindingName}?: unknown;`)),...R.map(e=>(p(e.bindingName,`queue binding "${e.bindingName}"`),` /** Queue producer binding for the \`${e.exportName}\` queue. */
1
+ import{CAPABILITIES as Re}from"./CAPABILITY_PROBES-brcmKenl.mjs";import{p as Se}from"./ir-DBSvhNa-.mjs";import{join as q,relative as m,dirname as Q,isAbsolute as De,sep as Me}from"node:path";import{ts as i,Project as Ce}from"ts-morph";import{G as Z,a as $,u as Ne,d as Ae}from"./shared-BXUKWh7t.mjs";const ee=/(?:\.d)?\.([cm]?)tsx?$/u,Fe=t=>t.replace(ee,".d.$1ts"),te=(t,n)=>{const a=m(t,n).split(Me).join("/").replace(ee,".$1js");return a.startsWith(".")?a:`./${a}`},ae=t=>t.replaceAll("\\","/"),E=(t,n,a)=>ae(q(t,Fe(m(n,a)))),Pe=t=>te(".",q("services",t.name,m(Q(t.wranglerPath),t.main))),We=t=>{const n=[],a=r=>{(i.isImportDeclaration(r)||i.isExportDeclaration(r))&&r.moduleSpecifier!==void 0&&i.isStringLiteral(r.moduleSpecifier)?n.push(r.moduleSpecifier):i.isImportTypeNode(r)&&i.isLiteralTypeNode(r.argument)&&i.isStringLiteral(r.argument.literal)&&n.push(r.argument.literal),i.forEachChild(r,a)};return a(t),n},Ge=(t,n)=>{const a=Q(t.wranglerPath),r=m(a,t.main);if(r.startsWith("..")||De(r))throw new Error(`@lunora/codegen: service "${t.name}": its entry module (${t.main}) must be inside ${a} to be typed as RPC`);const d=q(n,"services",t.name),c=i.findConfigFile(a,o=>i.sys.fileExists(o)),p=new Ce({compilerOptions:{composite:!1,declaration:!0,declarationMap:!1,emitDeclarationOnly:!0,incremental:!1,noEmit:!1,noEmitOnError:!1,outDir:d,rootDir:a},skipAddingFilesFromTsConfig:!0,...c===void 0?{}:{tsConfigFilePath:c}});p.addSourceFileAtPath(t.main),p.resolveSourceFileDependencies();const u={...p.getCompilerOptions(),preserveSymlinks:!0},x=new Map(p.getSourceFiles().map(o=>o.getFilePath()).filter(o=>!o.endsWith(".d.ts")&&!m(a,o).startsWith("..")).map(o=>[E(d,a,o),o])),y={};for(const o of p.emitToMemory({emitOnlyDtsFiles:!0}).getFiles()){const g=x.get(ae(o.filePath));if(g===void 0)continue;const h=i.createSourceFile(o.filePath,o.text,i.ScriptTarget.Latest,!1);let{text:f}=o;for(const b of We(h).toReversed()){const s=i.resolveModuleName(b.text,g,u,i.sys).resolvedModule?.resolvedFileName;if(s===void 0)continue;const T=E(d,a,s),v=x.has(T)?T:s;f=`${f.slice(0,b.getStart(h))}${JSON.stringify(te(Q(o.filePath),v))}${f.slice(b.getEnd())}`}y[m(n,o.filePath)]=`${Z}${f}`}if(y[m(n,E(d,a,t.main))]===void 0)throw new Error(`@lunora/codegen: service "${t.name}": TypeScript emitted no declaration for its entry module ${t.main}`);return y},je=(t,n=[])=>{const a=new Set;for(const r of t.tables)for(const d of Object.values(r.shape)){const c=Ne(d);c.kind==="storage"&&typeof c.bucket=="string"&&c.bucket!==""&&a.add(c.bucket)}for(const r of n)r!==""&&r!=="default"&&a.add(r);return["default",...[...a].toSorted((r,d)=>r.localeCompare(d))]},He=({agents:t=[],capabilities:n=new Set,containers:a=[],env:r,hasVectors:d=!0,hasFlags:c=!1,hasNotify:p=!1,identity:u,queues:x=[],schema:y,services:o=[],storageRuleBuckets:g=[],topics:h=[],useUmbrella:f=!1,workflows:b=[]}={})=>{const s=Ae(f),T=je(y??{tables:[]},g).map(e=>JSON.stringify(e)).join(" | "),v=e=>e.sandbox===!0?"SandboxContainerAccessor":"ContainerAccessor",re=[...new Set(a.map(e=>v(e)))].toSorted((e,l)=>e.localeCompare(l)),oe=a.length>0?`import type { ${re.join(", ")} } from "@lunora/container";
2
+ `:"",ne=a.length>0?`
3
+ readonly containers: {${a.map(e=>`
4
+ readonly ${e.exportName}: ${v(e)};`).join("")}
5
+ };`:"",L=[...n.has("ai")?[" /** Workers AI binding (the conventional `env.AI`), narrowing `ctx.ai`. */\n readonly AI?: unknown;"]:[],...a.map(e=>($(e.bindingName,`container binding "${e.bindingName}"`),` /** Durable Object namespace for the \`${e.exportName}\` container. */
6
+ readonly ${e.bindingName}?: unknown;`)),...x.map(e=>($(e.bindingName,`queue binding "${e.bindingName}"`),` /** Queue producer binding for the \`${e.exportName}\` queue. */
7
7
  readonly ${e.bindingName}?: unknown;`))].join(`
8
- `),X=`
8
+ `),se=`
9
9
 
10
10
  /**
11
11
  * This project's Cloudflare bindings, as far as codegen can discover them from
@@ -18,24 +18,24 @@ import{relative as ve,isAbsolute as ke,sep as we}from"node:path";import{LunoraEr
18
18
  * surface, so treat them as \`Fetcher\`/\`Service<unknown>\` and cast.
19
19
  */
20
20
  export interface CloudflareBindings {
21
- readonly [binding: string]: unknown;${A?`
22
- ${A}`:""}
21
+ readonly [binding: string]: unknown;${L?`
22
+ ${L}`:""}
23
23
  }
24
24
 
25
25
  /** Alias for {@link CloudflareBindings} — the typed shape of \`env\`. */
26
- export type Env = CloudflareBindings;`,S=e=>Ie.map(a=>a.tier!==void 0&&e.includes(a.tier)&&l.has(a.key)?a.serverCtxField:"").join(""),W=S(["every"]),Z=S(["every","action"]),c=i&&(O?.vectorIndexes.length??0)>0,m=c?' | "vectors"':"",F=c?`
27
- readonly vectors: VectorSearch<VectorIndexName>;`:"",ee=c?`
28
- readonly vectors: VectorSearchReader<VectorIndexName>;`:"",te=c?`import type { VectorSearch, VectorSearchReader } from "${o.server}";
26
+ export type Env = CloudflareBindings;`,V=e=>Re.map(l=>l.tier!==void 0&&e.includes(l.tier)&&n.has(l.key)?l.serverCtxField:"").join(""),_=V(["every"]),ie=V(["every","action"]),k=d&&(y?.vectorIndexes.length??0)>0,I=k?' | "vectors"':"",G=k?`
27
+ readonly vectors: VectorSearch<VectorIndexName>;`:"",le=k?`
28
+ readonly vectors: VectorSearchReader<VectorIndexName>;`:"",de=k?`import type { VectorSearch, VectorSearchReader } from "${s.server}";
29
29
  import type { VectorIndexName } from "./dataModel.js";
30
- `:"",h=n?`
30
+ `:"",O=c?`
31
31
  /** Feature-flag evaluation (OpenFeature). Reads are memoized per request; evaluations never throw — a provider error resolves to the supplied default. */
32
- readonly flags: import("${o.flags}").LunoraFlags;`:"",b=_?`
32
+ readonly flags: import("${s.flags}").LunoraFlags;`:"",B=p?`
33
33
  /** 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. */
34
34
  readonly notify: import("@lunora/notify").LunoraNotify;
35
35
  /** Device push sub-facade — the same object as ctx.notify.push (register / send / broadcast). Sends belong in action handlers. */
36
- readonly push: import("@lunora/notify").LunoraPush;`:"",u=C.length>0,ae=u?`import type { WorkflowHandle } from "@lunora/workflow";
36
+ readonly push: import("@lunora/notify").LunoraPush;`:"",w=b.length>0,ce=w?`import type { WorkflowHandle } from "@lunora/workflow";
37
37
  import type * as lunoraWorkflowDefinitions from "../workflows.js";
38
- `:"",re=u?`
38
+ `:"",ue=w?`
39
39
 
40
40
  /** Params type carried by a \`defineWorkflow\` definition (its phantom \`__params\`). */
41
41
  type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params }
@@ -46,56 +46,56 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
46
46
 
47
47
  /** This project's declared workflows, addressable from \`ctx.workflows\` by their \`lunora/workflows.ts\` export name. */
48
48
  export interface LunoraWorkflows {
49
- ${C.map(e=>` get(name: ${JSON.stringify(e.exportName)}): WorkflowHandle<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${e.exportName}>>;`).join(`
49
+ ${b.map(e=>` get(name: ${JSON.stringify(e.exportName)}): WorkflowHandle<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${e.exportName}>>;`).join(`
50
50
  `)}
51
- }`:"",Q=u?' | "workflows"':"",j=u?`
52
- readonly workflows: LunoraWorkflows;`:"",P=$e(R),f=P.length>0,x=M.length>0,g=[...f?["QueueProducer"]:[],...x?["TopicPublisher"]:[]],oe=g.length>0?`import type { ${g.join(", ")} } from "@lunora/queue";
53
- import type * as lunoraQueueDefinitions from "../queues.js";
54
- `:"",ne=g.length>0?"\n\n/** Message body type carried by a `defineQueue` / `defineTopic` definition (its phantom `__lunoraBody`). */\ntype QueueBodyOf<Definition> = Definition extends { __lunoraBody?: infer Body } ? (unknown extends Body ? unknown : NonNullable<Body>) : unknown;":"",se=f?`
51
+ }`:"",H=w?' | "workflows"':"",U=w?`
52
+ readonly workflows: LunoraWorkflows;`:"",R=Se(x),S=R.length>0,D=h.length>0,M=[...S?["QueueProducer"]:[],...D?["TopicPublisher"]:[]],z=[...new Set([...R,...h].map(e=>e.filePath))].toSorted((e,l)=>+(l==="queues")-+(e==="queues")||e.localeCompare(l)),C=e=>e==="queues"?"lunoraQueueDefinitions":`lunoraQueueDefinitions${String(z.indexOf(e))}`,pe=M.length>0?`import type { ${M.join(", ")} } from "@lunora/queue";
53
+ ${z.map(e=>`import type * as ${C(e)} from "../${e}.js";
54
+ `).join("")}`:"",me=M.length>0?"\n\n/** Message body type carried by a `defineQueue` / `defineTopic` definition (its phantom `__lunoraBody`). */\ntype QueueBodyOf<Definition> = Definition extends { __lunoraBody?: infer Body } ? (unknown extends Body ? unknown : NonNullable<Body>) : unknown;":"",ye=S?`
55
55
 
56
56
  /** This project's declared queues, addressable from \`ctx.queues\` by their \`lunora/queues.ts\` export name. */
57
57
  export interface LunoraQueues {
58
- ${P.map(e=>` readonly ${e.exportName}: QueueProducer<QueueBodyOf<typeof lunoraQueueDefinitions.${e.exportName}>>;`).join(`
58
+ ${R.map(e=>` readonly ${e.exportName}: QueueProducer<QueueBodyOf<typeof ${C(e.filePath)}.${e.exportName}>>;`).join(`
59
59
  `)}
60
- }`:"",ie=x?`
60
+ }`:"",he=D?`
61
61
 
62
62
  /** This project's declared topics, addressable from \`ctx.topics\` by their \`lunora/queues.ts\` export name. */
63
63
  export interface LunoraTopics {
64
- ${M.map(e=>` readonly ${e.exportName}: TopicPublisher<QueueBodyOf<typeof lunoraQueueDefinitions.${e.exportName}>>;`).join(`
64
+ ${h.map(e=>` readonly ${e.exportName}: TopicPublisher<QueueBodyOf<typeof ${C(e.filePath)}.${e.exportName}>>;`).join(`
65
65
  `)}
66
- }`:"",de=`${ne}${se}${ie}`,E=f?`
67
- readonly queues: LunoraQueues;`:"",q=x?`
68
- readonly topics: LunoraTopics;`:"",T=y.length>0,le=e=>{if(N==="")throw new V("INTERNAL","@lunora/codegen: emitServer needs `generatedDirectory` to import an RPC service's types");const a=ve(N,e);if(ke(a))throw new V("INTERNAL",`@lunora/codegen: an RPC service's entry (${e}) must be on the same drive as the app`);const B=a.split(we).join("/").replace(Ne,".$1js");return B.startsWith(".")?B:`./${B}`},L=y.filter(e=>e.rpcEntrypoint!==void 0),ce=L.length>0?"ServiceFetcher, ServiceRpc":"ServiceFetcher",ue=T?`import type { ${ce} } from "${o.server}";
69
- ${L.map(e=>`import type * as lunoraService_${e.name} from ${JSON.stringify(le(e.main))};
70
- `).join("")}`:"",pe=T?`
66
+ }`:"",fe=`${me}${ye}${he}`,J=S?`
67
+ readonly queues: LunoraQueues;`:"",K=D?`
68
+ readonly topics: LunoraTopics;`:"",N=o.length>0,Y=o.filter(e=>e.rpcEntrypoint!==void 0),be=Y.length>0?"ServiceFetcher, ServiceRpc":"ServiceFetcher",xe=N?`import type { ${be} } from "${s.server}";
69
+ ${Y.map(e=>`import type * as lunoraService_${e.name} from ${JSON.stringify(Pe(e))};
70
+ `).join("")}`:"",ge=N?`
71
71
 
72
72
  /** This project's service bindings (\`lunora.config\` \`services\`), addressable from \`ctx.services\` in actions. */
73
73
  export interface LunoraServices {
74
- ${y.map(e=>{p(e.name,`service "${e.name}"`);const a=e.rpcEntrypoint===void 0?"ServiceFetcher":`ServiceRpc<typeof lunoraService_${e.name}.${e.rpcEntrypoint}>`;return` readonly ${e.name}: ${a};`}).join(`
74
+ ${o.map(e=>{$(e.name,`service "${e.name}"`);const l=e.rpcEntrypoint===void 0?"ServiceFetcher":`ServiceRpc<typeof lunoraService_${e.name}.${e.rpcEntrypoint}>`;return` readonly ${e.name}: ${l};`}).join(`
75
75
  `)}
76
- }`:"",ye=T?`
77
- readonly services: LunoraServices;`:"",v=d.length>0,me=v?`import type { AgentHandle } from "@lunora/agent";
78
- `:"",he=v?`
76
+ }`:"",Te=N?`
77
+ readonly services: LunoraServices;`:"",A=t.length>0,ve=A?`import type { AgentHandle } from "@lunora/agent";
78
+ `:"",ke=A?`
79
79
 
80
80
  /** This project's declared agents, addressable from \`ctx.agents\` by their \`lunora/agents.ts\` export name. */
81
81
  export interface LunoraAgents {
82
- ${d.map(e=>(p(e.exportName,`agent export "${e.exportName}"`),` readonly ${e.exportName}: AgentHandle;`)).join(`
82
+ ${t.map(e=>($(e.exportName,`agent export "${e.exportName}"`),` readonly ${e.exportName}: AgentHandle;`)).join(`
83
83
  `)}
84
- }`:"",G=v?`
85
- readonly agents: LunoraAgents;`:"",be=s?`import type { InferIdentity } from "${o.server}";
84
+ }`:"",X=A?`
85
+ readonly agents: LunoraAgents;`:"",we=u?`import type { InferIdentity } from "${s.server}";
86
86
  import type * as lunoraIdentityContract from "../identity.js";
87
- `:"",fe=s?`
87
+ `:"",$e=u?`
88
88
 
89
89
  /** 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. */
90
- export type Identity = InferIdentity<typeof lunoraIdentityContract.${s.exportName}>;
90
+ export type Identity = InferIdentity<typeof lunoraIdentityContract.${u.exportName}>;
91
91
 
92
92
  /** \`ctx.auth\` narrowed so \`getIdentity()\` resolves the declared {@link Identity} contract instead of the untyped claim bag. */
93
- type NarrowedAuth = Omit<QueryCtxBase["auth"], "getIdentity"> & { getIdentity: () => Promise<Identity | null> };`:"",k=s?' | "auth"':"",w=s?`
94
- readonly auth: NarrowedAuth;`:"",xe=s?", Identity":"",ge=t?`import type * as lunoraEnvContract from "../env.js";
95
- `:"",Te=t?`
93
+ type NarrowedAuth = Omit<QueryCtxBase["auth"], "getIdentity"> & { getIdentity: () => Promise<Identity | null> };`:"",F=u?' | "auth"':"",P=u?`
94
+ readonly auth: NarrowedAuth;`:"",Ie=u?", Identity":"",Oe=r?`import type * as lunoraEnvContract from "../env.js";
95
+ `:"",Be=r?`
96
96
 
97
97
  /** This app's declared env contract (\`defineEnv\` in \`lunora/env.ts\`) — the validated, coercion-aware shape of \`ctx.env\`. */
98
- export type LunoraEnv = ReturnType<typeof lunoraEnvContract.${t.exportName}>;`:"",I=t?' | "env"':"",$=t?"\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`${Be}import { createPolicyDsl, defineMutator as defineMutatorBase, initLunora, v as vBase } from "${o.server}";
98
+ export type LunoraEnv = ReturnType<typeof lunoraEnvContract.${r.exportName}>;`:"",W=r?' | "env"':"",j=r?"\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`${Z}import { createPolicyDsl, defineMutator as defineMutatorBase, initLunora, v as vBase } from "${s.server}";
99
99
  import type {
100
100
  ActionBuilder,
101
101
  ActionCtx as ActionCtxBase,
@@ -117,7 +117,7 @@ import type {
117
117
  Storage as StorageBase,
118
118
  TableReader,
119
119
  Validator,
120
- } from "${o.server}";
120
+ } from "${s.server}";
121
121
 
122
122
  import type {
123
123
  DatabaseReaderFacade as DatabaseReaderFacadeOf,
@@ -126,7 +126,7 @@ import type {
126
126
  TableReaderFacade as TableReaderFacadeOf,
127
127
  TableWriterFacade as TableWriterFacadeOf,
128
128
  WithArg as WithArgOf,
129
- } from "${o.serverDataModel}";
129
+ } from "${s.serverDataModel}";
130
130
 
131
131
  export type {
132
132
  AggregateOp,
@@ -149,10 +149,10 @@ export type {
149
149
  Where,
150
150
  WhereOf,
151
151
  WhereOperators,
152
- } from "${o.serverDataModel}";
152
+ } from "${s.serverDataModel}";
153
153
 
154
154
  import type { DataModel, Doc, GeoIndexNamesByTable, Id as IdOfTable, IndexNamesByTable, Insert, InsertModel, RankIndexNamesByTable, Relations, SearchIndexNamesByTable, TableName } from "./dataModel.js";
155
- ${te}${K}${ae}${oe}${ue}${me}${be}${ge}
155
+ ${de}${oe}${ce}${pe}${xe}${ve}${we}${Oe}
156
156
  export type { AppTableName, DataModel, Doc, Id, TableName } from "./dataModel.js";
157
157
 
158
158
  /**
@@ -212,7 +212,7 @@ export interface OrmWriter extends OrmReader {
212
212
  }
213
213
 
214
214
  /** Storage buckets this schema declares (\`v.storage("name")\`), narrowing \`ctx.storage.bucket(name)\`. */
215
- export type StorageBucketName = ${U};${X}${re}${de}${pe}${he}${fe}${Te}
215
+ export type StorageBucketName = ${T};${se}${ue}${fe}${ge}${ke}${$e}${Be}
216
216
 
217
217
  /**
218
218
  * Project-typed contexts. The base contexts from \`@lunora/server\` are
@@ -275,22 +275,22 @@ type AsIdTable<T extends string> = T extends TableName ? T : string extends T ?
275
275
  */
276
276
  type TypedAsId = <T extends string>(tableName: AsIdTable<T>, id: string) => IdOfTable<T & TableName>;
277
277
 
278
- export interface QueryCtx extends Omit<QueryCtxBase, "db" | "storage"${m}${k}${I}> {
278
+ export interface QueryCtx extends Omit<QueryCtxBase, "db" | "storage"${I}${F}${W}> {
279
279
  readonly db: Omit<DatabaseReader, "asId" | "query" | "get"> & DatabaseReaderFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
280
280
  readonly orm: OrmReader;
281
- readonly storage: ReadOnlyStorage<StorageBucketName>;${ee}${W}${h}${b}${$}${w}
281
+ readonly storage: ReadOnlyStorage<StorageBucketName>;${le}${_}${O}${B}${j}${P}
282
282
  }
283
283
 
284
- export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${m}${Q}${k}${I}> {
284
+ export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${I}${H}${F}${W}> {
285
285
  readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
286
286
  readonly orm: OrmWriter;
287
- readonly storage: MutationStorage<StorageBucketName>;${F}${W}${h}${b}${$}${j}${E}${q}${G}${w}
287
+ readonly storage: MutationStorage<StorageBucketName>;${G}${_}${O}${B}${j}${U}${J}${K}${X}${P}
288
288
  }
289
289
 
290
- export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${m}${Q}${k}${I}> {
290
+ export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${I}${H}${F}${W}> {
291
291
  readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
292
292
  readonly orm: OrmWriter;
293
- readonly storage: StorageBase<StorageBucketName>;${F}${Z}${Y}${h}${b}${ye}${$}${j}${E}${q}${G}${w}
293
+ readonly storage: StorageBase<StorageBucketName>;${G}${ie}${ne}${O}${B}${Te}${j}${U}${J}${K}${X}${P}
294
294
  }
295
295
 
296
296
  /**
@@ -323,7 +323,7 @@ export const internalAction = lunoraBuilders.internalAction as unknown as Intern
323
323
  /**
324
324
  * \`defineMutator\` bound to this project's typed {@link MutationCtx} — declare
325
325
  * custom mutators (\`lunora/mutators.ts\`) with it instead of importing from
326
- * \`${o.server}\`, and the authoritative \`server\` impl's \`ctx\` carries the
326
+ * \`${s.server}\`, and the authoritative \`server\` impl's \`ctx\` carries the
327
327
  * schema-typed \`ctx.db\` (\`ctx.db.query("nodes")\` resolves \`Doc<"nodes">\`,
328
328
  * \`ctx.db.patch(id, …)\` takes an \`Id<"nodes">\`) with no hand-written ctx type and
329
329
  * no \`as unknown as\` cast. Runtime-identical to the package export; only the
@@ -348,7 +348,7 @@ export const defineMutator = defineMutatorBase as unknown as <Args extends Recor
348
348
  * Runtime-identical to \`@lunora/server\`'s \`definePolicy\`; only the types narrow,
349
349
  * so the \`rls()\` chain discovers a policy authored either way the same.
350
350
  */
351
- export const definePolicy = createPolicyDsl<DataModel, Relations${xe}>();
351
+ export const definePolicy = createPolicyDsl<DataModel, Relations${Ie}>();
352
352
 
353
353
  /**
354
354
  * The validator builder \`v\`, with \`v.id(...)\` constrained to THIS schema's
@@ -365,4 +365,4 @@ export const definePolicy = createPolicyDsl<DataModel, Relations${xe}>();
365
365
  export const v = vBase as unknown as Omit<typeof vBase, "id"> & {
366
366
  id: <T extends TableName>(table: T) => ColumnValidator<IdOfTable<T>, IdOfTable<T>>;
367
367
  };
368
- `};export{Qe as default};
368
+ `};export{Ge as a,He as e};
@@ -1,4 +1,4 @@
1
- import{LunoraError as vt}from"@lunora/errors";import{serializeSchemaSnapshot as kt,hashSchemaSnapshot as St}from"./SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs";import{isHyperdriveGlobalTable as Rt,isD1GlobalTable as xt}from"./isD1GlobalTable-udvHAAzD.mjs";import{p as At,i as Dt}from"./ir-DBSvhNa-.mjs";import{r as h}from"./json-data-Chfs2Cz5.mjs";import{r as C,e as Tt,a as Ot,b as Et,c as Ct,d as Lt,f as It,g as _t,h as Mt,i as Pt,j as qt,k as Nt,l as $t,m as Ft,n as Ut,o as Bt,p as Wt,q as jt}from"./shard-runtime-WWedZtLA.mjs";import{u as K,i as Ht,G as Vt,d as Kt}from"./shared-BXUKWh7t.mjs";const Gt=` /**
1
+ import{LunoraError as vt}from"@lunora/errors";import{serializeSchemaSnapshot as kt,hashSchemaSnapshot as St}from"./SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs";import{isHyperdriveGlobalTable as Rt,isD1GlobalTable as xt}from"./isD1GlobalTable-udvHAAzD.mjs";import{p as At,i as Dt}from"./ir-DBSvhNa-.mjs";import{r as h}from"./json-data-Chfs2Cz5.mjs";import{r as C,e as Tt,a as Ot,b as Et,c as Ct,d as Lt,f as It,g as _t,h as Mt,i as Pt,j as qt,k as Nt,l as $t,m as Ft,n as Ut,o as Bt,p as Wt,q as jt}from"./shard-runtime-DGrBvQWg.mjs";import{u as K,i as Ht,G as Vt,d as Kt}from"./shared-BXUKWh7t.mjs";const Gt=` /**
2
2
  * The bare writer every admin/maintenance entry point writes through.
3
3
  *
4
4
  * Admin and maintenance writes go through the SAME reactive-cache hooks as a
@@ -1,4 +1,4 @@
1
- import{s as b}from"./ir-DBSvhNa-.mjs";import{r as y}from"./json-data-Chfs2Cz5.mjs";import{CAPABILITIES as $}from"./CAPABILITY_PROBES-brcmKenl.mjs";import{a as c,G as p}from"./shared-BXUKWh7t.mjs";const I=e=>e?{importFragment:"serveRelationFanout, ",override:`
1
+ import{s as b}from"./ir-DBSvhNa-.mjs";import{r as y}from"./json-data-Chfs2Cz5.mjs";import{CAPABILITIES as $}from"./CAPABILITY_PROBES-brcmKenl.mjs";import{a as u,G as p}from"./shared-BXUKWh7t.mjs";const I=e=>e?{importFragment:"serveRelationFanout, ",override:`
2
2
  protected override async runRelationFanoutRead(functionPath: string, args: Record<string, unknown>): Promise<unknown> {
3
3
  this.ensureMigrated();
4
4
 
@@ -6,12 +6,12 @@ import{s as b}from"./ir-DBSvhNa-.mjs";import{r as y}from"./json-data-Chfs2Cz5.mj
6
6
 
7
7
  return serveRelationFanout(schema as unknown as SchemaLike, db, functionPath, args);
8
8
  }
9
- `}:{importFragment:"",override:""},g=(e,r,t,{cast:n="",sync:o=[]}={})=>{const i=`throw new Error(${JSON.stringify(r)});`,u=t.map(a=>` ${a}: ${o===!0||o.includes(a)?"":"async "}() => {
9
+ `}:{importFragment:"",override:""},g=(e,r,t,{cast:n="",sync:o=[]}={})=>{const i=`throw new Error(${JSON.stringify(r)});`,c=t.map(a=>` ${a}: ${o===!0||o.includes(a)?"":"async "}() => {
10
10
  ${i}
11
11
  },`).join(`
12
12
  `);return`
13
13
  const ${e} = {
14
- ${u}
14
+ ${c}
15
15
  }${n};
16
16
  `},f={build:"",configField:"",contextField:"",importLines:[],stub:""},W=e=>e.size===0?{configField:"",constant:"",override:""}:{configField:"\n /** The `ShardRegistryDO` namespace (typically `env.SHARD_REGISTRY`). This shard registers its key for each `.shardBy()` table it writes, so cross-shard export, sync and migrations reach it. */\n shardRegistry?: (env: Record<string, unknown>) => unknown;",constant:`
17
17
  /** The \`.shardBy()\` tables this shard registers with the shard registry when it writes them. */
@@ -22,14 +22,14 @@ const SHARDED_TABLES: ReadonlySet<string> = new Set([${[...e].map(r=>JSON.string
22
22
 
23
23
  return namespace === undefined ? undefined : { namespace, shardedTables: SHARDED_TABLES };
24
24
  }
25
- `},q=(e,r)=>e?{build:`
25
+ `},B=(e,r)=>e?{build:`
26
26
  const flags: import("${r}").LunoraFlags = createFlags(flagsConfig, env, {
27
27
  provider: () => config.flags?.(env),
28
28
  targetingKey: () => flagsConfig.identify?.({ identity: identity ?? null, userId: userId ?? null }),
29
29
  });
30
30
  `,configField:`
31
31
  flags?: (env: Record<string, unknown>) => import("${r}").Provider;`,contextField:`
32
- flags,`,importLines:[`import { createFlags } from "${r}";`,'import flagsConfig from "../flags.js";'],stub:""}:f,B=e=>e?{build:`
32
+ flags,`,importLines:[`import { createFlags } from "${r}";`,'import flagsConfig from "../flags.js";'],stub:""}:f,q=e=>e?{build:`
33
33
  const { notify, push } = createNotify(notifyConfig, env, { log, metrics });
34
34
  `,configField:"",contextField:`
35
35
  notify,
@@ -65,7 +65,7 @@ const LUNORA_FLAG_KEYS = ${y(e,'ReadonlyArray<{ key: string; type: "boolean" | "
65
65
 
66
66
  return { configured: true, flags: evaluations };
67
67
  }
68
- `,u=`
68
+ `,c=`
69
69
  protected override runFlagSubscriptionRead(_functionPath: string, args: Record<string, unknown>, identity?: SubscriptionIdentity): Promise<unknown> {${n("() => flagsConfig.identify?.({ identity: identity?.identity ?? null, userId: identity?.userId ?? null })")}
70
70
  const key = typeof args.key === "string" ? args.key : "";
71
71
 
@@ -98,7 +98,7 @@ const LUNORA_FLAG_KEYS = ${y(e,'ReadonlyArray<{ key: string; type: "boolean" | "
98
98
 
99
99
  return flags.boolean(key, typeof args.default === "boolean" ? args.default : false, context);
100
100
  }
101
- `;return{constant:o,evaluateOverride:i,subscriptionOverride:u}},v=()=>({build:`
101
+ `;return{constant:o,evaluateOverride:i,subscriptionOverride:c}},v=()=>({build:`
102
102
  const aiBinding = config.ai?.(env) ?? (env as Record<string, unknown>).AI;
103
103
  // Correlate AI-Gateway-routed calls with the Lunora trace: thread the
104
104
  // function path + trace id into createAi, which folds them into the
@@ -133,7 +133,7 @@ const LUNORA_FLAG_KEYS = ${y(e,'ReadonlyArray<{ key: string; type: "boolean" | "
133
133
  ? lazyX402Pay(config.x402(env), { getSecret: (name: string) => secrets.get(name) })
134
134
  : x402Stub;
135
135
  `,configField:`
136
- x402?: (env: Record<string, unknown>) => X402PayConfig;`,importLines:['import type { X402Pay, X402PayConfig } from "@lunora/x402/pay";','import { lazyX402Pay } from "@lunora/x402/pay";'],stub:g("x402Stub: X402Pay","ctx.x402: no pay rail configured. Pass `x402` to createShardDO().",["fetch"],{cast:" as unknown as X402Pay",sync:["fetch"]})}),S={access:k,ai:v,r2sql:R,x402:N},w=e=>e.shardBinding==="bespoke",L=e=>typeof e.shardBinding=="object",d=" ",A=(e,r,t)=>{const n=`${e}Binding`,{factory:o}=t;let i=`(${n} as ${r})`;if(o!==void 0){const u=`${n} as ${t.bindingType??r}`;i=o.option===void 0?`${o.name}(${u})`:`${o.name}({ ${o.option}: ${u} })`}return`${n} ? ${i} : ${e}Stub`},C=(e,r,t)=>{const n=A(e,r,t),o=`${d}const ${e}Binding = config.${e}?.(env) ?? (env as Record<string, unknown>).${t.envName};
136
+ x402?: (env: Record<string, unknown>) => X402PayConfig;`,importLines:['import type { X402Pay, X402PayConfig } from "@lunora/x402/pay";','import { lazyX402Pay } from "@lunora/x402/pay";'],stub:g("x402Stub: X402Pay","ctx.x402: no pay rail configured. Pass `x402` to createShardDO().",["fetch"],{cast:" as unknown as X402Pay",sync:["fetch"]})}),S={access:k,ai:v,r2sql:R,x402:N},w=e=>e.shardBinding==="bespoke",L=e=>typeof e.shardBinding=="object",d=" ",A=(e,r,t)=>{const n=`${e}Binding`,{factory:o}=t;let i=`(${n} as ${r})`;if(o!==void 0){const c=`${n} as ${t.bindingType??r}`;i=o.option===void 0?`${o.name}(${c})`:`${o.name}({ ${o.option}: ${c} })`}return`${n} ? ${i} : ${e}Stub`},C=(e,r,t)=>{const n=A(e,r,t),o=`${d}const ${e}Binding = config.${e}?.(env) ?? (env as Record<string, unknown>).${t.envName};
137
137
  `,i=t.unvouchableReads??[];return i.length===0?`
138
138
  ${o}${d}const ${e}: ${r} = ${n};
139
139
  `:`
@@ -141,22 +141,22 @@ ${o}${d}// ${t.envName} is not this shard's SQLite, so nothing appends a \`__cdc
141
141
  ${d}// when a value changes — a subscription that read one can never be proven
142
142
  ${d}// current on reconnect and must re-snapshot. Reads only; writes stay unstamped.
143
143
  ${d}const ${e}: ${r} = markUnvouchableReads(${n}, options.onRead, [
144
- ${i.map(u=>`${d} ${JSON.stringify(u)},`).join(`
144
+ ${i.map(c=>`${d} ${JSON.stringify(c)},`).join(`
145
145
  `)}
146
146
  ${d}]);
147
147
  `},F=(e,r,t)=>{const{binding:n,clientType:o}=t,i=g(`${e}Stub: ${o}`,t.missingMessage,t.stubMethods,{sync:t.syncStubMethods});if(n===void 0){const l=t.instrument===void 0?`config.${e}(env)`:`this.${t.instrument}(config.${e}(env), logFunctionPath, traceAnchor, observability)`;return{build:`
148
148
  ${d}const ${e}: ${o} = config.${e} ? ${l} : ${e}Stub;
149
149
  `,configField:`
150
- ${e}?: (env: Record<string, unknown>) => ${o};`,importLines:[`import type { ${o} } from "${r}";`],stub:i}}const u=n.bindingType??o,a=[...new Set([u,o])].toSorted((l,s)=>l.localeCompare(s));return{build:C(e,o,n),configField:`
151
- ${e}?: (env: Record<string, unknown>) => ${u};`,importLines:[`import type { ${a.join(", ")} } from "${r}";`,...n.factory===void 0?[]:[`import { ${n.factory.name} } from "${r}";`]],stub:i}},j=e=>{const r=[],t=[];let n="",o="",i="",u="",a="";for(const l of $.filter(({key:s})=>e.has(s))){let s;if(w(l))s=S[l.key]();else if(L(l))s=F(l.contextProperty,l.moduleSpecifier,l.shardBinding);else continue;const m=l.contextProperty;t.push(...s.importLines),o+=s.configField,a+=s.stub,l.tier==="every"?(i+=s.build,u+=`
152
- ${m},`):(n+=s.build,r.push(m))}return{actionBuild:n,actionFields:r,configFields:o,everyBuild:i,everyFields:u,importLines:t,stubs:a}},Q=(e,r)=>{if(e.length===0)return"";const t=r?`, ${JSON.stringify(r)}`:"",n=e.map(s=>{c(s.exportName,`container export "${s.exportName}"`),c(s.className,`container class "${s.className}"`);const m=s.sandbox===!0?"LunoraSandboxContainer":"LunoraContainer";return`/** Container DO for the \`${s.exportName}\` definition (binding \`${s.bindingName}\`). */
150
+ ${e}?: (env: Record<string, unknown>) => ${o};`,importLines:[`import type { ${o} } from "${r}";`],stub:i}}const c=n.bindingType??o,a=[...new Set([c,o])].toSorted((l,s)=>l.localeCompare(s));return{build:C(e,o,n),configField:`
151
+ ${e}?: (env: Record<string, unknown>) => ${c};`,importLines:[`import type { ${a.join(", ")} } from "${r}";`,...n.factory===void 0?[]:[`import { ${n.factory.name} } from "${r}";`]],stub:i}},j=e=>{const r=[],t=[];let n="",o="",i="",c="",a="";for(const l of $.filter(({key:s})=>e.has(s))){let s;if(w(l))s=S[l.key]();else if(L(l))s=F(l.contextProperty,l.moduleSpecifier,l.shardBinding);else continue;const m=l.contextProperty;t.push(...s.importLines),o+=s.configField,a+=s.stub,l.tier==="every"?(i+=s.build,c+=`
152
+ ${m},`):(n+=s.build,r.push(m))}return{actionBuild:n,actionFields:r,configFields:o,everyBuild:i,everyFields:c,importLines:t,stubs:a}},Q=(e,r)=>{if(e.length===0)return"";const t=r?`, ${JSON.stringify(r)}`:"",n=e.map(s=>{u(s.exportName,`container export "${s.exportName}"`),u(s.className,`container class "${s.className}"`);const m=s.sandbox===!0?"LunoraSandboxContainer":"LunoraContainer";return`/** Container DO for the \`${s.exportName}\` definition (binding \`${s.bindingName}\`). */
153
153
  export class ${s.className} extends ${m} {
154
154
  public constructor(ctx: ConstructorParameters<typeof ${m}>[0], env: Record<string, unknown>) {
155
155
  super(ctx, env, ${s.exportName}, "${s.exportName}"${t});
156
156
  }
157
157
  }
158
158
  `}).join(`
159
- `),o=e.map(s=>s.exportName).join(", "),i=e.some(s=>s.sandbox===!0),u=e.some(s=>s.sandbox!==!0)?`import { LunoraContainer } from "@lunora/container/do";
159
+ `),o=e.map(s=>s.exportName).join(", "),i=e.some(s=>s.sandbox===!0),c=e.some(s=>s.sandbox!==!0)?`import { LunoraContainer } from "@lunora/container/do";
160
160
  `:"";return`${p}/**
161
161
  * Container-enabled Durable Object classes for the containers declared in
162
162
  * \`lunora/containers.ts\`. Re-export them from your worker entry — wrangler
@@ -169,7 +169,7 @@ export class ${s.className} extends ${m} {
169
169
  * \`handle.egress\` controls) routes container outbound traffic through this
170
170
  * WorkerEntrypoint, so it too must be exported by the deployed worker.
171
171
  */
172
- ${u}${i?`import { LunoraSandboxContainer } from "@lunora/container/sandbox";
172
+ ${c}${i?`import { LunoraSandboxContainer } from "@lunora/container/sandbox";
173
173
  `:""}
174
174
  import { ${o} } from "../containers.js";
175
175
 
@@ -181,7 +181,7 @@ ${i?`
181
181
  */
182
182
  export { DirectoryBackupGateway, S3Gateway } from "@lunora/container/sandbox";
183
183
  `:""}
184
- ${n}`},M=(e,r)=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)c(n.exportName,`container export "${n.exportName}"`),c(n.bindingName,`container binding "${n.bindingName}"`);const t=e.map(n=>{const o=n.schedulingPolicy!==void 0||n.maxInstances===void 0?"":`, maxInstances: ${String(n.maxInstances)}`;return` { binding: "${n.bindingName}", exportName: "${n.exportName}"${o} },`}).join(`
184
+ ${n}`},M=(e,r)=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)u(n.exportName,`container export "${n.exportName}"`),u(n.bindingName,`container binding "${n.bindingName}"`);const t=e.map(n=>{const o=n.schedulingPolicy!==void 0||n.maxInstances===void 0?"":`, maxInstances: ${String(n.maxInstances)}`;return` { binding: "${n.bindingName}", exportName: "${n.exportName}"${o} },`}).join(`
185
185
  `);return{build:`
186
186
  const containers = createContainerContext(env, LUNORA_CONTAINERS, ${r?JSON.stringify(r):"undefined"}, this.getCurrentTraceparent(), this.getCurrentSampleErrors());
187
187
  `,contextField:`
@@ -190,7 +190,7 @@ ${n}`},M=(e,r)=>{if(e.length===0)return{build:"",contextField:"",importLines:[],
190
190
  const LUNORA_CONTAINERS: ReadonlyArray<ContainerBindingSpec> = [
191
191
  ${t}
192
192
  ];
193
- `}},K=e=>{if(e.length===0)return"";const r=e.map(n=>(c(n.exportName,`workflow export "${n.exportName}"`),c(n.className,`workflow class "${n.className}"`),`/** WorkflowEntrypoint for the \`${n.exportName}\` definition, reached as \`ctx.exports.${n.className}\`. */
193
+ `}},K=e=>{if(e.length===0)return"";const r=e.map(n=>(u(n.exportName,`workflow export "${n.exportName}"`),u(n.className,`workflow class "${n.className}"`),`/** WorkflowEntrypoint for the \`${n.exportName}\` definition, reached as \`ctx.exports.${n.className}\`. */
194
194
  export class ${n.className} extends LunoraWorkflow<WorkflowParamsOf<typeof ${n.exportName}>, WorkflowOutputOf<typeof ${n.exportName}>> {
195
195
  public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
196
196
  super(ctx, env, ${n.exportName}, "${n.exportName}");
@@ -218,13 +218,13 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
218
218
  /** Output type carried by a \`defineWorkflow\` definition (its phantom \`__output\`), so each entrypoint keeps the authored return type. */
219
219
  type WorkflowOutputOf<Definition> = Definition extends { __output?: infer Output } ? Output : unknown;
220
220
 
221
- ${r}`},G=e=>{if(e.length===0)return"";const t=e.filter(a=>a.voice).length>0,n=e.map(a=>{c(a.exportName,`agent export "${a.exportName}"`),c(a.className,`agent class "${a.className}"`);const l=`/** WorkflowEntrypoint for the \`${a.exportName}\` agent, reached as \`ctx.exports.${a.className}\`. */
221
+ ${r}`},G=e=>{if(e.length===0)return"";const t=e.filter(a=>a.voice).length>0,n=e.map(a=>{u(a.exportName,`agent export "${a.exportName}"`),u(a.className,`agent class "${a.className}"`);const l=`/** WorkflowEntrypoint for the \`${a.exportName}\` agent, reached as \`ctx.exports.${a.className}\`. */
222
222
  export class ${a.className} extends LunoraWorkflow<AgentRunInput, AgentRunResult> {
223
223
  public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
224
224
  super(ctx, env, compileAgentWorkflow(${a.exportName}, "${a.exportName}"), "${a.exportName}");
225
225
  }
226
226
  }
227
- `;if(!a.voice)return l;const s=a.voiceClassName??"",m=a.voiceBindingName??"";c(s,`agent voice class "${s}"`);const x=`
227
+ `;if(!a.voice)return l;const s=a.voiceClassName??"",m=a.voiceBindingName??"";u(s,`agent voice class "${s}"`);const x=`
228
228
  /** Voice-session Durable Object for the \`${a.exportName}\` agent (binding \`${m}\`). */
229
229
  export class ${s} extends VoiceSessionDO {
230
230
  public constructor(ctx: ConstructorParameters<typeof VoiceSessionDO>[0], env: Record<string, unknown>) {
@@ -246,7 +246,8 @@ import type { AgentRunInput, AgentRunResult } from "@lunora/agent";
246
246
 
247
247
  import { ${o} } from "../agents.js";
248
248
 
249
- ${n}`},H=e=>{const r=e.filter(o=>o.mode==="push");if(r.length===0)return"";for(const o of r)c(o.exportName,`queue export "${o.exportName}"`);const t=r.map(o=>o.exportName).join(", "),n=r.map(o=>` ${JSON.stringify(o.name)}: { binding: ${JSON.stringify(o.bindingName)}, definition: ${o.exportName}, exportName: ${JSON.stringify(o.exportName)} },`).join(`
249
+ ${n}`},H=e=>{const r=e.filter(o=>o.mode==="push");if(r.length===0)return"";for(const o of r)u(o.exportName,`queue export "${o.exportName}"`);const t=[...Map.groupBy(r,o=>o.filePath)].map(([o,i])=>`import { ${i.map(c=>c.exportName).join(", ")} } from "../${o}.js";`).join(`
250
+ `),n=r.map(o=>` ${JSON.stringify(o.name)}: { binding: ${JSON.stringify(o.bindingName)}, definition: ${o.exportName}, exportName: ${JSON.stringify(o.exportName)} },`).join(`
250
251
  `);return`${p}/**
251
252
  * Push-consumer registry for the queues declared in \`lunora/queues.ts\`. The
252
253
  * composed worker's \`queue(batch, env, ctx)\` entry routes each delivered batch
@@ -255,13 +256,13 @@ ${n}`},H=e=>{const r=e.filter(o=>o.mode==="push");if(r.length===0)return"";for(c
255
256
  */
256
257
  import type { QueueRegistry } from "@lunora/queue";
257
258
 
258
- import { ${t} } from "../queues.js";
259
+ ${t}
259
260
 
260
261
  /** Stable wrangler queue name → { binding, definition, exportName } for batch routing. */
261
262
  export const LUNORA_QUEUE_REGISTRY: QueueRegistry = {
262
263
  ${n}
263
264
  };
264
- `},J=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const t of e)c(t.exportName,`workflow export "${t.exportName}"`),c(t.className,`workflow class "${t.className}"`);const r=e.map(t=>` { className: "${t.className}", exportName: "${t.exportName}" },`).join(`
265
+ `},J=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const t of e)u(t.exportName,`workflow export "${t.exportName}"`),u(t.className,`workflow class "${t.className}"`);const r=e.map(t=>` { className: "${t.className}", exportName: "${t.exportName}" },`).join(`
265
266
  `);return{build:`
266
267
  const workflows = createWorkflowContext(env, LUNORA_WORKFLOWS, this.state.exports);
267
268
  `,contextField:`
@@ -270,7 +271,7 @@ ${n}
270
271
  const LUNORA_WORKFLOWS: ReadonlyArray<WorkflowBindingSpec> = [
271
272
  ${r}
272
273
  ];
273
- `}},V=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const t of e)c(t.exportName,`queue export "${t.exportName}"`),c(t.bindingName,`queue binding "${t.bindingName}"`);const r=e.map(t=>` { binding: "${t.bindingName}", exportName: "${t.exportName}", name: ${JSON.stringify(t.name)} },`).join(`
274
+ `}},V=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const t of e)u(t.exportName,`queue export "${t.exportName}"`),u(t.bindingName,`queue binding "${t.bindingName}"`);const r=e.map(t=>` { binding: "${t.bindingName}", exportName: "${t.exportName}", name: ${JSON.stringify(t.name)} },`).join(`
274
275
  `);return{build:`
275
276
  const queues = createQueueContext(env, LUNORA_QUEUES);
276
277
  `,contextField:`
@@ -279,7 +280,7 @@ ${r}
279
280
  const LUNORA_QUEUES: ReadonlyArray<QueueBindingSpec> = [
280
281
  ${r}
281
282
  ];
282
- `}},Y=(e,r)=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};const t=e.map(n=>{c(n.exportName,`topic export "${n.exportName}"`);const o=b(r,n.exportName).map(i=>`{ binding: "${i.bindingName}", exportName: "${i.exportName}" }`).join(", ");return` { exportName: "${n.exportName}", subscriptions: [${o}] },`}).join(`
283
+ `}},Y=(e,r)=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};const t=e.map(n=>{u(n.exportName,`topic export "${n.exportName}"`);const o=b(r,n.exportName).map(i=>`{ binding: "${i.bindingName}", exportName: "${i.exportName}" }`).join(", ");return` { exportName: "${n.exportName}", subscriptions: [${o}] },`}).join(`
283
284
  `);return{build:`
284
285
  const topics = createTopicContext(env, LUNORA_TOPICS);
285
286
  `,contextField:`
@@ -288,7 +289,7 @@ ${r}
288
289
  const LUNORA_TOPICS: ReadonlyArray<TopicBindingSpec> = [
289
290
  ${t}
290
291
  ];
291
- `}},X=(e,r)=>{if(e.length===0)return{build:"",importLines:[],specs:""};const t=e.map(n=>(c(n.name,`service "${n.name}"`),c(n.binding,`service binding "${n.binding}"`),` { binding: "${n.binding}", name: "${n.name}"${n.rpcEntrypoint===void 0?"":", rpc: true"} },`)).join(`
292
+ `}},X=(e,r)=>{if(e.length===0)return{build:"",importLines:[],specs:""};const t=e.map(n=>(u(n.name,`service "${n.name}"`),u(n.binding,`service binding "${n.binding}"`),` { binding: "${n.binding}", name: "${n.name}"${n.rpcEntrypoint===void 0?"":", rpc: true"} },`)).join(`
292
293
  `);return{build:`
293
294
  const services = createServices(env, LUNORA_SERVICES);
294
295
  `,importLines:[`import type { ServiceBindingSpec } from "${r}";`,`import { createServices } from "${r}";`],specs:`
@@ -296,7 +297,7 @@ ${t}
296
297
  const LUNORA_SERVICES: ReadonlyArray<ServiceBindingSpec> = [
297
298
  ${t}
298
299
  ];
299
- `}},z=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const t of e)c(t.exportName,`agent export "${t.exportName}"`),c(t.className,`agent class "${t.className}"`);const r=e.map(t=>` { className: "${t.className}", exportName: "${t.exportName}"${t.publicRun===!0?", publicRun: true":""} },`).join(`
300
+ `}},z=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const t of e)u(t.exportName,`agent export "${t.exportName}"`),u(t.className,`agent class "${t.className}"`);const r=e.map(t=>` { className: "${t.className}", exportName: "${t.exportName}"${t.publicRun===!0?", publicRun: true":""} },`).join(`
300
301
  `);return{build:`
301
302
  const agents = createAgentContext(env, LUNORA_AGENTS, { exports: this.state.exports });
302
303
  `,contextField:`
@@ -322,4 +323,4 @@ const ${e} = ${y(n,r)};
322
323
  : paymentStub;
323
324
 
324
325
  return payments;
325
- },`,stub:g("paymentStub: LunoraPayment","ctx.payments: no payment configured. Pass `payment` to createShardDO().",_,{cast:" as unknown as LunoraPayment",sync:!0})}:{build:"",configField:"",contextField:"",imports:[],stub:""},ne=(e,r,t,n,o)=>["AdvisorProcedure","AdvisoryFinding","DatabaseWriterLike","DataMigrationLike","DispatchBookmark","ExportRow",...n?["FlagsResult"]:[],"ImportShardResult","KeyRange","MaskPoliciesResult","MigrationRunResult","QueryReadScope",...t?["QueuesResult"]:[],"RelatedPage","RunShardApplyCdcArgs","RunShardExportArgs","RunShardFindRelatedArgs","RunShardImportArgs","RunShardMigrationArgs","RlsPoliciesResult","RunShardRankBeforeArgs","RunShardRankPageArgs","RunShardWriteArgs","RunShardWriteResult","SchedulerLike",...o?["SearchBackfillProgress"]:[],"TransactionHeadroomTracker","SchemaLike","ShardDOState","ShardRankPageResult","SqlExec","StorageRulesResult","StudioFeaturesResult","SubscriptionIdentity","SystemReaderStorageLike","TelemetrySink",...e?["VectorBackfillProgress"]:[],...r?["WorkflowsResult"]:[],...e?["WriteHook"]:[]];export{q as a,U as b,D as c,V as d,j as e,Y as f,X as g,M as h,J as i,z as j,te as k,Z as l,ee as m,W as n,ne as o,I as p,B as q,g as r,G as s,Q as t,K as u,H as v};
326
+ },`,stub:g("paymentStub: LunoraPayment","ctx.payments: no payment configured. Pass `payment` to createShardDO().",_,{cast:" as unknown as LunoraPayment",sync:!0})}:{build:"",configField:"",contextField:"",imports:[],stub:""},ne=(e,r,t,n,o)=>["AdvisorProcedure","AdvisoryFinding","DatabaseWriterLike","DataMigrationLike","DispatchBookmark","ExportRow",...n?["FlagsResult"]:[],"ImportShardResult","KeyRange","MaskPoliciesResult","MigrationRunResult","QueryReadScope",...t?["QueuesResult"]:[],"RelatedPage","RunShardApplyCdcArgs","RunShardExportArgs","RunShardFindRelatedArgs","RunShardImportArgs","RunShardMigrationArgs","RlsPoliciesResult","RunShardRankBeforeArgs","RunShardRankPageArgs","RunShardWriteArgs","RunShardWriteResult","SchedulerLike",...o?["SearchBackfillProgress"]:[],"TransactionHeadroomTracker","SchemaLike","ShardDOState","ShardRankPageResult","SqlExec","StorageRulesResult","StudioFeaturesResult","SubscriptionIdentity","SystemReaderStorageLike","TelemetrySink",...e?["VectorBackfillProgress"]:[],...r?["WorkflowsResult"]:[],...e?["WriteHook"]:[]];export{B as a,U as b,D as c,V as d,j as e,Y as f,X as g,M as h,J as i,z as j,te as k,Z as l,ee as m,W as n,ne as o,I as p,q,g as r,G as s,Q as t,K as u,H as v};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/codegen",
3
- "version": "1.0.0-alpha.272",
3
+ "version": "1.0.0-alpha.274",
4
4
  "description": "Code generator for Lunora: emits _generated/{api,server,dataModel}.ts from your schema",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -46,12 +46,12 @@
46
46
  "access": "public"
47
47
  },
48
48
  "dependencies": {
49
- "@lunora/advisor": "1.0.0-alpha.195",
50
- "@lunora/agent": "1.0.0-alpha.184",
49
+ "@lunora/advisor": "1.0.0-alpha.197",
50
+ "@lunora/agent": "1.0.0-alpha.185",
51
51
  "@lunora/container": "1.0.0-alpha.69",
52
52
  "@lunora/errors": "1.0.0-alpha.50",
53
53
  "@lunora/platform": "1.0.0-alpha.57",
54
- "@lunora/queue": "1.0.0-alpha.93",
54
+ "@lunora/queue": "1.0.0-alpha.94",
55
55
  "@lunora/scheduler": "1.0.0-alpha.112",
56
56
  "@lunora/values": "1.0.0-alpha.60",
57
57
  "@lunora/workflow": "1.0.0-alpha.71",
@@ -1 +0,0 @@
1
- import{existsSync as b}from"node:fs";import{join as h}from"node:path";import{LunoraError as f}from"@lunora/errors";import{queueDefaultName as y,queueBindingName as q}from"@lunora/queue";import{SyntaxKind as N,Node as c}from"ts-morph";import{diagnosticAt as d}from"./CodegenDiagnosticError-BUXlG3P-.mjs";import{findObjectProperty as m,stringPropertyFor as w}from"./isTestPath-DCyIyPa7.mjs";import{a as x}from"./attribution-NRssTEkk.mjs";import{r as v}from"./handler-reference-B3coD2YR.mjs";const E="queues.ts",S=i=>{const t=e=>e==="defineQueue"||e==="defineSubscription"||e==="defineTopic",o=i.getSymbol();if(!o){const e=i.getText();return t(e)?e:void 0}for(const e of o.getDeclarations()){if(!c.isImportSpecifier(e))continue;if(e.getImportDeclaration().getModuleSpecifierValue()!=="@lunora/queue")return;const r=e.getNameNode().getText();return t(r)?r:void 0}},l=w("queue"),$=(i,t,o)=>{if(c.isNumericLiteral(i))return i.getLiteralValue();throw d(i,`queue "${t}": \`${o}\` must be a static numeric literal — it is deploy configuration codegen writes into wrangler.jsonc`)},I=(i,t)=>{const o=m(i,"name");if(!o||!c.isPropertyAssignment(o))return;const e=l(o.getInitializerOrThrow(),t,"name");if(e.length===0)throw d(o,`queue "${t}": \`name\` must be a non-empty string when provided`);return e},g=(i,t,o,e)=>{const r=v(m(i,"handler"),e)?.site,s={bindingName:q(t),exportName:t,mode:"push",name:I(i,t)??y(t),...o===void 0?{}:{topic:o},...r===void 0?{}:{handlerSite:r},tuning:{}},n=m(i,"mode");if(n&&c.isPropertyAssignment(n)){if(o!==void 0)throw d(n,`subscription "${t}": \`mode\` is not allowed — a subscription is always a push consumer`);const u=l(n.getInitializerOrThrow(),t,"mode");if(u!=="push"&&u!=="pull")throw d(n,`queue "${t}": \`mode\` must be "push" or "pull" (got ${JSON.stringify(u)})`);s.mode=u}const a=m(i,"deadLetterQueue");a&&c.isPropertyAssignment(a)&&(s.tuning.deadLetterQueue=l(a.getInitializerOrThrow(),t,"deadLetterQueue"));for(const u of["maxBatchSize","maxBatchTimeout","maxRetries","retryDelay"]){const p=m(i,u);p&&c.isPropertyAssignment(p)&&(s.tuning[u]=$(p.getInitializerOrThrow(),t,u))}return s},P=(i,t,o)=>{const e=i.getArguments()[0];if(!e||!c.isObjectLiteralExpression(e))throw d(i,`queue "${t}": defineQueue must be passed an inline object literal`);return g(e,t,void 0,o)},T=(i,t,o,e)=>{const[r,s]=i.getArguments();if(!r||!c.isIdentifier(r)||!o.has(r.getText()))throw d(r??i,`subscription "${t}": the first argument must name a \`defineTopic()\` export of lunora/queues.ts`);if(!s||!c.isObjectLiteralExpression(s))throw d(i,`subscription "${t}": defineSubscription must be passed an inline object literal`);return g(s,t,o.get(r.getText()),e)},A=i=>{const t=[];for(const o of i.getVariableDeclarations()){const e=o.getInitializer();if(e?.getKind()!==N.CallExpression)continue;const r=e,s=r.getExpression(),n=c.isIdentifier(s)?S(s):void 0;if(n===void 0)continue;const a=o.getNameNode();if(!c.isIdentifier(a)){if(o.getVariableStatement()?.hasExportKeyword()!==!0)continue;throw d(a,`${n} exports must be plain named exports (no destructuring)`)}const u=x(o,"binding");u!==void 0&&t.push({call:r,exportName:u,factory:n,localName:a.getText()})}return t},Q=(i,t)=>{const o=A(i),e=new Map(o.filter(n=>n.factory==="defineTopic").map(n=>[n.localName,n.exportName])),r=[];for(const n of o)n.factory==="defineQueue"?r.push(P(n.call,n.exportName,t)):n.factory==="defineSubscription"&&r.push(T(n.call,n.exportName,e,t));const s=[...e.values()].map(n=>({exportName:n}));return{queues:r,topics:s}},L=i=>{const t=new Map,o=new Map;for(const e of i){const r=t.get(e.name);if(r!==void 0)throw new f("DUPLICATE_QUEUE_NAME",`Duplicate queue name "${e.name}": produced by both "${r}" and "${e.exportName}". Deployed queue names must be unique across the project.`,{status:500});t.set(e.name,e.exportName);const s=o.get(e.bindingName);if(s!==void 0)throw new f("DUPLICATE_QUEUE_BINDING",`Duplicate queue binding "${e.bindingName}": produced by both "${s}" and "${e.exportName}". Queue export names must yield unique binding names.`,{status:500});o.set(e.bindingName,e.exportName)}},O=(i,t)=>{const o=h(t,E);if(!b(o))return{queues:[],topics:[]};const e=i.getSourceFile(o)??i.addSourceFileAtPath(o),{queues:r,topics:s}=Q(e,t),n=r.toSorted((a,u)=>a.exportName.localeCompare(u.exportName));return L(n),{queues:n,topics:s.toSorted((a,u)=>a.exportName.localeCompare(u.exportName))}},V=(i,t)=>O(i,t).queues;export{E as QUEUES_FILENAME,O as discoverQueueDeclarations,V as discoverQueues};