@lunora/codegen 1.0.0-alpha.336 → 1.0.0-alpha.338

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -93,6 +93,12 @@ interface FieldSnapshot {
93
93
  nullable?: boolean;
94
94
  /** `v.array(inner)` element / `v.record(…, value)` value shape. */
95
95
  of?: FieldSnapshot;
96
+ /**
97
+ * `v.from(schema)` — the wrapped schema's inferred OUTPUT type as TS source, the
98
+ * type the column is stored and read as. Absent when it could not be resolved,
99
+ * and on baselines written before it was recorded; see {@link comparableFromOutput}.
100
+ */
101
+ output?: string;
96
102
  /** True when declared `v.optional(...)` — accepts `undefined` / absent on insert. */
97
103
  optional: boolean;
98
104
  /** `v.id("table")` — the referenced table. */
package/dist/index.d.ts CHANGED
@@ -93,6 +93,12 @@ interface FieldSnapshot {
93
93
  nullable?: boolean;
94
94
  /** `v.array(inner)` element / `v.record(…, value)` value shape. */
95
95
  of?: FieldSnapshot;
96
+ /**
97
+ * `v.from(schema)` — the wrapped schema's inferred OUTPUT type as TS source, the
98
+ * type the column is stored and read as. Absent when it could not be resolved,
99
+ * and on baselines written before it was recorded; see {@link comparableFromOutput}.
100
+ */
101
+ output?: string;
96
102
  /** True when declared `v.optional(...)` — accepts `undefined` / absent on insert. */
97
103
  optional: boolean;
98
104
  /** `v.id("table")` — the referenced table. */
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{SCHEMA_SNAPSHOT_VERSION as t,diffSchemaSnapshots as a,serializeSchemaSnapshot as s}from"./packem_shared/SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs";import{formatAdvisories as f,lintSchema as m,toAdvisorContext as d}from"./packem_shared/formatAdvisories-BCVASH7N.mjs";import{describeErrorLevelFindings as n,errorAdvisoryNames as l,errorPlatformDiagnosticNames as c,sortedUniqueNames as x}from"./packem_shared/describeErrorLevelFindings-vzaGS9KL.mjs";import{CAPABILITY_PROBES as E}from"./packem_shared/CAPABILITY_PROBES-brcmKenl.mjs";import{CodegenDiagnosticError as A,diagnosticAt as v}from"./packem_shared/CodegenDiagnosticError-BUXlG3P-.mjs";import{AGENTS_FILENAME as g,discoverAgents as N}from"./packem_shared/AGENTS_FILENAME-isdHqPIt.mjs";import{isTestPath as R,listLunoraSourceFiles as h}from"./packem_shared/isTestPath-C3QumE88.mjs";import{default as I}from"./packem_shared/discoverAuthApiCalls-CScPrUD-.mjs";import{CONTAINERS_FILENAME as L,discoverContainers as M}from"./packem_shared/CONTAINERS_FILENAME-mK4cZpcz.mjs";import{default as P}from"./packem_shared/discoverCrons-B1_NUt19.mjs";import{capabilitiesUsedBy as b,foldCapabilitySignals as y,mayReadCapabilityContext as U,sourceCapabilitySignals as G}from"./packem_shared/capabilitiesUsedBy-C-7D7vlH.mjs";import{FLAGS_FILENAME as j,discoverFlags as B}from"./packem_shared/FLAGS_FILENAME-BQk3SX8D.mjs";import{default as W}from"./packem_shared/discoverFunctions-DkPOc8b9.mjs";import{default as V}from"./packem_shared/discoverHttpRoutes-DCDgDIYv.mjs";import{default as Q}from"./packem_shared/discoverHyperdriveCalls-CL-d0IVo.mjs";import{default as w}from"./packem_shared/discoverInserts-BcoTjXqI.mjs";import{d as Y}from"./packem_shared/index-CN8FVvr-.mjs";import{default as Z}from"./packem_shared/discoverMigrations-BWxx8Wv9.mjs";import{MUTATORS_FILENAME as ee,discoverMutators as re}from"./packem_shared/MUTATORS_FILENAME-Cy9h3EVW.mjs";import{default as te}from"./packem_shared/discoverNondeterministicCalls-3INW8oqs.mjs";import{NOTIFY_FILENAME as se,discoverNotifyCalls as ie,discoverNotifyChannels as fe,discoverNotifyConfig as me}from"./packem_shared/NOTIFY_FILENAME-9to_l_Kh.mjs";import{default as pe}from"./packem_shared/readPackageDependencies-RHhGiz0k.mjs";import{default as le}from"./packem_shared/discoverQueries-CxQRVuIV.mjs";import{QUEUES_FILENAME as xe,discoverQueues as Se}from"./packem_shared/QUEUES_FILENAME-Civ-7SiI.mjs";import{default as ue}from"./packem_shared/discoverR2sqlCalls-B4oeTYEM.mjs";import{default as ve}from"./packem_shared/discoverRlsProcedures-Cl6UKT7L.mjs";import{default as ge}from"./packem_shared/discoverRlsMetadata-D0B4nCmG.mjs";import{discoverSandboxUsage as Oe}from"./packem_shared/discoverSandboxUsage--Z1vx7GM.mjs";import{default as he}from"./packem_shared/discoverSchema-Cwt-DQgh.mjs";import{readServiceBindings as Ie,resolveServiceBindings as _e}from"./packem_shared/readServiceBindings-BA49C6aN.mjs";import{SHAPES_FILENAME as Me,discoverShapes as Fe}from"./packem_shared/SHAPES_FILENAME-DVJbfDZ8.mjs";import{default as De}from"./packem_shared/discoverStorageRulesMetadata-CitX6ziW.mjs";import{WORKFLOWS_FILENAME as ye,discoverWorkflows as Ue}from"./packem_shared/WORKFLOWS_FILENAME-kXq07aGl.mjs";import{emitApp as He}from"./packem_shared/emitApp-BL16wvE9.mjs";import{isD1GlobalTable as Be,isHyperdriveGlobalTable as ke}from"./packem_shared/isD1GlobalTable-udvHAAzD.mjs";import{buildOpenApiDocument as Ke,emitOpenApi as Ve,emitOpenApiModule as ze}from"./packem_shared/buildOpenApiDocument-DWdj2jvW.mjs";import{OPENRPC_VERSION as qe,buildOpenRpcDocument as we,emitOpenRpc as Je,emitOpenRpcModule as Ye}from"./packem_shared/OPENRPC_VERSION-l4HD4osw.mjs";import{DEFAULT_TARGET as Ze,platformMatrixIds as $e,readProjectTarget as er,resolveCodegenTarget as rr}from"./packem_shared/DEFAULT_TARGET-3OLdJhTj.mjs";import{loadProjectConfig as tr,readProjectConfigLiterals as ar}from"./packem_shared/loadProjectConfig-B7RmxIeD.mjs";import{PROJECT_CONFIG_FILENAMES as ir,findCodegenConfigFile as fr,findProjectConfigFile as mr,projectConfigCandidatePaths as dr}from"./packem_shared/PROJECT_CONFIG_FILENAMES-CLfsyvjA.mjs";import{SCHEMA_SNAPSHOT_FILENAME as nr,runCodegen as lr}from"./packem_shared/SCHEMA_SNAPSHOT_FILENAME-DcWyFDv9.mjs";import{SchemaSnapshotParseError as xr,buildSchemaSnapshot as Sr,evaluateSchemaDrift as Er,parseSchemaSnapshot as ur}from"./packem_shared/SchemaSnapshotParseError-BRJT7c2k.mjs";import{default as vr}from"./packem_shared/fingerprintSchemaSources-BKXkgkj4.mjs";import{schemaFromIr as gr}from"./packem_shared/schemaFromIr-BWFnvCVg.mjs";import{LUNORA_ERROR_CODES as Or,validatorIrToJsonSchema as Rr}from"./packem_shared/LUNORA_ERROR_CODES-CIAJQeKB.mjs";import{SDK_LANGUAGES as Tr,SDK_TARGETS as Ir,generateSdk as _r}from"./sdk/index.mjs";import{redact as Mr,secretKindOf as Fr}from"./packem_shared/redact-Cy14LEnc.mjs";import{default as Dr}from"./packem_shared/emitDrizzleSchema-bct1OuH5.mjs";import{e as yr}from"./packem_shared/server-B6VhYK7m.mjs";import{e as Gr}from"./packem_shared/shard-B6afe1Uh.mjs";import{G as jr}from"./packem_shared/shared-8vTRkL2-.mjs";import{MESSAGE_SOLUTIONS as kr,findSolutionByMessage as Wr}from"@lunora/errors";import{createCodegenProject as Vr,findTsconfig as zr,refreshCodegenProject as Qr}from"./packem_shared/createCodegenProject-R4so-yTU.mjs";import{s as wr,t as Jr,u as Yr}from"./packem_shared/shard-runtime-BW1kffN4.mjs";import{emitApi as Zr,emitCollections as $r,emitInternalApi as eo}from"./packem_shared/emitApi-c14__tie.mjs";import{emitCrons as oo,emitScheduler as to,emitVectors as ao,emitWranglerCronTriggers as so}from"./packem_shared/emitCrons-lc-hnJYn.mjs";import{emitDataModel as fo}from"./packem_shared/emitDataModel-CuFqq97x.mjs";import{emitFunctions as po}from"./packem_shared/emitFunctions-CkBPtGDF.mjs";import{isTypedSchema as lo}from"./packem_shared/isTypedSchema-CKzc3ioR.mjs";const e="0.0.0";export{g as AGENTS_FILENAME,E as CAPABILITY_PROBES,L as CONTAINERS_FILENAME,A as CodegenDiagnosticError,Ze as DEFAULT_TARGET,j as FLAGS_FILENAME,jr as GENERATED_HEADER,Or as LUNORA_ERROR_CODES,kr as LUNORA_SOLUTION_RULES,ee as MUTATORS_FILENAME,se as NOTIFY_FILENAME,qe as OPENRPC_VERSION,ir as PROJECT_CONFIG_FILENAMES,xe as QUEUES_FILENAME,nr as SCHEMA_SNAPSHOT_FILENAME,t as SCHEMA_SNAPSHOT_VERSION,Tr as SDK_LANGUAGES,Ir as SDK_TARGETS,Me as SHAPES_FILENAME,xr as SchemaSnapshotParseError,e as VERSION,ye as WORKFLOWS_FILENAME,Ke as buildOpenApiDocument,we as buildOpenRpcDocument,Sr as buildSchemaSnapshot,b as capabilitiesUsedBy,Vr as createCodegenProject,n as describeErrorLevelFindings,v as diagnosticAt,a as diffSchemaSnapshots,N as discoverAgents,I as discoverAuthApiCalls,M as discoverContainers,P as discoverCrons,B as discoverFlags,W as discoverFunctions,V as discoverHttpRoutes,Q as discoverHyperdriveCalls,w as discoverInserts,Y as discoverMaskProcedures,Z as discoverMigrations,re as discoverMutators,te as discoverNondeterministicCalls,ie as discoverNotifyCalls,fe as discoverNotifyChannels,me as discoverNotifyConfig,le as discoverQueries,Se as discoverQueues,ue as discoverR2sqlCalls,ge as discoverRlsMetadata,ve as discoverRlsProcedures,Oe as discoverSandboxUsage,he as discoverSchema,Fe as discoverShapes,De as discoverStorageRulesMetadata,Ue as discoverWorkflows,wr as emitAgents,Zr as emitApi,He as emitApp,$r as emitCollections,Jr as emitContainers,oo as emitCrons,fo as emitDataModel,Dr as emitDrizzleSchema,po as emitFunctions,eo as emitInternalApi,Ve as emitOpenApi,ze as emitOpenApiModule,Je as emitOpenRpc,Ye as emitOpenRpcModule,to as emitScheduler,yr as emitServer,Gr as emitShard,ao as emitVectors,Yr as emitWorkflows,so as emitWranglerCronTriggers,l as errorAdvisoryNames,c as errorPlatformDiagnosticNames,Er as evaluateSchemaDrift,fr as findCodegenConfigFile,Wr as findLunoraSolution,mr as findProjectConfigFile,zr as findTsconfig,vr as fingerprintSchemaSources,y as foldCapabilitySignals,f as formatAdvisories,_r as generateSdk,Be as isD1GlobalTable,ke as isHyperdriveGlobalTable,R as isTestPath,lo as isTypedSchema,m as lintSchema,h as listLunoraSourceFiles,tr as loadProjectConfig,U as mayReadCapabilityContext,ur as parseSchemaSnapshot,$e as platformMatrixIds,dr as projectConfigCandidatePaths,pe as readPackageDependencies,ar as readProjectConfigLiterals,er as readProjectTarget,Ie as readServiceBindings,Mr as redact,Qr as refreshCodegenProject,rr as resolveCodegenTarget,_e as resolveServiceBindings,lr as runCodegen,gr as schemaFromIr,Fr as secretKindOf,s as serializeSchemaSnapshot,x as sortedUniqueNames,G as sourceCapabilitySignals,d as toAdvisorContext,Rr as validatorIrToJsonSchema};
1
+ import{SCHEMA_SNAPSHOT_VERSION as t,diffSchemaSnapshots as a,serializeSchemaSnapshot as s}from"./packem_shared/SCHEMA_SNAPSHOT_VERSION-C7Um0EnM.mjs";import{formatAdvisories as f,lintSchema as m,toAdvisorContext as d}from"./packem_shared/formatAdvisories-BCVASH7N.mjs";import{describeErrorLevelFindings as n,errorAdvisoryNames as l,errorPlatformDiagnosticNames as c,sortedUniqueNames as x}from"./packem_shared/describeErrorLevelFindings-vzaGS9KL.mjs";import{CAPABILITY_PROBES as E}from"./packem_shared/CAPABILITY_PROBES-brcmKenl.mjs";import{CodegenDiagnosticError as A,diagnosticAt as v}from"./packem_shared/CodegenDiagnosticError-BUXlG3P-.mjs";import{AGENTS_FILENAME as g,discoverAgents as N}from"./packem_shared/AGENTS_FILENAME-isdHqPIt.mjs";import{isTestPath as R,listLunoraSourceFiles as h}from"./packem_shared/isTestPath-C3QumE88.mjs";import{default as I}from"./packem_shared/discoverAuthApiCalls-CScPrUD-.mjs";import{CONTAINERS_FILENAME as L,discoverContainers as M}from"./packem_shared/CONTAINERS_FILENAME-mK4cZpcz.mjs";import{default as P}from"./packem_shared/discoverCrons-B1_NUt19.mjs";import{capabilitiesUsedBy as b,foldCapabilitySignals as y,mayReadCapabilityContext as U,sourceCapabilitySignals as G}from"./packem_shared/capabilitiesUsedBy-C-7D7vlH.mjs";import{FLAGS_FILENAME as j,discoverFlags as B}from"./packem_shared/FLAGS_FILENAME-BQk3SX8D.mjs";import{default as W}from"./packem_shared/discoverFunctions-DkPOc8b9.mjs";import{default as V}from"./packem_shared/discoverHttpRoutes-DCDgDIYv.mjs";import{default as Q}from"./packem_shared/discoverHyperdriveCalls-CL-d0IVo.mjs";import{default as w}from"./packem_shared/discoverInserts-BcoTjXqI.mjs";import{d as Y}from"./packem_shared/index-CN8FVvr-.mjs";import{default as Z}from"./packem_shared/discoverMigrations-BWxx8Wv9.mjs";import{MUTATORS_FILENAME as ee,discoverMutators as re}from"./packem_shared/MUTATORS_FILENAME-Cy9h3EVW.mjs";import{default as te}from"./packem_shared/discoverNondeterministicCalls-3INW8oqs.mjs";import{NOTIFY_FILENAME as se,discoverNotifyCalls as ie,discoverNotifyChannels as fe,discoverNotifyConfig as me}from"./packem_shared/NOTIFY_FILENAME-9to_l_Kh.mjs";import{default as pe}from"./packem_shared/readPackageDependencies-RHhGiz0k.mjs";import{default as le}from"./packem_shared/discoverQueries-CxQRVuIV.mjs";import{QUEUES_FILENAME as xe,discoverQueues as Se}from"./packem_shared/QUEUES_FILENAME-Civ-7SiI.mjs";import{default as ue}from"./packem_shared/discoverR2sqlCalls-B4oeTYEM.mjs";import{default as ve}from"./packem_shared/discoverRlsProcedures-Cl6UKT7L.mjs";import{default as ge}from"./packem_shared/discoverRlsMetadata-D0B4nCmG.mjs";import{discoverSandboxUsage as Oe}from"./packem_shared/discoverSandboxUsage--Z1vx7GM.mjs";import{default as he}from"./packem_shared/discoverSchema-Cwt-DQgh.mjs";import{readServiceBindings as Ie,resolveServiceBindings as _e}from"./packem_shared/readServiceBindings-BA49C6aN.mjs";import{SHAPES_FILENAME as Me,discoverShapes as Fe}from"./packem_shared/SHAPES_FILENAME-DVJbfDZ8.mjs";import{default as De}from"./packem_shared/discoverStorageRulesMetadata-CitX6ziW.mjs";import{WORKFLOWS_FILENAME as ye,discoverWorkflows as Ue}from"./packem_shared/WORKFLOWS_FILENAME-kXq07aGl.mjs";import{emitApp as He}from"./packem_shared/emitApp-BL16wvE9.mjs";import{isD1GlobalTable as Be,isHyperdriveGlobalTable as ke}from"./packem_shared/isD1GlobalTable-udvHAAzD.mjs";import{buildOpenApiDocument as Ke,emitOpenApi as Ve,emitOpenApiModule as ze}from"./packem_shared/buildOpenApiDocument-DWdj2jvW.mjs";import{OPENRPC_VERSION as qe,buildOpenRpcDocument as we,emitOpenRpc as Je,emitOpenRpcModule as Ye}from"./packem_shared/OPENRPC_VERSION-l4HD4osw.mjs";import{DEFAULT_TARGET as Ze,platformMatrixIds as $e,readProjectTarget as er,resolveCodegenTarget as rr}from"./packem_shared/DEFAULT_TARGET-3OLdJhTj.mjs";import{loadProjectConfig as tr,readProjectConfigLiterals as ar}from"./packem_shared/loadProjectConfig-B7RmxIeD.mjs";import{PROJECT_CONFIG_FILENAMES as ir,findCodegenConfigFile as fr,findProjectConfigFile as mr,projectConfigCandidatePaths as dr}from"./packem_shared/PROJECT_CONFIG_FILENAMES-CLfsyvjA.mjs";import{SCHEMA_SNAPSHOT_FILENAME as nr,runCodegen as lr}from"./packem_shared/SCHEMA_SNAPSHOT_FILENAME-6cfIWExE.mjs";import{SchemaSnapshotParseError as xr,buildSchemaSnapshot as Sr,evaluateSchemaDrift as Er,parseSchemaSnapshot as ur}from"./packem_shared/SchemaSnapshotParseError-H9eQX4ui.mjs";import{default as vr}from"./packem_shared/fingerprintSchemaSources-BKXkgkj4.mjs";import{schemaFromIr as gr}from"./packem_shared/schemaFromIr-BWFnvCVg.mjs";import{LUNORA_ERROR_CODES as Or,validatorIrToJsonSchema as Rr}from"./packem_shared/LUNORA_ERROR_CODES-CIAJQeKB.mjs";import{SDK_LANGUAGES as Tr,SDK_TARGETS as Ir,generateSdk as _r}from"./sdk/index.mjs";import{redact as Mr,secretKindOf as Fr}from"./packem_shared/redact-Cy14LEnc.mjs";import{default as Dr}from"./packem_shared/emitDrizzleSchema-bct1OuH5.mjs";import{e as yr}from"./packem_shared/server-B6VhYK7m.mjs";import{e as Gr}from"./packem_shared/shard-BCqz_05A.mjs";import{G as jr}from"./packem_shared/shared-8vTRkL2-.mjs";import{MESSAGE_SOLUTIONS as kr,findSolutionByMessage as Wr}from"@lunora/errors";import{createCodegenProject as Vr,findTsconfig as zr,refreshCodegenProject as Qr}from"./packem_shared/createCodegenProject-R4so-yTU.mjs";import{s as wr,t as Jr,u as Yr}from"./packem_shared/shard-runtime-ByYXjCKY.mjs";import{emitApi as Zr,emitCollections as $r,emitInternalApi as eo}from"./packem_shared/emitApi-c14__tie.mjs";import{emitCrons as oo,emitScheduler as to,emitVectors as ao,emitWranglerCronTriggers as so}from"./packem_shared/emitCrons-lc-hnJYn.mjs";import{emitDataModel as fo}from"./packem_shared/emitDataModel-CuFqq97x.mjs";import{emitFunctions as po}from"./packem_shared/emitFunctions-CkBPtGDF.mjs";import{isTypedSchema as lo}from"./packem_shared/isTypedSchema-CKzc3ioR.mjs";const e="0.0.0";export{g as AGENTS_FILENAME,E as CAPABILITY_PROBES,L as CONTAINERS_FILENAME,A as CodegenDiagnosticError,Ze as DEFAULT_TARGET,j as FLAGS_FILENAME,jr as GENERATED_HEADER,Or as LUNORA_ERROR_CODES,kr as LUNORA_SOLUTION_RULES,ee as MUTATORS_FILENAME,se as NOTIFY_FILENAME,qe as OPENRPC_VERSION,ir as PROJECT_CONFIG_FILENAMES,xe as QUEUES_FILENAME,nr as SCHEMA_SNAPSHOT_FILENAME,t as SCHEMA_SNAPSHOT_VERSION,Tr as SDK_LANGUAGES,Ir as SDK_TARGETS,Me as SHAPES_FILENAME,xr as SchemaSnapshotParseError,e as VERSION,ye as WORKFLOWS_FILENAME,Ke as buildOpenApiDocument,we as buildOpenRpcDocument,Sr as buildSchemaSnapshot,b as capabilitiesUsedBy,Vr as createCodegenProject,n as describeErrorLevelFindings,v as diagnosticAt,a as diffSchemaSnapshots,N as discoverAgents,I as discoverAuthApiCalls,M as discoverContainers,P as discoverCrons,B as discoverFlags,W as discoverFunctions,V as discoverHttpRoutes,Q as discoverHyperdriveCalls,w as discoverInserts,Y as discoverMaskProcedures,Z as discoverMigrations,re as discoverMutators,te as discoverNondeterministicCalls,ie as discoverNotifyCalls,fe as discoverNotifyChannels,me as discoverNotifyConfig,le as discoverQueries,Se as discoverQueues,ue as discoverR2sqlCalls,ge as discoverRlsMetadata,ve as discoverRlsProcedures,Oe as discoverSandboxUsage,he as discoverSchema,Fe as discoverShapes,De as discoverStorageRulesMetadata,Ue as discoverWorkflows,wr as emitAgents,Zr as emitApi,He as emitApp,$r as emitCollections,Jr as emitContainers,oo as emitCrons,fo as emitDataModel,Dr as emitDrizzleSchema,po as emitFunctions,eo as emitInternalApi,Ve as emitOpenApi,ze as emitOpenApiModule,Je as emitOpenRpc,Ye as emitOpenRpcModule,to as emitScheduler,yr as emitServer,Gr as emitShard,ao as emitVectors,Yr as emitWorkflows,so as emitWranglerCronTriggers,l as errorAdvisoryNames,c as errorPlatformDiagnosticNames,Er as evaluateSchemaDrift,fr as findCodegenConfigFile,Wr as findLunoraSolution,mr as findProjectConfigFile,zr as findTsconfig,vr as fingerprintSchemaSources,y as foldCapabilitySignals,f as formatAdvisories,_r as generateSdk,Be as isD1GlobalTable,ke as isHyperdriveGlobalTable,R as isTestPath,lo as isTypedSchema,m as lintSchema,h as listLunoraSourceFiles,tr as loadProjectConfig,U as mayReadCapabilityContext,ur as parseSchemaSnapshot,$e as platformMatrixIds,dr as projectConfigCandidatePaths,pe as readPackageDependencies,ar as readProjectConfigLiterals,er as readProjectTarget,Ie as readServiceBindings,Mr as redact,Qr as refreshCodegenProject,rr as resolveCodegenTarget,_e as resolveServiceBindings,lr as runCodegen,gr as schemaFromIr,Fr as secretKindOf,s as serializeSchemaSnapshot,x as sortedUniqueNames,G as sourceCapabilitySignals,d as toAdvisorContext,Rr as validatorIrToJsonSchema};
@@ -1,4 +1,4 @@
1
- import{existsSync as M,readFileSync as Ge,mkdirSync as $t,writeFileSync as gr,rmSync as ye,readdirSync as Cn}from"node:fs";import{dirname as Bt,join as E,relative as Tn}from"node:path";import{performance as mt}from"node:perf_hooks";import{runAdvisor as pr}from"@lunora/advisor";import{LunoraError as _}from"@lunora/errors";import{serializeSchemaSnapshot as mr}from"./SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs";import{toAdvisorContext as hr}from"./formatAdvisories-BCVASH7N.mjs";import{Node as r,SyntaxKind as d,Project as Vt,ts as vr,VariableDeclarationKind as Er}from"ts-morph";import{listLunoraSourceFiles as A,lunoraRelativePath as w,bindingKeyName as ce,collectCallRows as C,findObjectProperty as V,collectSecurityCallRows as xr,propertyInitializer as R,listSecurityScanFiles as Ye,objectLiteralFromCallbackBody as On,limitNameOf as kn,optionsObjectLiteral as Rn,handlerOf as Sr,collectNodeRows as ne,chainRootOf as Qe,outermostValueWrapper as I,isWriteTarget as Xe,isSameNode as y,unwrapExpression as h,isConstDeclaration as ie,memberAccessOf as Ut,returningFunctionOf as Pt,walkChain as Ar,RUN_METHODS as Fn,functionReferenceSegments as yr,isTestPath as br,isFunctionLike as re,functionKeyOf as Ln}from"./isTestPath-C3QumE88.mjs";import{b as Q,d as j,f as L,g as Wt,c as x,a as qt,w as jt,k as Nr,l as Pr,h as wr,m as Ir,j as wt,i as Cr}from"./attribution-CG8-kUcl.mjs";import{a as Fs,r as ht,i as G,b as Tr,m as Dn,c as Je,e as Ht,E as Mn,C as _n,d as Or,f as kr,g as Rr}from"./context-root-CNR6TAsP.mjs";import{a as P,i as Fr,c as ee,d as Kn,e as Lr,f as Dr,g as zn}from"./classify-procedure-call-BkaeM9Ej.mjs";import{a as S,s as Mr}from"./property-name-7cBlgK_O.mjs";import{b as _r,a as Ze}from"./module-specifiers-BctA0m_p.mjs";import{r as et,s as Kr}from"./parse-validator-iVTounLK.mjs";import zr from"./discoverAuthApiCalls-CScPrUD-.mjs";import{i as z,r as $n}from"./database-calls-UPlhi3Ks.mjs";import $r from"./discoverHyperdriveCalls-CL-d0IVo.mjs";import{diagnosticAt as de}from"./CodegenDiagnosticError-BUXlG3P-.mjs";import{m as Gt,a as Be,s as Bn,d as Br}from"./index-CN8FVvr-.mjs";import{MUTATORS_FILENAME as Vr,isDefineMutatorCallee as Ur,mutatorServerImplOf as Wr,discoverMutators as qr}from"./MUTATORS_FILENAME-Cy9h3EVW.mjs";import jr from"./discoverNondeterministicCalls-3INW8oqs.mjs";import{discoverNotifyConfig as Hr,discoverNotifyCalls as Gr}from"./NOTIFY_FILENAME-9to_l_Kh.mjs";import Yr from"./discoverR2sqlCalls-B4oeTYEM.mjs";import Qr from"./discoverRlsProcedures-Cl6UKT7L.mjs";import{s as Yt,n as Xr}from"./dispatch-namespace-DwTjD7BU.mjs";import{secretKindOf as Jr,redact as Zr,isHeuristicSecretKind as eo,isSecretishName as to}from"./redact-Cy14LEnc.mjs";import{readProjectConfigLiterals as Vn,readMergeDurableObjects as so}from"./loadProjectConfig-B7RmxIeD.mjs";import{a as Le,d as no,r as io}from"./modules-l-Db0C4S.mjs";import{WORKFLOWS_FILENAME as ro,discoverWorkflows as oo}from"./WORKFLOWS_FILENAME-kXq07aGl.mjs";import{r as ao}from"./json-data-Chfs2Cz5.mjs";import{a as co,I as lo,g as uo,G as Un,d as fo,i as go}from"./shared-8vTRkL2-.mjs";import{createCodegenProject as po}from"./createCodegenProject-R4so-yTU.mjs";import{findTsconfig as PE,refreshCodegenProject as wE}from"./createCodegenProject-R4so-yTU.mjs";import{CAPABILITIES as mo,usedCapabilities as ho}from"./CAPABILITY_PROBES-brcmKenl.mjs";import{isD1GlobalTable as Wn,isHyperdriveGlobalTable as qn}from"./isD1GlobalTable-udvHAAzD.mjs";import{discoverAgents as vo}from"./AGENTS_FILENAME-isdHqPIt.mjs";import{discoverContainers as Eo}from"./CONTAINERS_FILENAME-mK4cZpcz.mjs";import xo from"./discoverCrons-B1_NUt19.mjs";import{contextPropertiesRead as So,fileWiresRequestSecretTool as Ao,discoverFeatureUsage as yo}from"./capabilitiesUsedBy-C-7D7vlH.mjs";import jn from"./readPackageDependencies-RHhGiz0k.mjs";import{PROJECT_CONFIG_FILENAMES as bo,findProjectConfigFile as No}from"./PROJECT_CONFIG_FILENAMES-CLfsyvjA.mjs";import{discoverQueueDeclarations as Po}from"./QUEUES_FILENAME-Civ-7SiI.mjs";import{discoverSandboxUsage as wo}from"./discoverSandboxUsage--Z1vx7GM.mjs";import{resolveServiceBindings as Io}from"./readServiceBindings-BA49C6aN.mjs";import Co from"./discoverStorageRulesMetadata-CitX6ziW.mjs";import{resolveCodegenTarget as It,gatePlatformFeatures as To,readTargetDiagnostics as Oo,vectorizeDimensionDiagnostics as ko,liveStreamsDeliveryAuthorizationDiagnostic as Ro,socketRoutesDeliveryAuthorizationDiagnostic as Fo,studioPlatformFor as Lo,platformFeatureAvailable as Do}from"./DEFAULT_TARGET-3OLdJhTj.mjs";import{i as Mo}from"./schema-BgM8A3XV.mjs";import{b as Hn,e as _o}from"./shard-B6afe1Uh.mjs";import{e as Ko,a as zo}from"./server-B6VhYK7m.mjs";import{emitDataModel as $o}from"./emitDataModel-CuFqq97x.mjs";import{i as Bo,a as Vo,e as Uo,b as Wo,d as qo,c as jo}from"./unwrap-handler-return-CGdJGvGh.mjs";import Ho from"./discoverFunctions-DkPOc8b9.mjs";import Go from"./discoverHttpRoutes-DCDgDIYv.mjs";import Yo from"./discoverInserts-BcoTjXqI.mjs";import{e as Gn}from"./exported-procedure-chains-D1WlRfqJ.mjs";import Qo from"./discoverMigrations-BWxx8Wv9.mjs";import Xo from"./discoverQueries-CxQRVuIV.mjs";import Jo from"./discoverRlsMetadata-D0B4nCmG.mjs";import Zo from"./discoverSchema-Cwt-DQgh.mjs";import{discoverShapes as ea}from"./SHAPES_FILENAME-DVJbfDZ8.mjs";import{i as ta}from"./reserved-words-CW1QFbTd.mjs";import{emitApp as sa}from"./emitApp-BL16wvE9.mjs";import{readJsonSync as na}from"@visulima/fs";import{buildSchemaSnapshot as ia}from"./SchemaSnapshotParseError-BRJT7c2k.mjs";import{buildOpenApiDocument as ra,emitOpenApiModule as oa}from"./buildOpenApiDocument-DWdj2jvW.mjs";import{buildOpenRpcDocument as aa,emitOpenRpcModule as ca}from"./OPENRPC_VERSION-l4HD4osw.mjs";import{v as la,t as da,u as ua,s as fa,w as ga}from"./shard-runtime-BW1kffN4.mjs";import{emitCollections as pa,emitSeed as ma,emitApi as ha,emitInternalApi as va}from"./emitApi-c14__tie.mjs";import{emitCrons as Ea,emitScheduler as xa,emitShardRegistry as Sa,emitDurableObjects as Aa,emitVectors as ya,emitWranglerCronTriggers as ba}from"./emitCrons-lc-hnJYn.mjs";import Na from"./emitDrizzleSchema-bct1OuH5.mjs";import{LAZY_FUNCTION_DIRECTORY as Yn,emitFunctions as Pa,emitLazyFunctionModules as wa}from"./emitFunctions-CkBPtGDF.mjs";const Ia=(e,t=!1)=>{if(e.length===0)return"";const s=fo(t),n=e.map(c=>{if(co(c.exportName,"live stream export name"),!lo.test(c.filePath))throw new Error(`@lunora/codegen: live stream file path is not safe to import: ${JSON.stringify(c.filePath)}`);return`import type { ${c.exportName} as ${c.exportName}Stream } from "../${c.filePath}.js";`}),i=e.map(c=>{const l=c.topics.map(u=>{uo(u.name,"live topic name");const f=`(typeof ${c.exportName}Stream)["topics"]["${u.name}"]`,g=`LiveTopicRef<LiveTopicPayload<${f}>>`,m=JSON.stringify(c.id);if(u.fields.length===0)return` ${u.name}: (): ${g} => ({ __lunoraLive: ${m}, topic: ${JSON.stringify(u.name)} }),`;const v=u.fields.map($=>`\${encodeURIComponent(key.${$})}`).join(":");return` ${u.name}: (key: LiveTopicKey<${f}>): ${g} => ({
1
+ import{existsSync as M,readFileSync as Ge,mkdirSync as $t,writeFileSync as gr,rmSync as ye,readdirSync as Cn}from"node:fs";import{dirname as Bt,join as E,relative as Tn}from"node:path";import{performance as mt}from"node:perf_hooks";import{runAdvisor as pr}from"@lunora/advisor";import{LunoraError as _}from"@lunora/errors";import{serializeSchemaSnapshot as mr}from"./SCHEMA_SNAPSHOT_VERSION-C7Um0EnM.mjs";import{toAdvisorContext as hr}from"./formatAdvisories-BCVASH7N.mjs";import{Node as r,SyntaxKind as d,Project as Vt,ts as vr,VariableDeclarationKind as Er}from"ts-morph";import{listLunoraSourceFiles as A,lunoraRelativePath as w,bindingKeyName as ce,collectCallRows as C,findObjectProperty as V,collectSecurityCallRows as xr,propertyInitializer as R,listSecurityScanFiles as Ye,objectLiteralFromCallbackBody as On,limitNameOf as kn,optionsObjectLiteral as Rn,handlerOf as Sr,collectNodeRows as ne,chainRootOf as Qe,outermostValueWrapper as I,isWriteTarget as Xe,isSameNode as y,unwrapExpression as h,isConstDeclaration as ie,memberAccessOf as Ut,returningFunctionOf as Pt,walkChain as Ar,RUN_METHODS as Fn,functionReferenceSegments as yr,isTestPath as br,isFunctionLike as re,functionKeyOf as Ln}from"./isTestPath-C3QumE88.mjs";import{b as Q,d as j,f as L,g as Wt,c as x,a as qt,w as jt,k as Nr,l as Pr,h as wr,m as Ir,j as wt,i as Cr}from"./attribution-CG8-kUcl.mjs";import{a as Fs,r as ht,i as G,b as Tr,m as Dn,c as Je,e as Ht,E as Mn,C as _n,d as Or,f as kr,g as Rr}from"./context-root-CNR6TAsP.mjs";import{a as P,i as Fr,c as ee,d as Kn,e as Lr,f as Dr,g as zn}from"./classify-procedure-call-BkaeM9Ej.mjs";import{a as S,s as Mr}from"./property-name-7cBlgK_O.mjs";import{b as _r,a as Ze}from"./module-specifiers-BctA0m_p.mjs";import{r as et,s as Kr}from"./parse-validator-iVTounLK.mjs";import zr from"./discoverAuthApiCalls-CScPrUD-.mjs";import{i as z,r as $n}from"./database-calls-UPlhi3Ks.mjs";import $r from"./discoverHyperdriveCalls-CL-d0IVo.mjs";import{diagnosticAt as de}from"./CodegenDiagnosticError-BUXlG3P-.mjs";import{m as Gt,a as Be,s as Bn,d as Br}from"./index-CN8FVvr-.mjs";import{MUTATORS_FILENAME as Vr,isDefineMutatorCallee as Ur,mutatorServerImplOf as Wr,discoverMutators as qr}from"./MUTATORS_FILENAME-Cy9h3EVW.mjs";import jr from"./discoverNondeterministicCalls-3INW8oqs.mjs";import{discoverNotifyConfig as Hr,discoverNotifyCalls as Gr}from"./NOTIFY_FILENAME-9to_l_Kh.mjs";import Yr from"./discoverR2sqlCalls-B4oeTYEM.mjs";import Qr from"./discoverRlsProcedures-Cl6UKT7L.mjs";import{s as Yt,n as Xr}from"./dispatch-namespace-DwTjD7BU.mjs";import{secretKindOf as Jr,redact as Zr,isHeuristicSecretKind as eo,isSecretishName as to}from"./redact-Cy14LEnc.mjs";import{readProjectConfigLiterals as Vn,readMergeDurableObjects as so}from"./loadProjectConfig-B7RmxIeD.mjs";import{a as Le,d as no,r as io}from"./modules-l-Db0C4S.mjs";import{WORKFLOWS_FILENAME as ro,discoverWorkflows as oo}from"./WORKFLOWS_FILENAME-kXq07aGl.mjs";import{r as ao}from"./json-data-Chfs2Cz5.mjs";import{a as co,I as lo,g as uo,G as Un,d as fo,i as go}from"./shared-8vTRkL2-.mjs";import{createCodegenProject as po}from"./createCodegenProject-R4so-yTU.mjs";import{findTsconfig as PE,refreshCodegenProject as wE}from"./createCodegenProject-R4so-yTU.mjs";import{CAPABILITIES as mo,usedCapabilities as ho}from"./CAPABILITY_PROBES-brcmKenl.mjs";import{isD1GlobalTable as Wn,isHyperdriveGlobalTable as qn}from"./isD1GlobalTable-udvHAAzD.mjs";import{discoverAgents as vo}from"./AGENTS_FILENAME-isdHqPIt.mjs";import{discoverContainers as Eo}from"./CONTAINERS_FILENAME-mK4cZpcz.mjs";import xo from"./discoverCrons-B1_NUt19.mjs";import{contextPropertiesRead as So,fileWiresRequestSecretTool as Ao,discoverFeatureUsage as yo}from"./capabilitiesUsedBy-C-7D7vlH.mjs";import jn from"./readPackageDependencies-RHhGiz0k.mjs";import{PROJECT_CONFIG_FILENAMES as bo,findProjectConfigFile as No}from"./PROJECT_CONFIG_FILENAMES-CLfsyvjA.mjs";import{discoverQueueDeclarations as Po}from"./QUEUES_FILENAME-Civ-7SiI.mjs";import{discoverSandboxUsage as wo}from"./discoverSandboxUsage--Z1vx7GM.mjs";import{resolveServiceBindings as Io}from"./readServiceBindings-BA49C6aN.mjs";import Co from"./discoverStorageRulesMetadata-CitX6ziW.mjs";import{resolveCodegenTarget as It,gatePlatformFeatures as To,readTargetDiagnostics as Oo,vectorizeDimensionDiagnostics as ko,liveStreamsDeliveryAuthorizationDiagnostic as Ro,socketRoutesDeliveryAuthorizationDiagnostic as Fo,studioPlatformFor as Lo,platformFeatureAvailable as Do}from"./DEFAULT_TARGET-3OLdJhTj.mjs";import{i as Mo}from"./schema-BgM8A3XV.mjs";import{b as Hn,e as _o}from"./shard-BCqz_05A.mjs";import{e as Ko,a as zo}from"./server-B6VhYK7m.mjs";import{emitDataModel as $o}from"./emitDataModel-CuFqq97x.mjs";import{i as Bo,a as Vo,e as Uo,b as Wo,d as qo,c as jo}from"./unwrap-handler-return-CGdJGvGh.mjs";import Ho from"./discoverFunctions-DkPOc8b9.mjs";import Go from"./discoverHttpRoutes-DCDgDIYv.mjs";import Yo from"./discoverInserts-BcoTjXqI.mjs";import{e as Gn}from"./exported-procedure-chains-D1WlRfqJ.mjs";import Qo from"./discoverMigrations-BWxx8Wv9.mjs";import Xo from"./discoverQueries-CxQRVuIV.mjs";import Jo from"./discoverRlsMetadata-D0B4nCmG.mjs";import Zo from"./discoverSchema-Cwt-DQgh.mjs";import{discoverShapes as ea}from"./SHAPES_FILENAME-DVJbfDZ8.mjs";import{i as ta}from"./reserved-words-CW1QFbTd.mjs";import{emitApp as sa}from"./emitApp-BL16wvE9.mjs";import{readJsonSync as na}from"@visulima/fs";import{buildSchemaSnapshot as ia}from"./SchemaSnapshotParseError-H9eQX4ui.mjs";import{buildOpenApiDocument as ra,emitOpenApiModule as oa}from"./buildOpenApiDocument-DWdj2jvW.mjs";import{buildOpenRpcDocument as aa,emitOpenRpcModule as ca}from"./OPENRPC_VERSION-l4HD4osw.mjs";import{v as la,t as da,u as ua,s as fa,w as ga}from"./shard-runtime-ByYXjCKY.mjs";import{emitCollections as pa,emitSeed as ma,emitApi as ha,emitInternalApi as va}from"./emitApi-c14__tie.mjs";import{emitCrons as Ea,emitScheduler as xa,emitShardRegistry as Sa,emitDurableObjects as Aa,emitVectors as ya,emitWranglerCronTriggers as ba}from"./emitCrons-lc-hnJYn.mjs";import Na from"./emitDrizzleSchema-bct1OuH5.mjs";import{LAZY_FUNCTION_DIRECTORY as Yn,emitFunctions as Pa,emitLazyFunctionModules as wa}from"./emitFunctions-CkBPtGDF.mjs";const Ia=(e,t=!1)=>{if(e.length===0)return"";const s=fo(t),n=e.map(c=>{if(co(c.exportName,"live stream export name"),!lo.test(c.filePath))throw new Error(`@lunora/codegen: live stream file path is not safe to import: ${JSON.stringify(c.filePath)}`);return`import type { ${c.exportName} as ${c.exportName}Stream } from "../${c.filePath}.js";`}),i=e.map(c=>{const l=c.topics.map(u=>{uo(u.name,"live topic name");const f=`(typeof ${c.exportName}Stream)["topics"]["${u.name}"]`,g=`LiveTopicRef<LiveTopicPayload<${f}>>`,m=JSON.stringify(c.id);if(u.fields.length===0)return` ${u.name}: (): ${g} => ({ __lunoraLive: ${m}, topic: ${JSON.stringify(u.name)} }),`;const v=u.fields.map($=>`\${encodeURIComponent(key.${$})}`).join(":");return` ${u.name}: (key: LiveTopicKey<${f}>): ${g} => ({
2
2
  __lunoraLive: ${m},
3
3
  topic: \`${u.name}:${v}\`,
4
4
  }),`});return` ${c.exportName}: {
@@ -0,0 +1,2 @@
1
+ const k=(e,t=2166136261)=>{let i=t;for(let r=0;r<e.length;r+=1)i^=e.charCodeAt(r),i=Math.imul(i,16777619);return(i>>>0).toString(16).padStart(8,"0")},q=e=>`${k(e,2166136261)}${k(e,16777619)}`,X=1;function A(e){const t={},i=Object.keys(e);i.sort();for(const r of i)t[r]=e[r];return t}const C=e=>`${JSON.stringify(e,void 0,2)}
2
+ `,Z=e=>q(C(e)),l=e=>typeof e=="object"&&e!==null,I=e=>l(e)&&l(e.fields)&&l(e.indexes)&&l(e.relations)&&typeof e.shardMode=="string",N=e=>{if(e===void 0||e.trim()==="")return{status:"absent"};let t;try{t=JSON.parse(e)}catch(r){return{error:`baseline is not valid JSON: ${r instanceof Error?r.message:String(r)}`,status:"invalid"}}if(!l(t)||t.version!==1||!l(t.tables))return{error:`baseline is malformed or written by an incompatible version (expected version ${String(1)})`,status:"invalid"};for(const[r,o]of Object.entries(t.tables))if(!I(o))return{error:`baseline table "${r}" has an invalid structure`,status:"invalid"};return{snapshot:{jurisdiction:typeof t.jurisdiction=="string"?t.jurisdiction:void 0,migrationIds:Array.isArray(t.migrationIds)?t.migrationIds:[],tables:t.tables,version:1},status:"ok"}},R=(e,t)=>e.unique===t.unique&&e.fields.length===t.fields.length&&e.fields.every((i,r)=>i===t.fields[r]),S=e=>e.unique!==void 0,h=({nullable:e,optional:t,refined:i,unique:r,...o})=>JSON.stringify(A(o)),O=e=>({form:JSON.stringify([h(e),e.optional===!0,e.nullable===!0]),refined:e.refined===!0}),w=e=>e.kind==="union"&&e.members?e.members.map(t=>O(t)):[O({...e,nullable:!1,optional:!1})],V=(e,t)=>{if(t.kind!=="union")return!1;const i=w(t);return w(e).every(r=>i.some(o=>o.form===r.form&&(r.refined||!o.refined)))},c=e=>{switch(e.kind){case"array":return`array(${e.of?c(e.of):"?"})`;case"from":return e.output===void 0?"from":`from(${e.output})`;case"id":return`id(${e.ref??"?"})`;case"literal":return`literal(${e.literal??"?"})`;case"object":return`object({ ${Object.keys(e.fields??{}).join(", ")} })`;case"record":return`record(${e.key?c(e.key):"?"}, ${e.of?c(e.of):"?"})`;case"union":return(e.members??[]).map(t=>c(t)).join(" | ");default:return e.kind}},p=(e,t,i)=>({remediation:"backfill",scope:"table",severity:"breaking",summary:i,table:e,type:t}),g=(e,t,i)=>({remediation:"none",scope:"table",severity:"safe",summary:i,table:e,type:t}),M=(e,t)=>{const i=JSON.stringify(e),r=JSON.stringify(t);return i===r?0:i<r?-1:1},f=e=>({...e,...e.kind==="from"?{output:void 0}:{},...e.fields?{fields:Object.fromEntries(Object.entries(e.fields).map(([t,i])=>[t,f(i)]))}:{},...e.key?{key:f(e.key)}:{},...e.of?{of:f(e.of)}:{},...e.members?{members:e.members.map(t=>f(t)).toSorted(M)}:{}}),x=e=>e.kind==="union"?e.members??[]:[e],L=(e,t)=>{const i=[...e],r=[...t],o=new Set,n=new Set,s=(a,d)=>{for(const[b,$]of i.entries()){if(n.has(b))continue;const m=r.findIndex((_,E)=>!o.has(E)&&a($,_));m!==-1&&(o.add(m),n.add(b),d&&([i[b],r[m]]=v($,r[m])))}};return s((a,d)=>JSON.stringify(a)===JSON.stringify(d),!1),s((a,d)=>h(f(a))===h(f(d)),!0),[i,r]},v=(e,t)=>{if(e.kind==="union"||t.kind==="union"){const[o,n]=L(x(e),x(t)),s=(a,d)=>a.kind==="union"?{...a,members:d.toSorted(M)}:d[0];return[s(e,o),s(t,n)]}if(e.kind!==t.kind)return[e,t];if(e.kind==="from")return e.output===void 0||t.output===void 0?[{...e,output:void 0},{...t,output:void 0}]:[e,t];const i={...e.fields?{fields:{...e.fields}}:{}},r={...t.fields?{fields:{...t.fields}}:{}};for(const o of["key","of"])e[o]&&t[o]&&([i[o],r[o]]=v(e[o],t[o]));for(const o of Object.keys(e.fields??{})){const n=e.fields?.[o],s=t.fields?.[o];n&&s&&i.fields&&r.fields&&([i.fields[o],r.fields[o]]=v(n,s))}return[{...e,...i},{...t,...r}]},D=(e,t,i,r,o)=>{const[n,s]=v(i,r);if(!(n.kind===s.kind&&(!o||h(n)===h(s))))return o&&V(n,s)?g(e,"widenedFieldShape",`field ${e}.${t} widened: ${c(n)} → ${c(s)} — every stored value stays valid`):n.kind!==s.kind?p(e,"changedFieldKind",`field ${e}.${t} changed type: ${n.kind} → ${s.kind} — add a data migration to convert existing values`):p(e,"changedFieldShape",`field ${e}.${t} changed shape: ${c(n)} → ${c(s)} — stored values were written against the old shape; add a data migration to convert them`)},H=(e,t,i,r)=>{const o=[];return i.unique!==r.unique&&o.push(r.unique===!0?p(e,"addedFieldConstraint",`field ${e}.${t} became unique — existing duplicates would violate it; add a data migration to de-duplicate first`):g(e,"relaxedFieldConstraint",`field ${e}.${t} is no longer unique`)),i.nullable!==r.nullable&&o.push(r.nullable===!0?g(e,"relaxedFieldConstraint",`field ${e}.${t} became nullable`):p(e,"addedFieldConstraint",`field ${e}.${t} is no longer nullable — rows holding NULL would be invalid; add a data migration to backfill them`)),i.refined!==r.refined&&o.push(r.refined===!0?p(e,"addedFieldConstraint",`field ${e}.${t} gained a validation refinement — stored values were never checked against it; add a data migration if any could fail`):g(e,"relaxedFieldConstraint",`field ${e}.${t} dropped its validation refinement`)),o},J=(e,t,i,r)=>{const o=[],n=S(i)&&S(r),s=D(e,t,i,r,n);return s&&o.push(s),n&&o.push(...H(e,t,i,r)),i.optional&&!r.optional?o.push({remediation:"backfill",severity:"breaking",summary:`field ${e}.${t} became required — rows missing it would be invalid; add a data migration to backfill it`,table:e,scope:"table",type:"fieldOptionalToRequired"}):!i.optional&&r.optional&&o.push({remediation:"none",scope:"table",severity:"safe",summary:`field ${e}.${t} became optional`,table:e,type:"fieldRequiredToOptional"}),o},P=(e,t,i)=>i.optional?{remediation:"none",scope:"table",severity:"safe",summary:`added optional field ${e}.${t}`,table:e,type:"addedOptionalField"}:{remediation:"backfill",severity:"breaking",summary:`added required field ${e}.${t} — existing rows have no value; add a data migration to backfill it`,table:e,scope:"table",type:"addedRequiredField"},B=(e,t,i,r)=>{for(const[o,n]of Object.entries(i.fields)){const s=t.fields[o];s===void 0?r.push(P(e,o,n)):r.push(...J(e,o,s,n))}for(const o of Object.keys(t.fields))i.fields[o]===void 0&&r.push({remediation:"backfill",severity:"breaking",summary:`removed field ${e}.${o} — add a data migration if stored data must be cleaned up`,table:e,scope:"table",type:"removedField"})},G=(e,t,i,r)=>{for(const[o,n]of Object.entries(i.indexes)){const s=t.indexes[o];if(s===void 0){r.push(n.unique?{remediation:"backfill",scope:"table",severity:"breaking",summary:`added unique index ${o} on ${e} — existing duplicates would violate it; add a data migration to de-duplicate first`,table:e,type:"addedIndex"}:{remediation:"none",scope:"table",severity:"safe",summary:`added index ${o} on ${e}`,table:e,type:"addedIndex"});continue}R(s,n)||r.push({remediation:"code",severity:"breaking",summary:`index ${o} on ${e} changed shape — a query may have relied on the old index`,table:e,scope:"table",type:"changedIndex"})}for(const o of Object.keys(t.indexes))i.indexes[o]===void 0&&r.push({remediation:"code",severity:"breaking",summary:`removed index ${o} on ${e} — a query that used \`.withIndex("${o}")\` would break`,table:e,scope:"table",type:"removedIndex"})},U=(e,t,i,r)=>{for(const o of Object.keys(i.relations))t.relations[o]===void 0&&r.push({remediation:"none",scope:"schema",severity:"safe",summary:`added relation ${e}.${o}`,table:e,type:"addedRelation"});for(const o of Object.keys(t.relations))i.relations[o]===void 0&&r.push({remediation:"code",scope:"schema",severity:"breaking",summary:`removed relation ${e}.${o}`,table:e,type:"removedRelation"})},F="shardBy:_unknown_",y="global",W=(e,t)=>e===y&&t.startsWith(`${y}:`)||t===y&&e.startsWith(`${y}:`),K=(e,t,i)=>{if(t===i)return i!==F?void 0:{remediation:"rehome",scope:"table",severity:"breaking",summary:`table ${e} declares a non-literal .shardBy(...) key, so codegen cannot read which column partitions it — every such key records as "${F}" and two DIFFERENT keys would compare equal. Pass the shard key as a string literal; until then this is reported on every run, because the alternative is a silent pass on a re-home that strands every row (export/import is the only way back).`,table:e,type:"changedShardMode"};if(!W(t,i))return{remediation:"rehome",severity:"breaking",summary:`table ${e} changed shard mode: ${t} → ${i} — its physical storage moves, and existing rows do NOT follow the schema; re-home them with an export/import round trip (https://lunora.sh/docs/concepts/sharding#migrating-a-populated-table)`,table:e,scope:"table",type:"changedShardMode"}},T=e=>e.memory!==void 0,j=e=>e.after??0,u=e=>e.after===void 0?`.ttl("${e.field}")`:`.ttl("${e.field}", { after: ${String(e.after)} })`,z=(e,t,i)=>{if(t===void 0&&i===void 0)return;const r=a=>({remediation:"backfill",scope:"table",severity:"breaking",summary:a,table:e,type:"changedTtlPolicy"}),o=a=>({remediation:"none",scope:"table",severity:"safe",summary:a,table:e,type:"changedTtlPolicy"});if(i===void 0)return o(`table ${e} dropped its TTL policy — its rows are no longer swept`);if(t===void 0)return r(`table ${e} gained a TTL policy ${u(i)} — every row already past the cutoff is deleted on the next alarm sweep; add a data migration to refresh or clear "${i.field}" on the rows written before it`);if(t.field!==i.field)return r(`table ${e} moved its TTL to a different column: ${u(t)} → ${u(i)} — rows are now expired by a column they were never written against; add a data migration to populate "${i.field}"`);const n=j(t),s=j(i);return s<n?r(`table ${e} shortened its TTL: ${u(t)} → ${u(i)} — rows that were not expired under the old offset are deleted on the next alarm sweep; add a data migration to refresh "${i.field}" on the rows that must survive`):s>n?o(`table ${e} lengthened its TTL: ${u(t)} → ${u(i)}`):void 0},Q=(e,t,i)=>{const r=[];return t.memory!==i.memory&&r.push(i.memory===!0?{remediation:"rehome",scope:"table",severity:"breaking",summary:`table ${e} became a .memory() table — every row is deleted in every shard on the next Durable Object cold start, and no data migration survives that; export the rows first if they must be kept, or revert`,table:e,type:"changedMemoryMode"}:{remediation:"none",scope:"table",severity:"safe",summary:`table ${e} is no longer a .memory() table — its rows now survive a cold start`,table:e,type:"changedMemoryMode"}),t.commitOrdered!==i.commitOrdered&&r.push(i.commitOrdered===!0?{remediation:"backfill",scope:"table",severity:"breaking",summary:`table ${e} became .commitOrdered() — rows written before it carry no _commitSeq, so a \`_commitSeq > cursor\` changefeed never offers them; add a data migration over the table to stamp them (the rewrite allocates a sequence)`,table:e,type:"changedCommitOrdering"}:{remediation:"code",scope:"table",severity:"breaking",summary:`table ${e} is no longer .commitOrdered() — new rows carry no _commitSeq, so a \`_commitSeq > cursor\` changefeed stops advancing without erroring; update the consumers before deploying`,table:e,type:"changedCommitOrdering"}),r},Y=(e,t,i,r)=>{const o=K(e,t.shardMode,i.shardMode);if(o&&r.push(o),T(t)&&T(i)){r.push(...Q(e,t,i));const n=z(e,t.ttl,i.ttl);n&&r.push(n)}B(e,t,i,r),G(e,t,i,r),U(e,t,i,r)},ee=(e,t)=>{const i=[],r=e?.tables??{};for(const[o,n]of Object.entries(t.tables)){const s=r[o];if(s===void 0){i.push({remediation:"none",scope:"table",severity:"safe",summary:`added table ${o}`,table:o,type:"addedTable"});continue}Y(o,s,n,i)}for(const o of Object.keys(r))t.tables[o]===void 0&&i.push({remediation:"rehome",scope:"table",severity:"breaking",summary:`removed table ${o} — its rows stay in each shard's SQLite, unreachable through the schema; export the shard first if the data must be kept`,table:o,type:"removedTable"});if(e!==void 0&&e.jurisdiction!==t.jurisdiction){const o=e.jurisdiction??"(none)",n=t.jurisdiction??"(none)";i.push({remediation:"rehome",scope:"schema",severity:"breaking",summary:`Durable Object jurisdiction changed from ${o} to ${n} — this re-homes every DO and strands all existing shard, scheduler, and session-DO data in the old region (no in-place migration; export then import to move it). Revert the change, or override the gate to proceed intentionally.`,type:"changedJurisdiction"})}return{changes:i}};export{X as SCHEMA_SNAPSHOT_VERSION,c as describeShape,J as diffExistingField,ee as diffSchemaSnapshots,Z as hashSchemaSnapshot,I as isValidTableSnapshot,N as parseSnapshotJson,C as serializeSchemaSnapshot,A as sortKeys};
@@ -0,0 +1,18 @@
1
+ import{LunoraError as A}from"@lunora/errors";import{SCHEMA_SNAPSHOT_VERSION as E,sortKeys as f,diffSchemaSnapshots as I,parseSnapshotJson as L}from"./SCHEMA_SNAPSHOT_VERSION-C7Um0EnM.mjs";import{isHyperdriveGlobalTable as O}from"./isD1GlobalTable-udvHAAzD.mjs";const _=e=>{const t=e.shardMode;return t==="global"?`global:${O(e)?"hyperdrive":"d1"}`:t==="root"?t:`shardBy:${t.field}`},v=(e,t)=>{const s=JSON.stringify(e),i=JSON.stringify(t);return s===i?0:s<i?-1:1},l=e=>{const t=e.kind==="optional",s=t?e.inner:void 0,i=s??e,r={kind:t?s?.kind??"unknown":e.kind,nullable:i.column?.notNull===!1||e.column?.notNull===!1,optional:t,unique:i.column?.unique===!0||e.column?.unique===!0,...D[i.kind]?.(i)};return(i.hasRefinement===!0||e.hasRefinement===!0)&&(r.refined=!0),r},N=e=>{const t={};for(const[s,i]of Object.entries(e))t[s]=l(i);return f(t)},j=/import\(\s*["'`](?:[A-Za-z]:)?[\\/]/u,D={array:e=>e.inner?{of:l(e.inner)}:{},from:e=>e.tsType===void 0||j.test(e.tsType)?{}:{output:e.tsType},id:e=>e.tableName===void 0?{}:{ref:e.tableName},literal:e=>e.literalValue===void 0?{}:{literal:e.literalValue},object:e=>e.shape?{fields:N(e.shape)}:{},record:e=>({...e.keyType?{key:l(e.keyType)}:{},...e.valueType?{of:l(e.valueType)}:{}}),union:e=>e.members?{members:e.members.map(t=>l(t)).toSorted(v)}:{}},M=e=>{const t={};for(const[n,a]of Object.entries(e.shape))t[n]=l(a);const s={};for(const n of e.indexes)s[n.name]={fields:[...n.fields],unique:n.unique??!1};const i={};for(const n of e.relations)i[n.name]=n.through===void 0?{field:n.field,kind:n.kind,table:n.table}:{kind:n.kind,table:n.table,through:{...n.through}};const r={commitOrdered:e.commitOrdered===!0,fields:f(t),indexes:f(s),memory:e.memory===!0,relations:f(i),shardMode:_(e)};return e.ttl&&(r.ttl=e.ttl.after===void 0?{field:e.ttl.field}:{after:e.ttl.after,field:e.ttl.field}),r},z=(e,t)=>{const s={};for(const r of e.tables)s[r.name]=M(r);const i=[...t].sort();return{jurisdiction:e.jurisdiction,migrationIds:i,tables:f(s),version:E}};class R extends A{constructor(t){super("SCHEMA_SNAPSHOT_PARSE",t,{name:"SchemaSnapshotParseError"})}}const J=e=>{const t=L(e);if(t.status==="invalid")throw new R(t.error);return t.status==="ok"?t.snapshot:void 0},B={build:{allowDrift:!0,updateBaseline:!1},deploy:{allowDrift:!0,updateBaseline:!0},prepare:{allowDrift:!0,updateBaseline:!0},verify:{allowDrift:!0,updateBaseline:!1}},S=" • For backward-compatible changes (e.g. adding an optional field): pass `--allow-schema-drift` to skip the block.",k=" • To accept the new shape without a migration (you know data is compatible): pass `--update-schema-baseline`.",P=e=>{const t=e===void 0?void 0:B[e];if(e===void 0||t===void 0)return`${S}
2
+ ${k}
3
+ `;const s=t.updateBaseline?k:` • To accept the new shape without a migration, run \`lunora prepare --update-schema-baseline\` — \`lunora ${e}\` does not take that flag.`;return`${S}
4
+ ${s}
5
+ `},p=e=>e.map(t=>` - ${t.summary}`).join(`
6
+ `),T=e=>e.remediation==="backfill"&&e.table!==void 0,x=/^[A-Za-z_]\w*$/u,F=e=>` lunora migrate create backfill_${e} --table ${e}`,C=(e,t,s)=>{const i=[...new Set(e.filter(n=>T(n)).map(n=>n.table))],r=[];if(i.length>0){r.push(" • Add a `defineMigration({ id, table, up })` in lunora/ for each affected table, then re-run this command — the baseline is re-blessed on a successful deploy, not by `lunora migrate` itself.\n");const n=i.filter(a=>x.test(a));n.length>0&&r.push(`
7
+ Scaffold the missing migration(s) — the generated \`up\` is an identity placeholder you must fill in:
8
+ ${n.map(a=>F(a)).join(`
9
+ `)}
10
+
11
+ `)}return t.length>0&&r.push(` • Migration(s) ${t.join(", ")} declare a non-literal \`table\`, so codegen cannot tell which table they visit and they cover nothing. Use a string literal.
12
+ `),r.push(P(s)),[`${s??"deploy"} blocked: ${String(e.length)} unresolved breaking schema change(s) since the last blessed schema baseline:`,p(e),"",`To fix:
13
+ ${r.join("")}Docs: https://lunora.dev/docs/migrations`].join(`
14
+ `)},V=e=>{const{allowDrift:t=!1,baseline:s,command:i,current:r,migrations:n}=e,a=I(s,r),u=a.changes.filter(o=>o.severity==="breaking"),b=r.migrationIds.filter(o=>!(s?.migrationIds??[]).includes(o)),m=n.filter(o=>b.includes(o.id)),c=(o,h)=>({blocked:o,changes:a.changes,newMigrationIds:b,reason:h}),w=new Set(m.filter(o=>o.table!=="").map(o=>o.table)),$=m.filter(o=>o.table==="").map(o=>o.id);if(a.changes.length===0||s===void 0)return c(!1,"");if(u.length===0)return c(!1,`schema drift detected (all additive/safe):
15
+ ${p(a.changes)}`);const g=u.filter(o=>!T(o)||!w.has(o.table));if(g.length===0){const o=new Set(u.map(d=>d.table)),h=m.filter(d=>o.has(d.table)).map(d=>d.id);return c(!1,`breaking schema drift detected, covered by ${String(h.length)} new migration(s) (${h.join(", ")}):
16
+ ${p(u)}`)}const y=C(g,$,i);return t?c(!1,`${y}
17
+
18
+ (overridden by --allow-schema-drift)`):c(!0,y)};export{R as SchemaSnapshotParseError,z as buildSchemaSnapshot,V as evaluateSchemaDrift,J as parseSchemaSnapshot};
@@ -1 +1 @@
1
- import"./json-data-Chfs2Cz5.mjs";import{o as i,j as r,s as n,h as o,t as g,k as u,d as F,w as p,m as l,g as d,f,i as k,u as w,l as A,v as Q}from"./shard-runtime-BW1kffN4.mjs";import"./shared-8vTRkL2-.mjs";import"./platform-8oj7iXQy.mjs";export{i as buildDoTypeImports,r as emitAgentFragments,n as emitAgents,o as emitContainerFragments,g as emitContainers,u as emitPaymentFragments,F as emitQueueFragments,p as emitQueues,l as emitQueuesMetadataFragments,d as emitServiceFragments,f as emitTopicFragments,k as emitWorkflowFragments,w as emitWorkflows,A as emitWorkflowsMetadataFragments,Q as queueAliasFindings};
1
+ import"./json-data-Chfs2Cz5.mjs";import{o as i,j as r,s as n,h as o,t as g,k as u,d as F,w as p,m as l,g as d,f,i as k,u as w,l as A,v as Q}from"./shard-runtime-ByYXjCKY.mjs";import"./shared-8vTRkL2-.mjs";import"./platform-8oj7iXQy.mjs";export{i as buildDoTypeImports,r as emitAgentFragments,n as emitAgents,o as emitContainerFragments,g as emitContainers,u as emitPaymentFragments,F as emitQueueFragments,p as emitQueues,l as emitQueuesMetadataFragments,d as emitServiceFragments,f as emitTopicFragments,k as emitWorkflowFragments,w as emitWorkflows,A as emitWorkflowsMetadataFragments,Q as queueAliasFindings};
@@ -1 +1 @@
1
- import"./SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs";import"./isD1GlobalTable-udvHAAzD.mjs";import"./json-data-Chfs2Cz5.mjs";import{e as d}from"./shard-B6afe1Uh.mjs";import"./shard-runtime-BW1kffN4.mjs";import"./shared-8vTRkL2-.mjs";import"./platform-8oj7iXQy.mjs";import"./schema-BgM8A3XV.mjs";export{d as default};
1
+ import"./SCHEMA_SNAPSHOT_VERSION-C7Um0EnM.mjs";import"./isD1GlobalTable-udvHAAzD.mjs";import"./json-data-Chfs2Cz5.mjs";import{e as d}from"./shard-BCqz_05A.mjs";import"./shard-runtime-ByYXjCKY.mjs";import"./shared-8vTRkL2-.mjs";import"./platform-8oj7iXQy.mjs";import"./schema-BgM8A3XV.mjs";export{d as default};
@@ -1,4 +1,4 @@
1
- import{LunoraError as he}from"@lunora/errors";import{serializeSchemaSnapshot as Jt,hashSchemaSnapshot as zt}from"./SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs";import{isHyperdriveGlobalTable as Yt,isD1GlobalTable as Xt}from"./isD1GlobalTable-udvHAAzD.mjs";import{r as Zt}from"./json-data-Chfs2Cz5.mjs";import{r as $,e as er,a as tr,b as rr,c as nr,d as ar,f as sr,g as or,h as ir,i as dr,j as cr,k as lr,l as ur,m as hr,n as pr,o as mr,p as gr,q as fr}from"./shard-runtime-BW1kffN4.mjs";import{u as re,h as br,s as wr,a as yr,I as vr,c as kr,G as Sr,d as Rr}from"./shared-8vTRkL2-.mjs";import{p as xr}from"./platform-8oj7iXQy.mjs";import{i as Ar}from"./schema-BgM8A3XV.mjs";const u=(n,t)=>`((): (() => ${t}) => { let cached: ${t} | undefined; return () => (cached ??= JSON.parse(${JSON.stringify(JSON.stringify(n))}) as ${t}); })()`,pe=["categories","description","facing","level","remediation","title"],Or=n=>{const t={};return{advisoryRows:n.map(a=>{let r=t[a.name];return r||(r=Object.fromEntries(pe.filter(o=>o in a).map(o=>[o,a[o]])),t[a.name]=r),Object.fromEntries(Object.entries(a).filter(([o,d])=>!pe.includes(o)||JSON.stringify(d)!==JSON.stringify(r[o])))}),advisoryRules:t}},Dr=` /**
1
+ import{LunoraError as he}from"@lunora/errors";import{serializeSchemaSnapshot as Jt,hashSchemaSnapshot as Yt}from"./SCHEMA_SNAPSHOT_VERSION-C7Um0EnM.mjs";import{isHyperdriveGlobalTable as zt,isD1GlobalTable as Xt}from"./isD1GlobalTable-udvHAAzD.mjs";import{r as Zt}from"./json-data-Chfs2Cz5.mjs";import{r as $,e as er,a as tr,b as rr,c as nr,d as ar,f as sr,g as or,h as ir,i as dr,j as cr,k as lr,l as ur,m as hr,n as pr,o as mr,p as gr,q as fr}from"./shard-runtime-ByYXjCKY.mjs";import{u as re,h as br,s as wr,a as yr,I as vr,c as kr,G as Sr,d as Rr}from"./shared-8vTRkL2-.mjs";import{p as xr}from"./platform-8oj7iXQy.mjs";import{i as Ar}from"./schema-BgM8A3XV.mjs";const u=(n,t)=>`((): (() => ${t}) => { let cached: ${t} | undefined; return () => (cached ??= JSON.parse(${JSON.stringify(JSON.stringify(n))}) as ${t}); })()`,pe=["categories","description","facing","level","remediation","title"],Or=n=>{const t={};return{advisoryRows:n.map(a=>{let r=t[a.name];return r||(r=Object.fromEntries(pe.filter(o=>o in a).map(o=>[o,a[o]])),t[a.name]=r),Object.fromEntries(Object.entries(a).filter(([o,d])=>!pe.includes(o)||JSON.stringify(d)!==JSON.stringify(r[o])))}),advisoryRules:t}},Dr=` /**
2
2
  * The bare writer every admin/maintenance entry point writes through.
3
3
  *
4
4
  * Admin and maintenance writes go through the SAME reactive-cache hooks as a
@@ -49,19 +49,25 @@ import{LunoraError as he}from"@lunora/errors";import{serializeSchemaSnapshot as
49
49
 
50
50
  ${w()}
51
51
 
52
- return runDataMigration({
53
- ...(args.batchSize === undefined ? {} : { batchSize: args.batchSize }),
54
- ...(args.direction === undefined ? {} : { direction: args.direction }),
55
- ...(args.dryRun === undefined ? {} : { dryRun: args.dryRun }),
56
- ...(args.maxBatches === undefined ? {} : { maxBatches: args.maxBatches }),
57
- migration: migration as unknown as DataMigrationLike,
58
- // Flush after each batch so live migrationStatus subscribers see
59
- // progress mid-run (the base method records the reserved state
60
- // table the raw-SQL progress write is invisible to the tracker).
61
- onBatch: () => this.flushMigrationProgress(),
62
- sql: this.sql as SqlExec,
63
- writer,
64
- });
52
+ try {
53
+ return await runDataMigration({
54
+ ...(args.batchSize === undefined ? {} : { batchSize: args.batchSize }),
55
+ ...(args.direction === undefined ? {} : { direction: args.direction }),
56
+ ...(args.dryRun === undefined ? {} : { dryRun: args.dryRun }),
57
+ ...(args.maxBatches === undefined ? {} : { maxBatches: args.maxBatches }),
58
+ migration: migration as unknown as DataMigrationLike,
59
+ // Flush after each batch so live migrationStatus subscribers see
60
+ // progress mid-run (the base method records the reserved state
61
+ // table the raw-SQL progress write is invisible to the tracker).
62
+ onBatch: () => this.flushMigrationProgress(),
63
+ sql: this.sql as SqlExec,
64
+ writer,
65
+ });
66
+ } finally {
67
+ // The de-dup that unblocks a deferred UNIQUE index runs through here;
68
+ // let the next call rebuild it now instead of after the retry interval.
69
+ this.migrationRetryAt = 0;
70
+ }
65
71
  }
66
72
 
67
73
  protected override async runShardWrite(args: RunShardWriteArgs, headroom?: TransactionHeadroomTracker): Promise<RunShardWriteResult> {
@@ -225,9 +231,9 @@ ${w()}
225
231
  await applyCdcChanges(writer, args.changes);
226
232
 
227
233
  return { applied: args.changes.length };
228
- }`,_r=({actionOnlyBuild:n,actionOnlyFields:t,agentsBuild:e,agentsContextField:a,containersBuild:r,containersContextField:o,databaseOptions:d,everyContextBuild:m,everyContextField:g,facadeBlock:h,globalDatabaseLine:x,hasSensitiveArgs:S=!1,lazyFunctions:f=!1,notifyBuild:c,ormContextField:y,paymentsBuild:M,paymentsContextField:A,queuesBuild:q,queuesContextField:F,topicsBuild:R,topicsContextField:U,vectorsBuild:i,vectorsContextField:v,workflowsBuild:C,workflowsContextField:B})=>{const E=t.length>0,L=y===""?"{ db }":"{ db, orm: bindOrm(facade) }",j=y===""?"":`
234
+ }`,_r=({actionOnlyBuild:n,actionOnlyFields:t,agentsBuild:e,agentsContextField:a,containersBuild:r,containersContextField:o,databaseOptions:d,everyContextBuild:m,everyContextField:g,facadeBlock:h,globalDatabaseLine:x,hasSensitiveArgs:S=!1,lazyFunctions:f=!1,notifyBuild:c,ormContextField:y,paymentsBuild:M,paymentsContextField:A,queuesBuild:q,queuesContextField:F,topicsBuild:R,topicsContextField:U,vectorsBuild:i,vectorsContextField:v,workflowsBuild:E,workflowsContextField:B})=>{const I=t.length>0,C=y===""?"{ db }":"{ db, orm: bindOrm(facade) }",j=y===""?"":`
229
235
  orm: databaseContext.orm,`,W=y===""?"":`
230
- orm: { configurable: true, enumerable: true, value: mutationDatabase.orm, writable: true },`,O=E?`
236
+ orm: { configurable: true, enumerable: true, value: mutationDatabase.orm, writable: true },`,O=I?`
231
237
  // ActionCtx-only helpers (external, non-deterministic I/O): constructed
232
238
  // and attached only for an \`action\` so query/mutation ctx never carry them.
233
239
  if (isAction) {
@@ -261,7 +267,7 @@ ${n.replaceAll(/^(?=.)/gmu," ")}${t.map(p=>` ctx.${p} = ${p};`
261
267
  };
262
268
  })();
263
269
  const { identity, ip, userId } = caller;
264
- ${i}${m}${r}${C}${q}${R}${e}
270
+ ${i}${m}${r}${E}${q}${R}${e}
265
271
  // Which dispatch this ctx belongs to. Drives the two deferral facades
266
272
  // below and the \`ctx.run*\` caller guard; a ctx built for an
267
273
  // admin/lifecycle path has no registered function, and so no kind. An
@@ -376,7 +382,7 @@ ${x} // \`ctx.db\`, wrapped in automatic instrumentation: by default
376
382
  // mutation must rebuild its DB and table/ORM views with its own queue.
377
383
  const makeDatabaseContext = (scheduler: SchedulerLike) => {
378
384
  const db: DatabaseWriterLike = this.instrumentDb(createShardCtxDb(${d}), logFunctionPath, traceAnchor, observability, options.sensitive);
379
- ${h} return ${L};
385
+ ${h} return ${C};
380
386
  };
381
387
  const databaseContext = makeDatabaseContext(scheduler);
382
388
  const db = databaseContext.db;
@@ -446,7 +452,7 @@ ${c}
446
452
  trace,${v}${g}${A}${o}${B}${F}${U}${a}${S?`
447
453
  [Symbol.for("lunora.admitSensitiveArgs")]: (args: Record<string, unknown>, names: ReadonlySet<string>): void => this.admitSensitiveValues(options.sensitive, args, names),`:""}
448
454
  };
449
- ${E?` const isAction = contextKind === "action";
455
+ ${I?` const isAction = contextKind === "action";
450
456
  `:""}${O}
451
457
  ${f?` const captureScope = (): (() => void) => {
452
458
  const requestScope = this.captureRequestScope();
@@ -621,7 +627,7 @@ const dispatchRun = async (
621
627
  } finally {
622
628
  runDepth -= 1;
623
629
  }
624
- };`,Cr=n=>n?me.replace(" runTransactional?: (work: () => Promise<unknown>) => Promise<unknown>,",` runTransactional?: (work: () => Promise<unknown>) => Promise<unknown>,
630
+ };`,Er=n=>n?me.replace(" runTransactional?: (work: () => Promise<unknown>) => Promise<unknown>,",` runTransactional?: (work: () => Promise<unknown>) => Promise<unknown>,
625
631
  captureScope?: () => () => void,`).replace(` try {
626
632
  // A mutation composed from an action`,` try {
627
633
  let loaded = getLoadedFunction(functionPath);
@@ -642,7 +648,7 @@ const dispatchRun = async (
642
648
 
643
649
  const loadedFunction = loaded;
644
650
 
645
- // A mutation composed from an action`).replaceAll("registered.handler","loadedFunction.handler"):me,Er=` public override async handleRpc(functionPath: string, args: Record<string, unknown>, headroom?: TransactionHeadroomTracker, scope?: QueryReadScope, bookmarks?: DispatchBookmark, sensitive?: SensitiveScope): Promise<unknown> {
651
+ // A mutation composed from an action`).replaceAll("registered.handler","loadedFunction.handler"):me,Ir=` public override async handleRpc(functionPath: string, args: Record<string, unknown>, headroom?: TransactionHeadroomTracker, scope?: QueryReadScope, bookmarks?: DispatchBookmark, sensitive?: SensitiveScope): Promise<unknown> {
646
652
  // A dispatch that did not come through the shard's \`/rpc\` (a scheduled call,
647
653
  // a lifecycle hook, an admin run) has no scope of its own, so it opens one here
648
654
  // and releases it when the handler settles.
@@ -666,7 +672,7 @@ __PREPARE_FUNCTION__ const registered = LUNORA_FUNCTIONS[functionPath
666
672
  throw new LunoraError("FUNCTION_NOT_FOUND", \`function not registered: \${functionPath}\`);
667
673
  }
668
674
 
669
- this.ensureMigrated();
675
+ this.ensureServable();
670
676
 
671
677
  // \`headroom\`, when the caller supplied one, is threaded straight
672
678
  // through to \`buildCtx\` — bypassing its \`this.transactionHeadroom()\`
@@ -839,14 +845,14 @@ __COMMITTED_CATCH__ } finally {
839
845
  // \`ctx.scheduler\` call that reached the buffer in the first place.
840
846
  protected override scheduleOutboxScheduler(): SchedulerLike | undefined {
841
847
  return config.scheduler?.((this.env ?? {}) as Record<string, unknown>) as SchedulerLike | undefined;
842
- }`,Lr=` protected override async executeSubscription(functionPath: string, args: Record<string, unknown>, identity?: SubscriptionIdentity): Promise<{ ranges?: Map<string, KeyRange[]>; result: unknown; tables: Set<string> } | null> {
848
+ }`,Cr=` protected override async executeSubscription(functionPath: string, args: Record<string, unknown>, identity?: SubscriptionIdentity): Promise<{ ranges?: Map<string, KeyRange[]>; result: unknown; tables: Set<string> } | null> {
843
849
  const registered = LUNORA_FUNCTIONS[functionPath];
844
850
 
845
851
  if (!registered || registered.kind !== "query" || registered.visibility === "internal") {
846
852
  return null;
847
853
  }
848
854
 
849
- __PREPARE_FUNCTION__ this.ensureMigrated();
855
+ __PREPARE_FUNCTION__ this.ensureServable();
850
856
 
851
857
  const footprint = createReadFootprint();
852
858
  // Identity is threaded EXPLICITLY from the (deferred/interleaved)
@@ -869,7 +875,7 @@ __PREPARE_FUNCTION__ this.ensureMigrated();
869
875
  return null;
870
876
  }
871
877
 
872
- this.ensureMigrated();
878
+ this.ensureServable();
873
879
 
874
880
  return {
875
881
  ...(registered.durable ? { durable: registered.durable as { ttlMs?: number } } : {}),
@@ -880,7 +886,7 @@ __PREPARE_FUNCTION__ this.ensureMigrated();
880
886
  // \`ctx.auth\` stream as nobody — or as a concurrent RPC's caller.
881
887
  iterator: (signal) => (registered.handler as (context: unknown, args: Record<string, unknown>, signal: AbortSignal) => AsyncIterable<unknown>)(this.buildCtx({ functionPath, identity }), args, signal),
882
888
  };
883
- }`,Ir=` } catch (error) {
889
+ }`,Lr=` } catch (error) {
884
890
  // The write committed before this failed. Mark the error so the caller can tell
885
891
  // a durable write from a rollback: the rethrow still reaches the caller unchanged.
886
892
  if (typeof error === "object" && error !== null) {
@@ -905,7 +911,7 @@ __PREPARE_FUNCTION__ this.ensureMigrated();
905
911
  }
906
912
  }
907
913
 
908
- `:"";return Er.replace("__COMMITTED_CATCH__",n?Ir:"").replace("__PREPARE_FUNCTION__",`${e}${a}`)},Nr=n=>{const t={};for(const e of n.tables){const a={};for(const[r,o]of Object.entries(e.shape)){const d=re(o);d.kind==="id"&&d.tableName!==void 0&&(a[r]=d.tableName)}Object.keys(a).length>0&&(t[e.name]=a)}return t},$r=n=>{const t={};for(const e of n.tables){const a=[];for(const[r,o]of Object.entries(e.shape))re(o).kind==="storage"&&a.push(r);a.length>0&&(t[e.name]=a)}return t},Mr=n=>{const t={};for(const e of n.tables){const a=[...e.indexes.map(r=>({fields:[...r.fields],name:r.name,type:"index",...r.unique===!0?{unique:!0}:{}})),...e.searchIndexes.map(r=>({fields:[r.field,...r.filterFields??[]],name:r.name,type:"search"})),...(e.geoIndexes??[]).map(r=>({fields:[r.field],name:r.name,type:"geo"})),...e.rankIndexes.map(r=>({fields:r.sortBy.map(o=>o.field),name:r.name,type:"rank"})),...e.vectorIndexes.map(r=>({fields:r.field===void 0?[]:[r.field],name:r.name,type:"vector"}))];a.length>0&&(t[e.name]=a)}return t},qr=n=>{const t=[];for(const e of n.tables)!e.ttl||e.shardMode==="global"||t.push({...e.ttl.after===void 0?{}:{after:e.ttl.after},field:e.ttl.field,...e.softDelete?{softDeleteField:e.softDelete.field}:{},table:e.name});return t},Fr=n=>{if(n.kind!=="union"||n.members===void 0||n.members.length===0)return;const t=[];for(const e of n.members){if(e.kind!=="literal"||e.literalValue===void 0)return;try{const a=JSON.parse(e.literalValue);if(typeof a!="string")return;t.push(a)}catch{return}}return t},Ur=(n,t,e)=>{const a=re(t),r={name:n,optional:br(t),type:a.kind};if(a.kind==="id"&&a.tableName!==void 0){r.ref=a.tableName;const d=e.get(n);d!==void 0&&(r.onDelete=d)}a.kind==="storage"&&(r.isStorage=!0,a.bucket!==void 0&&(r.bucket=a.bucket));const o=Fr(a);return o!==void 0&&(r.enumValues=o),a.column?.notNull===!1&&(r.nullable=!0),r},Br=n=>{const t={};for(const e of n.tables){const a=[{name:"_id",optional:!1,pk:!0,type:"id"},{name:"_creationTime",optional:!1,type:"number"},...e.commitOrdered===!0?[{name:"_commitSeq",optional:!1,type:"number"}]:[]],r=new Map(e.relations.flatMap(o=>o.kind==="one"?[[o.field,o.onDelete]]:[]));for(const[o,d]of Object.entries(e.shape))a.push(Ur(o,d,r));t[e.name]=a}return t},jr=({hasMutators:n,hasSensitiveShapes:t,hasShapes:e,rlsData:a})=>{const r="{ columns?: readonly string[]; effectiveWhere?: WhereInput; global?: boolean; table: string } | undefined",o=t?` protected override resolveShape(name: string, args: Record<string, unknown>, identity?: SubscriptionIdentity): ${r} {
914
+ `:"";return Ir.replace("__COMMITTED_CATCH__",n?Lr:"").replace("__PREPARE_FUNCTION__",`${e}${a}`)},Nr=n=>{const t={};for(const e of n.tables){const a={};for(const[r,o]of Object.entries(e.shape)){const d=re(o);d.kind==="id"&&d.tableName!==void 0&&(a[r]=d.tableName)}Object.keys(a).length>0&&(t[e.name]=a)}return t},$r=n=>{const t={};for(const e of n.tables){const a=[];for(const[r,o]of Object.entries(e.shape))re(o).kind==="storage"&&a.push(r);a.length>0&&(t[e.name]=a)}return t},Mr=n=>{const t={};for(const e of n.tables){const a=[...e.indexes.map(r=>({fields:[...r.fields],name:r.name,type:"index",...r.unique===!0?{unique:!0}:{}})),...e.searchIndexes.map(r=>({fields:[r.field,...r.filterFields??[]],name:r.name,type:"search"})),...(e.geoIndexes??[]).map(r=>({fields:[r.field],name:r.name,type:"geo"})),...e.rankIndexes.map(r=>({fields:r.sortBy.map(o=>o.field),name:r.name,type:"rank"})),...e.vectorIndexes.map(r=>({fields:r.field===void 0?[]:[r.field],name:r.name,type:"vector"}))];a.length>0&&(t[e.name]=a)}return t},qr=n=>{const t=[];for(const e of n.tables)!e.ttl||e.shardMode==="global"||t.push({...e.ttl.after===void 0?{}:{after:e.ttl.after},field:e.ttl.field,...e.softDelete?{softDeleteField:e.softDelete.field}:{},table:e.name});return t},Fr=n=>{if(n.kind!=="union"||n.members===void 0||n.members.length===0)return;const t=[];for(const e of n.members){if(e.kind!=="literal"||e.literalValue===void 0)return;try{const a=JSON.parse(e.literalValue);if(typeof a!="string")return;t.push(a)}catch{return}}return t},Ur=(n,t,e)=>{const a=re(t),r={name:n,optional:br(t),type:a.kind};if(a.kind==="id"&&a.tableName!==void 0){r.ref=a.tableName;const d=e.get(n);d!==void 0&&(r.onDelete=d)}a.kind==="storage"&&(r.isStorage=!0,a.bucket!==void 0&&(r.bucket=a.bucket));const o=Fr(a);return o!==void 0&&(r.enumValues=o),a.column?.notNull===!1&&(r.nullable=!0),r},Br=n=>{const t={};for(const e of n.tables){const a=[{name:"_id",optional:!1,pk:!0,type:"id"},{name:"_creationTime",optional:!1,type:"number"},...e.commitOrdered===!0?[{name:"_commitSeq",optional:!1,type:"number"}]:[]],r=new Map(e.relations.flatMap(o=>o.kind==="one"?[[o.field,o.onDelete]]:[]));for(const[o,d]of Object.entries(e.shape))a.push(Ur(o,d,r));t[e.name]=a}return t},jr=({hasMutators:n,hasSensitiveShapes:t,hasShapes:e,rlsData:a})=>{const r="{ columns?: readonly string[]; effectiveWhere?: WhereInput; global?: boolean; table: string } | undefined",o=t?` protected override resolveShape(name: string, args: Record<string, unknown>, identity?: SubscriptionIdentity): ${r} {
909
915
  const sensitive = this.openSensitiveScope(\`__shape__:\${name}\`, args);
910
916
 
911
917
  try {
@@ -925,7 +931,7 @@ ${o}
925
931
  return undefined;
926
932
  }
927
933
 
928
- this.ensureMigrated();
934
+ this.ensureServable();
929
935
 
930
936
  // Trusted ctx from the socket's OWN verified identity — the client
931
937
  // supplies only the shape name + args; \`compileWhere\` validates the
@@ -1250,10 +1256,10 @@ ${o} const vectors = createContextVectors(lunora${g});
1250
1256
  ordered: async (read, work) => this.runOrderedAfterWrites(read, work),
1251
1257
  });
1252
1258
  }
1253
- `:"",vectorsBuild:h,vectorsStub:r}},on=({advisories:n=[],advisorProcedures:t=[],agents:e=[],capabilities:a=new Set,containers:r=[],env:o,flagKeys:d=[],hasFlags:m=!1,hasNotify:g=!1,hasRooms:h=!1,hasSecretValues:x=!1,hasSensitiveArgs:S=!1,hasSockets:f=!1,lazyFunctions:c=!1,hasVectors:y=!0,liveStreamDeclarations:M=[],liveStreams:A=!1,maskMetadata:q,mutators:F=[],queues:R=[],rlsMetadata:U,schema:i,schemaSnapshot:v,shapes:C=[],storageRules:B,studioFeatures:E,services:L=[],topics:j=[],useUmbrella:W=!1,workflows:O=[]})=>{const l=Rr(W),H=F.length>0,p=C.length>0,D=C.some(s=>wr(s.args).length>0),V=S||D,ge=v===void 0?"":Jt(v),fe=v===void 0?"":`
1259
+ `:"",vectorsBuild:h,vectorsStub:r}},on=({advisories:n=[],advisorProcedures:t=[],agents:e=[],capabilities:a=new Set,containers:r=[],env:o,flagKeys:d=[],hasFlags:m=!1,hasNotify:g=!1,hasRooms:h=!1,hasSecretValues:x=!1,hasSensitiveArgs:S=!1,hasSockets:f=!1,lazyFunctions:c=!1,hasVectors:y=!0,liveStreamDeclarations:M=[],liveStreams:A=!1,maskMetadata:q,mutators:F=[],queues:R=[],rlsMetadata:U,schema:i,schemaSnapshot:v,shapes:E=[],storageRules:B,studioFeatures:I,services:C=[],topics:j=[],useUmbrella:W=!1,workflows:O=[]})=>{const l=Rr(W),H=F.length>0,p=E.length>0,D=E.some(s=>wr(s.args).length>0),V=S||D,ge=v===void 0?"":Jt(v),fe=v===void 0?"":`
1254
1260
  /** Structural schema snapshot + its content hash, recorded in the shard's \`__lunora_schema_history\` ledger on cold start so the studio can show a schema-version timeline and diff any two versions. */
1255
- const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(zt(v))}, json: ${JSON.stringify(ge)} };
1256
- `,be=v===void 0?"":", schemaSnapshot: LUNORA_SCHEMA_SNAPSHOT",k=er(a),I=tr(m,l.flags),K=rr(d,m,l.flags),G=fr(g),Q=nr(o),{build:we,contextField:ye,importLines:ve,specs:ke}=ar(xr(R)),{build:Se,contextField:Re,importLines:xe,specs:Ae}=sr(j,R),J=or(L,l.server),{build:Oe,contextField:De,importLines:Te,specs:_e}=ir(r,i.jurisdiction),{build:Ce,contextField:Ee,importLines:Le,specs:Ie}=dr(O),{build:Pe,contextField:Ne,importLines:$e,specs:Me}=cr(e,x&&e.length>0),{build:qe,configField:Fe,contextField:Ue,imports:Be,stub:je}=lr(a.has("payments")),We=n,{advisoryRules:He,advisoryRows:Ve}=Or(We),Ke=t,ne=U??{policies:[],roles:[]},Ge=q??{columns:[]},Qe=B??{rules:[]},Je=E??{analytics:!1,auth:!1,containers:!1,flags:!1,kv:!1,mail:!1,notifications:!1,payments:!1,privacy:!1,queues:!1,scheduler:!1,storage:!1,vectors:!1,workflows:!1},{constant:ze,override:Ye}=ur(O),{constant:Xe,override:Ze}=hr(R),b=y&&i.vectorIndexes.length>0,z=new Set(i.tables.filter(s=>Ar(s)).map(s=>s.name)),ae=b&&i.vectorIndexes.some(s=>z.has(s.table)),T=i.tables.some(s=>s.shardMode==="global"),Y=pr(z),X=i.tables.some(s=>Yt(s)),se=i.tables.some(s=>Xt(s)),P=i.tables.some(s=>s.externalSource!==void 0),oe=i.tables.some(s=>s.memory===!0),Z=i.tables.some(s=>s.shardMode!=="global"&&s.searchIndexes.length>0);if(se&&X)throw new he("INTERNAL",'lunora codegen: mixing `.global()` (D1) and `.global({ backend: "hyperdrive" })` tables in one app is not supported yet — use a single global backend.');const ee=i.tables.length>0,et=Nr(i),tt=Mr(i),rt=Br(i),nt=$r(i),ie=qr(i),te=mr(b,O.length>0,R.length>0,m,Z);p&&te.push("WhereInput"),D&&te.push("SensitiveScope");const de=gr(T),{customMutatorOverride:at,shapeGuardImport:st,shapeReadPolicyAssertion:ot,shapeReadPolicyImport:it,shapeResolveOverride:dt}=jr({hasMutators:H,hasSensitiveShapes:D,hasShapes:p,rlsData:ne}),_=A?M:[];for(const s of _)if(yr(s.exportName,"live stream export name"),!vr.test(s.filePath))throw new he("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe live stream file path: ${JSON.stringify(s.filePath)}`);const ct=c?[]:_.map(s=>`import { ${s.exportName} as liveStream_${s.exportName} } from "../${s.filePath}.js";`),lt=` protected override liveStreams() {
1261
+ const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(Yt(v))}, json: ${JSON.stringify(ge)} };
1262
+ `,be=v===void 0?"":", schemaSnapshot: LUNORA_SCHEMA_SNAPSHOT",k=er(a),L=tr(m,l.flags),K=rr(d,m,l.flags),G=fr(g),Q=nr(o),{build:we,contextField:ye,importLines:ve,specs:ke}=ar(xr(R)),{build:Se,contextField:Re,importLines:xe,specs:Ae}=sr(j,R),J=or(C,l.server),{build:Oe,contextField:De,importLines:Te,specs:_e}=ir(r,i.jurisdiction),{build:Ee,contextField:Ie,importLines:Ce,specs:Le}=dr(O),{build:Pe,contextField:Ne,importLines:$e,specs:Me}=cr(e,x&&e.length>0),{build:qe,configField:Fe,contextField:Ue,imports:Be,stub:je}=lr(a.has("payments")),We=n,{advisoryRules:He,advisoryRows:Ve}=Or(We),Ke=t,ne=U??{policies:[],roles:[]},Ge=q??{columns:[]},Qe=B??{rules:[]},Je=I??{analytics:!1,auth:!1,containers:!1,flags:!1,kv:!1,mail:!1,notifications:!1,payments:!1,privacy:!1,queues:!1,scheduler:!1,storage:!1,vectors:!1,workflows:!1},{constant:Ye,override:ze}=ur(O),{constant:Xe,override:Ze}=hr(R),b=y&&i.vectorIndexes.length>0,Y=new Set(i.tables.filter(s=>Ar(s)).map(s=>s.name)),ae=b&&i.vectorIndexes.some(s=>Y.has(s.table)),T=i.tables.some(s=>s.shardMode==="global"),z=pr(Y),X=i.tables.some(s=>zt(s)),se=i.tables.some(s=>Xt(s)),P=i.tables.some(s=>s.externalSource!==void 0),oe=i.tables.some(s=>s.memory===!0),Z=i.tables.some(s=>s.shardMode!=="global"&&s.searchIndexes.length>0);if(se&&X)throw new he("INTERNAL",'lunora codegen: mixing `.global()` (D1) and `.global({ backend: "hyperdrive" })` tables in one app is not supported yet — use a single global backend.');const ee=i.tables.length>0,et=Nr(i),tt=Mr(i),rt=Br(i),nt=$r(i),ie=qr(i),te=mr(b,O.length>0,R.length>0,m,Z);p&&te.push("WhereInput"),D&&te.push("SensitiveScope");const de=gr(T),{customMutatorOverride:at,shapeGuardImport:st,shapeReadPolicyAssertion:ot,shapeReadPolicyImport:it,shapeResolveOverride:dt}=jr({hasMutators:H,hasSensitiveShapes:D,hasShapes:p,rlsData:ne}),_=A?M:[];for(const s of _)if(yr(s.exportName,"live stream export name"),!vr.test(s.filePath))throw new he("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe live stream file path: ${JSON.stringify(s.filePath)}`);const ct=c?[]:_.map(s=>`import { ${s.exportName} as liveStream_${s.exportName} } from "../${s.filePath}.js";`),lt=` protected override liveStreams() {
1257
1263
  return { ${_.map(s=>`${kr(s.id)}: liveStream_${s.exportName}`).join(", ")} };
1258
1264
  }
1259
1265
  `,ut=` private readonly liveStreamLoaders = new Map<string, () => Promise<{ validatePublish: (topic: string, payload: unknown) => unknown }>>([
@@ -1278,11 +1284,11 @@ ${_.map(s=>` [${JSON.stringify(s.id)}, () => import("../${s.filePath}
1278
1284
  protected override liveStreams() {
1279
1285
  return Object.fromEntries(this.loadedLiveStreams);
1280
1286
  }
1281
- `;let ce="";_.length>0&&(ce=c?ut:lt);const N=[`import type { ${te.join(", ")} } from "${l.do}";`,`import { applyCdcChanges, createStableIdFactory, ${Z?"backfillSearchIndexes, ":""}${b?"backfillVectorIndexes, ":""}buildReprojectionMigration, ${oe?"clearMemoryTables, ":""}${st}createReadFootprint, createShardCtxDb, exportShardRows, importShardRows, ${P?"isSourceDue, pullExternalSourceIncrementalTick, pullExternalSourceTick, ":""}markUnvouchableReads, ${ae?"ROOT_SHARD_NAME, ":""}runDataMigration, runShardMigrations, ${de.importFragment}ShardDO as ShardDOBase } from "${l.do}";`,...P?[`import type { ExternalSourceLike, SourceClientLike, TraceRefLike } from "${l.do}";`]:[],p?`import { asBucketStorage, ${it}beginDeferredDeletes, beginDeferredSchedules, composeShapeReadWhere, createSecrets, flushDeferredDeletes, LunoraError, withDeferredDeletes, withDeferredSchedules } from "${l.server}";`:`import { asBucketStorage, beginDeferredDeletes, beginDeferredSchedules, createSecrets, flushDeferredDeletes, LunoraError, withDeferredDeletes, withDeferredSchedules } from "${l.server}";`];ee&&N.push(`import { bindOrm, bindTableFacade } from "${l.server}";`),b&&N.push('import type { SchemaLike as VectorSchemaLike, VectorBackfillSync, VectorizeIndexLike, VectorSearchLike } from "@lunora/bindings/vectors";','import { createContextVectors, createVectorBackfillSync, createVectors, createVectorSyncHook, vectorBackfillTargets } from "@lunora/bindings/vectors";'),N.push(...k.importLines,...I.importLines,...G.importLines,...Q.importLines,...Te,...Le,...ve,...xe,...J.importLines,...$e,...Be,...V?[`import { sensitiveArgumentNames } from "${l.values}";`]:[],"",'import schema from "../schema.js";',...ct,`import { ${["LUNORA_FUNCTIONS","LUNORA_LIFECYCLE_HOOKS","LUNORA_MIGRATIONS",...c?["getLoadedFunction","loadFunction"]:[],...H?["LUNORA_MUTATOR_PATHS"]:[],...h?["LUNORA_ROOMS"]:[],...f?["LUNORA_SOCKETS"]:[],...p?["LUNORA_SHAPES"]:[]].join(", ")} } from "./functions.js";`);const ht=b?`
1287
+ `;let ce="";_.length>0&&(ce=c?ut:lt);const N=[`import type { ${te.join(", ")} } from "${l.do}";`,`import { applyCdcChanges, createStableIdFactory, ${Z?"backfillSearchIndexes, ":""}${b?"backfillVectorIndexes, ":""}buildReprojectionMigration, ${oe?"clearMemoryTables, ":""}${st}createReadFootprint, createShardCtxDb, exportShardRows, importShardRows, ${P?"isSourceDue, pullExternalSourceIncrementalTick, pullExternalSourceTick, ":""}markUnvouchableReads, ${ae?"ROOT_SHARD_NAME, ":""}runDataMigration, runShardMigrations, ${de.importFragment}ShardDO as ShardDOBase } from "${l.do}";`,...P?[`import type { ExternalSourceLike, SourceClientLike, TraceRefLike } from "${l.do}";`]:[],p?`import { asBucketStorage, ${it}beginDeferredDeletes, beginDeferredSchedules, composeShapeReadWhere, createSecrets, flushDeferredDeletes, LunoraError, withDeferredDeletes, withDeferredSchedules } from "${l.server}";`:`import { asBucketStorage, beginDeferredDeletes, beginDeferredSchedules, createSecrets, flushDeferredDeletes, LunoraError, withDeferredDeletes, withDeferredSchedules } from "${l.server}";`];ee&&N.push(`import { bindOrm, bindTableFacade } from "${l.server}";`),b&&N.push('import type { SchemaLike as VectorSchemaLike, VectorBackfillSync, VectorizeIndexLike, VectorSearchLike } from "@lunora/bindings/vectors";','import { createContextVectors, createVectorBackfillSync, createVectors, createVectorSyncHook, vectorBackfillTargets } from "@lunora/bindings/vectors";'),N.push(...k.importLines,...L.importLines,...G.importLines,...Q.importLines,...Te,...Ce,...ve,...xe,...J.importLines,...$e,...Be,...V?[`import { sensitiveArgumentNames } from "${l.values}";`]:[],"",'import schema from "../schema.js";',...ct,`import { ${["LUNORA_FUNCTIONS","LUNORA_LIFECYCLE_HOOKS","LUNORA_MIGRATIONS",...c?["getLoadedFunction","loadFunction"]:[],...H?["LUNORA_MUTATOR_PATHS"]:[],...h?["LUNORA_ROOMS"]:[],...f?["LUNORA_SOCKETS"]:[],...p?["LUNORA_SHAPES"]:[]].join(", ")} } from "./functions.js";`);const ht=b?`
1282
1288
  vectors?: (env: Record<string, unknown>) => Record<string, VectorizeIndexLike>;`:"",pt=se?`
1283
1289
  d1?: (env: Record<string, unknown>, request?: { bookmark?: string; cdc?: boolean; cdcRetentionMs?: number; identity?: Record<string, unknown>; onBookmark?: (bookmark: string | undefined) => void; userId?: string }) => DatabaseWriterLike | undefined;`:"",mt=X?`
1284
1290
  hyperdriveGlobal?: (env: Record<string, unknown>, request?: { cdc?: boolean; cdcRetentionMs?: number; identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",gt=P?`
1285
- sourceClient?: (env: Record<string, unknown>, binding: string) => { query: <Row = Record<string, unknown>>(text: string, params?: readonly unknown[]) => Promise<Row[]> } | undefined;`:"",ft="ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().",bt="ctx.scheduler: no scheduler configured. Pass `scheduler` to createShardDO().",wt="ctx.storage: no storage configured. Pass `storage` to createShardDO().",yt=T?$("globalDbStub: DatabaseWriterLike",ft,["aggregate","count","delete","explain","findFirst","findFirstOrThrow","findMany","get","groupBy","insert","normalizeId","patch","query","rank","rankPage","replace"],{sync:["normalizeId","query"]}):"",{vectorSyncMethod:vt,vectorsBuild:kt,vectorsStub:St}=Vr(b,ae?i.vectorIndexes.filter(s=>z.has(s.table)).map(s=>s.name):[]),Rt=`{
1291
+ sourceClient?: (env: Record<string, unknown>, binding: string) => { query: <Row = Record<string, unknown>>(text: string, params?: readonly unknown[]) => Promise<Row[]> } | undefined;`:"",ft="ctx.db.<globalTable>: no global backend configured. Pass `d1` or `hyperdriveGlobal` to createShardDO().",bt="ctx.scheduler: no scheduler configured. Pass `scheduler` to createShardDO().",wt="ctx.storage: no storage configured. Pass `storage` to createShardDO().",yt=T?$("globalDbStub: DatabaseWriterLike",ft,["aggregate","count","delete","explain","findFirst","findFirstOrThrow","findMany","get","groupBy","insert","normalizeId","patch","query","rank","rankPage","replace"],{sync:["normalizeId","query"]}):"",{vectorSyncMethod:vt,vectorsBuild:kt,vectorsStub:St}=Vr(b,ae?i.vectorIndexes.filter(s=>Y.has(s.table)).map(s=>s.name):[]),Rt=`{
1286
1292
  ...this.ctxDbTuning(),
1287
1293
  auth: { identity: identity ?? null, userId: userId ?? null },
1288
1294
  broadcast: (delta) => {
@@ -1354,13 +1360,52 @@ ${_.map(s=>` [${JSON.stringify(s.id)}, () => import("../${s.filePath}
1354
1360
  `:"",_t=f?` protected override socketRoute(path: string): { auth: boolean; functionPath: string } | undefined {
1355
1361
  return LUNORA_SOCKETS[path];
1356
1362
  }
1357
- `:"",{externalSourceOverride:Ct,sourceBootstrap:Et,sourceClientCacheConst:Lt}=Hr(P),It=`
1363
+ `:"",{externalSourceOverride:Et,sourceBootstrap:It,sourceClientCacheConst:Ct}=Hr(P),Lt=`
1364
+ private shardInitDeferred = false;
1365
+ private deferredShardInit?: Promise<void>;
1366
+
1358
1367
  protected override async runShardInit(): Promise<void> {
1359
1368
  this.ensureMigrated();
1360
1369
  ${oe?` clearMemoryTables(this.sql as SqlExec, schema as unknown as SchemaLike);
1361
1370
  `:""}
1371
+ if (this.blockedUniqueIndexes.length > 0) {
1372
+ this.shardInitDeferred = true;
1373
+
1374
+ return;
1375
+ }
1376
+
1362
1377
  await this.dispatchShardInit();
1363
1378
  }
1379
+
1380
+ protected override async ensureShardInit(): Promise<void> {
1381
+ await super.ensureShardInit();
1382
+
1383
+ if (!this.shardInitDeferred) {
1384
+ return;
1385
+ }
1386
+
1387
+ try {
1388
+ this.ensureMigrated();
1389
+ } catch (error: unknown) {
1390
+ this.recordShardInitError("__shard_init__", error);
1391
+
1392
+ return;
1393
+ }
1394
+
1395
+ if (this.blockedUniqueIndexes.length > 0) {
1396
+ return;
1397
+ }
1398
+
1399
+ this.deferredShardInit ??= (async (): Promise<void> => {
1400
+ try {
1401
+ await this.dispatchShardInit();
1402
+ } finally {
1403
+ this.shardInitDeferred = false;
1404
+ }
1405
+ })();
1406
+
1407
+ await this.deferredShardInit;
1408
+ }
1364
1409
  `,Pt=ie.length>0?`
1365
1410
  if (LUNORA_TTL_SWEEPS.length > 0) {
1366
1411
  void this.scheduleTtlSweep();
@@ -1382,7 +1427,7 @@ ${oe?` clearMemoryTables(this.sql as SqlExec, schema as unknown as Sc
1382
1427
  // exists — a trigger that fails first still flushes and fuses.
1383
1428
  ...(config.observability === undefined ? {} : { telemetrySink: () => config.observability?.((env ?? {}) as Record<string, unknown>) }),
1384
1429
  });
1385
- ${Et}${Pt} }
1430
+ ${It}${Pt} }
1386
1431
 
1387
1432
  protected override isCacheableQuery(functionPath: string): boolean {
1388
1433
  // NOT \`kind === "query"\` alone. A cache hit answers without running
@@ -1437,22 +1482,22 @@ ${Et}${Pt} }
1437
1482
  return new Set([...registered.sensitiveArgs, ...fromValidators]);
1438
1483
  }
1439
1484
 
1440
- `:"",qt=Cr(c),Ft=c?` const preparation = this.prepareFunction(functionPath, "subscription");
1485
+ `:"",qt=Er(c),Ft=c?` const preparation = this.prepareFunction(functionPath, "subscription");
1441
1486
  if (preparation !== undefined) await preparation;
1442
- `:"",Ut=Lr.replace("__PREPARE_FUNCTION__",Ft),Bt=Pr(h,c),jt=ee?`
1487
+ `:"",Ut=Cr.replace("__PREPARE_FUNCTION__",Ft),Bt=Pr(h,c),jt=ee?`
1443
1488
  const facade = db as unknown as Record<string, ReturnType<typeof bindTableFacade>>;
1444
1489
  ${i.tables.map(s=>` facade[${JSON.stringify(s.name)}] = bindTableFacade(db, ${JSON.stringify(s.name)});`).join(`
1445
1490
  `)}
1446
- `:"",Wt=`${k.everyBuild}${I.build}${Q.build}
1491
+ `:"",Wt=`${k.everyBuild}${L.build}${Q.build}
1447
1492
  const secrets = createSecrets(env);
1448
- `,Ht=`${k.everyFields}${I.contextField}${G.contextField}${Q.contextField}
1493
+ `,Ht=`${k.everyFields}${L.contextField}${G.contextField}${Q.contextField}
1449
1494
  secrets,`,Vt=G.build,Kt=A?`
1450
1495
  const live = {
1451
1496
  publish: async (ref: { __lunoraLive: string; topic: string }, payload: unknown, publishOptions?: { shardKey?: string }): Promise<void> => {
1452
1497
  await this.publishLiveFromAction(ref.topic, payload, { ...publishOptions, stream: ref.__lunoraLive });
1453
1498
  },
1454
1499
  };
1455
- `:"",Gt=[...k.actionFields,...L.length>0?["services"]:[],...A?["live"]:[]],Qt=`${k.actionBuild}${J.build}${Kt}`;return`${Sr}${N.join(`
1500
+ `:"",Gt=[...k.actionFields,...C.length>0?["services"]:[],...A?["live"]:[]],Qt=`${k.actionBuild}${J.build}${Kt}`;return`${Sr}${N.join(`
1456
1501
  `)}
1457
1502
 
1458
1503
  type FunctionKind = "action" | "mutation" | "query";
@@ -1515,7 +1560,10 @@ const LUNORA_STORAGE_RULES = ${u(Qe,"StorageRulesResult")};
1515
1560
 
1516
1561
  /** Which optional package-backed features this app wires up (discovered from imports / \`ctx.*\` reads / schema signals) served via \`__lunora_admin__:studioFeatures\` so the studio hides nav pages whose package isn't enabled. */
1517
1562
  const LUNORA_STUDIO_FEATURES = ${u(Je,"StudioFeaturesResult")};
1518
- ${fe}${Y.constant}${K.constant}${ze}${Xe}${_e}${Ie}${ke}${Ae}${J.specs}${Me}
1563
+
1564
+ /** How long a shard with a UNIQUE index blocked by duplicate rows serves the cached diagnostic before re-attempting the build. */
1565
+ const BLOCKED_MIGRATION_RETRY_MS = 5000;
1566
+ ${fe}${z.constant}${K.constant}${Ye}${Xe}${_e}${Le}${ke}${Ae}${J.specs}${Me}
1519
1567
  export interface ShardDOConfig {
1520
1568
  /** Opt into change-data-capture: records a post-image to \`__cdc_log\` on every write (backs streaming export + replay-PITR). */
1521
1569
  cdc?: boolean;
@@ -1532,9 +1580,9 @@ export interface ShardDOConfig {
1532
1580
  /** \`unknown\` because \`@lunora/scheduler\`'s \`Scheduler\` is not assignable to \`SchedulerLike\`; the shard casts it. */
1533
1581
  scheduler?: (env: Record<string, unknown>) => unknown;
1534
1582
  /** \`origin\` is the origin the current \`/rpc\` request reached the worker on — the fallback base for signed object URLs when no \`publicBaseUrl\` is configured. \`undefined\` off the synchronous dispatch path. */
1535
- storage?: (env: Record<string, unknown>, origin?: string) => unknown;${ht}${k.configFields}${I.configField}${Fe}${pt}${mt}${gt}${Y.configField}
1583
+ storage?: (env: Record<string, unknown>, origin?: string) => unknown;${ht}${k.configFields}${L.configField}${Fe}${pt}${mt}${gt}${z.configField}
1536
1584
  }
1537
- ${$("schedulerStub",bt,["cancel","runAfter","runAt"])}${$("storageStub",wt,["createMultipartUpload","delete","download","generateUploadUrl","getMetadata","getPresignedUrl","getSignedUrl","getUrl","head","list","resumeMultipartUpload","store","upload"],{sync:["getUrl","resumeMultipartUpload"]})}${yt}${Lt}${St}${k.stubs}${je}
1585
+ ${$("schedulerStub",bt,["cancel","runAfter","runAt"])}${$("storageStub",wt,["createMultipartUpload","delete","download","generateUploadUrl","getMetadata","getPresignedUrl","getSignedUrl","getUrl","head","list","resumeMultipartUpload","store","upload"],{sync:["getUrl","resumeMultipartUpload"]})}${yt}${Ct}${St}${k.stubs}${je}
1538
1586
  ${qt}
1539
1587
 
1540
1588
  /**
@@ -1543,14 +1591,16 @@ ${qt}
1543
1591
  */
1544
1592
  export const createShardDO = (config: ShardDOConfig = {}): new (state: ShardDOState, env: unknown) => ShardDOBase =>
1545
1593
  class extends ShardDOBase {${Nt}
1546
- private migrated = false;${$t}${Mt}${Bt}
1594
+ private blockedUniqueIndexes: readonly string[] = [];
1595
+ private migrated = false;
1596
+ private migrationRetryAt = 0;${$t}${Mt}${Bt}
1547
1597
  ${de.override}
1548
1598
  ${Ut}
1549
- ${at}${dt}${Dt}${Ct}
1599
+ ${at}${dt}${Dt}${Et}
1550
1600
  protected override lifecycleHookPaths(event: "connect" | "disconnect" | "init" | "reactor" | "whisper"): readonly string[] {
1551
1601
  return LUNORA_LIFECYCLE_HOOKS[event];
1552
1602
  }
1553
- ${Tt}${_t}${ce}${Y.override}${It}
1603
+ ${Tt}${_t}${ce}${z.override}${Lt}
1554
1604
  // One \`onQueryChange\` dispatch. Mirrors \`executeSubscription\` — the
1555
1605
  // socket-terminated half of the same reactivity — and differs only in who
1556
1606
  // consumes the result: the base's \`dispatchReactors\` stores the digest as
@@ -1588,7 +1638,7 @@ ${c?` const requestScope = this.captureRequestScope();
1588
1638
  return undefined;
1589
1639
  }
1590
1640
 
1591
- this.ensureMigrated();
1641
+ this.ensureServable();
1592
1642
 
1593
1643
  const footprint = createReadFootprint();
1594
1644
  const ctx = this.buildCtx({ functionPath, headroom: this.subscriptionHeadroom(), onRead: footprint.onRead, onReadRange: footprint.onReadRange, trusted: true });
@@ -1649,7 +1699,7 @@ ${c?` const requestScope = this.captureRequestScope();
1649
1699
  protected override studioFeatures(): StudioFeaturesResult {
1650
1700
  return LUNORA_STUDIO_FEATURES();
1651
1701
  }
1652
- ${K.evaluateOverride}${K.subscriptionOverride}${Ye}${Ze}
1702
+ ${K.evaluateOverride}${K.subscriptionOverride}${ze}${Ze}
1653
1703
  protected override advisories(): AdvisoryFinding[] {
1654
1704
  return LUNORA_ADVISORIES();
1655
1705
  }
@@ -1660,13 +1710,40 @@ ${K.evaluateOverride}${K.subscriptionOverride}${Ye}${Ze}
1660
1710
 
1661
1711
  ${Tr}
1662
1712
 
1713
+ /**
1714
+ * Migrate the base schema. A UNIQUE index that existing duplicate rows block
1715
+ * is deferred, not thrown: the rest of the pass completes so the admin path
1716
+ * (including the data migration that de-duplicates the table) keeps working.
1717
+ * User dispatch goes through \`ensureServable\`, which refuses until the
1718
+ * index exists. \`migrated\` stays false while one is outstanding, but the
1719
+ * retry (a schema-ledger write plus a full-table duplicate scan per blocked
1720
+ * index) runs at most once per \`BLOCKED_MIGRATION_RETRY_MS\`; in between,
1721
+ * callers see the cached diagnostics. The first call after a cold start
1722
+ * always migrates, and an admin data migration resets the clock so the
1723
+ * de-dup that unblocks the index takes effect on the next call.
1724
+ */
1663
1725
  protected override ensureMigrated(): void {
1664
1726
  if (this.migrated) {
1665
1727
  return;
1666
1728
  }
1667
1729
 
1668
- runShardMigrations(this.sql as SqlExec, schema as unknown as SchemaLike, { cdc: config.cdc ?? false${be} });
1669
- this.migrated = true;
1730
+ const now = Date.now();
1731
+
1732
+ if (this.blockedUniqueIndexes.length > 0 && now < this.migrationRetryAt) {
1733
+ return;
1734
+ }
1735
+
1736
+ this.blockedUniqueIndexes = runShardMigrations(this.sql as SqlExec, schema as unknown as SchemaLike, { cdc: config.cdc ?? false, deferBlockedUniqueIndexes: true${be} });
1737
+ this.migrated = this.blockedUniqueIndexes.length === 0;
1738
+ this.migrationRetryAt = now + BLOCKED_MIGRATION_RETRY_MS;
1739
+ }
1740
+
1741
+ private ensureServable(): void {
1742
+ this.ensureMigrated();
1743
+
1744
+ if (this.blockedUniqueIndexes.length > 0) {
1745
+ throw new LunoraError("INTERNAL", this.blockedUniqueIndexes.join("; "));
1746
+ }
1670
1747
  }
1671
1748
  ${Z?`
1672
1749
  protected override runShardSearchBackfill(options: { maxPages?: number }): SearchBackfillProgress {
@@ -1678,6 +1755,6 @@ ${Z?`
1678
1755
  return backfillSearchIndexes(this.sql as SqlExec, schema as unknown as SchemaLike, options);
1679
1756
  }
1680
1757
  `:""}${vt}
1681
- ${_r({hasSensitiveArgs:V,lazyFunctions:c,actionOnlyFields:Gt,agentsBuild:Pe,agentsContextField:Ne,containersBuild:Oe,containersContextField:De,databaseOptions:Rt,everyContextBuild:Wt,everyContextField:Ht,facadeBlock:jt,globalDatabaseLine:Ot,notifyBuild:Vt,ormContextField:At,paymentsBuild:qe,paymentsContextField:Ue,queuesBuild:we,queuesContextField:ye,topicsBuild:Se,topicsContextField:Re,vectorsBuild:kt,vectorsContextField:xt,workflowsBuild:Ce,workflowsContextField:Ee,actionOnlyBuild:Qt})}
1758
+ ${_r({hasSensitiveArgs:V,lazyFunctions:c,actionOnlyFields:Gt,agentsBuild:Pe,agentsContextField:Ne,containersBuild:Oe,containersContextField:De,databaseOptions:Rt,everyContextBuild:Wt,everyContextField:Ht,facadeBlock:jt,globalDatabaseLine:Ot,notifyBuild:Vt,ormContextField:At,paymentsBuild:qe,paymentsContextField:Ue,queuesBuild:we,queuesContextField:ye,topicsBuild:Se,topicsContextField:Re,vectorsBuild:kt,vectorsContextField:xt,workflowsBuild:Ee,workflowsContextField:Ie,actionOnlyBuild:Qt})}
1682
1759
  };
1683
1760
  `};export{$r as b,on as e};
@@ -1,6 +1,6 @@
1
1
  import{r as b}from"./json-data-Chfs2Cz5.mjs";import{CAPABILITIES as N}from"./CAPABILITY_PROBES-brcmKenl.mjs";import{a as l,G as g}from"./shared-8vTRkL2-.mjs";import{s as k}from"./platform-8oj7iXQy.mjs";const I=e=>e?{importFragment:"serveRelationFanout, ",override:`
2
2
  protected override async runRelationFanoutRead(functionPath: string, args: Record<string, unknown>): Promise<unknown> {
3
- this.ensureMigrated();
3
+ this.ensureServable();
4
4
 
5
5
  const { db } = this.buildCtx({ functionPath }) as { db: DatabaseWriterLike };
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/codegen",
3
- "version": "1.0.0-alpha.336",
3
+ "version": "1.0.0-alpha.338",
4
4
  "description": "Code generator for Lunora: emits _generated/{api,server,dataModel}.ts from your schema",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -50,15 +50,15 @@
50
50
  "access": "public"
51
51
  },
52
52
  "dependencies": {
53
- "@lunora/advisor": "1.0.0-alpha.243",
54
- "@lunora/agent": "1.0.0-alpha.233",
55
- "@lunora/container": "1.0.0-alpha.87",
53
+ "@lunora/advisor": "1.0.0-alpha.245",
54
+ "@lunora/agent": "1.0.0-alpha.235",
55
+ "@lunora/container": "1.0.0-alpha.88",
56
56
  "@lunora/errors": ">=1.0.0-alpha.51 <2.0.0-0",
57
- "@lunora/platform": "1.0.0-alpha.72",
58
- "@lunora/queue": "1.0.0-alpha.120",
59
- "@lunora/scheduler": "1.0.0-alpha.142",
57
+ "@lunora/platform": "1.0.0-alpha.73",
58
+ "@lunora/queue": "1.0.0-alpha.122",
59
+ "@lunora/scheduler": "1.0.0-alpha.144",
60
60
  "@lunora/values": "1.0.0-alpha.77",
61
- "@lunora/workflow": "1.0.0-alpha.90",
61
+ "@lunora/workflow": "1.0.0-alpha.91",
62
62
  "@visulima/fs": "6.0.29",
63
63
  "jiti": "^2.7.0",
64
64
  "quicktype-core": "^26.0.0",
@@ -1,2 +0,0 @@
1
- const m=(e,t=2166136261)=>{let i=t;for(let o=0;o<e.length;o+=1)i^=e.charCodeAt(o),i=Math.imul(i,16777619);return(i>>>0).toString(16).padStart(8,"0")},S=e=>`${m(e,2166136261)}${m(e,16777619)}`,H=1;function w(e){const t={},i=Object.keys(e);i.sort();for(const o of i)t[o]=e[o];return t}const O=e=>`${JSON.stringify(e,void 0,2)}
2
- `,P=e=>S(O(e)),c=e=>typeof e=="object"&&e!==null,x=e=>c(e)&&c(e.fields)&&c(e.indexes)&&c(e.relations)&&typeof e.shardMode=="string",J=e=>{if(e===void 0||e.trim()==="")return{status:"absent"};let t;try{t=JSON.parse(e)}catch(o){return{error:`baseline is not valid JSON: ${o instanceof Error?o.message:String(o)}`,status:"invalid"}}if(!c(t)||t.version!==1||!c(t.tables))return{error:`baseline is malformed or written by an incompatible version (expected version ${String(1)})`,status:"invalid"};for(const[o,r]of Object.entries(t.tables))if(!x(r))return{error:`baseline table "${o}" has an invalid structure`,status:"invalid"};return{snapshot:{jurisdiction:typeof t.jurisdiction=="string"?t.jurisdiction:void 0,migrationIds:Array.isArray(t.migrationIds)?t.migrationIds:[],tables:t.tables,version:1},status:"ok"}},F=(e,t)=>e.unique===t.unique&&e.fields.length===t.fields.length&&e.fields.every((i,o)=>i===t.fields[o]),y=e=>e.unique!==void 0,p=({nullable:e,optional:t,refined:i,unique:o,...r})=>JSON.stringify(w(r)),g=e=>({form:JSON.stringify([p(e),e.optional===!0,e.nullable===!0]),refined:e.refined===!0}),v=e=>e.kind==="union"&&e.members?e.members.map(t=>g(t)):[g({...e,nullable:!1,optional:!1})],T=(e,t)=>{if(t.kind!=="union")return!1;const i=v(t);return v(e).every(o=>i.some(r=>r.form===o.form&&(o.refined||!r.refined)))},a=e=>{switch(e.kind){case"array":return`array(${e.of?a(e.of):"?"})`;case"id":return`id(${e.ref??"?"})`;case"literal":return`literal(${e.literal??"?"})`;case"object":return`object({ ${Object.keys(e.fields??{}).join(", ")} })`;case"record":return`record(${e.key?a(e.key):"?"}, ${e.of?a(e.of):"?"})`;case"union":return(e.members??[]).map(t=>a(t)).join(" | ");default:return e.kind}},l=(e,t,i)=>({remediation:"backfill",scope:"table",severity:"breaking",summary:i,table:e,type:t}),f=(e,t,i)=>({remediation:"none",scope:"table",severity:"safe",summary:i,table:e,type:t}),_=(e,t,i,o,r)=>{if(!(i.kind===o.kind&&(!r||p(i)===p(o))))return r&&T(i,o)?f(e,"widenedFieldShape",`field ${e}.${t} widened: ${a(i)} → ${a(o)} — every stored value stays valid`):i.kind!==o.kind?l(e,"changedFieldKind",`field ${e}.${t} changed type: ${i.kind} → ${o.kind} — add a data migration to convert existing values`):l(e,"changedFieldShape",`field ${e}.${t} changed shape: ${a(i)} → ${a(o)} — stored values were written against the old shape; add a data migration to convert them`)},j=(e,t,i,o)=>{const r=[];return i.unique!==o.unique&&r.push(o.unique===!0?l(e,"addedFieldConstraint",`field ${e}.${t} became unique — existing duplicates would violate it; add a data migration to de-duplicate first`):f(e,"relaxedFieldConstraint",`field ${e}.${t} is no longer unique`)),i.nullable!==o.nullable&&r.push(o.nullable===!0?f(e,"relaxedFieldConstraint",`field ${e}.${t} became nullable`):l(e,"addedFieldConstraint",`field ${e}.${t} is no longer nullable — rows holding NULL would be invalid; add a data migration to backfill them`)),i.refined!==o.refined&&r.push(o.refined===!0?l(e,"addedFieldConstraint",`field ${e}.${t} gained a validation refinement — stored values were never checked against it; add a data migration if any could fail`):f(e,"relaxedFieldConstraint",`field ${e}.${t} dropped its validation refinement`)),r},q=(e,t,i,o)=>{const r=[],n=y(i)&&y(o),s=_(e,t,i,o,n);return s&&r.push(s),n&&r.push(...j(e,t,i,o)),i.optional&&!o.optional?r.push({remediation:"backfill",severity:"breaking",summary:`field ${e}.${t} became required — rows missing it would be invalid; add a data migration to backfill it`,table:e,scope:"table",type:"fieldOptionalToRequired"}):!i.optional&&o.optional&&r.push({remediation:"none",scope:"table",severity:"safe",summary:`field ${e}.${t} became optional`,table:e,type:"fieldRequiredToOptional"}),r},E=(e,t,i)=>i.optional?{remediation:"none",scope:"table",severity:"safe",summary:`added optional field ${e}.${t}`,table:e,type:"addedOptionalField"}:{remediation:"backfill",severity:"breaking",summary:`added required field ${e}.${t} — existing rows have no value; add a data migration to backfill it`,table:e,scope:"table",type:"addedRequiredField"},A=(e,t,i,o)=>{for(const[r,n]of Object.entries(i.fields)){const s=t.fields[r];s===void 0?o.push(E(e,r,n)):o.push(...q(e,r,s,n))}for(const r of Object.keys(t.fields))i.fields[r]===void 0&&o.push({remediation:"backfill",severity:"breaking",summary:`removed field ${e}.${r} — add a data migration if stored data must be cleaned up`,table:e,scope:"table",type:"removedField"})},M=(e,t,i,o)=>{for(const[r,n]of Object.entries(i.indexes)){const s=t.indexes[r];if(s===void 0){o.push(n.unique?{remediation:"backfill",scope:"table",severity:"breaking",summary:`added unique index ${r} on ${e} — existing duplicates would violate it; add a data migration to de-duplicate first`,table:e,type:"addedIndex"}:{remediation:"none",scope:"table",severity:"safe",summary:`added index ${r} on ${e}`,table:e,type:"addedIndex"});continue}F(s,n)||o.push({remediation:"code",severity:"breaking",summary:`index ${r} on ${e} changed shape — a query may have relied on the old index`,table:e,scope:"table",type:"changedIndex"})}for(const r of Object.keys(t.indexes))i.indexes[r]===void 0&&o.push({remediation:"code",severity:"breaking",summary:`removed index ${r} on ${e} — a query that used \`.withIndex("${r}")\` would break`,table:e,scope:"table",type:"removedIndex"})},C=(e,t,i,o)=>{for(const r of Object.keys(i.relations))t.relations[r]===void 0&&o.push({remediation:"none",scope:"schema",severity:"safe",summary:`added relation ${e}.${r}`,table:e,type:"addedRelation"});for(const r of Object.keys(t.relations))i.relations[r]===void 0&&o.push({remediation:"code",scope:"schema",severity:"breaking",summary:`removed relation ${e}.${r}`,table:e,type:"removedRelation"})},$="shardBy:_unknown_",u="global",I=(e,t)=>e===u&&t.startsWith(`${u}:`)||t===u&&e.startsWith(`${u}:`),R=(e,t,i)=>{if(t===i)return i!==$?void 0:{remediation:"rehome",scope:"table",severity:"breaking",summary:`table ${e} declares a non-literal .shardBy(...) key, so codegen cannot read which column partitions it — every such key records as "${$}" and two DIFFERENT keys would compare equal. Pass the shard key as a string literal; until then this is reported on every run, because the alternative is a silent pass on a re-home that strands every row (export/import is the only way back).`,table:e,type:"changedShardMode"};if(!I(t,i))return{remediation:"rehome",severity:"breaking",summary:`table ${e} changed shard mode: ${t} → ${i} — its physical storage moves, and existing rows do NOT follow the schema; re-home them with an export/import round trip (https://lunora.sh/docs/concepts/sharding#migrating-a-populated-table)`,table:e,scope:"table",type:"changedShardMode"}},b=e=>e.memory!==void 0,k=e=>e.after??0,d=e=>e.after===void 0?`.ttl("${e.field}")`:`.ttl("${e.field}", { after: ${String(e.after)} })`,V=(e,t,i)=>{if(t===void 0&&i===void 0)return;const o=h=>({remediation:"backfill",scope:"table",severity:"breaking",summary:h,table:e,type:"changedTtlPolicy"}),r=h=>({remediation:"none",scope:"table",severity:"safe",summary:h,table:e,type:"changedTtlPolicy"});if(i===void 0)return r(`table ${e} dropped its TTL policy — its rows are no longer swept`);if(t===void 0)return o(`table ${e} gained a TTL policy ${d(i)} — every row already past the cutoff is deleted on the next alarm sweep; add a data migration to refresh or clear "${i.field}" on the rows written before it`);if(t.field!==i.field)return o(`table ${e} moved its TTL to a different column: ${d(t)} → ${d(i)} — rows are now expired by a column they were never written against; add a data migration to populate "${i.field}"`);const n=k(t),s=k(i);return s<n?o(`table ${e} shortened its TTL: ${d(t)} → ${d(i)} — rows that were not expired under the old offset are deleted on the next alarm sweep; add a data migration to refresh "${i.field}" on the rows that must survive`):s>n?r(`table ${e} lengthened its TTL: ${d(t)} → ${d(i)}`):void 0},L=(e,t,i)=>{const o=[];return t.memory!==i.memory&&o.push(i.memory===!0?{remediation:"rehome",scope:"table",severity:"breaking",summary:`table ${e} became a .memory() table — every row is deleted in every shard on the next Durable Object cold start, and no data migration survives that; export the rows first if they must be kept, or revert`,table:e,type:"changedMemoryMode"}:{remediation:"none",scope:"table",severity:"safe",summary:`table ${e} is no longer a .memory() table — its rows now survive a cold start`,table:e,type:"changedMemoryMode"}),t.commitOrdered!==i.commitOrdered&&o.push(i.commitOrdered===!0?{remediation:"backfill",scope:"table",severity:"breaking",summary:`table ${e} became .commitOrdered() — rows written before it carry no _commitSeq, so a \`_commitSeq > cursor\` changefeed never offers them; add a data migration over the table to stamp them (the rewrite allocates a sequence)`,table:e,type:"changedCommitOrdering"}:{remediation:"code",scope:"table",severity:"breaking",summary:`table ${e} is no longer .commitOrdered() — new rows carry no _commitSeq, so a \`_commitSeq > cursor\` changefeed stops advancing without erroring; update the consumers before deploying`,table:e,type:"changedCommitOrdering"}),o},D=(e,t,i,o)=>{const r=R(e,t.shardMode,i.shardMode);if(r&&o.push(r),b(t)&&b(i)){o.push(...L(e,t,i));const n=V(e,t.ttl,i.ttl);n&&o.push(n)}A(e,t,i,o),M(e,t,i,o),C(e,t,i,o)},B=(e,t)=>{const i=[],o=e?.tables??{};for(const[r,n]of Object.entries(t.tables)){const s=o[r];if(s===void 0){i.push({remediation:"none",scope:"table",severity:"safe",summary:`added table ${r}`,table:r,type:"addedTable"});continue}D(r,s,n,i)}for(const r of Object.keys(o))t.tables[r]===void 0&&i.push({remediation:"rehome",scope:"table",severity:"breaking",summary:`removed table ${r} — its rows stay in each shard's SQLite, unreachable through the schema; export the shard first if the data must be kept`,table:r,type:"removedTable"});if(e!==void 0&&e.jurisdiction!==t.jurisdiction){const r=e.jurisdiction??"(none)",n=t.jurisdiction??"(none)";i.push({remediation:"rehome",scope:"schema",severity:"breaking",summary:`Durable Object jurisdiction changed from ${r} to ${n} — this re-homes every DO and strands all existing shard, scheduler, and session-DO data in the old region (no in-place migration; export then import to move it). Revert the change, or override the gate to proceed intentionally.`,type:"changedJurisdiction"})}return{changes:i}};export{H as SCHEMA_SNAPSHOT_VERSION,a as describeShape,q as diffExistingField,B as diffSchemaSnapshots,P as hashSchemaSnapshot,x as isValidTableSnapshot,J as parseSnapshotJson,O as serializeSchemaSnapshot,w as sortKeys};
@@ -1,18 +0,0 @@
1
- import{LunoraError as v}from"@lunora/errors";import{SCHEMA_SNAPSHOT_VERSION as E,sortKeys as f,diffSchemaSnapshots as I,parseSnapshotJson as A}from"./SCHEMA_SNAPSHOT_VERSION-C0oHwiJZ.mjs";import{isHyperdriveGlobalTable as L}from"./isD1GlobalTable-udvHAAzD.mjs";const O=e=>{const t=e.shardMode;return t==="global"?`global:${L(e)?"hyperdrive":"d1"}`:t==="root"?t:`shardBy:${t.field}`},_=(e,t)=>{const s=JSON.stringify(e),i=JSON.stringify(t);return s===i?0:s<i?-1:1},l=e=>{const t=e.kind==="optional",s=t?e.inner:void 0,i=s??e,r={kind:t?s?.kind??"unknown":e.kind,nullable:i.column?.notNull===!1||e.column?.notNull===!1,optional:t,unique:i.column?.unique===!0||e.column?.unique===!0,...j[i.kind]?.(i)};return(i.hasRefinement===!0||e.hasRefinement===!0)&&(r.refined=!0),r},N=e=>{const t={};for(const[s,i]of Object.entries(e))t[s]=l(i);return f(t)},j={array:e=>e.inner?{of:l(e.inner)}:{},id:e=>e.tableName===void 0?{}:{ref:e.tableName},literal:e=>e.literalValue===void 0?{}:{literal:e.literalValue},object:e=>e.shape?{fields:N(e.shape)}:{},record:e=>({...e.keyType?{key:l(e.keyType)}:{},...e.valueType?{of:l(e.valueType)}:{}}),union:e=>e.members?{members:e.members.map(t=>l(t)).toSorted(_)}:{}},D=e=>{const t={};for(const[n,a]of Object.entries(e.shape))t[n]=l(a);const s={};for(const n of e.indexes)s[n.name]={fields:[...n.fields],unique:n.unique??!1};const i={};for(const n of e.relations)i[n.name]=n.through===void 0?{field:n.field,kind:n.kind,table:n.table}:{kind:n.kind,table:n.table,through:{...n.through}};const r={commitOrdered:e.commitOrdered===!0,fields:f(t),indexes:f(s),memory:e.memory===!0,relations:f(i),shardMode:O(e)};return e.ttl&&(r.ttl=e.ttl.after===void 0?{field:e.ttl.field}:{after:e.ttl.after,field:e.ttl.field}),r},C=(e,t)=>{const s={};for(const r of e.tables)s[r.name]=D(r);const i=[...t].sort();return{jurisdiction:e.jurisdiction,migrationIds:i,tables:f(s),version:E}};class R extends v{constructor(t){super("SCHEMA_SNAPSHOT_PARSE",t,{name:"SchemaSnapshotParseError"})}}const J=e=>{const t=A(e);if(t.status==="invalid")throw new R(t.error);return t.status==="ok"?t.snapshot:void 0},M={build:{allowDrift:!0,updateBaseline:!1},deploy:{allowDrift:!0,updateBaseline:!0},prepare:{allowDrift:!0,updateBaseline:!0},verify:{allowDrift:!0,updateBaseline:!1}},y=" • For backward-compatible changes (e.g. adding an optional field): pass `--allow-schema-drift` to skip the block.",k=" • To accept the new shape without a migration (you know data is compatible): pass `--update-schema-baseline`.",B=e=>{const t=e===void 0?void 0:M[e];if(e===void 0||t===void 0)return`${y}
2
- ${k}
3
- `;const s=t.updateBaseline?k:` • To accept the new shape without a migration, run \`lunora prepare --update-schema-baseline\` — \`lunora ${e}\` does not take that flag.`;return`${y}
4
- ${s}
5
- `},p=e=>e.map(t=>` - ${t.summary}`).join(`
6
- `),w=e=>e.remediation==="backfill"&&e.table!==void 0,x=/^[A-Za-z_]\w*$/u,F=e=>` lunora migrate create backfill_${e} --table ${e}`,P=(e,t,s)=>{const i=[...new Set(e.filter(n=>w(n)).map(n=>n.table))],r=[];if(i.length>0){r.push(" • Add a `defineMigration({ id, table, up })` in lunora/ for each affected table, then re-run this command — the baseline is re-blessed on a successful deploy, not by `lunora migrate` itself.\n");const n=i.filter(a=>x.test(a));n.length>0&&r.push(`
7
- Scaffold the missing migration(s) — the generated \`up\` is an identity placeholder you must fill in:
8
- ${n.map(a=>F(a)).join(`
9
- `)}
10
-
11
- `)}return t.length>0&&r.push(` • Migration(s) ${t.join(", ")} declare a non-literal \`table\`, so codegen cannot tell which table they visit and they cover nothing. Use a string literal.
12
- `),r.push(B(s)),[`${s??"deploy"} blocked: ${String(e.length)} unresolved breaking schema change(s) since the last blessed schema baseline:`,p(e),"",`To fix:
13
- ${r.join("")}Docs: https://lunora.dev/docs/migrations`].join(`
14
- `)},V=e=>{const{allowDrift:t=!1,baseline:s,command:i,current:r,migrations:n}=e,a=I(s,r),u=a.changes.filter(o=>o.severity==="breaking"),b=r.migrationIds.filter(o=>!(s?.migrationIds??[]).includes(o)),m=n.filter(o=>b.includes(o.id)),c=(o,h)=>({blocked:o,changes:a.changes,newMigrationIds:b,reason:h}),T=new Set(m.filter(o=>o.table!=="").map(o=>o.table)),$=m.filter(o=>o.table==="").map(o=>o.id);if(a.changes.length===0||s===void 0)return c(!1,"");if(u.length===0)return c(!1,`schema drift detected (all additive/safe):
15
- ${p(a.changes)}`);const g=u.filter(o=>!w(o)||!T.has(o.table));if(g.length===0){const o=new Set(u.map(d=>d.table)),h=m.filter(d=>o.has(d.table)).map(d=>d.id);return c(!1,`breaking schema drift detected, covered by ${String(h.length)} new migration(s) (${h.join(", ")}):
16
- ${p(u)}`)}const S=P(g,$,i);return t?c(!1,`${S}
17
-
18
- (overridden by --allow-schema-drift)`):c(!0,S)};export{R as SchemaSnapshotParseError,C as buildSchemaSnapshot,V as evaluateSchemaDrift,J as parseSchemaSnapshot};