@lunora/codegen 1.0.0-alpha.249 → 1.0.0-alpha.250

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,9 +1,9 @@
1
- import{A as w}from"./capabilities-DJJWVEtk.mjs";import{i as k}from"./ir-DBSvhNa-.mjs";import{G as S}from"./shared-DjUziztz.mjs";const E=e=>`has${e.charAt(0).toUpperCase()}${e.slice(1)}`,g=w.map(({appMethod:e,key:t})=>[E(t),e.method,e.configKey,e.doc]),m=e=>g.some(([t])=>e[t]),D=e=>e?['import * as lunoraIdentityContract from "../identity.js";']:[],R=(e,t)=>e?['import type { CreateAccessResolverOptions } from "@lunora/cloudflare-access";',`import { createAccessResolver${t?", composeResolvers":""} } from "@lunora/cloudflare-access";`]:[],x=e=>e?['import { createKvIntrospectorFromEnv } from "@lunora/bindings/kv";']:[],A=e=>e?['import { createVectorAdminIntrospector } from "@lunora/bindings/vectors";']:[],C=e=>e?['import type { D1CtxDbOptions, D1DatabaseLike, D1Exec } from "@lunora/d1";','import { applyCdcChanges, createD1CtxDb, emitD1QueryCost, exportGlobalRows, facetGlobalColumn, importGlobalRows, listGlobalTables, readD1CdcChanges, readGlobalTablePage, retryingExec } from "@lunora/d1";']:[],O=e=>e?['import notifyConfig from "../notify.js";']:[],v=e=>(e.emailAgents?.length??0)>0,T=e=>v(e)?['import { dispatchAgentEmail } from "@lunora/agent/inbound";']:[],N=e=>v(e)?['import * as lunoraAgentDefinitions from "../agents.js";']:[],d=e=>e.tables.some(t=>k(t)),I=e=>{const{hasFramework:t,hasGlobal:r,hasHyperdriveGlobal:a,hasQueue:n,useUmbrella:i}=e,o=i?"lunorash/runtime":"@lunora/runtime",l=["ExecutionContextLike","HttpRouterLike","LunoraWorker","Route","ScheduledControllerLike","ShardNamespaceLike","WorkerOptions",...n?["TriggerTrace"]:[],...r?["GlobalIntrospector"]:[],...e.tables.length>0?["ShardingInfo"]:[],...t?["FrameworkHostHandler"]:[]],s=[...r||a?["createCrossShardRelationCapabilities"]:[],...d(e)?["createDynamicShardRegistry","createQueryCoordinator"]:[],"createWorker",...e.jurisdiction?["declareAppJurisdiction"]:[],"resolveLogArchiveFromEnv",...t?["withFrameworkWorker"]:[]].join(", ");return[`import type { ${[...l].toSorted((c,h)=>c.localeCompare(h)).join(", ")} } from "${o}";`,`import { ${s} } from "${o}";`]},L=e=>{const{hasAccess:t,hasAuth:r,hasGlobal:a,hasHyperdriveGlobal:n,hasKvIntrospector:i,hasQueue:o,hasScheduler:l,hasStorage:s,hasWorkflow:c,wantsOpenApi:h,wantsOpenRpc:u}=e;return[...r?['import type { AuthNamespaceLike, LunoraAuth, LunoraAuthOptions } from "@lunora/auth";','import { createAuth, createAuthAdmin, createAuthAuditReader, createDoAuthWiring, d1Executor, ensureMigrated, handleAuthRequest, lunoraD1Adapter } from "@lunora/auth";']:[],...R(t,r),...C(a),...n?['import type { HyperdriveEngine } from "@lunora/hyperdrive/global";','import { createHyperdriveGlobalCtxDb } from "@lunora/hyperdrive/global";','import type { SqlCtxDbOptions, SqlExec } from "@lunora/sql-store";']:[],...x(i),...A(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";']:[],...T(e),...I(e),"",...D(e.identity),...N(e),...a||n?['import schema from "../schema.js";']:[],...O(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";']:[],...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===!0?['import { LUNORA_VECTOR_INDEXES } from "./vectors.js";']:[]]},q=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}']:[]],j=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>;"]:[],...m(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>;"]:[]],G=e=>g.filter(([t])=>e[t]).map(([,t,r,a])=>` /** ${a} */
2
- public ${t}(factory: (env: Env) => ReturnType<NonNullable<ShardConfig["${r}"]>>): this {
1
+ import{A as k}from"./capabilities-CqnIsyA9.mjs";import{i as S}from"./ir-DBSvhNa-.mjs";import{G as E}from"./shared-DjUziztz.mjs";const g=e=>k.filter(({key:r})=>e.capabilities.has(r)),D=(e,r)=>{const t=new Set([...e].filter(a=>a!=="vectors"));return r&&t.add("vectors"),t},m=e=>g(e).length>0,R=e=>e?['import * as lunoraIdentityContract from "../identity.js";']:[],x=(e,r)=>e?['import type { CreateAccessResolverOptions } from "@lunora/cloudflare-access";',`import { createAccessResolver${r?", composeResolvers":""} } from "@lunora/cloudflare-access";`]:[],A=e=>e?['import { createKvIntrospectorFromEnv } from "@lunora/bindings/kv";']:[],C=e=>e?['import { createVectorAdminIntrospector } from "@lunora/bindings/vectors";']:[],O=e=>e?['import type { D1CtxDbOptions, D1DatabaseLike, D1Exec } from "@lunora/d1";','import { applyCdcChanges, createD1CtxDb, emitD1QueryCost, exportGlobalRows, facetGlobalColumn, importGlobalRows, listGlobalTables, readD1CdcChanges, readGlobalTablePage, retryingExec } from "@lunora/d1";']:[],T=e=>e?['import notifyConfig from "../notify.js";']:[],v=e=>(e.emailAgents?.length??0)>0,N=e=>v(e)?['import { dispatchAgentEmail } from "@lunora/agent/inbound";']:[],q=e=>v(e)?['import * as lunoraAgentDefinitions from "../agents.js";']:[],d=e=>e.tables.some(r=>S(r)),I=e=>{const{hasFramework:r,hasGlobal:t,hasHyperdriveGlobal:a,hasQueue:n,useUmbrella:o}=e,i=o?"lunorash/runtime":"@lunora/runtime",l=["ExecutionContextLike","HttpRouterLike","LunoraWorker","Route","ScheduledControllerLike","ShardNamespaceLike","WorkerOptions",...n?["TriggerTrace"]:[],...t?["GlobalIntrospector"]:[],...e.tables.length>0?["ShardingInfo"]:[],...r?["FrameworkHostHandler"]:[]],c=[...t||a?["createCrossShardRelationCapabilities"]:[],...d(e)?["createDynamicShardRegistry","createQueryCoordinator"]:[],"createWorker",...e.jurisdiction?["declareAppJurisdiction"]:[],"resolveLogArchiveFromEnv",...r?["withFrameworkWorker"]:[]].join(", ");return[`import type { ${[...l].toSorted((s,h)=>s.localeCompare(h)).join(", ")} } from "${i}";`,`import { ${c} } from "${i}";`]},L=e=>{const{hasAccess:r,hasAuth:t,hasGlobal:a,hasHyperdriveGlobal:n,hasKvIntrospector:o,hasQueue:i,hasScheduler:l,hasStorage:c,hasWorkflow:s,wantsOpenApi:h,wantsOpenRpc:u}=e;return[...t?['import type { AuthNamespaceLike, LunoraAuth, LunoraAuthOptions } from "@lunora/auth";','import { authDiscoveryPathsFor, createAuth, createAuthAdmin, createAuthAuditReader, createDoAuthWiring, d1Executor, ensureMigrated, handleAuthDiscoveryRequest, handleAuthRequest, lunoraD1Adapter } from "@lunora/auth";']:[],...x(r,t),...O(a),...n?['import type { HyperdriveEngine } from "@lunora/hyperdrive/global";','import { createHyperdriveGlobalCtxDb } from "@lunora/hyperdrive/global";','import type { SqlCtxDbOptions, SqlExec } from "@lunora/sql-store";']:[],...A(o),...C(e.hasVectors===!0),...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";']:[],...N(e),...I(e),"",...R(e.identity),...q(e),...a||n?['import schema from "../schema.js";']:[],...T(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===!0?['import { LUNORA_VECTOR_INDEXES } from "./vectors.js";']:[]]},j=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}']:[]],G=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>;"]:[],...m(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>;"]:[]],B=e=>g(e).map(({appMethod:{configKey:r,doc:t,method:a}})=>` /** ${t} */
2
+ public ${a}(factory: (env: Env) => ReturnType<NonNullable<ShardConfig["${r}"]>>): this {
3
3
  this.shardExtras.${r} = factory as NonNullable<ShardConfig["${r}"]>;
4
4
 
5
5
  return this;
6
- }`),B=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. */
6
+ }`),P=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. */
7
7
  public admin(selector: Selector<Env, string>): this {
8
8
  this.adminToken = selector;
9
9
 
@@ -62,8 +62,8 @@ import{A as w}from"./capabilities-DJJWVEtk.mjs";import{i as k}from"./ir-DBSvhNa-
62
62
  this.storageDeclaration = declaration;
63
63
 
64
64
  return this;
65
- }`]:[],...G(e)],P=e=>{const t=a=>e.hasScheduler?`
66
- ...(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 }),"," ...(this.relationExistsPushDownMode === undefined ? {} : { relationExistsPushDown: this.relationExistsPushDownMode }),",...e.hasGlobal?[` ...(this.globalDeclaration
65
+ }`]:[],...B(e)],W=e=>{const r=a=>e.hasScheduler?`
66
+ ...(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 }),"," ...(this.relationExistsPushDownMode === undefined ? {} : { relationExistsPushDown: this.relationExistsPushDownMode }),",...e.hasGlobal?[` ...(this.globalDeclaration
67
67
  ? {
68
68
  d1: (rawEnv: Record<string, unknown>, request?: { bookmark?: string; cdc?: boolean; cdcRetentionMs?: number; identity?: Record<string, unknown>; onBookmark?: (bookmark: string | undefined) => void; userId?: string | null }) => {
69
69
  const env = rawEnv as Env;
@@ -79,7 +79,7 @@ import{A as w}from"./capabilities-DJJWVEtk.mjs";import{i as k}from"./ir-DBSvhNa-
79
79
  : undefined;
80
80
 
81
81
  return createD1CtxDb({
82
- ...(crossShard ? { crossShardCounter: crossShard.crossShardCounter, crossShardReader: crossShard.crossShardReader } : {}),${t("D1CtxDbOptions")}
82
+ ...(crossShard ? { crossShardCounter: crossShard.crossShardCounter, crossShardReader: crossShard.crossShardReader } : {}),${r("D1CtxDbOptions")}
83
83
  ...(request?.cdcRetentionMs === undefined ? {} : { cdcRetentionMs: request.cdcRetentionMs }),
84
84
  auth: { identity: request?.identity ?? null, userId: request?.userId ?? null },
85
85
  // Forwarded from the shard's own \`cdc\` config, so ONE
@@ -113,7 +113,7 @@ import{A as w}from"./capabilities-DJJWVEtk.mjs";import{i as k}from"./ir-DBSvhNa-
113
113
  : undefined;
114
114
 
115
115
  return createHyperdriveGlobalCtxDb({
116
- ...(crossShard ? { crossShardCounter: crossShard.crossShardCounter, crossShardReader: crossShard.crossShardReader } : {}),${t("SqlCtxDbOptions")}
116
+ ...(crossShard ? { crossShardCounter: crossShard.crossShardCounter, crossShardReader: crossShard.crossShardReader } : {}),${r("SqlCtxDbOptions")}
117
117
  ...(request?.cdcRetentionMs === undefined ? {} : { cdcRetentionMs: request.cdcRetentionMs }),
118
118
  auth: { identity: request?.identity ?? null, userId: request?.userId ?? null },
119
119
  // See the D1 twin: one \`cdc\` switch, both changelogs.
@@ -134,13 +134,13 @@ import{A as w}from"./capabilities-DJJWVEtk.mjs";import{i as k}from"./ir-DBSvhNa-
134
134
  ? {
135
135
  scheduler: (rawEnv: Record<string, unknown>) => this.resolveScheduler(rawEnv as Env),
136
136
  }
137
- : {}),`]:[],...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) } : {}),"]:[],...m(e)?[" ...this.shardExtras,"]:[]];return r.length>0?`
138
- ${r.join(`
137
+ : {}),`]:[],...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) } : {}),"]:[],...m(e)?[" ...this.shardExtras,"]:[]];return t.length>0?`
138
+ ${t.join(`
139
139
  `)}
140
- `:""},W=e=>e.jurisdiction&&e.jurisdictionPinsAuth===!0?`
140
+ `:""},_=e=>e.jurisdiction&&e.jurisdictionPinsAuth===!0?`
141
141
  // The schema's jurisdiction pins the auth object like every other DO.
142
- jurisdiction: ${JSON.stringify(e.jurisdiction)},`:"",_=e=>typeof e=="string"?`{ mode: { kind: ${JSON.stringify(e)} } }`:`{ mode: { field: ${JSON.stringify(e.field)}, kind: "shardBy" } }`,$=e=>[...e.tables.length>0?[` const tableSharding = new Map<string, ShardingInfo>([
143
- ${e.tables.map(t=>` [${JSON.stringify(t.name)}, ${_(t.shardMode)}],`).join(`
142
+ jurisdiction: ${JSON.stringify(e.jurisdiction)},`:"",$=e=>typeof e=="string"?`{ mode: { kind: ${JSON.stringify(e)} } }`:`{ mode: { field: ${JSON.stringify(e.field)}, kind: "shardBy" } }`,H=e=>[...e.tables.length>0?[` const tableSharding = new Map<string, ShardingInfo>([
143
+ ${e.tables.map(r=>` [${JSON.stringify(r.name)}, ${$(r.shardMode)}],`).join(`
144
144
  `)}
145
145
  ]);
146
146
 
@@ -149,7 +149,7 @@ ${e.tables.map(t=>` [${JSON.stringify(t.name)}, ${_(t.shardMode)}],`)
149
149
 
150
150
  if (shardRegistry) {
151
151
  options.queryCoordinator = createQueryCoordinator({ registry: createDynamicShardRegistry({ ${e.jurisdiction?`jurisdiction: ${JSON.stringify(e.jurisdiction)}, `:""}namespace: shardRegistry }) });
152
- }`]:[]],H=e=>[...$(e),...e.hasScheduler?[` if (this.schedulerDeclaration) {
152
+ }`]:[]],U=e=>[...H(e),...e.hasScheduler?[` if (this.schedulerDeclaration) {
153
153
  options.schedulerDO = this.schedulerDeclaration.namespace(env);
154
154
  }`]:[],...e.hasWorkflow?[` options.workflowsClient = (workflowEnv) => {
155
155
  const source = workflowEnv as Record<string, unknown>;
@@ -211,12 +211,19 @@ ${e.tables.map(t=>` [${JSON.stringify(t.name)}, ${_(t.shardMode)}],`)
211
211
  // than more emitted code: request-path logic in generated output can only be
212
212
  // typechecked, never unit-tested.
213
213
  const authWiring = createDoAuthWiring({
214
- internalSecret: authDeclaration.internalSecret?.(env),${W(e)}
214
+ // The OAuth discovery documents (an \`mcp()\` resource's metadata, the
215
+ // issuer's) are derived here from the declared options, so the worker
216
+ // forwards only those exact paths and no other probe reaches the object.
217
+ // Memoised on the declaration: a framework-hosted worker rebuilds these
218
+ // options per request, and \`options(env)\` rebuilds every plugin.
219
+ discoveryPaths: authDiscoveryPathsFor(authDeclaration, env),
220
+ internalSecret: authDeclaration.internalSecret?.(env),${_(e)}
215
221
  namespace: authNamespace(env),
216
222
  objectName: authDeclaration.objectName?.(env),
217
223
  });
218
224
 
219
225
  options.authHandler = authWiring.authHandler;
226
+ options.authDiscoveryHandler = authWiring.discoveryHandler;
220
227
  options.resolveIdentity = authWiring.resolveIdentity;
221
228
  // The audit log lives in the object like every other auth table, so the feed
222
229
  // reads through it rather than querying D1.
@@ -234,6 +241,13 @@ ${e.tables.map(t=>` [${JSON.stringify(t.name)}, ${_(t.shardMode)}],`)
234
241
 
235
242
  return auth ? handleAuthRequest(auth, request) : Promise.resolve(undefined);
236
243
  };
244
+ // The OAuth discovery documents outside \`/api/auth\` (served only with an
245
+ // \`mcp()\` or \`oauthProvider()\` plugin, and only after the app's own routes).
246
+ options.authDiscoveryHandler = (request) => {
247
+ const auth = getAuth();
248
+
249
+ return auth ? handleAuthDiscoveryRequest(auth, request) : Promise.resolve(undefined);
250
+ };
237
251
  options.resolveIdentity = async (request) => {
238
252
  const auth = getAuth();
239
253
 
@@ -287,16 +301,16 @@ ${e.tables.map(t=>` [${JSON.stringify(t.name)}, ${_(t.shardMode)}],`)
287
301
  }`:` if (this.accessSelector) {
288
302
  options.resolveIdentity = createAccessResolver(this.accessSelector(env));
289
303
  }`]:[],...e.voiceAgents&&e.voiceAgents.length>0?[` options.voiceAgents = {
290
- ${e.voiceAgents.map(t=>` ${JSON.stringify(t.exportName)}: (env as Record<string, unknown>)[${JSON.stringify(t.bindingName)}] as ShardNamespaceLike,`).join(`
304
+ ${e.voiceAgents.map(r=>` ${JSON.stringify(r.exportName)}: (env as Record<string, unknown>)[${JSON.stringify(r.bindingName)}] as ShardNamespaceLike,`).join(`
291
305
  `)}
292
- };`]:[]],U=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): 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,"," }),"]:[]," ...(this.httpRouterApp ? { httpRouter: this.httpRouterApp } : {}),"," routes: this.routeMap,"," shardDO: this.shardSelector?.(env) ?? (undefined as unknown as ShardNamespaceLike),"],F=e=>e.hasScheduler?`
306
+ };`]:[]],F=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): 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,"," }),"]:[]," ...(this.httpRouterApp ? { httpRouter: this.httpRouterApp } : {}),"," routes: this.routeMap,"," shardDO: this.shardSelector?.(env) ?? (undefined as unknown as ShardNamespaceLike),"],M=e=>e.hasScheduler?`
293
307
  /** Resolve the \`SchedulerDO\`-backed scheduler for this env; \`undefined\` until the namespace is wired. */
294
308
  private resolveScheduler(env: Env): ReturnType<typeof createScheduler> | undefined {
295
309
  const namespace = this.schedulerDeclaration?.namespace(env);
296
310
 
297
311
  return namespace ? createScheduler({${e.jurisdiction?` jurisdiction: ${JSON.stringify(e.jurisdiction)},`:""} namespace }) : undefined;
298
312
  }
299
- `:"",M=e=>e?`
313
+ `:"",Q=e=>e?`
300
314
  /**
301
315
  * One bucket's \`Storage\`, signing under the name it is registered as.
302
316
  *
@@ -401,7 +415,7 @@ ${e.voiceAgents.map(t=>` ${JSON.stringify(t.exportName)}: (env as Rec
401
415
  storageUpload: (key: string, body: ArrayBuffer, opts?: { bucket?: string; contentType?: string; sha256?: string }) => pick(opts?.bucket).upload(key, body, opts),
402
416
  };
403
417
  }
404
- `:"",Q=e=>e?`
418
+ `:"",J=e=>e?`
405
419
  /**
406
420
  * 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\`).
407
421
  *
@@ -623,9 +637,9 @@ const buildGlobalCdcApplier =
623
637
 
624
638
  return request.changes.length;
625
639
  };
626
- `:"",K=e=>[...e.hasAuth?["AuthDeclaration"]:[],"ComposedApp",...e.hasGlobal?["GlobalDeclaration"]:[],"LunoraConfig",...e.hasScheduler?["SchedulerDeclaration"]:[],"Selector",...e.hasStorage?["StorageDeclaration"]:[]].toSorted((t,r)=>t.localeCompare(r)).join(", "),Y=e=>{const t={...e,hasVectors:(e.hasVectors??!0)&&(e.vectorIndexCount??0)>0},{hasAuth:r}=t,a=q(t),n=H(t),i=r?` let auth: LunoraAuth | null = null;
640
+ `:"",K=e=>[...e.hasAuth?["AuthDeclaration"]:[],"ComposedApp",...e.hasGlobal?["GlobalDeclaration"]:[],"LunoraConfig",...e.hasScheduler?["SchedulerDeclaration"]:[],"Selector",...e.hasStorage?["StorageDeclaration"]:[]].toSorted((r,t)=>r.localeCompare(t)).join(", "),X=e=>{const r=(e.hasVectors??!0)&&(e.vectorIndexCount??0)>0,t={...e,capabilities:D(e.capabilities,r),hasVectors:r},{hasAuth:a}=t,n=j(t),o=U(t),i=a?` let auth: LunoraAuth | null = null;
627
641
  let authInit: Promise<void> | null = null;
628
- `:"",o=r?`
642
+ `:"",l=a?`
629
643
  const initAuth = async (env: Env): Promise<void> => {
630
644
  if (!this.authDeclaration) {
631
645
  return;
@@ -674,17 +688,17 @@ const buildGlobalCdcApplier =
674
688
  authInit = null;
675
689
  throw error;
676
690
  }));
677
- `:"",l=r?`
678
- await ensureAuth(env);`:"",s=r?"() => auth":"() => null",c=r?"getAuth: () => LunoraAuth | null":"_getAuth: () => null",h=t.hasFramework?` const buildWorker = (env: Env): LunoraWorker =>
679
- host ? withFrameworkWorker(host, (hostEnv) => this.buildWorkerOptions(hostEnv as Env, ${s})) : createWorker(this.buildWorkerOptions(env, ${s}));`:` const buildWorker = (env: Env): LunoraWorker => createWorker(this.buildWorkerOptions(env, ${s}));`,u=t.hasFramework?"host?: FrameworkHostHandler":"",p=t.emailAgents??[],y=p.length>0?` composed.email = dispatchAgentEmail([
691
+ `:"",c=a?`
692
+ await ensureAuth(env);`:"",s=a?"() => auth":"() => null",h=a?"getAuth: () => LunoraAuth | null":"_getAuth: () => null",u=t.hasFramework?` const buildWorker = (env: Env): LunoraWorker =>
693
+ host ? withFrameworkWorker(host, (hostEnv) => this.buildWorkerOptions(hostEnv as Env, ${s})) : createWorker(this.buildWorkerOptions(env, ${s}));`:` const buildWorker = (env: Env): LunoraWorker => createWorker(this.buildWorkerOptions(env, ${s}));`,y=t.hasFramework?"host?: FrameworkHostHandler":"",p=t.emailAgents??[],f=p.length>0?` composed.email = dispatchAgentEmail([
680
694
  ${p.map(b=>` { agent: lunoraAgentDefinitions.${b.exportName}, className: ${JSON.stringify(b.className)} },`).join(`
681
695
  `)}
682
696
  ]);
683
697
 
684
- `:"",f=` /** Materialise the standalone Cloudflare worker + \`ShardDO\` class. */
698
+ `:"",w=` /** Materialise the standalone Cloudflare worker + \`ShardDO\` class. */
685
699
  public build(): ComposedApp {
686
700
  return this.assemble();
687
- }${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`${S}${L(t).join(`
701
+ }${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}${L(t).join(`
688
702
  `)}
689
703
 
690
704
  /** Read a value off the per-request \`env\`. Returns \`undefined\` to leave the capability unconfigured (its \`ctx.*\`/admin surface stays a clear-error stub). */
@@ -698,9 +712,9 @@ ${t.jurisdiction?`
698
712
  // \`@lunora/mail\` reads it to pin its shard RPC like every other DO path.
699
713
  declareAppJurisdiction(${JSON.stringify(t.jurisdiction)});
700
714
  `:""}
701
- ${a.join(`
715
+ ${n.join(`
702
716
 
703
- `)}${a.length>0?`
717
+ `)}${n.length>0?`
704
718
 
705
719
  `:""}/** The composed app: a Cloudflare module worker (\`fetch\` / \`scheduled\` / optional \`email\`) plus the \`ShardDO\` class binding. */
706
720
  interface ComposedApp extends LunoraWorker {
@@ -717,32 +731,32 @@ interface ComposedApp extends LunoraWorker {
717
731
  * first request so per-isolate singletons are built once.
718
732
  */
719
733
  class AppBuilder<Env extends object> {
720
- ${j(t).join(`
734
+ ${G(t).join(`
721
735
  `)}
722
736
 
723
737
  private emailHandler?: (env: Env) => (message: unknown, env: unknown, context: ExecutionContextLike) => Promise<void>;
724
738
 
725
- ${B(t).join(`
739
+ ${P(t).join(`
726
740
 
727
741
  `)}
728
742
 
729
- ${f}
743
+ ${w}
730
744
 
731
745
  /** Build the shard DO + compose the worker (standalone or framework-hosted), wrapping the lazy per-isolate singletons + auth init. */
732
- private assemble(${u}): ComposedApp {
733
- const ShardDO = createShardDO({${P(t)}});
746
+ private assemble(${y}): ComposedApp {
747
+ const ShardDO = createShardDO({${W(t)}});
734
748
 
735
749
  // Per-isolate singletons: the worker (and auth instance) are expensive to
736
750
  // build, so the first request constructs them and every later request on
737
751
  // the same isolate reuses them.
738
752
  let worker: LunoraWorker | null = null;
739
- ${i}${o}
740
- ${h}
753
+ ${i}${l}
754
+ ${u}
741
755
 
742
756
  const composed: ComposedApp = {
743
757
  ShardDO,
744
758
  fetch: async (request: Request, rawEnv: unknown, context: ExecutionContextLike): Promise<Response> => {
745
- const env = rawEnv as Env;${l}
759
+ const env = rawEnv as Env;${c}
746
760
  worker ??= buildWorker(env);
747
761
 
748
762
  return worker.fetch(request, rawEnv, context);
@@ -764,7 +778,7 @@ ${h}
764
778
  },`:""}
765
779
  };
766
780
 
767
- ${y} if (this.emailHandler) {
781
+ ${f} if (this.emailHandler) {
768
782
  const handler = this.emailHandler;
769
783
 
770
784
  composed.email = (message, rawEnv, context) => handler(rawEnv as Env)(message, rawEnv, context);
@@ -784,11 +798,11 @@ ${t.hasFramework?`
784
798
  `:""}
785
799
  return composed;
786
800
  }
787
- ${F(t)}${M(t.hasStorage)}
801
+ ${M(t)}${Q(t.hasStorage)}
788
802
  /** Fan the recorded declarations into the worker-side \`createWorker\` options. */
789
- private buildWorkerOptions(env: Env, ${c}): WorkerOptions {
803
+ private buildWorkerOptions(env: Env, ${h}): WorkerOptions {
790
804
  const options: WorkerOptions = {
791
- ${U(t).join(`
805
+ ${F(t).join(`
792
806
  `)}
793
807
  };
794
808
 
@@ -796,9 +810,9 @@ ${U(t).join(`
796
810
  options.adminToken = this.adminToken(env);
797
811
  }
798
812
 
799
- ${n.join(`
813
+ ${o.join(`
800
814
 
801
- `)}${n.length>0?`
815
+ `)}${o.length>0?`
802
816
 
803
817
  `:""} for (const fn of this.extendFns) {
804
818
  Object.assign(options, fn(env, { ...options }));
@@ -807,7 +821,7 @@ ${n.join(`
807
821
  return options;
808
822
  }
809
823
  }
810
- ${Q(t.hasGlobal)}
824
+ ${J(t.hasGlobal)}
811
825
  /**
812
826
  * Shape of the project's root \`lunora.config.*\`.
813
827
  *
@@ -843,4 +857,4 @@ const defineApp = <Env extends object>(): AppBuilder<Env> => new AppBuilder<Env>
843
857
 
844
858
  export { AppBuilder, defineApp };
845
859
  export type { ${K(t)} };
846
- `};export{Y as emitApp};
860
+ `};export{X as emitApp};
@@ -1,17 +1,17 @@
1
- import{relative as Ve,isAbsolute as Ge,sep as He}from"node:path";import{LunoraError as D}from"@lunora/errors";import{S as ze}from"./capabilities-DJJWVEtk.mjs";import{p as Ue}from"./ir-DBSvhNa-.mjs";import{a as h,G as Xe,u as Je,d as Ke}from"./shared-DjUziztz.mjs";const Ye=/\.([cm]?)tsx?$/u,Ze=(u,n=[])=>{const t=new Set;for(const a of u.tables)for(const s of Object.values(a.shape)){const d=Je(s);d.kind==="storage"&&typeof d.bucket=="string"&&d.bucket!==""&&t.add(d.bucket)}for(const a of n)a!==""&&a!=="default"&&t.add(a);return["default",...[...t].toSorted((a,s)=>a.localeCompare(s))]},st=({agents:u=[],containers:n=[],env:t,hasAccessFacade:a=!1,hasAi:s=!1,hasAnalytics:d=!1,hasBrowser:J=!1,hasVectors:K=!0,hasFlags:Y=!1,hasHyperdrive:Z=!1,hasImages:ee=!1,hasKv:te=!1,hasNotify:ae=!1,hasPayments:M=!1,hasPipelines:re=!1,hasR2sql:oe=!1,hasX402:S=!1,identity:l,queues:F=[],schema:W,generatedDirectory:Q="",services:b=[],storageRuleBuckets:ne=[],topics:E=[],useUmbrella:se=!1,workflows:j=[]}={})=>{const r=Ke(se),ie=Ze(W??{tables:[]},ne).map(e=>JSON.stringify(e)).join(" | "),de=s?`import type { LunoraAi } from "@lunora/ai";
2
- `:"",le=s?`
3
- readonly ai: LunoraAi;`:"",ce=M?`import type { LunoraPayment } from "@lunora/payment";
4
- `:"",ue=M?`
5
- readonly payments: LunoraPayment;`:"",pe=S?`import type { X402Pay } from "@lunora/x402/pay";
6
- `:"",ye=S?`
7
- readonly x402: X402Pay;`:"",P=e=>e.sandbox===!0?"SandboxContainerAccessor":"ContainerAccessor",me=[...new Set(n.map(e=>P(e)))].toSorted((e,o)=>e.localeCompare(o)),he=n.length>0?`import type { ${me.join(", ")} } from "@lunora/container";
8
- `:"",be=n.length>0?`
9
- readonly containers: {${n.map(e=>`
10
- readonly ${e.exportName}: ${P(e)};`).join("")}
11
- };`:"",L=[...s?[" /** Workers AI binding (the conventional `env.AI`), narrowing `ctx.ai`. */\n readonly AI?: unknown;"]:[],...n.map(e=>(h(e.bindingName,`container binding "${e.bindingName}"`),` /** Durable Object namespace for the \`${e.exportName}\` container. */
12
- readonly ${e.bindingName}?: unknown;`)),...F.map(e=>(h(e.bindingName,`queue binding "${e.bindingName}"`),` /** Queue producer binding for the \`${e.exportName}\` queue. */
1
+ import{relative as Ne,isAbsolute as Me,sep as Ae}from"node:path";import{LunoraError as z}from"@lunora/errors";import{C as De}from"./capabilities-CqnIsyA9.mjs";import{p as Se}from"./ir-DBSvhNa-.mjs";import{a as p,G as Fe,u as We,d as Qe}from"./shared-DjUziztz.mjs";const Pe=/\.([cm]?)tsx?$/u,je=(l,n=[])=>{const r=new Set;for(const t of l.tables)for(const d of Object.values(t.shape)){const s=We(d);s.kind==="storage"&&typeof s.bucket=="string"&&s.bucket!==""&&r.add(s.bucket)}for(const t of n)t!==""&&t!=="default"&&r.add(t);return["default",...[...r].toSorted((t,d)=>t.localeCompare(d))]},He=({agents:l=[],capabilities:n=new Set,containers:r=[],env:t,hasVectors:d=!0,hasFlags:s=!1,hasNotify:U=!1,identity:i,queues:O=[],schema:C,generatedDirectory:N="",services:y=[],storageRuleBuckets:X=[],topics:M=[],useUmbrella:J=!1,workflows:A=[]}={})=>{const o=Qe(J),m=n.has("ai"),D=n.has("payments"),S=n.has("x402"),K=je(C??{tables:[]},X).map(e=>JSON.stringify(e)).join(" | "),Y=m?`import type { LunoraAi } from "@lunora/ai";
2
+ `:"",Z=m?`
3
+ readonly ai: LunoraAi;`:"",ee=D?`import type { LunoraPayment } from "@lunora/payment";
4
+ `:"",te=D?`
5
+ readonly payments: LunoraPayment;`:"",ae=S?`import type { X402Pay } from "@lunora/x402/pay";
6
+ `:"",re=S?`
7
+ readonly x402: X402Pay;`:"",F=e=>e.sandbox===!0?"SandboxContainerAccessor":"ContainerAccessor",oe=[...new Set(r.map(e=>F(e)))].toSorted((e,a)=>e.localeCompare(a)),ne=r.length>0?`import type { ${oe.join(", ")} } from "@lunora/container";
8
+ `:"",se=r.length>0?`
9
+ readonly containers: {${r.map(e=>`
10
+ readonly ${e.exportName}: ${F(e)};`).join("")}
11
+ };`:"",W=[...m?[" /** Workers AI binding (the conventional `env.AI`), narrowing `ctx.ai`. */\n readonly AI?: unknown;"]:[],...r.map(e=>(p(e.bindingName,`container binding "${e.bindingName}"`),` /** Durable Object namespace for the \`${e.exportName}\` container. */
12
+ readonly ${e.bindingName}?: unknown;`)),...O.map(e=>(p(e.bindingName,`queue binding "${e.bindingName}"`),` /** Queue producer binding for the \`${e.exportName}\` queue. */
13
13
  readonly ${e.bindingName}?: unknown;`))].join(`
14
- `),fe=`
14
+ `),ie=`
15
15
 
16
16
  /**
17
17
  * This project's Cloudflare bindings, as far as codegen can discover them from
@@ -24,26 +24,24 @@ import{relative as Ve,isAbsolute as Ge,sep as He}from"node:path";import{LunoraEr
24
24
  * surface, so treat them as \`Fetcher\`/\`Service<unknown>\` and cast.
25
25
  */
26
26
  export interface CloudflareBindings {
27
- readonly [binding: string]: unknown;${L?`
28
- ${L}`:""}
27
+ readonly [binding: string]: unknown;${W?`
28
+ ${W}`:""}
29
29
  }
30
30
 
31
31
  /** Alias for {@link CloudflareBindings} — the typed shape of \`env\`. */
32
- export type Env = CloudflareBindings;`,i=(e,o,c)=>{const m=ze.get(e);if(m!==void 0&&m.tier!==c)throw new D("INTERNAL",`@lunora/codegen: capability "${e}" declares tier "${m.tier}" in SERVER_CTX_FIELDS but is emitted onto the "${c}" context — update whichever is wrong.`);return o?m?.field??"":""},f=i("kv",te,"every"),x=i("analytics",d,"every"),xe=i("hyperdrive",Z,"action"),ge=i("browser",J,"action"),Te=i("images",ee,"action"),ve=i("pipelines",re,"action"),we=i("r2sql",oe,"action"),p=K&&(W?.vectorIndexes.length??0)>0,g=p?' | "vectors"':"",q=p?`
33
- readonly vectors: VectorSearch<VectorIndexName>;`:"",$e=p?`
34
- readonly vectors: VectorSearchReader<VectorIndexName>;`:"",ke=p?`import type { VectorSearch, VectorSearchReader } from "${r.server}";
32
+ export type Env = CloudflareBindings;`,Q=e=>De.map(a=>a.serverCtxField!==void 0&&e.includes(a.tier)&&n.has(a.key)?a.serverCtxField:"").join(""),P=Q(["every"]),de=Q(["every","action"]),c=d&&(C?.vectorIndexes.length??0)>0,h=c?' | "vectors"':"",j=c?`
33
+ readonly vectors: VectorSearch<VectorIndexName>;`:"",le=c?`
34
+ readonly vectors: VectorSearchReader<VectorIndexName>;`:"",ce=c?`import type { VectorSearch, VectorSearchReader } from "${o.server}";
35
35
  import type { VectorIndexName } from "./dataModel.js";
36
- `:"",T=a?`
37
- /** Verified Cloudflare Access identity — a synchronous facade over the resolved claims (email / groups / hasGroup / claims). Anonymous when no Access token is present. */
38
- readonly access: import("@lunora/cloudflare-access/context").AccessFacade;`:"",v=Y?`
36
+ `:"",b=s?`
39
37
  /** Feature-flag evaluation (OpenFeature). Reads are memoized per request; evaluations never throw — a provider error resolves to the supplied default. */
40
- readonly flags: import("${r.flags}").LunoraFlags;`:"",w=ae?`
38
+ readonly flags: import("${o.flags}").LunoraFlags;`:"",f=U?`
41
39
  /** Multi-channel notifications (@lunora/notify): send / chat / inApp / webhook plus the push device sub-facade. Sends are external I/O — confine them to action handlers. */
42
40
  readonly notify: import("@lunora/notify").LunoraNotify;
43
41
  /** Device push sub-facade — the same object as ctx.notify.push (register / send / broadcast). Sends belong in action handlers. */
44
- readonly push: import("@lunora/notify").LunoraPush;`:"",y=j.length>0,Ie=y?`import type { WorkflowHandle } from "@lunora/workflow";
42
+ readonly push: import("@lunora/notify").LunoraPush;`:"",u=A.length>0,ue=u?`import type { WorkflowHandle } from "@lunora/workflow";
45
43
  import type * as lunoraWorkflowDefinitions from "../workflows.js";
46
- `:"",Re=y?`
44
+ `:"",pe=u?`
47
45
 
48
46
  /** Params type carried by a \`defineWorkflow\` definition (its phantom \`__params\`). */
49
47
  type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params }
@@ -54,56 +52,56 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
54
52
 
55
53
  /** This project's declared workflows, addressable from \`ctx.workflows\` by their \`lunora/workflows.ts\` export name. */
56
54
  export interface LunoraWorkflows {
57
- ${j.map(e=>` get(name: ${JSON.stringify(e.exportName)}): WorkflowHandle<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${e.exportName}>>;`).join(`
55
+ ${A.map(e=>` get(name: ${JSON.stringify(e.exportName)}): WorkflowHandle<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${e.exportName}>>;`).join(`
58
56
  `)}
59
- }`:"",_=y?' | "workflows"':"",V=y?`
60
- readonly workflows: LunoraWorkflows;`:"",G=Ue(F),$=G.length>0,k=E.length>0,I=[...$?["QueueProducer"]:[],...k?["TopicPublisher"]:[]],Be=I.length>0?`import type { ${I.join(", ")} } from "@lunora/queue";
57
+ }`:"",E=u?' | "workflows"':"",L=u?`
58
+ readonly workflows: LunoraWorkflows;`:"",q=Se(O),x=q.length>0,g=M.length>0,T=[...x?["QueueProducer"]:[],...g?["TopicPublisher"]:[]],ye=T.length>0?`import type { ${T.join(", ")} } from "@lunora/queue";
61
59
  import type * as lunoraQueueDefinitions from "../queues.js";
62
- `:"",Oe=I.length>0?"\n\n/** Message body type carried by a `defineQueue` / `defineTopic` definition (its phantom `__lunoraBody`). */\ntype QueueBodyOf<Definition> = Definition extends { __lunoraBody?: infer Body } ? (unknown extends Body ? unknown : NonNullable<Body>) : unknown;":"",Ae=$?`
60
+ `:"",me=T.length>0?"\n\n/** Message body type carried by a `defineQueue` / `defineTopic` definition (its phantom `__lunoraBody`). */\ntype QueueBodyOf<Definition> = Definition extends { __lunoraBody?: infer Body } ? (unknown extends Body ? unknown : NonNullable<Body>) : unknown;":"",he=x?`
63
61
 
64
62
  /** This project's declared queues, addressable from \`ctx.queues\` by their \`lunora/queues.ts\` export name. */
65
63
  export interface LunoraQueues {
66
- ${G.map(e=>` readonly ${e.exportName}: QueueProducer<QueueBodyOf<typeof lunoraQueueDefinitions.${e.exportName}>>;`).join(`
64
+ ${q.map(e=>` readonly ${e.exportName}: QueueProducer<QueueBodyOf<typeof lunoraQueueDefinitions.${e.exportName}>>;`).join(`
67
65
  `)}
68
- }`:"",Ne=k?`
66
+ }`:"",be=g?`
69
67
 
70
68
  /** This project's declared topics, addressable from \`ctx.topics\` by their \`lunora/queues.ts\` export name. */
71
69
  export interface LunoraTopics {
72
- ${E.map(e=>` readonly ${e.exportName}: TopicPublisher<QueueBodyOf<typeof lunoraQueueDefinitions.${e.exportName}>>;`).join(`
70
+ ${M.map(e=>` readonly ${e.exportName}: TopicPublisher<QueueBodyOf<typeof lunoraQueueDefinitions.${e.exportName}>>;`).join(`
73
71
  `)}
74
- }`:"",Ce=`${Oe}${Ae}${Ne}`,H=$?`
75
- readonly queues: LunoraQueues;`:"",z=k?`
76
- readonly topics: LunoraTopics;`:"",R=b.length>0,De=e=>{if(Q==="")throw new D("INTERNAL","@lunora/codegen: emitServer needs `generatedDirectory` to import an RPC service's types");const o=Ve(Q,e);if(Ge(o))throw new D("INTERNAL",`@lunora/codegen: an RPC service's entry (${e}) must be on the same drive as the app`);const c=o.split(He).join("/").replace(Ye,".$1js");return c.startsWith(".")?c:`./${c}`},U=b.filter(e=>e.rpcEntrypoint!==void 0),Me=U.length>0?"ServiceFetcher, ServiceRpc":"ServiceFetcher",Se=R?`import type { ${Me} } from "${r.server}";
77
- ${U.map(e=>`import type * as lunoraService_${e.name} from ${JSON.stringify(De(e.main))};
78
- `).join("")}`:"",Fe=R?`
72
+ }`:"",fe=`${me}${he}${be}`,G=x?`
73
+ readonly queues: LunoraQueues;`:"",V=g?`
74
+ readonly topics: LunoraTopics;`:"",v=y.length>0,xe=e=>{if(N==="")throw new z("INTERNAL","@lunora/codegen: emitServer needs `generatedDirectory` to import an RPC service's types");const a=Ne(N,e);if(Me(a))throw new z("INTERNAL",`@lunora/codegen: an RPC service's entry (${e}) must be on the same drive as the app`);const R=a.split(Ae).join("/").replace(Pe,".$1js");return R.startsWith(".")?R:`./${R}`},_=y.filter(e=>e.rpcEntrypoint!==void 0),ge=_.length>0?"ServiceFetcher, ServiceRpc":"ServiceFetcher",Te=v?`import type { ${ge} } from "${o.server}";
75
+ ${_.map(e=>`import type * as lunoraService_${e.name} from ${JSON.stringify(xe(e.main))};
76
+ `).join("")}`:"",ve=v?`
79
77
 
80
78
  /** This project's service bindings (\`lunora.config\` \`services\`), addressable from \`ctx.services\` in actions. */
81
79
  export interface LunoraServices {
82
- ${b.map(e=>{h(e.name,`service "${e.name}"`);const o=e.rpcEntrypoint===void 0?"ServiceFetcher":`ServiceRpc<typeof lunoraService_${e.name}.${e.rpcEntrypoint}>`;return` readonly ${e.name}: ${o};`}).join(`
80
+ ${y.map(e=>{p(e.name,`service "${e.name}"`);const a=e.rpcEntrypoint===void 0?"ServiceFetcher":`ServiceRpc<typeof lunoraService_${e.name}.${e.rpcEntrypoint}>`;return` readonly ${e.name}: ${a};`}).join(`
83
81
  `)}
84
- }`:"",We=R?`
85
- readonly services: LunoraServices;`:"",B=u.length>0,Qe=B?`import type { AgentHandle } from "@lunora/agent";
86
- `:"",Ee=B?`
82
+ }`:"",ke=v?`
83
+ readonly services: LunoraServices;`:"",k=l.length>0,we=k?`import type { AgentHandle } from "@lunora/agent";
84
+ `:"",Ie=k?`
87
85
 
88
86
  /** This project's declared agents, addressable from \`ctx.agents\` by their \`lunora/agents.ts\` export name. */
89
87
  export interface LunoraAgents {
90
- ${u.map(e=>(h(e.exportName,`agent export "${e.exportName}"`),` readonly ${e.exportName}: AgentHandle;`)).join(`
88
+ ${l.map(e=>(p(e.exportName,`agent export "${e.exportName}"`),` readonly ${e.exportName}: AgentHandle;`)).join(`
91
89
  `)}
92
- }`:"",X=B?`
93
- readonly agents: LunoraAgents;`:"",je=l?`import type { InferIdentity } from "${r.server}";
90
+ }`:"",H=k?`
91
+ readonly agents: LunoraAgents;`:"",$e=i?`import type { InferIdentity } from "${o.server}";
94
92
  import type * as lunoraIdentityContract from "../identity.js";
95
- `:"",Pe=l?`
93
+ `:"",Be=i?`
96
94
 
97
95
  /** This app's declared identity claim contract (\`defineIdentity\` in \`lunora/identity.ts\`) — the typed shape of \`ctx.auth.getIdentity()\`, the RLS policy \`ctx.auth.identity\`, and the \`authorizeShard\`/\`authorizeFanOut\` identity argument. */
98
- export type Identity = InferIdentity<typeof lunoraIdentityContract.${l.exportName}>;
96
+ export type Identity = InferIdentity<typeof lunoraIdentityContract.${i.exportName}>;
99
97
 
100
98
  /** \`ctx.auth\` narrowed so \`getIdentity()\` resolves the declared {@link Identity} contract instead of the untyped claim bag. */
101
- type NarrowedAuth = Omit<QueryCtxBase["auth"], "getIdentity"> & { getIdentity: () => Promise<Identity | null> };`:"",O=l?' | "auth"':"",A=l?`
102
- readonly auth: NarrowedAuth;`:"",Le=l?", Identity":"",qe=t?`import type * as lunoraEnvContract from "../env.js";
103
- `:"",_e=t?`
99
+ type NarrowedAuth = Omit<QueryCtxBase["auth"], "getIdentity"> & { getIdentity: () => Promise<Identity | null> };`:"",w=i?' | "auth"':"",I=i?`
100
+ readonly auth: NarrowedAuth;`:"",Re=i?", Identity":"",Oe=t?`import type * as lunoraEnvContract from "../env.js";
101
+ `:"",Ce=t?`
104
102
 
105
103
  /** This app's declared env contract (\`defineEnv\` in \`lunora/env.ts\`) — the validated, coercion-aware shape of \`ctx.env\`. */
106
- export type LunoraEnv = ReturnType<typeof lunoraEnvContract.${t.exportName}>;`:"",N=t?' | "env"':"",C=t?"\n /** Validated, typed environment declared by `defineEnv` in `lunora/env.ts` — parsed & coercion-aware config values (`ctx.env.STRIPE_KEY`); a missing or invalid value throws at read time. */\n readonly env: LunoraEnv;":"";return`${Xe}import { createPolicyDsl, defineMutator as defineMutatorBase, initLunora, v as vBase } from "${r.server}";
104
+ export type LunoraEnv = ReturnType<typeof lunoraEnvContract.${t.exportName}>;`:"",$=t?' | "env"':"",B=t?"\n /** Validated, typed environment declared by `defineEnv` in `lunora/env.ts` — parsed & coercion-aware config values (`ctx.env.STRIPE_KEY`); a missing or invalid value throws at read time. */\n readonly env: LunoraEnv;":"";return`${Fe}import { createPolicyDsl, defineMutator as defineMutatorBase, initLunora, v as vBase } from "${o.server}";
107
105
  import type {
108
106
  ActionBuilder,
109
107
  ActionCtx as ActionCtxBase,
@@ -125,7 +123,7 @@ import type {
125
123
  Storage as StorageBase,
126
124
  TableReader,
127
125
  Validator,
128
- } from "${r.server}";
126
+ } from "${o.server}";
129
127
 
130
128
  import type {
131
129
  DatabaseReaderFacade as DatabaseReaderFacadeOf,
@@ -134,7 +132,7 @@ import type {
134
132
  TableReaderFacade as TableReaderFacadeOf,
135
133
  TableWriterFacade as TableWriterFacadeOf,
136
134
  WithArg as WithArgOf,
137
- } from "${r.serverDataModel}";
135
+ } from "${o.serverDataModel}";
138
136
 
139
137
  export type {
140
138
  AggregateOp,
@@ -157,10 +155,10 @@ export type {
157
155
  Where,
158
156
  WhereOf,
159
157
  WhereOperators,
160
- } from "${r.serverDataModel}";
158
+ } from "${o.serverDataModel}";
161
159
 
162
160
  import type { DataModel, Doc, GeoIndexNamesByTable, Id as IdOfTable, IndexNamesByTable, Insert, InsertModel, RankIndexNamesByTable, Relations, SearchIndexNamesByTable, TableName } from "./dataModel.js";
163
- ${ke}${de}${ce}${pe}${he}${Ie}${Be}${Se}${Qe}${je}${qe}
161
+ ${ce}${Y}${ee}${ae}${ne}${ue}${ye}${Te}${we}${$e}${Oe}
164
162
  export type { AppTableName, DataModel, Doc, Id, TableName } from "./dataModel.js";
165
163
 
166
164
  /**
@@ -220,7 +218,7 @@ export interface OrmWriter extends OrmReader {
220
218
  }
221
219
 
222
220
  /** Storage buckets this schema declares (\`v.storage("name")\`), narrowing \`ctx.storage.bucket(name)\`. */
223
- export type StorageBucketName = ${ie};${fe}${Re}${Ce}${Fe}${Ee}${Pe}${_e}
221
+ export type StorageBucketName = ${K};${ie}${pe}${fe}${ve}${Ie}${Be}${Ce}
224
222
 
225
223
  /**
226
224
  * Project-typed contexts. The base contexts from \`@lunora/server\` are
@@ -283,22 +281,22 @@ type AsIdTable<T extends string> = T extends TableName ? T : string extends T ?
283
281
  */
284
282
  type TypedAsId = <T extends string>(tableName: AsIdTable<T>, id: string) => IdOfTable<T & TableName>;
285
283
 
286
- export interface QueryCtx extends Omit<QueryCtxBase, "db" | "storage"${g}${O}${N}> {
284
+ export interface QueryCtx extends Omit<QueryCtxBase, "db" | "storage"${h}${w}${$}> {
287
285
  readonly db: Omit<DatabaseReader, "asId" | "query" | "get"> & DatabaseReaderFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
288
286
  readonly orm: OrmReader;
289
- readonly storage: ReadOnlyStorage<StorageBucketName>;${$e}${T}${f}${v}${w}${x}${C}${A}
287
+ readonly storage: ReadOnlyStorage<StorageBucketName>;${le}${P}${b}${f}${B}${I}
290
288
  }
291
289
 
292
- export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${g}${_}${O}${N}> {
290
+ export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${h}${E}${w}${$}> {
293
291
  readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
294
292
  readonly orm: OrmWriter;
295
- readonly storage: MutationStorage<StorageBucketName>;${q}${T}${f}${v}${w}${x}${C}${V}${H}${z}${X}${A}
293
+ readonly storage: MutationStorage<StorageBucketName>;${j}${P}${b}${f}${B}${L}${G}${V}${H}${I}
296
294
  }
297
295
 
298
- export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${g}${_}${O}${N}> {
296
+ export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${h}${E}${w}${$}> {
299
297
  readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
300
298
  readonly orm: OrmWriter;
301
- readonly storage: StorageBase<StorageBucketName>;${q}${T}${le}${ue}${ye}${be}${f}${v}${w}${xe}${ge}${Te}${x}${ve}${we}${We}${C}${V}${H}${z}${X}${A}
299
+ readonly storage: StorageBase<StorageBucketName>;${j}${de}${Z}${te}${re}${se}${b}${f}${ke}${B}${L}${G}${V}${H}${I}
302
300
  }
303
301
 
304
302
  /**
@@ -331,7 +329,7 @@ export const internalAction = lunoraBuilders.internalAction as unknown as Intern
331
329
  /**
332
330
  * \`defineMutator\` bound to this project's typed {@link MutationCtx} — declare
333
331
  * custom mutators (\`lunora/mutators.ts\`) with it instead of importing from
334
- * \`${r.server}\`, and the authoritative \`server\` impl's \`ctx\` carries the
332
+ * \`${o.server}\`, and the authoritative \`server\` impl's \`ctx\` carries the
335
333
  * schema-typed \`ctx.db\` (\`ctx.db.query("nodes")\` resolves \`Doc<"nodes">\`,
336
334
  * \`ctx.db.patch(id, …)\` takes an \`Id<"nodes">\`) with no hand-written ctx type and
337
335
  * no \`as unknown as\` cast. Runtime-identical to the package export; only the
@@ -356,7 +354,7 @@ export const defineMutator = defineMutatorBase as unknown as <Args extends Recor
356
354
  * Runtime-identical to \`@lunora/server\`'s \`definePolicy\`; only the types narrow,
357
355
  * so the \`rls()\` chain discovers a policy authored either way the same.
358
356
  */
359
- export const definePolicy = createPolicyDsl<DataModel, Relations${Le}>();
357
+ export const definePolicy = createPolicyDsl<DataModel, Relations${Re}>();
360
358
 
361
359
  /**
362
360
  * The validator builder \`v\`, with \`v.id(...)\` constrained to THIS schema's
@@ -373,4 +371,4 @@ export const definePolicy = createPolicyDsl<DataModel, Relations${Le}>();
373
371
  export const v = vBase as unknown as Omit<typeof vBase, "id"> & {
374
372
  id: <T extends TableName>(table: T) => ColumnValidator<IdOfTable<T>, IdOfTable<T>>;
375
373
  };
376
- `};export{st as default};
374
+ `};export{He as default};
@@ -1 +1 @@
1
- import"./SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs";import"./isD1GlobalTable-udvHAAzD.mjs";import"./ir-DBSvhNa-.mjs";import"./json-data-Chfs2Cz5.mjs";import{e as f}from"./shard-C0OSxk7u.mjs";import"./shard-runtime-DvqfDuYO.mjs";import"./shared-DjUziztz.mjs";export{f as default};
1
+ import"./SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs";import"./isD1GlobalTable-udvHAAzD.mjs";import"./ir-DBSvhNa-.mjs";import"./json-data-Chfs2Cz5.mjs";import{e as f}from"./shard-f7coQFS9.mjs";import"./shard-runtime-CyEbIjPA.mjs";import"./shared-DjUziztz.mjs";export{f as default};