@lunora/codegen 1.0.0-alpha.240 → 1.0.0-alpha.242

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.
Files changed (26) hide show
  1. package/dist/index.d.mts +93 -55
  2. package/dist/index.d.ts +93 -55
  3. package/dist/index.mjs +1 -1
  4. package/dist/packem_shared/AGENTS_FILENAME-Bb2jxbOa.mjs +1 -0
  5. package/dist/packem_shared/CONTAINERS_FILENAME-CGB4bqUr.mjs +1 -0
  6. package/dist/packem_shared/DEFAULT_TARGET-B1zgC6k6.mjs +1 -0
  7. package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-BHDnOBKJ.mjs +9 -0
  8. package/dist/packem_shared/WORKFLOWS_FILENAME-DNaUHGS8.mjs +1 -0
  9. package/dist/packem_shared/{discoverCrons-MfKw7IFf.mjs → discoverCrons-0lNudk0S.mjs} +1 -1
  10. package/dist/packem_shared/{emitAgents-Cy7QGO1t.mjs → emitAgents-Ddcr_r3B.mjs} +1 -1
  11. package/dist/packem_shared/{emitApi-CJ9ziZnP.mjs → emitApi-DdW9RyGG.mjs} +22 -22
  12. package/dist/packem_shared/{emitApp-BGhO5bhT.mjs → emitApp--W9G6MZd.mjs} +48 -56
  13. package/dist/packem_shared/{emitCrons-mkwWkn0R.mjs → emitCrons-Bop1FTEz.mjs} +28 -14
  14. package/dist/packem_shared/{emitFunctions-BqAz1ssY.mjs → emitFunctions-BgNeOZt_.mjs} +1 -1
  15. package/dist/packem_shared/{emitServer-BEo_fCY8.mjs → emitServer-B8t7Hzb1.mjs} +38 -40
  16. package/dist/packem_shared/emitShard-RnNua5aR.mjs +1 -0
  17. package/dist/packem_shared/ir-BgM8A3XV.mjs +1 -0
  18. package/dist/packem_shared/{shard-BBv6VBmX.mjs → shard-CCNl561P.mjs} +61 -61
  19. package/dist/packem_shared/{shard-runtime-CM5qthZc.mjs → shard-runtime-B7xvdFPc.mjs} +48 -39
  20. package/package.json +10 -10
  21. package/dist/packem_shared/AGENTS_FILENAME-DoPI92Wu.mjs +0 -1
  22. package/dist/packem_shared/CONTAINERS_FILENAME-B6TFs82W.mjs +0 -1
  23. package/dist/packem_shared/DEFAULT_TARGET-DCpDuuUM.mjs +0 -1
  24. package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-IOiezeVr.mjs +0 -9
  25. package/dist/packem_shared/WORKFLOWS_FILENAME-B_ZJxRSx.mjs +0 -1
  26. package/dist/packem_shared/emitShard-CsWK2K91.mjs +0 -1
@@ -23,14 +23,23 @@ import{r as p}from"./json-data-Chfs2Cz5.mjs";import{a,G as d}from"./shared-DjUzi
23
23
  telemetry: { metrics, trace },
24
24
  });
25
25
  `,configField:`
26
- ai?: (env: Record<string, unknown>) => AiBindingLike;`}:{build:"",configField:""},l=(e,t,n,{cast:r="",sync:o=[]}={})=>{const s=n.map(u=>` ${u}: ${o.includes(u)?"":"async "}() => {
26
+ ai?: (env: Record<string, unknown>) => AiBindingLike;`}:{build:"",configField:""},l=(e,t,n,{cast:r="",sync:o=[]}={})=>{const i=n.map(u=>` ${u}: ${o.includes(u)?"":"async "}() => {
27
27
  ${t}
28
28
  },`).join(`
29
29
  `);return`
30
30
  const ${e} = {
31
- ${s}
31
+ ${i}
32
32
  }${r};
33
- `},c={build:"",configField:"",contextField:"",importLines:[],stub:""},w=e=>e?{build:`
33
+ `},c={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:`
34
+ /** The \`.shardBy()\` tables this shard registers with the shard registry when it writes them. */
35
+ const SHARDED_TABLES: ReadonlySet<string> = new Set([${[...e].map(t=>JSON.stringify(t)).join(", ")}]);
36
+ `,override:`
37
+ protected override shardRegistry(): undefined | { namespace: unknown; shardedTables: ReadonlySet<string> } {
38
+ const namespace = config.shardRegistry?.((this.env ?? {}) as Record<string, unknown>);
39
+
40
+ return namespace === undefined ? undefined : { namespace, shardedTables: SHARDED_TABLES };
41
+ }
42
+ `},R=e=>e?{build:`
34
43
  const kvBinding = config.kv?.(env) ?? (env as Record<string, unknown>).KV;
35
44
  // KV is not this shard's SQLite, so nothing appends a \`__cdc_log\` entry
36
45
  // when a value changes — a subscription that read one can never be proven
@@ -44,32 +53,32 @@ ${s}
44
53
  ]);
45
54
  `,configField:`
46
55
  kv?: (env: Record<string, unknown>) => KVNamespaceLike;`,contextField:`
47
- kv,`,importLines:['import type { Kv, KVNamespaceLike } from "@lunora/bindings/kv";','import { createKv } from "@lunora/bindings/kv";'],stub:l("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"])}:c,R=(e,t)=>e?{build:`
56
+ kv,`,importLines:['import type { Kv, KVNamespaceLike } from "@lunora/bindings/kv";','import { createKv } from "@lunora/bindings/kv";'],stub:l("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"])}:c,N=(e,t)=>e?{build:`
48
57
  const flags: import("${t}").LunoraFlags = createFlags(flagsConfig, env, {
49
58
  provider: () => config.flags?.(env),
50
59
  targetingKey: () => flagsConfig.identify?.({ identity: identity ?? null, userId: userId ?? null }),
51
60
  });
52
61
  `,configField:`
53
62
  flags?: (env: Record<string, unknown>) => import("${t}").Provider;`,contextField:`
54
- flags,`,importLines:[`import { createFlags } from "${t}";`,'import flagsConfig from "../flags.js";'],stub:""}:c,N=e=>e?{build:`
63
+ flags,`,importLines:[`import { createFlags } from "${t}";`,'import flagsConfig from "../flags.js";'],stub:""}:c,S=e=>e?{build:`
55
64
  const { notify, push } = createNotify(notifyConfig, env, { log, metrics });
