@lunora/codegen 1.0.0-alpha.235 → 1.0.0-alpha.237

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/index.d.mts +150 -122
  2. package/dist/index.d.ts +150 -122
  3. package/dist/index.mjs +1 -1
  4. package/dist/packem_shared/GENERATED_HEADER-DSXl0YM2.mjs +1 -0
  5. package/dist/packem_shared/OPENRPC_VERSION-Cl6P9WGv.mjs +3 -0
  6. package/dist/packem_shared/{SCHEMA_SNAPSHOT_FILENAME-BtMVx-4j.mjs → SCHEMA_SNAPSHOT_FILENAME-BxnbL9RB.mjs} +4 -4
  7. package/dist/packem_shared/buildOpenApiDocument-nYvBhjxu.mjs +3 -0
  8. package/dist/packem_shared/capabilities-DJJWVEtk.mjs +18 -0
  9. package/dist/packem_shared/{describeErrorLevelFindings-D23VSkFP.mjs → describeErrorLevelFindings-vzaGS9KL.mjs} +1 -1
  10. package/dist/packem_shared/emitAgents-BPFw6ww2.mjs +1 -0
  11. package/dist/packem_shared/emitApi-CJ9ziZnP.mjs +154 -0
  12. package/dist/packem_shared/{emitApp-CTLwFZHO.mjs → emitApp-BGhO5bhT.mjs} +3 -3
  13. package/dist/packem_shared/emitCrons-mkwWkn0R.mjs +69 -0
  14. package/dist/packem_shared/emitDataModel-D3WuEZ4b.mjs +113 -0
  15. package/dist/packem_shared/emitDrizzleSchema-Cv0HtLR3.mjs +15 -0
  16. package/dist/packem_shared/emitFunctions-BqAz1ssY.mjs +249 -0
  17. package/dist/packem_shared/emitServer-BEo_fCY8.mjs +365 -0
  18. package/dist/packem_shared/emitShard-Bu7EKdou.mjs +1 -0
  19. package/dist/packem_shared/fingerprintSchemaSources-L3nGKDQt.mjs +1 -0
  20. package/dist/packem_shared/json-data-Chfs2Cz5.mjs +1 -0
  21. package/dist/packem_shared/qualifiers-BhOL15WZ.mjs +1 -0
  22. package/dist/packem_shared/shard-B3LMNjIg.mjs +1435 -0
  23. package/dist/packem_shared/shard-runtime-B_ppYvOf.mjs +323 -0
  24. package/dist/packem_shared/shared-DjUziztz.mjs +9 -0
  25. package/package.json +3 -3
  26. package/dist/packem_shared/GENERATED_HEADER-Da0OC3EI.mjs +0 -1
  27. package/dist/packem_shared/OPENRPC_VERSION-CL0VnCPW.mjs +0 -3
  28. package/dist/packem_shared/buildOpenApiDocument-C7S5wJCl.mjs +0 -3
  29. package/dist/packem_shared/emit-DUpkZ68h.mjs +0 -2696
