@lunora/codegen 1.0.0-alpha.81 → 1.0.0-alpha.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +1125 -1074
- package/dist/index.d.ts +1125 -1074
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/DEFAULT_TARGET-CH5disA3.mjs +1 -0
- package/dist/packem_shared/GENERATED_HEADER-oy7DTIDi.mjs +1 -0
- package/dist/packem_shared/{OPENRPC_VERSION-DfKtsdPS.mjs → OPENRPC_VERSION-K3RTK2CP.mjs} +1 -1
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-ZIqaP_TZ.mjs +9 -0
- package/dist/packem_shared/SchemaSnapshotParseError-BJkhTEpi.mjs +16 -0
- package/dist/packem_shared/{buildOpenApiDocument-D46nZ7D_.mjs → buildOpenApiDocument-Blf3mpIz.mjs} +1 -1
- package/dist/packem_shared/describeErrorLevelFindings-IhNx9gPr.mjs +1 -0
- package/dist/packem_shared/discover-queries-Bhu9SNsy.mjs +1 -0
- package/dist/packem_shared/discoverCrons-DLwFH_K5.mjs +1 -0
- package/dist/packem_shared/discoverMaskProcedures-ZewKJLXx.mjs +1 -0
- package/dist/packem_shared/{discoverQueries-2A0lbpxV.mjs → discoverQueries-g4qZzLpl.mjs} +1 -1
- package/dist/packem_shared/discoverSchema-4nJgoLaJ.mjs +1 -0
- package/dist/packem_shared/{emit-CCw5fiXq.mjs → emit-B7IUlWwi.mjs} +371 -248
- package/dist/packem_shared/{emitApp-DEHN578T.mjs → emitApp-jRD2D9kI.mjs} +112 -37
- package/dist/packem_shared/readPackageDependencies-CogJX1Ia.mjs +1 -0
- package/package.json +10 -10
- package/dist/packem_shared/DEFAULT_TARGET-BYPEwgZu.mjs +0 -1
- package/dist/packem_shared/GENERATED_HEADER-CR3xA8yO.mjs +0 -1
- package/dist/packem_shared/SCHEMA_SNAPSHOT_FILENAME-DjpfF4p7.mjs +0 -12
- package/dist/packem_shared/SchemaSnapshotParseError-0KRzSjo4.mjs +0 -14
- package/dist/packem_shared/discover-queries-Ctpk9SA-.mjs +0 -1
- package/dist/packem_shared/discoverCrons-CwtPaymU.mjs +0 -1
- package/dist/packem_shared/discoverMaskProcedures-DQ-4yUUK.mjs +0 -1
- package/dist/packem_shared/discoverSchema-DUl8rbP3.mjs +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { AdvisorExportSink, AdvisorGeoIndexUsage, AdvisorNotifyCall, AdvisorNotifyConfig, Finding, LintContext, AdvisorProcedureProtection } from '@lunora/advisor';
|
|
2
2
|
export type { Finding } from '@lunora/advisor';
|
|
3
|
+
import '@lunora/platform';
|
|
4
|
+
import { Project, Node } from 'ts-morph';
|
|
3
5
|
import { LunoraError } from '@lunora/errors';
|
|
4
6
|
export { MESSAGE_SOLUTIONS as LUNORA_SOLUTION_RULES, type Solution as LunoraSolution, type SolutionRule as LunoraSolutionRule, findSolutionByMessage as findLunoraSolution } from '@lunora/errors';
|
|
5
|
-
import { Node, Project } from 'ts-morph';
|
|
6
7
|
import { StudioFeaturesResult } from '@lunora/shard-engine';
|
|
7
|
-
import '@lunora/platform';
|
|
8
8
|
import { Schema } from '@lunora/server';
|
|
9
9
|
import { JsonSchema } from '@lunora/values';
|
|
10
10
|
/**
|
|
@@ -1140,22 +1140,31 @@ interface HttpRouteIR {
|
|
|
1140
1140
|
* pass straight through to the advisor without conversion.
|
|
1141
1141
|
*/
|
|
1142
1142
|
interface ProcedureMiddlewareIR {
|
|
1143
|
-
/**
|
|
1144
|
-
|
|
1143
|
+
/**
|
|
1144
|
+
* `true` when the handler body could be read statically — an inline function
|
|
1145
|
+
* expression/arrow, or a same-file identifier resolved to one. `false` for a
|
|
1146
|
+
* genuinely cross-file handler (an imported function, or an identifier that
|
|
1147
|
+
* doesn't resolve in this file), in which case every behavioural fact below
|
|
1148
|
+
* is `undefined` rather than a false "not observed" — the feeder never saw
|
|
1149
|
+
* the body, so it has nothing to report.
|
|
1150
|
+
*/
|
|
1151
|
+
analyzableBody: boolean;
|
|
1152
|
+
/** `true` when the handler (or a helper inside it) references `ctx.mail` / `ctx.email`. `undefined` when `analyzableBody` is `false`. */
|
|
1153
|
+
callsMail?: boolean;
|
|
1145
1154
|
/** `true` when the handler emits a structured observability event (`ctx.log` / `ctx.span` / `ctx.trace`). */
|
|
1146
|
-
emitsEvent
|
|
1155
|
+
emitsEvent?: boolean;
|
|
1147
1156
|
/** `true` when a `// lunora-advisor-exempt` directive sits above the export. */
|
|
1148
1157
|
exempt: boolean;
|
|
1149
1158
|
/** The `-- reason` from that directive, or `""`. */
|
|
1150
1159
|
exemptReason: string;
|
|
1151
1160
|
/** Export binding name of the procedure (e.g. `signUp`). */
|
|
1152
1161
|
exportName: string;
|
|
1153
|
-
/** `true` when the handler fans work out to a privileged, cost-bearing dispatch surface (scheduler `runAfter`/`runAt`, a queue producer send, or a workflow create). Feeds the privileged-fanout lint. */
|
|
1154
|
-
fanOut
|
|
1162
|
+
/** `true` when the handler fans work out to a privileged, cost-bearing dispatch surface (scheduler `runAfter`/`runAt`, a queue producer send, or a workflow create). Feeds the privileged-fanout lint. `undefined` when `analyzableBody` is `false`. */
|
|
1163
|
+
fanOut?: boolean;
|
|
1155
1164
|
/** Source file relative to `<projectRoot>/lunora/`, without extension. */
|
|
1156
1165
|
file: string;
|
|
1157
1166
|
/** `true` when the handler wraps work in `try`/`catch`. */
|
|
1158
|
-
handlesErrors
|
|
1167
|
+
handlesErrors?: boolean;
|
|
1159
1168
|
/**
|
|
1160
1169
|
* `true` when the procedure declares an email-shaped argument (`email`,
|
|
1161
1170
|
* `emailAddress`, `userEmail`, …), `false` when it provably declares none,
|
|
@@ -1169,19 +1178,19 @@ interface ProcedureMiddlewareIR {
|
|
|
1169
1178
|
hasEmailArg?: boolean;
|
|
1170
1179
|
kind: "action" | "mutation" | "query";
|
|
1171
1180
|
/** `true` when the handler reaches an outbound surface (`ctx.fetch`, mail, queues, storage, sql, ai, …) that can fail. */
|
|
1172
|
-
reachesOutbound
|
|
1181
|
+
reachesOutbound?: boolean;
|
|
1173
1182
|
/** `true` when the handler runs any AI generation, bounded or not. */
|
|
1174
|
-
runsAiGeneration
|
|
1183
|
+
runsAiGeneration?: boolean;
|
|
1175
1184
|
/** `true` when the handler throws a bare `new Error(...)` rather than a coded `LunoraError`. */
|
|
1176
|
-
throwsBareError
|
|
1177
|
-
/** `true` when the handler runs an AI generation (`generateText`/`streamText`/`generateObject`/`streamObject`) with no `maxOutputTokens` bound in its config literal. Feeds the `ai_unbounded_generation_public` lint. */
|
|
1178
|
-
unboundedAiGeneration
|
|
1185
|
+
throwsBareError?: boolean;
|
|
1186
|
+
/** `true` when the handler runs an AI generation (`generateText`/`streamText`/`generateObject`/`streamObject`) with no `maxOutputTokens` bound in its config literal. Feeds the `ai_unbounded_generation_public` lint. `undefined` when `analyzableBody` is `false`. */
|
|
1187
|
+
unboundedAiGeneration?: boolean;
|
|
1179
1188
|
/** `true` when the chain carries `.use(verifyTurnstile(...))` or a `protectPublic({ captcha })` bundle. */
|
|
1180
1189
|
usesCaptcha: boolean;
|
|
1181
1190
|
/** `true` when the chain carries `.use(emailGateMiddleware(...))` (`@lunora/auth`). Feeds the `signup_mutation_without_disposable_gating` lint. */
|
|
1182
1191
|
usesEmailGate: boolean;
|
|
1183
|
-
/** `true` when the handler calls `ctx.db.insertManyUnsafe(...)`, bypassing validators and triggers. Feeds the `insert_many_unsafe_user_data` lint. */
|
|
1184
|
-
usesInsertManyUnsafe
|
|
1192
|
+
/** `true` when the handler calls `ctx.db.insertManyUnsafe(...)`, bypassing validators and triggers. Feeds the `insert_many_unsafe_user_data` lint. `undefined` when `analyzableBody` is `false`. */
|
|
1193
|
+
usesInsertManyUnsafe?: boolean;
|
|
1185
1194
|
/** `true` when the chain carries `.use(mask(...))`. */
|
|
1186
1195
|
usesMask: boolean;
|
|
1187
1196
|
/** `true` when the chain carries `.use(rateLimit(...))` or a `protectPublic({ rateLimit })` bundle. */
|
|
@@ -1190,8 +1199,8 @@ interface ProcedureMiddlewareIR {
|
|
|
1190
1199
|
usesRls: boolean;
|
|
1191
1200
|
/** `"internal"` for `internalQuery` / `internalMutation` / `internalAction`. */
|
|
1192
1201
|
visibility: "internal" | "public";
|
|
1193
|
-
/** `true` when the handler inserts into a user/session/account-shaped table. */
|
|
1194
|
-
writesUserTable
|
|
1202
|
+
/** `true` when the handler inserts into a user/session/account-shaped table. `undefined` when `analyzableBody` is `false`. */
|
|
1203
|
+
writesUserTable?: boolean;
|
|
1195
1204
|
}
|
|
1196
1205
|
/**
|
|
1197
1206
|
* Per-procedure argument-validator snapshot, produced by the
|
|
@@ -1374,6 +1383,14 @@ interface StorageKeyAccessIR {
|
|
|
1374
1383
|
line: number;
|
|
1375
1384
|
/** The bucket method invoked with the arg-derived key, e.g. `get` / `put` / `delete` / `download`. */
|
|
1376
1385
|
method: string;
|
|
1386
|
+
/**
|
|
1387
|
+
* Visibility of the enclosing procedure. `internal` procedures have no
|
|
1388
|
+
* untrusted caller by construction — see `owner_field_from_args_not_auth`'s
|
|
1389
|
+
* identical split — so `storage_key_from_user_args` drops the finding to
|
|
1390
|
+
* INFO rather than ERROR there. `undefined` when the access sits outside any
|
|
1391
|
+
* registered procedure the feeder could attribute it to.
|
|
1392
|
+
*/
|
|
1393
|
+
visibility?: "internal" | "public";
|
|
1377
1394
|
}
|
|
1378
1395
|
/**
|
|
1379
1396
|
* One `ctx.containers.<exportName>.get(name, …)` call whose instance key is derived
|
|
@@ -2040,1152 +2057,1184 @@ declare const lintSchema: (options: LintSchemaOptions) => Finding[];
|
|
|
2040
2057
|
*/
|
|
2041
2058
|
declare const formatAdvisories: (findings: ReadonlyArray<Finding>) => string;
|
|
2042
2059
|
/**
|
|
2043
|
-
*
|
|
2044
|
-
*
|
|
2045
|
-
*
|
|
2046
|
-
* `
|
|
2047
|
-
*
|
|
2048
|
-
*
|
|
2060
|
+
* The canonical capability list. **Order is load-bearing** for the `emit-app.ts`
|
|
2061
|
+
* long-tail: the fluent methods are emitted in the order the `appMethod`-bearing
|
|
2062
|
+
* rows appear here, so this array is ordered to reproduce the original
|
|
2063
|
+
* `LONG_TAIL` sequence (ai, analytics, browser, hyperdrive, images, kv, payment,
|
|
2064
|
+
* r2sql, vectors). The `serverCtxField` rows are referenced by name in the ctx
|
|
2065
|
+
* interface templates, so their order here is not output-affecting.
|
|
2049
2066
|
*/
|
|
2050
|
-
declare
|
|
2051
|
-
readonly
|
|
2052
|
-
readonly
|
|
2053
|
-
readonly
|
|
2054
|
-
|
|
2055
|
-
|
|
2067
|
+
declare const CAPABILITY_ROWS: readonly [{
|
|
2068
|
+
readonly contextProperty: "access";
|
|
2069
|
+
readonly key: "access";
|
|
2070
|
+
readonly moduleSpecifier: "@lunora/cloudflare-access";
|
|
2071
|
+
}, {
|
|
2072
|
+
readonly appMethod: {
|
|
2073
|
+
readonly configKey: "ai";
|
|
2074
|
+
readonly doc: "Override the Workers AI binding backing `ctx.ai` (defaults to `env.AI`).";
|
|
2075
|
+
readonly method: "ai";
|
|
2076
|
+
};
|
|
2077
|
+
readonly contextProperty: "ai";
|
|
2078
|
+
readonly key: "ai";
|
|
2079
|
+
readonly moduleSpecifier: "@lunora/ai";
|
|
2080
|
+
}, {
|
|
2081
|
+
readonly appMethod: {
|
|
2082
|
+
readonly configKey: "analytics";
|
|
2083
|
+
readonly doc: "Override the Analytics Engine dataset backing `ctx.analytics` (defaults to `env.ANALYTICS`).";
|
|
2084
|
+
readonly method: "analytics";
|
|
2085
|
+
};
|
|
2086
|
+
readonly contextProperty: "analytics";
|
|
2087
|
+
readonly key: "analytics";
|
|
2088
|
+
readonly moduleSpecifier: "@lunora/bindings/analytics";
|
|
2089
|
+
readonly serverCtxField: {
|
|
2090
|
+
readonly field: "\n /** Analytics Engine telemetry sink. Fire-and-forget and sampled; do not read it back in-handler. */\n readonly analytics: import(\"@lunora/bindings/analytics\").AnalyticsClient;";
|
|
2091
|
+
readonly tier: "every";
|
|
2092
|
+
};
|
|
2093
|
+
}, {
|
|
2094
|
+
readonly appMethod: {
|
|
2095
|
+
readonly configKey: "browser";
|
|
2096
|
+
readonly doc: "Override the Browser Rendering binding backing `ctx.browser` (defaults to `env.BROWSER`).";
|
|
2097
|
+
readonly method: "browser";
|
|
2098
|
+
};
|
|
2099
|
+
readonly contextProperty: "browser";
|
|
2100
|
+
readonly key: "browser";
|
|
2101
|
+
readonly moduleSpecifier: "@lunora/browser";
|
|
2102
|
+
readonly serverCtxField: {
|
|
2103
|
+
readonly field: "\n /** Browser Rendering (screenshots/PDF/scrape). Non-deterministic — available only in actions. */\n readonly browser: import(\"@lunora/browser\").Browser;";
|
|
2104
|
+
readonly tier: "action";
|
|
2105
|
+
};
|
|
2106
|
+
}, {
|
|
2107
|
+
readonly contextProperty: "containers";
|
|
2108
|
+
readonly key: "container";
|
|
2109
|
+
readonly moduleSpecifier: "@lunora/container";
|
|
2110
|
+
}, {
|
|
2111
|
+
readonly contextProperty: "flags";
|
|
2112
|
+
readonly key: "flags";
|
|
2113
|
+
readonly moduleSpecifier: "@lunora/flags";
|
|
2114
|
+
}, {
|
|
2115
|
+
readonly appMethod: {
|
|
2116
|
+
readonly configKey: "sql";
|
|
2117
|
+
readonly doc: "Wire the Hyperdrive SQL client backing `ctx.sql` — build it with `createHyperdrive` + `fromPostgresJs`/`fromNodePg`/`fromMysql2`.";
|
|
2118
|
+
readonly method: "hyperdrive";
|
|
2119
|
+
};
|
|
2120
|
+
readonly contextProperty: "sql";
|
|
2121
|
+
readonly key: "hyperdrive";
|
|
2122
|
+
readonly moduleSpecifier: "@lunora/hyperdrive";
|
|
2123
|
+
readonly serverCtxField: {
|
|
2124
|
+
readonly field: "\n /**\n * External database access via Hyperdrive. Non-deterministic — available only in actions. Writes here are NOT tracked by Lunora live queries; subscriptions will not re-run on external DB changes.\n */\n readonly sql: import(\"@lunora/hyperdrive\").SqlClient;";
|
|
2125
|
+
readonly tier: "action";
|
|
2126
|
+
};
|
|
2127
|
+
}, {
|
|
2128
|
+
readonly appMethod: {
|
|
2129
|
+
readonly configKey: "images";
|
|
2130
|
+
readonly doc: "Override the Images binding backing `ctx.images` (defaults to `env.IMAGES`).";
|
|
2131
|
+
readonly method: "images";
|
|
2132
|
+
};
|
|
2133
|
+
readonly contextProperty: "images";
|
|
2134
|
+
readonly key: "images";
|
|
2135
|
+
readonly moduleSpecifier: "@lunora/bindings/images";
|
|
2136
|
+
readonly serverCtxField: {
|
|
2137
|
+
readonly field: "\n /** Cloudflare Images transforms (resize/format/optimize). Non-deterministic — available only in actions. */\n readonly images: import(\"@lunora/bindings/images\").Images;";
|
|
2138
|
+
readonly tier: "action";
|
|
2139
|
+
};
|
|
2140
|
+
}, {
|
|
2141
|
+
readonly appMethod: {
|
|
2142
|
+
readonly configKey: "kv";
|
|
2143
|
+
readonly doc: "Override the Workers KV binding backing `ctx.kv` (defaults to `env.KV`).";
|
|
2144
|
+
readonly method: "kv";
|
|
2145
|
+
};
|
|
2146
|
+
readonly contextProperty: "kv";
|
|
2147
|
+
readonly key: "kv";
|
|
2148
|
+
readonly moduleSpecifier: "@lunora/bindings/kv";
|
|
2149
|
+
readonly serverCtxField: {
|
|
2150
|
+
readonly field: "\n readonly kv: import(\"@lunora/bindings/kv\").Kv;";
|
|
2151
|
+
readonly tier: "every";
|
|
2152
|
+
};
|
|
2153
|
+
}, {
|
|
2154
|
+
readonly key: "mail";
|
|
2155
|
+
readonly moduleSpecifier: "@lunora/mail";
|
|
2156
|
+
}, {
|
|
2157
|
+
readonly contextProperty: "notify";
|
|
2158
|
+
readonly key: "notify";
|
|
2159
|
+
readonly moduleSpecifier: "@lunora/notify";
|
|
2160
|
+
}, {
|
|
2161
|
+
readonly appMethod: {
|
|
2162
|
+
readonly configKey: "payment";
|
|
2163
|
+
readonly doc: "Wire the payment options backing `ctx.payments`.";
|
|
2164
|
+
readonly method: "payment";
|
|
2165
|
+
};
|
|
2166
|
+
readonly contextProperty: "payments";
|
|
2167
|
+
readonly key: "payments";
|
|
2168
|
+
readonly moduleSpecifier: "@lunora/payment";
|
|
2169
|
+
}, {
|
|
2170
|
+
readonly appMethod: {
|
|
2171
|
+
readonly configKey: "x402";
|
|
2172
|
+
readonly doc: "Wire the x402 agent-wallet pay rail backing `ctx.x402` — a payment-enabled `fetch` that answers `402` challenges under a mandatory spend policy (ActionCtx-only; spends real funds).";
|
|
2173
|
+
readonly method: "x402";
|
|
2174
|
+
};
|
|
2175
|
+
readonly contextProperty: "x402";
|
|
2176
|
+
readonly key: "x402";
|
|
2177
|
+
readonly moduleSpecifier: "@lunora/x402/pay";
|
|
2178
|
+
}, {
|
|
2179
|
+
readonly contextProperty: "pipelines";
|
|
2180
|
+
readonly key: "pipelines";
|
|
2181
|
+
readonly moduleSpecifier: "@lunora/bindings/pipelines";
|
|
2182
|
+
readonly serverCtxField: {
|
|
2183
|
+
readonly field: "\n /** Pipelines ingestion sink (durable, R2-backed). Fire-and-forget and batched; do not read it back in-handler. */\n readonly pipelines: import(\"@lunora/bindings/pipelines\").PipelineClient;";
|
|
2184
|
+
readonly tier: "action";
|
|
2185
|
+
};
|
|
2186
|
+
}, {
|
|
2187
|
+
readonly appMethod: {
|
|
2188
|
+
readonly configKey: "r2sql";
|
|
2189
|
+
readonly doc: "Wire the R2 SQL client backing `ctx.r2sql` — build it with `createR2Sql({ accountId, apiToken, bucket })` (defaults to env `R2_SQL_TOKEN` / `R2_SQL_ACCOUNT_ID` / `R2_SQL_BUCKET`).";
|
|
2190
|
+
readonly method: "r2sql";
|
|
2191
|
+
};
|
|
2192
|
+
readonly contextProperty: "r2sql";
|
|
2193
|
+
readonly key: "r2sql";
|
|
2194
|
+
readonly moduleSpecifier: "@lunora/bindings/r2sql";
|
|
2195
|
+
readonly serverCtxField: {
|
|
2196
|
+
readonly field: "\n /**\n * R2 SQL over Apache Iceberg tables (window functions, DISTINCT, set operations). Non-deterministic — available only in actions. Reads here are NOT tracked by Lunora live queries.\n */\n readonly r2sql: import(\"@lunora/bindings/r2sql\").R2SqlClient;";
|
|
2197
|
+
readonly tier: "action";
|
|
2198
|
+
};
|
|
2199
|
+
}, {
|
|
2200
|
+
readonly contextProperty: "scheduler";
|
|
2201
|
+
readonly key: "scheduler";
|
|
2202
|
+
readonly moduleSpecifier: "@lunora/scheduler";
|
|
2203
|
+
}, {
|
|
2204
|
+
readonly contextProperty: "storage";
|
|
2205
|
+
readonly key: "storage";
|
|
2206
|
+
readonly moduleSpecifier: "@lunora/storage";
|
|
2207
|
+
}, {
|
|
2208
|
+
readonly appMethod: {
|
|
2209
|
+
readonly configKey: "vectors";
|
|
2210
|
+
readonly doc: "Wire the Vectorize index map backing `ctx.vectors`.";
|
|
2211
|
+
readonly method: "vectors";
|
|
2212
|
+
};
|
|
2213
|
+
readonly contextProperty: "vectors";
|
|
2214
|
+
readonly key: "vectors";
|
|
2215
|
+
readonly moduleSpecifier: "@lunora/bindings/vectors";
|
|
2216
|
+
}, {
|
|
2217
|
+
readonly contextProperty: "workflows";
|
|
2218
|
+
readonly key: "workflows";
|
|
2219
|
+
readonly moduleSpecifier: "@lunora/workflow";
|
|
2220
|
+
}];
|
|
2221
|
+
/** The literal union of every capability id — the single source of truth for `FeatureUsage`'s keys (so they cannot drift). */
|
|
2222
|
+
type CapabilityKey = (typeof CAPABILITY_ROWS)[number]["key"];
|
|
2223
|
+
/** The default codegen target — today's behavior, byte-identical goldens. */
|
|
2224
|
+
declare const DEFAULT_TARGET = "cloudflare";
|
|
2056
2225
|
/**
|
|
2057
|
-
*
|
|
2058
|
-
* location and whose `file`/`line`/`column` properties are set from the
|
|
2059
|
-
* ts-morph `Node`'s position in its source file.
|
|
2226
|
+
* Read `target` from `<projectRoot>/lunora.json`.
|
|
2060
2227
|
*
|
|
2061
|
-
*
|
|
2228
|
+
* This lives in `@lunora/codegen` rather than `@lunora/config` — where the rest
|
|
2229
|
+
* of the `lunora.json` reading lives — because `@lunora/config` depends on
|
|
2230
|
+
* `@lunora/codegen`, not the reverse. Putting it there and importing it here
|
|
2231
|
+
* would invert that edge, so config delegates to this instead and there is
|
|
2232
|
+
* still exactly one parser for the key.
|
|
2062
2233
|
*
|
|
2063
|
-
*
|
|
2064
|
-
*
|
|
2065
|
-
*
|
|
2066
|
-
*
|
|
2067
|
-
*
|
|
2234
|
+
* Best-effort and deliberately unvalidated: a missing file, malformed JSONC, or
|
|
2235
|
+
* a non-string value all collapse to `undefined`, because those are shape
|
|
2236
|
+
* errors rather than a name the user meant. An unrecognized *name* is returned
|
|
2237
|
+
* as-is so the caller's registry lookup rejects it — swallowing a typo into the
|
|
2238
|
+
* default would ship an app to the wrong provider.
|
|
2239
|
+
* @param projectRoot Directory containing `lunora.json`.
|
|
2240
|
+
* @returns the declared target, or `undefined` when none is usable.
|
|
2068
2241
|
*/
|
|
2069
|
-
declare const
|
|
2070
|
-
/** The only file agents may be declared in — mirrors `lunora/workflows.ts`. */
|
|
2071
|
-
declare const AGENTS_FILENAME = "agents.ts";
|
|
2242
|
+
declare const readProjectTarget: (projectRoot: string) => string | undefined;
|
|
2072
2243
|
/**
|
|
2073
|
-
*
|
|
2074
|
-
* `lunora
|
|
2075
|
-
*
|
|
2076
|
-
*
|
|
2077
|
-
*
|
|
2078
|
-
*
|
|
2079
|
-
*
|
|
2080
|
-
*
|
|
2244
|
+
* The target codegen should emit for: an explicit option wins, then
|
|
2245
|
+
* `lunora.json`, then the default.
|
|
2246
|
+
*
|
|
2247
|
+
* `runCodegen` applies this itself so a caller that forgets to pass a target
|
|
2248
|
+
* still emits the surface the project declared. That default matters more than
|
|
2249
|
+
* it looks: a call site that silently omits the target emits the *default*
|
|
2250
|
+
* surface with no diagnostic to notice, and the mismatch only shows up at
|
|
2251
|
+
* runtime on the deployed app.
|
|
2252
|
+
* @param projectRoot Directory containing `lunora.json`.
|
|
2253
|
+
* @param explicit A caller-supplied target, if any.
|
|
2254
|
+
* @returns the resolved target id — not guaranteed to be registered.
|
|
2081
2255
|
*/
|
|
2082
|
-
declare const
|
|
2256
|
+
declare const resolveCodegenTarget: (projectRoot: string, explicit?: string) => string;
|
|
2083
2257
|
/**
|
|
2084
|
-
*
|
|
2085
|
-
*
|
|
2086
|
-
*
|
|
2258
|
+
* The target ids codegen can gate against.
|
|
2259
|
+
*
|
|
2260
|
+
* `@lunora/config`'s driver registry (`deployTargetIds`) used to assert
|
|
2261
|
+
* equality against this — "two id spaces for one concept" — on the theory that
|
|
2262
|
+
* a target with a matrix but no driver "gates a surface nothing can deploy."
|
|
2263
|
+
* Plan 234 found that reasoning incomplete by registering `node` here: a
|
|
2264
|
+
* codegen-gateable target and a deployable target are genuinely different
|
|
2265
|
+
* questions, and a spike/dev-only host answers the first "yes" and the second
|
|
2266
|
+
* "not yet" without that being a bug in either registry. See
|
|
2267
|
+
* `plans/234-node-host-findings.md` for the finding and `@lunora/config`'s
|
|
2268
|
+
* `project-config.test.ts` for where the now-relaxed invariant lives.
|
|
2269
|
+
* @returns the registered matrix ids, sorted.
|
|
2087
2270
|
*/
|
|
2088
|
-
declare const
|
|
2089
|
-
/**
|
|
2090
|
-
|
|
2271
|
+
declare const platformMatrixIds: () => ReadonlyArray<string>;
|
|
2272
|
+
/** An advisor-style diagnostic about a target's platform capabilities. */
|
|
2273
|
+
interface PlatformDiagnostic {
|
|
2274
|
+
/** The codegen capability this concerns, when it is feature-specific. */
|
|
2275
|
+
feature?: CapabilityKey;
|
|
2276
|
+
/** Severity. All three names are errors — each drops or misdirects an emitted surface. */
|
|
2277
|
+
level: "error" | "warn";
|
|
2278
|
+
/** Human-readable explanation of the gap. */
|
|
2279
|
+
message: string;
|
|
2280
|
+
/** The lint id: `platform_unsupported_feature`, `platform_undeclared_feature`, or `platform_unknown_target`. */
|
|
2281
|
+
name: "platform_undeclared_feature" | "platform_unknown_target" | "platform_unsupported_feature";
|
|
2282
|
+
/** How to resolve it. */
|
|
2283
|
+
remediation: string;
|
|
2284
|
+
/** The requested deploy target. */
|
|
2285
|
+
target: string;
|
|
2286
|
+
}
|
|
2091
2287
|
/**
|
|
2092
|
-
*
|
|
2093
|
-
*
|
|
2094
|
-
*
|
|
2095
|
-
*
|
|
2096
|
-
* any expression since the generated class imports the definition object.
|
|
2097
|
-
*/
|
|
2098
|
-
declare const discoverContainers: (project: Project, lunoraDirectory: string) => ContainerIR[];
|
|
2099
|
-
/**
|
|
2100
|
-
* Scan every `.ts` file under `lunoraDir` for `cronJobs()` builder registrations
|
|
2101
|
-
* (`crons.interval(...)`, `crons.daily(...)`, `crons.cron(...)`, …) and lift them
|
|
2102
|
-
* into {@link CronJobIR}. Schedules are compiled to standard cron expressions;
|
|
2103
|
-
* function references are resolved to their `namespace:fn` dispatch path, while a
|
|
2104
|
-
* `workflows.NAME` / `agents.NAME` reference (or a bare identifier naming a
|
|
2105
|
-
* declared workflow) resolves to a durable workflow start. Names must be unique
|
|
2106
|
-
* across the project.
|
|
2107
|
-
*/
|
|
2108
|
-
declare const discoverCrons: (project: Project, lunoraDirectory: string, workflows?: ReadonlyArray<WorkflowIR>, agents?: ReadonlyArray<AgentIR>) => CronJobIR[];
|
|
2109
|
-
/** The only file a feature-flag provider may be declared in — mirrors `lunora/queues.ts`. */
|
|
2110
|
-
declare const FLAGS_FILENAME = "flags.ts";
|
|
2111
|
-
/**
|
|
2112
|
-
* Discover the feature-flag provider a project declares in `lunora/flags.ts`.
|
|
2113
|
-
* Returns `undefined` when the file doesn't exist (the app has no flags). The
|
|
2114
|
-
* read is metadata-only and lenient: codegen wires `ctx.flags` purely from the
|
|
2115
|
-
* file's *existence* (`run-codegen.ts`) and imports the real module for the
|
|
2116
|
-
* provider value — this IR exists solely so the config layer can reconcile the
|
|
2117
|
-
* wrangler `flagship` binding for the Flagship binding-mode provider. Anything
|
|
2118
|
-
* it can't read statically degrades to a `custom` provider (no binding), never
|
|
2119
|
-
* a thrown error.
|
|
2120
|
-
*/
|
|
2121
|
-
declare const discoverFlags: (project: Project, lunoraDirectory: string) => FlagsIR | undefined;
|
|
2122
|
-
/**
|
|
2123
|
-
* Scan all .ts files under `lunoraDir` (skipping `_generated/` and `schema.ts`)
|
|
2124
|
-
* for top-level `export const x = query/mutation/action({...})` registrations.
|
|
2125
|
-
*/
|
|
2126
|
-
declare const discoverFunctions: (project: Project, lunoraDirectory: string) => FunctionIR[];
|
|
2127
|
-
/**
|
|
2128
|
-
* Scan all `.ts` files under `lunoraDir` (skipping `_generated/` and `schema.ts`)
|
|
2129
|
-
* for `export const x = httpRoute.<verb>(...)…handler(...)` typed REST routes.
|
|
2130
|
-
* These are the headline OpenAPI target: each becomes a real `paths` entry.
|
|
2131
|
-
*/
|
|
2132
|
-
declare const discoverHttpRoutes: (project: Project, lunoraDirectory: string) => HttpRouteIR[];
|
|
2133
|
-
/**
|
|
2134
|
-
* Discover `ctx.db.insert("table", …)` writes under the lunora source directory
|
|
2135
|
-
* and attribute each to the exported function (and file) performing it. Calls
|
|
2136
|
-
* with a non-literal table argument, or outside an exported declaration, are
|
|
2137
|
-
* dropped (`table === ""` / no enclosing export).
|
|
2138
|
-
*/
|
|
2139
|
-
declare const discoverInserts: (project: Project, lunoraDirectory: string) => InsertWriteIR[];
|
|
2140
|
-
/**
|
|
2141
|
-
* Discover masking usage for every exported Lunora procedure under the lunora
|
|
2142
|
-
* source directory — the column-level twin of `discoverRlsProcedures`. For each
|
|
2143
|
-
* procedure, records whether its builder chain includes `.use(mask(...))`, which
|
|
2144
|
-
* `(table, column)` pairs that mask declares, and which tables it reads/writes
|
|
2145
|
-
* through `ctx.db`. Feeds the `mask_uncovered_pii_column` advisor lint.
|
|
2146
|
-
*/
|
|
2147
|
-
declare const discoverMaskProcedures: (project: Project, lunoraDirectory: string) => MaskProcedureIR[];
|
|
2148
|
-
/**
|
|
2149
|
-
* Scan all `.ts` files under `lunoraDir` for top-level
|
|
2150
|
-
* `export const x = defineMigration({...})` declarations and lift them into
|
|
2151
|
-
* {@link MigrationIR}. `id` must be a static string literal (it's the registry
|
|
2152
|
-
* key); `table` is best-effort and left `""` when not a literal.
|
|
2153
|
-
*/
|
|
2154
|
-
declare const discoverMigrations: (project: Project, lunoraDirectory: string) => MigrationIR[];
|
|
2155
|
-
/** The only file custom mutators may be declared in — mirrors `lunora/queues.ts`. */
|
|
2156
|
-
declare const MUTATORS_FILENAME = "mutators.ts";
|
|
2157
|
-
/**
|
|
2158
|
-
* Discover every custom mutator the project declares: exported
|
|
2159
|
-
* `defineMutator()` calls in `lunora/mutators.ts`. Returns `[]` when the file
|
|
2160
|
-
* doesn't exist. The export binding plus the declared `args` / `server` return
|
|
2161
|
-
* type are lifted — enough to emit a typed `api.mutators.<name>` reference —
|
|
2162
|
-
* while the runtime object still carries the authoritative `server` impl +
|
|
2163
|
-
* `handler`, so codegen never evaluates the body. The client `client` impl is
|
|
2164
|
-
* split into the browser bundle separately.
|
|
2165
|
-
*/
|
|
2166
|
-
declare const discoverMutators: (project: Project, lunoraDirectory: string) => MutatorIR[];
|
|
2167
|
-
/**
|
|
2168
|
-
* Discover non-deterministic API calls (`Date.now`, `new Date()`, `Date()`,
|
|
2169
|
-
* `Math.random`, `crypto.randomUUID`, `crypto.getRandomValues` — including
|
|
2170
|
-
* `globalThis`/`self`/`window`-prefixed receivers — and `fetch`) lexically inside
|
|
2171
|
-
* the handler body of every exported `query(...)` / `mutation(...)` registration
|
|
2172
|
-
* under the lunora source directory — the `nondeterministic_query_mutation` lint
|
|
2173
|
-
* input. `action(...)` (and `stream(...)`) registrations are intentionally
|
|
2174
|
-
* skipped: actions run exactly once and may use ambient APIs freely.
|
|
2175
|
-
*
|
|
2176
|
-
* Traversal is scoped to the handler node (not the whole declaration), mirroring
|
|
2177
|
-
* how the auth-api / insert feeders attribute calls — so a call in a sibling
|
|
2178
|
-
* helper outside the handler, or in a nested `action(...)` passed elsewhere, is
|
|
2179
|
-
* not attributed to the query/mutation. One {@link NondeterministicCallIR} is
|
|
2180
|
-
* produced per call site.
|
|
2181
|
-
*/
|
|
2182
|
-
declare const discoverNondeterministicCalls: (project: Project, lunoraDirectory: string) => NondeterministicCallIR[];
|
|
2183
|
-
/** The only file a `@lunora/notify` provider may be declared in — mirrors `lunora/flags.ts`. */
|
|
2184
|
-
declare const NOTIFY_FILENAME = "notify.ts";
|
|
2185
|
-
/**
|
|
2186
|
-
* Discover `ctx.notify` / `ctx.push` sends lexically inside the handler body of
|
|
2187
|
-
* every exported `query(...)` / `mutation(...)` registration under the lunora
|
|
2188
|
-
* source directory — the `notify_send_outside_action` lint input. `action(...)`
|
|
2189
|
-
* (and `stream(...)`) registrations are intentionally skipped: a notification
|
|
2190
|
-
* send is external I/O that belongs in actions. One {@link AdvisorNotifyCall} is
|
|
2191
|
-
* produced per send site.
|
|
2192
|
-
*/
|
|
2193
|
-
declare const discoverNotifyCalls: (project: Project, lunoraDirectory: string) => AdvisorNotifyCall[];
|
|
2194
|
-
/**
|
|
2195
|
-
* Discover which push channels the project's `lunora/notify.ts` default export
|
|
2196
|
-
* (`defineNotify({...})`) wires plus whether any handler sends a push — the
|
|
2197
|
-
* `notify_missing_push_config` lint input. Returns `undefined` when the file is
|
|
2198
|
-
* absent (the app declares no notify config). The read is metadata-only and
|
|
2199
|
-
* lenient (like `discoverFlags`): a `webPush`/`fcm` property's mere presence
|
|
2200
|
-
* counts as the channel being wired; a non-literal config degrades to "unwired"
|
|
2201
|
-
* rather than throwing.
|
|
2202
|
-
*/
|
|
2203
|
-
declare const discoverNotifyConfig: (project: Project, lunoraDirectory: string) => AdvisorNotifyConfig | undefined;
|
|
2204
|
-
/**
|
|
2205
|
-
* Discover `ctx.db.query("table")…` reads under the lunora source directory and
|
|
2206
|
-
* reduce each to a {@link QueryReadIR}. Only reads that call `.filter()` are
|
|
2207
|
-
* returned — an unfiltered read is never a `filter_without_index` candidate, so
|
|
2208
|
-
* dropping the rest keeps the lint input small.
|
|
2288
|
+
* Committed, tracked baseline file holding the blessed structural schema
|
|
2289
|
+
* snapshot the pre-deploy drift gate diffs against. Lives in `lunora/` (NOT the
|
|
2290
|
+
* gitignored `_generated/`) so it is committed alongside `schema.ts`. Leading
|
|
2291
|
+
* dot keeps it tucked away next to the schema it describes.
|
|
2209
2292
|
*/
|
|
2210
|
-
declare const
|
|
2211
|
-
/** The only file queues may be declared in — mirrors `lunora/workflows.ts`. */
|
|
2212
|
-
declare const QUEUES_FILENAME = "queues.ts";
|
|
2293
|
+
declare const SCHEMA_SNAPSHOT_FILENAME = ".lunora-schema.json";
|
|
2213
2294
|
/**
|
|
2214
|
-
*
|
|
2215
|
-
* `
|
|
2216
|
-
*
|
|
2217
|
-
*
|
|
2295
|
+
* Construct the ts-morph `Project` codegen discovers over. Prefers the user's
|
|
2296
|
+
* `tsconfig.json` (when one is found walking up from `lunoraDirectory`) so
|
|
2297
|
+
* cross-file type resolution and path aliases work; falls back to an isolated
|
|
2298
|
+
* project otherwise. This is the exact construction {@link runCodegen} uses
|
|
2299
|
+
* when no `project` is injected — exported so a long-lived caller (the Vite
|
|
2300
|
+
* dev-loop) can build one once and reuse it across runs via
|
|
2301
|
+
* {@link refreshCodegenProject} instead of re-parsing the user's whole TS
|
|
2302
|
+
* program on every save.
|
|
2218
2303
|
*/
|
|
2219
|
-
declare const
|
|
2304
|
+
declare const createCodegenProject: (lunoraDirectory: string) => Project;
|
|
2220
2305
|
/**
|
|
2221
|
-
*
|
|
2222
|
-
*
|
|
2223
|
-
*
|
|
2224
|
-
*
|
|
2225
|
-
*
|
|
2306
|
+
* Synchronise a reused {@link createCodegenProject} Project with the current
|
|
2307
|
+
* on-disk state of `lunoraDirectory`, so the next {@link runCodegen} sees the
|
|
2308
|
+
* same files a freshly-constructed Project would — without re-parsing the whole
|
|
2309
|
+
* TS program. Adds any on-disk source file the Project doesn't yet have, and
|
|
2310
|
+
* `refreshFromFileSystemSync()`es the ones it does (picking up edits); then
|
|
2311
|
+
* removes Project source files under `lunoraDirectory` that no longer exist on
|
|
2312
|
+
* disk (the classic stale-deleted-file cache bug).
|
|
2226
2313
|
*
|
|
2227
|
-
*
|
|
2228
|
-
*
|
|
2229
|
-
*
|
|
2230
|
-
* {@link R2sqlCallIR} is produced per access site.
|
|
2314
|
+
* Files outside `lunoraDirectory` (e.g. those pulled in by the user's tsconfig)
|
|
2315
|
+
* are left untouched — they back type resolution and rarely change in the
|
|
2316
|
+
* dev-loop; a tsconfig change invalidates the whole cached Project upstream.
|
|
2231
2317
|
*/
|
|
2232
|
-
declare const
|
|
2233
|
-
declare const discoverRlsProcedures: (project: Project, lunoraDirectory: string) => RlsProcedureIR[];
|
|
2318
|
+
declare const refreshCodegenProject: (project: Project, lunoraDirectory: string) => void;
|
|
2234
2319
|
/**
|
|
2235
|
-
*
|
|
2236
|
-
*
|
|
2237
|
-
*
|
|
2238
|
-
* {@link discoverRlsProcedures} but extracts the richer `{ on }` operation +
|
|
2239
|
-
* role/permission shape rather than the lint's table-name set.
|
|
2320
|
+
* Top-level codegen entry. Parses `<projectRoot>/lunora/schema.ts` and every
|
|
2321
|
+
* function file under `<projectRoot>/lunora/`, then writes
|
|
2322
|
+
* `_generated/{api,server,dataModel}.ts` next to them.
|
|
2240
2323
|
*
|
|
2241
|
-
*
|
|
2242
|
-
*
|
|
2243
|
-
*
|
|
2244
|
-
*
|
|
2245
|
-
* several procedures lists once.
|
|
2246
|
-
*/
|
|
2247
|
-
declare const discoverRlsMetadata: (project: Project, lunoraDirectory: string) => RlsMetadataIR;
|
|
2248
|
-
/**
|
|
2249
|
-
* Which sandbox tools a project imports from `@lunora/agent` (main entry or the
|
|
2250
|
-
* `/sandbox` subpath), detected by NAMED value import. Drives two things:
|
|
2251
|
-
* registering the `sandbox:invoke` dispatcher (either tool) and provisioning the
|
|
2252
|
-
* `BROWSER` wrangler binding (`browserTool` — the browser op runs on
|
|
2253
|
-
* `ctx.browser` inside the dispatcher).
|
|
2324
|
+
* When `LUNORA_CODEGEN_TIMING` is set (truthy), a single diagnostic summary
|
|
2325
|
+
* line is written to stderr with the total wall time and the discovery-vs-emit
|
|
2326
|
+
* split — opt-in instrumentation that is otherwise zero-cost and side-effect-free
|
|
2327
|
+
* on the returned {@link CodegenResult}.
|
|
2254
2328
|
*/
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2329
|
+
declare const runCodegen: (options: CodegenOptions) => CodegenResult;
|
|
2330
|
+
interface CodegenOptions {
|
|
2331
|
+
/**
|
|
2332
|
+
* Which machine-readable API spec(s) to emit into `_generated/`.
|
|
2333
|
+
*
|
|
2334
|
+
* `"openapi"` (the default) writes only `openapi.json` (OpenAPI 3.1; covers
|
|
2335
|
+
* both the RPC functions and `httpRouter()` REST routes). `"openrpc"` writes
|
|
2336
|
+
* only `openrpc.json` (OpenRPC 1.x; the RPC functions only — OpenRPC cannot
|
|
2337
|
+
* represent REST routes). `"both"` writes both files; `"none"` writes neither.
|
|
2338
|
+
*
|
|
2339
|
+
* Regardless of the choice, `CodegenResult.generated.openApi` and `.openRpc`
|
|
2340
|
+
* always carry the rendered string (computation is cheap and pure); only the
|
|
2341
|
+
* on-disk write is gated by this option.
|
|
2342
|
+
*/
|
|
2343
|
+
apiSpec?: "both" | "none" | "openapi" | "openrpc";
|
|
2344
|
+
/**
|
|
2345
|
+
* When true, run discovery + emit (so any schema/function parse error
|
|
2346
|
+
* surfaces) but skip writing files to `_generated/`. The returned
|
|
2347
|
+
* `outputDirectory` is still the path that *would* have been written.
|
|
2348
|
+
*/
|
|
2349
|
+
dryRun?: boolean;
|
|
2350
|
+
/**
|
|
2351
|
+
* Run the static schema advisor (unindexed FKs, …) during codegen.
|
|
2352
|
+
* Defaults to `true`. When `false`, `CodegenResult.advisories` is empty.
|
|
2353
|
+
* Computed regardless of `dryRun`; codegen never prints them — see
|
|
2354
|
+
* {@link CodegenResult.advisories}.
|
|
2355
|
+
*/
|
|
2356
|
+
lint?: boolean;
|
|
2357
|
+
/** Override the lunora subdirectory name. Defaults to `"lunora"`. */
|
|
2358
|
+
lunoraDirectory?: string;
|
|
2359
|
+
/**
|
|
2360
|
+
* Reuse a previously-constructed ts-morph {@link Project} instead of building
|
|
2361
|
+
* a fresh one each run. The caller owns refreshing its source files from disk
|
|
2362
|
+
* (see {@link refreshCodegenProject}) — codegen does not re-read changed files
|
|
2363
|
+
* off an injected Project. Built via {@link createCodegenProject} when absent.
|
|
2364
|
+
* Used by the Vite dev-loop to avoid re-parsing the whole TS program on every
|
|
2365
|
+
* save; omit it (CLI one-shot path) to get the default fresh-Project behaviour.
|
|
2366
|
+
*/
|
|
2367
|
+
project?: Project;
|
|
2368
|
+
/** Project root containing the `lunora/` directory. */
|
|
2369
|
+
projectRoot: string;
|
|
2370
|
+
/**
|
|
2371
|
+
* The deploy target codegen tailors the emitted `ctx.*` surface to.
|
|
2372
|
+
* Defaults to `"cloudflare"` — whose capability matrix marks every feature
|
|
2373
|
+
* native or emulated, so the default output is unchanged (byte-identical
|
|
2374
|
+
* goldens). A target that marks a used feature unsupported omits its
|
|
2375
|
+
* `ctx.*` surface and reports it in {@link CodegenResult.platformDiagnostics}.
|
|
2376
|
+
* Only `"cloudflare"` is registered until other per-target `@lunora/platform`
|
|
2377
|
+
* matrices land; an unknown target emits the full surface un-gated and a
|
|
2378
|
+
* `platform_unknown_target` diagnostic.
|
|
2379
|
+
*/
|
|
2380
|
+
target?: string;
|
|
2381
|
+
/**
|
|
2382
|
+
* Re-bless the committed schema-drift baseline (`lunora/.lunora-schema.json`)
|
|
2383
|
+
* with the current structural snapshot. The baseline is ALWAYS written on
|
|
2384
|
+
* first capture (when the file is absent); set this to overwrite an existing
|
|
2385
|
+
* one — e.g. after the developer has added the data migration that justifies
|
|
2386
|
+
* a breaking change. Ignored when `dryRun` is true.
|
|
2387
|
+
*/
|
|
2388
|
+
updateSchemaBaseline?: boolean;
|
|
2389
|
+
/**
|
|
2390
|
+
* Committed `wrangler.jsonc` `vars` entries that hold plaintext secrets — the
|
|
2391
|
+
* `plaintext_secret_in_wrangler_vars` lint input. Produced by `@lunora/config`
|
|
2392
|
+
* (which reads `wrangler.jsonc`) and threaded through by the CLI / Vite plugin;
|
|
2393
|
+
* codegen only forwards it to the advisor. Absent when no wrangler config is
|
|
2394
|
+
* present or the caller doesn't scan it.
|
|
2395
|
+
*/
|
|
2396
|
+
wranglerVariables?: ReadonlyArray<WranglerVariableIR>;
|
|
2260
2397
|
}
|
|
2261
|
-
|
|
2398
|
+
interface CodegenResult {
|
|
2399
|
+
/**
|
|
2400
|
+
* The normalized advisor evidence the findings were produced from, so a
|
|
2401
|
+
* caller can score it into a health map (`scoreAdvisor`) without re-running
|
|
2402
|
+
* discovery. `undefined` under `lint: false`.
|
|
2403
|
+
*
|
|
2404
|
+
* Deliberately not scored here: the map carries a `generatedAt` stamp, and
|
|
2405
|
+
* codegen's result stays a pure function of the sources.
|
|
2406
|
+
*/
|
|
2407
|
+
advisorContext?: LintContext;
|
|
2408
|
+
/**
|
|
2409
|
+
* Static schema advisor findings (e.g. unindexed foreign keys) produced
|
|
2410
|
+
* this run. Empty when `lint` is `false` or the schema is clean. Codegen
|
|
2411
|
+
* does not print these itself — each caller presents them through its own
|
|
2412
|
+
* channel (the CLI logger, the vite overlay, the studio Advisors table).
|
|
2413
|
+
* `formatAdvisories` is exported for a plain multi-line rendering.
|
|
2414
|
+
*/
|
|
2415
|
+
advisories: ReadonlyArray<Finding>;
|
|
2416
|
+
/**
|
|
2417
|
+
* Agents discovered from `defineAgent` exports in `lunora/agents.ts` — the
|
|
2418
|
+
* list the config layer reconciles into wrangler's `workflows[]` array (an
|
|
2419
|
+
* agent compiles onto a Cloudflare Workflow). Agents are NOT Durable Objects,
|
|
2420
|
+
* so this adds no binding or migration. Empty when the project declares none.
|
|
2421
|
+
*/
|
|
2422
|
+
agents: ReadonlyArray<AgentIR>;
|
|
2423
|
+
/**
|
|
2424
|
+
* Containers discovered from `defineContainer` exports in
|
|
2425
|
+
* `lunora/containers.ts` — the list the config layer reconciles into
|
|
2426
|
+
* wrangler's `containers[]`, `CONTAINER_*` Durable Object bindings, and
|
|
2427
|
+
* migration classes. Empty when the project declares no containers.
|
|
2428
|
+
*/
|
|
2429
|
+
containers: ReadonlyArray<ContainerIR>;
|
|
2430
|
+
/**
|
|
2431
|
+
* Deduplicated cron schedules discovered from `cronJobs()` definitions —
|
|
2432
|
+
* the array the vite plugin reconciles into `wrangler.jsonc`'s
|
|
2433
|
+
* `triggers.crons`. Empty when the project declares no crons.
|
|
2434
|
+
*/
|
|
2435
|
+
cronTriggers: ReadonlyArray<string>;
|
|
2436
|
+
generated: {
|
|
2437
|
+
/** WorkflowEntrypoint classes for declared agents (`_generated/agents.ts`); `""` (and not written) when no agents are declared. */
|
|
2438
|
+
agents: string;
|
|
2439
|
+
api: string;
|
|
2440
|
+
/** Fluent worker-composition builder (`_generated/app.ts`) — `defineApp()`. Always written. */
|
|
2441
|
+
app: string;
|
|
2442
|
+
/** Partial-replication collection factories (`_generated/collections.ts`); `""` (and not written) unless the project declares shapes and installs `@lunora/db`. */
|
|
2443
|
+
collections: string;
|
|
2444
|
+
/** Container DO classes (`_generated/containers.ts`); `""` (and not written) when no containers are declared. */
|
|
2445
|
+
containers: string;
|
|
2446
|
+
crons: string;
|
|
2447
|
+
dataModel: string;
|
|
2448
|
+
drizzleGlobal: string;
|
|
2449
|
+
drizzleShard: string;
|
|
2450
|
+
functions: string;
|
|
2451
|
+
/** OpenAPI 3.1.0 document (`_generated/openapi.json`), pretty-printed JSON. */
|
|
2452
|
+
openApi: string;
|
|
2453
|
+
/**
|
|
2454
|
+
* OpenAPI document as an importable TS module (`_generated/openapi.ts`) —
|
|
2455
|
+
* `export const openApiSpec`, the worker imports it for
|
|
2456
|
+
* `createWorker({ openApiSpec })`. Same document as `openApi`. Written
|
|
2457
|
+
* alongside `openapi.json` whenever `apiSpec` includes `openapi`.
|
|
2458
|
+
*/
|
|
2459
|
+
openApiModule: string;
|
|
2460
|
+
/** OpenRPC 1.x document (`_generated/openrpc.json`), pretty-printed JSON. Always computed; written only when `apiSpec` includes `openrpc`. */
|
|
2461
|
+
openRpc: string;
|
|
2462
|
+
/**
|
|
2463
|
+
* OpenRPC document as an importable TS module (`_generated/openrpc.ts`) —
|
|
2464
|
+
* `export const openRpcSpec`, for `createWorker({ openRpcSpec })`. Same
|
|
2465
|
+
* document as `openRpc`. Written alongside `openrpc.json` whenever
|
|
2466
|
+
* `apiSpec` includes `openrpc`.
|
|
2467
|
+
*/
|
|
2468
|
+
openRpcModule: string;
|
|
2469
|
+
/** Push-consumer queue registry (`_generated/queues.ts`); `""` (and not written) when no push queues are declared. */
|
|
2470
|
+
queues: string;
|
|
2471
|
+
/** Project-bound seed client (`_generated/seed.ts`); `""` (and not written) when `@lunora/seed` is not a declared dependency. */
|
|
2472
|
+
seed: string;
|
|
2473
|
+
server: string;
|
|
2474
|
+
shard: string;
|
|
2475
|
+
/** Static vector-index registry (`_generated/vectors.ts`) — `LUNORA_VECTOR_INDEXES`. Empty array body when the schema declares none. */
|
|
2476
|
+
vectors: string;
|
|
2477
|
+
/** WorkflowEntrypoint classes (`_generated/workflows.ts`); `""` (and not written) when no workflows are declared. */
|
|
2478
|
+
workflows: string;
|
|
2479
|
+
};
|
|
2480
|
+
outputDirectory: string;
|
|
2481
|
+
/**
|
|
2482
|
+
* Portability diagnostics for the requested {@link CodegenOptions.target}:
|
|
2483
|
+
* `ctx.*` features the app uses that the target does not support (omitted
|
|
2484
|
+
* from the emitted surface), or an unknown target. Empty for a
|
|
2485
|
+
* fully-supported app on the default Cloudflare target. Presentation is the
|
|
2486
|
+
* caller's job, like {@link CodegenResult.advisories}.
|
|
2487
|
+
*/
|
|
2488
|
+
platformDiagnostics: ReadonlyArray<PlatformDiagnostic>;
|
|
2489
|
+
/**
|
|
2490
|
+
* Queues discovered from `defineQueue` exports in `lunora/queues.ts` — the
|
|
2491
|
+
* list the config layer reconciles into wrangler's `queues.producers[]` /
|
|
2492
|
+
* `queues.consumers[]`. Queues are NOT Durable Objects, so this adds no
|
|
2493
|
+
* binding or migration. Empty when the project declares no queues.
|
|
2494
|
+
*/
|
|
2495
|
+
queues: ReadonlyArray<QueueIR>;
|
|
2496
|
+
/**
|
|
2497
|
+
* The CURRENT structural schema snapshot computed this run (tables + field
|
|
2498
|
+
* kinds/optionality + indexes/relations/shard mode + declared migration ids).
|
|
2499
|
+
* The pre-deploy drift gate diffs this against the committed baseline read
|
|
2500
|
+
* from {@link CodegenResult.schemaSnapshotPath}. Always present, even on a
|
|
2501
|
+
* `dryRun`.
|
|
2502
|
+
*/
|
|
2503
|
+
schemaSnapshot: SchemaSnapshot;
|
|
2504
|
+
/** Absolute path of the committed baseline file (`lunora/.lunora-schema.json`). */
|
|
2505
|
+
schemaSnapshotPath: string;
|
|
2506
|
+
/**
|
|
2507
|
+
* Workflows discovered from `defineWorkflow` exports in
|
|
2508
|
+
* `lunora/workflows.ts` — the list the config layer reconciles into
|
|
2509
|
+
* wrangler's `workflows[]` array. Workflows are NOT Durable Objects, so this
|
|
2510
|
+
* adds no binding or migration. Empty when the project declares no workflows.
|
|
2511
|
+
*/
|
|
2512
|
+
workflows: ReadonlyArray<WorkflowIR>;
|
|
2513
|
+
}
|
|
2514
|
+
/** Deduplicated, sorted names of every ERROR-level advisory in `advisories`. */
|
|
2515
|
+
declare const errorAdvisoryNames: (advisories: ReadonlyArray<Pick<Finding, "level" | "name">>) => ReadonlyArray<string>;
|
|
2516
|
+
/** Deduplicated, sorted names of every error-level platform diagnostic in `platformDiagnostics`. */
|
|
2517
|
+
declare const errorPlatformDiagnosticNames: (platformDiagnostics: ReadonlyArray<Pick<PlatformDiagnostic, "level" | "name">>) => ReadonlyArray<string>;
|
|
2262
2518
|
/**
|
|
2263
|
-
*
|
|
2264
|
-
*
|
|
2519
|
+
* Convenience read combining both categories from a full {@link CodegenResult}
|
|
2520
|
+
* — the shape the Vite plugin's `buildBlockingMessage` needs, which (unlike
|
|
2521
|
+
* the CLI's `lunora codegen`/`lunora deploy`) folds ERROR-level advisories and
|
|
2522
|
+
* platform diagnostics into a single blocking message with no strict/CI
|
|
2523
|
+
* opt-out.
|
|
2265
2524
|
*/
|
|
2266
|
-
declare const
|
|
2267
|
-
|
|
2268
|
-
|
|
2525
|
+
declare const describeErrorLevelFindings: (result: Pick<CodegenResult, "advisories" | "platformDiagnostics">) => {
|
|
2526
|
+
advisoryNames: ReadonlyArray<string>;
|
|
2527
|
+
platformDiagnosticNames: ReadonlyArray<string>;
|
|
2528
|
+
};
|
|
2269
2529
|
/**
|
|
2270
|
-
*
|
|
2271
|
-
*
|
|
2272
|
-
*
|
|
2273
|
-
*
|
|
2274
|
-
*
|
|
2530
|
+
* An error thrown by codegen discovery when the user's schema or function
|
|
2531
|
+
* source has a structural problem that can be pinpointed to a specific source
|
|
2532
|
+
* location. A `LunoraError` subclass (`code: "CODEGEN_DIAGNOSTIC"`); the `file`,
|
|
2533
|
+
* `line`, and `column` properties (also passed through as the base `loc`) mirror
|
|
2534
|
+
* what Vite's error-overlay `loc` field expects so the browser can display the
|
|
2535
|
+
* exact spot.
|
|
2275
2536
|
*/
|
|
2276
|
-
declare
|
|
2537
|
+
declare class CodegenDiagnosticError extends LunoraError {
|
|
2538
|
+
readonly column: number;
|
|
2539
|
+
readonly file: string;
|
|
2540
|
+
readonly line: number;
|
|
2541
|
+
constructor(message: string, file: string, line: number, column: number);
|
|
2542
|
+
}
|
|
2277
2543
|
/**
|
|
2278
|
-
*
|
|
2279
|
-
*
|
|
2280
|
-
*
|
|
2281
|
-
*
|
|
2544
|
+
* Build a {@link CodegenDiagnosticError} whose message includes the source
|
|
2545
|
+
* location and whose `file`/`line`/`column` properties are set from the
|
|
2546
|
+
* ts-morph `Node`'s position in its source file.
|
|
2547
|
+
*
|
|
2548
|
+
* Message format: `@lunora/codegen: <detail> (<file>:<line>:<column>)`
|
|
2549
|
+
*
|
|
2550
|
+
* `meta` is merged onto the returned error for callers that also carry the
|
|
2551
|
+
* project-wide `LunoraError` envelope (`code`/`name`/`status`) — it never
|
|
2552
|
+
* touches `file`/`line`/`column`, and the error stays an instance of
|
|
2553
|
+
* {@link CodegenDiagnosticError} so the Vite overlay's `instanceof` location
|
|
2554
|
+
* lookup is unaffected.
|
|
2282
2555
|
*/
|
|
2283
|
-
declare const
|
|
2284
|
-
/** The only file
|
|
2285
|
-
declare const
|
|
2556
|
+
declare const diagnosticAt: (node: Node, detail: string, meta?: Record<string, unknown>) => CodegenDiagnosticError;
|
|
2557
|
+
/** The only file agents may be declared in — mirrors `lunora/workflows.ts`. */
|
|
2558
|
+
declare const AGENTS_FILENAME = "agents.ts";
|
|
2286
2559
|
/**
|
|
2287
|
-
* Discover every
|
|
2288
|
-
*
|
|
2289
|
-
*
|
|
2290
|
-
*
|
|
2560
|
+
* Discover every agent the project declares: exported `defineAgent()` calls in
|
|
2561
|
+
* `lunora/agents.ts`. Returns `[]` when the file doesn't exist. Only four things
|
|
2562
|
+
* are read statically — the optional `name` override (wrangler `workflows[].name`),
|
|
2563
|
+
* the optional `publicRun` opt-in (the `agents:agentRun` capability gate), the
|
|
2564
|
+
* presence of a `voice` block (which turns on the voice-session Durable Object),
|
|
2565
|
+
* and the presence of an `onEmail` mapper (which wires the worker `email()`
|
|
2566
|
+
* handler); the rest of the agent config (model / tools / memory / voice models /
|
|
2567
|
+
* the `onEmail` closure body) is runtime-only, so codegen never evaluates it.
|
|
2291
2568
|
*/
|
|
2292
|
-
declare const
|
|
2293
|
-
declare const GENERATED_HEADER = "// GENERATED by @lunora/codegen — do not edit.\n// Run `lunora codegen` to regenerate.\n\n";
|
|
2294
|
-
/** Emit `_generated/dataModel.ts` — `Doc<"name">` + `Id<"name">` for every table. */
|
|
2295
|
-
declare const emitDataModel: (schema: SchemaIR, useUmbrella?: boolean) => string;
|
|
2569
|
+
declare const discoverAgents: (project: Project, lunoraDirectory: string) => AgentIR[];
|
|
2296
2570
|
/**
|
|
2297
|
-
*
|
|
2298
|
-
*
|
|
2299
|
-
*
|
|
2300
|
-
* at runtime (the `__lunoraRef` is identical); visibility is enforced
|
|
2301
|
-
* server-side at dispatch, not in the reference. Splitting the *types* keeps
|
|
2302
|
-
* internal functions off the client-facing `api` surface.
|
|
2571
|
+
* Discover `ctx.authApi.<method>(...)` (and bare `authApi.<method>(...)`) calls
|
|
2572
|
+
* under the lunora source directory and attribute each to the exported function
|
|
2573
|
+
* (and file) performing it. Calls outside an exported declaration are dropped.
|
|
2303
2574
|
*/
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
/** Typed REST routes; only `.stream()` (SSE) routes emit a `httpStreams.*` reference. */
|
|
2308
|
-
httpRoutes?: ReadonlyArray<HttpRouteIR>;
|
|
2309
|
-
/** Custom mutators (`lunora/mutators.ts`) — emitted as `api.mutators.*` so a client `serverRef` is compile-checked. */
|
|
2310
|
-
mutators?: ReadonlyArray<MutatorIR>;
|
|
2311
|
-
useUmbrella?: boolean;
|
|
2312
|
-
workflows?: ReadonlyArray<WorkflowIR>;
|
|
2313
|
-
}
|
|
2314
|
-
declare const emitApi: (options: EmitApiOptions) => string;
|
|
2575
|
+
declare const discoverAuthApiCalls: (project: Project, lunoraDirectory: string) => AuthApiCallIR[];
|
|
2576
|
+
/** The only file containers may be declared in — mirrors `lunora/crons.ts`. */
|
|
2577
|
+
declare const CONTAINERS_FILENAME = "containers.ts";
|
|
2315
2578
|
/**
|
|
2316
|
-
*
|
|
2317
|
-
* in `lunora/
|
|
2318
|
-
*
|
|
2319
|
-
*
|
|
2320
|
-
*
|
|
2321
|
-
* `<shape>CollectionOptions(options)` is the composable form: it returns the full
|
|
2322
|
-
* `LunoraCollectionOptions` — `config` for `createCollection`, plus `checkpoints`
|
|
2323
|
-
* (which `bindMutators` gates optimistic overlays on) and `scope`. This is what an app
|
|
2324
|
-
* with custom mutators needs, and what the old single-factory form made impossible: it
|
|
2325
|
-
* built the collection internally and dropped `checkpoints` on the floor, so there was
|
|
2326
|
-
* no way to wire mutators to the collection codegen produced.
|
|
2327
|
-
*
|
|
2328
|
-
* `<shape>Collection(options)` is the convenience form for a read-only collection: it
|
|
2329
|
-
* returns `{ checkpoints, collection, scope }` rather than a bare `Collection`, so the
|
|
2330
|
-
* sync controls stay reachable even from the short path.
|
|
2331
|
-
*
|
|
2332
|
-
* Both are typed: `args` comes from the shape's own validators (a parameterless
|
|
2333
|
-
* shape takes none), rows resolve to `Doc<"table">` when the shape names its table
|
|
2334
|
-
* with a literal, and `shardKey` / `getKey` / `load` / `onError` / `checkpoints` are
|
|
2335
|
-
* all threadable — a sharded table needs `shardKey` for its watermark to land in the
|
|
2336
|
-
* right bucket, and a server-minted `_id` that differs from the app's natural key
|
|
2337
|
-
* needs `getKey`.
|
|
2338
|
-
*
|
|
2339
|
-
* Returns `""` (so `writeIfPresent` skips the file) unless the project both
|
|
2340
|
-
* declares shapes AND installs `@lunora/db` — the add-on that ships
|
|
2341
|
-
* `lunoraCollectionOptions`. `@lunora/db` stays a scoped install even under the
|
|
2342
|
-
* `lunorash` umbrella (an opt-in add-on, like `@lunora/auth`), so its import is
|
|
2343
|
-
* always `@lunora/db/collections`; only the in-umbrella `@lunora/client` import
|
|
2344
|
-
* is remapped to `lunorash/client`.
|
|
2579
|
+
* Discover every container the project declares: exported `defineContainer()`
|
|
2580
|
+
* calls in `lunora/containers.ts`. Returns `[]` when the file doesn't exist.
|
|
2581
|
+
* Wrangler-relevant fields (`image`, `instanceType`, `maxInstances`, `name`)
|
|
2582
|
+
* must be static literals; runtime-only fields (`env`, `sleepAfter`, …) may be
|
|
2583
|
+
* any expression since the generated class imports the definition object.
|
|
2345
2584
|
*/
|
|
2346
|
-
declare const
|
|
2347
|
-
interface EmitServerOptions {
|
|
2348
|
-
/** Agents declared via `defineAgent` exports — wires the typed `ctx.agents` producers onto Mutation/Action contexts. */
|
|
2349
|
-
agents?: ReadonlyArray<AgentIR>;
|
|
2350
|
-
containers?: ReadonlyArray<ContainerIR>;
|
|
2351
|
-
/**
|
|
2352
|
-
* The single `defineEnv(...)` contract declared in `lunora/env.ts`. When
|
|
2353
|
-
* present, `ctx.env` is typed as the validated `InferEnv` shape (recovered
|
|
2354
|
-
* via `ReturnType` over the accessor's `typeof`). `undefined` leaves `ctx.env`
|
|
2355
|
-
* the base optional binding record — byte-identical to today.
|
|
2356
|
-
*/
|
|
2357
|
-
env?: EnvIR;
|
|
2358
|
-
/**
|
|
2359
|
-
* A `lunora/` source reads `ctx.access` — wires the verified Cloudflare Access
|
|
2360
|
-
* facade (`@lunora/cloudflare-access/context`) onto every ctx. Distinct from
|
|
2361
|
-
* `emitApp`'s `hasAccess` (which gates the worker's `.access()` resolveIdentity
|
|
2362
|
-
* method); this one gates the per-request `ctx.access` read surface.
|
|
2363
|
-
*/
|
|
2364
|
-
hasAccessFacade?: boolean;
|
|
2365
|
-
hasAi?: boolean;
|
|
2366
|
-
/** A `lunora/` source uses `@lunora/bindings/analytics` / `ctx.analytics` — wires the write helper onto every ctx. */
|
|
2367
|
-
hasAnalytics?: boolean;
|
|
2368
|
-
/** A `lunora/` source uses `@lunora/browser` / `ctx.browser` — wires `ctx.browser` onto ActionCtx only. */
|
|
2369
|
-
hasBrowser?: boolean;
|
|
2370
|
-
/** The project declares `lunora/flags.ts` — wires `ctx.flags` (OpenFeature) onto every ctx. */
|
|
2371
|
-
hasFlags?: boolean;
|
|
2372
|
-
/** A `lunora/` source uses `@lunora/hyperdrive` / `ctx.sql` — wires `ctx.sql` onto ActionCtx only. */
|
|
2373
|
-
hasHyperdrive?: boolean;
|
|
2374
|
-
/** A `lunora/` source uses `@lunora/bindings/images` / `ctx.images` — wires `ctx.images` onto ActionCtx only. */
|
|
2375
|
-
hasImages?: boolean;
|
|
2376
|
-
/** A `lunora/` source uses `@lunora/bindings/kv` / `ctx.kv` — wires `ctx.kv` onto every ctx. */
|
|
2377
|
-
hasKv?: boolean;
|
|
2378
|
-
/** The project declares `lunora/notify.ts` — wires `ctx.notify` + its `ctx.push` alias (`@lunora/notify`) onto every ctx. */
|
|
2379
|
-
hasNotify?: boolean;
|
|
2380
|
-
hasPayments?: boolean;
|
|
2381
|
-
/** A `lunora/` source uses `@lunora/bindings/pipelines` / `ctx.pipelines` — wires `ctx.pipelines` onto ActionCtx only. */
|
|
2382
|
-
hasPipelines?: boolean;
|
|
2383
|
-
/** A `lunora/` source uses `@lunora/bindings/r2sql` / `ctx.r2sql` — wires `ctx.r2sql` onto ActionCtx only. */
|
|
2384
|
-
hasR2sql?: boolean;
|
|
2385
|
-
/** A `lunora/` source uses `@lunora/x402/pay` / `ctx.x402` — wires the agent-wallet pay rail onto ActionCtx only. */
|
|
2386
|
-
hasX402?: boolean;
|
|
2387
|
-
/**
|
|
2388
|
-
* The single `defineIdentity(...)` claim contract declared in
|
|
2389
|
-
* `lunora/identity.ts` (Plan 080). When present, `ctx.auth.getIdentity()`,
|
|
2390
|
-
* the RLS policy `ctx.auth.identity`, and the shard-authorization hooks
|
|
2391
|
-
* narrow to the declared shape (recovered via `InferIdentity` over the
|
|
2392
|
-
* contract's `typeof`). `undefined` keeps the identity an untyped bag —
|
|
2393
|
-
* byte-identical to today.
|
|
2394
|
-
*/
|
|
2395
|
-
identity?: IdentityIR;
|
|
2396
|
-
/** Queues declared via `defineQueue` exports — wires the typed `ctx.queues` producers onto Mutation/Action contexts. */
|
|
2397
|
-
queues?: ReadonlyArray<QueueIR>;
|
|
2398
|
-
schema?: SchemaIR;
|
|
2399
|
-
storageRuleBuckets?: ReadonlyArray<string>;
|
|
2400
|
-
/** The project depends on the `lunora` umbrella — import base packages via its subpaths. */
|
|
2401
|
-
useUmbrella?: boolean;
|
|
2402
|
-
workflows?: ReadonlyArray<WorkflowIR>;
|
|
2403
|
-
}
|
|
2404
|
-
declare const emitServer: ({ agents, containers, env, hasAccessFacade, hasAi, hasAnalytics, hasBrowser, hasFlags, hasHyperdrive, hasImages, hasKv, hasNotify, hasPayments, hasPipelines, hasR2sql, hasX402, identity, queues, schema, storageRuleBuckets, useUmbrella, workflows }?: EmitServerOptions) => string;
|
|
2405
|
-
interface EmitFunctionsOptions {
|
|
2406
|
-
agents?: ReadonlyArray<AgentIR>;
|
|
2407
|
-
functions: ReadonlyArray<FunctionIR>;
|
|
2408
|
-
migrations?: ReadonlyArray<MigrationIR>;
|
|
2409
|
-
mutators?: ReadonlyArray<MutatorIR>;
|
|
2410
|
-
shapes?: ReadonlyArray<ShapeIR>;
|
|
2411
|
-
/** Import of a sandbox tool (`browserTool`/`containerTool`) auto-registers the `sandbox:invoke` action. */
|
|
2412
|
-
usesSandbox?: boolean;
|
|
2413
|
-
useUmbrella?: boolean;
|
|
2414
|
-
}
|
|
2415
|
-
declare const emitFunctions: (options: EmitFunctionsOptions) => string;
|
|
2585
|
+
declare const discoverContainers: (project: Project, lunoraDirectory: string) => ContainerIR[];
|
|
2416
2586
|
/**
|
|
2417
|
-
*
|
|
2418
|
-
*
|
|
2419
|
-
*
|
|
2420
|
-
*
|
|
2421
|
-
* `
|
|
2422
|
-
*
|
|
2587
|
+
* Scan every `.ts` file under `lunoraDir` for `cronJobs()` builder registrations
|
|
2588
|
+
* (`crons.interval(...)`, `crons.daily(...)`, `crons.cron(...)`, …) and lift them
|
|
2589
|
+
* into {@link CronJobIR}. Schedules are compiled to standard cron expressions;
|
|
2590
|
+
* function references are resolved to their `namespace:fn` dispatch path, while a
|
|
2591
|
+
* `workflows.NAME` / `agents.NAME` reference (or a bare identifier naming a
|
|
2592
|
+
* declared workflow) resolves to a durable workflow start. Names must be unique
|
|
2593
|
+
* across the project.
|
|
2423
2594
|
*/
|
|
2424
|
-
declare const
|
|
2595
|
+
declare const discoverCrons: (project: Project, lunoraDirectory: string, workflows?: ReadonlyArray<WorkflowIR>, agents?: ReadonlyArray<AgentIR>) => CronJobIR[];
|
|
2596
|
+
/** The only file a feature-flag provider may be declared in — mirrors `lunora/queues.ts`. */
|
|
2597
|
+
declare const FLAGS_FILENAME = "flags.ts";
|
|
2425
2598
|
/**
|
|
2426
|
-
*
|
|
2427
|
-
* `
|
|
2428
|
-
*
|
|
2429
|
-
*
|
|
2430
|
-
*
|
|
2431
|
-
*
|
|
2599
|
+
* Discover the feature-flag provider a project declares in `lunora/flags.ts`.
|
|
2600
|
+
* Returns `undefined` when the file doesn't exist (the app has no flags). The
|
|
2601
|
+
* read is metadata-only and lenient: codegen wires `ctx.flags` purely from the
|
|
2602
|
+
* file's *existence* (`run-codegen.ts`) and imports the real module for the
|
|
2603
|
+
* provider value — this IR exists solely so the config layer can reconcile the
|
|
2604
|
+
* wrangler `flagship` binding for the Flagship binding-mode provider. Anything
|
|
2605
|
+
* it can't read statically degrades to a `custom` provider (no binding), never
|
|
2606
|
+
* a thrown error.
|
|
2432
2607
|
*/
|
|
2433
|
-
declare const
|
|
2608
|
+
declare const discoverFlags: (project: Project, lunoraDirectory: string) => FlagsIR | undefined;
|
|
2434
2609
|
/**
|
|
2435
|
-
*
|
|
2436
|
-
*
|
|
2437
|
-
* constructed with the compiled agent tool-loop (`compileAgentWorkflow`). Like
|
|
2438
|
-
* `_generated/workflows.ts`, the worker entry must re-export these classes:
|
|
2439
|
-
* wrangler requires every `workflows[].class_name` to be exported by the
|
|
2440
|
-
* deployed worker. Returns "" when the project declares no agents (the file is
|
|
2441
|
-
* not written then).
|
|
2610
|
+
* Scan all .ts files under `lunoraDir` (skipping `_generated/` and `schema.ts`)
|
|
2611
|
+
* for top-level `export const x = query/mutation/action({...})` registrations.
|
|
2442
2612
|
*/
|
|
2443
|
-
declare const
|
|
2444
|
-
interface EmitShardOptions {
|
|
2445
|
-
advisories?: ReadonlyArray<Finding>;
|
|
2446
|
-
/** Every declared procedure — the health map's denominator, served via `getAdvisorProcedures`. */
|
|
2447
|
-
advisorProcedures?: ReadonlyArray<AdvisorProcedureProtection>;
|
|
2448
|
-
/** Agents declared via `defineAgent` exports in `lunora/agents.ts` — wires the typed `ctx.agents` producers. */
|
|
2449
|
-
agents?: ReadonlyArray<AgentIR>;
|
|
2450
|
-
containers?: ReadonlyArray<ContainerIR>;
|
|
2451
|
-
/** The single `defineEnv(...)` contract declared in `lunora/env.ts` — applies the accessor to the worker `env` to populate `ctx.env`. */
|
|
2452
|
-
env?: EnvIR;
|
|
2453
|
-
/** Statically-discovered `ctx.flags.<type>("key")` reads — the studio Flags page + reactive evaluation iterate these. */
|
|
2454
|
-
flagKeys?: ReadonlyArray<{
|
|
2455
|
-
key: string;
|
|
2456
|
-
type: "boolean" | "number" | "object" | "string";
|
|
2457
|
-
}>;
|
|
2458
|
-
/** A `lunora/` source reads `ctx.access` — wires the verified Cloudflare Access facade onto every ctx. */
|
|
2459
|
-
hasAccessFacade?: boolean;
|
|
2460
|
-
hasAi?: boolean;
|
|
2461
|
-
/** A `lunora/` source reads `ctx.analytics` — wires the Analytics Engine write helper onto every ctx. */
|
|
2462
|
-
hasAnalytics?: boolean;
|
|
2463
|
-
/** A `lunora/` source reads `ctx.browser` — wires `ctx.browser` onto the ActionCtx only. */
|
|
2464
|
-
hasBrowser?: boolean;
|
|
2465
|
-
/** The project declares `lunora/flags.ts` — wires `ctx.flags` (OpenFeature) onto every ctx. */
|
|
2466
|
-
hasFlags?: boolean;
|
|
2467
|
-
/** A `lunora/` source reads `ctx.sql` (Hyperdrive) — wires `ctx.sql` onto the ActionCtx only. */
|
|
2468
|
-
hasHyperdrive?: boolean;
|
|
2469
|
-
/** A `lunora/` source reads `ctx.images` — wires `ctx.images` onto the ActionCtx only. */
|
|
2470
|
-
hasImages?: boolean;
|
|
2471
|
-
/** A `lunora/` source reads `ctx.kv` — wires `ctx.kv` onto every ctx. */
|
|
2472
|
-
hasKv?: boolean;
|
|
2473
|
-
/** The project declares `lunora/notify.ts` — wires `ctx.notify` + its `ctx.push` alias (`@lunora/notify`) onto every ctx. */
|
|
2474
|
-
hasNotify?: boolean;
|
|
2475
|
-
hasPayments?: boolean;
|
|
2476
|
-
/** A `lunora/` source reads `ctx.pipelines` — wires `ctx.pipelines` onto the ActionCtx only. */
|
|
2477
|
-
hasPipelines?: boolean;
|
|
2478
|
-
/** A `lunora/` source reads `ctx.r2sql` (R2 SQL) — wires `ctx.r2sql` onto the ActionCtx only. */
|
|
2479
|
-
hasR2sql?: boolean;
|
|
2480
|
-
/** A `lunora/` source reads `ctx.x402` — wires the agent-wallet pay rail onto the ActionCtx only. */
|
|
2481
|
-
hasX402?: boolean;
|
|
2482
|
-
maskMetadata?: MaskMetadataIR;
|
|
2483
|
-
/** Custom mutators declared via `defineMutator` in `lunora/mutators.ts` — wires the `isCustomMutator` push-protocol override. */
|
|
2484
|
-
mutators?: ReadonlyArray<MutatorIR>;
|
|
2485
|
-
/** Queues declared via `defineQueue` exports in `lunora/queues.ts` — wires the typed `ctx.queues` producers. */
|
|
2486
|
-
queues?: ReadonlyArray<QueueIR>;
|
|
2487
|
-
rlsMetadata?: RlsMetadataIR;
|
|
2488
|
-
schema: SchemaIR;
|
|
2489
|
-
/**
|
|
2490
|
-
* The structural snapshot the pre-deploy drift gate diffs against, threaded
|
|
2491
|
-
* in so the emitted DO records it in `__lunora_schema_history` on cold start
|
|
2492
|
-
* (plan 200 — the Studio's schema-version timeline). Optional so an emitter
|
|
2493
|
-
* caller that has no snapshot (tests, fixtures) emits the pre-ledger shape
|
|
2494
|
-
* unchanged.
|
|
2495
|
-
*/
|
|
2496
|
-
schemaSnapshot?: SchemaSnapshot;
|
|
2497
|
-
/** Replication shapes declared via `defineShape` in `lunora/shapes.ts` — wires the `resolveShape` subscription override. */
|
|
2498
|
-
shapes?: ReadonlyArray<ShapeIR>;
|
|
2499
|
-
storageRules?: StorageRulesMetadataIR;
|
|
2500
|
-
studioFeatures?: StudioFeaturesResult;
|
|
2501
|
-
/** The project depends on the `lunora` umbrella — import base packages via its subpaths. */
|
|
2502
|
-
useUmbrella?: boolean;
|
|
2503
|
-
workflows?: ReadonlyArray<WorkflowIR>;
|
|
2504
|
-
}
|
|
2505
|
-
declare const emitShard: ({ advisories, advisorProcedures, agents, containers, env, flagKeys, hasAccessFacade, hasAi, hasAnalytics, hasBrowser, hasFlags, hasHyperdrive, hasImages, hasKv, hasNotify, hasPayments, hasPipelines, hasR2sql, hasX402, maskMetadata, mutators, queues, rlsMetadata, schema, schemaSnapshot, shapes, storageRules, studioFeatures, useUmbrella, workflows }: EmitShardOptions) => string;
|
|
2613
|
+
declare const discoverFunctions: (project: Project, lunoraDirectory: string) => FunctionIR[];
|
|
2506
2614
|
/**
|
|
2507
|
-
*
|
|
2508
|
-
* `
|
|
2509
|
-
*
|
|
2510
|
-
* goes in the shard file.
|
|
2511
|
-
*
|
|
2512
|
-
* `searchIndexes` are intentionally not emitted — drizzle has no `sqliteTable`
|
|
2513
|
-
* abstraction for FTS5 virtual tables. FTS plumbing is handled by the runtime
|
|
2514
|
-
* outside of drizzle.
|
|
2615
|
+
* Scan all `.ts` files under `lunoraDir` (skipping `_generated/` and `schema.ts`)
|
|
2616
|
+
* for `export const x = httpRoute.<verb>(...)…handler(...)` typed REST routes.
|
|
2617
|
+
* These are the headline OpenAPI target: each becomes a real `paths` entry.
|
|
2515
2618
|
*/
|
|
2516
|
-
declare const
|
|
2517
|
-
global: string;
|
|
2518
|
-
shard: string;
|
|
2519
|
-
};
|
|
2619
|
+
declare const discoverHttpRoutes: (project: Project, lunoraDirectory: string) => HttpRouteIR[];
|
|
2520
2620
|
/**
|
|
2521
|
-
*
|
|
2522
|
-
*
|
|
2523
|
-
*
|
|
2524
|
-
*
|
|
2525
|
-
* `wrangler.jsonc`, and {@link emitWranglerCronTriggers} renders the same list
|
|
2526
|
-
* for the CLI / docs).
|
|
2527
|
-
*
|
|
2528
|
-
* `LUNORA_CRONS` is the dispatcher map keyed by cron expression, each value a
|
|
2529
|
-
* list of `{ name, functionPath, args }`. Cloudflare's `scheduled()` handler
|
|
2530
|
-
* receives only the cron string, so multiple jobs sharing one expression must
|
|
2531
|
-
* all fire — hence a list per key rather than a single entry.
|
|
2532
|
-
*
|
|
2533
|
-
* Jobs arrive pre-sorted by name (deterministic output); the trigger array
|
|
2534
|
-
* preserves first-seen order of distinct expressions.
|
|
2535
|
-
*
|
|
2536
|
-
* Cloudflare caps a Worker at **3 Cron Triggers** (i.e. 3 distinct cron
|
|
2537
|
-
* expressions). Because the dispatcher fires every job sharing an expression,
|
|
2538
|
-
* many jobs can ride a single trigger — only the count of *distinct* schedules
|
|
2539
|
-
* matters. `lunora codegen` warns when that count exceeds the limit; for
|
|
2540
|
-
* finer-grained scheduling use Durable Object alarms (`@lunora/scheduler`),
|
|
2541
|
-
* which have no such cap.
|
|
2621
|
+
* Discover `ctx.db.insert("table", …)` writes under the lunora source directory
|
|
2622
|
+
* and attribute each to the exported function (and file) performing it. Calls
|
|
2623
|
+
* with a non-literal table argument, or outside an exported declaration, are
|
|
2624
|
+
* dropped (`table === ""` / no enclosing export).
|
|
2542
2625
|
*/
|
|
2543
|
-
declare const
|
|
2626
|
+
declare const discoverInserts: (project: Project, lunoraDirectory: string) => InsertWriteIR[];
|
|
2544
2627
|
/**
|
|
2545
|
-
*
|
|
2546
|
-
*
|
|
2547
|
-
*
|
|
2548
|
-
*
|
|
2549
|
-
*
|
|
2550
|
-
* runtime — a binding can `describe()` itself but the worker can't ask "which
|
|
2551
|
-
* indexes exist". So this generated array is the source of truth the studio's
|
|
2552
|
-
* vector browser lists, and the worker's admin route pairs each entry with its
|
|
2553
|
-
* live `describe()` stats. Entries are sorted by name for deterministic output.
|
|
2628
|
+
* Discover masking usage for every exported Lunora procedure under the lunora
|
|
2629
|
+
* source directory — the column-level twin of `discoverRlsProcedures`. For each
|
|
2630
|
+
* procedure, records whether its builder chain includes `.use(mask(...))`, which
|
|
2631
|
+
* `(table, column)` pairs that mask declares, and which tables it reads/writes
|
|
2632
|
+
* through `ctx.db`. Feeds the `mask_uncovered_pii_column` advisor lint.
|
|
2554
2633
|
*/
|
|
2555
|
-
declare const
|
|
2634
|
+
declare const discoverMaskProcedures: (project: Project, lunoraDirectory: string) => MaskProcedureIR[];
|
|
2556
2635
|
/**
|
|
2557
|
-
*
|
|
2558
|
-
*
|
|
2559
|
-
*
|
|
2560
|
-
*
|
|
2636
|
+
* Scan all `.ts` files under `lunoraDir` for top-level
|
|
2637
|
+
* `export const x = defineMigration({...})` declarations and lift them into
|
|
2638
|
+
* {@link MigrationIR}. `id` must be a static string literal (it's the registry
|
|
2639
|
+
* key); `table` is best-effort and left `""` when not a literal.
|
|
2561
2640
|
*/
|
|
2562
|
-
declare const
|
|
2563
|
-
/**
|
|
2564
|
-
|
|
2565
|
-
/**
|
|
2566
|
-
* Inbound-email agents (`defineAgent({ onEmail })`) → wire the worker's
|
|
2567
|
-
* top-level `email()` handler to `dispatchAgentEmail(...)` (from
|
|
2568
|
-
* `@lunora/agent/inbound`), so received mail starts a durable run. Empty/absent
|
|
2569
|
-
* ⇒ no wiring, byte-identical output for email-free (and agent-free) projects.
|
|
2570
|
-
*/
|
|
2571
|
-
emailAgents?: ReadonlyArray<{
|
|
2572
|
-
bindingName: string;
|
|
2573
|
-
exportName: string;
|
|
2574
|
-
}>;
|
|
2575
|
-
/** App depends on `@lunora/cloudflare-access` → emit `.access()` (wire the Cloudflare Access `resolveIdentity`, composed ahead of `@lunora/auth` when both are present). */
|
|
2576
|
-
hasAccess: boolean;
|
|
2577
|
-
/** App uses `@lunora/ai` / `ctx.ai` → emit `.ai()` (override the Workers AI binding backing `ctx.ai`). */
|
|
2578
|
-
hasAi: boolean;
|
|
2579
|
-
/** App uses `@lunora/bindings/analytics` / `ctx.analytics` → emit `.analytics()` (override the dataset backing `ctx.analytics`). */
|
|
2580
|
-
hasAnalytics: boolean;
|
|
2581
|
-
/** App depends on `@lunora/auth` → emit `.auth()` + the lazy build/migrate dance. */
|
|
2582
|
-
hasAuth: boolean;
|
|
2583
|
-
/** App uses `@lunora/browser` / `ctx.browser` → emit `.browser()`. */
|
|
2584
|
-
hasBrowser: boolean;
|
|
2585
|
-
/** App depends on a worker-composition framework adapter (`@lunora/astro`/`@lunora/svelte`/`@lunora/vue`) → emit `.buildFrameworkWorker(host)`. */
|
|
2586
|
-
hasFramework: boolean;
|
|
2587
|
-
/** Schema declares **D1-backed** `.global()` tables → emit `.global()` (D1 ctx-db + studio introspector + cross-shard relations). */
|
|
2588
|
-
hasGlobal: boolean;
|
|
2589
|
-
/** App uses `@lunora/hyperdrive` / `ctx.sql` → emit `.hyperdrive()`. */
|
|
2590
|
-
hasHyperdrive: boolean;
|
|
2591
|
-
/** Schema declares **Hyperdrive-backed** `.global({ backend: "hyperdrive" })` tables → emit `.hyperdriveGlobal()` (reactive Postgres/MySQL ctx-db over Hyperdrive). */
|
|
2592
|
-
hasHyperdriveGlobal: boolean;
|
|
2593
|
-
/** App uses `@lunora/bindings/images` / `ctx.images` → emit `.images()`. */
|
|
2594
|
-
hasImages: boolean;
|
|
2595
|
-
/** App uses `@lunora/bindings/kv` / `ctx.kv` → emit `.kv()`. */
|
|
2596
|
-
hasKv: boolean;
|
|
2597
|
-
/** App declares `lunora/notify.ts` (`@lunora/notify`) → wire `options.notifySubscriptionStore` so the studio Notifications page can read registered devices. */
|
|
2598
|
-
hasNotify: boolean;
|
|
2599
|
-
/** App uses `@lunora/payment` / `ctx.payments` → emit `.payment()`. */
|
|
2600
|
-
hasPayments: boolean;
|
|
2601
|
-
/** App declares push queues (`defineQueue`) → wire `LUNORA_QUEUE_REGISTRY` into the worker's `queue()` consumer entry. */
|
|
2602
|
-
hasQueue: boolean;
|
|
2603
|
-
/** App uses `@lunora/bindings/r2sql` / `ctx.r2sql` → emit `.r2sql()`. */
|
|
2604
|
-
hasR2sql: boolean;
|
|
2605
|
-
/** App imports `@lunora/scheduler` / declares crons → emit `.scheduler()`. */
|
|
2606
|
-
hasScheduler: boolean;
|
|
2607
|
-
/** App uses `@lunora/storage` → emit `.storage()` (DO `ctx.storage` + studio file browser). */
|
|
2608
|
-
hasStorage: boolean;
|
|
2609
|
-
/** Schema declares vector indexes → emit `.vectors()` (the Vectorize index map backing `ctx.vectors`). */
|
|
2610
|
-
hasVectors: boolean;
|
|
2611
|
-
/** App declares Cloudflare Workflows (`defineWorkflow`) → wire `options.workflowsClient` so the studio's workflow-instance proxy can reach the CF REST API. */
|
|
2612
|
-
hasWorkflow: boolean;
|
|
2613
|
-
/** App uses `@lunora/x402/pay` / `ctx.x402` → emit `.x402()` (wire the agent-wallet pay rail). */
|
|
2614
|
-
hasX402: boolean;
|
|
2615
|
-
/** The single `defineIdentity(...)` contract in `lunora/identity.ts` (Plan 080) → import it as a VALUE and wire `options.identity`, so the runtime trust boundary validates every resolved identity before it becomes `ctx.auth`. `undefined` ⇒ no wiring, byte-identical output. */
|
|
2616
|
-
identity?: IdentityIR;
|
|
2617
|
-
/** Schema declares `.jurisdiction("…")` → pin every DO the worker reaches (shards, fan-out, scheduler, containers) to the Cloudflare data-residency jurisdiction. */
|
|
2618
|
-
jurisdiction?: JurisdictionIR;
|
|
2619
|
-
/** Project depends on the unscoped `lunorash` umbrella → import the runtime via `lunorash/runtime` instead of `@lunora/runtime`. */
|
|
2620
|
-
useUmbrella: boolean;
|
|
2621
|
-
/**
|
|
2622
|
-
* Voice-enabled agents (`defineAgent({ voice: … })`) → wire
|
|
2623
|
-
* `options.voiceAgents`, mapping each agent's export name to its `VOICE_*`
|
|
2624
|
-
* Durable Object namespace binding so the runtime exposes
|
|
2625
|
-
* `/_lunora/voice/<exportName>`. Empty/absent ⇒ no wiring, byte-identical
|
|
2626
|
-
* output for voice-free (and agent-free) projects.
|
|
2627
|
-
*/
|
|
2628
|
-
voiceAgents?: ReadonlyArray<{
|
|
2629
|
-
bindingName: string;
|
|
2630
|
-
exportName: string;
|
|
2631
|
-
}>;
|
|
2632
|
-
/** An OpenAPI spec is emitted (`openapi.ts`) → wire `openApiSpec` into the worker. */
|
|
2633
|
-
wantsOpenApi: boolean;
|
|
2634
|
-
/** An OpenRPC spec is emitted (`openrpc.ts`) → wire `openRpcSpec` into the worker. */
|
|
2635
|
-
wantsOpenRpc: boolean;
|
|
2636
|
-
}
|
|
2641
|
+
declare const discoverMigrations: (project: Project, lunoraDirectory: string) => MigrationIR[];
|
|
2642
|
+
/** The only file custom mutators may be declared in — mirrors `lunora/queues.ts`. */
|
|
2643
|
+
declare const MUTATORS_FILENAME = "mutators.ts";
|
|
2637
2644
|
/**
|
|
2638
|
-
*
|
|
2639
|
-
*
|
|
2640
|
-
*
|
|
2641
|
-
*
|
|
2642
|
-
*
|
|
2643
|
-
* `
|
|
2644
|
-
*
|
|
2645
|
-
* / scheduler / global are declared once instead of twice. The builder is pure
|
|
2646
|
-
* sugar over the public `createWorker` / `createShardDO`; both stay usable.
|
|
2647
|
-
*
|
|
2648
|
-
* Lives in generated code (not `@lunora/runtime`, which is dependency-free) so
|
|
2649
|
-
* it can import the add-on packages the app installed (`@lunora/auth`,
|
|
2650
|
-
* `@lunora/storage`, …) directly.
|
|
2645
|
+
* Discover every custom mutator the project declares: exported
|
|
2646
|
+
* `defineMutator()` calls in `lunora/mutators.ts`. Returns `[]` when the file
|
|
2647
|
+
* doesn't exist. The export binding plus the declared `args` / `server` return
|
|
2648
|
+
* type are lifted — enough to emit a typed `api.mutators.<name>` reference —
|
|
2649
|
+
* while the runtime object still carries the authoritative `server` impl +
|
|
2650
|
+
* `handler`, so codegen never evaluates the body. The client `client` impl is
|
|
2651
|
+
* split into the browser bundle separately.
|
|
2651
2652
|
*/
|
|
2652
|
-
declare const
|
|
2653
|
-
/** Inputs the OpenAPI emitter needs from a codegen run. */
|
|
2654
|
-
interface OpenApiEmitInput {
|
|
2655
|
-
functions: ReadonlyArray<FunctionIR>;
|
|
2656
|
-
httpRoutes: ReadonlyArray<HttpRouteIR>;
|
|
2657
|
-
/** `info.version`; defaults to `"0.0.0"` with a TODO when the project version is unknown. */
|
|
2658
|
-
version?: string;
|
|
2659
|
-
}
|
|
2653
|
+
declare const discoverMutators: (project: Project, lunoraDirectory: string) => MutatorIR[];
|
|
2660
2654
|
/**
|
|
2661
|
-
*
|
|
2662
|
-
*
|
|
2663
|
-
* `
|
|
2664
|
-
*
|
|
2665
|
-
*
|
|
2655
|
+
* Discover non-deterministic API calls (`Date.now`, `new Date()`, `Date()`,
|
|
2656
|
+
* `Math.random`, `crypto.randomUUID`, `crypto.getRandomValues` — including
|
|
2657
|
+
* `globalThis`/`self`/`window`-prefixed receivers — and `fetch`) lexically inside
|
|
2658
|
+
* the handler body of every exported `query(...)` / `mutation(...)` registration
|
|
2659
|
+
* under the lunora source directory — the `nondeterministic_query_mutation` lint
|
|
2660
|
+
* input. `action(...)` (and `stream(...)`) registrations are intentionally
|
|
2661
|
+
* skipped: actions run exactly once and may use ambient APIs freely.
|
|
2666
2662
|
*
|
|
2667
|
-
*
|
|
2668
|
-
*
|
|
2669
|
-
*
|
|
2670
|
-
*
|
|
2663
|
+
* Traversal is scoped to the handler node (not the whole declaration), mirroring
|
|
2664
|
+
* how the auth-api / insert feeders attribute calls — so a call in a sibling
|
|
2665
|
+
* helper outside the handler, or in a nested `action(...)` passed elsewhere, is
|
|
2666
|
+
* not attributed to the query/mutation. One {@link NondeterministicCallIR} is
|
|
2667
|
+
* produced per call site.
|
|
2668
|
+
*/
|
|
2669
|
+
declare const discoverNondeterministicCalls: (project: Project, lunoraDirectory: string) => NondeterministicCallIR[];
|
|
2670
|
+
/** The only file a `@lunora/notify` provider may be declared in — mirrors `lunora/flags.ts`. */
|
|
2671
|
+
declare const NOTIFY_FILENAME = "notify.ts";
|
|
2672
|
+
/**
|
|
2673
|
+
* Discover `ctx.notify` / `ctx.push` sends lexically inside the handler body of
|
|
2674
|
+
* every exported `query(...)` / `mutation(...)` registration under the lunora
|
|
2675
|
+
* source directory — the `notify_send_outside_action` lint input. `action(...)`
|
|
2676
|
+
* (and `stream(...)`) registrations are intentionally skipped: a notification
|
|
2677
|
+
* send is external I/O that belongs in actions. One {@link AdvisorNotifyCall} is
|
|
2678
|
+
* produced per send site.
|
|
2679
|
+
*/
|
|
2680
|
+
declare const discoverNotifyCalls: (project: Project, lunoraDirectory: string) => AdvisorNotifyCall[];
|
|
2681
|
+
/**
|
|
2682
|
+
* Discover which push channels the project's `lunora/notify.ts` default export
|
|
2683
|
+
* (`defineNotify({...})`) wires plus whether any handler sends a push — the
|
|
2684
|
+
* `notify_missing_push_config` lint input. Returns `undefined` when the file is
|
|
2685
|
+
* absent (the app declares no notify config). The read is metadata-only and
|
|
2686
|
+
* lenient (like `discoverFlags`): a `webPush`/`fcm` property's mere presence
|
|
2687
|
+
* counts as the channel being wired; a non-literal config degrades to "unwired"
|
|
2688
|
+
* rather than throwing.
|
|
2689
|
+
*/
|
|
2690
|
+
declare const discoverNotifyConfig: (project: Project, lunoraDirectory: string) => AdvisorNotifyConfig | undefined;
|
|
2691
|
+
/**
|
|
2692
|
+
* Every package name the project declares a dependency on, read from the
|
|
2693
|
+
* `package.json` at the project root across all four dependency fields
|
|
2694
|
+
* (`dependencies`, `devDependencies`, `peerDependencies`,
|
|
2695
|
+
* `optionalDependencies`).
|
|
2671
2696
|
*
|
|
2672
|
-
*
|
|
2673
|
-
*
|
|
2674
|
-
*
|
|
2675
|
-
*
|
|
2676
|
-
*
|
|
2677
|
-
*
|
|
2678
|
-
* `.json` and `.ts` artifacts can never drift).
|
|
2697
|
+
* Returns `undefined` — NOT an empty set — when the manifest is absent or
|
|
2698
|
+
* unparseable, which is the whole reason this exists. Studio nav gating can
|
|
2699
|
+
* treat "declares nothing" and "cannot tell" the same way, but a check that
|
|
2700
|
+
* errors on a missing package cannot: conflating them makes it fire on every
|
|
2701
|
+
* project without a root `package.json` (the codegen fixtures, an embedded
|
|
2702
|
+
* schema, a tool driving `runCodegen` directly).
|
|
2679
2703
|
*/
|
|
2680
|
-
declare const
|
|
2704
|
+
declare const readPackageDependencies: (projectRoot: string) => Set<string> | undefined;
|
|
2681
2705
|
/**
|
|
2682
|
-
*
|
|
2683
|
-
*
|
|
2706
|
+
* Discover `ctx.db.query("table")…` reads under the lunora source directory and
|
|
2707
|
+
* reduce each to a {@link QueryReadIR}. Only reads that call `.filter()` are
|
|
2708
|
+
* returned — an unfiltered read is never a `filter_without_index` candidate, so
|
|
2709
|
+
* dropping the rest keeps the lint input small.
|
|
2684
2710
|
*/
|
|
2685
|
-
declare const
|
|
2711
|
+
declare const discoverQueries: (project: Project, lunoraDirectory: string) => QueryReadIR[];
|
|
2712
|
+
/** The only file queues may be declared in — mirrors `lunora/workflows.ts`. */
|
|
2713
|
+
declare const QUEUES_FILENAME = "queues.ts";
|
|
2686
2714
|
/**
|
|
2687
|
-
*
|
|
2688
|
-
*
|
|
2689
|
-
* `
|
|
2690
|
-
*
|
|
2691
|
-
* `.json` are byte-identical content and regenerate together — closing the gap
|
|
2692
|
-
* where a Worker cannot read the JSON file at runtime. `document_` is the object
|
|
2693
|
-
* returned by {@link buildOpenApiDocument} (reused, never recomputed).
|
|
2715
|
+
* Discover every queue the project declares: exported `defineQueue()` calls in
|
|
2716
|
+
* `lunora/queues.ts`. Returns `[]` when the file doesn't exist. Only the
|
|
2717
|
+
* wrangler-relevant literals (`name`/`mode`/batch tuning) are read; the handler
|
|
2718
|
+
* body is runtime-only, so codegen never evaluates it.
|
|
2694
2719
|
*/
|
|
2695
|
-
declare const
|
|
2696
|
-
/** The OpenRPC dialect version this emitter targets. */
|
|
2697
|
-
declare const OPENRPC_VERSION = "1.3.2";
|
|
2698
|
-
/** Inputs the OpenRPC emitter needs from a codegen run. */
|
|
2699
|
-
interface OpenRpcEmitInput {
|
|
2700
|
-
functions: ReadonlyArray<FunctionIR>;
|
|
2701
|
-
/** `info.version`; defaults to `"0.0.0"` with a TODO when the project version is unknown. */
|
|
2702
|
-
version?: string;
|
|
2703
|
-
}
|
|
2720
|
+
declare const discoverQueues: (project: Project, lunoraDirectory: string) => QueueIR[];
|
|
2704
2721
|
/**
|
|
2705
|
-
*
|
|
2722
|
+
* Discover `ctx.r2sql` accesses lexically inside the handler body of every
|
|
2723
|
+
* exported `query(...)` / `mutation(...)` registration under the lunora source
|
|
2724
|
+
* directory — the `r2sql_outside_action` lint input. `action(...)` (and
|
|
2725
|
+
* `stream(...)`) registrations are intentionally skipped: R2 SQL is the
|
|
2726
|
+
* external, non-reactive surface that belongs in actions.
|
|
2706
2727
|
*
|
|
2707
|
-
*
|
|
2708
|
-
*
|
|
2709
|
-
*
|
|
2710
|
-
*
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2728
|
+
* Traversal is scoped to the handler node (not the whole declaration), mirroring
|
|
2729
|
+
* `discoverNondeterministicCalls` — so a `ctx.r2sql` touch in a sibling helper
|
|
2730
|
+
* outside the handler is not attributed to the query/mutation. One
|
|
2731
|
+
* {@link R2sqlCallIR} is produced per access site.
|
|
2732
|
+
*/
|
|
2733
|
+
declare const discoverR2sqlCalls: (project: Project, lunoraDirectory: string) => R2sqlCallIR[];
|
|
2734
|
+
declare const discoverRlsProcedures: (project: Project, lunoraDirectory: string) => RlsProcedureIR[];
|
|
2735
|
+
/**
|
|
2736
|
+
* Aggregate the schema-wide RLS metadata the studio's read-only inspector reads:
|
|
2737
|
+
* every statically-discovered `(table, on, procedure)` policy entry plus every
|
|
2738
|
+
* role declared via `rls(policies, { roles })`. Walks the same builder chains as
|
|
2739
|
+
* {@link discoverRlsProcedures} but extracts the richer `{ on }` operation +
|
|
2740
|
+
* role/permission shape rather than the lint's table-name set.
|
|
2714
2741
|
*
|
|
2715
|
-
* `
|
|
2716
|
-
*
|
|
2717
|
-
*
|
|
2718
|
-
*
|
|
2719
|
-
*
|
|
2720
|
-
* `.ts` artifacts can never drift).
|
|
2742
|
+
* Only the **builder** form (`c.use(rls(...)).query(...)`) can declare policies,
|
|
2743
|
+
* so bare-factory procedures contribute nothing. The `when` predicate is never
|
|
2744
|
+
* read — it's an opaque JS closure whose logic belongs in code, not the UI.
|
|
2745
|
+
* Roles are deduped by name (first declaration wins) so a role registered on
|
|
2746
|
+
* several procedures lists once.
|
|
2721
2747
|
*/
|
|
2722
|
-
declare const
|
|
2748
|
+
declare const discoverRlsMetadata: (project: Project, lunoraDirectory: string) => RlsMetadataIR;
|
|
2723
2749
|
/**
|
|
2724
|
-
*
|
|
2725
|
-
*
|
|
2750
|
+
* Which sandbox tools a project imports from `@lunora/agent` (main entry or the
|
|
2751
|
+
* `/sandbox` subpath), detected by NAMED value import. Drives two things:
|
|
2752
|
+
* registering the `sandbox:invoke` dispatcher (either tool) and provisioning the
|
|
2753
|
+
* `BROWSER` wrangler binding (`browserTool` — the browser op runs on
|
|
2754
|
+
* `ctx.browser` inside the dispatcher).
|
|
2726
2755
|
*/
|
|
2727
|
-
|
|
2756
|
+
interface SandboxUsage {
|
|
2757
|
+
/** `import { browserTool } from "@lunora/agent"` (or `/sandbox`) appears in `lunora/`. */
|
|
2758
|
+
usesSandboxBrowser: boolean;
|
|
2759
|
+
/** `import { containerTool } from "@lunora/agent"` (or `/sandbox`) appears in `lunora/`. */
|
|
2760
|
+
usesSandboxContainer: boolean;
|
|
2761
|
+
}
|
|
2762
|
+
declare const discoverSandboxUsage: (project: Project, lunoraDirectory: string) => SandboxUsage;
|
|
2728
2763
|
/**
|
|
2729
|
-
*
|
|
2730
|
-
*
|
|
2731
|
-
* `createWorker({ openRpcSpec })`. The document object literal is inlined
|
|
2732
|
-
* verbatim (same `JSON.stringify` form the `.json` uses), so the `.ts` and
|
|
2733
|
-
* `.json` are byte-identical content and regenerate together. `document_` is
|
|
2734
|
-
* the object returned by {@link buildOpenRpcDocument} (reused, never recomputed).
|
|
2764
|
+
* Load `<projectRoot>/lunora/schema.ts`, find `defineSchema({...})`, and
|
|
2765
|
+
* return a structural IR. Throws if the file or call cannot be found.
|
|
2735
2766
|
*/
|
|
2736
|
-
declare const
|
|
2767
|
+
declare const discoverSchema: (project: Project, schemaPath: string, projectRoot?: string) => SchemaIR;
|
|
2768
|
+
/** The only file shapes may be declared in — mirrors `lunora/queues.ts`. */
|
|
2769
|
+
declare const SHAPES_FILENAME = "shapes.ts";
|
|
2737
2770
|
/**
|
|
2738
|
-
*
|
|
2739
|
-
*
|
|
2740
|
-
*
|
|
2741
|
-
*
|
|
2742
|
-
*
|
|
2743
|
-
* interface templates, so their order here is not output-affecting.
|
|
2771
|
+
* Discover every replication shape the project declares: exported
|
|
2772
|
+
* `defineShape()` calls in `lunora/shapes.ts`. Returns `[]` when the file
|
|
2773
|
+
* doesn't exist. Only the export binding is lifted — the runtime object carries
|
|
2774
|
+
* the authoritative `table`/`columns`/`compileWhere`, so codegen never
|
|
2775
|
+
* evaluates the predicate.
|
|
2744
2776
|
*/
|
|
2745
|
-
declare const
|
|
2746
|
-
readonly contextProperty: "access";
|
|
2747
|
-
readonly key: "access";
|
|
2748
|
-
readonly moduleSpecifier: "@lunora/cloudflare-access";
|
|
2749
|
-
}, {
|
|
2750
|
-
readonly appMethod: {
|
|
2751
|
-
readonly configKey: "ai";
|
|
2752
|
-
readonly doc: "Override the Workers AI binding backing `ctx.ai` (defaults to `env.AI`).";
|
|
2753
|
-
readonly method: "ai";
|
|
2754
|
-
};
|
|
2755
|
-
readonly contextProperty: "ai";
|
|
2756
|
-
readonly key: "ai";
|
|
2757
|
-
readonly moduleSpecifier: "@lunora/ai";
|
|
2758
|
-
}, {
|
|
2759
|
-
readonly appMethod: {
|
|
2760
|
-
readonly configKey: "analytics";
|
|
2761
|
-
readonly doc: "Override the Analytics Engine dataset backing `ctx.analytics` (defaults to `env.ANALYTICS`).";
|
|
2762
|
-
readonly method: "analytics";
|
|
2763
|
-
};
|
|
2764
|
-
readonly contextProperty: "analytics";
|
|
2765
|
-
readonly key: "analytics";
|
|
2766
|
-
readonly moduleSpecifier: "@lunora/bindings/analytics";
|
|
2767
|
-
readonly serverCtxField: {
|
|
2768
|
-
readonly field: "\n /** Analytics Engine telemetry sink. Fire-and-forget and sampled; do not read it back in-handler. */\n readonly analytics: import(\"@lunora/bindings/analytics\").AnalyticsClient;";
|
|
2769
|
-
readonly tier: "every";
|
|
2770
|
-
};
|
|
2771
|
-
}, {
|
|
2772
|
-
readonly appMethod: {
|
|
2773
|
-
readonly configKey: "browser";
|
|
2774
|
-
readonly doc: "Override the Browser Rendering binding backing `ctx.browser` (defaults to `env.BROWSER`).";
|
|
2775
|
-
readonly method: "browser";
|
|
2776
|
-
};
|
|
2777
|
-
readonly contextProperty: "browser";
|
|
2778
|
-
readonly key: "browser";
|
|
2779
|
-
readonly moduleSpecifier: "@lunora/browser";
|
|
2780
|
-
readonly serverCtxField: {
|
|
2781
|
-
readonly field: "\n /** Browser Rendering (screenshots/PDF/scrape). Non-deterministic — available only in actions. */\n readonly browser: import(\"@lunora/browser\").Browser;";
|
|
2782
|
-
readonly tier: "action";
|
|
2783
|
-
};
|
|
2784
|
-
}, {
|
|
2785
|
-
readonly contextProperty: "containers";
|
|
2786
|
-
readonly key: "container";
|
|
2787
|
-
readonly moduleSpecifier: "@lunora/container";
|
|
2788
|
-
}, {
|
|
2789
|
-
readonly contextProperty: "flags";
|
|
2790
|
-
readonly key: "flags";
|
|
2791
|
-
readonly moduleSpecifier: "@lunora/flags";
|
|
2792
|
-
}, {
|
|
2793
|
-
readonly appMethod: {
|
|
2794
|
-
readonly configKey: "sql";
|
|
2795
|
-
readonly doc: "Wire the Hyperdrive SQL client backing `ctx.sql` — build it with `createHyperdrive` + `fromPostgresJs`/`fromNodePg`/`fromMysql2`.";
|
|
2796
|
-
readonly method: "hyperdrive";
|
|
2797
|
-
};
|
|
2798
|
-
readonly contextProperty: "sql";
|
|
2799
|
-
readonly key: "hyperdrive";
|
|
2800
|
-
readonly moduleSpecifier: "@lunora/hyperdrive";
|
|
2801
|
-
readonly serverCtxField: {
|
|
2802
|
-
readonly field: "\n /**\n * External database access via Hyperdrive. Non-deterministic — available only in actions. Writes here are NOT tracked by Lunora live queries; subscriptions will not re-run on external DB changes.\n */\n readonly sql: import(\"@lunora/hyperdrive\").SqlClient;";
|
|
2803
|
-
readonly tier: "action";
|
|
2804
|
-
};
|
|
2805
|
-
}, {
|
|
2806
|
-
readonly appMethod: {
|
|
2807
|
-
readonly configKey: "images";
|
|
2808
|
-
readonly doc: "Override the Images binding backing `ctx.images` (defaults to `env.IMAGES`).";
|
|
2809
|
-
readonly method: "images";
|
|
2810
|
-
};
|
|
2811
|
-
readonly contextProperty: "images";
|
|
2812
|
-
readonly key: "images";
|
|
2813
|
-
readonly moduleSpecifier: "@lunora/bindings/images";
|
|
2814
|
-
readonly serverCtxField: {
|
|
2815
|
-
readonly field: "\n /** Cloudflare Images transforms (resize/format/optimize). Non-deterministic — available only in actions. */\n readonly images: import(\"@lunora/bindings/images\").Images;";
|
|
2816
|
-
readonly tier: "action";
|
|
2817
|
-
};
|
|
2818
|
-
}, {
|
|
2819
|
-
readonly appMethod: {
|
|
2820
|
-
readonly configKey: "kv";
|
|
2821
|
-
readonly doc: "Override the Workers KV binding backing `ctx.kv` (defaults to `env.KV`).";
|
|
2822
|
-
readonly method: "kv";
|
|
2823
|
-
};
|
|
2824
|
-
readonly contextProperty: "kv";
|
|
2825
|
-
readonly key: "kv";
|
|
2826
|
-
readonly moduleSpecifier: "@lunora/bindings/kv";
|
|
2827
|
-
readonly serverCtxField: {
|
|
2828
|
-
readonly field: "\n readonly kv: import(\"@lunora/bindings/kv\").Kv;";
|
|
2829
|
-
readonly tier: "every";
|
|
2830
|
-
};
|
|
2831
|
-
}, {
|
|
2832
|
-
readonly key: "mail";
|
|
2833
|
-
readonly moduleSpecifier: "@lunora/mail";
|
|
2834
|
-
}, {
|
|
2835
|
-
readonly contextProperty: "notify";
|
|
2836
|
-
readonly key: "notify";
|
|
2837
|
-
readonly moduleSpecifier: "@lunora/notify";
|
|
2838
|
-
}, {
|
|
2839
|
-
readonly appMethod: {
|
|
2840
|
-
readonly configKey: "payment";
|
|
2841
|
-
readonly doc: "Wire the payment options backing `ctx.payments`.";
|
|
2842
|
-
readonly method: "payment";
|
|
2843
|
-
};
|
|
2844
|
-
readonly contextProperty: "payments";
|
|
2845
|
-
readonly key: "payments";
|
|
2846
|
-
readonly moduleSpecifier: "@lunora/payment";
|
|
2847
|
-
}, {
|
|
2848
|
-
readonly appMethod: {
|
|
2849
|
-
readonly configKey: "x402";
|
|
2850
|
-
readonly doc: "Wire the x402 agent-wallet pay rail backing `ctx.x402` — a payment-enabled `fetch` that answers `402` challenges under a mandatory spend policy (ActionCtx-only; spends real funds).";
|
|
2851
|
-
readonly method: "x402";
|
|
2852
|
-
};
|
|
2853
|
-
readonly contextProperty: "x402";
|
|
2854
|
-
readonly key: "x402";
|
|
2855
|
-
readonly moduleSpecifier: "@lunora/x402/pay";
|
|
2856
|
-
}, {
|
|
2857
|
-
readonly contextProperty: "pipelines";
|
|
2858
|
-
readonly key: "pipelines";
|
|
2859
|
-
readonly moduleSpecifier: "@lunora/bindings/pipelines";
|
|
2860
|
-
readonly serverCtxField: {
|
|
2861
|
-
readonly field: "\n /** Pipelines ingestion sink (durable, R2-backed). Fire-and-forget and batched; do not read it back in-handler. */\n readonly pipelines: import(\"@lunora/bindings/pipelines\").PipelineClient;";
|
|
2862
|
-
readonly tier: "action";
|
|
2863
|
-
};
|
|
2864
|
-
}, {
|
|
2865
|
-
readonly appMethod: {
|
|
2866
|
-
readonly configKey: "r2sql";
|
|
2867
|
-
readonly doc: "Wire the R2 SQL client backing `ctx.r2sql` — build it with `createR2Sql({ accountId, apiToken, bucket })` (defaults to env `R2_SQL_TOKEN` / `R2_SQL_ACCOUNT_ID` / `R2_SQL_BUCKET`).";
|
|
2868
|
-
readonly method: "r2sql";
|
|
2869
|
-
};
|
|
2870
|
-
readonly contextProperty: "r2sql";
|
|
2871
|
-
readonly key: "r2sql";
|
|
2872
|
-
readonly moduleSpecifier: "@lunora/bindings/r2sql";
|
|
2873
|
-
readonly serverCtxField: {
|
|
2874
|
-
readonly field: "\n /**\n * R2 SQL over Apache Iceberg tables (window functions, DISTINCT, set operations). Non-deterministic — available only in actions. Reads here are NOT tracked by Lunora live queries.\n */\n readonly r2sql: import(\"@lunora/bindings/r2sql\").R2SqlClient;";
|
|
2875
|
-
readonly tier: "action";
|
|
2876
|
-
};
|
|
2877
|
-
}, {
|
|
2878
|
-
readonly contextProperty: "scheduler";
|
|
2879
|
-
readonly key: "scheduler";
|
|
2880
|
-
readonly moduleSpecifier: "@lunora/scheduler";
|
|
2881
|
-
}, {
|
|
2882
|
-
readonly contextProperty: "storage";
|
|
2883
|
-
readonly key: "storage";
|
|
2884
|
-
readonly moduleSpecifier: "@lunora/storage";
|
|
2885
|
-
}, {
|
|
2886
|
-
readonly appMethod: {
|
|
2887
|
-
readonly configKey: "vectors";
|
|
2888
|
-
readonly doc: "Wire the Vectorize index map backing `ctx.vectors`.";
|
|
2889
|
-
readonly method: "vectors";
|
|
2890
|
-
};
|
|
2891
|
-
readonly contextProperty: "vectors";
|
|
2892
|
-
readonly key: "vectors";
|
|
2893
|
-
readonly moduleSpecifier: "@lunora/bindings/vectors";
|
|
2894
|
-
}, {
|
|
2895
|
-
readonly contextProperty: "workflows";
|
|
2896
|
-
readonly key: "workflows";
|
|
2897
|
-
readonly moduleSpecifier: "@lunora/workflow";
|
|
2898
|
-
}];
|
|
2899
|
-
/** The literal union of every capability id — the single source of truth for `FeatureUsage`'s keys (so they cannot drift). */
|
|
2900
|
-
type CapabilityKey = (typeof CAPABILITY_ROWS)[number]["key"];
|
|
2901
|
-
/** The default codegen target — today's behavior, byte-identical goldens. */
|
|
2902
|
-
declare const DEFAULT_TARGET = "cloudflare";
|
|
2777
|
+
declare const discoverShapes: (project: Project, lunoraDirectory: string) => ShapeIR[];
|
|
2903
2778
|
/**
|
|
2904
|
-
*
|
|
2905
|
-
*
|
|
2906
|
-
*
|
|
2907
|
-
*
|
|
2908
|
-
* `@lunora/codegen`, not the reverse. Putting it there and importing it here
|
|
2909
|
-
* would invert that edge, so config delegates to this instead and there is
|
|
2910
|
-
* still exactly one parser for the key.
|
|
2911
|
-
*
|
|
2912
|
-
* Best-effort and deliberately unvalidated: a missing file, malformed JSONC, or
|
|
2913
|
-
* a non-string value all collapse to `undefined`, because those are shape
|
|
2914
|
-
* errors rather than a name the user meant. An unrecognized *name* is returned
|
|
2915
|
-
* as-is so the caller's registry lookup rejects it — swallowing a typo into the
|
|
2916
|
-
* default would ship an app to the wrong provider.
|
|
2917
|
-
* @param projectRoot Directory containing `lunora.json`.
|
|
2918
|
-
* @returns the declared target, or `undefined` when none is usable.
|
|
2779
|
+
* Aggregate the schema-wide storage-rule metadata the studio's inspector reads:
|
|
2780
|
+
* every statically-discovered `(bucket, on, prefix, procedure)` entry across all
|
|
2781
|
+
* `.use(storageRules(...))` chains. Only the builder form can declare rules, so
|
|
2782
|
+
* bare-factory procedures contribute nothing.
|
|
2919
2783
|
*/
|
|
2920
|
-
declare const
|
|
2784
|
+
declare const discoverStorageRulesMetadata: (project: Project, lunoraDirectory: string) => StorageRulesMetadataIR;
|
|
2785
|
+
/** The only file workflows may be declared in — mirrors `lunora/containers.ts`. */
|
|
2786
|
+
declare const WORKFLOWS_FILENAME = "workflows.ts";
|
|
2921
2787
|
/**
|
|
2922
|
-
*
|
|
2923
|
-
* `lunora.
|
|
2924
|
-
*
|
|
2925
|
-
*
|
|
2926
|
-
* still emits the surface the project declared. That default matters more than
|
|
2927
|
-
* it looks: a call site that silently omits the target emits the *default*
|
|
2928
|
-
* surface with no diagnostic to notice, and the mismatch only shows up at
|
|
2929
|
-
* runtime on the deployed app.
|
|
2930
|
-
* @param projectRoot Directory containing `lunora.json`.
|
|
2931
|
-
* @param explicit A caller-supplied target, if any.
|
|
2932
|
-
* @returns the resolved target id — not guaranteed to be registered.
|
|
2788
|
+
* Discover every workflow the project declares: exported `defineWorkflow()`
|
|
2789
|
+
* calls in `lunora/workflows.ts`. Returns `[]` when the file doesn't exist. The
|
|
2790
|
+
* only wrangler-relevant literal is the optional `name` override; the workflow
|
|
2791
|
+
* body is runtime-only, so codegen never evaluates it.
|
|
2933
2792
|
*/
|
|
2934
|
-
declare const
|
|
2793
|
+
declare const discoverWorkflows: (project: Project, lunoraDirectory: string) => WorkflowIR[];
|
|
2794
|
+
declare const GENERATED_HEADER = "// GENERATED by @lunora/codegen — do not edit.\n// Run `lunora codegen` to regenerate.\n\n";
|
|
2795
|
+
/** Emit `_generated/dataModel.ts` — `Doc<"name">` + `Id<"name">` for every table. */
|
|
2796
|
+
declare const emitDataModel: (schema: SchemaIR, useUmbrella?: boolean) => string;
|
|
2935
2797
|
/**
|
|
2936
|
-
*
|
|
2937
|
-
*
|
|
2938
|
-
*
|
|
2939
|
-
*
|
|
2940
|
-
*
|
|
2941
|
-
*
|
|
2942
|
-
* driver gates a surface nothing can deploy. Today both hold exactly
|
|
2943
|
-
* `cloudflare`, which is why nothing has noticed.
|
|
2944
|
-
* @returns the registered matrix ids, sorted.
|
|
2798
|
+
* Emit `_generated/api.ts` — the typed `api.*` registry (public functions), the
|
|
2799
|
+
* `internal.*` registry, and (when the project declares them) the typed
|
|
2800
|
+
* `workflows.*` / `agents.*` scheduler-target reference objects. `api`/`internal` are the same `anyApi` proxy
|
|
2801
|
+
* at runtime (the `__lunoraRef` is identical); visibility is enforced
|
|
2802
|
+
* server-side at dispatch, not in the reference. Splitting the *types* keeps
|
|
2803
|
+
* internal functions off the client-facing `api` surface.
|
|
2945
2804
|
*/
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
/**
|
|
2950
|
-
|
|
2951
|
-
/**
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
/** The lint id: `platform_unsupported_feature` or `platform_unknown_target`. */
|
|
2956
|
-
name: "platform_unknown_target" | "platform_unsupported_feature";
|
|
2957
|
-
/** How to resolve it. */
|
|
2958
|
-
remediation: string;
|
|
2959
|
-
/** The requested deploy target. */
|
|
2960
|
-
target: string;
|
|
2805
|
+
interface EmitApiOptions {
|
|
2806
|
+
agents?: ReadonlyArray<AgentIR>;
|
|
2807
|
+
functions: ReadonlyArray<FunctionIR>;
|
|
2808
|
+
/** Typed REST routes; only `.stream()` (SSE) routes emit a `httpStreams.*` reference. */
|
|
2809
|
+
httpRoutes?: ReadonlyArray<HttpRouteIR>;
|
|
2810
|
+
/** Custom mutators (`lunora/mutators.ts`) — emitted as `api.mutators.*` so a client `serverRef` is compile-checked. */
|
|
2811
|
+
mutators?: ReadonlyArray<MutatorIR>;
|
|
2812
|
+
useUmbrella?: boolean;
|
|
2813
|
+
workflows?: ReadonlyArray<WorkflowIR>;
|
|
2961
2814
|
}
|
|
2815
|
+
declare const emitApi: (options: EmitApiOptions) => string;
|
|
2962
2816
|
/**
|
|
2963
|
-
*
|
|
2964
|
-
*
|
|
2965
|
-
* gitignored `_generated/`) so it is committed alongside `schema.ts`. Leading
|
|
2966
|
-
* dot keeps it tucked away next to the schema it describes.
|
|
2967
|
-
*/
|
|
2968
|
-
declare const SCHEMA_SNAPSHOT_FILENAME = ".lunora-schema.json";
|
|
2969
|
-
/**
|
|
2970
|
-
* Construct the ts-morph `Project` codegen discovers over. Prefers the user's
|
|
2971
|
-
* `tsconfig.json` (when one is found walking up from `lunoraDirectory`) so
|
|
2972
|
-
* cross-file type resolution and path aliases work; falls back to an isolated
|
|
2973
|
-
* project otherwise. This is the exact construction {@link runCodegen} uses
|
|
2974
|
-
* when no `project` is injected — exported so a long-lived caller (the Vite
|
|
2975
|
-
* dev-loop) can build one once and reuse it across runs via
|
|
2976
|
-
* {@link refreshCodegenProject} instead of re-parsing the user's whole TS
|
|
2977
|
-
* program on every save.
|
|
2978
|
-
*/
|
|
2979
|
-
declare const createCodegenProject: (lunoraDirectory: string) => Project;
|
|
2980
|
-
/**
|
|
2981
|
-
* Synchronise a reused {@link createCodegenProject} Project with the current
|
|
2982
|
-
* on-disk state of `lunoraDirectory`, so the next {@link runCodegen} sees the
|
|
2983
|
-
* same files a freshly-constructed Project would — without re-parsing the whole
|
|
2984
|
-
* TS program. Adds any on-disk source file the Project doesn't yet have, and
|
|
2985
|
-
* `refreshFromFileSystemSync()`es the ones it does (picking up edits); then
|
|
2986
|
-
* removes Project source files under `lunoraDirectory` that no longer exist on
|
|
2987
|
-
* disk (the classic stale-deleted-file cache bug).
|
|
2817
|
+
* Emit `_generated/collections.ts` — a typed TanStack DB binding per `defineShape`
|
|
2818
|
+
* in `lunora/shapes.ts` (the local-first partial-replication surface).
|
|
2988
2819
|
*
|
|
2989
|
-
*
|
|
2990
|
-
* are left untouched — they back type resolution and rarely change in the
|
|
2991
|
-
* dev-loop; a tsconfig change invalidates the whole cached Project upstream.
|
|
2992
|
-
*/
|
|
2993
|
-
declare const refreshCodegenProject: (project: Project, lunoraDirectory: string) => void;
|
|
2994
|
-
/**
|
|
2995
|
-
* Top-level codegen entry. Parses `<projectRoot>/lunora/schema.ts` and every
|
|
2996
|
-
* function file under `<projectRoot>/lunora/`, then writes
|
|
2997
|
-
* `_generated/{api,server,dataModel}.ts` next to them.
|
|
2820
|
+
* Each shape emits **two** entry points.
|
|
2998
2821
|
*
|
|
2999
|
-
*
|
|
3000
|
-
*
|
|
3001
|
-
*
|
|
3002
|
-
*
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
* {@link CodegenResult.advisories}.
|
|
3030
|
-
*/
|
|
3031
|
-
lint?: boolean;
|
|
3032
|
-
/** Override the lunora subdirectory name. Defaults to `"lunora"`. */
|
|
3033
|
-
lunoraDirectory?: string;
|
|
3034
|
-
/**
|
|
3035
|
-
* Reuse a previously-constructed ts-morph {@link Project} instead of building
|
|
3036
|
-
* a fresh one each run. The caller owns refreshing its source files from disk
|
|
3037
|
-
* (see {@link refreshCodegenProject}) — codegen does not re-read changed files
|
|
3038
|
-
* off an injected Project. Built via {@link createCodegenProject} when absent.
|
|
3039
|
-
* Used by the Vite dev-loop to avoid re-parsing the whole TS program on every
|
|
3040
|
-
* save; omit it (CLI one-shot path) to get the default fresh-Project behaviour.
|
|
3041
|
-
*/
|
|
3042
|
-
project?: Project;
|
|
3043
|
-
/** Project root containing the `lunora/` directory. */
|
|
3044
|
-
projectRoot: string;
|
|
2822
|
+
* `<shape>CollectionOptions(options)` is the composable form: it returns the full
|
|
2823
|
+
* `LunoraCollectionOptions` — `config` for `createCollection`, plus `checkpoints`
|
|
2824
|
+
* (which `bindMutators` gates optimistic overlays on) and `scope`. This is what an app
|
|
2825
|
+
* with custom mutators needs, and what the old single-factory form made impossible: it
|
|
2826
|
+
* built the collection internally and dropped `checkpoints` on the floor, so there was
|
|
2827
|
+
* no way to wire mutators to the collection codegen produced.
|
|
2828
|
+
*
|
|
2829
|
+
* `<shape>Collection(options)` is the convenience form for a read-only collection: it
|
|
2830
|
+
* returns `{ checkpoints, collection, scope }` rather than a bare `Collection`, so the
|
|
2831
|
+
* sync controls stay reachable even from the short path.
|
|
2832
|
+
*
|
|
2833
|
+
* Both are typed: `args` comes from the shape's own validators (a parameterless
|
|
2834
|
+
* shape takes none), rows resolve to `Doc<"table">` when the shape names its table
|
|
2835
|
+
* with a literal, and `shardKey` / `getKey` / `load` / `onError` / `checkpoints` are
|
|
2836
|
+
* all threadable — a sharded table needs `shardKey` for its watermark to land in the
|
|
2837
|
+
* right bucket, and a server-minted `_id` that differs from the app's natural key
|
|
2838
|
+
* needs `getKey`.
|
|
2839
|
+
*
|
|
2840
|
+
* Returns `""` (so `writeIfPresent` skips the file) unless the project both
|
|
2841
|
+
* declares shapes AND installs `@lunora/db` — the add-on that ships
|
|
2842
|
+
* `lunoraCollectionOptions`. `@lunora/db` stays a scoped install even under the
|
|
2843
|
+
* `lunorash` umbrella (an opt-in add-on, like `@lunora/auth`), so its import is
|
|
2844
|
+
* always `@lunora/db/collections`; only the in-umbrella `@lunora/client` import
|
|
2845
|
+
* is remapped to `lunorash/client`.
|
|
2846
|
+
*/
|
|
2847
|
+
declare const emitCollections: (shapes: ReadonlyArray<ShapeIR>, hasDatabase: boolean, useUmbrella?: boolean) => string;
|
|
2848
|
+
interface EmitServerOptions {
|
|
2849
|
+
/** Agents declared via `defineAgent` exports — wires the typed `ctx.agents` producers onto Mutation/Action contexts. */
|
|
2850
|
+
agents?: ReadonlyArray<AgentIR>;
|
|
2851
|
+
containers?: ReadonlyArray<ContainerIR>;
|
|
3045
2852
|
/**
|
|
3046
|
-
* The
|
|
3047
|
-
*
|
|
3048
|
-
*
|
|
3049
|
-
*
|
|
3050
|
-
* `ctx.*` surface and reports it in {@link CodegenResult.platformDiagnostics}.
|
|
3051
|
-
* Only `"cloudflare"` is registered until other per-target `@lunora/platform`
|
|
3052
|
-
* matrices land; an unknown target emits the full surface un-gated and a
|
|
3053
|
-
* `platform_unknown_target` diagnostic.
|
|
2853
|
+
* The single `defineEnv(...)` contract declared in `lunora/env.ts`. When
|
|
2854
|
+
* present, `ctx.env` is typed as the validated `InferEnv` shape (recovered
|
|
2855
|
+
* via `ReturnType` over the accessor's `typeof`). `undefined` leaves `ctx.env`
|
|
2856
|
+
* the base optional binding record — byte-identical to today.
|
|
3054
2857
|
*/
|
|
3055
|
-
|
|
2858
|
+
env?: EnvIR;
|
|
3056
2859
|
/**
|
|
3057
|
-
*
|
|
3058
|
-
*
|
|
3059
|
-
*
|
|
3060
|
-
*
|
|
3061
|
-
* a breaking change. Ignored when `dryRun` is true.
|
|
2860
|
+
* A `lunora/` source reads `ctx.access` — wires the verified Cloudflare Access
|
|
2861
|
+
* facade (`@lunora/cloudflare-access/context`) onto every ctx. Distinct from
|
|
2862
|
+
* `emitApp`'s `hasAccess` (which gates the worker's `.access()` resolveIdentity
|
|
2863
|
+
* method); this one gates the per-request `ctx.access` read surface.
|
|
3062
2864
|
*/
|
|
3063
|
-
|
|
2865
|
+
hasAccessFacade?: boolean;
|
|
2866
|
+
hasAi?: boolean;
|
|
2867
|
+
/** A `lunora/` source uses `@lunora/bindings/analytics` / `ctx.analytics` — wires the write helper onto every ctx. */
|
|
2868
|
+
hasAnalytics?: boolean;
|
|
2869
|
+
/** A `lunora/` source uses `@lunora/browser` / `ctx.browser` — wires `ctx.browser` onto ActionCtx only. */
|
|
2870
|
+
hasBrowser?: boolean;
|
|
2871
|
+
/** The project declares `lunora/flags.ts` — wires `ctx.flags` (OpenFeature) onto every ctx. */
|
|
2872
|
+
hasFlags?: boolean;
|
|
2873
|
+
/** A `lunora/` source uses `@lunora/hyperdrive` / `ctx.sql` — wires `ctx.sql` onto ActionCtx only. */
|
|
2874
|
+
hasHyperdrive?: boolean;
|
|
2875
|
+
/** A `lunora/` source uses `@lunora/bindings/images` / `ctx.images` — wires `ctx.images` onto ActionCtx only. */
|
|
2876
|
+
hasImages?: boolean;
|
|
2877
|
+
/** A `lunora/` source uses `@lunora/bindings/kv` / `ctx.kv` — wires `ctx.kv` onto every ctx. */
|
|
2878
|
+
hasKv?: boolean;
|
|
2879
|
+
/** The project declares `lunora/notify.ts` — wires `ctx.notify` + its `ctx.push` alias (`@lunora/notify`) onto every ctx. */
|
|
2880
|
+
hasNotify?: boolean;
|
|
2881
|
+
hasPayments?: boolean;
|
|
2882
|
+
/** A `lunora/` source uses `@lunora/bindings/pipelines` / `ctx.pipelines` — wires `ctx.pipelines` onto ActionCtx only. */
|
|
2883
|
+
hasPipelines?: boolean;
|
|
2884
|
+
/** A `lunora/` source uses `@lunora/bindings/r2sql` / `ctx.r2sql` — wires `ctx.r2sql` onto ActionCtx only. */
|
|
2885
|
+
hasR2sql?: boolean;
|
|
2886
|
+
/** A `lunora/` source uses `@lunora/x402/pay` / `ctx.x402` — wires the agent-wallet pay rail onto ActionCtx only. */
|
|
2887
|
+
hasX402?: boolean;
|
|
3064
2888
|
/**
|
|
3065
|
-
*
|
|
3066
|
-
* `
|
|
3067
|
-
*
|
|
3068
|
-
*
|
|
3069
|
-
*
|
|
2889
|
+
* The single `defineIdentity(...)` claim contract declared in
|
|
2890
|
+
* `lunora/identity.ts` (Plan 080). When present, `ctx.auth.getIdentity()`,
|
|
2891
|
+
* the RLS policy `ctx.auth.identity`, and the shard-authorization hooks
|
|
2892
|
+
* narrow to the declared shape (recovered via `InferIdentity` over the
|
|
2893
|
+
* contract's `typeof`). `undefined` keeps the identity an untyped bag —
|
|
2894
|
+
* byte-identical to today.
|
|
3070
2895
|
*/
|
|
3071
|
-
|
|
2896
|
+
identity?: IdentityIR;
|
|
2897
|
+
/** Queues declared via `defineQueue` exports — wires the typed `ctx.queues` producers onto Mutation/Action contexts. */
|
|
2898
|
+
queues?: ReadonlyArray<QueueIR>;
|
|
2899
|
+
schema?: SchemaIR;
|
|
2900
|
+
storageRuleBuckets?: ReadonlyArray<string>;
|
|
2901
|
+
/** The project depends on the `lunora` umbrella — import base packages via its subpaths. */
|
|
2902
|
+
useUmbrella?: boolean;
|
|
2903
|
+
workflows?: ReadonlyArray<WorkflowIR>;
|
|
3072
2904
|
}
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
2905
|
+
declare const emitServer: ({ agents, containers, env, hasAccessFacade, hasAi, hasAnalytics, hasBrowser, hasFlags, hasHyperdrive, hasImages, hasKv, hasNotify, hasPayments, hasPipelines, hasR2sql, hasX402, identity, queues, schema, storageRuleBuckets, useUmbrella, workflows }?: EmitServerOptions) => string;
|
|
2906
|
+
interface EmitFunctionsOptions {
|
|
2907
|
+
agents?: ReadonlyArray<AgentIR>;
|
|
2908
|
+
functions: ReadonlyArray<FunctionIR>;
|
|
2909
|
+
migrations?: ReadonlyArray<MigrationIR>;
|
|
2910
|
+
mutators?: ReadonlyArray<MutatorIR>;
|
|
2911
|
+
shapes?: ReadonlyArray<ShapeIR>;
|
|
2912
|
+
/** Import of a sandbox tool (`browserTool`/`containerTool`) auto-registers the `sandbox:invoke` action. */
|
|
2913
|
+
usesSandbox?: boolean;
|
|
2914
|
+
useUmbrella?: boolean;
|
|
2915
|
+
}
|
|
2916
|
+
declare const emitFunctions: (options: EmitFunctionsOptions) => string;
|
|
2917
|
+
/**
|
|
2918
|
+
* Emit `_generated/containers.ts` — one container-enabled Durable Object class
|
|
2919
|
+
* per `defineContainer` export, each a thin subclass of `LunoraContainer`
|
|
2920
|
+
* (`@lunora/container/do`) constructed with the user's definition object. The
|
|
2921
|
+
* worker entry must re-export these classes: wrangler requires every
|
|
2922
|
+
* `containers[].class_name` to be exported by the deployed worker. Returns ""
|
|
2923
|
+
* when the project declares no containers (the file is not written then).
|
|
2924
|
+
*/
|
|
2925
|
+
declare const emitContainers: (containers: ReadonlyArray<ContainerIR>, jurisdiction?: JurisdictionIR) => string;
|
|
2926
|
+
/**
|
|
2927
|
+
* Emit `_generated/workflows.ts` — one `WorkflowEntrypoint` class per
|
|
2928
|
+
* `defineWorkflow` export, each a thin subclass of `LunoraWorkflow`
|
|
2929
|
+
* (`@lunora/workflow/do`) constructed with the user's definition object. The
|
|
2930
|
+
* worker entry must re-export these classes: wrangler requires every
|
|
2931
|
+
* `workflows[].class_name` to be exported by the deployed worker. Returns ""
|
|
2932
|
+
* when the project declares no workflows (the file is not written then).
|
|
2933
|
+
*/
|
|
2934
|
+
declare const emitWorkflows: (workflows: ReadonlyArray<WorkflowIR>) => string;
|
|
2935
|
+
/**
|
|
2936
|
+
* Emit `_generated/agents.ts` — one `WorkflowEntrypoint` class per `defineAgent`
|
|
2937
|
+
* export, each a thin subclass of `LunoraWorkflow` (`@lunora/workflow/do`)
|
|
2938
|
+
* constructed with the compiled agent tool-loop (`compileAgentWorkflow`). Like
|
|
2939
|
+
* `_generated/workflows.ts`, the worker entry must re-export these classes:
|
|
2940
|
+
* wrangler requires every `workflows[].class_name` to be exported by the
|
|
2941
|
+
* deployed worker. Returns "" when the project declares no agents (the file is
|
|
2942
|
+
* not written then).
|
|
2943
|
+
*/
|
|
2944
|
+
declare const emitAgents: (agents: ReadonlyArray<AgentIR>) => string;
|
|
2945
|
+
interface EmitShardOptions {
|
|
2946
|
+
advisories?: ReadonlyArray<Finding>;
|
|
2947
|
+
/** Every declared procedure — the health map's denominator, served via `getAdvisorProcedures`. */
|
|
2948
|
+
advisorProcedures?: ReadonlyArray<AdvisorProcedureProtection>;
|
|
2949
|
+
/** Agents declared via `defineAgent` exports in `lunora/agents.ts` — wires the typed `ctx.agents` producers. */
|
|
2950
|
+
agents?: ReadonlyArray<AgentIR>;
|
|
2951
|
+
containers?: ReadonlyArray<ContainerIR>;
|
|
2952
|
+
/** The single `defineEnv(...)` contract declared in `lunora/env.ts` — applies the accessor to the worker `env` to populate `ctx.env`. */
|
|
2953
|
+
env?: EnvIR;
|
|
2954
|
+
/** Statically-discovered `ctx.flags.<type>("key")` reads — the studio Flags page + reactive evaluation iterate these. */
|
|
2955
|
+
flagKeys?: ReadonlyArray<{
|
|
2956
|
+
key: string;
|
|
2957
|
+
type: "boolean" | "number" | "object" | "string";
|
|
2958
|
+
}>;
|
|
2959
|
+
/** A `lunora/` source reads `ctx.access` — wires the verified Cloudflare Access facade onto every ctx. */
|
|
2960
|
+
hasAccessFacade?: boolean;
|
|
2961
|
+
hasAi?: boolean;
|
|
2962
|
+
/** A `lunora/` source reads `ctx.analytics` — wires the Analytics Engine write helper onto every ctx. */
|
|
2963
|
+
hasAnalytics?: boolean;
|
|
2964
|
+
/** A `lunora/` source reads `ctx.browser` — wires `ctx.browser` onto the ActionCtx only. */
|
|
2965
|
+
hasBrowser?: boolean;
|
|
2966
|
+
/** The project declares `lunora/flags.ts` — wires `ctx.flags` (OpenFeature) onto every ctx. */
|
|
2967
|
+
hasFlags?: boolean;
|
|
2968
|
+
/** A `lunora/` source reads `ctx.sql` (Hyperdrive) — wires `ctx.sql` onto the ActionCtx only. */
|
|
2969
|
+
hasHyperdrive?: boolean;
|
|
2970
|
+
/** A `lunora/` source reads `ctx.images` — wires `ctx.images` onto the ActionCtx only. */
|
|
2971
|
+
hasImages?: boolean;
|
|
2972
|
+
/** A `lunora/` source reads `ctx.kv` — wires `ctx.kv` onto every ctx. */
|
|
2973
|
+
hasKv?: boolean;
|
|
2974
|
+
/** The project declares `lunora/notify.ts` — wires `ctx.notify` + its `ctx.push` alias (`@lunora/notify`) onto every ctx. */
|
|
2975
|
+
hasNotify?: boolean;
|
|
2976
|
+
hasPayments?: boolean;
|
|
2977
|
+
/** A `lunora/` source reads `ctx.pipelines` — wires `ctx.pipelines` onto the ActionCtx only. */
|
|
2978
|
+
hasPipelines?: boolean;
|
|
2979
|
+
/** A `lunora/` source reads `ctx.r2sql` (R2 SQL) — wires `ctx.r2sql` onto the ActionCtx only. */
|
|
2980
|
+
hasR2sql?: boolean;
|
|
2981
|
+
/** A `lunora/` source reads `ctx.x402` — wires the agent-wallet pay rail onto the ActionCtx only. */
|
|
2982
|
+
hasX402?: boolean;
|
|
2983
|
+
maskMetadata?: MaskMetadataIR;
|
|
2984
|
+
/** Custom mutators declared via `defineMutator` in `lunora/mutators.ts` — wires the `isCustomMutator` push-protocol override. */
|
|
2985
|
+
mutators?: ReadonlyArray<MutatorIR>;
|
|
2986
|
+
/** Queues declared via `defineQueue` exports in `lunora/queues.ts` — wires the typed `ctx.queues` producers. */
|
|
2987
|
+
queues?: ReadonlyArray<QueueIR>;
|
|
2988
|
+
rlsMetadata?: RlsMetadataIR;
|
|
2989
|
+
schema: SchemaIR;
|
|
3098
2990
|
/**
|
|
3099
|
-
*
|
|
3100
|
-
*
|
|
3101
|
-
*
|
|
3102
|
-
*
|
|
2991
|
+
* The structural snapshot the pre-deploy drift gate diffs against, threaded
|
|
2992
|
+
* in so the emitted DO records it in `__lunora_schema_history` on cold start
|
|
2993
|
+
* (plan 200 — the Studio's schema-version timeline). Optional so an emitter
|
|
2994
|
+
* caller that has no snapshot (tests, fixtures) emits the pre-ledger shape
|
|
2995
|
+
* unchanged.
|
|
3103
2996
|
*/
|
|
3104
|
-
|
|
3105
|
-
/**
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
2997
|
+
schemaSnapshot?: SchemaSnapshot;
|
|
2998
|
+
/** Replication shapes declared via `defineShape` in `lunora/shapes.ts` — wires the `resolveShape` subscription override. */
|
|
2999
|
+
shapes?: ReadonlyArray<ShapeIR>;
|
|
3000
|
+
storageRules?: StorageRulesMetadataIR;
|
|
3001
|
+
studioFeatures?: StudioFeaturesResult;
|
|
3002
|
+
/** The project depends on the `lunora` umbrella — import base packages via its subpaths. */
|
|
3003
|
+
useUmbrella?: boolean;
|
|
3004
|
+
workflows?: ReadonlyArray<WorkflowIR>;
|
|
3005
|
+
}
|
|
3006
|
+
declare const emitShard: ({ advisories, advisorProcedures, agents, containers, env, flagKeys, hasAccessFacade, hasAi, hasAnalytics, hasBrowser, hasFlags, hasHyperdrive, hasImages, hasKv, hasNotify, hasPayments, hasPipelines, hasR2sql, hasX402, maskMetadata, mutators, queues, rlsMetadata, schema, schemaSnapshot, shapes, storageRules, studioFeatures, useUmbrella, workflows }: EmitShardOptions) => string;
|
|
3007
|
+
/**
|
|
3008
|
+
* Emit drizzle `sqliteTable` definitions for the project schema, split into
|
|
3009
|
+
* `global` (D1-backed) and `shard` (DO-SQLite-backed) buckets. Tables marked
|
|
3010
|
+
* `.global()` go in the global file; everything else (default root + `.shardBy()`)
|
|
3011
|
+
* goes in the shard file.
|
|
3012
|
+
*
|
|
3013
|
+
* `searchIndexes` are intentionally not emitted — drizzle has no `sqliteTable`
|
|
3014
|
+
* abstraction for FTS5 virtual tables. FTS plumbing is handled by the runtime
|
|
3015
|
+
* outside of drizzle.
|
|
3016
|
+
*/
|
|
3017
|
+
declare const emitDrizzleSchema: (schema: SchemaIR, useUmbrella?: boolean) => {
|
|
3018
|
+
global: string;
|
|
3019
|
+
shard: string;
|
|
3020
|
+
};
|
|
3021
|
+
/**
|
|
3022
|
+
* Emit `_generated/crons.ts` from the discovered cron jobs.
|
|
3023
|
+
*
|
|
3024
|
+
* `LUNORA_CRON_TRIGGERS` is the deduplicated schedule array — what lands in
|
|
3025
|
+
* wrangler's `triggers.crons` (the vite plugin reconciles it into
|
|
3026
|
+
* `wrangler.jsonc`, and {@link emitWranglerCronTriggers} renders the same list
|
|
3027
|
+
* for the CLI / docs).
|
|
3028
|
+
*
|
|
3029
|
+
* `LUNORA_CRONS` is the dispatcher map keyed by cron expression, each value a
|
|
3030
|
+
* list of `{ name, functionPath, args }`. Cloudflare's `scheduled()` handler
|
|
3031
|
+
* receives only the cron string, so multiple jobs sharing one expression must
|
|
3032
|
+
* all fire — hence a list per key rather than a single entry.
|
|
3033
|
+
*
|
|
3034
|
+
* Jobs arrive pre-sorted by name (deterministic output); the trigger array
|
|
3035
|
+
* preserves first-seen order of distinct expressions.
|
|
3036
|
+
*
|
|
3037
|
+
* Cloudflare caps a Worker at **3 Cron Triggers** (i.e. 3 distinct cron
|
|
3038
|
+
* expressions). Because the dispatcher fires every job sharing an expression,
|
|
3039
|
+
* many jobs can ride a single trigger — only the count of *distinct* schedules
|
|
3040
|
+
* matters. `lunora codegen` warns when that count exceeds the limit; for
|
|
3041
|
+
* finer-grained scheduling use Durable Object alarms (`@lunora/scheduler`),
|
|
3042
|
+
* which have no such cap.
|
|
3043
|
+
*/
|
|
3044
|
+
declare const emitCrons: (crons: ReadonlyArray<CronJobIR>) => string;
|
|
3045
|
+
/**
|
|
3046
|
+
* Render `_generated/vectors.ts` — the static registry of every vector index
|
|
3047
|
+
* declared in `schema.ts` (inline `.vectorize()` columns + standalone
|
|
3048
|
+
* `defineVectorIndex()` definitions).
|
|
3049
|
+
*
|
|
3050
|
+
* Cloudflare Vectorize exposes no way to enumerate an account's indexes at
|
|
3051
|
+
* runtime — a binding can `describe()` itself but the worker can't ask "which
|
|
3052
|
+
* indexes exist". So this generated array is the source of truth the studio's
|
|
3053
|
+
* vector browser lists, and the worker's admin route pairs each entry with its
|
|
3054
|
+
* live `describe()` stats. Entries are sorted by name for deterministic output.
|
|
3055
|
+
*/
|
|
3056
|
+
declare const emitVectors: (vectorIndexes: ReadonlyArray<VectorIndexIR>) => string;
|
|
3057
|
+
/**
|
|
3058
|
+
* Render the deduplicated cron schedules as a JSON fragment suitable for
|
|
3059
|
+
* splicing into `wrangler.jsonc`'s `triggers.crons`. The vite plugin uses this
|
|
3060
|
+
* (plus the parsed wrangler config) to reconcile generated triggers without the
|
|
3061
|
+
* user hand-editing the file.
|
|
3062
|
+
*/
|
|
3063
|
+
declare const emitWranglerCronTriggers: (crons: ReadonlyArray<CronJobIR>) => string[];
|
|
3064
|
+
/** Which capability methods the generated `defineApp` builder exposes — one flag per package-backed feature the app actually uses. */
|
|
3065
|
+
interface EmitAppOptions {
|
|
3171
3066
|
/**
|
|
3172
|
-
*
|
|
3173
|
-
*
|
|
3174
|
-
*
|
|
3175
|
-
*
|
|
3176
|
-
* `dryRun`.
|
|
3067
|
+
* Inbound-email agents (`defineAgent({ onEmail })`) → wire the worker's
|
|
3068
|
+
* top-level `email()` handler to `dispatchAgentEmail(...)` (from
|
|
3069
|
+
* `@lunora/agent/inbound`), so received mail starts a durable run. Empty/absent
|
|
3070
|
+
* ⇒ no wiring, byte-identical output for email-free (and agent-free) projects.
|
|
3177
3071
|
*/
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3072
|
+
emailAgents?: ReadonlyArray<{
|
|
3073
|
+
bindingName: string;
|
|
3074
|
+
exportName: string;
|
|
3075
|
+
}>;
|
|
3076
|
+
/** App depends on `@lunora/cloudflare-access` → emit `.access()` (wire the Cloudflare Access `resolveIdentity`, composed ahead of `@lunora/auth` when both are present). */
|
|
3077
|
+
hasAccess: boolean;
|
|
3078
|
+
/** App uses `@lunora/ai` / `ctx.ai` → emit `.ai()` (override the Workers AI binding backing `ctx.ai`). */
|
|
3079
|
+
hasAi: boolean;
|
|
3080
|
+
/** App uses `@lunora/bindings/analytics` / `ctx.analytics` → emit `.analytics()` (override the dataset backing `ctx.analytics`). */
|
|
3081
|
+
hasAnalytics: boolean;
|
|
3082
|
+
/** App depends on `@lunora/auth` → emit `.auth()` + the lazy build/migrate dance. */
|
|
3083
|
+
hasAuth: boolean;
|
|
3084
|
+
/** App uses `@lunora/browser` / `ctx.browser` → emit `.browser()`. */
|
|
3085
|
+
hasBrowser: boolean;
|
|
3086
|
+
/** App depends on a worker-composition framework adapter (`@lunora/astro`/`@lunora/svelte`/`@lunora/vue`) → emit `.buildFrameworkWorker(host)`. */
|
|
3087
|
+
hasFramework: boolean;
|
|
3088
|
+
/** Schema declares **D1-backed** `.global()` tables → emit `.global()` (D1 ctx-db + studio introspector + cross-shard relations). */
|
|
3089
|
+
hasGlobal: boolean;
|
|
3090
|
+
/** App uses `@lunora/hyperdrive` / `ctx.sql` → emit `.hyperdrive()`. */
|
|
3091
|
+
hasHyperdrive: boolean;
|
|
3092
|
+
/** Schema declares **Hyperdrive-backed** `.global({ backend: "hyperdrive" })` tables → emit `.hyperdriveGlobal()` (reactive Postgres/MySQL ctx-db over Hyperdrive). */
|
|
3093
|
+
hasHyperdriveGlobal: boolean;
|
|
3094
|
+
/** App uses `@lunora/bindings/images` / `ctx.images` → emit `.images()`. */
|
|
3095
|
+
hasImages: boolean;
|
|
3096
|
+
/** App uses `@lunora/bindings/kv` / `ctx.kv` → emit `.kv()`. */
|
|
3097
|
+
hasKv: boolean;
|
|
3098
|
+
/** App declares `lunora/notify.ts` (`@lunora/notify`) → wire `options.notifySubscriptionStore` so the studio Notifications page can read registered devices. */
|
|
3099
|
+
hasNotify: boolean;
|
|
3100
|
+
/** App uses `@lunora/payment` / `ctx.payments` → emit `.payment()`. */
|
|
3101
|
+
hasPayments: boolean;
|
|
3102
|
+
/** App declares push queues (`defineQueue`) → wire `LUNORA_QUEUE_REGISTRY` into the worker's `queue()` consumer entry. */
|
|
3103
|
+
hasQueue: boolean;
|
|
3104
|
+
/** App uses `@lunora/bindings/r2sql` / `ctx.r2sql` → emit `.r2sql()`. */
|
|
3105
|
+
hasR2sql: boolean;
|
|
3106
|
+
/** App imports `@lunora/scheduler` / declares crons → emit `.scheduler()`. */
|
|
3107
|
+
hasScheduler: boolean;
|
|
3108
|
+
/** App uses `@lunora/storage` → emit `.storage()` (DO `ctx.storage` + studio file browser). */
|
|
3109
|
+
hasStorage: boolean;
|
|
3110
|
+
/** Schema declares vector indexes → emit `.vectors()` (the Vectorize index map backing `ctx.vectors`). */
|
|
3111
|
+
hasVectors: boolean;
|
|
3112
|
+
/** App declares Cloudflare Workflows (`defineWorkflow`) → wire `options.workflowsClient` so the studio's workflow-instance proxy can reach the CF REST API. */
|
|
3113
|
+
hasWorkflow: boolean;
|
|
3114
|
+
/** App uses `@lunora/x402/pay` / `ctx.x402` → emit `.x402()` (wire the agent-wallet pay rail). */
|
|
3115
|
+
hasX402: boolean;
|
|
3116
|
+
/** The single `defineIdentity(...)` contract in `lunora/identity.ts` (Plan 080) → import it as a VALUE and wire `options.identity`, so the runtime trust boundary validates every resolved identity before it becomes `ctx.auth`. `undefined` ⇒ no wiring, byte-identical output. */
|
|
3117
|
+
identity?: IdentityIR;
|
|
3118
|
+
/** Schema declares `.jurisdiction("…")` → pin every DO the worker reaches (shards, fan-out, scheduler, containers) to the Cloudflare data-residency jurisdiction. */
|
|
3119
|
+
jurisdiction?: JurisdictionIR;
|
|
3120
|
+
/** Project depends on the unscoped `lunorash` umbrella → import the runtime via `lunorash/runtime` instead of `@lunora/runtime`. */
|
|
3121
|
+
useUmbrella: boolean;
|
|
3181
3122
|
/**
|
|
3182
|
-
*
|
|
3183
|
-
* `
|
|
3184
|
-
*
|
|
3185
|
-
*
|
|
3123
|
+
* Voice-enabled agents (`defineAgent({ voice: … })`) → wire
|
|
3124
|
+
* `options.voiceAgents`, mapping each agent's export name to its `VOICE_*`
|
|
3125
|
+
* Durable Object namespace binding so the runtime exposes
|
|
3126
|
+
* `/_lunora/voice/<exportName>`. Empty/absent ⇒ no wiring, byte-identical
|
|
3127
|
+
* output for voice-free (and agent-free) projects.
|
|
3186
3128
|
*/
|
|
3187
|
-
|
|
3129
|
+
voiceAgents?: ReadonlyArray<{
|
|
3130
|
+
bindingName: string;
|
|
3131
|
+
exportName: string;
|
|
3132
|
+
}>;
|
|
3133
|
+
/** An OpenAPI spec is emitted (`openapi.ts`) → wire `openApiSpec` into the worker. */
|
|
3134
|
+
wantsOpenApi: boolean;
|
|
3135
|
+
/** An OpenRPC spec is emitted (`openrpc.ts`) → wire `openRpcSpec` into the worker. */
|
|
3136
|
+
wantsOpenRpc: boolean;
|
|
3188
3137
|
}
|
|
3138
|
+
/**
|
|
3139
|
+
* Emit `_generated/app.ts` — a fluent, feature-specialized worker-composition
|
|
3140
|
+
* builder. Only the methods for capabilities THIS app uses are emitted, so the
|
|
3141
|
+
* builder's type surface (IntelliSense) lists exactly what can be configured.
|
|
3142
|
+
*
|
|
3143
|
+
* Each capability declaration is fanned into BOTH runtime surfaces: the DO-side
|
|
3144
|
+
* `createShardDO(...)` factory that backs `ctx.*`, and the worker-side
|
|
3145
|
+
* `createWorker(...)` options that back the studio/admin endpoints — so storage
|
|
3146
|
+
* / scheduler / global are declared once instead of twice. The builder is pure
|
|
3147
|
+
* sugar over the public `createWorker` / `createShardDO`; both stay usable.
|
|
3148
|
+
*
|
|
3149
|
+
* Lives in generated code (not `@lunora/runtime`, which is dependency-free) so
|
|
3150
|
+
* it can import the add-on packages the app installed (`@lunora/auth`,
|
|
3151
|
+
* `@lunora/storage`, …) directly.
|
|
3152
|
+
*/
|
|
3153
|
+
declare const emitApp: (options: EmitAppOptions) => string;
|
|
3154
|
+
/** Inputs the OpenAPI emitter needs from a codegen run. */
|
|
3155
|
+
interface OpenApiEmitInput {
|
|
3156
|
+
functions: ReadonlyArray<FunctionIR>;
|
|
3157
|
+
httpRoutes: ReadonlyArray<HttpRouteIR>;
|
|
3158
|
+
/** `info.version`; defaults to `"0.0.0"` with a TODO when the project version is unknown. */
|
|
3159
|
+
version?: string;
|
|
3160
|
+
}
|
|
3161
|
+
/**
|
|
3162
|
+
* Emit an OpenAPI 3.1.0 document covering both Lunora function surfaces.
|
|
3163
|
+
*
|
|
3164
|
+
* `httpRouter()` typed REST routes become real `paths` keyed by their method +
|
|
3165
|
+
* URL, with query/path parameters and JSON request bodies derived from their
|
|
3166
|
+
* `v.*` validators, and a response schema from `.output()` when declared.
|
|
3167
|
+
*
|
|
3168
|
+
* RPC `query`/`mutation`/`action` functions become one operation each on
|
|
3169
|
+
* `POST /_lunora/rpc` (disambiguated by a `#functionPath` path fragment), with a
|
|
3170
|
+
* requestBody pinning `functionPath` + typed `args`. `internal`/`stream`
|
|
3171
|
+
* functions are excluded (unreachable / not invocable on the external RPC path).
|
|
3172
|
+
*
|
|
3173
|
+
* Operations are grouped into `tags` by file namespace, and every operation
|
|
3174
|
+
* references a reusable `LunoraError` error-response component enumerating the
|
|
3175
|
+
* standard error codes. Borrows oRPC's per-procedure-operation + tag-grouping +
|
|
3176
|
+
* internal-filtering structure; the JSON Schema dialect matches `@lunora/values`
|
|
3177
|
+
* (Draft 2020-12). Returns the document as a plain object (the single source of
|
|
3178
|
+
* truth `emitOpenApi` stringifies and `emitOpenApiModule` inlines, so the
|
|
3179
|
+
* `.json` and `.ts` artifacts can never drift).
|
|
3180
|
+
*/
|
|
3181
|
+
declare const buildOpenApiDocument: (input: OpenApiEmitInput) => Record<string, unknown>;
|
|
3182
|
+
/**
|
|
3183
|
+
* Emit the OpenAPI 3.1 document as a pretty-printed JSON string
|
|
3184
|
+
* (`_generated/openapi.json`) — the portable artifact for external tooling.
|
|
3185
|
+
*/
|
|
3186
|
+
declare const emitOpenApi: (input: OpenApiEmitInput) => string;
|
|
3187
|
+
/**
|
|
3188
|
+
* Emit the OpenAPI document as an importable TS module
|
|
3189
|
+
* (`_generated/openapi.ts`) the worker entry imports and passes to
|
|
3190
|
+
* `createWorker({ openApiSpec })`. The document object literal is inlined
|
|
3191
|
+
* verbatim (same `JSON.stringify` form the `.json` uses), so the `.ts` and
|
|
3192
|
+
* `.json` are byte-identical content and regenerate together — closing the gap
|
|
3193
|
+
* where a Worker cannot read the JSON file at runtime. `document_` is the object
|
|
3194
|
+
* returned by {@link buildOpenApiDocument} (reused, never recomputed).
|
|
3195
|
+
*/
|
|
3196
|
+
declare const emitOpenApiModule: (document_: Record<string, unknown>) => string;
|
|
3197
|
+
/** The OpenRPC dialect version this emitter targets. */
|
|
3198
|
+
declare const OPENRPC_VERSION = "1.3.2";
|
|
3199
|
+
/** Inputs the OpenRPC emitter needs from a codegen run. */
|
|
3200
|
+
interface OpenRpcEmitInput {
|
|
3201
|
+
functions: ReadonlyArray<FunctionIR>;
|
|
3202
|
+
/** `info.version`; defaults to `"0.0.0"` with a TODO when the project version is unknown. */
|
|
3203
|
+
version?: string;
|
|
3204
|
+
}
|
|
3205
|
+
/**
|
|
3206
|
+
* Emit an OpenRPC 1.x document describing Lunora's JSON-RPC surface.
|
|
3207
|
+
*
|
|
3208
|
+
* Only the RPC `query`/`mutation`/`action` functions become `methods` — one per
|
|
3209
|
+
* function, `name` = `file:fn`. `internal` (off the external RPC path) and
|
|
3210
|
+
* `stream` (not invocable over the RPC envelope) are excluded, the same filter
|
|
3211
|
+
* the OpenAPI emitter applies. Each method's single `args` param is typed from
|
|
3212
|
+
* the function's `v.*` validators (`argsObjectSchema`); `result` is the
|
|
3213
|
+
* `.output()` schema when declared, else a best-effort inferred schema. The
|
|
3214
|
+
* standard `LunoraError` codes ride along under each method's `errors`.
|
|
3215
|
+
*
|
|
3216
|
+
* `httpRouter()` typed REST routes are deliberately omitted — OpenRPC is
|
|
3217
|
+
* RPC-only and cannot represent REST paths; the OpenAPI document is the spec
|
|
3218
|
+
* that covers the REST surface. Methods are sorted by name for stable output.
|
|
3219
|
+
* Returns the document as a plain object (the single source of truth
|
|
3220
|
+
* `emitOpenRpc` stringifies and `emitOpenRpcModule` inlines, so the `.json` and
|
|
3221
|
+
* `.ts` artifacts can never drift).
|
|
3222
|
+
*/
|
|
3223
|
+
declare const buildOpenRpcDocument: (input: OpenRpcEmitInput) => Record<string, unknown>;
|
|
3224
|
+
/**
|
|
3225
|
+
* Emit the OpenRPC 1.x document as a pretty-printed JSON string
|
|
3226
|
+
* (`_generated/openrpc.json`) — the portable artifact for external tooling.
|
|
3227
|
+
*/
|
|
3228
|
+
declare const emitOpenRpc: (input: OpenRpcEmitInput) => string;
|
|
3229
|
+
/**
|
|
3230
|
+
* Emit the OpenRPC document as an importable TS module
|
|
3231
|
+
* (`_generated/openrpc.ts`) the worker entry imports and passes to
|
|
3232
|
+
* `createWorker({ openRpcSpec })`. The document object literal is inlined
|
|
3233
|
+
* verbatim (same `JSON.stringify` form the `.json` uses), so the `.ts` and
|
|
3234
|
+
* `.json` are byte-identical content and regenerate together. `document_` is
|
|
3235
|
+
* the object returned by {@link buildOpenRpcDocument} (reused, never recomputed).
|
|
3236
|
+
*/
|
|
3237
|
+
declare const emitOpenRpcModule: (document_: Record<string, unknown>) => string;
|
|
3189
3238
|
/**
|
|
3190
3239
|
* Build a {@link SchemaSnapshot} from a parsed {@link SchemaIR} and the set of
|
|
3191
3240
|
* declared migration ids. Tables and migration ids are sorted so the emitted
|
|
@@ -3244,6 +3293,8 @@ interface SchemaDriftDecision {
|
|
|
3244
3293
|
declare const evaluateSchemaDrift: (options: {
|
|
3245
3294
|
allowDrift?: boolean;
|
|
3246
3295
|
baseline: SchemaSnapshot | undefined;
|
|
3296
|
+
/** The command printing the remediation, so it names only flags that command accepts. */
|
|
3297
|
+
command?: string;
|
|
3247
3298
|
current: SchemaSnapshot;
|
|
3248
3299
|
}) => SchemaDriftDecision;
|
|
3249
3300
|
/**
|
|
@@ -3275,4 +3326,4 @@ declare const secretKindOf: (value: string) => string | undefined;
|
|
|
3275
3326
|
/** A redacted preview of a secret value — first 4 chars plus its length, never the full value. */
|
|
3276
3327
|
declare const redact: (value: string) => string;
|
|
3277
3328
|
declare const VERSION = "0.0.0";
|
|
3278
|
-
export { AGENTS_FILENAME, type AgentIR, type AuthApiCallIR, CONTAINERS_FILENAME, CodegenDiagnosticError, type CodegenOptions, type CodegenResult, type ContainerIR, type CronJobIR, DEFAULT_TARGET, type DriftChange, type DriftScope, type EmitAppOptions, FLAGS_FILENAME, type FieldSnapshot, type FlagsIR, type FunctionIR, GENERATED_HEADER, type HttpRouteIR, type IndexIR, type IndexSnapshot, type InsertWriteIR, LUNORA_ERROR_CODES, type LintSchemaOptions, MUTATORS_FILENAME, type MaskProcedureIR, type MigrationIR, type MutatorIR, NOTIFY_FILENAME, OPENRPC_VERSION, type OpenApiEmitInput, type OpenRpcEmitInput, type PlatformDiagnostic, type ProjectIR, QUEUES_FILENAME, type QueryReadIR, type QueueIR, type R2sqlCallIR, type RelationSnapshot, type RlsMetadataIR, type RlsPolicyIR, type RlsProcedureIR, type RlsRoleIR, SCHEMA_SNAPSHOT_FILENAME, SCHEMA_SNAPSHOT_VERSION, SHAPES_FILENAME, type SandboxUsage, type SchemaDrift, type SchemaDriftDecision, type SchemaIR, type SchemaSnapshot, SchemaSnapshotParseError, type ShapeIR, type StorageRuleIR, type StorageRulesMetadataIR, type TableIR, type TableSnapshot, VERSION, type ValidatorIR, type VectorIndexIR, WORKFLOWS_FILENAME, type WorkflowIR, type WranglerVariableIR, buildOpenApiDocument, buildOpenRpcDocument, buildSchemaSnapshot, createCodegenProject, diagnosticAt, diffSchemaSnapshots, discoverAgents, discoverAuthApiCalls, discoverContainers, discoverCrons, discoverFlags, discoverFunctions, discoverHttpRoutes, discoverInserts, discoverMaskProcedures, discoverMigrations, discoverMutators, discoverNondeterministicCalls, discoverNotifyCalls, discoverNotifyConfig, discoverQueries, discoverQueues, discoverR2sqlCalls, discoverRlsMetadata, discoverRlsProcedures, discoverSandboxUsage, discoverSchema, discoverShapes, discoverStorageRulesMetadata, discoverWorkflows, emitAgents, emitApi, emitApp, emitCollections, emitContainers, emitCrons, emitDataModel, emitDrizzleSchema, emitFunctions, emitOpenApi, emitOpenApiModule, emitOpenRpc, emitOpenRpcModule, emitServer, emitShard, emitVectors, emitWorkflows, emitWranglerCronTriggers, evaluateSchemaDrift, formatAdvisories, lintSchema, parseSchemaSnapshot, platformMatrixIds, readProjectTarget, redact, refreshCodegenProject, resolveCodegenTarget, runCodegen, schemaFromIr, secretKindOf, serializeSchemaSnapshot, toAdvisorContext, validatorIrToJsonSchema };
|
|
3329
|
+
export { AGENTS_FILENAME, type AgentIR, type AuthApiCallIR, CONTAINERS_FILENAME, CodegenDiagnosticError, type CodegenOptions, type CodegenResult, type ContainerIR, type CronJobIR, DEFAULT_TARGET, type DriftChange, type DriftScope, type EmitAppOptions, FLAGS_FILENAME, type FieldSnapshot, type FlagsIR, type FunctionIR, GENERATED_HEADER, type HttpRouteIR, type IndexIR, type IndexSnapshot, type InsertWriteIR, LUNORA_ERROR_CODES, type LintSchemaOptions, MUTATORS_FILENAME, type MaskProcedureIR, type MigrationIR, type MutatorIR, NOTIFY_FILENAME, OPENRPC_VERSION, type OpenApiEmitInput, type OpenRpcEmitInput, type PlatformDiagnostic, type ProjectIR, QUEUES_FILENAME, type QueryReadIR, type QueueIR, type R2sqlCallIR, type RelationSnapshot, type RlsMetadataIR, type RlsPolicyIR, type RlsProcedureIR, type RlsRoleIR, SCHEMA_SNAPSHOT_FILENAME, SCHEMA_SNAPSHOT_VERSION, SHAPES_FILENAME, type SandboxUsage, type SchemaDrift, type SchemaDriftDecision, type SchemaIR, type SchemaSnapshot, SchemaSnapshotParseError, type ShapeIR, type StorageRuleIR, type StorageRulesMetadataIR, type TableIR, type TableSnapshot, VERSION, type ValidatorIR, type VectorIndexIR, WORKFLOWS_FILENAME, type WorkflowIR, type WranglerVariableIR, buildOpenApiDocument, buildOpenRpcDocument, buildSchemaSnapshot, createCodegenProject, describeErrorLevelFindings, diagnosticAt, diffSchemaSnapshots, discoverAgents, discoverAuthApiCalls, discoverContainers, discoverCrons, discoverFlags, discoverFunctions, discoverHttpRoutes, discoverInserts, discoverMaskProcedures, discoverMigrations, discoverMutators, discoverNondeterministicCalls, discoverNotifyCalls, discoverNotifyConfig, discoverQueries, discoverQueues, discoverR2sqlCalls, discoverRlsMetadata, discoverRlsProcedures, discoverSandboxUsage, discoverSchema, discoverShapes, discoverStorageRulesMetadata, discoverWorkflows, emitAgents, emitApi, emitApp, emitCollections, emitContainers, emitCrons, emitDataModel, emitDrizzleSchema, emitFunctions, emitOpenApi, emitOpenApiModule, emitOpenRpc, emitOpenRpcModule, emitServer, emitShard, emitVectors, emitWorkflows, emitWranglerCronTriggers, errorAdvisoryNames, errorPlatformDiagnosticNames, evaluateSchemaDrift, formatAdvisories, lintSchema, parseSchemaSnapshot, platformMatrixIds, readPackageDependencies, readProjectTarget, redact, refreshCodegenProject, resolveCodegenTarget, runCodegen, schemaFromIr, secretKindOf, serializeSchemaSnapshot, toAdvisorContext, validatorIrToJsonSchema };
|