@lunora/codegen 1.0.0-alpha.347 → 1.0.0-alpha.349

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.
@@ -1,11 +1,11 @@
1
- import{APP_METHOD_CAPABILITIES as k}from"./CAPABILITY_PROBES-brcmKenl.mjs";import{i as S}from"./schema-BgM8A3XV.mjs";import{G as E}from"./shared-8vTRkL2-.mjs";const D={configKey:"vectors",doc:"Wire the Vectorize index map backing `ctx.vectors`.",method:"vectors"},m=e=>[...k.filter(({key:r})=>e.capabilities.has(r)).map(({appMethod:r})=>r),...e.hasVectors?[D]:[]],g=e=>m(e).length>0,v=e=>(e.emailAgents?.length??0)>0,d=e=>e.tables.some(r=>S(r)),R=e=>e.hasScheduler?`
1
+ import{APP_METHOD_CAPABILITIES as E}from"./CAPABILITY_PROBES-brcmKenl.mjs";import{i as D}from"./schema-BgM8A3XV.mjs";import{a as R,I as A,G as x}from"./shared-8vTRkL2-.mjs";const C={configKey:"vectors",doc:"Wire the Vectorize index map backing `ctx.vectors`.",method:"vectors"},g=e=>[...E.filter(({key:t})=>e.capabilities.has(t)).map(({appMethod:t})=>t),...e.hasVectors?[C]:[]],v=e=>g(e).length>0,y=e=>(e.emailAgents?.length??0)>0,d=e=>e.tables.some(t=>D(t)),u=e=>e.liveStreams===!0&&(e.liveStreamDeclarations?.length??0)>0,O=e=>e.hasScheduler?`
2
2
  /** Resolve the \`SchedulerDO\`-backed scheduler for this env; \`undefined\` until the namespace is wired. */
3
3
  private resolveScheduler(env: Env): ReturnType<typeof createScheduler> | undefined {
4
4
  const namespace = this.schedulerDeclaration?.namespace(env);
5
5
 
6
6
  return namespace ? createScheduler({${e.jurisdiction?` jurisdiction: ${JSON.stringify(e.jurisdiction)},`:""} namespace }) : undefined;
7
7
  }
