@lunora/codegen 1.0.0-alpha.25 → 1.0.0-alpha.250

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 (113) hide show
  1. package/LICENSE.md +6 -0
  2. package/README.md +1 -1
  3. package/dist/index.d.mts +3755 -1247
  4. package/dist/index.d.ts +3755 -1247
  5. package/dist/index.mjs +1 -34
  6. package/dist/packem_shared/AGENTS_FILENAME-D8SgT3OR.mjs +1 -0
  7. package/dist/packem_shared/CONTAINERS_FILENAME-C13yKxas.mjs +1 -0
  8. package/dist/packem_shared/CodegenDiagnosticError-BUXlG3P-.mjs +1 -0
  9. package/dist/packem_shared/DEFAULT_TARGET-vMWzRzRF.mjs +1 -0
  10. package/dist/packem_shared/FLAGS_FILENAME-W5XQz_Po.mjs +1 -0
  11. package/dist/packem_shared/GENERATED_HEADER-DSXl0YM2.mjs +1 -0
  12. package/dist/packem_shared/LUNORA_ERROR_CODES-C2s0xWQD.mjs +1 -0
  13. package/dist/packem_shared/MUTATORS_FILENAME-DqWOgC5Z.mjs +1 -0
  14. package/dist/packem_shared/NOTIFY_FILENAME-C1J_47et.mjs +1 -0
  15. package/dist/packem_shared/OPENRPC_VERSION-Cr7Zzp6s.mjs +3 -0
  16. package/dist/packem_shared/PROJECT_CONFIG_FILENAMES-DzOu-lSc.mjs +1 -0
  17. package/dist/packem_shared/QUEUES_FILENAME-RGwht3Xu.mjs +1 -0
  18. package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-jefy8GTn.mjs +11 -0
  19. package/dist/packem_shared/SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs +2 -0
  20. package/dist/packem_shared/SDK_LANGUAGES-Df_CnJx5.mjs +372 -0
  21. package/dist/packem_shared/SHAPES_FILENAME-DRUFomCj.mjs +1 -0
  22. package/dist/packem_shared/SchemaSnapshotParseError-CPOXlFhI.mjs +18 -0
  23. package/dist/packem_shared/WORKFLOWS_FILENAME-4-ib4HH-.mjs +1 -0
  24. package/dist/packem_shared/buildOpenApiDocument-SxfElVzK.mjs +3 -0
  25. package/dist/packem_shared/capabilities-CqnIsyA9.mjs +20 -0
  26. package/dist/packem_shared/chain-mte5djRJ.mjs +1 -0
  27. package/dist/packem_shared/classify-procedure-call-CmcShAze.mjs +1 -0
  28. package/dist/packem_shared/context-property-calls-CWf9-6G5.mjs +1 -0
  29. package/dist/packem_shared/contextPropertiesRead-BGy4tGCY.mjs +1 -0
  30. package/dist/packem_shared/declared-output-Iaar469J.mjs +1 -0
  31. package/dist/packem_shared/describeErrorLevelFindings-vzaGS9KL.mjs +1 -0
  32. package/dist/packem_shared/discoverAuthApiCalls-DoSN_yc3.mjs +1 -0
  33. package/dist/packem_shared/discoverCrons-BEALHx1S.mjs +1 -0
  34. package/dist/packem_shared/discoverFunctions-BcBzcG5x.mjs +1 -0
  35. package/dist/packem_shared/discoverHttpRoutes-CJHS4llq.mjs +1 -0
  36. package/dist/packem_shared/discoverHyperdriveCalls-Bkbh4tG7.mjs +1 -0
  37. package/dist/packem_shared/discoverInserts-DpuLYPPd.mjs +1 -0
  38. package/dist/packem_shared/discoverMaskProcedures-B0w8gM0S.mjs +1 -0
  39. package/dist/packem_shared/discoverMigrations-Dt7ywfZv.mjs +1 -0
  40. package/dist/packem_shared/discoverNondeterministicCalls-CNJV2BiP.mjs +1 -0
  41. package/dist/packem_shared/discoverQueries-BcdqjYky.mjs +1 -0
  42. package/dist/packem_shared/discoverR2sqlCalls-30Wtbc0P.mjs +1 -0
  43. package/dist/packem_shared/discoverRlsMetadata-mXBmPOGj.mjs +1 -0
  44. package/dist/packem_shared/discoverRlsProcedures-F4Cy-kSi.mjs +1 -0
  45. package/dist/packem_shared/discoverSandboxUsage-BnsPld5I.mjs +1 -0
  46. package/dist/packem_shared/discoverSchema-D5R60b4F.mjs +1 -0
  47. package/dist/packem_shared/discoverStorageRulesMetadata-D3Ot9g5f.mjs +1 -0
  48. package/dist/packem_shared/emitAgents-3XP5C-VJ.mjs +1 -0
  49. package/dist/packem_shared/emitApi-DdW9RyGG.mjs +154 -0
  50. package/dist/packem_shared/emitApp-T_My13i6.mjs +860 -0
  51. package/dist/packem_shared/emitCrons-BRKXFGFu.mjs +83 -0
  52. package/dist/packem_shared/emitDataModel-D3WuEZ4b.mjs +113 -0
  53. package/dist/packem_shared/emitDrizzleSchema-Cv0HtLR3.mjs +15 -0
  54. package/dist/packem_shared/emitFunctions-BgNeOZt_.mjs +249 -0
  55. package/dist/packem_shared/emitServer-DQxwHVPM.mjs +374 -0
  56. package/dist/packem_shared/emitShard-BDfiH_JF.mjs +1 -0
  57. package/dist/packem_shared/exported-procedure-chains-D48EXUVQ.mjs +1 -0
  58. package/dist/packem_shared/fingerprintSchemaSources-Cl1CJFeh.mjs +1 -0
  59. package/dist/packem_shared/formatAdvisories-DwmUKYuc.mjs +2 -0
  60. package/dist/packem_shared/index-D7dKfGPh.mjs +1 -0
  61. package/dist/packem_shared/ir-DBSvhNa-.mjs +1 -0
  62. package/dist/packem_shared/isD1GlobalTable-udvHAAzD.mjs +1 -0
  63. package/dist/packem_shared/isTypedSchema-CKzc3ioR.mjs +4 -0
  64. package/dist/packem_shared/json-data-Chfs2Cz5.mjs +1 -0
  65. package/dist/packem_shared/listLunoraSourceFiles-CSlcBYlo.mjs +1 -0
  66. package/dist/packem_shared/loadProjectConfig-nNIDOrlR.mjs +1 -0
  67. package/dist/packem_shared/module-specifiers-WF8iAydP.mjs +1 -0
  68. package/dist/packem_shared/modules-DyCocr1e.mjs +1 -0
  69. package/dist/packem_shared/parse-validator-C6fHL7OS.mjs +1 -0
  70. package/dist/packem_shared/paths-C-9fwEgQ.mjs +1 -0
  71. package/dist/packem_shared/qualifiers-BhOL15WZ.mjs +1 -0
  72. package/dist/packem_shared/readPackageDependencies-C6h6FZuP.mjs +1 -0
  73. package/dist/packem_shared/readServiceBindings-CeQvSswr.mjs +1 -0
  74. package/dist/packem_shared/redact-Cy14LEnc.mjs +1 -0
  75. package/dist/packem_shared/schemaFromIr-BWFnvCVg.mjs +1 -0
  76. package/dist/packem_shared/shard-f7coQFS9.mjs +1435 -0
  77. package/dist/packem_shared/shard-runtime-CyEbIjPA.mjs +321 -0
  78. package/dist/packem_shared/shared-DjUziztz.mjs +9 -0
  79. package/dist/packem_shared/unwrap-handler-return-DVY_kFF7.mjs +1 -0
  80. package/package.json +16 -7
  81. package/dist/packem_shared/CONTAINERS_FILENAME-DlP6YM_Q.mjs +0 -224
  82. package/dist/packem_shared/CodegenDiagnosticError-DeblMkzO.mjs +0 -23
  83. package/dist/packem_shared/FLAGS_FILENAME-B1vE0LIo.mjs +0 -139
  84. package/dist/packem_shared/GENERATED_HEADER-BullHnLo.mjs +0 -3265
  85. package/dist/packem_shared/LUNORA_ERROR_CODES-CySpQPD3.mjs +0 -61
  86. package/dist/packem_shared/LUNORA_SOLUTION_RULES-BTejmZp-.mjs +0 -131
  87. package/dist/packem_shared/MUTATORS_FILENAME-BhqdPtKp.mjs +0 -81
  88. package/dist/packem_shared/OPENRPC_VERSION-D7MAVX3K.mjs +0 -60
  89. package/dist/packem_shared/QUEUES_FILENAME-B5_eWCRe.mjs +0 -119
  90. package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-BAcxxSdB.mjs +0 -1130
  91. package/dist/packem_shared/SCHEMA_SNAPSHOT_VERSION-wWGP2_5E.mjs +0 -245
  92. package/dist/packem_shared/SHAPES_FILENAME-ChV7MqgE.mjs +0 -94
  93. package/dist/packem_shared/WORKFLOWS_FILENAME-CCisG0Vy.mjs +0 -124
  94. package/dist/packem_shared/buildOpenApiDocument-Bm56LsBb.mjs +0 -183
  95. package/dist/packem_shared/discover-ast-CT6BgBr4.mjs +0 -13
  96. package/dist/packem_shared/discoverAuthApiCalls-CoirYbg6.mjs +0 -62
  97. package/dist/packem_shared/discoverCrons-Cev7RRAf.mjs +0 -257
  98. package/dist/packem_shared/discoverFunctions-BWMczzBx.mjs +0 -465
  99. package/dist/packem_shared/discoverHttpRoutes-CfP6cMzt.mjs +0 -131
  100. package/dist/packem_shared/discoverInserts-C7zxXkUf.mjs +0 -61
  101. package/dist/packem_shared/discoverMaskProcedures-Cm81kwrb.mjs +0 -217
  102. package/dist/packem_shared/discoverMigrations-Bi5nJ0mJ.mjs +0 -97
  103. package/dist/packem_shared/discoverNondeterministicCalls-C4M8AXmQ.mjs +0 -122
  104. package/dist/packem_shared/discoverQueries-B0wGT-xe.mjs +0 -62
  105. package/dist/packem_shared/discoverR2sqlCalls-BVNMd428.mjs +0 -80
  106. package/dist/packem_shared/discoverRlsMetadata-BS9GOGC5.mjs +0 -280
  107. package/dist/packem_shared/discoverSchema-KYq55qu3.mjs +0 -864
  108. package/dist/packem_shared/discoverStorageRulesMetadata-Da8BKXcI.mjs +0 -97
  109. package/dist/packem_shared/emitApp-BUN7hhlY.mjs +0 -666
  110. package/dist/packem_shared/formatAdvisories-DdjK7sgh.mjs +0 -81
  111. package/dist/packem_shared/parse-validator-Cabb60UV.mjs +0 -133
  112. package/dist/packem_shared/paths-BRd6JHuF.mjs +0 -11
  113. package/dist/packem_shared/schemaFromIr-DTYsLBaA.mjs +0 -57
