@lunora/codegen 1.0.0-alpha.24 → 1.0.0-alpha.240
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +6 -0
- package/README.md +1 -1
- package/dist/index.d.mts +3388 -1179
- package/dist/index.d.ts +3388 -1179
- package/dist/index.mjs +1 -34
- package/dist/packem_shared/AGENTS_FILENAME-DoPI92Wu.mjs +1 -0
- package/dist/packem_shared/CONTAINERS_FILENAME-B6TFs82W.mjs +1 -0
- package/dist/packem_shared/CodegenDiagnosticError-BUXlG3P-.mjs +1 -0
- package/dist/packem_shared/DEFAULT_TARGET-DCpDuuUM.mjs +1 -0
- package/dist/packem_shared/FLAGS_FILENAME-BedPDCsR.mjs +1 -0
- package/dist/packem_shared/GENERATED_HEADER-DSXl0YM2.mjs +1 -0
- package/dist/packem_shared/LUNORA_ERROR_CODES-C2s0xWQD.mjs +1 -0
- package/dist/packem_shared/MUTATORS_FILENAME-B6cKrN_m.mjs +1 -0
- package/dist/packem_shared/NOTIFY_FILENAME-Cri3NT5U.mjs +1 -0
- package/dist/packem_shared/OPENRPC_VERSION-Cl6P9WGv.mjs +3 -0
- package/dist/packem_shared/PROJECT_CONFIG_FILENAMES-DzOu-lSc.mjs +1 -0
- package/dist/packem_shared/QUEUES_FILENAME-CxkPcMH1.mjs +1 -0
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-IOiezeVr.mjs +9 -0
- package/dist/packem_shared/SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs +2 -0
- package/dist/packem_shared/SDK_LANGUAGES-Df_CnJx5.mjs +372 -0
- package/dist/packem_shared/SHAPES_FILENAME-zJgzynXR.mjs +1 -0
- package/dist/packem_shared/SchemaSnapshotParseError-CPOXlFhI.mjs +18 -0
- package/dist/packem_shared/WORKFLOWS_FILENAME-B_ZJxRSx.mjs +1 -0
- package/dist/packem_shared/buildOpenApiDocument-nYvBhjxu.mjs +3 -0
- package/dist/packem_shared/capabilities-DJJWVEtk.mjs +18 -0
- package/dist/packem_shared/chain-H2N_uKgj.mjs +1 -0
- package/dist/packem_shared/classify-procedure-call-BztLe76A.mjs +1 -0
- package/dist/packem_shared/context-property-calls-CjDzLU8p.mjs +1 -0
- package/dist/packem_shared/declared-output-Iaar469J.mjs +1 -0
- package/dist/packem_shared/describeErrorLevelFindings-vzaGS9KL.mjs +1 -0
- package/dist/packem_shared/discoverAuthApiCalls-FxrdBeVt.mjs +1 -0
- package/dist/packem_shared/discoverCrons-MfKw7IFf.mjs +1 -0
- package/dist/packem_shared/discoverFunctions-BsmX-sEq.mjs +1 -0
- package/dist/packem_shared/discoverHttpRoutes-BcXI9CNt.mjs +1 -0
- package/dist/packem_shared/discoverHyperdriveCalls-D9qXqTq3.mjs +1 -0
- package/dist/packem_shared/discoverInserts-CFJ3IVeI.mjs +1 -0
- package/dist/packem_shared/discoverMaskProcedures-CV_Cc2_g.mjs +1 -0
- package/dist/packem_shared/discoverMigrations-DbrHwcGE.mjs +1 -0
- package/dist/packem_shared/discoverNondeterministicCalls-CSQ_GDcA.mjs +1 -0
- package/dist/packem_shared/discoverQueries-C7y8i_Ga.mjs +1 -0
- package/dist/packem_shared/discoverR2sqlCalls-fu7fC0i_.mjs +1 -0
- package/dist/packem_shared/discoverRlsMetadata-CPmAGL0W.mjs +1 -0
- package/dist/packem_shared/discoverRlsProcedures-BO4qC77y.mjs +1 -0
- package/dist/packem_shared/discoverSandboxUsage-CrjZ6yNg.mjs +1 -0
- package/dist/packem_shared/discoverSchema-D8DBDHEg.mjs +1 -0
- package/dist/packem_shared/discoverStorageRulesMetadata-D8VYflWt.mjs +1 -0
- package/dist/packem_shared/emitAgents-Cy7QGO1t.mjs +1 -0
- package/dist/packem_shared/emitApi-CJ9ziZnP.mjs +154 -0
- package/dist/packem_shared/emitApp-BGhO5bhT.mjs +852 -0
- package/dist/packem_shared/emitCrons-mkwWkn0R.mjs +69 -0
- package/dist/packem_shared/emitDataModel-D3WuEZ4b.mjs +113 -0
- package/dist/packem_shared/emitDrizzleSchema-Cv0HtLR3.mjs +15 -0
- package/dist/packem_shared/emitFunctions-BqAz1ssY.mjs +249 -0
- package/dist/packem_shared/emitServer-BEo_fCY8.mjs +365 -0
- package/dist/packem_shared/emitShard-CsWK2K91.mjs +1 -0
- package/dist/packem_shared/exported-procedure-chains-CmCDiPBV.mjs +1 -0
- package/dist/packem_shared/fingerprintSchemaSources-L3nGKDQt.mjs +1 -0
- package/dist/packem_shared/formatAdvisories-DwmUKYuc.mjs +2 -0
- package/dist/packem_shared/index-BoaHhVtM.mjs +1 -0
- package/dist/packem_shared/isD1GlobalTable-udvHAAzD.mjs +1 -0
- package/dist/packem_shared/isTypedSchema-CKzc3ioR.mjs +4 -0
- package/dist/packem_shared/json-data-Chfs2Cz5.mjs +1 -0
- package/dist/packem_shared/listLunoraSourceFiles-DP-5e-RE.mjs +1 -0
- package/dist/packem_shared/loadProjectConfig-CKsFNgn3.mjs +1 -0
- package/dist/packem_shared/module-specifiers-WF8iAydP.mjs +1 -0
- package/dist/packem_shared/parse-validator-C94Yiabo.mjs +1 -0
- package/dist/packem_shared/paths-C-9fwEgQ.mjs +1 -0
- package/dist/packem_shared/qualifiers-BhOL15WZ.mjs +1 -0
- package/dist/packem_shared/queries-B-f4jO-x.mjs +1 -0
- package/dist/packem_shared/readPackageDependencies-C6h6FZuP.mjs +1 -0
- package/dist/packem_shared/redact-Cy14LEnc.mjs +1 -0
- package/dist/packem_shared/schemaFromIr-BWFnvCVg.mjs +1 -0
- package/dist/packem_shared/shard-BBv6VBmX.mjs +1435 -0
- package/dist/packem_shared/shard-runtime-CM5qthZc.mjs +309 -0
- package/dist/packem_shared/shared-DjUziztz.mjs +9 -0
- package/dist/packem_shared/unwrap-handler-return-CoV_GK33.mjs +1 -0
- package/package.json +16 -7
- package/dist/packem_shared/CONTAINERS_FILENAME-DlP6YM_Q.mjs +0 -224
- package/dist/packem_shared/CodegenDiagnosticError-DeblMkzO.mjs +0 -23
- package/dist/packem_shared/FLAGS_FILENAME-B1vE0LIo.mjs +0 -139
- package/dist/packem_shared/GENERATED_HEADER-DUkXYD5R.mjs +0 -3260
- package/dist/packem_shared/LUNORA_ERROR_CODES-CySpQPD3.mjs +0 -61
- package/dist/packem_shared/LUNORA_SOLUTION_RULES-BTejmZp-.mjs +0 -131
- package/dist/packem_shared/MUTATORS_FILENAME-BhqdPtKp.mjs +0 -81
- package/dist/packem_shared/OPENRPC_VERSION-CjBUaolx.mjs +0 -60
- package/dist/packem_shared/QUEUES_FILENAME-B5_eWCRe.mjs +0 -119
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-BUcGCXi3.mjs +0 -1130
- package/dist/packem_shared/SCHEMA_SNAPSHOT_VERSION-wWGP2_5E.mjs +0 -245
- package/dist/packem_shared/SHAPES_FILENAME-ChV7MqgE.mjs +0 -94
- package/dist/packem_shared/WORKFLOWS_FILENAME-CCisG0Vy.mjs +0 -124
- package/dist/packem_shared/buildOpenApiDocument-WxYTLh11.mjs +0 -183
- package/dist/packem_shared/discover-ast-CT6BgBr4.mjs +0 -13
- package/dist/packem_shared/discoverAuthApiCalls-CoirYbg6.mjs +0 -62
- package/dist/packem_shared/discoverCrons-Cev7RRAf.mjs +0 -257
- package/dist/packem_shared/discoverFunctions-BWMczzBx.mjs +0 -465
- package/dist/packem_shared/discoverHttpRoutes-CfP6cMzt.mjs +0 -131
- package/dist/packem_shared/discoverInserts-C7zxXkUf.mjs +0 -61
- package/dist/packem_shared/discoverMaskProcedures-Cm81kwrb.mjs +0 -217
- package/dist/packem_shared/discoverMigrations-Bi5nJ0mJ.mjs +0 -97
- package/dist/packem_shared/discoverNondeterministicCalls-C4M8AXmQ.mjs +0 -122
- package/dist/packem_shared/discoverQueries-B0wGT-xe.mjs +0 -62
- package/dist/packem_shared/discoverR2sqlCalls-BVNMd428.mjs +0 -80
- package/dist/packem_shared/discoverRlsMetadata-BS9GOGC5.mjs +0 -280
- package/dist/packem_shared/discoverSchema-KYq55qu3.mjs +0 -864
- package/dist/packem_shared/discoverStorageRulesMetadata-Da8BKXcI.mjs +0 -97
- package/dist/packem_shared/emitApp-DD0i1ks0.mjs +0 -666
- package/dist/packem_shared/formatAdvisories-DdjK7sgh.mjs +0 -81
- package/dist/packem_shared/parse-validator-Cabb60UV.mjs +0 -133
- package/dist/packem_shared/paths-BRd6JHuF.mjs +0 -11
- package/dist/packem_shared/schemaFromIr-DTYsLBaA.mjs +0 -57
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import{r as p}from"./json-data-Chfs2Cz5.mjs";import{a,G as d}from"./shared-DjUziztz.mjs";const x=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:""},k=e=>e?{build:`
|
|
10
|
+
const aiBinding = config.ai?.(env) ?? (env as Record<string, unknown>).AI;
|
|
11
|
+
// Correlate AI-Gateway-routed calls with the Lunora trace: thread the
|
|
12
|
+
// function path + trace id into createAi, which folds them into the
|
|
13
|
+
// gateway's \`metadata\`. Mirror the tracer's anchor guard — a deferred
|
|
14
|
+
// subscription re-run must not borrow a concurrent dispatch's trace, so
|
|
15
|
+
// read \`getCurrentTrace()\` only on the synchronous (non-threaded-identity) path.
|
|
16
|
+
const aiTrace = options.identity ? undefined : this.getCurrentTrace();
|
|
17
|
+
// \`telemetry\` gives every model call an \`ai.generate\` / \`ai.stream\` span
|
|
18
|
+
// and \`gen_ai.usage.*\` token + cost counters attributed to this function.
|
|
19
|
+
const ai: LunoraAi = createAi({
|
|
20
|
+
binding: aiBinding as AiBindingLike | undefined,
|
|
21
|
+
env: env as Record<string, unknown>,
|
|
22
|
+
metadata: { functionPath: options.functionPath, traceId: aiTrace?.traceId },
|
|
23
|
+
telemetry: { metrics, trace },
|
|
24
|
+
});
|
|
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 "}() => {
|
|
27
|
+
${t}
|
|
28
|
+
},`).join(`
|
|
29
|
+
`);return`
|
|
30
|
+
const ${e} = {
|
|
31
|
+
${s}
|
|
32
|
+
}${r};
|
|
33
|
+
`},c={build:"",configField:"",contextField:"",importLines:[],stub:""},w=e=>e?{build:`
|
|
34
|
+
const kvBinding = config.kv?.(env) ?? (env as Record<string, unknown>).KV;
|
|
35
|
+
// KV is not this shard's SQLite, so nothing appends a \`__cdc_log\` entry
|
|
36
|
+
// when a value changes — a subscription that read one can never be proven
|
|
37
|
+
// current on reconnect and must re-snapshot. Reads only; \`put\`/\`delete\`
|
|
38
|
+
// are writes and stay unstamped.
|
|
39
|
+
const kv: Kv = markUnvouchableReads(kvBinding ? createKv({ namespace: kvBinding as KVNamespaceLike }) : kvStub, options.onRead, [
|
|
40
|
+
"get",
|
|
41
|
+
"getRaw",
|
|
42
|
+
"getWithMetadata",
|
|
43
|
+
"list",
|
|
44
|
+
]);
|
|
45
|
+
`,configField:`
|
|
46
|
+
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:`
|
|
48
|
+
const flags: import("${t}").LunoraFlags = createFlags(flagsConfig, env, {
|
|
49
|
+
provider: () => config.flags?.(env),
|
|
50
|
+
targetingKey: () => flagsConfig.identify?.({ identity: identity ?? null, userId: userId ?? null }),
|
|
51
|
+
});
|
|
52
|
+
`,configField:`
|
|
53
|
+
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:`
|
|
55
|
+
const { notify, push } = createNotify(notifyConfig, env, { log, metrics });
|
|
56
|
+
`,configField:"",contextField:`
|
|
57
|
+
notify,
|
|
58
|
+
push,`,importLines:['import { createNotify } from "@lunora/notify";','import notifyConfig from "../notify.js";'],stub:""}:c,S=e=>e?{build:`
|
|
59
|
+
const envConfig = lunoraEnvContract.${e.exportName}(env);
|
|
60
|
+
`,configField:"",contextField:`
|
|
61
|
+
env: envConfig,`,importLines:['import * as lunoraEnvContract from "../env.js";'],stub:""}:c,L=e=>e?{build:`
|
|
62
|
+
const access = accessFacade(identity, userId);
|
|
63
|
+
`,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=>`
|
|
65
|
+
const env = (this.env ?? {}) as Record<string, unknown>;
|
|
66
|
+
const flags: import("${n}").LunoraFlags = createFlags(flagsConfig, env, {
|
|
67
|
+
provider: () => config.flags?.(env),
|
|
68
|
+
targetingKey: ${i},
|
|
69
|
+
});`,o=`
|
|
70
|
+
/** Statically-discovered feature flags (\`ctx.flags.<type>("key")\` reads) served via \`__lunora_admin__:listFlags\` + the reactive \`__lunora_flags__:\` channel. */
|
|
71
|
+
const LUNORA_FLAG_KEYS = ${p(e,'ReadonlyArray<{ key: string; type: "boolean" | "number" | "object" | "string" }>')};
|
|
72
|
+
`,s=`
|
|
73
|
+
protected override async evaluateFlags(context?: Record<string, unknown>): Promise<FlagsResult> {${r("undefined")}
|
|
74
|
+
const evalContext = context as import("${n}").EvaluationContext | undefined;
|
|
75
|
+
const evaluations: FlagsResult["flags"] = [];
|
|
76
|
+
|
|
77
|
+
for (const entry of LUNORA_FLAG_KEYS) {
|
|
78
|
+
// eslint-disable-next-line no-await-in-loop -- flags evaluate sequentially; each shares the single memoized provider client
|
|
79
|
+
const details =
|
|
80
|
+
entry.type === "boolean"
|
|
81
|
+
? await flags.details.boolean(entry.key, false, evalContext)
|
|
82
|
+
: entry.type === "number"
|
|
83
|
+
? await flags.details.number(entry.key, 0, evalContext)
|
|
84
|
+
: entry.type === "string"
|
|
85
|
+
? await flags.details.string(entry.key, "", evalContext)
|
|
86
|
+
: await flags.details.object(entry.key, {}, evalContext);
|
|
87
|
+
|
|
88
|
+
evaluations.push({ errorCode: details.errorCode, key: entry.key, reason: details.reason, type: entry.type, value: details.value, variant: details.variant });
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return { configured: true, flags: evaluations };
|
|
92
|
+
}
|
|
93
|
+
`,u=`
|
|
94
|
+
protected override runFlagSubscriptionRead(_functionPath: string, args: Record<string, unknown>, identity?: SubscriptionIdentity): Promise<unknown> {${r("() => flagsConfig.identify?.({ identity: identity?.identity ?? null, userId: identity?.userId ?? null })")}
|
|
95
|
+
const key = typeof args.key === "string" ? args.key : "";
|
|
96
|
+
|
|
97
|
+
// SECURITY: the reactive channel is public (any socket, no auth). Serve
|
|
98
|
+
// ONLY statically-discovered flag keys — an arbitrary client-supplied key
|
|
99
|
+
// would let a subscriber probe the value of internal/unreleased flags the
|
|
100
|
+
// app never exposes. Unknown key ⇒ the "nothing to deliver" sentinel.
|
|
101
|
+
// eslint-disable-next-line unicorn/no-null -- the base hook's "nothing to deliver" sentinel
|
|
102
|
+
if (key.length === 0 || !LUNORA_FLAG_KEYS.some((entry) => entry.key === key)) {
|
|
103
|
+
return Promise.resolve(null);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// SECURITY: evaluate under the socket's server-verified identity ONLY
|
|
107
|
+
// (the targetingKey resolved above). Client-supplied targeting context is
|
|
108
|
+
// NOT honored on this public channel — otherwise a subscriber could spoof
|
|
109
|
+
// targeting attributes (e.g. plan/role) to unlock a flag gated on them.
|
|
110
|
+
const context = undefined;
|
|
111
|
+
|
|
112
|
+
if (args.type === "number") {
|
|
113
|
+
return flags.number(key, typeof args.default === "number" ? args.default : 0, context);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (args.type === "string") {
|
|
117
|
+
return flags.string(key, typeof args.default === "string" ? args.default : "", context);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (args.type === "object") {
|
|
121
|
+
return flags.object(key, (args.default ?? {}) as import("${n}").JsonValue, context);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return flags.boolean(key, typeof args.default === "boolean" ? args.default : false, context);
|
|
125
|
+
}
|
|
126
|
+
`;return{constant:o,evaluateOverride:s,subscriptionOverride:u}},F=e=>e?{build:`
|
|
127
|
+
const analyticsBinding = config.analytics?.(env) ?? (env as Record<string, unknown>).ANALYTICS;
|
|
128
|
+
const analytics: AnalyticsClient = analyticsBinding ? createAnalytics(analyticsBinding as AnalyticsEngineDatasetLike) : analyticsStub;
|
|
129
|
+
`,configField:`
|
|
130
|
+
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:`
|
|
132
|
+
const imagesBinding = config.images?.(env) ?? (env as Record<string, unknown>).IMAGES;
|
|
133
|
+
const images: Images = imagesBinding ? createImages({ binding: imagesBinding as ImagesBindingLike }) : imagesStub;
|
|
134
|
+
`,configField:`
|
|
135
|
+
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:`
|
|
137
|
+
const sql: SqlClient = config.sql ? config.sql(env) : sqlStub;
|
|
138
|
+
`,configField:`
|
|
139
|
+
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:`
|
|
141
|
+
const browser: Browser = config.browser ? config.browser(env) : browserStub;
|
|
142
|
+
`,configField:`
|
|
143
|
+
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:`
|
|
145
|
+
const r2sqlEnv = env as Record<string, unknown>;
|
|
146
|
+
const r2sqlAccountId = (r2sqlEnv.R2_SQL_ACCOUNT_ID ?? r2sqlEnv.CLOUDFLARE_ACCOUNT_ID) as string | undefined;
|
|
147
|
+
const r2sqlToken = r2sqlEnv.R2_SQL_TOKEN as string | undefined;
|
|
148
|
+
const r2sqlBucket = r2sqlEnv.R2_SQL_BUCKET as string | undefined;
|
|
149
|
+
const r2sql: R2SqlClient = config.r2sql
|
|
150
|
+
? config.r2sql(env)
|
|
151
|
+
: r2sqlAccountId && r2sqlToken && r2sqlBucket
|
|
152
|
+
? createR2Sql({ accountId: r2sqlAccountId, apiToken: r2sqlToken, bucket: r2sqlBucket })
|
|
153
|
+
: r2sqlStub;
|
|
154
|
+
`,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:`
|
|
156
|
+
const pipelinesBinding = config.pipelines?.(env) ?? (env as Record<string, unknown>).PIPELINES;
|
|
157
|
+
const pipelines: PipelineClient = pipelinesBinding ? createPipelines({ binding: pipelinesBinding as PipelineBindingLike }) : pipelinesStub;
|
|
158
|
+
`,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 {
|
|
161
|
+
public constructor(ctx: ConstructorParameters<typeof LunoraContainer>[0], env: Record<string, unknown>) {
|
|
162
|
+
super(ctx, env, ${s.exportName}, "${s.exportName}"${n});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
`)).join(`
|
|
166
|
+
`),o=e.map(s=>s.exportName).join(", ");return`${d}/**
|
|
167
|
+
* Container-enabled Durable Object classes for the containers declared in
|
|
168
|
+
* \`lunora/containers.ts\`. Re-export them from your worker entry — wrangler
|
|
169
|
+
* requires each \`containers[].class_name\` to be exported by the worker:
|
|
170
|
+
*
|
|
171
|
+
* \`export * from "./lunora/_generated/containers.js";\`
|
|
172
|
+
*
|
|
173
|
+
* \`ContainerProxy\` is re-exported alongside them: the egress-interception path
|
|
174
|
+
* (\`allowedHosts\`/\`deniedHosts\`/\`interceptHttps\` and the runtime
|
|
175
|
+
* \`handle.egress\` controls) routes container outbound traffic through this
|
|
176
|
+
* WorkerEntrypoint, so it too must be exported by the deployed worker.
|
|
177
|
+
*/
|
|
178
|
+
import { LunoraContainer } from "@lunora/container/do";
|
|
179
|
+
|
|
180
|
+
import { ${o} } from "../containers.js";
|
|
181
|
+
|
|
182
|
+
export { ContainerProxy } from "@lunora/container/do";
|
|
183
|
+
|
|
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(`
|
|
185
|
+
`);return{build:`
|
|
186
|
+
const containers = createContainerContext(env, LUNORA_CONTAINERS, ${t?JSON.stringify(t):"undefined"}, this.getCurrentTraceparent(), this.getCurrentSampleErrors());
|
|
187
|
+
`,contextField:`
|
|
188
|
+
containers,`,importLines:['import type { ContainerBindingSpec } from "@lunora/container";','import { createContainerContext } from "@lunora/container";'],specs:`
|
|
189
|
+
/** Wiring specs for \`ctx.containers\` (codegen-derived from \`lunora/containers.ts\`). */
|
|
190
|
+
const LUNORA_CONTAINERS: ReadonlyArray<ContainerBindingSpec> = [
|
|
191
|
+
${n}
|
|
192
|
+
];
|
|
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}\`). */
|
|
194
|
+
export class ${r.className} extends LunoraWorkflow<WorkflowParamsOf<typeof ${r.exportName}>, WorkflowOutputOf<typeof ${r.exportName}>> {
|
|
195
|
+
public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
|
|
196
|
+
super(ctx, env, ${r.exportName}, "${r.exportName}");
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
`)).join(`
|
|
200
|
+
`),n=e.map(r=>r.exportName).join(", ");return`${d}/**
|
|
201
|
+
* WorkflowEntrypoint classes for the workflows declared in
|
|
202
|
+
* \`lunora/workflows.ts\`. Re-export them from your worker entry — wrangler
|
|
203
|
+
* requires each \`workflows[].class_name\` to be exported by the worker:
|
|
204
|
+
*
|
|
205
|
+
* \`export * from "./lunora/_generated/workflows.js";\`
|
|
206
|
+
*/
|
|
207
|
+
import LunoraWorkflow from "@lunora/workflow/do";
|
|
208
|
+
|
|
209
|
+
import { ${n} } from "../workflows.js";
|
|
210
|
+
|
|
211
|
+
/** Params type carried by a \`defineWorkflow\` definition (its phantom \`__params\`), so each entrypoint keeps the authored \`ctx.params\` type. */
|
|
212
|
+
type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params }
|
|
213
|
+
? unknown extends Params
|
|
214
|
+
? Record<string, unknown>
|
|
215
|
+
: NonNullable<Params>
|
|
216
|
+
: Record<string, unknown>;
|
|
217
|
+
|
|
218
|
+
/** Output type carried by a \`defineWorkflow\` definition (its phantom \`__output\`), so each entrypoint keeps the authored return type. */
|
|
219
|
+
type WorkflowOutputOf<Definition> = Definition extends { __output?: infer Output } ? Output : unknown;
|
|
220
|
+
|
|
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> {
|
|
223
|
+
public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
|
|
224
|
+
super(ctx, env, compileAgentWorkflow(${i.exportName}, "${i.exportName}"), "${i.exportName}");
|
|
225
|
+
}
|
|
226
|
+
}
|
|
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}\`). */
|
|
229
|
+
export class ${m} extends VoiceSessionDO {
|
|
230
|
+
public constructor(ctx: ConstructorParameters<typeof VoiceSessionDO>[0], env: Record<string, unknown>) {
|
|
231
|
+
super(ctx, env, ${i.exportName}, "${i.exportName}");
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
`;return`${g}${b}`}).join(`
|
|
235
|
+
`),o=e.map(i=>i.exportName).join(", ");return`${d}/**
|
|
236
|
+
* WorkflowEntrypoint classes for the agents declared in \`lunora/agents.ts\`.
|
|
237
|
+
* Each \`defineAgent\` compiles a replay-safe tool-loop onto a Cloudflare
|
|
238
|
+
* Workflow. Re-export them from your worker entry — wrangler requires each
|
|
239
|
+
* \`workflows[].class_name\` to be exported by the worker:
|
|
240
|
+
*
|
|
241
|
+
* \`export * from "./lunora/_generated/agents.js";\`${n?"\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).":""}
|
|
242
|
+
*/
|
|
243
|
+
import LunoraWorkflow from "@lunora/workflow/do";
|
|
244
|
+
${n?'import { compileAgentWorkflow, VoiceSessionDO } from "@lunora/agent";':'import { compileAgentWorkflow } from "@lunora/agent";'}
|
|
245
|
+
import type { AgentRunInput, AgentRunResult } from "@lunora/agent";
|
|
246
|
+
|
|
247
|
+
import { ${o} } from "../agents.js";
|
|
248
|
+
|
|
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(`
|
|
250
|
+
`);return`${d}/**
|
|
251
|
+
* Push-consumer registry for the queues declared in \`lunora/queues.ts\`. The
|
|
252
|
+
* composed worker's \`queue(batch, env, ctx)\` entry routes each delivered batch
|
|
253
|
+
* by \`batch.queue\` to the matching \`defineQueue\` handler. Wired automatically
|
|
254
|
+
* by \`defineApp\` — you don't import this directly.
|
|
255
|
+
*/
|
|
256
|
+
import type { QueueRegistry } from "@lunora/queue";
|
|
257
|
+
|
|
258
|
+
import { ${n} } from "../queues.js";
|
|
259
|
+
|
|
260
|
+
/** Stable wrangler queue name → { binding, definition, exportName } for batch routing. */
|
|
261
|
+
export const LUNORA_QUEUE_REGISTRY: QueueRegistry = {
|
|
262
|
+
${r}
|
|
263
|
+
};
|
|
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(`
|
|
265
|
+
`);return{build:`
|
|
266
|
+
const workflows = createWorkflowContext(env, LUNORA_WORKFLOWS);
|
|
267
|
+
`,contextField:`
|
|
268
|
+
workflows,`,importLines:['import type { WorkflowBindingSpec } from "@lunora/workflow";','import { createWorkflowContext } from "@lunora/workflow";'],specs:`
|
|
269
|
+
/** Wiring specs for \`ctx.workflows\` (codegen-derived from \`lunora/workflows.ts\`). */
|
|
270
|
+
const LUNORA_WORKFLOWS: ReadonlyArray<WorkflowBindingSpec> = [
|
|
271
|
+
${t}
|
|
272
|
+
];
|
|
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(`
|
|
274
|
+
`);return{build:`
|
|
275
|
+
const queues = createQueueContext(env, LUNORA_QUEUES);
|
|
276
|
+
`,contextField:`
|
|
277
|
+
queues,`,importLines:['import type { QueueBindingSpec } from "@lunora/queue";','import { createQueueContext } from "@lunora/queue";'],specs:`
|
|
278
|
+
/** Wiring specs for \`ctx.queues\` (codegen-derived from \`lunora/queues.ts\`). */
|
|
279
|
+
const LUNORA_QUEUES: ReadonlyArray<QueueBindingSpec> = [
|
|
280
|
+
${t}
|
|
281
|
+
];
|
|
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(`
|
|
283
|
+
`);return{build:`
|
|
284
|
+
const agents = createAgentContext(env, LUNORA_AGENTS);
|
|
285
|
+
`,contextField:`
|
|
286
|
+
agents,`,importLines:['import { createAgentContext } from "@lunora/agent";','import type { AgentBindingSpec } from "@lunora/agent";'],specs:`
|
|
287
|
+
/** Wiring specs for \`ctx.agents\` (codegen-derived from \`lunora/agents.ts\`). */
|
|
288
|
+
const LUNORA_AGENTS: ReadonlyArray<AgentBindingSpec> = [
|
|
289
|
+
${t}
|
|
290
|
+
];
|
|
291
|
+
`}},f=(e,t,n,r,o)=>({constant:`
|
|
292
|
+
${o}
|
|
293
|
+
const ${e} = ${p(r,t)};
|
|
294
|
+
`,override:`
|
|
295
|
+
protected override ${n}(): ${t} {
|
|
296
|
+
return ${e};
|
|
297
|
+
}
|
|
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:`
|
|
299
|
+
const payments: LunoraPayment = config.payment
|
|
300
|
+
? paymentsFromContext({ auth: { userId: userId ?? null }, db: db as unknown as LunoraPaymentDbLike }, config.payment(env))
|
|
301
|
+
: paymentStub;
|
|
302
|
+
`,configField:`
|
|
303
|
+
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:`
|
|
305
|
+
const x402: X402Pay = config.x402
|
|
306
|
+
? lazyX402Pay(config.x402(env), { getSecret: (name: string) => secrets.get(name) })
|
|
307
|
+
: x402Stub;
|
|
308
|
+
`,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};
|
|
@@ -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-DP-5e-RE.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.
|
|
3
|
+
"version": "1.0.0-alpha.240",
|
|
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.
|
|
50
|
-
"@lunora/
|
|
51
|
-
"@lunora/
|
|
52
|
-
"@lunora/
|
|
53
|
-
"@lunora/
|
|
54
|
-
"@lunora/
|
|
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",
|
|
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 };
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
class CodegenDiagnosticError extends Error {
|
|
2
|
-
column;
|
|
3
|
-
file;
|
|
4
|
-
line;
|
|
5
|
-
constructor(message, file, line, column) {
|
|
6
|
-
super(message);
|
|
7
|
-
this.name = "CodegenDiagnosticError";
|
|
8
|
-
this.file = file;
|
|
9
|
-
this.line = line;
|
|
10
|
-
this.column = column;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
const diagnosticAt = (node, detail, meta) => {
|
|
14
|
-
const sourceFile = node.getSourceFile();
|
|
15
|
-
const file = sourceFile.getFilePath();
|
|
16
|
-
const line = node.getStartLineNumber();
|
|
17
|
-
const { column } = sourceFile.getLineAndColumnAtPos(node.getStart());
|
|
18
|
-
const message = `@lunora/codegen: ${detail} (${file}:${line.toString()}:${column.toString()})`;
|
|
19
|
-
const error = new CodegenDiagnosticError(message, file, line, column);
|
|
20
|
-
return meta ? Object.assign(error, meta) : error;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export { CodegenDiagnosticError, diagnosticAt };
|