8
- `:"",A=e=>e?`
8
+ `:"",T=e=>e?`
9
9
  /**
10
10
  * One bucket's \`Storage\`, signing under the name it is registered as.
11
11
  *
@@ -114,7 +114,7 @@ import{APP_METHOD_CAPABILITIES as k}from"./CAPABILITY_PROBES-brcmKenl.mjs";impor
114
114
  storageUpload: (key: string, body: ArrayBuffer, opts?: { bucket?: string; contentType?: string; sha256?: string }) => pick(opts?.bucket).upload(key, body, opts),
115
115
  };
116
116
  }
117
- `:"",x=e=>e?`
117
+ `:"",N=e=>e?`
118
118
  /**
119
119
  * Adapt the raw D1 binding to \`@lunora/d1\`'s \`D1Exec\` (reads via \`all\`, writes via \`run\`, and — when the binding exposes it — several writes in one round trip via \`batch\`).
120
120
  *
@@ -336,12 +336,12 @@ const buildGlobalCdcApplier =
336
336
 
337
337
  return request.changes.length;
338
338
  };
339
- `:"",C=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}']:[]],O=e=>[...e.hasAccess?[" private accessSelector?: Selector<Env, CreateAccessResolverOptions | undefined>;"]:[]," private adminToken?: Selector<Env, string>;",...e.hasAuth?[" private authDeclaration?: AuthDeclaration<Env>;"]:[]," private cdcEnabled = false;",...e.hasDeliveryAuthorization===!1?[]:[' private deliveryAuthorizationSelector?: ShardConfig["deliveryAuthorization"];']," 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> = {};"]:[],...d(e)?[" private shardRegistrySelector?: Selector<Env, ShardNamespaceLike>;"]:[]," private shardSelector?: Selector<Env, ShardNamespaceLike>;",...e.hasSourcedTables?[' private sourceClientFactory?: NonNullable<ShardConfig["sourceClient"]>;']:[],...e.hasStorage?[" private storageDeclaration?: StorageDeclaration<Env>;"]:[]],T=e=>m(e).map(({configKey:r,doc:t,method:a})=>` /** ${t} */
340
- public ${a}(factory: (env: Env) => ReturnType<NonNullable<ShardConfig["${r}"]>>): this {
341
- this.shardExtras.${r} = factory as NonNullable<ShardConfig["${r}"]>;
339
+ `:"",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}']:[]],q=e=>[...e.hasAccess?[" private accessSelector?: Selector<Env, CreateAccessResolverOptions | undefined>;"]:[]," private adminToken?: Selector<Env, string>;",...e.hasAuth?[" private authDeclaration?: AuthDeclaration<Env>;"]:[]," private cdcEnabled = false;",...e.hasDeliveryAuthorization===!1?[]:[' private deliveryAuthorizationSelector?: ShardConfig["deliveryAuthorization"];']," 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>;"]:[],...v(e)?[" private readonly shardExtras: Partial<ShardConfig> = {};"]:[],...d(e)?[" private shardRegistrySelector?: Selector<Env, ShardNamespaceLike>;"]:[]," private shardSelector?: Selector<Env, ShardNamespaceLike>;",...e.hasSourcedTables?[' private sourceClientFactory?: NonNullable<ShardConfig["sourceClient"]>;']:[],...e.hasStorage?[" private storageDeclaration?: StorageDeclaration<Env>;"]:[]],L=e=>g(e).map(({configKey:t,doc:r,method:a})=>` /** ${r} */
340
+ public ${a}(factory: (env: Env) => ReturnType<NonNullable<ShardConfig["${t}"]>>): this {
341
+ this.shardExtras.${t} = factory as NonNullable<ShardConfig["${t}"]>;
342
342
 
343
343
  return this;
344
- }`),N=e=>[...e.hasAccess?[" /** Wire Cloudflare Access (Zero Trust) — feeds the verified Access identity into `ctx.auth` / RLS via `resolveIdentity`. Call it with no argument when the Access policy is attached to the Worker (the identity arrives on the execution context; nothing to configure); pass `teamDomain` + `aud` for a hostname-scoped Access application, whose `Cf-Access-Jwt-Assertion` JWT is verified against your team JWKS. When `.auth(...)` is also configured, Access is composed ahead of it (Access wins when it authenticated the caller; everyone else falls through to the app session). */\n public access(selector?: Selector<Env, CreateAccessResolverOptions>): this {\n this.accessSelector = selector ?? (() => undefined);\n\n return this;\n }"]:[],` /** Bearer token gating the \`/_lunora/admin/*\` endpoints the studio calls. */
344
+ }`),j=e=>[...e.hasAccess?[" /** Wire Cloudflare Access (Zero Trust) — feeds the verified Access identity into `ctx.auth` / RLS via `resolveIdentity`. Call it with no argument when the Access policy is attached to the Worker (the identity arrives on the execution context; nothing to configure); pass `teamDomain` + `aud` for a hostname-scoped Access application, whose `Cf-Access-Jwt-Assertion` JWT is verified against your team JWKS. When `.auth(...)` is also configured, Access is composed ahead of it (Access wins when it authenticated the caller; everyone else falls through to the app session). */\n public access(selector?: Selector<Env, CreateAccessResolverOptions>): this {\n this.accessSelector = selector ?? (() => undefined);\n\n return this;\n }"]:[],` /** Bearer token gating the \`/_lunora/admin/*\` endpoints the studio calls. */
345
345
  public admin(selector: Selector<Env, string>): this {
346
346
  this.adminToken = selector;
347
347
 
@@ -405,8 +405,8 @@ const buildGlobalCdcApplier =
405
405
  this.storageDeclaration = declaration;
406
406
 
407
407
  return this;
408
- }`]:[],...T(e)],q=e=>{const r=a=>e.hasScheduler?`
409
- ...(this.schedulerDeclaration ? { scheduler: this.resolveScheduler(env) as unknown as ${a}["scheduler"] } : {}),`:"",t=[" cdc: this.cdcEnabled,"," reactiveCache: this.reactiveCacheConfig,"," ...(this.maxRelationKeysLimit === undefined ? {} : { maxRelationKeys: this.maxRelationKeysLimit }),"," ...(this.observabilitySink === undefined ? {} : { observability: this.observabilitySink }),",...e.hasDeliveryAuthorization===!1?[]:[" ...(this.deliveryAuthorizationSelector === undefined ? {} : { deliveryAuthorization: this.deliveryAuthorizationSelector }),"]," ...(this.relationExistsPushDownMode === undefined ? {} : { relationExistsPushDown: this.relationExistsPushDownMode }),",...e.hasGlobal?[` ...(this.globalDeclaration
408
+ }`]:[],...L(e)],P=e=>{const t=a=>e.hasScheduler?`
409
+ ...(this.schedulerDeclaration ? { scheduler: this.resolveScheduler(env) as unknown as ${a}["scheduler"] } : {}),`:"",r=[" cdc: this.cdcEnabled,"," reactiveCache: this.reactiveCacheConfig,"," ...(this.maxRelationKeysLimit === undefined ? {} : { maxRelationKeys: this.maxRelationKeysLimit }),"," ...(this.observabilitySink === undefined ? {} : { observability: this.observabilitySink }),",...e.hasDeliveryAuthorization===!1?[]:[" ...(this.deliveryAuthorizationSelector === undefined ? {} : { deliveryAuthorization: this.deliveryAuthorizationSelector }),"]," ...(this.relationExistsPushDownMode === undefined ? {} : { relationExistsPushDown: this.relationExistsPushDownMode }),",...e.hasGlobal?[` ...(this.globalDeclaration
410
410
  ? {
411
411
  d1: (rawEnv: Record<string, unknown>, request?: { bookmark?: string; cdc?: boolean; cdcRetentionMs?: number; identity?: Record<string, unknown>; onBookmark?: (bookmark: string | undefined) => void; userId?: string | null }) => {
412
412
  const env = rawEnv as Env;
@@ -426,7 +426,7 @@ const buildGlobalCdcApplier =
426
426
  : undefined;
427
427
 
428
428
  return createD1CtxDb({
429
- ...(crossShard ? { crossShardCounter: crossShard.crossShardCounter, crossShardReader: crossShard.crossShardReader } : {}),${r("D1CtxDbOptions")}
429
+ ...(crossShard ? { crossShardCounter: crossShard.crossShardCounter, crossShardReader: crossShard.crossShardReader } : {}),${t("D1CtxDbOptions")}
430
430
  ...(request?.cdcRetentionMs === undefined ? {} : { cdcRetentionMs: request.cdcRetentionMs }),
431
431
  auth: { identity: request?.identity ?? null, userId: request?.userId ?? null },
432
432
  // Forwarded from the shard's own \`cdc\` config, so ONE
@@ -464,7 +464,7 @@ const buildGlobalCdcApplier =
464
464
  : undefined;
465
465
 
466
466
  return createHyperdriveGlobalCtxDb({
467
- ...(crossShard ? { crossShardCounter: crossShard.crossShardCounter, crossShardReader: crossShard.crossShardReader } : {}),${r("SqlCtxDbOptions")}
467
+ ...(crossShard ? { crossShardCounter: crossShard.crossShardCounter, crossShardReader: crossShard.crossShardReader } : {}),${t("SqlCtxDbOptions")}
468
468
  ...(request?.cdcRetentionMs === undefined ? {} : { cdcRetentionMs: request.cdcRetentionMs }),
469
469
  auth: { identity: request?.identity ?? null, userId: request?.userId ?? null },
470
470
  // See the D1 twin: one \`cdc\` switch, both changelogs.
@@ -485,13 +485,13 @@ const buildGlobalCdcApplier =
485
485
  ? {
486
486
  scheduler: (rawEnv: Record<string, unknown>) => this.resolveScheduler(rawEnv as Env),
487
487
  }
488
- : {}),`]:[],...d(e)?[" ...(this.shardRegistrySelector ? { shardRegistry: (rawEnv: Record<string, unknown>) => this.shardRegistrySelector?.(rawEnv as Env) } : {}),"]:[],...e.hasSourcedTables?[" ...(this.sourceClientFactory === undefined ? {} : { sourceClient: this.sourceClientFactory }),"]:[],...e.hasStorage?[" ...(this.storageDeclaration ? { storage: (rawEnv: Record<string, unknown>, origin?: string) => this.resolveStorage(rawEnv as Env, origin) } : {}),"]:[],...g(e)?[" ...this.shardExtras,"]:[]];return t.length>0?`
489
- ${t.join(`
488
+ : {}),`]:[],...d(e)?[" ...(this.shardRegistrySelector ? { shardRegistry: (rawEnv: Record<string, unknown>) => this.shardRegistrySelector?.(rawEnv as Env) } : {}),"]:[],...e.hasSourcedTables?[" ...(this.sourceClientFactory === undefined ? {} : { sourceClient: this.sourceClientFactory }),"]:[],...e.hasStorage?[" ...(this.storageDeclaration ? { storage: (rawEnv: Record<string, unknown>, origin?: string) => this.resolveStorage(rawEnv as Env, origin) } : {}),"]:[],...v(e)?[" ...this.shardExtras,"]:[]];return r.length>0?`
489
+ ${r.join(`
490
490
  `)}
491
- `:""},I=e=>e?['import * as lunoraIdentityContract from "../identity.js";']:[],L=(e,r)=>e?['import type { CreateAccessResolverOptions } from "@lunora/cloudflare-access";',`import { createAccessResolver${r?", composeResolvers":""} } from "@lunora/cloudflare-access";`]:[],j=e=>e?['import { createKvIntrospectorFromEnv } from "@lunora/bindings/kv";']:[],B=e=>e?['import { createVectorAdminIntrospector } from "@lunora/bindings/vectors";']:[],P=e=>e?['import type { D1CtxDbOptions, D1DatabaseLike, D1Exec } from "@lunora/d1";','import { applyCdcChanges, createD1CtxDb, emitD1QueryCost, exportGlobalRows, facetGlobalColumn, importGlobalRows, listGlobalTables, readD1CdcChanges, readGlobalTablePage, retryingExec } from "@lunora/d1";']:[],G=e=>e?['import notifyConfig from "../notify.js";']:[],_=e=>v(e)?['import { dispatchAgentEmail } from "@lunora/agent/inbound";']:[],W=e=>v(e)?['import * as lunoraAgentDefinitions from "../agents.js";']:[],M=e=>{const{hasFramework:r,hasGlobal:t,hasHyperdriveGlobal:a,hasQueue:s,useUmbrella:o}=e,i=o?"lunorash/runtime":"@lunora/runtime",c=["ExecutionContextLike","HttpRouterLike","LunoraWorker","Route","ScheduledControllerLike","ShardNamespaceLike","WorkerOptions",...s?["TriggerTrace"]:[],...t?["GlobalIntrospector"]:[],...e.tables.length>0?["ShardingInfo"]:[],...r?["FrameworkHostHandler"]:[]],l=[...t||a?["createCrossShardRelationCapabilities"]:[],...d(e)?["createDynamicShardRegistry","createQueryCoordinator"]:[],"createWorker",...e.jurisdiction?["declareAppJurisdiction"]:[],"resolveLogArchiveFromEnv",...e.hasAuth?["memoizeIdentity"]:[],...r?["withFrameworkWorker"]:[]].join(", ");return[`import type { ${[...c].toSorted((n,h)=>n.localeCompare(h)).join(", ")} } from "${i}";`,`import { ${l} } from "${i}";`]},H=e=>{const{hasAccess:r,hasAuth:t,hasGlobal:a,hasHyperdriveGlobal:s,hasKvIntrospector:o,hasQueue:i,hasScheduler:c,hasStorage:l,hasWorkflow:n,wantsOpenApi:h,wantsOpenRpc:u}=e;return[...t?['import type { AuthNamespaceLike, LunoraAuth, LunoraAuthOptions } from "@lunora/auth";','import { authDiscoveryPathsFor, createAuth, createAuthAdmin, createAuthAuditReader, createDoAuthWiring, d1Executor, handleAuthDiscoveryRequest, handleAuthRequest, lunoraD1Adapter } from "@lunora/auth";']:[],...L(r,t),...P(a),...s?['import type { HyperdriveEngine } from "@lunora/hyperdrive/global";','import { createHyperdriveGlobalCtxDb } from "@lunora/hyperdrive/global";','import type { SqlCtxDbOptions, SqlExec } from "@lunora/sql-store";']:[],...j(o),...B(e.hasVectors),...c?['import type { DurableObjectNamespaceLike } from "@lunora/scheduler";','import { createScheduler } from "@lunora/scheduler";']:[],...l?['import type { R2BucketLike, R2S3Credentials, Storage } from "@lunora/storage";','import { createBucketStorage, createStorage } from "@lunora/storage";']:[],...n?['import { createWorkflowsRestClient } from "@lunora/workflow";']:[],..._(e),...M(e),"",...I(e.identity),...W(e),...a||s?['import schema from "../schema.js";']:[],...G(e.hasNotify),'import { LUNORA_CRONS } from "./crons.js";','import { LUNORA_FUNCTIONS } from "./functions.js";',...i?['import { createQueueCaptureSink, dispatchQueueBatch, shouldCaptureQueue } from "@lunora/queue";','import { LUNORA_QUEUE_REGISTRY } from "./queues.js";']:[],...e.wantsArchitecture?['import { architecture } from "./architecture.js";']:[],...h?['import { openApiSpec } from "./openapi.js";']:[],...u?['import { openRpcSpec } from "./openrpc.js";']:[],'import { createShardDO } from "./shard.js";',...e.hasVectors?['import { LUNORA_VECTOR_INDEXES } from "./vectors.js";']:[]]},$=e=>e.jurisdiction&&e.jurisdictionPinsAuth===!0?`
491
+ `:""},B=e=>e?['import * as lunoraIdentityContract from "../identity.js";']:[],G=(e,t)=>e?['import type { CreateAccessResolverOptions } from "@lunora/cloudflare-access";',`import { createAccessResolver${t?", composeResolvers":""} } from "@lunora/cloudflare-access";`]:[],_=e=>e?['import { createKvIntrospectorFromEnv } from "@lunora/bindings/kv";']:[],M=e=>e?['import { createVectorAdminIntrospector } from "@lunora/bindings/vectors";']:[],W=e=>e?['import type { D1CtxDbOptions, D1DatabaseLike, D1Exec } from "@lunora/d1";','import { applyCdcChanges, createD1CtxDb, emitD1QueryCost, exportGlobalRows, facetGlobalColumn, importGlobalRows, listGlobalTables, readD1CdcChanges, readGlobalTablePage, retryingExec } from "@lunora/d1";']:[],$=e=>e?['import notifyConfig from "../notify.js";']:[],H=e=>y(e)?['import { dispatchAgentEmail } from "@lunora/agent/inbound";']:[],U=e=>y(e)?['import * as lunoraAgentDefinitions from "../agents.js";']:[],F=e=>{const{hasFramework:t,hasGlobal:r,hasHyperdriveGlobal:a,hasQueue:n,useUmbrella:o}=e,i=o?"lunorash/runtime":"@lunora/runtime",l=["ExecutionContextLike","HttpRouterLike","LunoraWorker","Route","ScheduledControllerLike","ShardNamespaceLike","WorkerOptions",...n?["TriggerTrace"]:[],...r?["GlobalIntrospector"]:[],...e.tables.length>0?["ShardingInfo"]:[],...t?["FrameworkHostHandler"]:[]],c=[...r||a?["createCrossShardRelationCapabilities"]:[],...d(e)?["createDynamicShardRegistry","createQueryCoordinator"]:[],"createWorker",...e.jurisdiction?["declareAppJurisdiction"]:[],"resolveLogArchiveFromEnv",...e.hasAuth?["memoizeIdentity"]:[],...t?["withFrameworkWorker"]:[]].join(", ");return[`import type { ${[...l].toSorted((s,h)=>s.localeCompare(h)).join(", ")} } from "${i}";`,`import { ${c} } from "${i}";`]},Q=e=>{const{hasAccess:t,hasAuth:r,hasGlobal:a,hasHyperdriveGlobal:n,hasKvIntrospector:o,hasQueue:i,hasScheduler:l,hasStorage:c,hasWorkflow:s,wantsOpenApi:h,wantsOpenRpc:p}=e;return[...r?['import type { AuthNamespaceLike, LunoraAuth, LunoraAuthOptions } from "@lunora/auth";','import { authDiscoveryPathsFor, createAuth, createAuthAdmin, createAuthAuditReader, createDoAuthWiring, d1Executor, handleAuthDiscoveryRequest, handleAuthRequest, lunoraD1Adapter } from "@lunora/auth";']:[],...G(t,r),...W(a),...n?['import type { HyperdriveEngine } from "@lunora/hyperdrive/global";','import { createHyperdriveGlobalCtxDb } from "@lunora/hyperdrive/global";','import type { SqlCtxDbOptions, SqlExec } from "@lunora/sql-store";']:[],..._(o),...M(e.hasVectors),...l?['import type { DurableObjectNamespaceLike } from "@lunora/scheduler";','import { createScheduler } from "@lunora/scheduler";']:[],...c?['import type { R2BucketLike, R2S3Credentials, Storage } from "@lunora/storage";','import { createBucketStorage, createStorage } from "@lunora/storage";']:[],...s?['import { createWorkflowsRestClient } from "@lunora/workflow";']:[],...H(e),...F(e),"",...B(e.identity),...U(e),...a||n?['import schema from "../schema.js";']:[],...$(e.hasNotify),'import { LUNORA_CRONS } from "./crons.js";','import { LUNORA_FUNCTIONS } from "./functions.js";',...i?['import { createQueueCaptureSink, dispatchQueueBatch, shouldCaptureQueue } from "@lunora/queue";','import { LUNORA_QUEUE_REGISTRY } from "./queues.js";']:[],...e.wantsArchitecture?['import { architecture } from "./architecture.js";']:[],...h?['import { openApiSpec } from "./openapi.js";']:[],...p?['import { openRpcSpec } from "./openrpc.js";']:[],'import { createShardDO } from "./shard.js";',...u(e)?[`import { liveStreamRouter } from "${e.useUmbrella?"lunorash/server":"@lunora/server"}";`]:[],...e.hasVectors?['import { LUNORA_VECTOR_INDEXES } from "./vectors.js";']:[]]},z=e=>e.jurisdiction&&e.jurisdictionPinsAuth===!0?`
492
492
  // The schema's jurisdiction pins the auth object like every other DO.
493
- jurisdiction: ${JSON.stringify(e.jurisdiction)},`:"",U=e=>typeof e=="string"?`{ mode: { kind: ${JSON.stringify(e)} } }`:`{ mode: { field: ${JSON.stringify(e.field)}, kind: "shardBy" } }`,F=e=>[...e.tables.length>0?[` const tableSharding = new Map<string, ShardingInfo>([
494
- ${e.tables.map(r=>` [${JSON.stringify(r.name)}, ${U(r.shardMode)}],`).join(`
493
+ jurisdiction: ${JSON.stringify(e.jurisdiction)},`:"",J=e=>typeof e=="string"?`{ mode: { kind: ${JSON.stringify(e)} } }`:`{ mode: { field: ${JSON.stringify(e.field)}, kind: "shardBy" } }`,K=e=>[...e.tables.length>0?[` const tableSharding = new Map<string, ShardingInfo>([
494
+ ${e.tables.map(t=>` [${JSON.stringify(t.name)}, ${J(t.shardMode)}],`).join(`
495
495
  `)}
496
496
  ]);
497
497
 
@@ -500,7 +500,10 @@ ${e.tables.map(r=>` [${JSON.stringify(r.name)}, ${U(r.shardMode)}],`)
500
500
 
501
501
  if (shardRegistry) {
502
502
  options.queryCoordinator = createQueryCoordinator({ registry: createDynamicShardRegistry({ ${e.jurisdiction?`jurisdiction: ${JSON.stringify(e.jurisdiction)}, `:""}namespace: shardRegistry }) });
503
- }`]:[]],Q=e=>[...F(e),...e.hasScheduler?[` if (this.schedulerDeclaration) {
503
+ }`]:[]],f=e=>(e.liveStreamDeclarations??[]).map(t=>{if(R(t.exportName,"live stream export name"),!A.test(t.filePath))throw new Error(`@lunora/codegen: live stream file path is not safe to import: ${JSON.stringify(t.filePath)}`);return` { id: ${JSON.stringify(t.id)}, load: () => import("../${t.filePath}.js").then((m) => m.${t.exportName}) },`}),V=e=>u(e)?[" httpRouter: liveStreamRouter([",...f(e)," ], this.httpRouterApp),"]:[" ...(this.httpRouterApp ? { httpRouter: this.httpRouterApp } : {}),"],Y=e=>u(e)?[" liveStreamRoutes: [",...(e.liveStreamDeclarations??[]).flatMap(t=>[` ${JSON.stringify(`GET /live/${t.id}/connect`)},`,` ${JSON.stringify(`POST /live/${t.id}/control`)},`])," ],"]:[],X=e=>u(e)?`liveStreamRouter([
504
+ ${f(e).join(`
505
+ `)}
506
+ ], host)`:"host",Z=e=>[...K(e),...e.hasScheduler?[` if (this.schedulerDeclaration) {
504
507
  options.schedulerDO = this.schedulerDeclaration.namespace(env);
505
508
  }`]:[],...e.hasWorkflow?[` options.workflowsClient = (workflowEnv) => {
506
509
  const source = workflowEnv as Record<string, unknown>;
@@ -578,7 +581,7 @@ ${e.tables.map(r=>` [${JSON.stringify(r.name)}, ${U(r.shardMode)}],`)
578
581
  // Memoised on the declaration: a framework-hosted worker rebuilds these
579
582
  // options per request, and \`options(env)\` rebuilds every plugin.
580
583
  discoveryPaths,
581
- internalSecret,${$(e)}
584
+ internalSecret,${z(e)}
582
585
  namespace,
583
586
  ...(objectName === undefined ? {} : { objectName }),
584
587
  });
@@ -746,17 +749,17 @@ ${e.tables.map(r=>` [${JSON.stringify(r.name)}, ${U(r.shardMode)}],`)
746
749
  }`:` if (this.accessSelector) {
747
750
  options.resolveIdentity = createAccessResolver(this.accessSelector(env));
748
751
  }`]:[],...e.voiceAgents&&e.voiceAgents.length>0?[` options.voiceAgents = {
749
- ${e.voiceAgents.map(r=>` ${JSON.stringify(r.exportName)}: (env as Record<string, unknown>)[${JSON.stringify(r.bindingName)}] as ShardNamespaceLike,`).join(`
752
+ ${e.voiceAgents.map(t=>` ${JSON.stringify(t.exportName)}: (env as Record<string, unknown>)[${JSON.stringify(t.bindingName)}] as ShardNamespaceLike,`).join(`
750
753
  `)}
751
- };`]:[]],z=e=>[" cronJobs: LUNORA_CRONS,"," functions: LUNORA_FUNCTIONS,",...e.identity?[` identity: lunoraIdentityContract.${e.identity.exportName},`]:[],...e.jurisdiction?[` jurisdiction: ${JSON.stringify(e.jurisdiction)},`]:[],...e.wantsArchitecture?[" architecture,"]:[],...e.wantsOpenApi?[" openApiSpec,"]:[],...e.wantsOpenRpc?[" openRpcSpec,"]:[],...e.hasQueue?[` queue: (batch: unknown, queueEnv: unknown, _context: ExecutionContextLike, trigger: TriggerTrace, ${e.liveStreams?"queueLive":"_live"}: Parameters<typeof dispatchQueueBatch>[2]["live"], queueFetch: Parameters<typeof dispatchQueueBatch>[2]["fetchImpl"]): Promise<void> =>`," dispatchQueueBatch(batch as Parameters<typeof dispatchQueueBatch>[0], LUNORA_QUEUE_REGISTRY, {"," capture: shouldCaptureQueue(queueEnv as Record<string, unknown>)",` ? createQueueCaptureSink(queueEnv as Record<string, unknown>${e.jurisdiction?`, { jurisdiction: ${JSON.stringify(e.jurisdiction)} }`:""})`," : undefined,"," env: queueEnv as Record<string, unknown>,"," traceparent: trigger.traceparent,"," fetchImpl: queueFetch,",...e.liveStreams?[" live: queueLive,"]:[]," }),"]:[]," ...(this.httpRouterApp ? { httpRouter: this.httpRouterApp } : {}),"," routes: this.routeMap,",...e.liveStreamsWithheld?[" liveStreams: false,"]:[]," shardDO: this.shardSelector?.(env) ?? (undefined as unknown as ShardNamespaceLike),"],J=e=>e?`
754
+ };`]:[]],ee=e=>[" cronJobs: LUNORA_CRONS,"," functions: LUNORA_FUNCTIONS,",...e.identity?[` identity: lunoraIdentityContract.${e.identity.exportName},`]:[],...e.jurisdiction?[` jurisdiction: ${JSON.stringify(e.jurisdiction)},`]:[],...e.wantsArchitecture?[" architecture,"]:[],...e.wantsOpenApi?[" openApiSpec,"]:[],...e.wantsOpenRpc?[" openRpcSpec,"]:[],...e.hasQueue?[` queue: (batch: unknown, queueEnv: unknown, _context: ExecutionContextLike, trigger: TriggerTrace, ${e.liveStreams?"queueLive":"_live"}: Parameters<typeof dispatchQueueBatch>[2]["live"], queueFetch: Parameters<typeof dispatchQueueBatch>[2]["fetchImpl"]): Promise<void> =>`," dispatchQueueBatch(batch as Parameters<typeof dispatchQueueBatch>[0], LUNORA_QUEUE_REGISTRY, {"," capture: shouldCaptureQueue(queueEnv as Record<string, unknown>)",` ? createQueueCaptureSink(queueEnv as Record<string, unknown>${e.jurisdiction?`, { jurisdiction: ${JSON.stringify(e.jurisdiction)} }`:""})`," : undefined,"," env: queueEnv as Record<string, unknown>,"," traceparent: trigger.traceparent,"," fetchImpl: queueFetch,",...e.liveStreams?[" live: queueLive,"]:[]," }),"]:[],...V(e),...Y(e)," routes: this.routeMap,",...e.liveStreamsWithheld?[" liveStreams: false,"]:[]," shardDO: this.shardSelector?.(env) ?? (undefined as unknown as ShardNamespaceLike),"],te=e=>e?`
752
755
  /** The identity memo per \`env\` object, owned by one assembled worker. */
753
756
  type IdentityMemoStore = WeakMap<object, ReturnType<typeof memoizeIdentity>>;
754
- `:"",K=e=>[...e.hasAuth?["AuthDeclaration"]:[],"ComposedApp",...e.hasGlobal?["GlobalDeclaration"]:[],"LunoraConfig",...e.hasScheduler?["SchedulerDeclaration"]:[],"Selector",...e.hasStorage?["StorageDeclaration"]:[]].toSorted((r,t)=>r.localeCompare(t)).join(", "),Z=e=>{const r=(e.hasVectors??!0)&&(e.vectorIndexCount??0)>0,t={...e,hasVectors:r},{hasAuth:a}=t,s=C(t),o=Q(t),i=a?` let auth: LunoraAuth | null = null;
757
+ `:"",re=e=>[...e.hasAuth?["AuthDeclaration"]:[],"ComposedApp",...e.hasGlobal?["GlobalDeclaration"]:[],"LunoraConfig",...e.hasScheduler?["SchedulerDeclaration"]:[],"Selector",...e.hasStorage?["StorageDeclaration"]:[]].toSorted((t,r)=>t.localeCompare(r)).join(", "),oe=e=>{const t=(e.hasVectors??!0)&&(e.vectorIndexCount??0)>0,r={...e,hasVectors:t},{hasAuth:a}=r,n=I(r),o=Z(r),i=a?` let auth: LunoraAuth | null = null;
755
758
  let authInit: Promise<void> | null = null;
756
759
  // One memo per env for THIS assembled worker: a framework-hosted worker rebuilds its options per
757
760
  // request and must reuse it, but a second \`assemble()\` has its own auth closure and must not share.
758
761
  const identityMemos: IdentityMemoStore = new WeakMap();
759
- `:"",c=a?`
762
+ `:"",l=a?`
760
763
  const initAuth = async (env: Env): Promise<void> => {
761
764
  if (!this.authDeclaration) {
762
765
  return;
@@ -808,17 +811,17 @@ type IdentityMemoStore = WeakMap<object, ReturnType<typeof memoizeIdentity>>;
808
811
  authInit = null;
809
812
  throw error;
810
813
  }));
811
- `:"",l=a?`
812
- await ensureAuth(env);`:"",n=a?"() => auth, identityMemos":"() => null",h=a?"getAuth: () => LunoraAuth | null, identityMemos: IdentityMemoStore":"_getAuth: () => null",u=t.hasFramework?` const buildWorker = (env: Env): LunoraWorker =>
813
- host ? withFrameworkWorker(host, (hostEnv) => this.buildWorkerOptions(hostEnv as Env, ${n})) : createWorker(this.buildWorkerOptions(env, ${n}));`:` const buildWorker = (env: Env): LunoraWorker => createWorker(this.buildWorkerOptions(env, ${n}));`,y=t.hasFramework?"host?: FrameworkHostHandler":"",p=t.emailAgents??[],f=p.length>0?` composed.email = dispatchAgentEmail([
814
- ${p.map(b=>` { agent: lunoraAgentDefinitions.${b.exportName}, className: ${JSON.stringify(b.className)} },`).join(`
814
+ `:"",c=a?`
815
+ await ensureAuth(env);`:"",s=a?"() => auth, identityMemos":"() => null",h=a?"getAuth: () => LunoraAuth | null, identityMemos: IdentityMemoStore":"_getAuth: () => null",p=r.hasFramework?` const buildWorker = (env: Env): LunoraWorker =>
816
+ host ? withFrameworkWorker(${X(r)}, (hostEnv) => this.buildWorkerOptions(hostEnv as Env, ${s})) : createWorker(this.buildWorkerOptions(env, ${s}));`:` const buildWorker = (env: Env): LunoraWorker => createWorker(this.buildWorkerOptions(env, ${s}));`,w=r.hasFramework?"host?: FrameworkHostHandler":"",b=r.emailAgents??[],k=b.length>0?` composed.email = dispatchAgentEmail([
817
+ ${b.map(m=>` { agent: lunoraAgentDefinitions.${m.exportName}, className: ${JSON.stringify(m.className)} },`).join(`
815
818
  `)}
816
819
  ]);
817
820
 
818
- `:"",w=` /** Materialise the standalone Cloudflare worker + \`ShardDO\` class. */
821
+ `:"",S=` /** Materialise the standalone Cloudflare worker + \`ShardDO\` class. */
819
822
  public build(): ComposedApp {
820
823
  return this.assemble();
821
- }${t.hasFramework?"\n\n /** Compose Lunora's realtime plane INTO a meta-framework's Cloudflare handler (SvelteKit/Astro/Nuxt). The framework `host` serves everything except the reserved `/_lunora/*` endpoints; pass the adapter-emitted worker (e.g. SvelteKit's `_worker.js`, Astro's `handle`). */\n public buildFrameworkWorker(host: FrameworkHostHandler): ComposedApp {\n return this.assemble(host);\n }":""}`;return`${E}${H(t).join(`
824
+ }${r.hasFramework?"\n\n /** Compose Lunora's realtime plane INTO a meta-framework's Cloudflare handler (SvelteKit/Astro/Nuxt). The framework `host` serves everything except the reserved `/_lunora/*` endpoints; pass the adapter-emitted worker (e.g. SvelteKit's `_worker.js`, Astro's `handle`). */\n public buildFrameworkWorker(host: FrameworkHostHandler): ComposedApp {\n return this.assemble(host);\n }":""}`;return`${x}${Q(r).join(`
822
825
  `)}
823
826
 
824
827
  /** Read a value off the per-request \`env\`. Returns \`undefined\` to leave the capability unconfigured (its \`ctx.*\`/admin surface stays a clear-error stub). */
@@ -826,15 +829,15 @@ type Selector<Env, T> = (env: Env) => T | undefined;
826
829
 
827
830
  /** The generated \`createShardDO\` config — \`.observability()\`, \`.maxRelationKeys()\` and the long-tail \`.ai()\` / \`.kv()\` / … methods pass straight through to it. */
828
831
  type ShardConfig = NonNullable<Parameters<typeof createShardDO>[0]>;
829
- ${J(a)}${t.jurisdiction?`
832
+ ${te(a)}${r.jurisdiction?`
830
833
  // Module scope, so every isolate loading this script (the worker and each Durable
831
834
  // Object class it exports) knows the schema's jurisdiction before a request runs.
832
835
  // \`@lunora/mail\` reads it to pin its shard RPC like every other DO path.
833
- declareAppJurisdiction(${JSON.stringify(t.jurisdiction)});
836
+ declareAppJurisdiction(${JSON.stringify(r.jurisdiction)});
834
837
  `:""}
835
- ${s.join(`
838
+ ${n.join(`
836
839
 
837
- `)}${s.length>0?`
840
+ `)}${n.length>0?`
838
841
 
839
842
  `:""}/** The composed app: a Cloudflare module worker (\`fetch\` / \`scheduled\` / optional \`email\`) plus the \`ShardDO\` class binding. */
840
843
  interface ComposedApp extends LunoraWorker {
@@ -851,32 +854,32 @@ interface ComposedApp extends LunoraWorker {
851
854
  * first request so per-isolate singletons are built once.
852
855
  */
853
856
  class AppBuilder<Env extends object> {
854
- ${O(t).join(`
857
+ ${q(r).join(`
855
858
  `)}
856
859
 
857
860
  private emailHandler?: (env: Env) => (message: unknown, env: unknown, context: ExecutionContextLike) => Promise<void>;
858
861
 
859
- ${N(t).join(`
862
+ ${j(r).join(`
860
863
 
861
864
  `)}
862
865
 
863
- ${w}
866
+ ${S}
864
867
 
865
868
  /** Build the shard DO + compose the worker (standalone or framework-hosted), wrapping the lazy per-isolate singletons + auth init. */
866
- private assemble(${y}): ComposedApp {
867
- const ShardDO = createShardDO({${q(t)}});
869
+ private assemble(${w}): ComposedApp {
870
+ const ShardDO = createShardDO({${P(r)}});
868
871
 
869
872
  // Per-isolate singletons: the worker (and auth instance) are expensive to
870
873
  // build, so the first request constructs them and every later request on
871
874
  // the same isolate reuses them.
872
875
  let worker: LunoraWorker | null = null;
873
- ${i}${c}
874
- ${u}
876
+ ${i}${l}
877
+ ${p}
875
878
 
876
879
  const composed: ComposedApp = {
877
880
  ShardDO,
878
881
  fetch: async (request: Request, rawEnv: unknown, context: ExecutionContextLike): Promise<Response> => {
879
- const env = rawEnv as Env;${l}
882
+ const env = rawEnv as Env;${c}
880
883
  worker ??= buildWorker(env);
881
884
 
882
885
  return worker.fetch(request, rawEnv, context);
@@ -890,7 +893,7 @@ ${u}
890
893
  worker ??= buildWorker(rawEnv as Env);
891
894
 
892
895
  return worker.serverQuery(request, rawEnv, reference, args, options);
893
- },${t.hasQueue||t.hasFramework?`
896
+ },${r.hasQueue||r.hasFramework?`
894
897
  queue: async (batch: unknown, rawEnv: unknown, context: ExecutionContextLike): Promise<void> => {
895
898
  worker ??= buildWorker(rawEnv as Env);
896
899
 
@@ -898,12 +901,12 @@ ${u}
898
901
  },`:""}
899
902
  };
900
903
 
901
- ${f} if (this.emailHandler) {
904
+ ${k} if (this.emailHandler) {
902
905
  const handler = this.emailHandler;
903
906
 
904
907
  composed.email = (message, rawEnv, context) => handler(rawEnv as Env)(message, rawEnv, context);
905
908
  }
906
- ${t.hasFramework?`
909
+ ${r.hasFramework?`
907
910
  // A framework host may export its own \`email\` (Nitro's \`cloudflare-module\`
908
911
  // does). Nothing in Lunora serves one, so when the app registered no handler
909
912
  // of its own the host's is the only one there is — forward to it rather than
@@ -918,11 +921,11 @@ ${t.hasFramework?`
918
921
  `:""}
919
922
  return composed;
920
923
  }
921
- ${R(t)}${A(t.hasStorage)}
924
+ ${O(r)}${T(r.hasStorage)}
922
925
  /** Fan the recorded declarations into the worker-side \`createWorker\` options. */
923
926
  private buildWorkerOptions(env: Env, ${h}): WorkerOptions {
924
927
  const options: WorkerOptions = {
925
- ${z(t).join(`
928
+ ${ee(r).join(`
926
929
  `)}
927
930
  };
928
931
 
@@ -943,7 +946,7 @@ ${o.join(`
943
946
  return options;
944
947
  }
945
948
  }
946
- ${x(t.hasGlobal)}
949
+ ${N(r.hasGlobal)}
947
950
  /**
948
951
  * Shape of the project's root \`lunora.config.*\`.
949
952
  *
@@ -982,5 +985,5 @@ interface LunoraConfig<Env extends object = object> {
982
985
  const defineApp = <Env extends object>(): AppBuilder<Env> => new AppBuilder<Env>();
983
986
 
984
987
  export { AppBuilder, defineApp };
985
- export type { ${K(t)} };
986
- `};export{Z as emitApp};
988
+ export type { ${re(r)} };
989
+ `};export{oe as emitApp};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/codegen",
3
- "version": "1.0.0-alpha.347",
3
+ "version": "1.0.0-alpha.349",
4
4
  "description": "Code generator for Lunora: emits _generated/{api,server,dataModel}.ts from your schema",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -50,8 +50,8 @@
50
50
  "access": "public"
51
51
  },
52
52
  "dependencies": {
53
- "@lunora/advisor": "1.0.0-alpha.251",
54
- "@lunora/agent": "1.0.0-alpha.241",
53
+ "@lunora/advisor": "1.0.0-alpha.253",
54
+ "@lunora/agent": "1.0.0-alpha.243",
55
55
  "@lunora/container": "1.0.0-alpha.89",
56
56
  "@lunora/errors": ">=1.0.0-alpha.51 <2.0.0-0",
57
57
  "@lunora/platform": "1.0.0-alpha.74",