@lunora/codegen 1.0.0-alpha.236 → 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 (27) hide show
  1. package/dist/index.d.mts +116 -116
  2. package/dist/index.d.ts +116 -116
  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/emitAgents-BPFw6ww2.mjs +1 -0
  10. package/dist/packem_shared/emitApi-CJ9ziZnP.mjs +154 -0
  11. package/dist/packem_shared/{emitApp-CTLwFZHO.mjs → emitApp-BGhO5bhT.mjs} +3 -3
  12. package/dist/packem_shared/emitCrons-mkwWkn0R.mjs +69 -0
  13. package/dist/packem_shared/emitDataModel-D3WuEZ4b.mjs +113 -0
  14. package/dist/packem_shared/emitDrizzleSchema-Cv0HtLR3.mjs +15 -0
  15. package/dist/packem_shared/emitFunctions-BqAz1ssY.mjs +249 -0
  16. package/dist/packem_shared/emitServer-BEo_fCY8.mjs +365 -0
  17. package/dist/packem_shared/emitShard-Bu7EKdou.mjs +1 -0
  18. package/dist/packem_shared/json-data-Chfs2Cz5.mjs +1 -0
  19. package/dist/packem_shared/qualifiers-BhOL15WZ.mjs +1 -0
  20. package/dist/packem_shared/shard-B3LMNjIg.mjs +1435 -0
  21. package/dist/packem_shared/shard-runtime-B_ppYvOf.mjs +323 -0
  22. package/dist/packem_shared/shared-DjUziztz.mjs +9 -0
  23. package/package.json +3 -3
  24. package/dist/packem_shared/GENERATED_HEADER-Da0OC3EI.mjs +0 -1
  25. package/dist/packem_shared/OPENRPC_VERSION-CL0VnCPW.mjs +0 -3
  26. package/dist/packem_shared/buildOpenApiDocument-C7S5wJCl.mjs +0 -3
  27. package/dist/packem_shared/emit-DUpkZ68h.mjs +0 -2696