@@ -0,0 +1,249 @@
1
+ import{LunoraError as B}from"@lunora/errors";import{L as H,G as q,I as J,d as Q,r as G,b as z,c as x}from"./shared-DjUziztz.mjs";import{s as p}from"./paths-C-9fwEgQ.mjs";import{renderAgentFunctionRegistry as V,renderSandboxFunctionRegistry as W,groupByFileSorted as K}from"./emitApi-CJ9ziZnP.mjs";import{r as Y,a as X,b as O,c as Z}from"./qualifiers-BhOL15WZ.mjs";const ee=new Set(["any","bigint","boolean","date","id","null","number","storage","string","timestamp"]),A=n=>n.column!==void 0,te=(n,e)=>{switch(n){case"bigint":return`if (typeof ${e} !== "bigint") return DEFER;
2
+ `;case"boolean":return`if (typeof ${e} !== "boolean") return DEFER;
3
+ `;case"date":case"number":case"timestamp":return`if (typeof ${e} !== "number" || !Number.isFinite(${e})) return DEFER;
4
+ `;case"null":return`if (${e} !== null) return DEFER;
5
+ `;default:return`if (typeof ${e} !== "string") return DEFER;
6
+ `}},ne=(n,e)=>n.stringMaxLength===void 0?"":`if (${e}.length > ${String(n.stringMaxLength)}) return DEFER;
7
+ `,re=(n,e)=>{const r=n.literalValue?.trim();if(!(r===void 0||!H.test(r)))return{out:e,pre:`if (${e} !== ${r}) return DEFER;
8
+ `}},v=(n,e,r)=>{if(!A(n)&&!(n.unmodelledRefinement||n.sourceText!==void 0)){if(ee.has(n.kind))return n.kind==="any"?{out:e,pre:""}:{out:e,pre:te(n.kind,e)+ne(n,e)};switch(n.kind){case"array":return oe(n,e,r);case"literal":return re(n,e);case"object":return ie(n,e,r);default:return}}},oe=(n,e,r)=>{const{inner:c}=n;if(!c)return;const o=r.next(),a=`__arr${String(o)}`,i=`__i${String(o)}`,s=`__e${String(o)}`,l=v(c,s,r);if(!l)return;const u=`if (!Array.isArray(${e})) return DEFER;
9
+ const ${a} = new Array(${e}.length);
10
+ for (let ${i} = 0; ${i} < ${e}.length; ${i}++) {
11
+ const ${s} = ${e}[${i}];
12
+ ${l.pre}${a}[${i}] = ${l.out};
13
+ }
14
+ `;return{out:a,pre:u}},ae=(n,e,r,c)=>{const o=JSON.stringify(n);if(e.kind==="optional"){if(e.hasRefinement||e.sourceText!==void 0||A(e))return;const{inner:i}=e;if(!i)return;const s=v(i,r,c);if(!s)return;const l=c.next(),u=`__has${String(l)}`,d=`__val${String(l)}`,f=`let ${u} = false;
15
+ let ${d};
16
+ if (${r} !== undefined) {
17
+ ${s.pre}${d} = ${s.out};
18
+ ${u} = true;
19
+ }
20
+ `;return{entry:`...(${u} ? { ${o}: ${d} } : {})`,pre:f}}const a=v(e,r,c);if(a)return{entry:`${o}: ${a.out}`,pre:a.pre}},se=new Set(Object.getOwnPropertyNames(Object.prototype)),_=(n,e,r)=>{let c="";const o=[];for(const a of Object.keys(n)){const i=n[a];if(!i)return;const s=JSON.stringify(a);let l=`${e}[${s}]`;if(se.has(a)){const d=`__f${String(r.next())}`;c+=`const ${d} = Object.hasOwn(${e}, ${s}) ? ${e}[${s}] : undefined;
21
+ `,l=d}const u=ae(a,i,l,r);if(!u)return;c+=u.pre,o.push(u.entry)}return{entries:o.join(", "),pre:c}},T=n=>{const e=`Object.getPrototypeOf(${n})`;return`if (${e} !== Object.prototype && ${e} !== null) return DEFER;
22
+ `},ie=(n,e,r)=>{const c=n.shape??{},o=_(c,e,r);if(!o)return;const a=r.next(),i=`__obj${String(a)}`,s=`if (typeof ${e} !== "object" || ${e} === null || Array.isArray(${e})) return DEFER;
23
+ ${T(e)}${o.pre}const ${i} = { ${o.entries} };
24
+ `;return{out:i,pre:s}},ce=n=>{let e=0;const c=_(n,"source",{next:()=>(e+=1,e)});if(c)return`(source) => {
25
+ if (typeof source !== "object" || source === null || Array.isArray(source)) return DEFER;
26
+ ${T("source")}${c.pre}return { ${c.entries} };
27
+ }`},le=(n,e)=>`lunora_${p(n)}_${String(e)}`,ue=`const callRegistered = async <R>(context: CallerCtx, functionPath: string, args: Record<string, unknown> | undefined): Promise<R> => {
28
+ const registered = LUNORA_FUNCTIONS[functionPath];
29
+
30
+ if (!registered) {
31
+ throw new LunoraError("FUNCTION_NOT_FOUND", \`function not registered: \${functionPath}\`);
32
+ }
33
+
34
+ // A mutation is routed through the caller's own \`ctx.runMutation\` rather than
35
+ // invoked directly, so \`createCaller(ctx).ns.someMutation()\` gets exactly what
36
+ // \`ctx.runMutation(api.ns.someMutation)\` gets: the BEGIN/COMMIT span (or the
37
+ // enclosing one, when the caller is already inside a transaction), the jobs it
38
+ // schedules held until that span commits, and the deferred object deletes
39
+ // flushed only once it has. Called straight, a mutation composed from an action
40
+ // or a stream had none of the three — its writes autocommitted one row at a
41
+ // time and its \`ctx.scheduler\` calls dispatched immediately, so a mid-handler
42
+ // throw left the earlier writes durable and the job already enqueued.
43
+ //
44
+ // The fallback covers a context that is not a shard dispatch (\`runMutation\` is
45
+ // installed by \`buildCtx\` on every kind but a query's TYPE omits it); there is
46
+ // no transaction to join in that case, so a direct call is all there is.
47
+ //
48
+ // A query is routed through \`ctx.runQuery\` for the same reason: that is what
49
+ // hands it a query view of a mutation's or action's ctx (no request origin,
50
+ // query-guarded \`run*\`) instead of the caller's own.
51
+ if (registered.kind === "mutation" || registered.kind === "query") {
52
+ const run = (context as { runMutation?: unknown; runQuery?: unknown })[registered.kind === "mutation" ? "runMutation" : "runQuery"];
53
+
54
+ if (typeof run === "function") {
55
+ return (await run.call(context, { __lunoraRef: functionPath }, args ?? {})) as R;
56
+ }
57
+ }
58
+
59
+ return (await registered.handler(context, args ?? {})) as R;
60
+ };`,de=(n,e,r=[],c=[])=>{const o=new Map,a=t=>{o.has(t)||o.set(t,le(t,o.size))};for(const t of n)a(t.filePath);for(const t of e)a(t.filePath);for(const t of r)a(t.filePath);for(const t of c)a(t.filePath);const i=[...o.entries()].map(([t,g])=>{if(!J.test(t))throw new B("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(t)}`);return`import * as ${g} from "../${t}.js";`}).join(`
61
+ `),s=n.map(t=>` "${p(t.filePath)}:${t.exportName}": ${o.get(t.filePath)??""}.${t.exportName} as unknown as RegisteredLunoraFunction,`).join(`
62
+ `),l=e.map(t=>` ${JSON.stringify(t.id)}: ${o.get(t.filePath)??""}.${t.exportName} as unknown as RegisteredDataMigration,`).join(`
63
+ `),u=r.map(t=>` "${p(t.filePath)}:${t.exportName}": ${o.get(t.filePath)??""}.${t.exportName} as unknown as RegisteredLunoraFunction,`).join(`
64
+ `),d=c.map(t=>` "${t.exportName}": ${o.get(t.filePath)??""}.${t.exportName} as unknown as RegisteredShape,`).join(`
65
+ `),f=r.map(t=>`${p(t.filePath)}:${t.exportName}`),m=[s,u].filter(t=>t.length>0).join(`
66
+ `),R=n.map(t=>{if(t.lifecycle||Object.keys(t.args).length===0)return;const g=ce(t.args);return g===void 0?void 0:`installCompiledValidatorMap(${o.get(t.filePath)??""}.${t.exportName}.args, ${g});`}).filter(t=>t!==void 0).join(`
67
+ `);return{dispatchBody:m.length>0?`
68
+ ${m}
69
+ `:"",importBlock:i.length>0?`${i}
70
+
71
+ `:"",installBlock:R,migrationBody:l.length>0?`
72
+ ${l}
73
+ `:"",mutatorPaths:f,shapeBody:d.length>0?`
74
+ ${d}
75
+ `:""}},he=n=>{const e=K(n),r=e.map(([o,a])=>{const i=a.map(s=>{const l=O(G(s.args),s.filePath),u=l==="{}"?"?":"",d=O(Z(s),s.filePath);return s.kind==="stream"?` ${s.exportName}: (args${u}: ${l}) => Promise<AsyncIterable<${d}>>;`:` ${s.exportName}: (args${u}: ${l}) => Promise<${d}>;`}).join(`
76
+ `);return` ${z(p(o))}: {
77
+ ${i}
78
+ };`}).join(`
79
+ `);return{implementation:e.map(([o,a])=>{const i=p(o),s=a.map(l=>` ${x(l.exportName)}: (args) => callRegistered(context, "${i}:${l.exportName}", args),`).join(`
80
+ `);return` ${x(i)}: {
81
+ ${s}
82
+ },`}).join(`
83
+ `),types:r}},pe=n=>{const e={connect:[],disconnect:[],init:[],reactor:[],whisper:[]};for(const r of n)r.lifecycle&&e[r.lifecycle].push(`${p(r.filePath)}:${r.exportName}`);return e},be=n=>{const{agents:e=[],functions:r,migrations:c=[],mutators:o=[],shapes:a=[],useUmbrella:i=!1,usesSandbox:s=!1}=n,l=r.length>0,u=Q(i),{dispatchBody:d,importBlock:f,installBlock:m,migrationBody:R,mutatorPaths:t,shapeBody:g}=de(r,c,o,a),b=V(e,r),w=W(s,r),k=[b.lines,w.lines].filter(h=>h.length>0).join(`
84
+ `);let N=d;k.length>0&&(N=d.length>0?`${d.trimEnd()}
85
+ ${k}
86
+ `:`
87
+ ${k}
88
+ `);const y=pe(r),P=a.length>0?`import type { RegisteredShape } from "${u.server}";
89
+ `:"",L=a.length>0?`
90
+ /**
91
+ * Replication-shape registry — one entry per \`defineShape\` in \`lunora/shapes.ts\`.
92
+ * The generated ShardDO's \`resolveShape\` override looks a shape up by name and
93
+ * evaluates its trusted \`compileWhere(ctx, args)\` to authorize + scope a
94
+ * \`shape_subscribe\` (reads-as-permissions).
95
+ */
96
+ export const LUNORA_SHAPES: Record<string, RegisteredShape> = {${g}};
97
+ `:"",j=t.length>0?`
98
+ /**
99
+ * Custom-mutator function paths — the \`LUNORA_FUNCTIONS\` keys the generated
100
+ * ShardDO's \`isCustomMutator\` override routes through the client-watermark push
101
+ * protocol (\`x-lunora-client-id\`/\`x-lunora-client-seq\` ordering).
102
+ */
103
+ export const LUNORA_MUTATOR_PATHS: ReadonlySet<string> = new Set([${t.map(h=>JSON.stringify(h)).join(", ")}]);
104
+ `:"",E=m.length>0?`import { DEFER_VALIDATION as DEFER, installCompiledValidatorMap } from "${u.values}";
105
+ `:"",C=m.length>0?`
106
+ /**
107
+ * AOT-compiled argument validators (Worker-safe, no \`eval\`). Each is installed
108
+ * onto its function's live \`.args\` object and consulted by the interpreted
109
+ * parser as a zero-allocation fast path; anything it can't model is deferred.
110
+ */
111
+ ${m}
112
+ `:"",$=he(r),F=$.types?`
113
+ ${$.types}
114
+ `:"",M=$.implementation?`
115
+ ${$.implementation}
116
+ `:"",S=Y($.types),D=S.length>0?`import type { ${S.join(", ")} } from "./dataModel.js";
117
+ `:"",I=l?"context":"_context",U=l?`${ue}
118
+
119
+ `:"";return X(`${q}${f}${b.importLine}${w.importLine}${E}${P}import { LunoraError } from "${u.server}";
120
+ import type { ActionCtx, MutationCtx, QueryCtx } from "./server.js";
121
+ ${D}
122
+ /**
123
+ * Single registered function, narrowed to the shape \`handleRpc\` needs.
124
+ * The real argument validators / return types are checked elsewhere — at
125
+ * the dispatch site we erase to \`unknown\` so a single map can host every
126
+ * registered function.
127
+ */
128
+ export interface RegisteredLunoraFunction {
129
+ kind: "action" | "mutation" | "query" | "stream";
130
+ args: Record<string, unknown>;
131
+ /**
132
+ * Present on a \`"stream"\` declared \`durable\`: its run is persisted and
133
+ * survives the socket that opened it. Absent on every other kind, and on an
134
+ * ephemeral stream.
135
+ */
136
+ durable?: { ttlMs?: number };
137
+ /**
138
+ * For \`"action" | "mutation" | "query"\` the handler is awaited and its result returned.
139
+ * For \`"stream"\` the handler returns an \`AsyncIterable\` synchronously and takes an
140
+ * \`AbortSignal\` as a third argument — the runtime drives it frame-by-frame.
141
+ */
142
+ handler: ((context: unknown, args: Record<string, unknown>) => Promise<unknown> | unknown) | ((context: unknown, args: Record<string, unknown>, signal?: AbortSignal) => AsyncIterable<unknown>);
143
+ /**
144
+ * The lifecycle moment a hook fires on, when this registration came from
145
+ * \`onConnect\`/\`onDisconnect\`/\`onShardInit\`/\`onQueryChange\`/\`onWhisper\`.
146
+ * Read at dispatch to decide whether the function runs system-trusted:
147
+ * \`init\` and \`reactor\` have no caller identity, so RLS has no user to scope
148
+ * to. \`whisper\` does have one — it runs under the asking socket's identity.
149
+ */
150
+ lifecycle?: "connect" | "disconnect" | "init" | "reactor" | "whisper";
151
+ /**
152
+ * Hoisted by the builder when the \`.use()\` chain carries a step with a
153
+ * per-dispatch effect — \`rateLimit(...)\` consuming budget, a single-use
154
+ * captcha token being burned. Read by \`isCacheableQuery\`: the chain runs
155
+ * inside the dispatch callback, and a reactive-cache HIT skips that
156
+ * callback, so such a query must never be memoized.
157
+ */
158
+ perDispatch?: boolean;
159
+ /** \`"internal"\` functions are rejected on the external RPC path; absence === public. */
160
+ visibility?: "internal" | "public";
161
+ /**
162
+ * \`.x402({ price })\` tag on a paid public procedure. The origin worker
163
+ * paywalls it; the shard refuses to subscribe it (\`isPaidFunction\`).
164
+ */
165
+ x402?: { readonly price: number | string };
166
+ }
167
+ ${b.prelude}${w.prelude}
168
+ /**
169
+ * Static dispatch table. The key matches the \`__lunoraRef\` the client
170
+ * emits (\`api[namespace][fn].__lunoraRef === "namespace:fn"\`).
171
+ */
172
+ export const LUNORA_FUNCTIONS: Record<string, RegisteredLunoraFunction> = {${N}};
173
+ ${C}${L}${j}
174
+ /**
175
+ * Lifecycle manifest: the function paths the generated ShardDO dispatches when a
176
+ * client's WebSocket connects (\`connect\`) or disconnects (\`disconnect\`), once
177
+ * per Durable Object instance before any handler runs (\`init\`), after a
178
+ * write flush when a watched read's result changed (\`reactor\`), and before a
179
+ * socket joins or broadcasts to a whisper topic (\`whisper\`). Each path also
180
+ * resolves through {@link LUNORA_FUNCTIONS}. The socket-scoped moments run under
181
+ * the socket's verified identity; \`init\` and \`reactor\` have no caller, so they
182
+ * run anonymous — all via system dispatch.
183
+ */
184
+ export const LUNORA_LIFECYCLE_HOOKS: {
185
+ connect: readonly string[];
186
+ disconnect: readonly string[];
187
+ init: readonly string[];
188
+ reactor: readonly string[];
189
+ whisper: readonly string[];
190
+ } = {
191
+ connect: [${y.connect.map(h=>JSON.stringify(h)).join(", ")}],
192
+ disconnect: [${y.disconnect.map(h=>JSON.stringify(h)).join(", ")}],
193
+ init: [${y.init.map(h=>JSON.stringify(h)).join(", ")}],
194
+ reactor: [${y.reactor.map(h=>JSON.stringify(h)).join(", ")}],
195
+ whisper: [${y.whisper.map(h=>JSON.stringify(h)).join(", ")}],
196
+ };
197
+
198
+ /**
199
+ * Resolve and invoke a registered function from an external caller. Throws a
200
+ * LunoraError-shaped object (404) when the path is unknown — the runtime's
201
+ * structural error mapper turns that into the right HTTP status. Internal
202
+ * functions are treated as not-found so their existence never leaks to clients.
203
+ */
204
+ export const dispatchLunoraFunction = async (functionPath: string, context: unknown, args: Record<string, unknown>): Promise<unknown> => {
205
+ const registered = LUNORA_FUNCTIONS[functionPath];
206
+
207
+ if (!registered || registered.visibility === "internal") {
208
+ throw new LunoraError("FUNCTION_NOT_FOUND", \`function not registered: \${functionPath}\`);
209
+ }
210
+
211
+ return registered.handler(context, args);
212
+ };
213
+
214
+ /**
215
+ * A handler context accepted by {@link createCaller}. The runtime context the
216
+ * shard DO builds is uniform across kinds, so any handler's \`ctx\` works here.
217
+ */
218
+ export type CallerCtx = ActionCtx | MutationCtx | QueryCtx;
219
+
220
+ /**
221
+ * Typed, in-process server-to-server caller. Every registered function — public
222
+ * *and* internal — is reachable; each call dispatches against the same shard
223
+ * with the supplied \`context\`, exactly like \`ctx.runQuery\`/\`runMutation\`/
224
+ * \`runAction\` but without re-stating the function path.
225
+ */
226
+ export interface Caller {${F}}
227
+
228
+ ${U}/** Build a {@link Caller} bound to \`context\` (typically a handler's \`ctx\`). */
229
+ export const createCaller = (${I}: CallerCtx): Caller => ({${M}});
230
+
231
+ /**
232
+ * Single registered data migration, narrowed to the shape the per-shard runner
233
+ * consumes. \`up\`/\`down\` are erased to a structural transform; the authoring
234
+ * validation lives in \`defineMigration\`.
235
+ */
236
+ export interface RegisteredDataMigration {
237
+ batchSize?: number;
238
+ down?: (document: Record<string, unknown>) => Record<string, unknown> | undefined;
239
+ id: string;
240
+ table: string;
241
+ up: (document: Record<string, unknown>) => Record<string, unknown> | undefined;
242
+ }
243
+
244
+ /**
245
+ * Registry of online data migrations keyed by \`defineMigration\`'s \`id\`. The
246
+ * shard DO's admin RPC and the CLI resolve migrations to run through this map.
247
+ */
248
+ export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${R}};
249
+ `,i)};export{be as default};
@@ -0,0 +1,365 @@
1
+ import{LunoraError as Ie}from"@lunora/errors";import{S as $e}from"./capabilities-DJJWVEtk.mjs";import{a as c,G as Re,u as Be,d as Oe}from"./shared-DjUziztz.mjs";const De=(l,s=[])=>{const t=new Set;for(const a of l.tables)for(const n of Object.values(a.shape)){const i=Be(n);i.kind==="storage"&&typeof i.bucket=="string"&&i.bucket!==""&&t.add(i.bucket)}for(const a of s)a!==""&&a!=="default"&&t.add(a);return["default",...[...t].toSorted((a,n)=>a.localeCompare(n))]},Fe=({agents:l=[],containers:s=[],env:t,hasAccessFacade:a=!1,hasAi:n=!1,hasAnalytics:i=!1,hasBrowser:E=!1,hasVectors:P=!0,hasFlags:j=!1,hasHyperdrive:q=!1,hasImages:L=!1,hasKv:V=!1,hasNotify:G=!1,hasPayments:O=!1,hasPipelines:_=!1,hasR2sql:H=!1,hasX402:D=!1,identity:d,queues:m=[],schema:M,storageRuleBuckets:z=[],useUmbrella:U=!1,workflows:b=[]}={})=>{const r=Oe(U),K=De(M??{tables:[]},z).map(e=>JSON.stringify(e)).join(" | "),X=n?`import type { LunoraAi } from "@lunora/ai";
2
+ `:"",J=n?`
3
+ readonly ai: LunoraAi;`:"",Y=O?`import type { LunoraPayment } from "@lunora/payment";
4
+ `:"",Z=O?`
5
+ readonly payments: LunoraPayment;`:"",ee=D?`import type { X402Pay } from "@lunora/x402/pay";
6
+ `:"",te=D?`
7
+ readonly x402: X402Pay;`:"",ae=s.length>0?`import type { ContainerAccessor } from "@lunora/container";
8
+ `:"",re=s.length>0?`
9
+ readonly containers: {${s.map(e=>`
10
+ readonly ${e.exportName}: ContainerAccessor;`).join("")}
11
+ };`:"",N=[...n?[" /** Workers AI binding (the conventional `env.AI`), narrowing `ctx.ai`. */\n readonly AI?: unknown;"]:[],...s.map(e=>(c(e.bindingName,`container binding "${e.bindingName}"`),` /** Durable Object namespace for the \`${e.exportName}\` container. */
12
+ readonly ${e.bindingName}?: unknown;`)),...b.map(e=>(c(e.bindingName,`workflow binding "${e.bindingName}"`),` /** Workflow binding for the \`${e.exportName}\` workflow. */
13
+ readonly ${e.bindingName}?: unknown;`)),...m.map(e=>(c(e.bindingName,`queue binding "${e.bindingName}"`),` /** Queue producer binding for the \`${e.exportName}\` queue. */
14
+ readonly ${e.bindingName}?: unknown;`)),...l.map(e=>(c(e.bindingName,`agent binding "${e.bindingName}"`),` /** Workflow binding for the \`${e.exportName}\` agent. */
15
+ readonly ${e.bindingName}?: unknown;`))].join(`
16
+ `),ne=`
17
+
18
+ /**
19
+ * This project's Cloudflare bindings, as far as codegen can discover them from
20
+ * \`lunora/\` source — the container/workflow Durable Object namespaces and the
21
+ * conventional Workers AI binding. Bindings the config layer reconciles from
22
+ * user-named wrangler config (R2/KV/D1/\`services\`/queues/…) aren't statically
23
+ * visible here, so the open index signature keeps them reachable (cast at the
24
+ * use site). Service bindings (\`env.<SERVICE>.fetch(...)\` / RPC stubs) live
25
+ * under this signature too — Lunora can't type a third-party worker's RPC
26
+ * surface, so treat them as \`Fetcher\`/\`Service<unknown>\` and cast.
27
+ */
28
+ export interface CloudflareBindings {
29
+ readonly [binding: string]: unknown;${N?`
30
+ ${N}`:""}
31
+ }
32
+
33
+ /** Alias for {@link CloudflareBindings} — the typed shape of \`env\`. */
34
+ export type Env = CloudflareBindings;`,o=(e,we,Q)=>{const y=$e.get(e);if(y!==void 0&&y.tier!==Q)throw new Ie("INTERNAL",`@lunora/codegen: capability "${e}" declares tier "${y.tier}" in SERVER_CTX_FIELDS but is emitted onto the "${Q}" context — update whichever is wrong.`);return we?y?.field??"":""},h=o("kv",V,"every"),f=o("analytics",i,"every"),oe=o("hyperdrive",q,"action"),se=o("browser",E,"action"),ie=o("images",L,"action"),de=o("pipelines",_,"action"),le=o("r2sql",H,"action"),u=P&&(M?.vectorIndexes.length??0)>0,x=u?' | "vectors"':"",A=u?`
35
+ readonly vectors: VectorSearch<VectorIndexName>;`:"",ce=u?`
36
+ readonly vectors: VectorSearchReader<VectorIndexName>;`:"",ue=u?`import type { VectorSearch, VectorSearchReader } from "${r.server}";
37
+ import type { VectorIndexName } from "./dataModel.js";
38
+ `:"",g=a?`
39
+ /** Verified Cloudflare Access identity — a synchronous facade over the resolved claims (email / groups / hasGroup / claims). Anonymous when no Access token is present. */
40
+ readonly access: import("@lunora/cloudflare-access/context").AccessFacade;`:"",T=j?`
41
+ /** Feature-flag evaluation (OpenFeature). Reads are memoized per request; evaluations never throw — a provider error resolves to the supplied default. */
42
+ readonly flags: import("${r.flags}").LunoraFlags;`:"",v=G?`
43
+ /** Multi-channel notifications (@lunora/notify): send / chat / inApp / webhook plus the push device sub-facade. Sends are external I/O — confine them to action handlers. */
44
+ readonly notify: import("@lunora/notify").LunoraNotify;
45
+ /** Device push sub-facade — the same object as ctx.notify.push (register / send / broadcast). Sends belong in action handlers. */
46
+ readonly push: import("@lunora/notify").LunoraPush;`:"",p=b.length>0,pe=p?`import type { WorkflowHandle } from "@lunora/workflow";
47
+ import type * as lunoraWorkflowDefinitions from "../workflows.js";
48
+ `:"",ye=p?`
49
+
50
+ /** Params type carried by a \`defineWorkflow\` definition (its phantom \`__params\`). */
51
+ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params }
52
+ ? unknown extends Params
53
+ ? Record<string, unknown>
54
+ : NonNullable<Params>
55
+ : Record<string, unknown>;
56
+
57
+ /** This project's declared workflows, addressable from \`ctx.workflows\` by their \`lunora/workflows.ts\` export name. */
58
+ export interface LunoraWorkflows {
59
+ ${b.map(e=>` get(name: ${JSON.stringify(e.exportName)}): WorkflowHandle<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${e.exportName}>>;`).join(`
60
+ `)}
61
+ }`:"",C=p?' | "workflows"':"",F=p?`
62
+ readonly workflows: LunoraWorkflows;`:"",k=m.length>0,me=k?`import type { QueueProducer } from "@lunora/queue";
63
+ import type * as lunoraQueueDefinitions from "../queues.js";
64
+ `:"",be=k?`
65
+
66
+ /** Message body type carried by a \`defineQueue\` definition (its phantom \`__lunoraBody\`). */
67
+ type QueueBodyOf<Definition> = Definition extends { __lunoraBody?: infer Body } ? (unknown extends Body ? unknown : NonNullable<Body>) : unknown;
68
+
69
+ /** This project's declared queues, addressable from \`ctx.queues\` by their \`lunora/queues.ts\` export name. */
70
+ export interface LunoraQueues {
71
+ ${m.map(e=>` readonly ${e.exportName}: QueueProducer<QueueBodyOf<typeof lunoraQueueDefinitions.${e.exportName}>>;`).join(`
72
+ `)}
73
+ }`:"",S=k?`
74
+ readonly queues: LunoraQueues;`:"",w=l.length>0,he=w?`import type { AgentHandle } from "@lunora/agent";
75
+ `:"",fe=w?`
76
+
77
+ /** This project's declared agents, addressable from \`ctx.agents\` by their \`lunora/agents.ts\` export name. */
78
+ export interface LunoraAgents {
79
+ ${l.map(e=>(c(e.exportName,`agent export "${e.exportName}"`),` readonly ${e.exportName}: AgentHandle;`)).join(`
80
+ `)}
81
+ }`:"",W=w?`
82
+ readonly agents: LunoraAgents;`:"",xe=d?`import type { InferIdentity } from "${r.server}";
83
+ import type * as lunoraIdentityContract from "../identity.js";
84
+ `:"",ge=d?`
85
+
86
+ /** This app's declared identity claim contract (\`defineIdentity\` in \`lunora/identity.ts\`) — the typed shape of \`ctx.auth.getIdentity()\`, the RLS policy \`ctx.auth.identity\`, and the \`authorizeShard\`/\`authorizeFanOut\` identity argument. */
87
+ export type Identity = InferIdentity<typeof lunoraIdentityContract.${d.exportName}>;
88
+
89
+ /** \`ctx.auth\` narrowed so \`getIdentity()\` resolves the declared {@link Identity} contract instead of the untyped claim bag. */
90
+ type NarrowedAuth = Omit<QueryCtxBase["auth"], "getIdentity"> & { getIdentity: () => Promise<Identity | null> };`:"",I=d?' | "auth"':"",$=d?`
91
+ readonly auth: NarrowedAuth;`:"",Te=d?", Identity":"",ve=t?`import type * as lunoraEnvContract from "../env.js";
92
+ `:"",ke=t?`
93
+
94
+ /** This app's declared env contract (\`defineEnv\` in \`lunora/env.ts\`) — the validated, coercion-aware shape of \`ctx.env\`. */
95
+ export type LunoraEnv = ReturnType<typeof lunoraEnvContract.${t.exportName}>;`:"",R=t?' | "env"':"",B=t?"\n /** Validated, typed environment declared by `defineEnv` in `lunora/env.ts` — parsed & coercion-aware config values (`ctx.env.STRIPE_KEY`); a missing or invalid value throws at read time. */\n readonly env: LunoraEnv;":"";return`${Re}import { createPolicyDsl, defineMutator as defineMutatorBase, initLunora, v as vBase } from "${r.server}";
96
+ import type {
97
+ ActionBuilder,
98
+ ActionCtx as ActionCtxBase,
99
+ ColumnValidator,
100
+ DatabaseReader,
101
+ DatabaseWriter,
102
+ EmptyArgs,
103
+ InternalActionBuilder,
104
+ InternalMutationBuilder,
105
+ InternalQueryBuilder,
106
+ MutationBuilder,
107
+ MutationCtx as MutationCtxBase,
108
+ MutationStorage,
109
+ MutatorDefinition,
110
+ QueryBuilder,
111
+ QueryCtx as QueryCtxBase,
112
+ ReadOnlyStorage,
113
+ RegisteredMutator,
114
+ Storage as StorageBase,
115
+ TableReader,
116
+ Validator,
117
+ } from "${r.server}";
118
+
119
+ import type {
120
+ DatabaseReaderFacade as DatabaseReaderFacadeOf,
121
+ DatabaseWriterFacade as DatabaseWriterFacadeOf,
122
+ LoadWith as LoadWithOf,
123
+ TableReaderFacade as TableReaderFacadeOf,
124
+ TableWriterFacade as TableWriterFacadeOf,
125
+ WithArg as WithArgOf,
126
+ } from "${r.serverDataModel}";
127
+
128
+ export type {
129
+ AggregateOp,
130
+ GroupByEntry,
131
+ OrderBy,
132
+ QueryArgs,
133
+ QueryPage,
134
+ RankPage,
135
+ RankResult,
136
+ RestrictableQueryOptions,
137
+ RestrictableQueryOptionsOf,
138
+ SearchFilterBuilder,
139
+ SearchReader,
140
+ TableAggregateOptions,
141
+ TableAggregateOptionsOf,
142
+ TableGroupByOptions,
143
+ TableGroupByOptionsOf,
144
+ TableRankOptions,
145
+ TableRankPageOptions,
146
+ Where,
147
+ WhereOf,
148
+ WhereOperators,
149
+ } from "${r.serverDataModel}";
150
+
151
+ import type { DataModel, Doc, GeoIndexNamesByTable, Id as IdOfTable, IndexNamesByTable, Insert, InsertModel, RankIndexNamesByTable, Relations, SearchIndexNamesByTable, TableName } from "./dataModel.js";
152
+ ${ue}${X}${Y}${ee}${ae}${pe}${me}${he}${xe}${ve}
153
+ export type { AppTableName, DataModel, Doc, Id, TableName } from "./dataModel.js";
154
+
155
+ /**
156
+ * The query-DSL bindings: \`@lunora/server/data-model\`'s generics parameterized
157
+ * over this project's \`DataModel\` / \`InsertModel\` / \`Relations\` / index maps.
158
+ *
159
+ * They live here rather than in \`dataModel.ts\` because they are the half that
160
+ * needs the SERVER package. Keeping \`dataModel.ts\` free of it lets a sibling
161
+ * package — a web app, another Worker — compile \`api.ts\` for its \`Doc\`/\`Id\`
162
+ * types without installing a server dependency to do it.
163
+ */
164
+
165
+ /** The \`with\` argument for table \`T\` — see \`@lunora/server/data-model\`. */
166
+ export type WithArg<T extends keyof DataModel> = WithArgOf<DataModel, Relations, T>;
167
+
168
+ /** \`Doc<T>\` narrowed to exactly the relations requested in the with-arg \`W\`. */
169
+ export type LoadWith<T extends keyof DataModel, W> = LoadWithOf<DataModel, Relations, T, W>;
170
+
171
+ /** Read-only typed table accessor exposed on \`QueryCtx.db.<table>\`. */
172
+ export type TableReaderFacade<T extends keyof DataModel> = TableReaderFacadeOf<DataModel, Relations, RankIndexNamesByTable, SearchIndexNamesByTable, T, GeoIndexNamesByTable>;
173
+
174
+ /** Read-write typed table accessor exposed on \`MutationCtx.db.<table>\` / \`ActionCtx.db.<table>\`. */
175
+ export type TableWriterFacade<T extends keyof DataModel> = TableWriterFacadeOf<DataModel, InsertModel, Relations, RankIndexNamesByTable, SearchIndexNamesByTable, T, GeoIndexNamesByTable>;
176
+
177
+ /** Per-table read facade — \`ctx.db.<table>\` on a \`QueryCtx\`. */
178
+ export type DatabaseReaderFacade = DatabaseReaderFacadeOf<DataModel, Relations, RankIndexNamesByTable, SearchIndexNamesByTable, GeoIndexNamesByTable>;
179
+
180
+ /** Per-table read-write facade — \`ctx.db.<table>\` on a \`MutationCtx\` / \`ActionCtx\`. */
181
+ export type DatabaseWriterFacade = DatabaseWriterFacadeOf<DataModel, InsertModel, Relations, RankIndexNamesByTable, SearchIndexNamesByTable, GeoIndexNamesByTable>;
182
+
183
+ /** Insert builder returned by \`ctx.orm.insert(table)\`. */
184
+ export interface OrmInsertBuilder<T extends keyof DataModel> {
185
+ values: (values: Insert<T>) => Promise<IdOfTable<T>>;
186
+ }
187
+
188
+ /** Replace builder returned by \`ctx.orm.replace(table, id)\` — swaps the whole document. */
189
+ export interface OrmReplaceBuilder<T extends keyof DataModel> {
190
+ with: (values: Insert<T>) => Promise<void>;
191
+ }
192
+
193
+ /** Update builder returned by \`ctx.orm.update(table, id)\` — patches the named fields. */
194
+ export interface OrmUpdateBuilder<T extends keyof DataModel> {
195
+ set: (values: Partial<Insert<T>>) => Promise<void>;
196
+ }
197
+
198
+ /** Read-only ORM surface — \`ctx.orm\` on a \`QueryCtx\`. Mirrors \`ctx.db\` reads under a kitcn-style \`query\` namespace. */
199
+ export interface OrmReader {
200
+ query: DatabaseReaderFacade;
201
+ }
202
+
203
+ /** Read-write ORM surface — \`ctx.orm\` on a \`MutationCtx\` / \`ActionCtx\`. Writes are addressed by id, like \`ctx.db\`. */
204
+ export interface OrmWriter extends OrmReader {
205
+ delete: <T extends keyof DataModel>(table: T, id: IdOfTable<T>) => Promise<void>;
206
+ insert: <T extends keyof DataModel>(table: T) => OrmInsertBuilder<T>;
207
+ replace: <T extends keyof DataModel>(table: T, id: IdOfTable<T>) => OrmReplaceBuilder<T>;
208
+ update: <T extends keyof DataModel>(table: T, id: IdOfTable<T>) => OrmUpdateBuilder<T>;
209
+ }
210
+
211
+ /** Storage buckets this schema declares (\`v.storage("name")\`), narrowing \`ctx.storage.bucket(name)\`. */
212
+ export type StorageBucketName = ${K};${ne}${ye}${be}${fe}${ge}${ke}
213
+
214
+ /**
215
+ * Project-typed contexts. The base contexts from \`@lunora/server\` are
216
+ * untyped against the schema; here \`db\` is widened to the generated per-table
217
+ * facade (\`ctx.db.<table>.findMany(...)\`) while keeping the legacy structural
218
+ * \`db.get\`/\`db.query\` surface for back-compat, and \`storage\` is narrowed so
219
+ * \`ctx.storage.bucket(name)\` autocompletes the declared buckets.
220
+ */
221
+ /**
222
+ * The Convex-style fluent reader \`ctx.db.query(table)\`, bound to this schema:
223
+ * a table-name literal narrows the row type, so \`.collect()\` / \`.first()\` /
224
+ * \`.take()\` (and the \`.withIndex()\` / \`.filter()\` / \`.order()\` chain) resolve
225
+ * as \`Doc<table>\` with no \`as unknown as Doc<...>\` casts. The per-table accessor
226
+ * \`ctx.db.<table>\` stays available alongside it via the facade.
227
+ *
228
+ * Intersected with the wide \`(string) => TableReader\` signature so the bound
229
+ * \`ctx.db\` is still structurally assignable to schema-agnostic consumers that
230
+ * call \`db.query(someString)\` (e.g. \`@lunora/ratelimit\`'s \`createDbStore\`).
231
+ *
232
+ * The three index-name unions are what make \`.withIndex("by_TYPO")\` a compile
233
+ * error: each resolves to the table's declared names, or \`never\` when it
234
+ * declares none of that kind. Without them a renamed or dropped index left
235
+ * every call site typechecking, and the query either threw at runtime or
236
+ * degraded silently to a full table scan.
237
+ */
238
+ type TypedTableQuery = (<T extends TableName>(
239
+ table: T,
240
+ ) => TableReader<Doc<T>, IndexNamesByTable[T], SearchIndexNamesByTable[T], GeoIndexNamesByTable[T]>) &
241
+ ((table: string) => TableReader);
242
+
243
+ /**
244
+ * The point read \`ctx.db.get(id)\`, bound to this schema: an \`Id<"table">\`
245
+ * carries its table name, so the resolved document is typed \`Doc<table>\` (or
246
+ * \`null\` when absent) with no \`as Doc<...>\` cast. Mirrors {@link TypedTableQuery}.
247
+ */
248
+ type TypedTableGet = <T extends TableName>(id: IdOfTable<T>) => Promise<Doc<T> | null>;
249
+
250
+ /**
251
+ * Resolves the \`asId\` table argument: a literal in {@link TableName} passes through, a
252
+ * genuinely-wide \`string\` (a computed name) passes through, and any OTHER literal
253
+ * collapses to \`never\` so it fails to typecheck.
254
+ *
255
+ * The \`string extends T\` arm is what distinguishes "the caller passed a computed
256
+ * string" from "the caller passed a misspelled literal" — only the wide \`string\` type
257
+ * is a supertype of \`string\`.
258
+ */
259
+ type AsIdTable<T extends string> = T extends TableName ? T : string extends T ? T : never;
260
+
261
+ /**
262
+ * The id parse boundary \`ctx.db.asId(table, id)\`, bound to this schema: a misspelled
263
+ * table literal is a compile error rather than a call that hands back a confidently-
264
+ * branded id for a table that does not exist. Mirrors {@link TypedTableQuery} /
265
+ * {@link TypedTableGet}.
266
+ *
267
+ * Deliberately NOT an intersection with a wide \`(string, string) => string\` overload:
268
+ * overload resolution would fall through to it for a bad literal, silently restoring
269
+ * the very typo hole this narrowing exists to close. {@link AsIdTable} instead keeps a
270
+ * computed table name working — and keeps \`ctx.db\` structurally assignable to
271
+ * schema-agnostic consumers — without accepting an invalid literal.
272
+ */
273
+ type TypedAsId = <T extends string>(tableName: AsIdTable<T>, id: string) => IdOfTable<T & TableName>;
274
+
275
+ export interface QueryCtx extends Omit<QueryCtxBase, "db" | "storage"${x}${I}${R}> {
276
+ readonly db: Omit<DatabaseReader, "asId" | "query" | "get"> & DatabaseReaderFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
277
+ readonly orm: OrmReader;
278
+ readonly storage: ReadOnlyStorage<StorageBucketName>;${ce}${g}${h}${T}${v}${f}${B}${$}
279
+ }
280
+
281
+ export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${x}${C}${I}${R}> {
282
+ readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
283
+ readonly orm: OrmWriter;
284
+ readonly storage: MutationStorage<StorageBucketName>;${A}${g}${h}${T}${v}${f}${B}${F}${S}${W}${$}
285
+ }
286
+
287
+ export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${x}${C}${I}${R}> {
288
+ readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
289
+ readonly orm: OrmWriter;
290
+ readonly storage: StorageBase<StorageBucketName>;${A}${g}${J}${Z}${te}${re}${h}${T}${v}${oe}${se}${ie}${f}${de}${le}${B}${F}${S}${W}${$}
291
+ }
292
+
293
+ /**
294
+ * Procedure builders bound to this project's typed contexts. Chain
295
+ * \`.input({...})\` to declare args, \`.use(middleware)\` for rate limiting / RLS /
296
+ * masking (each middleware may refine \`ctx\`), then the terminal
297
+ * \`.query()\` / \`.mutation()\` / \`.action()\` with a \`({ ctx, args }) => ...\`
298
+ * handler. \`.output(validator)\` and (queries) \`.stream()\` are also available.
299
+ */
300
+ const lunoraBuilders = initLunora.dataModel<DataModel>().create();
301
+
302
+ /** \`query\` builder bound to this project's typed {@link QueryCtx}. */
303
+ export const query = lunoraBuilders.query as unknown as QueryBuilder<QueryCtx, EmptyArgs>;
304
+
305
+ /** \`mutation\` builder bound to this project's typed {@link MutationCtx}. */
306
+ export const mutation = lunoraBuilders.mutation as unknown as MutationBuilder<MutationCtx, EmptyArgs>;
307
+
308
+ /** \`action\` builder bound to this project's typed {@link ActionCtx}. */
309
+ export const action = lunoraBuilders.action as unknown as ActionBuilder<ActionCtx, EmptyArgs>;
310
+
311
+ /** \`internalQuery\` builder bound to this project's typed {@link QueryCtx} — never exposed on \`api\`. */
312
+ export const internalQuery = lunoraBuilders.internalQuery as unknown as InternalQueryBuilder<QueryCtx, EmptyArgs>;
313
+
314
+ /** \`internalMutation\` builder bound to this project's typed {@link MutationCtx} — never exposed on \`api\`. */
315
+ export const internalMutation = lunoraBuilders.internalMutation as unknown as InternalMutationBuilder<MutationCtx, EmptyArgs>;
316
+
317
+ /** \`internalAction\` builder bound to this project's typed {@link ActionCtx} — never exposed on \`api\`. */
318
+ export const internalAction = lunoraBuilders.internalAction as unknown as InternalActionBuilder<ActionCtx, EmptyArgs>;
319
+
320
+ /**
321
+ * \`defineMutator\` bound to this project's typed {@link MutationCtx} — declare
322
+ * custom mutators (\`lunora/mutators.ts\`) with it instead of importing from
323
+ * \`${r.server}\`, and the authoritative \`server\` impl's \`ctx\` carries the
324
+ * schema-typed \`ctx.db\` (\`ctx.db.query("nodes")\` resolves \`Doc<"nodes">\`,
325
+ * \`ctx.db.patch(id, …)\` takes an \`Id<"nodes">\`) with no hand-written ctx type and
326
+ * no \`as unknown as\` cast. Runtime-identical to the package export; only the
327
+ * context type narrows, so discovery finds a mutator authored either way.
328
+ * @example
329
+ * export const setText = defineMutator({
330
+ * args: { id: v.id("nodes"), text: v.string() },
331
+ * server: async (ctx, args) => { await ctx.db.patch(args.id, { text: args.text }); },
332
+ * });
333
+ */
334
+ export const defineMutator = defineMutatorBase as unknown as <Args extends Record<string, Validator> = Record<string, Validator>, ClientTx = unknown, R = unknown>(
335
+ definition: MutatorDefinition<Args, MutationCtx, ClientTx, R>,
336
+ ) => RegisteredMutator<Args, MutationCtx, ClientTx, R>;
337
+
338
+ /**
339
+ * \`definePolicy\` bound to THIS schema's {@link DataModel} + {@link Relations}.
340
+ * Import it from here (\`./_generated/server\`) instead of \`@lunora/server\` to get
341
+ * a relation-aware RLS authoring surface: \`table\` autocompletes to a real table
342
+ * name and the \`when\` predicate type-checks against the table's columns **and**
343
+ * its declared relations — \`{ author: { is: {...} } }\`, \`{ posts: { some: {...} } }\`,
344
+ * etc. (the \`@lunora/do\` pre-resolver resolves relation predicates on reads).
345
+ * Runtime-identical to \`@lunora/server\`'s \`definePolicy\`; only the types narrow,
346
+ * so the \`rls()\` chain discovers a policy authored either way the same.
347
+ */
348
+ export const definePolicy = createPolicyDsl<DataModel, Relations${Te}>();
349
+
350
+ /**
351
+ * The validator builder \`v\`, with \`v.id(...)\` constrained to THIS schema's
352
+ * table names — so the argument autocompletes and returns a precise
353
+ * \`Id<"table">\`. Identical to \`@lunora/server\`'s \`v\` at runtime; the only
354
+ * difference is the tightened \`id\` type.
355
+ *
356
+ * Import \`v\` from here (\`./_generated/server\`) in your queries/mutations/actions
357
+ * to get table-name autocomplete. \`lunora/schema.ts\` can't use it — it is the
358
+ * file that defines the table names, so they aren't known yet there; pass the
359
+ * names as string literals and the generated \`Id<"table">\` types still catch a
360
+ * typo wherever the id is used.
361
+ */
362
+ export const v = vBase as unknown as Omit<typeof vBase, "id"> & {
363
+ id: <T extends TableName>(table: T) => ColumnValidator<IdOfTable<T>, IdOfTable<T>>;
364
+ };
365
+ `};export{Fe as default};
@@ -0,0 +1 @@
1
+ import"./SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs";import"./isD1GlobalTable-udvHAAzD.mjs";import"./json-data-Chfs2Cz5.mjs";import{e as a}from"./shard-B3LMNjIg.mjs";import"./shard-runtime-B_ppYvOf.mjs";import"./shared-DjUziztz.mjs";export{a as default};
@@ -0,0 +1 @@
1
+ import{createHash as c}from"node:crypto";import{existsSync as s,readFileSync as i}from"node:fs";import{join as h}from"node:path";import{listLunoraSourceFiles as u}from"./listLunoraSourceFiles-DP-5e-RE.mjs";const S=t=>{if(!s(t))return"unreadable";const e=u(t),o=h(t,"schema.ts");s(o)&&e.push(o);const r=c("sha256");for(const a of e.toSorted((n,p)=>n.localeCompare(p)))try{r.update(a).update("\0").update(i(a))}catch{}return r.digest("hex")};export{S as default};
@@ -0,0 +1 @@
1
+ const a=(r,s)=>`JSON.parse(${JSON.stringify(JSON.stringify(r))}) as ${s}`;export{a as r};
@@ -0,0 +1 @@
1
+ import{d as E}from"./declared-output-Iaar469J.mjs";import{v as u}from"./shared-DjUziztz.mjs";const p=/import\("(?<spec>(?:\.\.?\/)*_generated\/[^"]+)"\)/gu,l=/^(?:\.\.?\/)*_generated\//u,i=/\.[A-Za-z]\w*$/u,R=t=>t.replaceAll(p,(e,r)=>{const o=r.replace(l,"./");return`import("${i.test(o)?o:`${o}.js`}")`}),_=/import\("(?<spec>[^"]+)"\)/gu,a="node_modules/",m=/^@types\//u,A=t=>t.replaceAll(_,(e,r)=>{const o=r.lastIndexOf(a);if(o===-1||o>0&&r[o-1]!=="/")return e;const s=r.slice(o+a.length);return s===""||m.test(s)?e:`import("${s}")`}),I=/import\("(?<spec>\.\.?\/[^"]+)"\)/gu,f=/^(?:\.\.?\/)+/u,g=t=>{const e=[];for(const r of t.split("/"))if(!(r===""||r===".")){if(r===".."&&e.length>0&&e.at(-1)!==".."){e.pop();continue}e.push(r)}return e.join("/")},S=(t,e)=>t.replaceAll(I,(r,o)=>{if(l.test(o.replace(f,"")))return r;const s=e.includes("/")?e.slice(0,e.lastIndexOf("/")):"",c=`../${g(`${s}/${o}`)}`;return`import("${i.test(c)?c:`${c}.js`}")`}),v=(t,e)=>R(S(A(t),e)),d=["client","do","errors","flags","observability","platform","ratelimit","runtime","server","values"],L=new RegExp(String.raw`import\("@lunora/(?<pkg>${d.join("|")})(?<subpath>/[^"]*)?"\)`,"gu"),T={flags:new Set(["/web"]),platform:new Set},M=(t,e)=>e?t.replaceAll(L,(r,o,s)=>{const n=T[o];return s&&n&&!n.has(s)?r:`import("lunorash/${o}${s??""}")`}):t,O=t=>["Doc","Id"].filter(e=>new RegExp(String.raw`(?<![.$\w])${e}<`,"u").test(t)),U=t=>E(t)?u(t.output):t.returnType;export{M as a,v as b,U as c,O as r};