56
65
  `,configField:"",contextField:`
57
66
  notify,
58
- push,`,importLines:['import { createNotify } from "@lunora/notify";','import notifyConfig from "../notify.js";'],stub:""}:c,S=e=>e?{build:`
67
+ push,`,importLines:['import { createNotify } from "@lunora/notify";','import notifyConfig from "../notify.js";'],stub:""}:c,L=e=>e?{build:`
59
68
  const envConfig = lunoraEnvContract.${e.exportName}(env);
60
69
  `,configField:"",contextField:`
61
- env: envConfig,`,importLines:['import * as lunoraEnvContract from "../env.js";'],stub:""}:c,L=e=>e?{build:`
70
+ env: envConfig,`,importLines:['import * as lunoraEnvContract from "../env.js";'],stub:""}:c,A=e=>e?{build:`
62
71
  const access = accessFacade(identity, userId);
63
72
  `,configField:"",contextField:`
64
- access,`,importLines:['import { accessFacade } from "@lunora/cloudflare-access/context";'],stub:""}:c,$=(e,t,n)=>{if(!t)return{constant:"",evaluateOverride:"",subscriptionOverride:""};const r=i=>`
73
+ access,`,importLines:['import { accessFacade } from "@lunora/cloudflare-access/context";'],stub:""}:c,F=(e,t,n)=>{if(!t)return{constant:"",evaluateOverride:"",subscriptionOverride:""};const r=s=>`
65
74
  const env = (this.env ?? {}) as Record<string, unknown>;
66
75
  const flags: import("${n}").LunoraFlags = createFlags(flagsConfig, env, {
67
76
  provider: () => config.flags?.(env),
68
- targetingKey: ${i},
77
+ targetingKey: ${s},
69
78
  });`,o=`
70
79
  /** Statically-discovered feature flags (\`ctx.flags.<type>("key")\` reads) served via \`__lunora_admin__:listFlags\` + the reactive \`__lunora_flags__:\` channel. */
71
80
  const LUNORA_FLAG_KEYS = ${p(e,'ReadonlyArray<{ key: string; type: "boolean" | "number" | "object" | "string" }>')};