@@ -0,0 +1,321 @@
1
+ import{s as v}from"./ir-DBSvhNa-.mjs";import{r as x}from"./json-data-Chfs2Cz5.mjs";import{C as k}from"./capabilities-CqnIsyA9.mjs";import{a as c,G as f}from"./shared-DjUziztz.mjs";const P=e=>e?{importFragment:"serveRelationFanout, ",override:`
2
+ protected override async runRelationFanoutRead(functionPath: string, args: Record<string, unknown>): Promise<unknown> {
3
+ this.ensureMigrated();
4
+
5
+ const { db } = this.buildCtx({ functionPath }) as { db: DatabaseWriterLike };
6
+
7
+ return serveRelationFanout(schema as unknown as SchemaLike, db, functionPath, args);
8
+ }
9
+ `}:{importFragment:"",override:""},y=(e,r,t,{cast:n="",sync:o=[]}={})=>{const i=t.map(u=>` ${u}: ${o.includes(u)?"":"async "}() => {
10
+ ${r}
11
+ },`).join(`
12
+ `);return`
13
+ const ${e} = {
14
+ ${i}
15
+ }${n};
16
+ `},h={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
+ /** The \`.shardBy()\` tables this shard registers with the shard registry when it writes them. */
18
+ const SHARDED_TABLES: ReadonlySet<string> = new Set([${[...e].map(r=>JSON.stringify(r)).join(", ")}]);
19
+ `,override:`
20
+ protected override shardRegistry(): undefined | { namespace: unknown; shardedTables: ReadonlySet<string> } {
21
+ const namespace = config.shardRegistry?.((this.env ?? {}) as Record<string, unknown>);
22
+
23
+ return namespace === undefined ? undefined : { namespace, shardedTables: SHARDED_TABLES };
24
+ }
25
+ `},I=(e,r)=>e?{build:`
26
+ const flags: import("${r}").LunoraFlags = createFlags(flagsConfig, env, {
27
+ provider: () => config.flags?.(env),
28
+ targetingKey: () => flagsConfig.identify?.({ identity: identity ?? null, userId: userId ?? null }),
29
+ });
30
+ `,configField:`
31
+ flags?: (env: Record<string, unknown>) => import("${r}").Provider;`,contextField:`
32
+ flags,`,importLines:[`import { createFlags } from "${r}";`,'import flagsConfig from "../flags.js";'],stub:""}:h,T=e=>e?{build:`
33
+ const { notify, push } = createNotify(notifyConfig, env, { log, metrics });
34
+ `,configField:"",contextField:`
35
+ notify,
36
+ push,`,importLines:['import { createNotify } from "@lunora/notify";','import notifyConfig from "../notify.js";'],stub:""}:h,q=e=>e?{build:`
37
+ const envConfig = lunoraEnvContract.${e.exportName}(env);
38
+ `,configField:"",contextField:`
39
+ env: envConfig,`,importLines:['import * as lunoraEnvContract from "../env.js";'],stub:""}:h,B=(e,r,t)=>{if(!r)return{constant:"",evaluateOverride:"",subscriptionOverride:""};const n=s=>`
40
+ const env = (this.env ?? {}) as Record<string, unknown>;
41
+ const flags: import("${t}").LunoraFlags = createFlags(flagsConfig, env, {
42
+ provider: () => config.flags?.(env),
43
+ targetingKey: ${s},
44
+ });`,o=`
45
+ /** Statically-discovered feature flags (\`ctx.flags.<type>("key")\` reads) served via \`__lunora_admin__:listFlags\` + the reactive \`__lunora_flags__:\` channel. */
46
+ const LUNORA_FLAG_KEYS = ${x(e,'ReadonlyArray<{ key: string; type: "boolean" | "number" | "object" | "string" }>')};
47
+ `,i=`
48
+ protected override async evaluateFlags(context?: Record<string, unknown>): Promise<FlagsResult> {${n("undefined")}
49
+ const evalContext = context as import("${t}").EvaluationContext | undefined;
50
+ const evaluations: FlagsResult["flags"] = [];
51
+
52
+ for (const entry of LUNORA_FLAG_KEYS) {
53
+ // eslint-disable-next-line no-await-in-loop -- flags evaluate sequentially; each shares the single memoized provider client
54
+ const details =
55
+ entry.type === "boolean"
56
+ ? await flags.details.boolean(entry.key, false, evalContext)
57
+ : entry.type === "number"
58
+ ? await flags.details.number(entry.key, 0, evalContext)
59
+ : entry.type === "string"
60
+ ? await flags.details.string(entry.key, "", evalContext)
61
+ : await flags.details.object(entry.key, {}, evalContext);
62
+
63
+ evaluations.push({ errorCode: details.errorCode, key: entry.key, reason: details.reason, type: entry.type, value: details.value, variant: details.variant });
64
+ }
65
+
66
+ return { configured: true, flags: evaluations };
67
+ }
68
+ `,u=`
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
+ const key = typeof args.key === "string" ? args.key : "";
71
+
72
+ // SECURITY: the reactive channel is public (any socket, no auth). Serve
73
+ // ONLY statically-discovered flag keys — an arbitrary client-supplied key
74
+ // would let a subscriber probe the value of internal/unreleased flags the
75
+ // app never exposes. Unknown key ⇒ the "nothing to deliver" sentinel.
76
+ // eslint-disable-next-line unicorn/no-null -- the base hook's "nothing to deliver" sentinel
77
+ if (key.length === 0 || !LUNORA_FLAG_KEYS.some((entry) => entry.key === key)) {
78
+ return Promise.resolve(null);
79
+ }
80
+
81
+ // SECURITY: evaluate under the socket's server-verified identity ONLY
82
+ // (the targetingKey resolved above). Client-supplied targeting context is
83
+ // NOT honored on this public channel — otherwise a subscriber could spoof
84
+ // targeting attributes (e.g. plan/role) to unlock a flag gated on them.
85
+ const context = undefined;
86
+
87
+ if (args.type === "number") {
88
+ return flags.number(key, typeof args.default === "number" ? args.default : 0, context);
89
+ }
90
+
91
+ if (args.type === "string") {
92
+ return flags.string(key, typeof args.default === "string" ? args.default : "", context);
93
+ }
94
+
95
+ if (args.type === "object") {
96
+ return flags.object(key, (args.default ?? {}) as import("${t}").JsonValue, context);
97
+ }
98
+
99
+ return flags.boolean(key, typeof args.default === "boolean" ? args.default : false, context);
100
+ }
101
+ `;return{constant:o,evaluateOverride:i,subscriptionOverride:u}},R=()=>({build:`
102
+ const aiBinding = config.ai?.(env) ?? (env as Record<string, unknown>).AI;
103
+ // Correlate AI-Gateway-routed calls with the Lunora trace: thread the
104
+ // function path + trace id into createAi, which folds them into the
105
+ // gateway's \`metadata\`. Mirror the tracer's anchor guard — a deferred
106
+ // subscription re-run must not borrow a concurrent dispatch's trace, so
107
+ // read \`getCurrentTrace()\` only on the synchronous (non-threaded-identity) path.
108
+ const aiTrace = options.identity ? undefined : this.getCurrentTrace();
109
+ // \`telemetry\` gives every model call an \`ai.generate\` / \`ai.stream\` span
110
+ // and \`gen_ai.usage.*\` token + cost counters attributed to this function.
111
+ const ai: LunoraAi = createAi({
112
+ binding: aiBinding as AiBindingLike | undefined,
113
+ env: env as Record<string, unknown>,
114
+ metadata: { functionPath: options.functionPath, traceId: aiTrace?.traceId },
115
+ telemetry: { metrics, trace },
116
+ });
117
+ `,configField:`
118
+ ai?: (env: Record<string, unknown>) => AiBindingLike;`,importLines:['import type { AiBindingLike, LunoraAi } from "@lunora/ai";','import { createAi } from "@lunora/ai";'],stub:""}),N=()=>({build:`
119
+ const access = accessFacade(identity, userId);
120
+ `,configField:"",importLines:['import { accessFacade } from "@lunora/cloudflare-access/context";'],stub:""}),S=()=>({build:`
121
+ const r2sqlEnv = env as Record<string, unknown>;
122
+ const r2sqlAccountId = (r2sqlEnv.R2_SQL_ACCOUNT_ID ?? r2sqlEnv.CLOUDFLARE_ACCOUNT_ID) as string | undefined;
123
+ const r2sqlToken = r2sqlEnv.R2_SQL_TOKEN as string | undefined;
124
+ const r2sqlBucket = r2sqlEnv.R2_SQL_BUCKET as string | undefined;
125
+ const r2sql: R2SqlClient = config.r2sql
126
+ ? config.r2sql(env)
127
+ : r2sqlAccountId && r2sqlToken && r2sqlBucket
128
+ ? createR2Sql({ accountId: r2sqlAccountId, apiToken: r2sqlToken, bucket: r2sqlBucket })
129
+ : r2sqlStub;
130
+ `,configField:`
131
+ r2sql?: (env: Record<string, unknown>) => R2SqlClient;`,importLines:['import type { R2SqlClient } from "@lunora/bindings/r2sql";','import { createR2Sql } from "@lunora/bindings/r2sql";'],stub:y("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"]})}),b={access:N,ai:R,r2sql:S},d=" ",w=(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`},L=(e,r,t)=>{const n=w(e,r,t),o=`${d}const ${e}Binding = config.${e}?.(env) ?? (env as Record<string, unknown>).${t.envName};
132
+ `,i=t.unvouchableReads??[];return i.length===0?`
133
+ ${o}${d}const ${e}: ${r} = ${n};
134
+ `:`
135
+ ${o}${d}// ${t.envName} is not this shard's SQLite, so nothing appends a \`__cdc_log\` entry
136
+ ${d}// when a value changes — a subscription that read one can never be proven
137
+ ${d}// current on reconnect and must re-snapshot. Reads only; writes stay unstamped.
138
+ ${d}const ${e}: ${r} = markUnvouchableReads(${n}, options.onRead, [
139
+ ${i.map(u=>`${d} ${JSON.stringify(u)},`).join(`
140
+ `)}
141
+ ${d}]);
142
+ `},C=(e,r,t)=>{const{binding:n,clientType:o}=t,i=y(`${e}Stub: ${o}`,`throw new Error("${t.missingMessage}");`,t.stubMethods,{sync:t.syncStubMethods});if(n===void 0)return{build:`
143
+ ${d}const ${e}: ${o} = config.${e} ? config.${e}(env) : ${e}Stub;
144
+ `,configField:`
145
+ ${e}?: (env: Record<string, unknown>) => ${o};`,importLines:[`import type { ${o} } from "${r}";`],stub:i};const u=n.bindingType??o,s=[...new Set([u,o])].toSorted((l,a)=>l.localeCompare(a));return{build:L(e,o,n),configField:`
146
+ ${e}?: (env: Record<string, unknown>) => ${u};`,importLines:[`import type { ${s.join(", ")} } from "${r}";`,...n.factory===void 0?[]:[`import { ${n.factory.name} } from "${r}";`]],stub:i}},A=e=>Object.hasOwn(b,e),D=e=>{const r=[],t=[];let n="",o="",i="",u="",s="";for(const l of k){const{key:a,shardBinding:m}=l;if(m===void 0||!e.has(a))continue;const g=l.contextProperty;let p;A(a)?p=b[a]():m!=="bespoke"&&(p=C(g,l.moduleSpecifier,m)),p!==void 0&&(t.push(...p.importLines),o+=p.configField,s+=p.stub,l.tier==="every"?(i+=p.build,u+=`
147
+ ${g},`):(n+=p.build,r.push(g)))}return{actionBuild:n,actionFields:r,configFields:o,everyBuild:i,everyFields:u,importLines:t,stubs:s}},U=(e,r)=>{if(e.length===0)return"";const t=r?`, ${JSON.stringify(r)}`:"",n=e.map(a=>{c(a.exportName,`container export "${a.exportName}"`),c(a.className,`container class "${a.className}"`);const m=a.sandbox===!0?"LunoraSandboxContainer":"LunoraContainer";return`/** Container DO for the \`${a.exportName}\` definition (binding \`${a.bindingName}\`). */
148
+ export class ${a.className} extends ${m} {
149
+ public constructor(ctx: ConstructorParameters<typeof ${m}>[0], env: Record<string, unknown>) {
150
+ super(ctx, env, ${a.exportName}, "${a.exportName}"${t});
151
+ }
152
+ }
153
+ `}).join(`
154
+ `),o=e.map(a=>a.exportName).join(", "),i=e.some(a=>a.sandbox===!0),u=e.some(a=>a.sandbox!==!0)?`import { LunoraContainer } from "@lunora/container/do";
155
+ `:"";return`${f}/**
156
+ * Container-enabled Durable Object classes for the containers declared in
157
+ * \`lunora/containers.ts\`. Re-export them from your worker entry — wrangler
158
+ * requires each \`containers[].class_name\` to be exported by the worker:
159
+ *
160
+ * \`export * from "./lunora/_generated/containers.js";\`
161
+ *
162
+ * \`ContainerProxy\` is re-exported alongside them: the egress-interception path
163
+ * (\`allowedHosts\`/\`deniedHosts\`/\`interceptHttps\` and the runtime
164
+ * \`handle.egress\` controls) routes container outbound traffic through this
165
+ * WorkerEntrypoint, so it too must be exported by the deployed worker.
166
+ */
167
+ ${u}${i?`import { LunoraSandboxContainer } from "@lunora/container/sandbox";
168
+ `:""}
169
+ import { ${o} } from "../containers.js";
170
+
171
+ export { ContainerProxy } from "@lunora/container/do";
172
+ ${i?`
173
+ /**
174
+ * \`DirectoryBackup\` and \`S3Mount\` route a \`sandbox: true\` container's storage
175
+ * traffic through these WorkerEntrypoints, so the deployed worker must export them.
176
+ */
177
+ export { DirectoryBackupGateway, S3Gateway } from "@lunora/container/sandbox";
178
+ `:""}
179
+ ${n}`},j=(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(`
180
+ `);return{build:`
181
+ const containers = createContainerContext(env, LUNORA_CONTAINERS, ${r?JSON.stringify(r):"undefined"}, this.getCurrentTraceparent(), this.getCurrentSampleErrors());
182
+ `,contextField:`
183
+ containers,`,importLines:['import type { ContainerBindingSpec } from "@lunora/container";','import { createContainerContext } from "@lunora/container";'],specs:`
184
+ /** Wiring specs for \`ctx.containers\` (codegen-derived from \`lunora/containers.ts\`). */
185
+ const LUNORA_CONTAINERS: ReadonlyArray<ContainerBindingSpec> = [
186
+ ${t}
187
+ ];
188
+ `}},Q=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}\`. */
189
+ export class ${n.className} extends LunoraWorkflow<WorkflowParamsOf<typeof ${n.exportName}>, WorkflowOutputOf<typeof ${n.exportName}>> {
190
+ public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
191
+ super(ctx, env, ${n.exportName}, "${n.exportName}");
192
+ }
193
+ }
194
+ `)).join(`
195
+ `),t=e.map(n=>n.exportName).join(", ");return`${f}/**
196
+ * WorkflowEntrypoint classes for the workflows declared in
197
+ * \`lunora/workflows.ts\`. Re-export them from your worker entry — wrangler
198
+ * requires each \`workflows[].class_name\` to be exported by the worker:
199
+ *
200
+ * \`export * from "./lunora/_generated/workflows.js";\`
201
+ */
202
+ import LunoraWorkflow from "@lunora/workflow/do";
203
+
204
+ import { ${t} } from "../workflows.js";
205
+
206
+ /** Params type carried by a \`defineWorkflow\` definition (its phantom \`__params\`), so each entrypoint keeps the authored \`ctx.params\` type. */
207
+ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params }
208
+ ? unknown extends Params
209
+ ? Record<string, unknown>
210
+ : NonNullable<Params>
211
+ : Record<string, unknown>;
212
+
213
+ /** Output type carried by a \`defineWorkflow\` definition (its phantom \`__output\`), so each entrypoint keeps the authored return type. */
214
+ type WorkflowOutputOf<Definition> = Definition extends { __output?: infer Output } ? Output : unknown;
215
+
216
+ ${r}`},M=e=>{if(e.length===0)return"";const t=e.filter(s=>s.voice).length>0,n=e.map(s=>{c(s.exportName,`agent export "${s.exportName}"`),c(s.className,`agent class "${s.className}"`);const l=`/** WorkflowEntrypoint for the \`${s.exportName}\` agent, reached as \`ctx.exports.${s.className}\`. */
217
+ export class ${s.className} extends LunoraWorkflow<AgentRunInput, AgentRunResult> {
218
+ public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
219
+ super(ctx, env, compileAgentWorkflow(${s.exportName}, "${s.exportName}"), "${s.exportName}");
220
+ }
221
+ }
222
+ `;if(!s.voice)return l;const a=s.voiceClassName??"",m=s.voiceBindingName??"";c(a,`agent voice class "${a}"`);const g=`
223
+ /** Voice-session Durable Object for the \`${s.exportName}\` agent (binding \`${m}\`). */
224
+ export class ${a} extends VoiceSessionDO {
225
+ public constructor(ctx: ConstructorParameters<typeof VoiceSessionDO>[0], env: Record<string, unknown>) {
226
+ super(ctx, env, ${s.exportName}, "${s.exportName}");
227
+ }
228
+ }
229
+ `;return`${l}${g}`}).join(`
230
+ `),o=e.map(s=>s.exportName).join(", ");return`${f}/**
231
+ * WorkflowEntrypoint classes for the agents declared in \`lunora/agents.ts\`.
232
+ * Each \`defineAgent\` compiles a replay-safe tool-loop onto a Cloudflare
233
+ * Workflow. Re-export them from your worker entry — wrangler requires each
234
+ * \`workflows[].class_name\` to be exported by the worker:
235
+ *
236
+ * \`export * from "./lunora/_generated/agents.js";\`${t?"\n *\n * Voice-enabled agents ALSO get a `VoiceSessionDO` subclass here — a real\n * Durable Object (unlike the Workflow), so wrangler needs both its\n * `durable_objects` binding and its `class_name` export (the same re-export\n * line covers it).":""}
237
+ */
238
+ import LunoraWorkflow from "@lunora/workflow/do";
239
+ ${t?'import { compileAgentWorkflow, VoiceSessionDO } from "@lunora/agent";':'import { compileAgentWorkflow } from "@lunora/agent";'}
240
+ import type { AgentRunInput, AgentRunResult } from "@lunora/agent";
241
+
242
+ import { ${o} } from "../agents.js";
243
+
244
+ ${n}`},K=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(`
245
+ `);return`${f}/**
246
+ * Push-consumer registry for the queues declared in \`lunora/queues.ts\`. The
247
+ * composed worker's \`queue(batch, env, ctx)\` entry routes each delivered batch
248
+ * by \`batch.queue\` to the matching \`defineQueue\` handler. Wired automatically
249
+ * by \`defineApp\` — you don't import this directly.
250
+ */
251
+ import type { QueueRegistry } from "@lunora/queue";
252
+
253
+ import { ${t} } from "../queues.js";
254
+
255
+ /** Stable wrangler queue name → { binding, definition, exportName } for batch routing. */
256
+ export const LUNORA_QUEUE_REGISTRY: QueueRegistry = {
257
+ ${n}
258
+ };
259
+ `},G=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(`
260
+ `);return{build:`
261
+ const workflows = createWorkflowContext(env, LUNORA_WORKFLOWS, this.state.exports);
262
+ `,contextField:`
263
+ workflows,`,importLines:['import type { WorkflowBindingSpec } from "@lunora/workflow";','import { createWorkflowContext } from "@lunora/workflow";'],specs:`
264
+ /** Wiring specs for \`ctx.workflows\` (codegen-derived from \`lunora/workflows.ts\`). */
265
+ const LUNORA_WORKFLOWS: ReadonlyArray<WorkflowBindingSpec> = [
266
+ ${r}
267
+ ];
268
+ `}},H=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(`
269
+ `);return{build:`
270
+ const queues = createQueueContext(env, LUNORA_QUEUES);
271
+ `,contextField:`
272
+ queues,`,importLines:['import type { QueueBindingSpec } from "@lunora/queue";','import { createQueueContext } from "@lunora/queue";'],specs:`
273
+ /** Wiring specs for \`ctx.queues\` (codegen-derived from \`lunora/queues.ts\`). */
274
+ const LUNORA_QUEUES: ReadonlyArray<QueueBindingSpec> = [
275
+ ${r}
276
+ ];
277
+ `}},V=(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=v(r,n.exportName).map(i=>`{ binding: "${i.bindingName}", exportName: "${i.exportName}" }`).join(", ");return` { exportName: "${n.exportName}", subscriptions: [${o}] },`}).join(`
278
+ `);return{build:`
279
+ const topics = createTopicContext(env, LUNORA_TOPICS);
280
+ `,contextField:`
281
+ topics,`,importLines:['import type { TopicBindingSpec } from "@lunora/queue";','import { createTopicContext } from "@lunora/queue";'],specs:`
282
+ /** Wiring specs for \`ctx.topics\` (codegen-derived from \`lunora/queues.ts\`): each topic's subscription queues. */
283
+ const LUNORA_TOPICS: ReadonlyArray<TopicBindingSpec> = [
284
+ ${t}
285
+ ];
286
+ `}},J=(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(`
287
+ `);return{build:`
288
+ const services = createServices(env, LUNORA_SERVICES);
289
+ `,importLines:[`import type { ServiceBindingSpec } from "${r}";`,`import { createServices } from "${r}";`],specs:`
290
+ /** Wiring specs for \`ctx.services\` (codegen-derived from \`lunora.config\` \`services\`). */
291
+ const LUNORA_SERVICES: ReadonlyArray<ServiceBindingSpec> = [
292
+ ${t}
293
+ ];
294
+ `}},Y=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(`
295
+ `);return{build:`
296
+ const agents = createAgentContext(env, LUNORA_AGENTS, { exports: this.state.exports });
297
+ `,contextField:`
298
+ agents,`,importLines:['import { createAgentContext } from "@lunora/agent";','import type { AgentBindingSpec } from "@lunora/agent";'],specs:`
299
+ /** Wiring specs for \`ctx.agents\` (codegen-derived from \`lunora/agents.ts\`). */
300
+ const LUNORA_AGENTS: ReadonlyArray<AgentBindingSpec> = [
301
+ ${r}
302
+ ];
303
+ `}},$=(e,r,t,n,o)=>({constant:`
304
+ ${o}
305
+ const ${e} = ${x(n,r)};
306
+ `,override:`
307
+ protected override ${t}(): ${r} {
308
+ return ${e};
309
+ }
310
+ `}),X=e=>{if(e.length===0)return{constant:"",override:""};const r={workflows:e.map(t=>({className:t.className,exportName:t.exportName,name:t.name}))};return $("LUNORA_WORKFLOWS_INFO","WorkflowsResult","workflowsMetadata",r,"/** Read-only declared-workflow metadata (discovered from `lunora/workflows.ts`) served via `__lunora_admin__:listWorkflows` for the studio's workflows view. */")},z=e=>{if(e.length===0)return{constant:"",override:""};const r={queues:e.map(t=>({binding:t.bindingName,...t.tuning.deadLetterQueue===void 0?{}:{deadLetterQueue:t.tuning.deadLetterQueue},exportName:t.exportName,mode:t.mode,name:t.name,...t.topic===void 0?{}:{topic:t.topic}}))};return $("LUNORA_QUEUES_INFO","QueuesResult","queuesMetadata",r,"/** Read-only declared-queue metadata (discovered from `lunora/queues.ts`) served via `__lunora_admin__:listQueues` for the studio's queues view. */")},Z=e=>e?{imports:['import type { LunoraDatabaseLike as LunoraPaymentDbLike, LunoraPayment, PaymentsFromContextOptions } from "@lunora/payment";','import { paymentsFromContext } from "@lunora/payment";'],build:`
311
+ const payments: LunoraPayment = config.payment
312
+ ? paymentsFromContext({ auth: { userId: userId ?? null }, db: db as unknown as LunoraPaymentDbLike }, config.payment(env))
313
+ : paymentStub;
314
+ `,configField:`
315
+ payment?: (env: Record<string, unknown>) => PaymentsFromContextOptions;`,contextField:`
316
+ payments,`,stub:y("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:""},ee=e=>e?{imports:['import type { X402Pay, X402PayConfig } from "@lunora/x402/pay";','import { lazyX402Pay } from "@lunora/x402/pay";'],build:`
317
+ const x402: X402Pay = config.x402
318
+ ? lazyX402Pay(config.x402(env), { getSecret: (name: string) => secrets.get(name) })
319
+ : x402Stub;
320
+ `,configField:`
321
+ x402?: (env: Record<string, unknown>) => X402PayConfig;`,stub:y("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:""},te=(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{I as a,B as b,q as c,H as d,D as e,V as f,J as g,j as h,G as i,Y as j,Z as k,ee as l,X as m,z as n,W as o,te as p,P as q,y as r,T as s,M as t,U as u,Q as v,K as w};
@@ -0,0 +1,9 @@
1
+ import{LunoraError as l}from"@lunora/errors";import{acceptsAbsentIr as $}from"./LUNORA_ERROR_CODES-C2s0xWQD.mjs";const b=/^(?:"(?:[^"\\]|\\(?:["\\/bfnrt]|u[0-9A-Fa-f]{4}))*"|'[^'\\]*'|-?\d+(?:\.\d+)?|true|false|null)$/u,_=`// GENERATED by @lunora/codegen — do not edit.
2
+ // Run \`lunora codegen\` to regenerate.
3
+
4
+ `,w=(e=!1)=>e?{client:"lunorash/client",do:"lunorash/do",flags:"lunorash/flags",server:"lunorash/server",serverDataModel:"lunorash/server/data-model",serverDrizzle:"lunorash/server/drizzle",serverTypes:"lunorash/server/types",values:"lunorash/values"}:{client:"@lunora/client",do:"@lunora/do",flags:"@lunora/flags",server:"@lunora/server",serverDataModel:"@lunora/server/data-model",serverDrizzle:"@lunora/server/drizzle",serverTypes:"@lunora/server/types",values:"@lunora/values"},p=/^[A-Za-z_$][\w$]*$/u,A=/^[\w./-]+$/u,y=(e,n)=>{if(!p.test(e))throw new l("INTERNAL",`@lunora/codegen: ${n} is not a valid JS identifier: ${JSON.stringify(e)}`)},I=e=>e.charAt(0).toUpperCase()+e.slice(1),u=e=>p.test(e)?e:JSON.stringify(e),R=e=>e==="__proto__"?`[${JSON.stringify(e)}]`:u(e),g={any:"unknown",bigint:"bigint",boolean:"boolean",bytes:"ArrayBuffer",date:"number",geoPoint:"{ lat: number; lng: number }",null:"null",number:"number",storage:"string",string:"string",timestamp:"number"},T=e=>{if(e===void 0)return"unknown";if(!b.test(e))throw new l("INTERNAL",`@lunora/codegen: v.literal() argument is not a parseable string/number/boolean/null literal: ${JSON.stringify(e)}`);return e},t=e=>e.column?.notNull===!1?`${a(e)} | null`:a(e),a=e=>{const n=g[e.kind];if(n!==void 0)return n;switch(e.kind){case"array":return`Array<${e.inner?t(e.inner):"unknown"}>`;case"from":return e.tsType??"unknown";case"id":{const r=e.tableName??"_unknown_";return y(r,"v.id() table name"),`Id<"${r}">`}case"literal":return T(e.literalValue);case"object":return e.shape?`{ ${Object.entries(e.shape).map(([s,o])=>m(s,o)).join("; ")} }`:"Record<string, unknown>";case"optional":return`${e.inner?t(e.inner):"unknown"} | undefined`;case"record":{const r=e.keyType?t(e.keyType):"string",s=e.valueType?t(e.valueType):"unknown";return`Record<${r}, ${s}>`}case"union":return e.members&&e.members.length>0?e.members.map(r=>t(r)).join(" | "):"never";default:return"unknown"}},m=(e,n)=>{const r=u(e);if(n.kind==="optional"){const s=n.inner?t(n.inner):"unknown";return`${r}?: ${s}`}return $(n)?`${r}?: ${t(n)}`:`${r}: ${t(n)}`},O=e=>{const n=Object.entries(e);return n.length===0?"{}":`{ ${n.map(([r,s])=>m(r,s)).join("; ")} }`},d=e=>e.kind==="optional"||!!e.column?.hasDefault,E=e=>e.kind==="optional"&&e.inner?e.inner:e,N=e=>{y(e.name,"table name");const n=Object.entries(e.shape).map(([s,o])=>{const f=E(o),c=t(f),i=u(s);return d(o)?` ${i}?: ${c};`:` ${i}: ${c};`}).join(`
5
+ `),r=n?`
6
+ ${n}
7
+ `:"";return`export interface Insert_${e.name} {
8
+ _id?: Id<"${e.name}">;
9
+ _creationTime?: number;${r}}`};export{_ as G,A as I,b as L,y as a,u as b,R as c,w as d,N as e,d as i,I as p,O as r,E as u,t as v};
@@ -0,0 +1 @@
1
+ import{Node as l,SyntaxKind as g}from"ts-morph";import{lunoraRelativePath as L}from"./listLunoraSourceFiles-CSlcBYlo.mjs";import{posix as D}from"node:path";let S,v;const Ae=e=>{const t=S,n=[];S=n;try{return{erased:n,value:e()}}finally{S=t}},Te=e=>{S?.push(...e)},j=e=>{for(const t of e.getAncestors())if(l.isVariableDeclaration(t))return t.getName()},w=(e,t)=>{S?.push({exportName:j(e),filePath:e.getSourceFile().getFilePath(),line:e.getStartLineNumber(),rendered:t})},Ne=e=>{v!==void 0&&w(v,e)},xe=(e,t)=>{const n=v;v=e;try{return t()}finally{v=n}},k=(e,t)=>{const n=e.exportName??`line ${e.line.toString()}`;return{cacheKey:`procedure_return_type_erased:${t}:${n}`,categories:["SCHEMA"],description:"Codegen renders a procedure's return type into `_generated/`, where only names that resolve from that directory may appear. A type it can neither name nor reproduce structurally — a class instance, a call or index signature, a recursive or very deeply nested shape — is emitted as `unknown` instead, so callers lose the shape while the runtime still returns it.",detail:`\`${n}\` in \`${t}\` (line ${e.line.toString()}) returns \`${e.rendered}\`, which codegen could not reproduce — its generated type is \`unknown\`.`,facing:"INTERNAL",level:"WARN",metadata:{exportName:e.exportName,filePath:t,line:e.line,rendered:e.rendered},name:"procedure_return_type_erased",remediation:"Declare the shape explicitly with `.output(...)`, or export the type from the module that declares it so codegen can name it. A class instance cannot cross the wire at all — return a plain object.",title:"Procedure return type is missing from the generated type"}},De=(e,t)=>{const n=new Map;for(const r of e){const s=k(r,L(t,r.filePath));n.set(s.cacheKey,s)}return[...n.values()].toSorted((r,s)=>r.cacheKey.localeCompare(s.cacheKey))},P=/\bany\b(?!\s*(?:\?\s*)?:)/u,U=/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|`(?:[^`\\]|\\.)*`/gu,O=e=>P.test(e.replaceAll(U,"")),K="/_generated/",B=e=>{const t=[e.getSymbol(),e.getAliasSymbol()].flatMap(n=>n?.getDeclarations()??[]);return t.length>0&&t.every(n=>n.getSourceFile().getSymbol()===void 0)},F=/^(?<quote>["'])(?<specifier>.*)\k<quote>$/su,T=e=>{for(const t of e.getAncestors())if(l.isModuleDeclaration(t)){const n=F.exec(t.getName());if(n?.groups?.specifier!==void 0)return n.groups.specifier}},h=new WeakMap,V=(e,t)=>{const n=e.getSymbol();if(n===void 0)return;let r=h.get(n.compilerSymbol);return r===void 0&&(r=new Map,h.set(n.compilerSymbol,r)),r.has(t)||r.set(t,n.getExport(t)??e.getExportSymbols().find(s=>s.getName()===t)),r.get(t)},_=(e,t)=>e.getNamespaceImport()!==void 0||e.getNamedImports().some(n=>n.getName()===t),W=(e,t,n)=>e.getModuleSpecifierValue()===t&&_(e,n)?n:void 0,q=(e,t)=>{const n=e.getDefaultImport();if(n===void 0)return;const r=n.getSymbol();return(r?.getAliasedSymbol()??r)?.getDeclarations().includes(t)===!0?"default":void 0},G=(e,t,n)=>{if(!_(e,n))return;const r=e.getModuleSpecifierSourceFile(),s=r===void 0?void 0:V(r,n);return(s?.getAliasedSymbol()??s)?.getDeclarations().includes(t)===!0?n:void 0},X=/^\.\.?(?:$|\/)/u,H=new Map([[".cjs",".cjs"],[".cts",".cjs"],[".d.ts",".js"],[".js",".js"],[".jsx",".jsx"],[".mjs",".mjs"],[".mts",".mjs"],[".ts",".js"],[".tsx",".js"]]),Y=(e,t)=>{const n=t.getModuleSpecifierValue();if(!X.test(n))return;const r=t.getModuleSpecifierSourceFile(),s=r===void 0?void 0:H.get(r.getExtension());if(r===void 0||s===void 0)return;const i=`${D.join(r.getDirectoryPath(),r.getBaseNameWithoutExtension())}${s}`,o=D.relative(e.getDirectoryPath(),i);return o.startsWith(".")?o:`./${o}`},J=(e,t,n)=>{const r=T(t);for(const s of e.getImportDeclarations()){const i=r===void 0?q(s,t)??G(s,t,n):W(s,r,n);if(i!==void 0)return{exportName:i,specifier:Y(e,s)??s.getModuleSpecifierValue()}}},z=(e,t)=>Object.keys(t.getProject().getCompilerOptions().paths??{}).some(n=>{const r=n.indexOf("*");return r===-1?e===n:e.startsWith(n.slice(0,r))&&e.endsWith(n.slice(r+1))}),m={kind:"verbatim"},p={kind:"expand"},Q=new Set([g.ClassDeclaration,g.EnumDeclaration,g.EnumMember,g.InterfaceDeclaration,g.TypeAliasDeclaration]),Z=e=>T(e)!==void 0||l.isExportable(e)&&e.isExported(),ee=(e,t)=>new RegExp(String.raw`(?<![$\w])${t.replaceAll(/[$()*+.?[\\\]^{|}]/gu,String.raw`\$&`)}(?![$\w])`,"u").test(e),M=(e,t,n,r)=>{const s=e.getSourceFile();if(s.getSymbol()===void 0&&T(e)===void 0||!Q.has(e.getKind()))return m;const i=s.getFilePath();if(i.includes(K))return m;if(i===n)return p;const o=l.isEnumMember(e)?e.getParent():e;if(!l.hasName(o))return p;const a=J(t.getSourceFile(),o,o.getName());return a===void 0?Z(o)||!ee(r(),o.getName())?m:p:z(a.specifier,t)?p:{kind:"qualify",qualified:a}},te=new Set([g.ClassDeclaration,g.EnumDeclaration,g.FunctionDeclaration,g.ModuleDeclaration]),I=e=>{const t=e?.getDeclarations()??[];return t.length>0&&t.every(n=>n.getSourceFile().getSymbol()===void 0)},ne=e=>{for(const t of e.getDeclarations()){const n=t.getFirstChildByKind(g.ComputedPropertyName);if(n!==void 0){let r=n.getExpression();for(;l.isPropertyAccessExpression(r);)r=r.getExpression();return r}}},re=(e,t)=>{if(e.getProperties().some(s=>{if(!s.getName().startsWith("__@"))return!1;const i=ne(s);return i===void 0||!I(i.getSymbol())}))return!0;const r=e.getSymbol();return r!==void 0&&r.getDeclarations().some(s=>te.has(s.getKind()))&&!I(r)&&t().startsWith("typeof ")},R=(e,t,n)=>{const r=e.getAliasSymbol(),s=e.getSymbol(),i=new Set((r??s)?.getDeclarations());let o=!1,a;const c=()=>(a??=e.getText(t),a);for(const u of[s,r].flatMap(d=>d?.getDeclarations()??[])){const d=M(u,t,n,c);if(d.kind==="qualify"&&i.has(u))return d;o||=d.kind!=="verbatim"}return o||re(e,c)?p:m},se=(e,t,n)=>{const r=l.isPropertySignature(e)||l.isPropertyDeclaration(e)?e.getTypeNode():void 0;if(r===void 0)return m;let s=!1;for(const i of[r,...r.getDescendantsOfKind(g.TypeReference)].filter(o=>l.isTypeReference(o))){const o=i.getTypeName().getSymbol();for(const a of(o?.getAliasedSymbol()??o)?.getDeclarations()??[]){const c=M(a,t,n,()=>i.getText());if(c.kind==="qualify")return c;s||=c.kind!=="verbatim"}}return s?p:m},oe=/^[A-Za-z_$][\w$]*$/u,ie=e=>oe.test(e)?e:JSON.stringify(e),$=e=>{const t=[...e.getTypeArguments()];return e.isUnion()&&t.push(...e.getUnionTypes()),e.isIntersection()&&t.push(...e.getIntersectionTypes()),t},y=e=>!e.isObject()||e.isArray()||e.isTuple()||e.getCallSignatures().length>0||e.getConstructSignatures().length>0?!1:e.getStringIndexType()===void 0&&e.getNumberIndexType()===void 0&&!e.getProperties().some(t=>t.getName().startsWith("__@")),E=(e,t,n,r=new Set)=>r.has(e)?!1:(r.add(e),R(e,t,n).kind!=="verbatim"||$(e).some(s=>E(s,t,n,r))?!0:y(e)?e.getProperties().some(s=>s.getDeclarations().some(i=>se(i,t,n).kind!=="verbatim")?!0:E(s.getTypeAtLocation(t),t,n,r)):!1),ae=(e,t)=>{const n=e.getValueDeclaration()??e.getDeclarations()[0];return n&&(l.isPropertySignature(n)||l.isPropertyDeclaration(n))&&n.hasQuestionToken()?!0:t.isUnion()&&t.getUnionTypes().some(r=>r.isUndefined())},C=(e,t)=>e!==void 0&&(y(e)||e.isString()||e.isNumber()||e.isBigInt()||e.isBoolean()||e.isLiteral()||e.isBooleanLiteral()||e.isEnumLiteral()||e.isTemplateLiteral()||e.isNull()||e.isUndefined()||e.isAny()||e.isUnknown()||e.isNever()||e.isVoid())?t:`(${t})`,ce=32,ue=8,le=(e,t,n,r,s,i)=>{const o=e.getArrayElementType(),a=o?i(o,t,n,r,s):void 0;if(a!==void 0)return`${C(o,a)}[]`},ge=(e,t,n,r,s,i)=>{const o=[];for(const a of e.getUnionTypes()){const c=i(a,t,n,r,s);if(c===void 0)return;o.push(c)}return o.join(" | ")},de=(e,t,n,r,s,i)=>{const o=[];for(const a of e.getIntersectionTypes()){const c=i(a,t,n,r,s);if(c===void 0)return;o.push(C(a,c))}return o.join(" & ")},me=(e,t,n,r,s,i)=>{if(!y(e))return;const o=[];for(const a of e.getProperties()){const c=a.getTypeAtLocation(t),u=ae(a,c),d=u&&c.isUnion()?c.getUnionTypes().filter(A=>!A.isUndefined()):[c],N=[];for(const A of d){const x=i(A,t,n,r+1,s);if(x===void 0)return;N.push(x)}o.push(`${ie(a.getName())}${u?"?":""}: ${N.join(" | ")}`)}return o.length>0?`{ ${o.join("; ")} }`:"{}"},fe=e=>{const t=e.getLiteralValue();return typeof t=="string"?JSON.stringify(t):typeof t=="number"?String(t):void 0},pe=e=>[e.getSymbol(),e.getAliasSymbol()].flatMap(t=>t?.getDeclarations()??[]).some(t=>l.isClassDeclaration(t)||l.isClassExpression(t)),b=(e,t,n,r,s=new Set)=>{if(r.has(e)||s.has(e))return!1;if(n>ce)return!0;const i=new Set(r).add(e);if($(e).some(u=>b(u,t,n+1,i,s)))return!0;const o=e.getArrayElementType();if(o!==void 0)return b(o,t,n+1,i,s);if(B(e))return s.add(e),!1;if(e.getCallSignatures().length>0||e.getConstructSignatures().length>0||[e.getSymbol(),e.getAliasSymbol()].flatMap(u=>u?.getDeclarations()??[]).some(u=>l.isClassDeclaration(u)||l.isClassExpression(u)))return!0;const c=y(e)&&e.getProperties().some(u=>b(u.getTypeAtLocation(t),t,n+1,i,s));return c||s.add(e),c},Se=(e,t,n,r,s,i,o)=>{const a=[];for(const c of t.getAliasSymbol()===void 0?t.getTypeArguments():t.getAliasTypeArguments()){const u=o(c,n,r,s+1,i);if(u===void 0)return;a.push(u)}return`import("${e.specifier}").${e.exportName}${a.length>0?`<${a.join(", ")}>`:""}`},ve=e=>[e.getSymbol(),e.getAliasSymbol()].flatMap(t=>t?.getDeclarations()??[]).some(t=>l.isEnumDeclaration(t)||l.isEnumMember(t)),f=(e,t,n,r,s)=>{if(r>ue||s.has(e))return;const i=R(e,t,n);if(i.kind==="verbatim"&&!E(e,t,n))return e.getText(t);const o=new Set(s).add(e);if(!pe(e)){if(e.isEnumLiteral())return fe(e);if(i.kind==="qualify"&&!ve(e)){const a=Se(i.qualified,e,t,n,r,o,f);if(a!==void 0)return a}return e.isArray()?le(e,t,n,r,o,f):e.isUnion()?ge(e,t,n,r,o,f):e.isIntersection()?de(e,t,n,r,o,f):me(e,t,n,r,o,f)}},he=e=>{const t=e.getType().getCallSignatures()[0];if(!t)return"unknown";let n=t.getReturnType();const s=(n.getSymbol()??n.getAliasSymbol())?.getName();if(s==="Promise"||s==="AsyncIterable"||s==="AsyncIterableIterator"||s==="AsyncGenerator"){const a=n.getTypeArguments()[0];a&&(n=a)}const i=n.getText(e);if(!i||i==="any"||i==="never"||O(i)||b(n,e,0,new Set))return"unknown";const o=e.getSourceFile().getFilePath();if(E(n,e,o)){const a=f(n,e,o,0,new Set);return a===void 0&&w(e,i),a??"unknown"}return i};export{E as a,Ne as b,Ae as c,De as d,f as e,O as i,xe as p,Te as r,he as u};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/codegen",
3
- "version": "1.0.0-alpha.25",
3
+ "version": "1.0.0-alpha.250",
4
4
  "description": "Code generator for Lunora: emits _generated/{api,server,dataModel}.ts from your schema",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -46,14 +46,23 @@
46
46
  "access": "public"
47
47
  },
48
48
  "dependencies": {
49
- "@lunora/advisor": "1.0.0-alpha.14",
50
- "@lunora/container": "1.0.0-alpha.5",
51
- "@lunora/queue": "1.0.0-alpha.2",
52
- "@lunora/scheduler": "1.0.0-alpha.4",
53
- "@lunora/values": "1.0.0-alpha.3",
54
- "@lunora/workflow": "1.0.0-alpha.5",
49
+ "@lunora/advisor": "1.0.0-alpha.181",
50
+ "@lunora/agent": "1.0.0-alpha.163",
51
+ "@lunora/container": "1.0.0-alpha.66",
52
+ "@lunora/errors": "1.0.0-alpha.49",
53
+ "@lunora/platform": "1.0.0-alpha.50",
54
+ "@lunora/queue": "1.0.0-alpha.86",
55
+ "@lunora/scheduler": "1.0.0-alpha.104",
56
+ "@lunora/values": "1.0.0-alpha.59",
57
+ "@lunora/workflow": "1.0.0-alpha.70",
58
+ "jiti": "^2.7.0",
59
+ "quicktype-core": "^26.0.0",
55
60
  "ts-morph": "^28.0.0"
56
61
  },
62
+ "peerDependencies": {
63
+ "@lunora/server": ">=1.0.0-alpha.91 <2.0.0-0",
64
+ "@lunora/shard-engine": ">=1.0.0-alpha.45 <2.0.0-0"
65
+ },
57
66
  "engines": {
58
67
  "node": "^22.15.0 || >=24.11.0"
59
68
  }
@@ -1,224 +0,0 @@
1
- import { existsSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import { containerClassName, containerBindingName, normalizeContainerImage } from '@lunora/container';
4
- import { SyntaxKind, Node } from 'ts-morph';
5
- import { diagnosticAt } from './CodegenDiagnosticError-DeblMkzO.mjs';
6
-
7
- const CONTAINERS_FILENAME = "containers.ts";
8
- const isDefineContainer = (identifier) => {
9
- const symbol = identifier.getSymbol();
10
- if (!symbol) {
11
- return identifier.getText() === "defineContainer";
12
- }
13
- for (const declaration of symbol.getDeclarations()) {
14
- if (!Node.isImportSpecifier(declaration)) {
15
- continue;
16
- }
17
- if (declaration.getImportDeclaration().getModuleSpecifierValue() !== "@lunora/container") {
18
- return false;
19
- }
20
- return declaration.getNameNode().getText() === "defineContainer";
21
- }
22
- return false;
23
- };
24
- const stringProperty = (expression, exportName, property) => {
25
- if (Node.isStringLiteral(expression) || Node.isNoSubstitutionTemplateLiteral(expression)) {
26
- return expression.getLiteralValue();
27
- }
28
- throw diagnosticAt(
29
- expression,
30
- `container "${exportName}": \`${property}\` must be a static string literal — it is deploy configuration codegen writes into wrangler.jsonc`
31
- );
32
- };
33
- const numberProperty = (expression, exportName, property) => {
34
- if (Node.isNumericLiteral(expression)) {
35
- return expression.getLiteralValue();
36
- }
37
- throw diagnosticAt(
38
- expression,
39
- `container "${exportName}": \`${property}\` must be a static number literal — it is deploy configuration codegen writes into wrangler.jsonc`
40
- );
41
- };
42
- const imageFromExpression = (expression, exportName) => {
43
- if (Node.isStringLiteral(expression) || Node.isNoSubstitutionTemplateLiteral(expression)) {
44
- return normalizeContainerImage(expression.getLiteralValue());
45
- }
46
- if (Node.isObjectLiteralExpression(expression)) {
47
- const registry = expression.getProperty("registry");
48
- if (registry && Node.isPropertyAssignment(registry)) {
49
- const initializer = registry.getInitializerOrThrow();
50
- return normalizeContainerImage({ registry: stringProperty(initializer, exportName, "image.registry") });
51
- }
52
- const build = expression.getProperty("build");
53
- if (build && Node.isPropertyAssignment(build)) {
54
- const initializer = build.getInitializerOrThrow();
55
- return normalizeContainerImage({ build: stringProperty(initializer, exportName, "image.build") });
56
- }
57
- }
58
- throw diagnosticAt(expression, `container "${exportName}": \`image\` must be a static string path, { registry: "…" }, or { build: "…" } literal`);
59
- };
60
- const stringRecordLiteral = (expression) => {
61
- if (!Node.isObjectLiteralExpression(expression)) {
62
- return void 0;
63
- }
64
- const record = {};
65
- for (const property of expression.getProperties()) {
66
- if (!Node.isPropertyAssignment(property)) {
67
- continue;
68
- }
69
- const value = property.getInitializerOrThrow();
70
- if (Node.isStringLiteral(value) || Node.isNoSubstitutionTemplateLiteral(value)) {
71
- record[property.getName()] = value.getLiteralValue();
72
- }
73
- }
74
- return Object.keys(record).length > 0 ? record : void 0;
75
- };
76
- const rolloutLiteral = (expression) => {
77
- if (!Node.isObjectLiteralExpression(expression)) {
78
- return void 0;
79
- }
80
- const rollout = {};
81
- for (const property of expression.getProperties()) {
82
- if (!Node.isPropertyAssignment(property)) {
83
- continue;
84
- }
85
- const key = property.getName();
86
- const value = property.getInitializerOrThrow();
87
- if (Node.isNumericLiteral(value) && (key === "gracePeriodSeconds" || key === "stepPercentage")) {
88
- rollout[key] = value.getLiteralValue();
89
- }
90
- }
91
- return rollout.gracePeriodSeconds === void 0 && rollout.stepPercentage === void 0 ? void 0 : rollout;
92
- };
93
- const booleanLiteral = (expression) => {
94
- if (Node.isTrueLiteral(expression)) {
95
- return true;
96
- }
97
- if (Node.isFalseLiteral(expression)) {
98
- return false;
99
- }
100
- return void 0;
101
- };
102
- const stringOrNumberLiteral = (expression) => {
103
- if (Node.isStringLiteral(expression) || Node.isNoSubstitutionTemplateLiteral(expression)) {
104
- return expression.getLiteralValue();
105
- }
106
- if (Node.isNumericLiteral(expression)) {
107
- return expression.getLiteralValue();
108
- }
109
- return void 0;
110
- };
111
- const instanceTypeFromExpression = (expression, exportName) => {
112
- if (Node.isStringLiteral(expression)) {
113
- return expression.getLiteralValue();
114
- }
115
- if (Node.isObjectLiteralExpression(expression)) {
116
- const custom = {};
117
- for (const property of expression.getProperties()) {
118
- if (!Node.isPropertyAssignment(property)) {
119
- throw diagnosticAt(property, `container "${exportName}": \`instanceType\` must be an object of static number literals`);
120
- }
121
- const key = property.getName();
122
- if (key !== "diskMb" && key !== "memoryMib" && key !== "vcpu") {
123
- throw diagnosticAt(property, `container "${exportName}": unknown \`instanceType\` field "${key}" — expected vcpu, memoryMib, or diskMb`);
124
- }
125
- custom[key] = numberProperty(property.getInitializerOrThrow(), exportName, `instanceType.${key}`);
126
- }
127
- return custom;
128
- }
129
- throw diagnosticAt(expression, `container "${exportName}": \`instanceType\` must be a static string or { vcpu, memoryMib, diskMb } literal`);
130
- };
131
- const containerFromCall = (call, exportName) => {
132
- const argument = call.getArguments()[0];
133
- if (!argument || !Node.isObjectLiteralExpression(argument)) {
134
- throw diagnosticAt(call, `container "${exportName}": defineContainer must be passed an inline object literal`);
135
- }
136
- const ir = {
137
- bindingName: containerBindingName(exportName),
138
- className: containerClassName(exportName),
139
- exportName,
140
- image: { buildContext: ".", dockerfilePath: "./Dockerfile", kind: "dockerfile" }
141
- };
142
- let sawImage = false;
143
- for (const property of argument.getProperties()) {
144
- if (!Node.isPropertyAssignment(property)) {
145
- continue;
146
- }
147
- const key = property.getName();
148
- const initializer = property.getInitializerOrThrow();
149
- switch (key) {
150
- case "buildArgs": {
151
- ir.buildArgs = stringRecordLiteral(initializer);
152
- break;
153
- }
154
- case "enableInternet": {
155
- ir.enableInternet = booleanLiteral(initializer);
156
- break;
157
- }
158
- case "image": {
159
- ir.image = imageFromExpression(initializer, exportName);
160
- sawImage = true;
161
- break;
162
- }
163
- case "instanceType": {
164
- ir.instanceType = instanceTypeFromExpression(initializer, exportName);
165
- break;
166
- }
167
- case "maxInstances": {
168
- ir.maxInstances = numberProperty(initializer, exportName, "maxInstances");
169
- break;
170
- }
171
- case "name": {
172
- ir.name = stringProperty(initializer, exportName, "name");
173
- break;
174
- }
175
- case "rollout": {
176
- ir.rollout = rolloutLiteral(initializer);
177
- break;
178
- }
179
- case "sleepAfter": {
180
- ir.sleepAfter = stringOrNumberLiteral(initializer);
181
- break;
182
- }
183
- }
184
- }
185
- if (!sawImage) {
186
- throw diagnosticAt(argument, `container "${exportName}": defineContainer requires a static \`image\` property`);
187
- }
188
- return ir;
189
- };
190
- const containersFromSource = (source) => {
191
- const containers = [];
192
- for (const declaration of source.getVariableDeclarations()) {
193
- if (!declaration.isExported()) {
194
- continue;
195
- }
196
- const initializer = declaration.getInitializer();
197
- if (initializer?.getKind() !== SyntaxKind.CallExpression) {
198
- continue;
199
- }
200
- const call = initializer;
201
- const callee = call.getExpression();
202
- if (!Node.isIdentifier(callee) || !isDefineContainer(callee)) {
203
- continue;
204
- }
205
- const nameNode = declaration.getNameNode();
206
- if (!Node.isIdentifier(nameNode)) {
207
- throw diagnosticAt(nameNode, "defineContainer exports must be plain named exports (no destructuring)");
208
- }
209
- containers.push(containerFromCall(call, nameNode.getText()));
210
- }
211
- return containers;
212
- };
213
- const discoverContainers = (project, lunoraDirectory) => {
214
- const containersPath = join(lunoraDirectory, CONTAINERS_FILENAME);
215
- if (!existsSync(containersPath)) {
216
- return [];
217
- }
218
- const source = project.getSourceFile(containersPath) ?? project.addSourceFileAtPath(containersPath);
219
- const containers = containersFromSource(source);
220
- containers.sort((a, b) => a.exportName.localeCompare(b.exportName));
221
- return containers;
222
- };
223
-
224
- export { CONTAINERS_FILENAME, discoverContainers };