@@ -0,0 +1,154 @@
1
+ import{agentComponent as T}from"@lunora/agent/component";import{LunoraError as P}from"@lunora/errors";import{s as u}from"./paths-C-9fwEgQ.mjs";import{r as j,a as K,b as g,c as E}from"./qualifiers-BhOL15WZ.mjs";import{G as w,a as B,r as h,p as $,b as x,c as y,d as v}from"./shared-DjUziztz.mjs";const A=t=>{const r=new Map;for(const o of t){const e=r.get(o.filePath)??[];e.push(o),r.set(o.filePath,e)}return[...r.entries()].toSorted(([o],[e])=>o.localeCompare(e))},C=t=>{const r=([o,e])=>{const c=e.toSorted((i,a)=>i.exportName.localeCompare(a.exportName)).map(i=>{const a=g(h(i.args),i.filePath),n=g(E(i),i.filePath);return` ${i.exportName}: FunctionReference<"${i.kind}", ${a}, ${n}>;`}).join(`
2
+ `);return` ${x(u(o))}: {
3
+ ${c}
4
+ };`};return A(t).map(o=>r(o)).join(`
5
+ `)},W=(t,r)=>{if(t.length===0&&r.length===0)return{block:"",importLine:""};const o=[];let e="";if(t.length>0&&(e+="\n/** Params type carried by a `defineWorkflow` definition (its phantom `__params`). */\ntype WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params } ? (unknown extends Params ? Record<string, unknown> : Params) : Record<string, unknown>;\n"),e+=`
6
+ /** A typed reference to a durable workflow, addressable for \`cronJobs()\` targets. Mirrors \`@lunora/scheduler\`'s \`WorkflowReference\` structurally. */
7
+ export interface WorkflowReference<Params = Record<string, unknown>> {
8
+ readonly isLunoraWorkflow: true;
9
+ readonly __params?: Params;
10
+ readonly binding: string;
11
+ readonly name: string;
12
+ }
13
+ `,t.length>0){const c=[...t].toSorted((n,s)=>n.exportName.localeCompare(s.exportName)),i=c.map(n=>` ${n.exportName}: WorkflowReference<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${n.exportName}>>;`).join(`
14
+ `),a=c.map(n=>` ${y(n.exportName)}: { isLunoraWorkflow: true, binding: ${JSON.stringify(n.bindingName)}, name: ${JSON.stringify(n.exportName)} },`).join(`
15
+ `);e+=`
16
+ /** This project's durable workflows, addressable as typed references (e.g. \`crons.daily("digest", …, workflows.digestPipeline, params)\`). */
17
+ export interface WorkflowsRef {
18
+ ${i}
19
+ }
20
+
21
+ export const workflows: WorkflowsRef = {
22
+ ${a}
23
+ };
24
+ `,o.push(`import type * as lunoraWorkflowDefinitions from "../workflows.js";
25
+ `)}if(r.length>0){const c=[...r].toSorted((n,s)=>n.exportName.localeCompare(s.exportName)),i=c.map(n=>` ${n.exportName}: WorkflowReference<AgentRunInput>;`).join(`
26
+ `),a=c.map(n=>` ${y(n.exportName)}: { isLunoraWorkflow: true, binding: ${JSON.stringify(n.bindingName)}, name: ${JSON.stringify(n.name)} },`).join(`
27
+ `);e+=`
28
+ /** This project's durable agents, addressable as typed references for \`cronJobs()\` — each fire starts a fresh agent run (e.g. \`crons.daily("sweep", …, agents.support, { input, threadKey })\`). */
29
+ export interface AgentsRef {
30
+ ${i}
31
+ }
32
+
33
+ export const agents: AgentsRef = {
34
+ ${a}
35
+ };
36
+ `,o.push(`import type { AgentRunInput } from "@lunora/agent";
37
+ `)}return{block:e,importLine:o.join("")}},D=()=>Object.keys(T().functions).toSorted((t,r)=>t.localeCompare(r)),O=t=>new Set(t.filter(r=>u(r.filePath)==="agents").map(r=>r.exportName)),J=()=>new Set(Object.entries(T().functions).filter(([,t])=>t.visibility==="internal").map(([t])=>t)),X=(t,r)=>{const o={importLine:"",lines:"",prelude:""};if(t.length===0)return o;const e=O(r),c=J(),i=r.find(n=>u(n.filePath)==="agents"&&c.has(n.exportName));if(i)throw new P("INTERNAL",`@lunora/codegen: "agents:${i.exportName}" is reserved for the durable agent loop's internal dispatch — rename the "${i.exportName}" export in ${i.filePath}`);const a=D().filter(n=>!e.has(n));return a.length===0?o:{importLine:`import { agentComponent } from "@lunora/agent/component";
38
+ `,lines:a.map(n=>` "agents:${n}": lunoraAgentRuntimeFunctions.${n} as unknown as RegisteredLunoraFunction,`).join(`
39
+ `),prelude:`
40
+ /**
41
+ * The \`@lunora/agent\` runtime component — auto-registered because \`lunora/agents.ts\`
42
+ * declares agents. The durable loop dispatches the internal mutations; clients
43
+ * subscribe to the public queries (\`agents:agentMessages\` is the live thread view).
44
+ */
45
+ const lunoraAgentRuntimeFunctions = agentComponent().functions;
46
+ `}},Y=(t,r)=>{if(!t)return{importLine:"",lines:"",prelude:""};const o=r.find(e=>u(e.filePath)==="sandbox"&&e.exportName==="invoke");if(o)throw new P("INTERNAL",`@lunora/codegen: "sandbox:invoke" is reserved for the batteries-included sandbox tool dispatcher (browserTool/containerTool) — rename the "invoke" export in ${o.filePath}`);return{importLine:`import { sandboxComponent } from "@lunora/agent/component";
47
+ `,lines:' "sandbox:invoke": lunoraSandbox.invoke as unknown as RegisteredLunoraFunction,',prelude:"\n/**\n * The `@lunora/agent` sandbox dispatcher — auto-registered because `lunora/`\n * imports a sandbox tool (`browserTool`/`containerTool`). The batteries-included\n * tools dispatch to this internal action, which runs on an action ctx carrying\n * `ctx.browser` + `ctx.containers` (the durable tool step itself has neither).\n */\nconst lunoraSandbox = sandboxComponent();\n"}},H=(t,r)=>{if(t.length===0)return[];const o=O(r),e=[{args:{key:{kind:"string"},limit:{inner:{kind:"number"},kind:"optional"}},exportName:"agentMessages",filePath:"agents",kind:"query",returnType:"Record<string, unknown>[]"},{args:{decision:{kind:"union",members:[{kind:"literal",literalValue:'"approve"'},{kind:"literal",literalValue:'"reject"'}]},instanceId:{kind:"string"},note:{inner:{kind:"string"},kind:"optional"},threadKey:{kind:"string"},toolCallId:{kind:"string"}},exportName:"agentResolveApproval",filePath:"agents",kind:"mutation",returnType:"{ resolved: boolean }"},{args:{agent:{kind:"string"},input:{kind:"string"},threadKey:{kind:"string"},title:{inner:{kind:"string"},kind:"optional"}},exportName:"agentRun",filePath:"agents",kind:"mutation",returnType:"{ id: string; threadKey: string }"},{args:{key:{kind:"string"}},exportName:"agentState",filePath:"agents",kind:"query",returnType:"Record<string, unknown> | undefined"},{args:{key:{kind:"string"}},exportName:"agentThread",filePath:"agents",kind:"query",returnType:"Record<string, unknown> | undefined"}];for(const c of t)c.voice&&e.push({args:{threadKey:{kind:"string"}},exportName:`${c.exportName}Voice`,filePath:"agents",kind:"stream",returnType:"Record<string, unknown>"});return e.filter(c=>!o.has(c.exportName))},_=(t,r)=>{if(t.length===0)return[];const o=new Set(r.filter(e=>u(e.filePath)==="mutators").map(e=>e.exportName));return t.filter(e=>!o.has(e.exportName)).map(e=>({args:e.args,exportName:e.exportName,filePath:e.filePath,kind:"mutation",returnType:e.returnType}))},q=t=>{const r=t.filter(a=>a.stream);if(r.length===0)return{block:"",body:""};const o=A(r),e=o.map(([a,n])=>{const s=n.map(l=>{const p=g(l.chunkType??"unknown",l.filePath),d=g(h(l.searchParams),l.filePath),m=g(h(l.params),l.filePath);return` ${x(l.exportName)}: HttpStreamRef<${p}, ${d}, ${m}>;`}).join(`
48
+ `);return` ${x(u(a))}: {
49
+ ${s}
50
+ };`}).join(`
51
+ `),c=o.map(([a,n])=>{const s=n.map(l=>` ${y(l.exportName)}: { method: ${JSON.stringify(l.method)}, path: ${JSON.stringify(l.path)} },`).join(`
52
+ `);return` ${y(u(a))}: {
53
+ ${s}
54
+ },`}).join(`
55
+ `);return{block:`
56
+ /** This project's HTTP-SSE stream routes (\`httpRoute.<verb>(path).stream()\`), addressable as typed references for \`client.httpStream\` / \`useHttpStream\`. */
57
+ export interface HttpStreamsRef {
58
+ ${e}
59
+ }
60
+
61
+ export const httpStreams: HttpStreamsRef = {
62
+ ${c}
63
+ };
64
+ `,body:e}},Z=t=>{const{agents:r=[],functions:o,httpRoutes:e=[],mutators:c=[],useUmbrella:i=!1,workflows:a=[]}=t,n=v(i),s=[...o.filter(k=>k.visibility!=="internal"),...H(r,o),..._(c,o)],l=o.filter(k=>k.visibility==="internal"),p=C(s),d=C(l),m=q(e),b=`${p}
65
+ ${d}
66
+ ${m.body}`,f=j(b),L=f.length>0?`
67
+ import type { ${f.join(", ")} } from "./dataModel.js";
68
+ `:"",I=p?`
69
+ ${p}
70
+ `:"",M=d?`
71
+ ${d}
72
+ `:"",N=W(a,r),R=`export interface ApiTypes {${I}}
73
+
74
+ export const api = anyApi as unknown as ApiTypes;
75
+
76
+ /** Internal functions — callable only server-side via \`ctx.run*\`, never from a client. */
77
+ export interface InternalApiTypes {${M}}
78
+
79
+ export const internal = anyApi as unknown as InternalApiTypes;
80
+ ${N.block}${m.block}`,S=[...R.includes("FunctionReference<")?["FunctionReference"]:[],...m.block===""?[]:["HttpStreamRef"]],F=S.length>0?`import type { ${S.join(", ")} } from "${n.client}";
81
+ `:"";return K(`${w}import { anyApi } from "${n.client}";
82
+ ${F}${N.importLine}${L}
83
+ ${R}`,i)},ee=t=>t?`${w}import { createSeedClient as createSeedClientBase } from "@lunora/seed";
84
+ import type { SeedClient, SeedClientOptions } from "@lunora/seed";
85
+
86
+ import schema from "../schema.js";
87
+ import type { InsertModel } from "./dataModel.js";
88
+
89
+ /**
90
+ * Schema-aware seed client with this project's \`InsertModel\` and runtime schema
91
+ * pre-bound. Each table is a method; call it with a count, a range, explicit
92
+ * partial rows, or per-field overrides. Foreign keys connect to rows seeded
93
+ * earlier in the run, and FK-parent tables are seeded automatically.
94
+ * @example
95
+ * const seed = createSeedClient({ seed: 1 });
96
+ * const { users } = await seed.users(5);
97
+ * const { posts } = await seed.posts((x) => x([10, 20]));
98
+ */
99
+ export const createSeedClient = (options?: SeedClientOptions): SeedClient<InsertModel> => createSeedClientBase<InsertModel>(schema, options);
100
+ `:"",te=(t,r,o=!1)=>{if(t.length===0||!r)return"";const e=v(o),c=s=>s.table===void 0?"Row":`Doc<${JSON.stringify(s.table)}> & Row`,i=t.map(s=>{B(s.exportName,"shape export name");const l=c(s),p=g(h(s.args),s.filePath),d=Object.keys(s.args).length>0,m=d?` args: ${p};`:` args?: ${p};`,b=d?`(args: ${p}) => void`:`(args?: ${p}) => void`,f=`${s.exportName}CollectionOptions`;return`/** Options for the \`${s.exportName}\` shape binding. */
101
+ export interface ${$(f)} {
102
+ ${m}
103
+ /**
104
+ * Share the optimistic-overlay gate with other collections + mutators on this
105
+ * shard. Defaults to the shared per-shard registry, which is almost always what
106
+ * you want — pass one only to isolate this collection's gate.
107
+ */
108
+ checkpoints?: CheckpointRegistry;
109
+ /** The Lunora client to subscribe through. */
110
+ client: LunoraClient;
111
+ /** Row key extractor — defaults to \`row._id\`. Override when the app keys rows by a natural column. */
112
+ getKey?: (row: ${l}) => string;
113
+ /** \`"eager"\` starts syncing at creation; \`"lazy"\` (default) on the first subscriber. */
114
+ load?: "eager" | "lazy";
115
+ /** Notified when the underlying subscription errors; the collection always leaves \`loading\`. */
116
+ onError?: (error: SubscriptionError) => void;
117
+ /** Routes the subscription to a shard's DO. **Required for a \`.shardBy()\` table** — without it the watermark lands in the default bucket. */
118
+ shardKey?: string;
119
+ }
120
+
121
+ /**
122
+ * Collection options for the \`${s.exportName}\` replication shape: \`config\` for
123
+ * \`createCollection\`, plus the \`checkpoints\` registry to hand \`bindMutators\` and
124
+ * \`scope\` to re-point the subscription.
125
+ */
126
+ export const ${s.exportName}CollectionOptions = (options: ${$(f)}): LunoraCollectionOptions<${l}> =>
127
+ lunoraCollectionOptions<${l}>({
128
+ client: options.client,
129
+ ...(options.checkpoints === undefined ? {} : { checkpoints: options.checkpoints }),
130
+ ...(options.getKey === undefined ? {} : { getKey: options.getKey }),
131
+ ...(options.load === undefined ? {} : { load: options.load }),
132
+ ...(options.onError === undefined ? {} : { onError: options.onError }),
133
+ ...(options.shardKey === undefined ? {} : { shardKey: options.shardKey }),
134
+ shape: { args: options.args, name: ${JSON.stringify(s.exportName)}, ...(options.shardKey === undefined ? {} : { shardKey: options.shardKey }) },
135
+ });
136
+
137
+ /** Live collection for the \`${s.exportName}\` shape, with its sync controls. */
138
+ export const ${s.exportName}Collection = (
139
+ options: ${$(f)},
140
+ ): { checkpoints: CheckpointRegistry; collection: Collection<${l}, string>; scope: ${b} } => {
141
+ const { checkpoints, config, scope } = ${s.exportName}CollectionOptions(options);
142
+
143
+ return { checkpoints, collection: createCollection(config), scope };
144
+ };`}).join(`
145
+
146
+ `),a=j(i),n=a.length>0?`import type { ${a.join(", ")} } from "./dataModel.js";
147
+ `:"";return`${w}import type { LunoraClient, SubscriptionError } from "${e.client}";
148
+ import { lunoraCollectionOptions } from "@lunora/db/collections";
149
+ import type { CheckpointRegistry, LunoraCollectionOptions, Row } from "@lunora/db";
150
+ import type { Collection } from "@tanstack/db";
151
+ import { createCollection } from "@tanstack/db";
152
+ ${n}
153
+ ${i}
154
+ `};export{Z as emitApi,te as emitCollections,ee as emitSeed,A as groupByFileSorted,X as renderAgentFunctionRegistry,Y as renderSandboxFunctionRegistry};
@@ -1,4 +1,4 @@
1
- import{A as w,G as y}from"./emit-DUpkZ68h.mjs";const k=e=>`has${e.charAt(0).toUpperCase()}${e.slice(1)}`,b=w.map(({appMethod:e,key:t})=>[k(t),e.method,e.configKey,e.doc]),g=e=>b.some(([t])=>e[t]),S=e=>e?['import * as lunoraIdentityContract from "../identity.js";']:[],E=(e,t)=>e?['import type { CreateAccessResolverOptions } from "@lunora/cloudflare-access";',`import { createAccessResolver${t?", composeResolvers":""} } from "@lunora/cloudflare-access";`]:[],D=e=>e?['import { createKvIntrospectorFromEnv } from "@lunora/bindings/kv";']:[],x=e=>e?['import { createVectorAdminIntrospector } from "@lunora/bindings/vectors";']:[],R=e=>e?['import type { D1CtxDbOptions, D1DatabaseLike, D1Exec } from "@lunora/d1";','import { applyCdcChanges, createD1CtxDb, emitD1QueryCost, exportGlobalRows, facetGlobalColumn, importGlobalRows, listGlobalTables, readD1CdcChanges, readGlobalTablePage, retryingExec } from "@lunora/d1";']:[],A=e=>e?['import notifyConfig from "../notify.js";']:[],m=e=>(e.emailAgents?.length??0)>0,C=e=>m(e)?['import { dispatchAgentEmail } from "@lunora/agent/inbound";']:[],O=e=>m(e)?['import * as lunoraAgentDefinitions from "../agents.js";']:[],T=e=>{const{hasFramework:t,hasGlobal:a,hasHyperdriveGlobal:r,hasQueue:n,useUmbrella:i}=e,o=i?"lunorash/runtime":"@lunora/runtime",l=["ExecutionContextLike","HttpRouterLike","LunoraWorker","Route","ScheduledControllerLike","ShardNamespaceLike","WorkerOptions",...n?["TriggerTrace"]:[],...a?["GlobalIntrospector","AdminTableResolver"]:[],...t?["FrameworkHostHandler"]:[]],s=[...a||r?["createCrossShardRelationCapabilities"]:[],"createWorker",...e.jurisdiction?["declareAppJurisdiction"]:[],"resolveLogArchiveFromEnv",...t?["withFrameworkWorker"]:[]].join(", ");return[`import type { ${[...l].toSorted((c,d)=>c.localeCompare(d)).join(", ")} } from "${o}";`,`import { ${s} } from "${o}";`]},N=e=>{const{hasAccess:t,hasAuth:a,hasGlobal:r,hasHyperdriveGlobal:n,hasKvIntrospector:i,hasQueue:o,hasScheduler:l,hasStorage:s,hasWorkflow:c,wantsOpenApi:d,wantsOpenRpc:h}=e;return[...a?['import type { AuthNamespaceLike, LunoraAuth, LunoraAuthOptions } from "@lunora/auth";','import { createAuth, createAuthAdmin, createAuthAuditReader, createDoAuthWiring, d1Executor, ensureMigrated, handleAuthRequest, lunoraD1Adapter } from "@lunora/auth";']:[],...E(t,a),...R(r),...n?['import type { HyperdriveEngine } from "@lunora/hyperdrive/global";','import { createHyperdriveGlobalCtxDb } from "@lunora/hyperdrive/global";','import type { SqlCtxDbOptions, SqlExec } from "@lunora/sql-store";']:[],...D(i),...x(e.hasVectors===!0),...l?['import type { DurableObjectNamespaceLike } from "@lunora/scheduler";','import { createScheduler } from "@lunora/scheduler";']:[],...s?['import type { R2BucketLike, R2S3Credentials, Storage } from "@lunora/storage";','import { createBucketStorage, createStorage } from "@lunora/storage";']:[],...c?['import { createWorkflowsRestClient } from "@lunora/workflow";']:[],...C(e),...T(e),"",...S(e.identity),...O(e),...r||n?['import schema from "../schema.js";']:[],...A(e.hasNotify),'import { LUNORA_CRONS } from "./crons.js";','import { LUNORA_FUNCTIONS } from "./functions.js";',...o?['import { createQueueCaptureSink, dispatchQueueBatch, shouldCaptureQueue } from "@lunora/queue";','import { LUNORA_QUEUE_REGISTRY } from "./queues.js";']:[],...d?['import { openApiSpec } from "./openapi.js";']:[],...h?['import { openRpcSpec } from "./openrpc.js";']:[],'import { createShardDO } from "./shard.js";',...e.hasVectors===!0?['import { LUNORA_VECTOR_INDEXES } from "./vectors.js";']:[]]},I=e=>[...e.hasStorage?["/** `.storage(...)` declaration — one bucket (required) plus optional extra named buckets and signed-URL config. Backs `ctx.storage` AND the studio file browser. */\ninterface StorageDeclaration<Env> {\n /** The default R2 bucket binding (the bare `ctx.storage`). */\n bucket: Selector<Env, R2BucketLike>;\n /** Extra named buckets, reached via `ctx.storage.bucket(\"name\")` and the studio's bucket picker. */\n buckets?: Record<string, Selector<Env, R2BucketLike>>;\n /** Public base URL signed/public object URLs resolve against. Omit it and `ctx.storage` in a mutation, action or HTTP handler (and the studio's copy-URL) signs against the origin the request reached the worker on — no per-environment value to ship. Queries get no such fallback (a live query re-runs with no request behind it), so a query that signs URLs needs this set. */\n publicBaseUrl?: Selector<Env, string>;\n /** R2 S3-API credentials (`{ accountId, accessKeyId, secretAccessKey, bucket, jurisdiction? }`) enabling `ctx.storage.getPresignedUrl` — native S3 presigned URLs that hit R2 directly, bypassing the worker. Omit to use only the worker-signed `getSignedUrl` path. */\n s3?: Selector<Env, R2S3Credentials>;\n /** HMAC secret for signed URLs. */\n signingSecret?: Selector<Env, string>;\n}"]:[],...e.hasScheduler?["/** `.scheduler(...)` declaration — the `SchedulerDO` namespace. Backs `ctx.scheduler` AND the studio's scheduled-jobs view. The origin its callbacks dispatch back to is not declared here: the DO reads `env.LUNORA_ORIGIN_URL` at fire time, because a caller-supplied dispatch target would be an SSRF vector. */\ninterface SchedulerDeclaration<Env> {\n /** The `SchedulerDO` namespace binding (typically `env.SCHEDULER`). */\n namespace: Selector<Env, DurableObjectNamespaceLike & ShardNamespaceLike>;\n}"]:[],...e.hasGlobal?["/** `.global(...)` declaration — the D1 binding backing `.global()` tables. Backs cross-tenant `ctx.db` reads/writes AND the studio's global data browser. */\ninterface GlobalDeclaration<Env> {\n /** The D1 binding (typically `env.DB`). */\n d1: Selector<Env, D1DatabaseLike>;\n /** The worker origin used to fan reverse cross-backend relations across shards. Without it, such a relation throws a clear error. */\n origin?: Selector<Env, string>;\n}"]:[],...e.hasHyperdriveGlobal?['/** `.hyperdriveGlobal(...)` declaration — backs `.global({ backend: "hyperdrive" })` tables on a Postgres/MySQL database via Hyperdrive. Stays reactive: the writer is injected as `globalDb` and the broadcast hook drives live queries. */\ninterface HyperdriveGlobalDeclaration<Env> {\n /** The Hyperdrive engine — selects the Postgres or MySQL dialect. */\n engine: HyperdriveEngine;\n /** Build the `SqlExec` from `env` — e.g. `buildPgExec(fromPostgresJs(postgres(env.HYPERDRIVE.connectionString)))`. Cache the driver on the DO instance; rebuild lazily after hibernation. */\n exec: (env: Env) => SqlExec;\n /** The worker origin used to fan reverse cross-backend relations across shards. Without it, such a relation throws a clear error. */\n origin?: Selector<Env, string>;\n}']:[],...e.hasAuth?['/** `.auth(...)` declaration — better-auth options plus the storage the adapter reads. Give it `d1` (the default) or `namespace` (a Durable Object that hosts the auth tables), never both. The builder owns the lazy build + `ensureMigrated` dance and wires `authHandler` / `resolveIdentity` / `authAdmin`. */\ninterface AuthDeclaration<Env> {\n /** The D1 binding the auth SQL adapter is wired over (via `lunoraD1Adapter`). Omit only when using `namespace`. */\n d1?: Selector<Env, unknown>;\n /** Shared secret the worker presents on the object\'s internal session route. REQUIRED with `namespace`: the binding is reachable from any worker bound to it, so the secret — not the binding — is the authorization boundary. Without it identity resolution fails closed. */\n internalSecret?: Selector<Env, string>;\n /** Name of the Durable Object instance holding the auth tables. Defaults to `"auth"`. Set it to run separate auth objects (per deployment, per tenant) off one namespace. */\n objectName?: Selector<Env, string>;\n /** The auth Durable Object namespace — the DO-backed mode. Needed for `@better-auth/scim`, which requires native transactions that D1 has none of. The object owns the auth tables, so `/api/auth/*` and identity resolution both go through it. Typed as `AuthNamespaceLike` because `createDoAuthWiring` resolves through `idFromName` + `get` and has no `getByName` fallback — both members are load-bearing here, and `ShardNamespaceLike` leaves both optional. */\n namespace?: Selector<Env, AuthNamespaceLike>;\n /** Build the better-auth options from `env` (secret, plugins, email/password, …). */\n options: (env: Env) => LunoraAuthOptions;\n}']:[]],L=e=>[...e.hasAccess?[" private accessSelector?: Selector<Env, CreateAccessResolverOptions | undefined>;"]:[]," private adminToken?: Selector<Env, string>;",...e.hasAuth?[" private authDeclaration?: AuthDeclaration<Env>;"]:[]," private cdcEnabled = false;"," private reactiveCacheConfig: boolean | { maxBytes?: number; maxEntries?: number } = false;",' private maxRelationKeysLimit?: ShardConfig["maxRelationKeys"];',' private observabilitySink?: ShardConfig["observability"];',' private relationExistsPushDownMode?: ShardConfig["relationExistsPushDown"];'," private readonly extendFns: ((env: Env, derived: Readonly<WorkerOptions>) => Partial<WorkerOptions>)[] = [];",...e.hasGlobal?[" private globalDeclaration?: GlobalDeclaration<Env>;"]:[],...e.hasHyperdriveGlobal?[" private hyperdriveGlobalDeclaration?: HyperdriveGlobalDeclaration<Env>;"]:[]," private httpRouterApp?: HttpRouterLike;"," private readonly routeMap: Record<string, Route> = {};",...e.hasScheduler?[" private schedulerDeclaration?: SchedulerDeclaration<Env>;"]:[],...g(e)?[" private readonly shardExtras: Partial<ShardConfig> = {};"]:[]," private shardSelector?: Selector<Env, ShardNamespaceLike>;",...e.hasSourcedTables?[' private sourceClientFactory?: NonNullable<ShardConfig["sourceClient"]>;']:[],...e.hasStorage?[" private storageDeclaration?: StorageDeclaration<Env>;"]:[]],q=e=>b.filter(([t])=>e[t]).map(([,t,a,r])=>` /** ${r} */
1
+ import{A as w}from"./capabilities-DJJWVEtk.mjs";import{G as y}from"./shared-DjUziztz.mjs";const k=e=>`has${e.charAt(0).toUpperCase()}${e.slice(1)}`,b=w.map(({appMethod:e,key:t})=>[k(t),e.method,e.configKey,e.doc]),g=e=>b.some(([t])=>e[t]),S=e=>e?['import * as lunoraIdentityContract from "../identity.js";']:[],E=(e,t)=>e?['import type { CreateAccessResolverOptions } from "@lunora/cloudflare-access";',`import { createAccessResolver${t?", composeResolvers":""} } from "@lunora/cloudflare-access";`]:[],D=e=>e?['import { createKvIntrospectorFromEnv } from "@lunora/bindings/kv";']:[],x=e=>e?['import { createVectorAdminIntrospector } from "@lunora/bindings/vectors";']:[],R=e=>e?['import type { D1CtxDbOptions, D1DatabaseLike, D1Exec } from "@lunora/d1";','import { applyCdcChanges, createD1CtxDb, emitD1QueryCost, exportGlobalRows, facetGlobalColumn, importGlobalRows, listGlobalTables, readD1CdcChanges, readGlobalTablePage, retryingExec } from "@lunora/d1";']:[],A=e=>e?['import notifyConfig from "../notify.js";']:[],m=e=>(e.emailAgents?.length??0)>0,C=e=>m(e)?['import { dispatchAgentEmail } from "@lunora/agent/inbound";']:[],O=e=>m(e)?['import * as lunoraAgentDefinitions from "../agents.js";']:[],T=e=>{const{hasFramework:t,hasGlobal:a,hasHyperdriveGlobal:r,hasQueue:n,useUmbrella:i}=e,o=i?"lunorash/runtime":"@lunora/runtime",l=["ExecutionContextLike","HttpRouterLike","LunoraWorker","Route","ScheduledControllerLike","ShardNamespaceLike","WorkerOptions",...n?["TriggerTrace"]:[],...a?["GlobalIntrospector","AdminTableResolver"]:[],...t?["FrameworkHostHandler"]:[]],s=[...a||r?["createCrossShardRelationCapabilities"]:[],"createWorker",...e.jurisdiction?["declareAppJurisdiction"]:[],"resolveLogArchiveFromEnv",...t?["withFrameworkWorker"]:[]].join(", ");return[`import type { ${[...l].toSorted((c,d)=>c.localeCompare(d)).join(", ")} } from "${o}";`,`import { ${s} } from "${o}";`]},N=e=>{const{hasAccess:t,hasAuth:a,hasGlobal:r,hasHyperdriveGlobal:n,hasKvIntrospector:i,hasQueue:o,hasScheduler:l,hasStorage:s,hasWorkflow:c,wantsOpenApi:d,wantsOpenRpc:h}=e;return[...a?['import type { AuthNamespaceLike, LunoraAuth, LunoraAuthOptions } from "@lunora/auth";','import { createAuth, createAuthAdmin, createAuthAuditReader, createDoAuthWiring, d1Executor, ensureMigrated, handleAuthRequest, lunoraD1Adapter } from "@lunora/auth";']:[],...E(t,a),...R(r),...n?['import type { HyperdriveEngine } from "@lunora/hyperdrive/global";','import { createHyperdriveGlobalCtxDb } from "@lunora/hyperdrive/global";','import type { SqlCtxDbOptions, SqlExec } from "@lunora/sql-store";']:[],...D(i),...x(e.hasVectors===!0),...l?['import type { DurableObjectNamespaceLike } from "@lunora/scheduler";','import { createScheduler } from "@lunora/scheduler";']:[],...s?['import type { R2BucketLike, R2S3Credentials, Storage } from "@lunora/storage";','import { createBucketStorage, createStorage } from "@lunora/storage";']:[],...c?['import { createWorkflowsRestClient } from "@lunora/workflow";']:[],...C(e),...T(e),"",...S(e.identity),...O(e),...r||n?['import schema from "../schema.js";']:[],...A(e.hasNotify),'import { LUNORA_CRONS } from "./crons.js";','import { LUNORA_FUNCTIONS } from "./functions.js";',...o?['import { createQueueCaptureSink, dispatchQueueBatch, shouldCaptureQueue } from "@lunora/queue";','import { LUNORA_QUEUE_REGISTRY } from "./queues.js";']:[],...d?['import { openApiSpec } from "./openapi.js";']:[],...h?['import { openRpcSpec } from "./openrpc.js";']:[],'import { createShardDO } from "./shard.js";',...e.hasVectors===!0?['import { LUNORA_VECTOR_INDEXES } from "./vectors.js";']:[]]},I=e=>[...e.hasStorage?["/** `.storage(...)` declaration — one bucket (required) plus optional extra named buckets and signed-URL config. Backs `ctx.storage` AND the studio file browser. */\ninterface StorageDeclaration<Env> {\n /** The default R2 bucket binding (the bare `ctx.storage`). */\n bucket: Selector<Env, R2BucketLike>;\n /** Extra named buckets, reached via `ctx.storage.bucket(\"name\")` and the studio's bucket picker. */\n buckets?: Record<string, Selector<Env, R2BucketLike>>;\n /** Public base URL signed/public object URLs resolve against. Omit it and `ctx.storage` in a mutation, action or HTTP handler (and the studio's copy-URL) signs against the origin the request reached the worker on — no per-environment value to ship. Queries get no such fallback (a live query re-runs with no request behind it), so a query that signs URLs needs this set. */\n publicBaseUrl?: Selector<Env, string>;\n /** R2 S3-API credentials (`{ accountId, accessKeyId, secretAccessKey, bucket, jurisdiction? }`) enabling `ctx.storage.getPresignedUrl` — native S3 presigned URLs that hit R2 directly, bypassing the worker. Omit to use only the worker-signed `getSignedUrl` path. */\n s3?: Selector<Env, R2S3Credentials>;\n /** HMAC secret for signed URLs. */\n signingSecret?: Selector<Env, string>;\n}"]:[],...e.hasScheduler?["/** `.scheduler(...)` declaration — the `SchedulerDO` namespace. Backs `ctx.scheduler` AND the studio's scheduled-jobs view. The origin its callbacks dispatch back to is not declared here: the DO reads `env.LUNORA_ORIGIN_URL` at fire time, because a caller-supplied dispatch target would be an SSRF vector. */\ninterface SchedulerDeclaration<Env> {\n /** The `SchedulerDO` namespace binding (typically `env.SCHEDULER`). */\n namespace: Selector<Env, DurableObjectNamespaceLike & ShardNamespaceLike>;\n}"]:[],...e.hasGlobal?["/** `.global(...)` declaration — the D1 binding backing `.global()` tables. Backs cross-tenant `ctx.db` reads/writes AND the studio's global data browser. */\ninterface GlobalDeclaration<Env> {\n /** The D1 binding (typically `env.DB`). */\n d1: Selector<Env, D1DatabaseLike>;\n /** The worker origin used to fan reverse cross-backend relations across shards. Without it, such a relation throws a clear error. */\n origin?: Selector<Env, string>;\n}"]:[],...e.hasHyperdriveGlobal?['/** `.hyperdriveGlobal(...)` declaration — backs `.global({ backend: "hyperdrive" })` tables on a Postgres/MySQL database via Hyperdrive. Stays reactive: the writer is injected as `globalDb` and the broadcast hook drives live queries. */\ninterface HyperdriveGlobalDeclaration<Env> {\n /** The Hyperdrive engine — selects the Postgres or MySQL dialect. */\n engine: HyperdriveEngine;\n /** Build the `SqlExec` from `env` — e.g. `buildPgExec(fromPostgresJs(postgres(env.HYPERDRIVE.connectionString)))`. Cache the driver on the DO instance; rebuild lazily after hibernation. */\n exec: (env: Env) => SqlExec;\n /** The worker origin used to fan reverse cross-backend relations across shards. Without it, such a relation throws a clear error. */\n origin?: Selector<Env, string>;\n}']:[],...e.hasAuth?['/** `.auth(...)` declaration — better-auth options plus the storage the adapter reads. Give it `d1` (the default) or `namespace` (a Durable Object that hosts the auth tables), never both. The builder owns the lazy build + `ensureMigrated` dance and wires `authHandler` / `resolveIdentity` / `authAdmin`. */\ninterface AuthDeclaration<Env> {\n /** The D1 binding the auth SQL adapter is wired over (via `lunoraD1Adapter`). Omit only when using `namespace`. */\n d1?: Selector<Env, unknown>;\n /** Shared secret the worker presents on the object\'s internal session route. REQUIRED with `namespace`: the binding is reachable from any worker bound to it, so the secret — not the binding — is the authorization boundary. Without it identity resolution fails closed. */\n internalSecret?: Selector<Env, string>;\n /** Name of the Durable Object instance holding the auth tables. Defaults to `"auth"`. Set it to run separate auth objects (per deployment, per tenant) off one namespace. */\n objectName?: Selector<Env, string>;\n /** The auth Durable Object namespace — the DO-backed mode. Needed for `@better-auth/scim`, which requires native transactions that D1 has none of. The object owns the auth tables, so `/api/auth/*` and identity resolution both go through it. Typed as `AuthNamespaceLike` because `createDoAuthWiring` resolves through `idFromName` + `get` and has no `getByName` fallback — both members are load-bearing here, and `ShardNamespaceLike` leaves both optional. */\n namespace?: Selector<Env, AuthNamespaceLike>;\n /** Build the better-auth options from `env` (secret, plugins, email/password, …). */\n options: (env: Env) => LunoraAuthOptions;\n}']:[]],L=e=>[...e.hasAccess?[" private accessSelector?: Selector<Env, CreateAccessResolverOptions | undefined>;"]:[]," private adminToken?: Selector<Env, string>;",...e.hasAuth?[" private authDeclaration?: AuthDeclaration<Env>;"]:[]," private cdcEnabled = false;"," private reactiveCacheConfig: boolean | { maxBytes?: number; maxEntries?: number } = false;",' private maxRelationKeysLimit?: ShardConfig["maxRelationKeys"];',' private observabilitySink?: ShardConfig["observability"];',' private relationExistsPushDownMode?: ShardConfig["relationExistsPushDown"];'," private readonly extendFns: ((env: Env, derived: Readonly<WorkerOptions>) => Partial<WorkerOptions>)[] = [];",...e.hasGlobal?[" private globalDeclaration?: GlobalDeclaration<Env>;"]:[],...e.hasHyperdriveGlobal?[" private hyperdriveGlobalDeclaration?: HyperdriveGlobalDeclaration<Env>;"]:[]," private httpRouterApp?: HttpRouterLike;"," private readonly routeMap: Record<string, Route> = {};",...e.hasScheduler?[" private schedulerDeclaration?: SchedulerDeclaration<Env>;"]:[],...g(e)?[" private readonly shardExtras: Partial<ShardConfig> = {};"]:[]," private shardSelector?: Selector<Env, ShardNamespaceLike>;",...e.hasSourcedTables?[' private sourceClientFactory?: NonNullable<ShardConfig["sourceClient"]>;']:[],...e.hasStorage?[" private storageDeclaration?: StorageDeclaration<Env>;"]:[]],q=e=>b.filter(([t])=>e[t]).map(([,t,a,r])=>` /** ${r} */
2
2
  public ${t}(factory: (env: Env) => ReturnType<NonNullable<ShardConfig["${a}"]>>): this {
3
3
  this.shardExtras.${a} = factory as NonNullable<ShardConfig["${a}"]>;
4
4
 
@@ -631,7 +631,7 @@ const buildGlobalCdcApplier =
631
631
 
632
632
  return request.changes.length;
633
633
  };
634
- `:"",U=e=>[...e.hasAuth?["AuthDeclaration"]:[],"ComposedApp",...e.hasGlobal?["GlobalDeclaration"]:[],"LunoraConfig",...e.hasScheduler?["SchedulerDeclaration"]:[],"Selector",...e.hasStorage?["StorageDeclaration"]:[]].toSorted((t,a)=>t.localeCompare(a)).join(", "),M=e=>{const t={...e,hasVectors:(e.hasVectors??!0)&&(e.vectorIndexCount??0)>0},{hasAuth:a}=t,r=I(t),n=P(t),i=a?` let auth: LunoraAuth | null = null;
634
+ `:"",U=e=>[...e.hasAuth?["AuthDeclaration"]:[],"ComposedApp",...e.hasGlobal?["GlobalDeclaration"]:[],"LunoraConfig",...e.hasScheduler?["SchedulerDeclaration"]:[],"Selector",...e.hasStorage?["StorageDeclaration"]:[]].toSorted((t,a)=>t.localeCompare(a)).join(", "),Q=e=>{const t={...e,hasVectors:(e.hasVectors??!0)&&(e.vectorIndexCount??0)>0},{hasAuth:a}=t,r=I(t),n=P(t),i=a?` let auth: LunoraAuth | null = null;
635
635
  let authInit: Promise<void> | null = null;
636
636
  `:"",o=a?`
637
637
  const initAuth = async (env: Env): Promise<void> => {
@@ -849,4 +849,4 @@ const defineApp = <Env extends object>(): AppBuilder<Env> => new AppBuilder<Env>
849
849
 
850
850
  export { AppBuilder, defineApp };
851
851
  export type { ${U(t)} };
852
- `};export{M as emitApp};
852
+ `};export{Q as emitApp};
@@ -0,0 +1,69 @@
1
+ import{G as c}from"./shared-DjUziztz.mjs";const g=o=>o?`${c}/**
2
+ * The \`SchedulerDO\` Durable Object class, re-exported so a worker entry can
3
+ * forward it — wrangler binds only what the entry exports:
4
+ *
5
+ * \`export * from "./lunora/_generated/scheduler.js";\`
6
+ *
7
+ * A Vite-first (class-A) app needs no such line: the generated worker entry
8
+ * forwards this module for you whenever it exists.
9
+ */
10
+ export { SchedulerDO } from "@lunora/scheduler";
11
+ `:"",h=o=>{const t=new Map;for(const n of o){const a=t.get(n.cron);a?a.push(n):t.set(n.cron,[n])}const i=[...t.keys()].map(n=>` ${JSON.stringify(n)},`).join(`
12
+ `),e=i.length>0?`
13
+ ${i}
14
+ `:"",r=[...t.entries()].map(([n,a])=>{const l=a.map(s=>{const f=s.workflow?`workflow: ${JSON.stringify(s.workflow.binding)}`:`functionPath: ${JSON.stringify(s.functionPath)}`;return` { name: ${JSON.stringify(s.name)}, ${f}, args: ${JSON.stringify(s.args)} },`}).join(`
15
+ `);return` ${JSON.stringify(n)}: [
16
+ ${l}
17
+ ],`}).join(`
18
+ `),d=r.length>0?`
19
+ ${r}
20
+ `:"";return`${c}/**
21
+ * One scheduled cron invocation. Exactly one target is set: \`functionPath\` is
22
+ * the \`namespace:fn\` dispatch ref (matches \`__lunoraRef\`), invoked on the
23
+ * shard; \`workflow\` is a \`WORKFLOW_*\` binding name whose durable workflow is
24
+ * started fresh per fire. \`args\` are forwarded verbatim (a workflow's become
25
+ * its \`params\`).
26
+ */
27
+ export interface LunoraCronJob {
28
+ args: Record<string, unknown>;
29
+ functionPath?: string;
30
+ name: string;
31
+ workflow?: string;
32
+ }
33
+
34
+ /**
35
+ * Deduplicated cron schedules — mirror of wrangler's \`triggers.crons\`. The
36
+ * Lunora vite plugin keeps \`wrangler.jsonc\` in sync with this array.
37
+ */
38
+ export const LUNORA_CRON_TRIGGERS: ReadonlyArray<string> = [${e}];
39
+
40
+ /**
41
+ * Dispatcher map keyed by cron expression. The Worker's \`scheduled()\` handler
42
+ * looks up \`event.cron\` here and dispatches every job in the list.
43
+ */
44
+ export const LUNORA_CRONS: Record<string, ReadonlyArray<LunoraCronJob>> = {${d}};
45
+ `},u=o=>{const t=[...o].toSorted((e,r)=>e.name.localeCompare(r.name)).map(e=>{const r=[`name: ${JSON.stringify(e.name)}`,`table: ${JSON.stringify(e.table)}`];return e.field!==void 0&&r.push(`field: ${JSON.stringify(e.field)}`),e.dimensions!==void 0&&r.push(`dimensions: ${JSON.stringify(e.dimensions)}`),e.metric!==void 0&&r.push(`metric: ${JSON.stringify(e.metric)}`),e.metadata!==void 0&&r.push(`metadata: ${JSON.stringify(e.metadata)}`),` { ${r.join(", ")} },`}).join(`
46
+ `),i=t.length>0?`
47
+ ${t}
48
+ `:"";return`${c}/**
49
+ * One vector index declared in \`schema.ts\` — an inline \`.vectorize()\` column
50
+ * or a standalone \`defineVectorIndex()\`. \`field\` is the source column (absent
51
+ * for a \`select\`-derived Shape B index); \`metadata\` lists the row fields
52
+ * mirrored into Vectorize for filtering.
53
+ */
54
+ export interface LunoraVectorIndex {
55
+ dimensions?: number;
56
+ field?: string;
57
+ metadata?: ReadonlyArray<string>;
58
+ metric?: "cosine" | "dot-product" | "euclidean";
59
+ name: string;
60
+ table: string;
61
+ }
62
+
63
+ /**
64
+ * Static registry of every vector index in the schema, sorted by name.
65
+ * Vectorize cannot enumerate indexes at runtime, so the worker passes this to
66
+ * \`createWorker({ vectorIntrospector })\` to back the studio's vector browser.
67
+ */
68
+ export const LUNORA_VECTOR_INDEXES: ReadonlyArray<LunoraVectorIndex> = [${i}];
69
+ `},p=o=>[...new Set(o.map(t=>t.cron))];export{h as emitCrons,g as emitScheduler,u as emitVectors,p as emitWranglerCronTriggers};
@@ -0,0 +1,113 @@
1
+ import{b as k}from"./qualifiers-BhOL15WZ.mjs";import{a as s,b as i,v as d,e as v,G as M}from"./shared-DjUziztz.mjs";const D="schema",w=a=>{for(const e of a.tables)s(e.name,"table name");const l=a.tables.map(e=>`"${e.name}"`).join(" | ")||"never",m=a.tables.filter(e=>e.extensionKey===void 0).map(e=>`"${e.name}"`).join(" | ")||"never",p=a.tables.map(e=>{const t=Object.entries(e.shape).map(([h,r])=>{const o=i(h);if(r.kind==="optional"){const g=r.inner?d(r.inner):"unknown";return` ${o}?: ${g};`}return` ${o}: ${d(r)};`}).join(`
2
+ `),n=t?`
3
+ ${t}
4
+ `:"",N=e.commitOrdered===!0?`
5
+ _commitSeq: number;`:"";return`export interface Doc_${e.name} {
6
+ _id: Id<"${e.name}">;
7
+ _creationTime: number;${N}${n}}`}).join(`
8
+
9
+ `),c=a.tables.map(e=>` ${e.name}: Doc_${e.name};`).join(`
10
+ `),y=a.tables.map(e=>{const t=e.indexes.map(n=>JSON.stringify(n.name)).join(" | ");return` ${e.name}: ${t||"never"};`}).join(`
11
+ `),x=a.tables.map(e=>{const t=e.searchIndexes.map(n=>JSON.stringify(n.name)).join(" | ");return` ${e.name}: ${t||"never"};`}).join(`
12
+ `),b=a.tables.map(e=>{const t=e.rankIndexes.map(n=>JSON.stringify(n.name)).join(" | ");return` ${e.name}: ${t||"never"};`}).join(`
13
+ `),T=a.tables.map(e=>{const t=e.shardMode==="global"?"":(e.geoIndexes??[]).map(n=>JSON.stringify(n.name)).join(" | ");return` ${e.name}: ${t||"never"};`}).join(`
14
+ `),f=a.vectorIndexes.map(e=>JSON.stringify(e.name)).join(" | ")||"never",$=a.tables.map(e=>v(e)).join(`
15
+
16
+ `),u=a.tables.map(e=>` ${e.name}: Insert_${e.name};`).join(`
17
+ `),I=a.tables.map(e=>{const t=e.relations.map(n=>(s(n.table,"relation target table"),` ${i(n.name)}: ${n.kind==="one"?"OneRelation":"ManyRelation"}<"${n.table}">;`)).join(`
18
+ `);return t?` ${e.name}: {
19
+ ${t}
20
+ };`:` ${e.name}: {};`}).join(`
21
+ `);return k(`${M}export type TableName = ${l};
22
+
23
+ /**
24
+ * The tables **this app declared** — every {@link TableName} except those an add-on
25
+ * contributed through \`defineSchema(...).extend(...)\`.
26
+ *
27
+ * An add-on's tables are real tables and stay in \`TableName\` (they are queryable,
28
+ * they appear in \`DataModel\`), but an app enumerating "my tables" should not have to
29
+ * know they exist: an account-deletion sweep, an export, a migration allowlist, or a
30
+ * helper generic over a table union is about the app's own data, and every add-on
31
+ * added or removed would otherwise silently change the correct answer.
32
+ *
33
+ * \`\`\`ts
34
+ * // Doesn't need to mention \`ratelimit_buckets\`, and won't drift when an add-on lands.
35
+ * const EXPORTED: readonly AppTableName[] = ["nodes", "tagColors"];
36
+ * \`\`\`
37
+ */
38
+ export type AppTableName = ${m};
39
+
40
+ export type Id<TName extends string> = string & { readonly __table: TName };
41
+
42
+ ${p}
43
+
44
+ export interface DataModel {
45
+ ${c}
46
+ }
47
+
48
+ export type Doc<T extends keyof DataModel> = DataModel[T];
49
+
50
+ /**
51
+ * Per-table index name union. \`never\` for tables without secondary indexes.
52
+ * Used by \`TableReader.withIndex()\` to constrain callers to declared names.
53
+ */
54
+ export interface IndexNamesByTable {
55
+ ${y}
56
+ }
57
+
58
+ export type IndexName<T extends keyof DataModel> = IndexNamesByTable[T];
59
+
60
+ /** Per-table search-index name union. \`never\` for tables without searchIndex. */
61
+ export interface SearchIndexNamesByTable {
62
+ ${x}
63
+ }
64
+
65
+ export type SearchIndexName<T extends keyof DataModel> = SearchIndexNamesByTable[T];
66
+
67
+ /** Per-table rank-index name union. \`never\` for tables without a rankIndex. */
68
+ export interface RankIndexNamesByTable {
69
+ ${b}
70
+ }
71
+
72
+ export type RankIndexName<T extends keyof DataModel> = RankIndexNamesByTable[T];
73
+
74
+ /** Per-table geo-index name union. \`never\` for tables without a geoIndex. */
75
+ export interface GeoIndexNamesByTable {
76
+ ${T}
77
+ }
78
+
79
+ export type GeoIndexName<T extends keyof DataModel> = GeoIndexNamesByTable[T];
80
+
81
+ /** Union of declared vector index names. \`never\` when none are declared. */
82
+ export type VectorIndexName = ${f};
83
+
84
+ ${$}
85
+
86
+ /** Per-table insert shape, accepted by \`ctx.db.<table>.insert(...)\`. */
87
+ export interface InsertModel {
88
+ ${u}
89
+ }
90
+
91
+ export type Insert<T extends keyof DataModel> = InsertModel[T];
92
+
93
+ /**
94
+ * Phantom relation descriptors. They carry the relation kind and target table
95
+ * as type parameters only — there is no runtime value — so the \`with\` argument
96
+ * and its return type can be inferred from {@link Relations}.
97
+ */
98
+ export interface OneRelation<Target extends keyof DataModel> {
99
+ readonly __relationKind: "one";
100
+ readonly __target: Target;
101
+ }
102
+
103
+ export interface ManyRelation<Target extends keyof DataModel> {
104
+ readonly __relationKind: "many";
105
+ readonly __target: Target;
106
+ }
107
+
108
+ /** Per-table relation map keyed by accessor name. \`{}\` for tables with none. */
109
+ export interface Relations {
110
+ ${I}
111
+ }
112
+
113
+ `,D)};export{D as SCHEMA_MODULE_PATH,w as emitDataModel};
@@ -0,0 +1,15 @@
1
+ import{SCHEMA_MODULE_PATH as m}from"./emitDataModel-D3WuEZ4b.mjs";import{b}from"./qualifiers-BhOL15WZ.mjs";import{G as f,a as d,d as g,v as p,u as T,c as A}from"./shared-DjUziztz.mjs";const c=e=>{switch(e.kind){case"array":case"object":case"record":case"union":return{builder:"text",mode:"json",notNull:!0,typeAnnotation:p(e)};case"bigint":return{builder:"blob",mode:"bigint",notNull:!0};case"boolean":return{builder:"integer",mode:"boolean",notNull:!0};case"bytes":return{builder:"blob",mode:"buffer",notNull:!0};case"date":case"timestamp":return{builder:"integer",notNull:!0};case"from":return{builder:"text",notNull:!0,typeAnnotation:p(e)};case"id":return{builder:"text",notNull:!0};case"literal":{const t=e.literalValue??"";return t.startsWith('"')||t.startsWith("'")?{builder:"text",notNull:!0}:t==="true"||t==="false"?{builder:"integer",mode:"boolean",notNull:!0}:t==="null"?{builder:"text",notNull:!0}:{builder:"real",notNull:!0}}case"null":return{builder:"text",notNull:!0};case"number":return{builder:"real",notNull:!0};case"optional":return{...e.inner?c(e.inner):{builder:"text",notNull:!1},notNull:!1};case"storage":case"string":return{builder:"text",notNull:!0};default:return{builder:"text",notNull:!0}}},N=(e,t)=>{const r=T(e);return r.kind==="id"&&r.tableName!==void 0&&t.has(r.tableName)?r.tableName:void 0},h=(e,t,r)=>{d(e,"drizzle column name");const n=c(t),o=n.mode?`, { mode: "${n.mode}" }`:"";let l=`${n.builder}("${e}"${o})`;n.typeAnnotation&&(l+=`.$type<${n.typeAnnotation}>()`);const s=N(t,r);return s!==void 0&&(l+=`.references((): AnySQLiteColumn => ${s}._id)`),n.notNull&&t.column?.notNull!==!1&&(l+=".notNull()"),l},j=e=>{const t=e.unique?"uniqueIndex":"index",r=e.fields.map(n=>(d(n,"drizzle index field"),`t.${n}`)).join(", ");return` ${A(e.name)}: ${t}(${JSON.stringify(e.name)}).on(${r}),`},S=(e,t)=>{d(e.name,"table name");const r=[' _id: text("_id").primaryKey(),',' _creationTime: integer("_creationTime").notNull(),',...Object.entries(e.shape).map(([o,l])=>` ${o}: ${h(o,l,t)},`)].join(`
2
+ `),n=e.indexes.length>0?`, (t) => ({
3
+ ${e.indexes.map(o=>j(o)).join(`
4
+ `)}
5
+ })`:"";return`export const ${e.name} = sqliteTable("${e.name}", {
6
+ ${r}
7
+ }${n});`},I=e=>e.typeAnnotation?.includes('Id<"')??!1,C=(e,t)=>{const r=new Set(["integer","sqliteTable","text"]),n=new Set;let o=!1,l=!1;for(const s of e){for(const i of Object.values(s.shape)){const a=c(i);r.add(a.builder),l=l||I(a),o=o||N(i,t)!==void 0}for(const i of s.indexes)n.add(i.unique?"uniqueIndex":"index")}return{columns:[...r].toSorted((s,i)=>s.localeCompare(i)),indexes:[...n].toSorted((s,i)=>s.localeCompare(i)),needsAnyColumn:o,needsId:l}},x=(e,t=!1)=>{if(e.length===0)return`${f}export {};
8
+ `;const r=g(t),n=new Set(e.map(u=>u.name)),{columns:o,indexes:l,needsAnyColumn:s,needsId:i}=C(e,n),a=[...l,...o].toSorted((u,z)=>u.localeCompare(z)),$=e.map(u=>S(u,n)).join(`
9
+
10
+ `),y=[s?`import type { AnySQLiteColumn } from "${r.serverDrizzle}";
11
+ `:"",i?`import type { Id } from "./dataModel.js";
12
+ `:""].join("");return`${f}import { ${a.join(", ")} } from "${r.serverDrizzle}";
13
+ ${y}
14
+ ${$}
15
+ `},q=(e,t=!1)=>{const r=e.tables.filter(o=>o.shardMode==="global"),n=e.tables.filter(o=>o.shardMode!=="global");return{global:b(x(r,t),m),shard:b(x(n,t),m)}};export{q as default};