72
- `,s=`
81
+ `,i=`
73
82
  protected override async evaluateFlags(context?: Record<string, unknown>): Promise<FlagsResult> {${r("undefined")}
74
83
  const evalContext = context as import("${n}").EvaluationContext | undefined;
75
84
  const evaluations: FlagsResult["flags"] = [];
@@ -123,25 +132,25 @@ const LUNORA_FLAG_KEYS = ${p(e,'ReadonlyArray<{ key: string; type: "boolean" | "
123
132
 
124
133
  return flags.boolean(key, typeof args.default === "boolean" ? args.default : false, context);
125
134
  }
126
- `;return{constant:o,evaluateOverride:s,subscriptionOverride:u}},F=e=>e?{build:`
135
+ `;return{constant:o,evaluateOverride:i,subscriptionOverride:u}},$=e=>e?{build:`
127
136
  const analyticsBinding = config.analytics?.(env) ?? (env as Record<string, unknown>).ANALYTICS;
128
137
  const analytics: AnalyticsClient = analyticsBinding ? createAnalytics(analyticsBinding as AnalyticsEngineDatasetLike) : analyticsStub;
129
138
  `,configField:`
130
139
  analytics?: (env: Record<string, unknown>) => AnalyticsEngineDatasetLike;`,contextField:`
131
- analytics,`,importLines:['import type { AnalyticsClient, AnalyticsEngineDatasetLike } from "@lunora/bindings/analytics";','import { createAnalytics } from "@lunora/bindings/analytics";'],stub:l("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"]})}:c,A=e=>e?{build:`
140
+ analytics,`,importLines:['import type { AnalyticsClient, AnalyticsEngineDatasetLike } from "@lunora/bindings/analytics";','import { createAnalytics } from "@lunora/bindings/analytics";'],stub:l("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"]})}:c,C=e=>e?{build:`
132
141
  const imagesBinding = config.images?.(env) ?? (env as Record<string, unknown>).IMAGES;
133
142
  const images: Images = imagesBinding ? createImages({ binding: imagesBinding as ImagesBindingLike }) : imagesStub;
134
143
  `,configField:`
135
144
  images?: (env: Record<string, unknown>) => ImagesBindingLike;`,contextField:`
136
- images,`,importLines:['import type { Images, ImagesBindingLike } from "@lunora/bindings/images";','import { createImages } from "@lunora/bindings/images";'],stub:l("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"])}:c,C=e=>e?{build:`
145
+ images,`,importLines:['import type { Images, ImagesBindingLike } from "@lunora/bindings/images";','import { createImages } from "@lunora/bindings/images";'],stub:l("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"])}:c,_=e=>e?{build:`
137
146
  const sql: SqlClient = config.sql ? config.sql(env) : sqlStub;
138
147
  `,configField:`
139
148
  sql?: (env: Record<string, unknown>) => SqlClient;`,contextField:`
140
- sql,`,importLines:['import type { SqlClient } from "@lunora/hyperdrive";'],stub:l("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"])}:c,_=e=>e?{build:`
149
+ sql,`,importLines:['import type { SqlClient } from "@lunora/hyperdrive";'],stub:l("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"])}:c,E=e=>e?{build:`
141
150
  const browser: Browser = config.browser ? config.browser(env) : browserStub;
142
151
  `,configField:`
143
152
  browser?: (env: Record<string, unknown>) => Browser;`,contextField:`
144
- browser,`,importLines:['import type { Browser } from "@lunora/browser";'],stub:l("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"])}:c,E=e=>e?{build:`
153
+ browser,`,importLines:['import type { Browser } from "@lunora/browser";'],stub:l("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.\");",["cancelCrawl","connect","content","crawl","crawlResult","launch","pdf","quickAction","scrape","screenshot","sessions"])}:c,O=e=>e?{build:`
145
154
  const r2sqlEnv = env as Record<string, unknown>;
146
155
  const r2sqlAccountId = (r2sqlEnv.R2_SQL_ACCOUNT_ID ?? r2sqlEnv.CLOUDFLARE_ACCOUNT_ID) as string | undefined;
147
156
  const r2sqlToken = r2sqlEnv.R2_SQL_TOKEN as string | undefined;
@@ -152,18 +161,18 @@ const LUNORA_FLAG_KEYS = ${p(e,'ReadonlyArray<{ key: string; type: "boolean" | "
152
161
  ? createR2Sql({ accountId: r2sqlAccountId, apiToken: r2sqlToken, bucket: r2sqlBucket })
153
162
  : r2sqlStub;
154
163
  `,configField:`
155
- r2sql?: (env: Record<string, unknown>) => R2SqlClient;`,contextField:"",importLines:['import type { R2SqlClient } from "@lunora/bindings/r2sql";','import { createR2Sql } from "@lunora/bindings/r2sql";'],stub:l("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"]})}:c,O=e=>e?{build:`
164
+ r2sql?: (env: Record<string, unknown>) => R2SqlClient;`,contextField:"",importLines:['import type { R2SqlClient } from "@lunora/bindings/r2sql";','import { createR2Sql } from "@lunora/bindings/r2sql";'],stub:l("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"]})}:c,P=e=>e?{build:`
156
165
  const pipelinesBinding = config.pipelines?.(env) ?? (env as Record<string, unknown>).PIPELINES;
157
166
  const pipelines: PipelineClient = pipelinesBinding ? createPipelines({ binding: pipelinesBinding as PipelineBindingLike }) : pipelinesStub;
158
167
  `,configField:`
159
- pipelines?: (env: Record<string, unknown>) => PipelineBindingLike;`,contextField:"",importLines:['import type { PipelineBindingLike, PipelineClient } from "@lunora/bindings/pipelines";','import { createPipelines } from "@lunora/bindings/pipelines";'],stub:l("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"])}:c,P=(e,t)=>{if(e.length===0)return"";const n=t?`, ${JSON.stringify(t)}`:"",r=e.map(s=>(a(s.exportName,`container export "${s.exportName}"`),a(s.className,`container class "${s.className}"`),`/** Container DO for the \`${s.exportName}\` definition (binding \`${s.bindingName}\`). */
160
- export class ${s.className} extends LunoraContainer {
168
+ pipelines?: (env: Record<string, unknown>) => PipelineBindingLike;`,contextField:"",importLines:['import type { PipelineBindingLike, PipelineClient } from "@lunora/bindings/pipelines";','import { createPipelines } from "@lunora/bindings/pipelines";'],stub:l("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"])}:c,q=(e,t)=>{if(e.length===0)return"";const n=t?`, ${JSON.stringify(t)}`:"",r=e.map(i=>(a(i.exportName,`container export "${i.exportName}"`),a(i.className,`container class "${i.className}"`),`/** Container DO for the \`${i.exportName}\` definition (binding \`${i.bindingName}\`). */
169
+ export class ${i.className} extends LunoraContainer {
161
170
  public constructor(ctx: ConstructorParameters<typeof LunoraContainer>[0], env: Record<string, unknown>) {
162
- super(ctx, env, ${s.exportName}, "${s.exportName}"${n});
171
+ super(ctx, env, ${i.exportName}, "${i.exportName}"${n});
163
172
  }
164
173
  }
165
174
  `)).join(`
166
- `),o=e.map(s=>s.exportName).join(", ");return`${d}/**
175
+ `),o=e.map(i=>i.exportName).join(", ");return`${d}/**
167
176
  * Container-enabled Durable Object classes for the containers declared in
168
177
  * \`lunora/containers.ts\`. Re-export them from your worker entry — wrangler
169
178
  * requires each \`containers[].class_name\` to be exported by the worker:
@@ -181,7 +190,7 @@ import { ${o} } from "../containers.js";
181
190
 
182
191
  export { ContainerProxy } from "@lunora/container/do";
183
192
 
184
- ${r}`},q=(e,t)=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const r of e)a(r.exportName,`container export "${r.exportName}"`),a(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(`
193
+ ${r}`},I=(e,t)=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const r of e)a(r.exportName,`container export "${r.exportName}"`),a(r.bindingName,`container binding "${r.bindingName}"`);const n=e.map(r=>{const o=r.schedulingPolicy!==void 0||r.maxInstances===void 0?"":`, maxInstances: ${String(r.maxInstances)}`;return` { binding: "${r.bindingName}", exportName: "${r.exportName}"${o} },`}).join(`
185
194
  `);return{build:`
186
195
  const containers = createContainerContext(env, LUNORA_CONTAINERS, ${t?JSON.stringify(t):"undefined"}, this.getCurrentTraceparent(), this.getCurrentSampleErrors());
187
196
  `,contextField:`
@@ -190,7 +199,7 @@ ${r}`},q=(e,t)=>{if(e.length===0)return{build:"",contextField:"",importLines:[],
190
199
  const LUNORA_CONTAINERS: ReadonlyArray<ContainerBindingSpec> = [
191
200
  ${n}
192
201
  ];
193
- `}},I=e=>{if(e.length===0)return"";const t=e.map(r=>(a(r.exportName,`workflow export "${r.exportName}"`),a(r.className,`workflow class "${r.className}"`),`/** WorkflowEntrypoint for the \`${r.exportName}\` definition (binding \`${r.bindingName}\`). */
202
+ `}},B=e=>{if(e.length===0)return"";const t=e.map(r=>(a(r.exportName,`workflow export "${r.exportName}"`),a(r.className,`workflow class "${r.className}"`),`/** WorkflowEntrypoint for the \`${r.exportName}\` definition, reached as \`ctx.exports.${r.className}\`. */
194
203
  export class ${r.className} extends LunoraWorkflow<WorkflowParamsOf<typeof ${r.exportName}>, WorkflowOutputOf<typeof ${r.exportName}>> {
195
204
  public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
196
205
  super(ctx, env, ${r.exportName}, "${r.exportName}");
@@ -218,21 +227,21 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
218
227
  /** Output type carried by a \`defineWorkflow\` definition (its phantom \`__output\`), so each entrypoint keeps the authored return type. */
219
228
  type WorkflowOutputOf<Definition> = Definition extends { __output?: infer Output } ? Output : unknown;
220
229
 
221
- ${t}`},W=e=>{if(e.length===0)return"";const n=e.filter(i=>i.voice).length>0,r=e.map(i=>{a(i.exportName,`agent export "${i.exportName}"`),a(i.className,`agent class "${i.className}"`);const g=`/** WorkflowEntrypoint for the \`${i.exportName}\` agent (binding \`${i.bindingName}\`). */
222
- export class ${i.className} extends LunoraWorkflow<AgentRunInput, AgentRunResult> {
230
+ ${t}`},W=e=>{if(e.length===0)return"";const n=e.filter(s=>s.voice).length>0,r=e.map(s=>{a(s.exportName,`agent export "${s.exportName}"`),a(s.className,`agent class "${s.className}"`);const g=`/** WorkflowEntrypoint for the \`${s.exportName}\` agent, reached as \`ctx.exports.${s.className}\`. */
231
+ export class ${s.className} extends LunoraWorkflow<AgentRunInput, AgentRunResult> {
223
232
  public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
224
- super(ctx, env, compileAgentWorkflow(${i.exportName}, "${i.exportName}"), "${i.exportName}");
233
+ super(ctx, env, compileAgentWorkflow(${s.exportName}, "${s.exportName}"), "${s.exportName}");
225
234
  }
226
235
  }
227
- `;if(!i.voice)return g;const m=i.voiceClassName??"",y=i.voiceBindingName??"";a(m,`agent voice class "${m}"`);const b=`
228
- /** Voice-session Durable Object for the \`${i.exportName}\` agent (binding \`${y}\`). */
236
+ `;if(!s.voice)return g;const m=s.voiceClassName??"",y=s.voiceBindingName??"";a(m,`agent voice class "${m}"`);const h=`
237
+ /** Voice-session Durable Object for the \`${s.exportName}\` agent (binding \`${y}\`). */
229
238
  export class ${m} extends VoiceSessionDO {
230
239
  public constructor(ctx: ConstructorParameters<typeof VoiceSessionDO>[0], env: Record<string, unknown>) {
231
- super(ctx, env, ${i.exportName}, "${i.exportName}");
240
+ super(ctx, env, ${s.exportName}, "${s.exportName}");
232
241
  }
233
242
  }
234
- `;return`${g}${b}`}).join(`
235
- `),o=e.map(i=>i.exportName).join(", ");return`${d}/**
243
+ `;return`${g}${h}`}).join(`
244
+ `),o=e.map(s=>s.exportName).join(", ");return`${d}/**
236
245
  * WorkflowEntrypoint classes for the agents declared in \`lunora/agents.ts\`.
237
246
  * Each \`defineAgent\` compiles a replay-safe tool-loop onto a Cloudflare
238
247
  * Workflow. Re-export them from your worker entry — wrangler requires each
@@ -246,7 +255,7 @@ import type { AgentRunInput, AgentRunResult } from "@lunora/agent";
246
255
 
247
256
  import { ${o} } from "../agents.js";
248
257
 
249
- ${r}`},B=e=>{const t=e.filter(o=>o.mode==="push");if(t.length===0)return"";for(const o of t)a(o.exportName,`queue export "${o.exportName}"`);const n=t.map(o=>o.exportName).join(", "),r=t.map(o=>` ${JSON.stringify(o.name)}: { binding: ${JSON.stringify(o.bindingName)}, definition: ${o.exportName}, exportName: ${JSON.stringify(o.exportName)} },`).join(`
258
+ ${r}`},D=e=>{const t=e.filter(o=>o.mode==="push");if(t.length===0)return"";for(const o of t)a(o.exportName,`queue export "${o.exportName}"`);const n=t.map(o=>o.exportName).join(", "),r=t.map(o=>` ${JSON.stringify(o.name)}: { binding: ${JSON.stringify(o.bindingName)}, definition: ${o.exportName}, exportName: ${JSON.stringify(o.exportName)} },`).join(`
250
259
  `);return`${d}/**
251
260
  * Push-consumer registry for the queues declared in \`lunora/queues.ts\`. The
252
261
  * composed worker's \`queue(batch, env, ctx)\` entry routes each delivered batch
@@ -261,16 +270,16 @@ import { ${n} } from "../queues.js";
261
270
  export const LUNORA_QUEUE_REGISTRY: QueueRegistry = {
262
271
  ${r}
263
272
  };
264
- `},D=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)a(n.exportName,`workflow export "${n.exportName}"`),a(n.bindingName,`workflow binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}" },`).join(`
273
+ `},T=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)a(n.exportName,`workflow export "${n.exportName}"`),a(n.className,`workflow class "${n.className}"`);const t=e.map(n=>` { className: "${n.className}", exportName: "${n.exportName}" },`).join(`
265
274
  `);return{build:`
266
- const workflows = createWorkflowContext(env, LUNORA_WORKFLOWS);
275
+ const workflows = createWorkflowContext(env, LUNORA_WORKFLOWS, this.state.exports);
267
276
  `,contextField:`
268
277
  workflows,`,importLines:['import type { WorkflowBindingSpec } from "@lunora/workflow";','import { createWorkflowContext } from "@lunora/workflow";'],specs:`
269
278
  /** Wiring specs for \`ctx.workflows\` (codegen-derived from \`lunora/workflows.ts\`). */
270
279
  const LUNORA_WORKFLOWS: ReadonlyArray<WorkflowBindingSpec> = [
271
280
  ${t}
272
281
  ];
273
- `}},T=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)a(n.exportName,`queue export "${n.exportName}"`),a(n.bindingName,`queue binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}", name: ${JSON.stringify(n.name)} },`).join(`
282
+ `}},j=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)a(n.exportName,`queue export "${n.exportName}"`),a(n.bindingName,`queue binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}", name: ${JSON.stringify(n.name)} },`).join(`
274
283
  `);return{build:`
275
284
  const queues = createQueueContext(env, LUNORA_QUEUES);
276
285
  `,contextField:`
@@ -279,9 +288,9 @@ ${t}
279
288
  const LUNORA_QUEUES: ReadonlyArray<QueueBindingSpec> = [
280
289
  ${t}
281
290
  ];
282
- `}},j=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)a(n.exportName,`agent export "${n.exportName}"`),a(n.bindingName,`agent binding "${n.bindingName}"`);const t=e.map(n=>` { binding: "${n.bindingName}", exportName: "${n.exportName}"${n.publicRun===!0?", publicRun: true":""} },`).join(`
291
+ `}},U=e=>{if(e.length===0)return{build:"",contextField:"",importLines:[],specs:""};for(const n of e)a(n.exportName,`agent export "${n.exportName}"`),a(n.className,`agent class "${n.className}"`);const t=e.map(n=>` { className: "${n.className}", exportName: "${n.exportName}"${n.publicRun===!0?", publicRun: true":""} },`).join(`
283
292
  `);return{build:`
284
- const agents = createAgentContext(env, LUNORA_AGENTS);
293
+ const agents = createAgentContext(env, LUNORA_AGENTS, { exports: this.state.exports });
285
294
  `,contextField:`
286
295
  agents,`,importLines:['import { createAgentContext } from "@lunora/agent";','import type { AgentBindingSpec } from "@lunora/agent";'],specs:`
287
296
  /** Wiring specs for \`ctx.agents\` (codegen-derived from \`lunora/agents.ts\`). */
@@ -295,15 +304,15 @@ const ${e} = ${p(r,t)};
295
304
  protected override ${n}(): ${t} {
296
305
  return ${e};
297
306
  }
298
- `}),U=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 f("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. */")},M=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 f("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. */")},Q=e=>e?{imports:['import type { LunoraDatabaseLike as LunoraPaymentDbLike, LunoraPayment, PaymentsFromContextOptions } from "@lunora/payment";','import { paymentsFromContext } from "@lunora/payment";'],build:`
307
+ `}),M=e=>{if(e.length===0)return{constant:"",override:""};const t={workflows:e.map(n=>({className:n.className,exportName:n.exportName,name:n.name}))};return f("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. */")},Q=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 f("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. */")},K=e=>e?{imports:['import type { LunoraDatabaseLike as LunoraPaymentDbLike, LunoraPayment, PaymentsFromContextOptions } from "@lunora/payment";','import { paymentsFromContext } from "@lunora/payment";'],build:`
299
308
  const payments: LunoraPayment = config.payment
300
309
  ? paymentsFromContext({ auth: { userId: userId ?? null }, db: db as unknown as LunoraPaymentDbLike }, config.payment(env))
301
310
  : paymentStub;
302
311
  `,configField:`
303
312
  payment?: (env: Record<string, unknown>) => PaymentsFromContextOptions;`,contextField:`
304
- payments,`,stub:l("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:""},K=e=>e?{imports:['import type { X402Pay, X402PayConfig } from "@lunora/x402/pay";','import { lazyX402Pay } from "@lunora/x402/pay";'],build:`
313
+ payments,`,stub:l("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:""},V=e=>e?{imports:['import type { X402Pay, X402PayConfig } from "@lunora/x402/pay";','import { lazyX402Pay } from "@lunora/x402/pay";'],build:`
305
314
  const x402: X402Pay = config.x402
306
315
  ? lazyX402Pay(config.x402(env), { getSecret: (name: string) => secrets.get(name) })
307
316
  : x402Stub;
308
317
  `,configField:`
309
- x402?: (env: Record<string, unknown>) => X402PayConfig;`,stub:l("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:""},V=(e,t,n,r,o)=>["AdvisorProcedure","AdvisoryFinding","DatabaseWriterLike","DataMigrationLike","DispatchBookmark","ExportRow",...r?["FlagsResult"]:[],"ImportShardResult","KeyRange","MaskPoliciesResult","MigrationRunResult","QueryReadScope",...n?["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"]:[],...t?["WorkflowsResult"]:[],...e?["WriteHook"]:[]];export{I as A,B,w as a,R as b,$ as c,S as d,k as e,F as f,A as g,C as h,_ as i,E as j,O as k,T as l,q as m,D as n,j as o,Q as p,K as q,l as r,U as s,M as t,V as u,x as v,L as w,N as x,W as y,P as z};
318
+ x402?: (env: Record<string, unknown>) => X402PayConfig;`,stub:l("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:""},H=(e,t,n,r,o)=>["AdvisorProcedure","AdvisoryFinding","DatabaseWriterLike","DataMigrationLike","DispatchBookmark","ExportRow",...r?["FlagsResult"]:[],"ImportShardResult","KeyRange","MaskPoliciesResult","MigrationRunResult","QueryReadScope",...n?["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"]:[],...t?["WorkflowsResult"]:[],...e?["WriteHook"]:[]];export{q as A,B,D as C,R as a,N as b,F as c,L as d,k as e,$ as f,C as g,_ as h,E as i,O as j,P as k,j as l,I as m,T as n,U as o,K as p,V as q,l as r,M as s,Q as t,w as u,H as v,x as w,A as x,S as y,W as z};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/codegen",
3
- "version": "1.0.0-alpha.240",
3
+ "version": "1.0.0-alpha.242",
4
4
  "description": "Code generator for Lunora: emits _generated/{api,server,dataModel}.ts from your schema",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -46,15 +46,15 @@
46
46
  "access": "public"
47
47
  },
48
48
  "dependencies": {
49
- "@lunora/advisor": "1.0.0-alpha.172",
50
- "@lunora/agent": "1.0.0-alpha.154",
51
- "@lunora/container": "1.0.0-alpha.63",
52
- "@lunora/errors": "1.0.0-alpha.47",
53
- "@lunora/platform": "1.0.0-alpha.44",
54
- "@lunora/queue": "1.0.0-alpha.79",
55
- "@lunora/scheduler": "1.0.0-alpha.98",
56
- "@lunora/values": "1.0.0-alpha.57",
57
- "@lunora/workflow": "1.0.0-alpha.68",
49
+ "@lunora/advisor": "1.0.0-alpha.174",
50
+ "@lunora/agent": "1.0.0-alpha.156",
51
+ "@lunora/container": "1.0.0-alpha.64",
52
+ "@lunora/errors": "1.0.0-alpha.48",
53
+ "@lunora/platform": "1.0.0-alpha.46",
54
+ "@lunora/queue": "1.0.0-alpha.81",
55
+ "@lunora/scheduler": "1.0.0-alpha.100",
56
+ "@lunora/values": "1.0.0-alpha.58",
57
+ "@lunora/workflow": "1.0.0-alpha.69",
58
58
  "jiti": "^2.7.0",
59
59
  "quicktype-core": "^26.0.0",
60
60
  "ts-morph": "^28.0.0"
@@ -1 +0,0 @@
1
- import{existsSync as d}from"node:fs";import{join as p}from"node:path";import{agentDefaultName as f,agentClassName as b,agentBindingName as N,voiceBindingName as A,voiceClassName as y}from"@lunora/agent/naming";import{LunoraError as m}from"@lunora/errors";import{Node as a,SyntaxKind as u}from"ts-morph";import{diagnosticAt as l}from"./CodegenDiagnosticError-BUXlG3P-.mjs";import{unwrapToCallExpression as w,findObjectProperty as g,stringPropertyFor as h}from"./listLunoraSourceFiles-DP-5e-RE.mjs";const E="agents.ts",I=i=>{const t=i.getSymbol();if(!t)return i.getText()==="defineAgent";for(const n of t.getDeclarations())if(a.isImportSpecifier(n))return n.getImportDeclaration().getModuleSpecifierValue()!=="@lunora/agent"?!1:n.getNameNode().getText()==="defineAgent";return!1},P=h("agent"),T=(i,t,n)=>{if(i.getKind()===u.TrueKeyword)return!0;if(i.getKind()===u.FalseKeyword)return!1;throw l(i,`agent "${t}": \`${n}\` must be a static boolean literal — it is deploy configuration codegen writes into the ctx.agents wiring spec`)},v=(i,t)=>{const n=i.getArguments()[0];if(!n||!a.isObjectLiteralExpression(n))throw l(i,`agent "${t}": defineAgent must be passed an inline object literal`);const o={bindingName:N(t),className:b(t),exportName:t,name:f(t)},e=g(n,"name");e&&a.isPropertyAssignment(e)&&(o.name=P(e.getInitializerOrThrow(),t,"name"));const r=g(n,"publicRun");r&&a.isPropertyAssignment(r)&&T(r.getInitializerOrThrow(),t,"publicRun")&&(o.publicRun=!0);const s=g(n,"voice");if(s&&a.isPropertyAssignment(s)){const c=s.getInitializerOrThrow();if(!a.isObjectLiteralExpression(c))throw l(c,`agent "${t}": \`voice\` must be an inline object literal — its presence tells codegen to emit the voice-session Durable Object`);o.voice=!0,o.voiceBindingName=A(t),o.voiceClassName=y(t)}return g(n,"onEmail")&&(o.onEmail=!0),o},D=i=>{const t=[];for(const n of i.getVariableDeclarations()){if(!n.isExported())continue;const o=w(n.getInitializer());if(!o)continue;const e=o.getExpression();if(!a.isIdentifier(e)||!I(e))continue;const r=n.getNameNode();if(!a.isIdentifier(r))throw l(r,"defineAgent exports must be plain named exports (no destructuring)");t.push(v(o,r.getText()))}return t},x=i=>{const t=new Map,n=new Map,o=new Map;for(const e of i){const r=t.get(e.name);if(r!==void 0)throw new m("DUPLICATE_AGENT_NAME",`Duplicate agent name "${e.name}": produced by both "${r}" and "${e.exportName}". Deployed agent names must be unique across the project.`,{status:500});t.set(e.name,e.exportName);const s=n.get(e.bindingName);if(s!==void 0)throw new m("DUPLICATE_AGENT_BINDING",`Duplicate agent binding "${e.bindingName}": produced by both "${s}" and "${e.exportName}". Agent export names must yield unique binding names.`,{status:500});n.set(e.bindingName,e.exportName);const c=o.get(e.className);if(c!==void 0)throw new m("DUPLICATE_AGENT_CLASS",`Duplicate agent class "${e.className}": produced by both "${c}" and "${e.exportName}". Agent export names must yield unique generated class names.`,{status:500});o.set(e.className,e.exportName)}},_=(i,t)=>{const n=p(t,E);if(!d(n))return[];const o=i.getSourceFile(n)??i.addSourceFileAtPath(n),e=D(o);return e.sort((r,s)=>r.exportName.localeCompare(s.exportName)),x(e),e};export{E as AGENTS_FILENAME,_ as discoverAgents};
@@ -1 +0,0 @@
1
- import{existsSync as T}from"node:fs";import{join as A}from"node:path";import{containerClassName as L,containerBindingName as k,normalizeContainerImage as d}from"@lunora/container";import{SyntaxKind as g,Node as s}from"ts-morph";import{diagnosticAt as c}from"./CodegenDiagnosticError-BUXlG3P-.mjs";import{propertyKeyName as b,stringPropertyFor as v,findObjectProperty as h,symbolConstInitializer as P}from"./listLunoraSourceFiles-DP-5e-RE.mjs";const $="containers.ts",O=e=>{const t=e.getSymbol();if(!t)return e.getText()==="defineContainer";for(const n of t.getDeclarations())if(s.isImportSpecifier(n))return n.getImportDeclaration().getModuleSpecifierValue()!=="@lunora/container"?!1:n.getNameNode().getText()==="defineContainer";return!1},f=v("container"),p=(e,t,n)=>{if(s.isNumericLiteral(e))return e.getLiteralValue();throw c(e,`container "${t}": \`${n}\` must be a static number literal — it is deploy configuration codegen writes into wrangler.jsonc`)},I=(e,t)=>{if(s.isStringLiteral(e)||s.isNoSubstitutionTemplateLiteral(e))return d(e.getLiteralValue());if(s.isObjectLiteralExpression(e)){const n=h(e,"registry");if(n&&s.isPropertyAssignment(n)){const i=n.getInitializerOrThrow();return d({registry:f(i,t,"image.registry")})}const r=h(e,"build");if(r&&s.isPropertyAssignment(r)){const i=r.getInitializerOrThrow();return d({build:f(i,t,"image.build")})}}throw c(e,`container "${t}": \`image\` must be a static string path, { registry: "…" }, or { build: "…" } literal`)},j=new Set(["buildArgs","image","instanceType","maxInstances","name","rollout"]),C=new Set(["gracePeriodSeconds","stepPercentage"]),w=e=>{let t=e;for(;s.isAsExpression(t)||s.isSatisfiesExpression(t)||s.isTypeAssertion(t)||s.isParenthesizedExpression(t);)t=t.getExpression();return t},z=(e,t)=>{const n=i=>{let o=i;for(;s.isPropertyAccessExpression(o)||s.isElementAccessExpression(o)||s.isParenthesizedExpression(o);)o=o.getExpression();return o===i?void 0:o},r=i=>i!==void 0&&s.isIdentifier(i)&&i.getSymbol()===e;return t.getDescendants().some(i=>{if(s.isBinaryExpression(i)){const o=i.getOperatorToken().getKind();return o>=g.FirstAssignment&&o<=g.LastAssignment&&r(n(i.getLeft()))}if(s.isPrefixUnaryExpression(i)||s.isPostfixUnaryExpression(i)){const o=i.getOperatorToken();return(o===g.PlusPlusToken||o===g.MinusMinusToken)&&r(n(i.getOperand()))}return s.isDeleteExpression(i)?r(n(i.getExpression())):s.isCallExpression(i)&&i.getExpression().getText()==="Object.assign"&&r(i.getArguments()[0])})},M=16,E=(e,t,n,r)=>{let i={name:n,symbol:e},o;for(let a=0;a<M;a+=1){const l=P(i.symbol);if(l===void 0||!s.isExpression(l))return o;if(o=w(l),s.isObjectLiteralExpression(o)&&i.symbol!==void 0&&z(i.symbol,t.getSourceFile()))throw c(t,`${r}: \`${i.name}\` is a const object that is written to elsewhere in this file, so its initializer is not the value the container runs with. Declare the settings where they are final.`);if(!s.isIdentifier(o))return o;i={name:o.getText(),symbol:o.getSymbol()}}return o},S=(e,t)=>{const n=w(e);return s.isIdentifier(n)?E(n.getSymbol(),n,n.getText(),t)??n:n},x=e=>{const t=e.getNonNullableType();return(t.isUnion()?t.getUnionTypes():[t]).flatMap(r=>r.getApparentType().getProperties().map(i=>i.getName()))},N=(e,t,n)=>{const r=e.getExpression().getType(),i=t==="every"||r.isAny()||r.isUnknown()?["its keys"]:[...new Set(x(r))].filter(o=>t.has(o)).map(o=>`\`${o}\``);if(i.length>0)throw c(e,`${n}: this spread can set ${i.join(", ")}, which codegen writes into wrangler.jsonc and so must read statically. Spread a module-scope \`const\` object literal, or write the keys inline.`)},F=(e,t,n)=>{const r=b(e),i=s.isShorthandPropertyAssignment(e)?E(e.getValueSymbol(),e,r,n):void 0;if(i!==void 0)return[r,i];if(t==="every"||t.has(r))throw c(e,`${n}: \`${r}\` is deploy configuration codegen writes into wrangler.jsonc, so it must be a static literal — inline it, or name a module-scope \`const\` initialized with one.`)},m=(e,t,n,r=new Set)=>{const i=[],o=new Set(r).add(e);for(const a of e.getProperties())if(s.isPropertyAssignment(a))i.push([b(a),S(a.getInitializerOrThrow(),n)]);else if(s.isSpreadAssignment(a))i.push(...D(a,t,n,o));else{const l=F(a,t,n);l!==void 0&&i.push(l)}return i},D=(e,t,n,r)=>{const i=S(e.getExpression(),n);if(!s.isObjectLiteralExpression(i))return N(e,t,n),[];if(r.has(i))throw c(e,`${n}: this spread refers back to an object it is part of, so it has no static value.`);return m(i,t,n,r)},V=(e,t)=>{if(!s.isObjectLiteralExpression(e))throw c(e,`container "${t}": \`buildArgs\` must be a static object literal — it is deploy configuration codegen writes into wrangler.jsonc`);const n={};for(const[r,i]of m(e,"every",`container "${t}" buildArgs`))n[r]=f(i,t,`buildArgs.${r}`);return Object.keys(n).length>0?n:void 0},B=(e,t)=>{if(!s.isObjectLiteralExpression(e))throw c(e,`container "${t}": \`rollout\` must be a static object literal — it is deploy configuration codegen writes into wrangler.jsonc`);const n={};for(const[r,i]of m(e,C,`container "${t}" rollout`))(r==="gracePeriodSeconds"||r==="stepPercentage")&&(n[r]=p(i,t,`rollout.${r}`));return n.gracePeriodSeconds===void 0&&n.stepPercentage===void 0?void 0:n},K=e=>{if(s.isTrueLiteral(e))return!0;if(s.isFalseLiteral(e))return!1},U=e=>{if(s.isStringLiteral(e)||s.isNoSubstitutionTemplateLiteral(e)||s.isNumericLiteral(e))return e.getLiteralValue()},R=(e,t)=>{if(s.isStringLiteral(e))return e.getLiteralValue();if(s.isObjectLiteralExpression(e)){const n={};for(const r of e.getProperties()){if(!s.isPropertyAssignment(r))throw c(r,`container "${t}": \`instanceType\` must be an object of static number literals`);const i=b(r);if(i!=="diskMb"&&i!=="memoryMib"&&i!=="vcpu")throw c(r,`container "${t}": unknown \`instanceType\` field "${i}" — expected vcpu, memoryMib, or diskMb`);n[i]=p(r.getInitializerOrThrow(),t,`instanceType.${i}`)}return n}throw c(e,`container "${t}": \`instanceType\` must be a static string or { vcpu, memoryMib, diskMb } literal`)},_=(e,t)=>{const n=e.getArguments()[0];if(!n||!s.isObjectLiteralExpression(n))throw c(e,`container "${t}": defineContainer must be passed an inline object literal`);const r={bindingName:k(t),className:L(t),exportName:t,image:{buildContext:".",dockerfilePath:"./Dockerfile",kind:"dockerfile"}};let i=!1;for(const[o,a]of m(n,j,`container "${t}"`))switch(o){case"buildArgs":{r.buildArgs=V(a,t);break}case"enableInternet":{r.enableInternet=K(a);break}case"image":{r.image=I(a,t),i=!0;break}case"instanceType":{r.instanceType=R(a,t);break}case"maxInstances":{r.maxInstances=p(a,t,"maxInstances");break}case"name":{r.name=f(a,t,"name");break}case"rollout":{r.rollout=B(a,t);break}case"sleepAfter":{r.sleepAfter=U(a);break}}if(!i)throw c(n,`container "${t}": defineContainer requires a static \`image\` property`);return r},q=e=>{const t=[],n=new Map;for(const r of e.getVariableDeclarations()){if(!r.isExported())continue;const i=r.getInitializer();if(i?.getKind()!==g.CallExpression)continue;const o=i,a=o.getExpression();if(!s.isIdentifier(a)||!O(a))continue;const l=r.getNameNode();if(!s.isIdentifier(l))throw c(l,"defineContainer exports must be plain named exports (no destructuring)");const u=_(o,l.getText()),y=n.get(u.bindingName);if(y!==void 0)throw c(l,`containers "${y}" and "${u.exportName}" both map to the binding ${u.bindingName} — rename one so each container gets its own Durable Object binding`);n.set(u.bindingName,u.exportName),t.push(u)}return t},Q=(e,t)=>{const n=A(t,$);if(!T(n))return[];const r=e.getSourceFile(n)??e.addSourceFileAtPath(n),i=q(r);return i.sort((o,a)=>o.exportName.localeCompare(a.exportName)),i};export{$ as CONTAINERS_FILENAME,Q as discoverContainers};
@@ -1 +0,0 @@
1
- import{NODE_CAPABILITIES as f,CLOUDFLARE_CAPABILITIES as h,CELLD_CAPABILITIES as v}from"@lunora/platform";import{readProjectConfigLiterals as m}from"./loadProjectConfig-CKsFNgn3.mjs";const c="cloudflare",b=t=>{const{target:e}=m(t);return e!==void 0&&e.length>0?e:void 0},L=(t,e)=>e??b(t)??c,x=(t,e)=>{if(e!==void 0)return[];const{target:a,unreadable:r}=m(t);return r!==!0||a!==void 0?[]:[{level:"warn",message:`lunora.config declares a \`target\` that codegen cannot read without evaluating it, so the "${c}" surface was emitted. \`runCodegen\` resolves the target synchronously, which means it reads literals only.`,name:"platform_unreadable_target",remediation:`Write \`target\` as a string literal on the config's default export (\`export default { target: "${c}" }\`), or pass \`--target\`.`,target:c}]},u={celld:v,cloudflare:h,node:f},C=()=>Object.keys(u).toSorted((t,e)=>t.localeCompare(e)),y={access:null,ai:"ai",analytics:"analytics",browser:"browser",container:"containers",flags:null,hyperdrive:"hyperdrive",images:"images",kv:"keyValueStore",mail:"mail",notify:null,payments:null,pipelines:"pipelines",r2sql:null,scheduler:"scheduler",storage:"objectStorage",vectors:"vectorStore",workflows:"workflows",x402:null},w=["agents","commitOrderedTables","containerEgressPolicy","cronTriggers","crossShardFanout","durableStreams","globalTables","queues","relationGraph","secrets","vectorStore","workerLoaders","workflowRollback"],g={agents:"durable agents (`defineAgent`)",commitOrderedTables:"commit-ordered tables (`.commitOrdered()`)",containerEgressPolicy:"container egress policies (`defineContainer({ allowedHosts | deniedHosts | interceptHttps })`)",cronTriggers:"declared cron triggers (`cronJobs()`)",crossShardFanout:"cross-shard fan-out queries (a `.shardBy(...)` schema)",durableStreams:"durable streams (`.stream(handler, { durable: true })`)",globalTables:"global tables (`.global()`)",queues:"queues (`defineQueue`)",relationGraph:"relation-graph traversal (`ctx.db.related`, derived from `v.id(...)` columns)",secrets:"the secrets store (`ctx.secrets`)",vectorStore:"vector indexes (`.vectorize()`)",workerLoaders:"sandboxed agent scripts (`jsCodeTool`, on Worker Loaders)",workflowRollback:"workflow step rollback (`defineStep({ rollback })`)"},S=(t,e,a)=>({level:"error",message:`${e.name} does not support ${g[t]}, which this app declares.`,name:"platform_unsupported_feature",remediation:`Remove the declaration, or deploy to a target whose capability matrix marks "${t}" as native or emulated.`,target:a}),T=(t,e,a)=>({level:"error",message:`${e.name}'s capability matrix does not declare a support level for ${g[t]}, which this app declares. Treated as unsupported.`,name:"platform_undeclared_feature",remediation:`Rate "${t}" in the ${e.name} capability matrix as "native", "emulated", or "unsupported" — an undeclared feature fails closed rather than letting the app deploy onto a primitive the host may not provide.`,target:a}),_=t=>{const{diagnostics:e,gatedSignals:a,matrix:r,reported:n,signals:d,target:l}=t;for(const s of w){if(d[s]!==!0)continue;const o=r.features[s]?.level;o!=="unsupported"&&o!==void 0||(a[s]=!1,!n.has(s)&&e.push(o==="unsupported"?S(s,r,l):T(s,r,l)))}},$=(t,e,a,r={})=>{const n={...t},d={...r},l=[],s=new Set;for(const[o,i]of Object.entries(y)){if(i===null||!t[o])continue;const p=e.features[i]?.level;p==="unsupported"?(n[o]=!1,s.add(i),l.push({feature:o,level:"error",message:`${e.name} does not support "${o}" (ctx.${o}).`,name:"platform_unsupported_feature",remediation:`Remove the ctx.${o} usage, or deploy to a target whose capability matrix marks "${i}" as native or emulated.`,target:a})):p===void 0&&(n[o]=!1,s.add(i),l.push({feature:o,level:"error",message:`${e.name}'s capability matrix does not declare a support level for "${o}" (ctx.${o}). Treated as unsupported.`,name:"platform_undeclared_feature",remediation:`Rate "${i}" in the ${e.name} capability matrix as "native", "emulated", or "unsupported" — an undeclared feature fails closed rather than shipping a surface the host may not provide.`,target:a}))}return _({diagnostics:l,gatedSignals:d,matrix:e,reported:s,signals:r,target:a}),{diagnostics:l,signals:d,usage:n}},E=(t,e,a={})=>{const r=u[e];return r===void 0?{diagnostics:[{level:"error",message:`Unknown deploy target "${e}" — no capability matrix is registered for it. Codegen emitted the full Cloudflare surface un-gated.`,name:"platform_unknown_target",remediation:`Use a registered target (${Object.keys(u).join(", ")}) or install the target's @lunora/platform-${e} package.`,target:e}],signals:{...a},usage:{...t}}:$(t,r,e,a)},I=t=>{const e=u[t];if(e===void 0)return;const a=Object.entries(e.features).filter(([,r])=>r.level==="unsupported").map(([r])=>r).toSorted((r,n)=>r.localeCompare(n));return{id:e.id,name:e.name,unsupported:a}};export{y as CAPABILITY_TO_FEATURE,c as DEFAULT_TARGET,$ as gateAgainstMatrix,E as gatePlatformFeatures,C as platformMatrixIds,b as readProjectTarget,x as readTargetDiagnostics,L as resolveCodegenTarget,I as studioPlatformFor};