@lunora/codegen 1.0.0-alpha.180 → 1.0.0-alpha.182
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.mjs +1 -1
- package/dist/packem_shared/{GENERATED_HEADER-C09Nx5NT.mjs → GENERATED_HEADER-CHXXi4ZC.mjs} +1 -1
- package/dist/packem_shared/{OPENRPC_VERSION-BP55emE7.mjs → OPENRPC_VERSION-Cm0hghqI.mjs} +1 -1
- package/dist/packem_shared/{SCHEMA_SNAPSHOT_FILENAME-C4tzDKID.mjs → SCHEMA_SNAPSHOT_FILENAME-Hw1OTX7t.mjs} +1 -1
- package/dist/packem_shared/{buildOpenApiDocument-B886sQ5Z.mjs → buildOpenApiDocument-CyT-_2sB.mjs} +1 -1
- package/dist/packem_shared/{emit-CBLJHtDY.mjs → emit-pX7uKd5t.mjs} +179 -138
- package/dist/packem_shared/{emitApp-Xwfxv1S-.mjs → emitApp-Bk9cSlFf.mjs} +1 -1
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{SCHEMA_SNAPSHOT_VERSION as t,diffSchemaSnapshots as s,serializeSchemaSnapshot as a}from"./packem_shared/SCHEMA_SNAPSHOT_VERSION-CWESEYLi.mjs";import{formatAdvisories as m,lintSchema as d,toAdvisorContext as f}from"./packem_shared/formatAdvisories-CkEu1eye.mjs";import{describeErrorLevelFindings as c,errorAdvisoryNames as n,errorPlatformDiagnosticNames as l}from"./packem_shared/describeErrorLevelFindings-D23VSkFP.mjs";import{CodegenDiagnosticError as x,diagnosticAt as E}from"./packem_shared/CodegenDiagnosticError-BUXlG3P-.mjs";import{AGENTS_FILENAME as u,discoverAgents as v}from"./packem_shared/AGENTS_FILENAME-B78F7DuQ.mjs";import{listLunoraSourceFiles as g}from"./packem_shared/listLunoraSourceFiles-D4xthUf-.mjs";import{default as O}from"./packem_shared/discoverAuthApiCalls-DoblmzUW.mjs";import{CONTAINERS_FILENAME as M,discoverContainers as T}from"./packem_shared/CONTAINERS_FILENAME-CQoUu7n7.mjs";import{default as h}from"./packem_shared/discoverCrons-CMu0sA8k.mjs";import{FLAGS_FILENAME as F,discoverFlags as I}from"./packem_shared/FLAGS_FILENAME-CoTJH0-7.mjs";import{default as D}from"./packem_shared/discoverFunctions-DB9G_XrW.mjs";import{default as U}from"./packem_shared/discoverHttpRoutes-S81Iv_iB.mjs";import{default as H}from"./packem_shared/discoverHyperdriveCalls-DgAYcZRD.mjs";import{default as y}from"./packem_shared/discoverInserts-COk-Sm_n.mjs";import{d as W}from"./packem_shared/index-D_Z8rX-f.mjs";import{default as V}from"./packem_shared/discoverMigrations-B_sYrTyE.mjs";import{MUTATORS_FILENAME as Q,discoverMutators as w}from"./packem_shared/MUTATORS_FILENAME-CTHlZ1j6.mjs";import{default as q}from"./packem_shared/discoverNondeterministicCalls-DkVVHe3U.mjs";import{NOTIFY_FILENAME as Y,discoverNotifyCalls as X,discoverNotifyConfig as Z}from"./packem_shared/NOTIFY_FILENAME-CZh4jN4q.mjs";import{default as ee}from"./packem_shared/readPackageDependencies-C6h6FZuP.mjs";import{d as oe}from"./packem_shared/queries-CPlxXagL.mjs";import{QUEUES_FILENAME as se,discoverQueues as ae}from"./packem_shared/QUEUES_FILENAME-Q3CF3uYr.mjs";import{default as me}from"./packem_shared/discoverR2sqlCalls-6u0OKy2N.mjs";import{default as fe}from"./packem_shared/discoverRlsProcedures-vJZq3yhb.mjs";import{default as ce}from"./packem_shared/discoverRlsMetadata-CwWRPb8N.mjs";import{discoverSandboxUsage as le}from"./packem_shared/discoverSandboxUsage-DskdDbkM.mjs";import{default as xe}from"./packem_shared/discoverSchema-DoZtXwLg.mjs";import{SHAPES_FILENAME as Ae,discoverShapes as ue}from"./packem_shared/SHAPES_FILENAME-Bvd5kgsF.mjs";import{default as Ne}from"./packem_shared/discoverStorageRulesMetadata-xhxu-mkS.mjs";import{WORKFLOWS_FILENAME as Ce,discoverWorkflows as Oe}from"./packem_shared/WORKFLOWS_FILENAME-BaSbufF2.mjs";import{G as Me,e as Te,a as _e,b as he,c as Le,d as Fe,f as Ie,g as Pe,h as De,i as Ge,j as Ue,k as be,l as He,m as je,n as ye}from"./packem_shared/emit-
|
|
1
|
+
import{SCHEMA_SNAPSHOT_VERSION as t,diffSchemaSnapshots as s,serializeSchemaSnapshot as a}from"./packem_shared/SCHEMA_SNAPSHOT_VERSION-CWESEYLi.mjs";import{formatAdvisories as m,lintSchema as d,toAdvisorContext as f}from"./packem_shared/formatAdvisories-CkEu1eye.mjs";import{describeErrorLevelFindings as c,errorAdvisoryNames as n,errorPlatformDiagnosticNames as l}from"./packem_shared/describeErrorLevelFindings-D23VSkFP.mjs";import{CodegenDiagnosticError as x,diagnosticAt as E}from"./packem_shared/CodegenDiagnosticError-BUXlG3P-.mjs";import{AGENTS_FILENAME as u,discoverAgents as v}from"./packem_shared/AGENTS_FILENAME-B78F7DuQ.mjs";import{listLunoraSourceFiles as g}from"./packem_shared/listLunoraSourceFiles-D4xthUf-.mjs";import{default as O}from"./packem_shared/discoverAuthApiCalls-DoblmzUW.mjs";import{CONTAINERS_FILENAME as M,discoverContainers as T}from"./packem_shared/CONTAINERS_FILENAME-CQoUu7n7.mjs";import{default as h}from"./packem_shared/discoverCrons-CMu0sA8k.mjs";import{FLAGS_FILENAME as F,discoverFlags as I}from"./packem_shared/FLAGS_FILENAME-CoTJH0-7.mjs";import{default as D}from"./packem_shared/discoverFunctions-DB9G_XrW.mjs";import{default as U}from"./packem_shared/discoverHttpRoutes-S81Iv_iB.mjs";import{default as H}from"./packem_shared/discoverHyperdriveCalls-DgAYcZRD.mjs";import{default as y}from"./packem_shared/discoverInserts-COk-Sm_n.mjs";import{d as W}from"./packem_shared/index-D_Z8rX-f.mjs";import{default as V}from"./packem_shared/discoverMigrations-B_sYrTyE.mjs";import{MUTATORS_FILENAME as Q,discoverMutators as w}from"./packem_shared/MUTATORS_FILENAME-CTHlZ1j6.mjs";import{default as q}from"./packem_shared/discoverNondeterministicCalls-DkVVHe3U.mjs";import{NOTIFY_FILENAME as Y,discoverNotifyCalls as X,discoverNotifyConfig as Z}from"./packem_shared/NOTIFY_FILENAME-CZh4jN4q.mjs";import{default as ee}from"./packem_shared/readPackageDependencies-C6h6FZuP.mjs";import{d as oe}from"./packem_shared/queries-CPlxXagL.mjs";import{QUEUES_FILENAME as se,discoverQueues as ae}from"./packem_shared/QUEUES_FILENAME-Q3CF3uYr.mjs";import{default as me}from"./packem_shared/discoverR2sqlCalls-6u0OKy2N.mjs";import{default as fe}from"./packem_shared/discoverRlsProcedures-vJZq3yhb.mjs";import{default as ce}from"./packem_shared/discoverRlsMetadata-CwWRPb8N.mjs";import{discoverSandboxUsage as le}from"./packem_shared/discoverSandboxUsage-DskdDbkM.mjs";import{default as xe}from"./packem_shared/discoverSchema-DoZtXwLg.mjs";import{SHAPES_FILENAME as Ae,discoverShapes as ue}from"./packem_shared/SHAPES_FILENAME-Bvd5kgsF.mjs";import{default as Ne}from"./packem_shared/discoverStorageRulesMetadata-xhxu-mkS.mjs";import{WORKFLOWS_FILENAME as Ce,discoverWorkflows as Oe}from"./packem_shared/WORKFLOWS_FILENAME-BaSbufF2.mjs";import{G as Me,e as Te,a as _e,b as he,c as Le,d as Fe,f as Ie,g as Pe,h as De,i as Ge,j as Ue,k as be,l as He,m as je,n as ye}from"./packem_shared/emit-pX7uKd5t.mjs";import{emitApp as We}from"./packem_shared/emitApp-Bk9cSlFf.mjs";import{isD1GlobalTable as Ve,isHyperdriveGlobalTable as ze}from"./packem_shared/isD1GlobalTable-udvHAAzD.mjs";import{buildOpenApiDocument as we,emitOpenApi as Je,emitOpenApiModule as qe}from"./packem_shared/buildOpenApiDocument-CyT-_2sB.mjs";import{OPENRPC_VERSION as Ye,buildOpenRpcDocument as Xe,emitOpenRpc as Ze,emitOpenRpcModule as $e}from"./packem_shared/OPENRPC_VERSION-Cm0hghqI.mjs";import{DEFAULT_TARGET as rr,platformMatrixIds as or,readProjectTarget as tr,resolveCodegenTarget as sr}from"./packem_shared/DEFAULT_TARGET-DtzlGawL.mjs";import{PROJECT_CONFIG_FILENAMES as ir,findProjectConfigFile as mr,loadProjectConfig as dr,readProjectConfigLiterals as fr}from"./packem_shared/PROJECT_CONFIG_FILENAMES-D29yBg5X.mjs";import{SCHEMA_SNAPSHOT_FILENAME as cr,createCodegenProject as nr,findTsconfig as lr,refreshCodegenProject as Sr,runCodegen as xr}from"./packem_shared/SCHEMA_SNAPSHOT_FILENAME-Hw1OTX7t.mjs";import{SchemaSnapshotParseError as Ar,buildSchemaSnapshot as ur,evaluateSchemaDrift as vr,parseSchemaSnapshot as Nr}from"./packem_shared/SchemaSnapshotParseError-yrVM8bTa.mjs";import{schemaFromIr as Cr}from"./packem_shared/schemaFromIr-BWFnvCVg.mjs";import{LUNORA_ERROR_CODES as Rr,validatorIrToJsonSchema as Mr}from"./packem_shared/LUNORA_ERROR_CODES-C2s0xWQD.mjs";import{SDK_LANGUAGES as _r,SDK_TARGETS as hr,generateSdk as Lr}from"./packem_shared/SDK_LANGUAGES-CFyux-74.mjs";import{redact as Ir,secretKindOf as Pr}from"./packem_shared/redact-Cy14LEnc.mjs";import{MESSAGE_SOLUTIONS as Gr,findSolutionByMessage as Ur}from"@lunora/errors";import{isTypedSchema as Hr}from"./packem_shared/isTypedSchema-B_qlBbE-.mjs";const e="0.0.0";export{u as AGENTS_FILENAME,M as CONTAINERS_FILENAME,x as CodegenDiagnosticError,rr as DEFAULT_TARGET,F as FLAGS_FILENAME,Me as GENERATED_HEADER,Rr as LUNORA_ERROR_CODES,Gr as LUNORA_SOLUTION_RULES,Q as MUTATORS_FILENAME,Y as NOTIFY_FILENAME,Ye as OPENRPC_VERSION,ir as PROJECT_CONFIG_FILENAMES,se as QUEUES_FILENAME,cr as SCHEMA_SNAPSHOT_FILENAME,t as SCHEMA_SNAPSHOT_VERSION,_r as SDK_LANGUAGES,hr as SDK_TARGETS,Ae as SHAPES_FILENAME,Ar as SchemaSnapshotParseError,e as VERSION,Ce as WORKFLOWS_FILENAME,we as buildOpenApiDocument,Xe as buildOpenRpcDocument,ur as buildSchemaSnapshot,nr as createCodegenProject,c as describeErrorLevelFindings,E as diagnosticAt,s as diffSchemaSnapshots,v as discoverAgents,O as discoverAuthApiCalls,T as discoverContainers,h as discoverCrons,I as discoverFlags,D as discoverFunctions,U as discoverHttpRoutes,H as discoverHyperdriveCalls,y as discoverInserts,W as discoverMaskProcedures,V as discoverMigrations,w as discoverMutators,q as discoverNondeterministicCalls,X as discoverNotifyCalls,Z as discoverNotifyConfig,oe as discoverQueries,ae as discoverQueues,me as discoverR2sqlCalls,ce as discoverRlsMetadata,fe as discoverRlsProcedures,le as discoverSandboxUsage,xe as discoverSchema,ue as discoverShapes,Ne as discoverStorageRulesMetadata,Oe as discoverWorkflows,Te as emitAgents,_e as emitApi,We as emitApp,he as emitCollections,Le as emitContainers,Fe as emitCrons,Ie as emitDataModel,Pe as emitDrizzleSchema,De as emitFunctions,Je as emitOpenApi,qe as emitOpenApiModule,Ze as emitOpenRpc,$e as emitOpenRpcModule,Ge as emitScheduler,Ue as emitServer,be as emitShard,He as emitVectors,je as emitWorkflows,ye as emitWranglerCronTriggers,n as errorAdvisoryNames,l as errorPlatformDiagnosticNames,vr as evaluateSchemaDrift,Ur as findLunoraSolution,mr as findProjectConfigFile,lr as findTsconfig,m as formatAdvisories,Lr as generateSdk,Ve as isD1GlobalTable,ze as isHyperdriveGlobalTable,Hr as isTypedSchema,d as lintSchema,g as listLunoraSourceFiles,dr as loadProjectConfig,Nr as parseSchemaSnapshot,or as platformMatrixIds,ee as readPackageDependencies,fr as readProjectConfigLiterals,tr as readProjectTarget,Ir as redact,Sr as refreshCodegenProject,sr as resolveCodegenTarget,xr as runCodegen,Cr as schemaFromIr,Pr as secretKindOf,a as serializeSchemaSnapshot,f as toAdvisorContext,Mr as validatorIrToJsonSchema};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./SCHEMA_SNAPSHOT_VERSION-CWESEYLi.mjs";import{G as r,U as o,o as n,e as l,a as A,b as E,c as S,d as p,f as c,g as d,h as g,p as u,i as C,q as h,j as D,k as f,l as G,m as R,n as _}from"./emit-
|
|
1
|
+
import"./SCHEMA_SNAPSHOT_VERSION-CWESEYLi.mjs";import{G as r,U as o,o as n,e as l,a as A,b as E,c as S,d as p,f as c,g as d,h as g,p as u,i as C,q as h,j as D,k as f,l as G,m as R,n as _}from"./emit-pX7uKd5t.mjs";import"./isD1GlobalTable-udvHAAzD.mjs";import"./paths-C-9fwEgQ.mjs";import"./LUNORA_ERROR_CODES-C2s0xWQD.mjs";export{r as GENERATED_HEADER,o as UMBRELLA_BASE_PACKAGES,n as buildStorageColumns,l as emitAgents,A as emitApi,E as emitCollections,S as emitContainers,p as emitCrons,c as emitDataModel,d as emitDrizzleSchema,g as emitFunctions,u as emitQueues,C as emitScheduler,h as emitSeed,D as emitServer,f as emitShard,G as emitVectors,R as emitWorkflows,_ as emitWranglerCronTriggers};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{G as c}from"./emit-
|
|
1
|
+
import{G as c}from"./emit-pX7uKd5t.mjs";import{s as u}from"./paths-C-9fwEgQ.mjs";import{validatorIrToJsonSchema as m,objectSchema as p,LUNORA_ERROR_CODES as i}from"./LUNORA_ERROR_CODES-C2s0xWQD.mjs";const l="1.3.2",d={description:"Result is TS-inferred from the function's return type (no `.output()` declared); best-effort — any JSON."},R=e=>{const n=u(e.filePath),o=`${n}:${e.exportName}`;return{description:`Invoke the \`${e.kind}\` \`${o}\` over the Lunora RPC envelope (POST /_lunora/rpc, body \`{ "functionPath": "${o}", "args": { … } }\`).`,errors:i.map((r,s)=>({code:-32e3-s,data:{code:r},message:r})),name:o,params:[{description:"The function's argument object (the RPC envelope's `args`).",name:"args",required:Object.keys(e.args).length>0,schema:p(e.args)}],result:{name:"result",schema:e.output?m(e.output):d},summary:`${e.kind}: ${o}`,"x-lunora-function-kind":e.kind,"x-tags":[{name:n}]}},g=e=>{const n=e.version??"0.0.0",r=e.functions.filter(t=>t.visibility!=="internal"&&t.kind!=="stream").map(t=>R(t)).toSorted((t,a)=>t.name.localeCompare(a.name));return{info:{description:"Auto-generated from @lunora/values-typed functions by @lunora/codegen. Do not edit — run `lunora codegen` to regenerate.",title:"Lunora RPC",version:n},methods:r,openrpc:l}},S=e=>`${JSON.stringify(g(e),void 0,2)}
|
|
2
2
|
`,v=e=>`${c}export const openRpcSpec: Record<string, unknown> = ${JSON.stringify(e,void 0,4)};
|
|
3
3
|
`;export{l as OPENRPC_VERSION,g as buildOpenRpcDocument,S as emitOpenRpc,v as emitOpenRpcModule};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{existsSync as b,mkdirSync as Ps,readFileSync as Mt,writeFileSync as Is,rmSync as ws}from"node:fs";import{join as f,dirname as te}from"node:path";import{performance as Ee}from"node:perf_hooks";import{runAdvisor as Ts}from"@lunora/advisor";import{LunoraError as D}from"@lunora/errors";import{SyntaxKind as l,Node as i,Project as at}from"ts-morph";import{serializeSchemaSnapshot as Cs}from"./SCHEMA_SNAPSHOT_VERSION-CWESEYLi.mjs";import{toAdvisorContext as Fs}from"./formatAdvisories-CkEu1eye.mjs";import{s as Os}from"./paths-C-9fwEgQ.mjs";import{C as se,o as _t,j as Rs,f as Ls,k as Ds,b as ks,c as Ms,m as _s,e as Ks,p as zs,d as $s,i as Us,l as qs,g as Bs,q as Vs,n as Ws,a as js,h as Hs}from"./emit-
|
|
1
|
+
import{existsSync as b,mkdirSync as Ps,readFileSync as Mt,writeFileSync as Is,rmSync as ws}from"node:fs";import{join as f,dirname as te}from"node:path";import{performance as Ee}from"node:perf_hooks";import{runAdvisor as Ts}from"@lunora/advisor";import{LunoraError as D}from"@lunora/errors";import{SyntaxKind as l,Node as i,Project as at}from"ts-morph";import{serializeSchemaSnapshot as Cs}from"./SCHEMA_SNAPSHOT_VERSION-CWESEYLi.mjs";import{toAdvisorContext as Fs}from"./formatAdvisories-CkEu1eye.mjs";import{s as Os}from"./paths-C-9fwEgQ.mjs";import{C as se,o as _t,j as Rs,f as Ls,k as Ds,b as ks,c as Ms,m as _s,e as Ks,p as zs,d as $s,i as Us,l as qs,g as Bs,q as Vs,n as Ws,a as js,h as Hs}from"./emit-pX7uKd5t.mjs";import{isD1GlobalTable as Kt,isHyperdriveGlobalTable as zt}from"./isD1GlobalTable-udvHAAzD.mjs";import{discoverAgents as Gs}from"./AGENTS_FILENAME-B78F7DuQ.mjs";import{discoverContainers as Ys}from"./CONTAINERS_FILENAME-CQoUu7n7.mjs";import Qs from"./discoverCrons-CMu0sA8k.mjs";import{diagnosticAt as ce}from"./CodegenDiagnosticError-BUXlG3P-.mjs";import{b as le}from"./module-specifiers-WF8iAydP.mjs";import{listLunoraSourceFiles as h,unwrapExpression as H,listSecurityScanFiles as Te,objectLiteralFromCallbackBody as $t,propertyInitializer as N,lunoraRelativePath as E,collectCallRows as I,collectSecurityCallRows as Xs,limitNameOf as Ut,isContextIdentifier as Ne,handlerOf as Zs,isDatabaseAccessor as k,readTargetOf as qt,enclosingExportName as Js}from"./listLunoraSourceFiles-D4xthUf-.mjs";import en from"./readPackageDependencies-C6h6FZuP.mjs";import{discoverQueues as tn}from"./QUEUES_FILENAME-Q3CF3uYr.mjs";import{discoverSandboxUsage as sn}from"./discoverSandboxUsage-DskdDbkM.mjs";import nn from"./discoverStorageRulesMetadata-xhxu-mkS.mjs";import{a as y,c as M,d as Bt,e as rn}from"./classify-procedure-call-C8jbo0IJ.mjs";import{discoverWorkflows as on}from"./WORKFLOWS_FILENAME-BaSbufF2.mjs";import{gatePlatformFeatures as an,resolveCodegenTarget as cn,readTargetDiagnostics as ln}from"./DEFAULT_TARGET-DtzlGawL.mjs";import{i as L,a as z,e as S,r as un,b as dn,s as ue,c as fn,f as gn,d as pn}from"./queries-CPlxXagL.mjs";import{r as de,s as mn}from"./parse-validator-tdRHHDzh.mjs";import hn from"./discoverAuthApiCalls-DoblmzUW.mjs";import ct from"./discoverFunctions-DB9G_XrW.mjs";import{i as xn,r as vn,e as En}from"./unwrap-handler-return-CmIWbykC.mjs";import lt from"./discoverHttpRoutes-S81Iv_iB.mjs";import Sn from"./discoverHyperdriveCalls-DgAYcZRD.mjs";import yn from"./discoverInserts-COk-Sm_n.mjs";import{m as Ce,a as re,s as Vt,d as An}from"./index-D_Z8rX-f.mjs";import{e as Wt}from"./exported-procedure-chains-C9FHwphy.mjs";import Nn from"./discoverMigrations-B_sYrTyE.mjs";import{MUTATORS_FILENAME as bn,isDefineMutatorCallee as Pn,discoverMutators as ut}from"./MUTATORS_FILENAME-CTHlZ1j6.mjs";import In from"./discoverNondeterministicCalls-DkVVHe3U.mjs";import{discoverNotifyConfig as wn,discoverNotifyCalls as Tn}from"./NOTIFY_FILENAME-CZh4jN4q.mjs";import Cn from"./discoverR2sqlCalls-6u0OKy2N.mjs";import Fn from"./discoverRlsProcedures-vJZq3yhb.mjs";import On from"./discoverRlsMetadata-CwWRPb8N.mjs";import Rn from"./discoverSchema-DoZtXwLg.mjs";import{secretKindOf as Ln,redact as Dn,isHeuristicSecretKind as kn,isSecretishName as Mn}from"./redact-Cy14LEnc.mjs";import{discoverShapes as _n}from"./SHAPES_FILENAME-Bvd5kgsF.mjs";import{emitApp as Kn}from"./emitApp-Bk9cSlFf.mjs";import{buildOpenApiDocument as zn,emitOpenApiModule as $n}from"./buildOpenApiDocument-CyT-_2sB.mjs";import{buildOpenRpcDocument as Un,emitOpenRpcModule as qn}from"./OPENRPC_VERSION-Cm0hghqI.mjs";import{buildSchemaSnapshot as Bn}from"./SchemaSnapshotParseError-yrVM8bTa.mjs";const dt=(e,t="api")=>{const s=new Map;for(const n of e){const o=Os(n),r=s.get(o);if(r===void 0){s.set(o,n);continue}if(r!==n){const a=t==="api"?`the generated api.ts would declare "${o}" twice and the dispatch key "${o}:<fn>" would be ambiguous`:`the generated api.ts would declare "${o}" twice in HttpStreamsRef and again in the httpStreams object literal`;throw new D("INTERNAL",`@lunora/codegen: "${r}" and "${n}" both map to the ${t} namespace "${o}" — ${a}. Rename one file so the two differ by more than a non-identifier character (\`-\`, \`.\`, \`/\` and \`_\` all sanitize to \`_\`).`,{status:500})}}},Vn=(e,t={})=>{const{hasVectors:s=!0,scheduler:n=!1,storage:o=!1,usage:r}=t,a=[];e.tables.some(c=>Kt(c))&&a.push({name:"@lunora/d1",reason:"`.global()` tables are D1-backed, so `_generated/app.ts` imports the D1 `ctx.db` adapter"}),e.tables.some(c=>zt(c))&&a.push({name:"@lunora/hyperdrive",reason:'`.global({ backend: "hyperdrive" })` tables route through `@lunora/hyperdrive/global`'},{name:"@lunora/sql-store",reason:'`.global({ backend: "hyperdrive" })` makes `_generated/app.ts` import the `SqlCtxDbOptions` / `SqlExec` types'}),n&&a.push({name:"@lunora/scheduler",reason:"a declared cron (or `ctx.scheduler` use) makes `_generated/app.ts` import `createScheduler`"}),o&&a.push({name:"@lunora/storage",reason:"a `v.storage()` column, a storage access rule (or `ctx.storage` use) makes `_generated/app.ts` import `createStorage`"}),e.vectorIndexes.length>0&&s&&a.push({name:"@lunora/bindings",reason:"`.vectorize()` indexes make `_generated/shard.ts` import `@lunora/bindings/vectors`"});for(const c of r===void 0?[]:se)c.requiredPackage!==void 0&&r?.[c.key]===!0&&a.push({name:c.requiredPackage,reason:`\`ctx.${c.contextProperty??c.key}\` usage makes \`_generated/\` import \`${c.moduleSpecifier}\``});return a.filter((c,u)=>a.findIndex(d=>d.name===c.name)===u)},Wn=(e,t,s={})=>{if(t===void 0)return;const n=Vn(e,s).filter(r=>!t.has(r.name));if(n.length===0)return;const o=n.map(r=>` - ${r.name} — ${r.reason}`).join(`
|
|
2
2
|
`);throw new D("INTERNAL",`@lunora/codegen: this schema's generated code imports packages the project does not declare:
|
|
3
3
|
${o}
|
|
4
4
|
|
package/dist/packem_shared/{buildOpenApiDocument-B886sQ5Z.mjs → buildOpenApiDocument-CyT-_2sB.mjs}
RENAMED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{G as S}from"./emit-
|
|
1
|
+
import{G as S}from"./emit-pX7uKd5t.mjs";import{s as p}from"./paths-C-9fwEgQ.mjs";import{LUNORA_ERROR_CODES as O,objectSchema as h,validatorIrToJsonSchema as u}from"./LUNORA_ERROR_CODES-C2s0xWQD.mjs";const E="/_lunora/rest",A=["authorization","cf-access-jwt-assertion","cookie","x-payment"],f=["x-d1-bookmark","x-lunora-shard-key"],P=e=>[...A,...(e.credentialHeaders??[]).map(t=>t.toLowerCase())],g=e=>Number.isFinite(e)?Math.max(0,Math.floor(e)):0,y=(...e)=>{const t=[];for(const r of e)for(const o of r?.split(",")??[]){const s=o.trim().toLowerCase();s!==""&&!t.includes(s)&&t.push(s)}return t.length===0?void 0:t.join(", ")},T=(e,t)=>{const r=[t,`max-age=${String(g(e.maxAge))}`];return e.staleWhileRevalidate!==void 0&&r.push(`stale-while-revalidate=${String(g(e.staleWhileRevalidate))}`),r.join(", ")},b=e=>e.scope==="public"?y(e.vary,...P(e),...f):y(e.vary,...f),x=e=>{const t=e.indexOf(":");if(!(t<=0||t>=e.length-1||e.indexOf(":",t+1)!==-1))return{name:e.slice(t+1),namespace:e.slice(0,t)}},N=e=>{const t=x(e);if(t!==void 0)return`${E}/${t.namespace}/${t.name}`},k=e=>e==="query"?"GET":"POST",m="#/components/responses/LunoraError",v=/:([A-Za-z_$][\w$]*)/gu,q=e=>[...e.matchAll(v)].map(t=>t[1]),_=e=>e.replaceAll(v,"{$1}"),l=e=>e.kind==="optional"?e.inner??e:e,j=e=>{const t=new Set(q(e.path)),r=[];for(const[o,s]of Object.entries(e.searchParams)){const c=l(s);r.push({description:`Query parameter \`${o}\``,in:"query",name:o,required:s.kind!=="optional",schema:u(c)})}for(const[o,s]of Object.entries(e.params)){const c=l(s);r.push({description:`Path parameter \`${o}\``,in:t.has(o)?"path":"query",name:o,required:t.has(o)?!0:s.kind!=="optional",schema:u(c)})}return r},$=e=>e?{content:{"application/json":{schema:u(e)}},description:"Successful response."}:{content:{"application/json":{schema:{description:"Return shape is TS-inferred (no `.output()` declared); best-effort — any JSON."}}},description:"Successful response. The return shape is TypeScript-inferred and not declared via `.output()`, so it is documented best-effort."},C=e=>{const t=p(e.filePath),r=j(e),o={description:`${e.stream?"Streaming (SSE) ":""}HTTP route handler \`${e.exportName}\` (${e.method} ${e.path}).`,operationId:`${e.method.toLowerCase()}_${p(e.path)}`,responses:{200:$(e.output),204:{description:"No content (handler returned `undefined`)."},default:{$ref:m}},summary:`${e.method} ${e.path}`,tags:[t]};return r.length>0&&(o.parameters=r),Object.keys(e.body).length>0&&(o.requestBody={content:{"application/json":{schema:h(e.body)}},required:!0}),e.stream&&(o["x-lunora-stream"]="text/event-stream"),o},w=e=>{const t=p(e.filePath),r=`${t}:${e.exportName}`,o={additionalProperties:!1,properties:{args:h(e.args),functionPath:{const:r,type:"string"},shardKey:{description:"Optional shard key; omitted routes to the default shard.",type:"string"}},required:["functionPath"],type:"object"};return{operation:{description:`Invoke the \`${e.kind}\` \`${r}\` over the Lunora RPC envelope (POST /_lunora/rpc).`,operationId:r,requestBody:{content:{"application/json":{schema:o}},required:!0},responses:{200:$(e.output),default:{$ref:m}},summary:`${e.kind}: ${r}`,tags:[t],"x-lunora-function-kind":e.kind},pathKey:`/_lunora/rpc#${r}`}},D=(e,t)=>{if(e===void 0||t!=="get"||e.scope===void 0||e.maxAge===void 0)return{};const r={maxAge:e.maxAge,scope:e.scope,...e.staleWhileRevalidate===void 0?{}:{staleWhileRevalidate:e.staleWhileRevalidate},...e.tag===void 0?{}:{tag:e.tag},...e.vary===void 0?{}:{vary:e.vary}},o={"Cache-Control":{description:r.scope==="public"?"Caching policy. `public` applies only to an uncredentialed request — a request carrying `Authorization` or `Cookie` is always answered `private`.":"Caching policy. Restricted to the caller's own cache; never stored by a shared/edge cache.",schema:{example:T(r,r.scope),type:"string"}}};r.tag!==void 0&&(o["Cache-Tag"]={description:"Purge tag for `ctx.cache.purge({ tags: [...] })`.",schema:{example:r.tag,type:"string"}});const s=b(r);return s!==void 0&&(o.Vary={description:"Request headers this response varies by. The endpoint's own negotiated headers are merged in at runtime.",schema:{example:s,type:"string"}}),{headers:o}},L=e=>{const t=p(e.filePath),r=`${t}:${e.exportName}`,o=N(r);if(o===void 0)return;const s=k(e.kind),c=s==="GET",d={description:`Public REST endpoint for the \`${e.kind}\` \`${r}\` (opt-in via \`.expose({ rest: true })\`). Routed through the procedure, so auth / RLS / validators are enforced.`,operationId:`rest_${p(o)}`,responses:{200:{content:{"application/json":{schema:{description:"Procedure result. The shape is TS-inferred from the return type; best-effort — any JSON."}}},description:"Successful result (TypeScript-inferred return shape, documented best-effort).",...D(e.expose?.cache,c?"get":"post")},default:{$ref:m}},summary:`${s} ${o}`,tags:[t],"x-lunora-function-kind":e.kind};if(c){const n=Object.entries(e.args).map(([a,i])=>{const R=l(i);return{description:`Argument \`${a}\` (JSON-encoded for non-string values).`,in:"query",name:a,required:i.kind!=="optional",schema:u(R)}});return n.length>0&&(d.parameters=n),{method:"get",operation:d,path:o}}return d.requestBody={content:{"application/json":{schema:h(e.args)}},required:Object.keys(e.args).length>0},{method:"post",operation:d,path:o}},I=e=>{const t=e.version??"0.0.0",r={},o=new Set;for(const n of e.httpRoutes){const a=_(n.path),i=r[a]??{};i[n.method.toLowerCase()]=C(n),r[a]=i,o.add(p(n.filePath))}const s=e.functions.filter(n=>n.visibility!=="internal"&&n.kind!=="stream");for(const n of s){const{operation:a,pathKey:i}=w(n);r[i]={post:a},o.add(p(n.filePath))}for(const n of s){if(n.expose?.rest!==!0)continue;const a=L(n);if(a===void 0)continue;const i=r[a.path]??{};i[a.method]=a.operation,r[a.path]=i}const c=[...o].toSorted((n,a)=>n.localeCompare(a)).map(n=>({description:`Operations declared in \`lunora/${n}\`.`,name:n}));return{components:{responses:{LunoraError:{content:{"application/json":{schema:{additionalProperties:!1,description:"Standard Lunora error envelope.",properties:{error:{additionalProperties:!1,properties:{code:{description:"Machine-readable error code. Clients switch on this value.",enum:O,type:"string"},message:{description:"Human-readable error message (never echoes internal details).",type:"string"}},required:["code","message"],type:"object"}},required:["error"],type:"object"}}},description:"A Lunora error response. The HTTP status reflects the error code (e.g. BAD_REQUEST→400, UNAUTHORIZED→401, FORBIDDEN→403, NOT_FOUND→404)."}}},info:{description:"Auto-generated from @lunora/values-typed functions by @lunora/codegen. Do not edit — run `lunora codegen` to regenerate.",title:"Lunora API",version:t},openapi:"3.1.0",paths:r,tags:c}},J=e=>`${JSON.stringify(I(e),void 0,2)}
|
|
2
2
|
`,U=e=>`${S}export const openApiSpec: Record<string, unknown> = ${JSON.stringify(e,void 0,4)};
|
|
3
3
|
`;export{I as buildOpenApiDocument,J as emitOpenApi,U as emitOpenApiModule};
|
|
@@ -15,36 +15,36 @@ import{agentComponent as pt}from"@lunora/agent/component";import{LunoraError as
|
|
|
15
15
|
/**
|
|
16
16
|
* R2 SQL over Apache Iceberg tables (window functions, DISTINCT, set operations). Non-deterministic — available only in actions. Reads here are NOT tracked by Lunora live queries.
|
|
17
17
|
*/
|
|
18
|
-
readonly r2sql: import("@lunora/bindings/r2sql").R2SqlClient;`,tier:"action"}},{contextProperty:"scheduler",key:"scheduler",moduleSpecifier:"@lunora/scheduler"},{contextProperty:"storage",key:"storage",moduleSpecifier:"@lunora/storage"},{appMethod:{configKey:"vectors",doc:"Wire the Vectorize index map backing `ctx.vectors`.",method:"vectors"},contextProperty:"vectors",key:"vectors",moduleSpecifier:"@lunora/bindings/vectors"},{contextProperty:"workflows",key:"workflows",moduleSpecifier:"@lunora/workflow"}],In=mt,Cn=new Map(In.flatMap(e=>e.serverCtxField?[[e.key,e.serverCtxField]]:[])),co=mt.flatMap(e=>"appMethod"in e?[{appMethod:e.appMethod,key:e.key}]:[]),gt=/^(?:"(?:[^"\\]|\\(?:["\\/bfnrt]|u[0-9A-Fa-f]{4}))*"|'[^'\\]*'|-?\d+(?:\.\d+)?|true|false|null)$/u,
|
|
18
|
+
readonly r2sql: import("@lunora/bindings/r2sql").R2SqlClient;`,tier:"action"}},{contextProperty:"scheduler",key:"scheduler",moduleSpecifier:"@lunora/scheduler"},{contextProperty:"storage",key:"storage",moduleSpecifier:"@lunora/storage"},{appMethod:{configKey:"vectors",doc:"Wire the Vectorize index map backing `ctx.vectors`.",method:"vectors"},contextProperty:"vectors",key:"vectors",moduleSpecifier:"@lunora/bindings/vectors"},{contextProperty:"workflows",key:"workflows",moduleSpecifier:"@lunora/workflow"}],In=mt,Cn=new Map(In.flatMap(e=>e.serverCtxField?[[e.key,e.serverCtxField]]:[])),co=mt.flatMap(e=>"appMethod"in e?[{appMethod:e.appMethod,key:e.key}]:[]),gt=/^(?:"(?:[^"\\]|\\(?:["\\/bfnrt]|u[0-9A-Fa-f]{4}))*"|'[^'\\]*'|-?\d+(?:\.\d+)?|true|false|null)$/u,Dn=new Set(["any","bigint","boolean","date","id","null","number","storage","string","timestamp"]),ft=e=>e.column!==void 0,Ln=(e,t)=>{switch(e){case"bigint":return`if (typeof ${t} !== "bigint") return DEFER;
|
|
19
19
|
`;case"boolean":return`if (typeof ${t} !== "boolean") return DEFER;
|
|
20
20
|
`;case"date":case"number":case"timestamp":return`if (typeof ${t} !== "number" || !Number.isFinite(${t})) return DEFER;
|
|
21
21
|
`;case"null":return`if (${t} !== null) return DEFER;
|
|
22
22
|
`;default:return`if (typeof ${t} !== "string") return DEFER;
|
|
23
23
|
`}},En=(e,t)=>e.stringMaxLength===void 0?"":`if (${t}.length > ${String(e.stringMaxLength)}) return DEFER;
|
|
24
24
|
`,_n=(e,t)=>{const n=e.literalValue?.trim();if(!(n===void 0||!gt.test(n)))return{out:t,pre:`if (${t} !== ${n}) return DEFER;
|
|
25
|
-
`}},Ge=(e,t,n)=>{if(!ft(e)&&!(e.unmodelledRefinement||e.sourceText!==void 0)){if(
|
|
26
|
-
const ${
|
|
25
|
+
`}},Ge=(e,t,n)=>{if(!ft(e)&&!(e.unmodelledRefinement||e.sourceText!==void 0)){if(Dn.has(e.kind))return e.kind==="any"?{out:t,pre:""}:{out:t,pre:Ln(e.kind,t)+En(e,t)};switch(e.kind){case"array":return Pn(e,t,n);case"literal":return _n(e,t);case"object":return Bn(e,t,n);default:return}}},Pn=(e,t,n)=>{const{inner:r}=e;if(!r)return;const o=n.next(),a=`__arr${String(o)}`,i=`__i${String(o)}`,s=`__e${String(o)}`,c=Ge(r,s,n);if(!c)return;const d=`if (!Array.isArray(${t})) return DEFER;
|
|
26
|
+
const ${a} = new Array(${t}.length);
|
|
27
27
|
for (let ${i} = 0; ${i} < ${t}.length; ${i}++) {
|
|
28
|
-
const ${
|
|
29
|
-
${c.pre}${
|
|
28
|
+
const ${s} = ${t}[${i}];
|
|
29
|
+
${c.pre}${a}[${i}] = ${c.out};
|
|
30
30
|
}
|
|
31
|
-
`;return{out:
|
|
31
|
+
`;return{out:a,pre:d}},Mn=(e,t,n,r)=>{const o=JSON.stringify(e);if(t.kind==="optional"){if(t.hasRefinement||t.sourceText!==void 0||ft(t))return;const{inner:i}=t;if(!i)return;const s=Ge(i,n,r);if(!s)return;const c=r.next(),d=`__has${String(c)}`,h=`__val${String(c)}`,g=`let ${d} = false;
|
|
32
32
|
let ${h};
|
|
33
33
|
if (${n} !== undefined) {
|
|
34
|
-
${
|
|
34
|
+
${s.pre}${h} = ${s.out};
|
|
35
35
|
${d} = true;
|
|
36
36
|
}
|
|
37
|
-
`;return{entry:`...(${d} ? { ${o}: ${h} } : {})`,pre:g}}const
|
|
38
|
-
`,c=h}const d=Mn(
|
|
39
|
-
`},Bn=(e,t,n)=>{const r=e.shape??{},o=bt(r,t,n);if(!o)return;const
|
|
37
|
+
`;return{entry:`...(${d} ? { ${o}: ${h} } : {})`,pre:g}}const a=Ge(t,n,r);if(a)return{entry:`${o}: ${a.out}`,pre:a.pre}},Fn=new Set(Object.getOwnPropertyNames(Object.prototype)),bt=(e,t,n)=>{let r="";const o=[];for(const a of Object.keys(e)){const i=e[a];if(!i)return;const s=JSON.stringify(a);let c=`${t}[${s}]`;if(Fn.has(a)){const h=`__f${String(n.next())}`;r+=`const ${h} = Object.hasOwn(${t}, ${s}) ? ${t}[${s}] : undefined;
|
|
38
|
+
`,c=h}const d=Mn(a,i,c,n);if(!d)return;r+=d.pre,o.push(d.entry)}return{entries:o.join(", "),pre:r}},yt=e=>{const t=`Object.getPrototypeOf(${e})`;return`if (${t} !== Object.prototype && ${t} !== null) return DEFER;
|
|
39
|
+
`},Bn=(e,t,n)=>{const r=e.shape??{},o=bt(r,t,n);if(!o)return;const a=n.next(),i=`__obj${String(a)}`,s=`if (typeof ${t} !== "object" || ${t} === null || Array.isArray(${t})) return DEFER;
|
|
40
40
|
${yt(t)}${o.pre}const ${i} = { ${o.entries} };
|
|
41
|
-
`;return{out:i,pre:
|
|
41
|
+
`;return{out:i,pre:s}},qn=e=>{let t=0;const r=bt(e,"source",{next:()=>(t+=1,t)});if(r)return`(source) => {
|
|
42
42
|
if (typeof source !== "object" || source === null || Array.isArray(source)) return DEFER;
|
|
43
43
|
${yt("source")}${r.pre}return { ${r.entries} };
|
|
44
|
-
}`},
|
|
44
|
+
}`},S=`// GENERATED by @lunora/codegen — do not edit.
|
|
45
45
|
// Run \`lunora codegen\` to regenerate.
|
|
46
46
|
|
|
47
|
-
`,ae=(e=!1)=>e?{client:"lunorash/client",do:"lunorash/do",flags:"lunorash/flags",server:"lunorash/server",serverDataModel:"lunorash/server/data-model",serverDrizzle:"lunorash/server/drizzle",serverTypes:"lunorash/server/types",values:"lunorash/values"}:{client:"@lunora/client",do:"@lunora/do",flags:"@lunora/flags",server:"@lunora/server",serverDataModel:"@lunora/server/data-model",serverDrizzle:"@lunora/server/drizzle",serverTypes:"@lunora/server/types",values:"@lunora/values"},wt=/^[A-Za-z_$][\w$]*$/u,jn=/^[\w./-]+$/u,f=(e,t)=>{if(!wt.test(e))throw new X("INTERNAL",`@lunora/codegen: ${t} is not a valid JS identifier: ${JSON.stringify(e)}`)},He=e=>e.charAt(0).toUpperCase()+e.slice(1),q=e=>wt.test(e)?e:JSON.stringify(e),Y=e=>e==="__proto__"?`[${JSON.stringify(e)}]`:q(e),Wn={any:"unknown",bigint:"bigint",boolean:"boolean",bytes:"ArrayBuffer",date:"number",geoPoint:"{ lat: number; lng: number }",null:"null",number:"number",storage:"string",string:"string",timestamp:"number"},Un=e=>{if(e===void 0)return"unknown";if(!gt.test(e))throw new X("INTERNAL",`@lunora/codegen: v.literal() argument is not a parseable string/number/boolean/null literal: ${JSON.stringify(e)}`);return e},T=e=>{const t=Wn[e.kind];if(t!==void 0)return t;switch(e.kind){case"array":return`Array<${e.inner?T(e.inner):"unknown"}>`;case"from":return e.tsType??"unknown";case"id":{const n=e.tableName??"_unknown_";return f(n,"v.id() table name"),`Id<"${n}">`}case"literal":return Un(e.literalValue);case"object":return e.shape?`{ ${Object.entries(e.shape).map(([r,o])=>kt(r,o)).join("; ")} }`:"Record<string, unknown>";case"optional":return`${e.inner?T(e.inner):"unknown"} | undefined`;case"record":{const n=e.keyType?T(e.keyType):"string",r=e.valueType?T(e.valueType):"unknown";return`Record<${n}, ${r}>`}case"union":return e.members&&e.members.length>0?e.members.map(n=>T(n)).join(" | "):"never";default:return"unknown"}},kt=(e,t)=>{const n=q(e);if(t.kind==="optional"){const r=t.inner?T(t.inner):"unknown";return`${n}?: ${r}`}return On(t)?`${n}?: ${T(t)}`:`${n}: ${T(t)}`},xe=e=>{const t=Object.entries(e);return t.length===0?"{}":`{ ${t.map(([n,r])=>kt(n,r)).join("; ")} }`},xt=e=>e.kind==="optional"||!!e.column?.hasDefault,se=e=>e.kind==="optional"&&e.inner?e.inner:e,Kn=e=>{f(e.name,"table name");const t=Object.entries(e.shape).map(([r,o])=>{const
|
|
47
|
+
`,ae=(e=!1)=>e?{client:"lunorash/client",do:"lunorash/do",flags:"lunorash/flags",server:"lunorash/server",serverDataModel:"lunorash/server/data-model",serverDrizzle:"lunorash/server/drizzle",serverTypes:"lunorash/server/types",values:"lunorash/values"}:{client:"@lunora/client",do:"@lunora/do",flags:"@lunora/flags",server:"@lunora/server",serverDataModel:"@lunora/server/data-model",serverDrizzle:"@lunora/server/drizzle",serverTypes:"@lunora/server/types",values:"@lunora/values"},wt=/^[A-Za-z_$][\w$]*$/u,jn=/^[\w./-]+$/u,f=(e,t)=>{if(!wt.test(e))throw new X("INTERNAL",`@lunora/codegen: ${t} is not a valid JS identifier: ${JSON.stringify(e)}`)},He=e=>e.charAt(0).toUpperCase()+e.slice(1),q=e=>wt.test(e)?e:JSON.stringify(e),Y=e=>e==="__proto__"?`[${JSON.stringify(e)}]`:q(e),Wn={any:"unknown",bigint:"bigint",boolean:"boolean",bytes:"ArrayBuffer",date:"number",geoPoint:"{ lat: number; lng: number }",null:"null",number:"number",storage:"string",string:"string",timestamp:"number"},Un=e=>{if(e===void 0)return"unknown";if(!gt.test(e))throw new X("INTERNAL",`@lunora/codegen: v.literal() argument is not a parseable string/number/boolean/null literal: ${JSON.stringify(e)}`);return e},T=e=>{const t=Wn[e.kind];if(t!==void 0)return t;switch(e.kind){case"array":return`Array<${e.inner?T(e.inner):"unknown"}>`;case"from":return e.tsType??"unknown";case"id":{const n=e.tableName??"_unknown_";return f(n,"v.id() table name"),`Id<"${n}">`}case"literal":return Un(e.literalValue);case"object":return e.shape?`{ ${Object.entries(e.shape).map(([r,o])=>kt(r,o)).join("; ")} }`:"Record<string, unknown>";case"optional":return`${e.inner?T(e.inner):"unknown"} | undefined`;case"record":{const n=e.keyType?T(e.keyType):"string",r=e.valueType?T(e.valueType):"unknown";return`Record<${n}, ${r}>`}case"union":return e.members&&e.members.length>0?e.members.map(n=>T(n)).join(" | "):"never";default:return"unknown"}},kt=(e,t)=>{const n=q(e);if(t.kind==="optional"){const r=t.inner?T(t.inner):"unknown";return`${n}?: ${r}`}return On(t)?`${n}?: ${T(t)}`:`${n}: ${T(t)}`},xe=e=>{const t=Object.entries(e);return t.length===0?"{}":`{ ${t.map(([n,r])=>kt(n,r)).join("; ")} }`},xt=e=>e.kind==="optional"||!!e.column?.hasDefault,se=e=>e.kind==="optional"&&e.inner?e.inner:e,Kn=e=>{f(e.name,"table name");const t=Object.entries(e.shape).map(([r,o])=>{const a=se(o),i=T(a),s=q(r);return xt(o)?` ${s}?: ${i};`:` ${s}: ${i};`}).join(`
|
|
48
48
|
`),n=t?`
|
|
49
49
|
${t}
|
|
50
50
|
`:"";return`export interface Insert_${e.name} {
|
|
@@ -52,15 +52,15 @@ ${t}
|
|
|
52
52
|
_creationTime?: number;${n}}`},Je="schema",uo=e=>{for(const u of e.tables)f(u.name,"table name");const t=e.tables.map(u=>`"${u.name}"`).join(" | ")||"never",n=e.tables.filter(u=>u.extensionKey===void 0).map(u=>`"${u.name}"`).join(" | ")||"never",r=e.tables.map(u=>{const l=Object.entries(u.shape).map(([x,v])=>{const $=q(x);if(v.kind==="optional"){const A=v.inner?T(v.inner):"unknown";return` ${$}?: ${A};`}return` ${$}: ${T(v)};`}).join(`
|
|
53
53
|
`),b=l?`
|
|
54
54
|
${l}
|
|
55
|
-
`:"",
|
|
55
|
+
`:"",R=u.commitOrdered===!0?`
|
|
56
56
|
_commitSeq: number;`:"";return`export interface Doc_${u.name} {
|
|
57
57
|
_id: Id<"${u.name}">;
|
|
58
|
-
_creationTime: number;${
|
|
58
|
+
_creationTime: number;${R}${b}}`}).join(`
|
|
59
59
|
|
|
60
60
|
`),o=e.tables.map(u=>` ${u.name}: Doc_${u.name};`).join(`
|
|
61
|
-
`),
|
|
61
|
+
`),a=e.tables.map(u=>{const l=u.indexes.map(b=>JSON.stringify(b.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
|
|
62
62
|
`),i=e.tables.map(u=>{const l=u.searchIndexes.map(b=>JSON.stringify(b.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
|
|
63
|
-
`),
|
|
63
|
+
`),s=e.tables.map(u=>{const l=u.rankIndexes.map(b=>JSON.stringify(b.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
|
|
64
64
|
`),c=e.tables.map(u=>{const l=u.shardMode==="global"?"":(u.geoIndexes??[]).map(b=>JSON.stringify(b.name)).join(" | ");return` ${u.name}: ${l||"never"};`}).join(`
|
|
65
65
|
`),d=e.vectorIndexes.map(u=>JSON.stringify(u.name)).join(" | ")||"never",h=e.tables.map(u=>Kn(u)).join(`
|
|
66
66
|
|
|
@@ -69,7 +69,7 @@ ${l}
|
|
|
69
69
|
`);return l?` ${u.name}: {
|
|
70
70
|
${l}
|
|
71
71
|
};`:` ${u.name}: {};`}).join(`
|
|
72
|
-
`);return
|
|
72
|
+
`);return L(`${S}export type TableName = ${t};
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
75
|
* The tables **this app declared** — every {@link TableName} except those an add-on
|
|
@@ -103,7 +103,7 @@ export type Doc<T extends keyof DataModel> = DataModel[T];
|
|
|
103
103
|
* Used by \`TableReader.withIndex()\` to constrain callers to declared names.
|
|
104
104
|
*/
|
|
105
105
|
export interface IndexNamesByTable {
|
|
106
|
-
${
|
|
106
|
+
${a}
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
export type IndexName<T extends keyof DataModel> = IndexNamesByTable[T];
|
|
@@ -117,7 +117,7 @@ export type SearchIndexName<T extends keyof DataModel> = SearchIndexNamesByTable
|
|
|
117
117
|
|
|
118
118
|
/** Per-table rank-index name union. \`never\` for tables without a rankIndex. */
|
|
119
119
|
export interface RankIndexNamesByTable {
|
|
120
|
-
${
|
|
120
|
+
${s}
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
export type RankIndexName<T extends keyof DataModel> = RankIndexNamesByTable[T];
|
|
@@ -161,7 +161,7 @@ export interface Relations {
|
|
|
161
161
|
${y}
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
`,Je)},Qn=/import\("(?<spec>(?:\.\.?\/)*_generated\/[^"]+)"\)/gu,vt=/^(?:\.\.?\/)*_generated\//u,
|
|
164
|
+
`,Je)},Qn=/import\("(?<spec>(?:\.\.?\/)*_generated\/[^"]+)"\)/gu,vt=/^(?:\.\.?\/)*_generated\//u,St=/\.[A-Za-z]\w*$/u,Vn=e=>e.replaceAll(Qn,(t,n)=>{const r=n.replace(vt,"./");return`import("${St.test(r)?r:`${r}.js`}")`}),Hn=/import\("(?<spec>[^"]+)"\)/gu,dt="node_modules/",Gn=/^@types\//u,Jn=e=>e.replaceAll(Hn,(t,n)=>{const r=n.lastIndexOf(dt);if(r===-1||r>0&&n[r-1]!=="/")return t;const o=n.slice(r+dt.length);return o===""||Gn.test(o)?t:`import("${o}")`}),zn=/import\("(?<spec>\.\.?\/[^"]+)"\)/gu,Yn=/^(?:\.\.?\/)+/u,Xn=e=>{const t=[];for(const n of e.split("/"))if(!(n===""||n===".")){if(n===".."&&t.length>0&&t.at(-1)!==".."){t.pop();continue}t.push(n)}return t.join("/")},Zn=(e,t)=>e.replaceAll(zn,(n,r)=>{if(vt.test(r.replace(Yn,"")))return n;const o=t.includes("/")?t.slice(0,t.lastIndexOf("/")):"",i=`../${Xn(`${o}/${r}`)}`;return`import("${St.test(i)?i:`${i}.js`}")`}),L=(e,t)=>Vn(Zn(Jn(e),t)),er=["client","do","errors","flags","observability","platform","ratelimit","runtime","server","values"],tr=new RegExp(String.raw`import\("@lunora/(?<pkg>${er.join("|")})(?<subpath>/[^"]*)?"\)`,"gu"),nr={flags:new Set(["/web"]),platform:new Set},Rt=(e,t)=>t?e.replaceAll(tr,(n,r,o)=>{const a=nr[r];return o&&a&&!a.has(o)?n:`import("lunorash/${r}${o??""}")`}):e,ze=e=>["Doc","Id"].filter(t=>new RegExp(String.raw`(?<![.$\w])${t}<`,"u").test(e)),$t=e=>e.output===void 0||e.output.kind==="any"||e.kind==="stream"?e.returnType:T(e.output),Ye=e=>{const t=new Map;for(const n of e){const r=t.get(n.filePath)??[];r.push(n),t.set(n.filePath,r)}return[...t.entries()].toSorted(([n],[r])=>n.localeCompare(r))},ut=e=>{const t=([n,r])=>{const o=r.toSorted((a,i)=>a.exportName.localeCompare(i.exportName)).map(a=>{const i=L(xe(a.args),a.filePath),s=L($t(a),a.filePath);return` ${a.exportName}: FunctionReference<"${a.kind}", ${i}, ${s}>;`}).join(`
|
|
165
165
|
`);return` ${q(N(n))}: {
|
|
166
166
|
${o}
|
|
167
167
|
};`};return Ye(e).map(n=>t(n)).join(`
|
|
@@ -173,32 +173,32 @@ export interface WorkflowReference<Params = Record<string, unknown>> {
|
|
|
173
173
|
readonly binding: string;
|
|
174
174
|
readonly name: string;
|
|
175
175
|
}
|
|
176
|
-
`,e.length>0){const o=[...e].toSorted((
|
|
177
|
-
`),i=o.map(
|
|
176
|
+
`,e.length>0){const o=[...e].toSorted((s,c)=>s.exportName.localeCompare(c.exportName)),a=o.map(s=>` ${s.exportName}: WorkflowReference<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${s.exportName}>>;`).join(`
|
|
177
|
+
`),i=o.map(s=>` ${Y(s.exportName)}: { isLunoraWorkflow: true, binding: ${JSON.stringify(s.bindingName)}, name: ${JSON.stringify(s.exportName)} },`).join(`
|
|
178
178
|
`);r+=`
|
|
179
179
|
/** This project's durable workflows, addressable as typed references (e.g. \`crons.daily("digest", …, workflows.digestPipeline, params)\`). */
|
|
180
180
|
export interface WorkflowsRef {
|
|
181
|
-
${
|
|
181
|
+
${a}
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
export const workflows: WorkflowsRef = {
|
|
185
185
|
${i}
|
|
186
186
|
};
|
|
187
187
|
`,n.push(`import type * as lunoraWorkflowDefinitions from "../workflows.js";
|
|
188
|
-
`)}if(t.length>0){const o=[...t].toSorted((
|
|
189
|
-
`),i=o.map(
|
|
188
|
+
`)}if(t.length>0){const o=[...t].toSorted((s,c)=>s.exportName.localeCompare(c.exportName)),a=o.map(s=>` ${s.exportName}: WorkflowReference<AgentRunInput>;`).join(`
|
|
189
|
+
`),i=o.map(s=>` ${Y(s.exportName)}: { isLunoraWorkflow: true, binding: ${JSON.stringify(s.bindingName)}, name: ${JSON.stringify(s.name)} },`).join(`
|
|
190
190
|
`);r+=`
|
|
191
191
|
/** This project's durable agents, addressable as typed references for \`cronJobs()\` — each fire starts a fresh agent run (e.g. \`crons.daily("sweep", …, agents.support, { input, threadKey })\`). */
|
|
192
192
|
export interface AgentsRef {
|
|
193
|
-
${
|
|
193
|
+
${a}
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
export const agents: AgentsRef = {
|
|
197
197
|
${i}
|
|
198
198
|
};
|
|
199
199
|
`,n.push(`import type { AgentRunInput } from "@lunora/agent";
|
|
200
|
-
`)}return{block:r,importLine:n.join("")}},or=()=>Object.keys(pt().functions).toSorted((e,t)=>e.localeCompare(t)),Tt=e=>new Set(e.filter(t=>N(t.filePath)==="agents").map(t=>t.exportName)),ar=()=>new Set(Object.entries(pt().functions).filter(([,e])=>e.visibility==="internal").map(([e])=>e)),sr=(e,t)=>{const n={importLine:"",lines:"",prelude:""};if(e.length===0)return n;const r=Tt(t),o=ar(),
|
|
201
|
-
`,lines:i.map(
|
|
200
|
+
`)}return{block:r,importLine:n.join("")}},or=()=>Object.keys(pt().functions).toSorted((e,t)=>e.localeCompare(t)),Tt=e=>new Set(e.filter(t=>N(t.filePath)==="agents").map(t=>t.exportName)),ar=()=>new Set(Object.entries(pt().functions).filter(([,e])=>e.visibility==="internal").map(([e])=>e)),sr=(e,t)=>{const n={importLine:"",lines:"",prelude:""};if(e.length===0)return n;const r=Tt(t),o=ar(),a=t.find(s=>N(s.filePath)==="agents"&&o.has(s.exportName));if(a)throw new X("INTERNAL",`@lunora/codegen: "agents:${a.exportName}" is reserved for the durable agent loop's internal dispatch — rename the "${a.exportName}" export in ${a.filePath}`);const i=or().filter(s=>!r.has(s));return i.length===0?n:{importLine:`import { agentComponent } from "@lunora/agent/component";
|
|
201
|
+
`,lines:i.map(s=>` "agents:${s}": lunoraAgentRuntimeFunctions.${s} as unknown as RegisteredLunoraFunction,`).join(`
|
|
202
202
|
`),prelude:`
|
|
203
203
|
/**
|
|
204
204
|
* The \`@lunora/agent\` runtime component — auto-registered because \`lunora/agents.ts\`
|
|
@@ -207,11 +207,11 @@ ${i}
|
|
|
207
207
|
*/
|
|
208
208
|
const lunoraAgentRuntimeFunctions = agentComponent().functions;
|
|
209
209
|
`}},ir=(e,t)=>{if(!e)return{importLine:"",lines:"",prelude:""};const n=t.find(r=>N(r.filePath)==="sandbox"&&r.exportName==="invoke");if(n)throw new X("INTERNAL",`@lunora/codegen: "sandbox:invoke" is reserved for the batteries-included sandbox tool dispatcher (browserTool/containerTool) — rename the "invoke" export in ${n.filePath}`);return{importLine:`import { sandboxComponent } from "@lunora/agent/component";
|
|
210
|
-
`,lines:' "sandbox:invoke": lunoraSandbox.invoke as unknown as RegisteredLunoraFunction,',prelude:"\n/**\n * The `@lunora/agent` sandbox dispatcher — auto-registered because `lunora/`\n * imports a sandbox tool (`browserTool`/`containerTool`). The batteries-included\n * tools dispatch to this internal action, which runs on an action ctx carrying\n * `ctx.browser` + `ctx.containers` (the durable tool step itself has neither).\n */\nconst lunoraSandbox = sandboxComponent();\n"}},lr=(e,t)=>{if(e.length===0)return[];const n=Tt(t),r=[{args:{key:{kind:"string"},limit:{inner:{kind:"number"},kind:"optional"}},exportName:"agentMessages",filePath:"agents",kind:"query",returnType:"Record<string, unknown>[]"},{args:{decision:{kind:"union",members:[{kind:"literal",literalValue:'"approve"'},{kind:"literal",literalValue:'"reject"'}]},instanceId:{kind:"string"},note:{inner:{kind:"string"},kind:"optional"},threadKey:{kind:"string"},toolCallId:{kind:"string"}},exportName:"agentResolveApproval",filePath:"agents",kind:"mutation",returnType:"{ resolved: boolean }"},{args:{agent:{kind:"string"},input:{kind:"string"},threadKey:{kind:"string"},title:{inner:{kind:"string"},kind:"optional"}},exportName:"agentRun",filePath:"agents",kind:"mutation",returnType:"{ id: string; threadKey: string }"},{args:{key:{kind:"string"}},exportName:"agentState",filePath:"agents",kind:"query",returnType:"Record<string, unknown> | undefined"},{args:{key:{kind:"string"}},exportName:"agentThread",filePath:"agents",kind:"query",returnType:"Record<string, unknown> | undefined"}];for(const o of e)o.voice&&r.push({args:{threadKey:{kind:"string"}},exportName:`${o.exportName}Voice`,filePath:"agents",kind:"stream",returnType:"Record<string, unknown>"});return r.filter(o=>!n.has(o.exportName))},cr=(e,t)=>{if(e.length===0)return[];const n=new Set(t.filter(r=>N(r.filePath)==="mutators").map(r=>r.exportName));return e.filter(r=>!n.has(r.exportName)).map(r=>({args:r.args,exportName:r.exportName,filePath:r.filePath,kind:"mutation",returnType:r.returnType}))},dr=e=>{const t=e.filter(i=>i.stream);if(t.length===0)return{block:"",body:""};const n=Ye(t),r=n.map(([i,
|
|
210
|
+
`,lines:' "sandbox:invoke": lunoraSandbox.invoke as unknown as RegisteredLunoraFunction,',prelude:"\n/**\n * The `@lunora/agent` sandbox dispatcher — auto-registered because `lunora/`\n * imports a sandbox tool (`browserTool`/`containerTool`). The batteries-included\n * tools dispatch to this internal action, which runs on an action ctx carrying\n * `ctx.browser` + `ctx.containers` (the durable tool step itself has neither).\n */\nconst lunoraSandbox = sandboxComponent();\n"}},lr=(e,t)=>{if(e.length===0)return[];const n=Tt(t),r=[{args:{key:{kind:"string"},limit:{inner:{kind:"number"},kind:"optional"}},exportName:"agentMessages",filePath:"agents",kind:"query",returnType:"Record<string, unknown>[]"},{args:{decision:{kind:"union",members:[{kind:"literal",literalValue:'"approve"'},{kind:"literal",literalValue:'"reject"'}]},instanceId:{kind:"string"},note:{inner:{kind:"string"},kind:"optional"},threadKey:{kind:"string"},toolCallId:{kind:"string"}},exportName:"agentResolveApproval",filePath:"agents",kind:"mutation",returnType:"{ resolved: boolean }"},{args:{agent:{kind:"string"},input:{kind:"string"},threadKey:{kind:"string"},title:{inner:{kind:"string"},kind:"optional"}},exportName:"agentRun",filePath:"agents",kind:"mutation",returnType:"{ id: string; threadKey: string }"},{args:{key:{kind:"string"}},exportName:"agentState",filePath:"agents",kind:"query",returnType:"Record<string, unknown> | undefined"},{args:{key:{kind:"string"}},exportName:"agentThread",filePath:"agents",kind:"query",returnType:"Record<string, unknown> | undefined"}];for(const o of e)o.voice&&r.push({args:{threadKey:{kind:"string"}},exportName:`${o.exportName}Voice`,filePath:"agents",kind:"stream",returnType:"Record<string, unknown>"});return r.filter(o=>!n.has(o.exportName))},cr=(e,t)=>{if(e.length===0)return[];const n=new Set(t.filter(r=>N(r.filePath)==="mutators").map(r=>r.exportName));return e.filter(r=>!n.has(r.exportName)).map(r=>({args:r.args,exportName:r.exportName,filePath:r.filePath,kind:"mutation",returnType:r.returnType}))},dr=e=>{const t=e.filter(i=>i.stream);if(t.length===0)return{block:"",body:""};const n=Ye(t),r=n.map(([i,s])=>{const c=s.map(d=>{const h=L(d.chunkType??"unknown",d.filePath),g=L(xe(d.searchParams),d.filePath),y=L(xe(d.params),d.filePath);return` ${q(d.exportName)}: HttpStreamRef<${h}, ${g}, ${y}>;`}).join(`
|
|
211
211
|
`);return` ${q(N(i))}: {
|
|
212
212
|
${c}
|
|
213
213
|
};`}).join(`
|
|
214
|
-
`),o=n.map(([i,
|
|
214
|
+
`),o=n.map(([i,s])=>{const c=s.map(d=>` ${Y(d.exportName)}: { method: ${JSON.stringify(d.method)}, path: ${JSON.stringify(d.path)} },`).join(`
|
|
215
215
|
`);return` ${Y(N(i))}: {
|
|
216
216
|
${c}
|
|
217
217
|
},`}).join(`
|
|
@@ -224,15 +224,15 @@ ${r}
|
|
|
224
224
|
export const httpStreams: HttpStreamsRef = {
|
|
225
225
|
${o}
|
|
226
226
|
};
|
|
227
|
-
`,body:r}},ho=e=>{const{agents:t=[],functions:n,httpRoutes:r=[],mutators:o=[],useUmbrella:
|
|
227
|
+
`,body:r}},ho=e=>{const{agents:t=[],functions:n,httpRoutes:r=[],mutators:o=[],useUmbrella:a=!1,workflows:i=[]}=e,s=ae(a),c=[...n.filter(O=>O.visibility!=="internal"),...lr(t,n),...cr(o,n)],d=n.filter(O=>O.visibility==="internal"),h=ut(c),g=ut(d),y=dr(r),u=`${h}
|
|
228
228
|
${g}
|
|
229
229
|
${y.body}`,l=ze(u),b=l.length>0?`
|
|
230
230
|
import type { ${l.join(", ")} } from "./dataModel.js";
|
|
231
|
-
`:"",
|
|
231
|
+
`:"",R=h?`
|
|
232
232
|
${h}
|
|
233
233
|
`:"",x=g?`
|
|
234
234
|
${g}
|
|
235
|
-
`:"",v=rr(i,t),$=`export interface ApiTypes {${
|
|
235
|
+
`:"",v=rr(i,t),$=`export interface ApiTypes {${R}}
|
|
236
236
|
|
|
237
237
|
export const api = anyApi as unknown as ApiTypes;
|
|
238
238
|
|
|
@@ -240,10 +240,10 @@ export const api = anyApi as unknown as ApiTypes;
|
|
|
240
240
|
export interface InternalApiTypes {${x}}
|
|
241
241
|
|
|
242
242
|
export const internal = anyApi as unknown as InternalApiTypes;
|
|
243
|
-
${v.block}${y.block}`,A=[...$.includes("FunctionReference<")?["FunctionReference"]:[],...y.block===""?[]:["HttpStreamRef"]],V=A.length>0?`import type { ${A.join(", ")} } from "${
|
|
244
|
-
`:"";return
|
|
243
|
+
${v.block}${y.block}`,A=[...$.includes("FunctionReference<")?["FunctionReference"]:[],...y.block===""?[]:["HttpStreamRef"]],V=A.length>0?`import type { ${A.join(", ")} } from "${s.client}";
|
|
244
|
+
`:"";return Rt(`${S}import { anyApi } from "${s.client}";
|
|
245
245
|
${V}${v.importLine}${b}
|
|
246
|
-
${$}`,
|
|
246
|
+
${$}`,a)},po=e=>e?`${S}import { createSeedClient as createSeedClientBase } from "@lunora/seed";
|
|
247
247
|
import type { SeedClient, SeedClientOptions } from "@lunora/seed";
|
|
248
248
|
|
|
249
249
|
import schema from "../schema.js";
|
|
@@ -260,7 +260,7 @@ import type { InsertModel } from "./dataModel.js";
|
|
|
260
260
|
* const { posts } = await seed.posts((x) => x([10, 20]));
|
|
261
261
|
*/
|
|
262
262
|
export const createSeedClient = (options?: SeedClientOptions): SeedClient<InsertModel> => createSeedClientBase<InsertModel>(schema, options);
|
|
263
|
-
`:"",mo=(e,t,n=!1)=>{if(e.length===0||!t)return"";const r=ae(n),o=c=>c.table===void 0?"Row":`Doc<${JSON.stringify(c.table)}> & Row`,
|
|
263
|
+
`:"",mo=(e,t,n=!1)=>{if(e.length===0||!t)return"";const r=ae(n),o=c=>c.table===void 0?"Row":`Doc<${JSON.stringify(c.table)}> & Row`,a=e.map(c=>{f(c.exportName,"shape export name");const d=o(c),h=L(xe(c.args),c.filePath),g=Object.keys(c.args).length>0,y=g?` args: ${h};`:` args?: ${h};`,u=g?`(args: ${h}) => void`:`(args?: ${h}) => void`,l=`${c.exportName}CollectionOptions`;return`/** Options for the \`${c.exportName}\` shape binding. */
|
|
264
264
|
export interface ${He(l)} {
|
|
265
265
|
${y}
|
|
266
266
|
/**
|
|
@@ -306,14 +306,14 @@ export const ${c.exportName}Collection = (
|
|
|
306
306
|
return { checkpoints, collection: createCollection(config), scope };
|
|
307
307
|
};`}).join(`
|
|
308
308
|
|
|
309
|
-
`),i=ze(
|
|
310
|
-
`:"";return`${
|
|
309
|
+
`),i=ze(a),s=i.length>0?`import type { ${i.join(", ")} } from "./dataModel.js";
|
|
310
|
+
`:"";return`${S}import type { LunoraClient, SubscriptionError } from "${r.client}";
|
|
311
311
|
import { lunoraCollectionOptions } from "@lunora/db/collections";
|
|
312
312
|
import type { CheckpointRegistry, LunoraCollectionOptions, Row } from "@lunora/db";
|
|
313
313
|
import type { Collection } from "@tanstack/db";
|
|
314
314
|
import { createCollection } from "@tanstack/db";
|
|
315
|
-
${a}
|
|
316
315
|
${s}
|
|
316
|
+
${a}
|
|
317
317
|
`},ur=(e,t)=>`lunora_${N(e)}_${String(t)}`,hr=`const callRegistered = async <R>(context: CallerCtx, functionPath: string, args: Record<string, unknown> | undefined): Promise<R> => {
|
|
318
318
|
const registered = LUNORA_FUNCTIONS[functionPath];
|
|
319
319
|
|
|
@@ -343,12 +343,12 @@ ${s}
|
|
|
343
343
|
}
|
|
344
344
|
|
|
345
345
|
return (await registered.handler(context, args ?? {})) as R;
|
|
346
|
-
};`,pr=(e,t,n=[],r=[])=>{const o=new Map,
|
|
347
|
-
`),
|
|
346
|
+
};`,pr=(e,t,n=[],r=[])=>{const o=new Map,a=l=>{o.has(l)||o.set(l,ur(l,o.size))};for(const l of e)a(l.filePath);for(const l of t)a(l.filePath);for(const l of n)a(l.filePath);for(const l of r)a(l.filePath);const i=[...o.entries()].map(([l,b])=>{if(!jn.test(l))throw new X("INTERNAL",`@lunora/codegen: refusing to emit import for unsafe file path: ${JSON.stringify(l)}`);return`import * as ${b} from "../${l}.js";`}).join(`
|
|
347
|
+
`),s=e.map(l=>` "${N(l.filePath)}:${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredLunoraFunction,`).join(`
|
|
348
348
|
`),c=t.map(l=>` ${JSON.stringify(l.id)}: ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredDataMigration,`).join(`
|
|
349
349
|
`),d=n.map(l=>` "${N(l.filePath)}:${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredLunoraFunction,`).join(`
|
|
350
350
|
`),h=r.map(l=>` "${l.exportName}": ${o.get(l.filePath)??""}.${l.exportName} as unknown as RegisteredShape,`).join(`
|
|
351
|
-
`),g=n.map(l=>`${N(l.filePath)}:${l.exportName}`),y=[
|
|
351
|
+
`),g=n.map(l=>`${N(l.filePath)}:${l.exportName}`),y=[s,d].filter(l=>l.length>0).join(`
|
|
352
352
|
`),u=e.map(l=>{if(l.lifecycle||Object.keys(l.args).length===0)return;const b=qn(l.args);return b===void 0?void 0:`installCompiledValidatorMap(${o.get(l.filePath)??""}.${l.exportName}.args, ${b});`}).filter(l=>l!==void 0).join(`
|
|
353
353
|
`);return{dispatchBody:y.length>0?`
|
|
354
354
|
${y}
|
|
@@ -358,21 +358,21 @@ ${y}
|
|
|
358
358
|
${c}
|
|
359
359
|
`:"",mutatorPaths:g,shapeBody:h.length>0?`
|
|
360
360
|
${h}
|
|
361
|
-
`:""}},mr=e=>{const t=Ye(e),n=t.map(([o,
|
|
361
|
+
`:""}},mr=e=>{const t=Ye(e),n=t.map(([o,a])=>{const i=a.map(s=>{const c=L(xe(s.args),s.filePath),d=c==="{}"?"?":"",h=L($t(s),s.filePath);return s.kind==="stream"?` ${s.exportName}: (args${d}: ${c}) => Promise<AsyncIterable<${h}>>;`:` ${s.exportName}: (args${d}: ${c}) => Promise<${h}>;`}).join(`
|
|
362
362
|
`);return` ${q(N(o))}: {
|
|
363
363
|
${i}
|
|
364
364
|
};`}).join(`
|
|
365
|
-
`);return{implementation:t.map(([o,
|
|
365
|
+
`);return{implementation:t.map(([o,a])=>{const i=N(o),s=a.map(c=>` ${Y(c.exportName)}: (args) => callRegistered(context, "${i}:${c.exportName}", args),`).join(`
|
|
366
366
|
`);return` ${Y(i)}: {
|
|
367
|
-
${
|
|
367
|
+
${s}
|
|
368
368
|
},`}).join(`
|
|
369
|
-
`),types:n}},gr=(e,t=[])=>{const n=new Set;for(const r of e.tables)for(const o of Object.values(r.shape)){const
|
|
369
|
+
`),types:n}},gr=(e,t=[])=>{const n=new Set;for(const r of e.tables)for(const o of Object.values(r.shape)){const a=se(o);a.kind==="storage"&&typeof a.bucket=="string"&&a.bucket!==""&&n.add(a.bucket)}for(const r of t)r!==""&&r!=="default"&&n.add(r);return["default",...[...n].toSorted((r,o)=>r.localeCompare(o))]},go=({agents:e=[],containers:t=[],env:n,hasAccessFacade:r=!1,hasAi:o=!1,hasAnalytics:a=!1,hasBrowser:i=!1,hasVectors:s=!0,hasFlags:c=!1,hasHyperdrive:d=!1,hasImages:h=!1,hasKv:g=!1,hasNotify:y=!1,hasPayments:u=!1,hasPipelines:l=!1,hasR2sql:b=!1,hasX402:R=!1,identity:x,queues:v=[],schema:$,storageRuleBuckets:A=[],useUmbrella:V=!1,workflows:O=[]}={})=>{const C=ae(V),w=gr($??{tables:[]},A).map(p=>JSON.stringify(p)).join(" | "),P=o?`import type { LunoraAi } from "@lunora/ai";
|
|
370
370
|
`:"",M=o?`
|
|
371
371
|
readonly ai: LunoraAi;`:"",ie=u?`import type { LunoraPayment } from "@lunora/payment";
|
|
372
372
|
`:"",le=u?`
|
|
373
|
-
readonly payments: LunoraPayment;`:"",Z=
|
|
374
|
-
`:"",H=
|
|
375
|
-
readonly x402: X402Pay;`:"",
|
|
373
|
+
readonly payments: LunoraPayment;`:"",Z=R?`import type { X402Pay } from "@lunora/x402/pay";
|
|
374
|
+
`:"",H=R?`
|
|
375
|
+
readonly x402: X402Pay;`:"",D=t.length>0?`import type { ContainerAccessor } from "@lunora/container";
|
|
376
376
|
`:"",ee=t.length>0?`
|
|
377
377
|
readonly containers: {${t.map(p=>`
|
|
378
378
|
readonly ${p.exportName}: ContainerAccessor;`).join("")}
|
|
@@ -399,7 +399,7 @@ ${k}`:""}
|
|
|
399
399
|
}
|
|
400
400
|
|
|
401
401
|
/** Alias for {@link CloudflareBindings} — the typed shape of \`env\`. */
|
|
402
|
-
export type Env = CloudflareBindings;`,F=(p,We,Te)=>{const re=Cn.get(p);if(re!==void 0&&re.tier!==Te)throw new X("INTERNAL",`@lunora/codegen: capability "${p}" declares tier "${re.tier}" in SERVER_CTX_FIELDS but is emitted onto the "${Te}" context — update whichever is wrong.`);return We?re?.field??"":""},ce=F("kv",g,"every"),de=F("analytics",
|
|
402
|
+
export type Env = CloudflareBindings;`,F=(p,We,Te)=>{const re=Cn.get(p);if(re!==void 0&&re.tier!==Te)throw new X("INTERNAL",`@lunora/codegen: capability "${p}" declares tier "${re.tier}" in SERVER_CTX_FIELDS but is emitted onto the "${Te}" context — update whichever is wrong.`);return We?re?.field??"":""},ce=F("kv",g,"every"),de=F("analytics",a,"every"),Oe=F("hyperdrive",d,"action"),Ie=F("browser",i,"action"),Ce=F("images",h,"action"),ue=F("pipelines",l,"action"),G=F("r2sql",b,"action"),_=s&&($?.vectorIndexes.length??0)>0,J=_?' | "vectors"':"",te=_?`
|
|
403
403
|
readonly vectors: VectorSearch<VectorIndexName>;`:"",he=_?`
|
|
404
404
|
readonly vectors: VectorSearchReader<VectorIndexName>;`:"",z=_?`import type { VectorSearch, VectorSearchReader } from "${C.server}";
|
|
405
405
|
import type { VectorIndexName } from "./dataModel.js";
|
|
@@ -413,7 +413,7 @@ import type { VectorIndexName } from "./dataModel.js";
|
|
|
413
413
|
/** Device push sub-facade — the same object as ctx.notify.push (register / send / broadcast). Sends belong in action handlers. */
|
|
414
414
|
readonly push: import("@lunora/notify").LunoraPush;`:"",B=O.length>0,ne=B?`import type { WorkflowHandle } from "@lunora/workflow";
|
|
415
415
|
import type * as lunoraWorkflowDefinitions from "../workflows.js";
|
|
416
|
-
`:"",
|
|
416
|
+
`:"",De=B?`
|
|
417
417
|
|
|
418
418
|
/** Params type carried by a \`defineWorkflow\` definition (its phantom \`__params\`). */
|
|
419
419
|
type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params }
|
|
@@ -426,8 +426,8 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
|
|
|
426
426
|
export interface LunoraWorkflows {
|
|
427
427
|
${O.map(p=>` get(name: ${JSON.stringify(p.exportName)}): WorkflowHandle<WorkflowParamsOf<typeof lunoraWorkflowDefinitions.${p.exportName}>>;`).join(`
|
|
428
428
|
`)}
|
|
429
|
-
}`:"",ve=B?' | "workflows"':"",
|
|
430
|
-
readonly workflows: LunoraWorkflows;`:"",pe=v.length>0,
|
|
429
|
+
}`:"",ve=B?' | "workflows"':"",Se=B?`
|
|
430
|
+
readonly workflows: LunoraWorkflows;`:"",pe=v.length>0,Le=pe?`import type { QueueProducer } from "@lunora/queue";
|
|
431
431
|
import type * as lunoraQueueDefinitions from "../queues.js";
|
|
432
432
|
`:"",Ee=pe?`
|
|
433
433
|
|
|
@@ -438,7 +438,7 @@ type QueueBodyOf<Definition> = Definition extends { __lunoraBody?: infer Body }
|
|
|
438
438
|
export interface LunoraQueues {
|
|
439
439
|
${v.map(p=>` readonly ${p.exportName}: QueueProducer<QueueBodyOf<typeof lunoraQueueDefinitions.${p.exportName}>>;`).join(`
|
|
440
440
|
`)}
|
|
441
|
-
}`:"",
|
|
441
|
+
}`:"",Re=pe?`
|
|
442
442
|
readonly queues: LunoraQueues;`:"",me=e.length>0,_e=me?`import type { AgentHandle } from "@lunora/agent";
|
|
443
443
|
`:"",Pe=me?`
|
|
444
444
|
|
|
@@ -460,7 +460,7 @@ type NarrowedAuth = Omit<QueryCtxBase["auth"], "getIdentity"> & { getIdentity: (
|
|
|
460
460
|
`:"",je=n?`
|
|
461
461
|
|
|
462
462
|
/** This app's declared env contract (\`defineEnv\` in \`lunora/env.ts\`) — the validated, coercion-aware shape of \`ctx.env\`. */
|
|
463
|
-
export type LunoraEnv = ReturnType<typeof lunoraEnvContract.${n.exportName}>;`:"",be=n?' | "env"':"",ye=n?"\n /** Validated, typed environment declared by `defineEnv` in `lunora/env.ts` — parsed & coercion-aware config values (`ctx.env.STRIPE_KEY`); a missing or invalid value throws at read time. */\n readonly env: LunoraEnv;":"";return`${
|
|
463
|
+
export type LunoraEnv = ReturnType<typeof lunoraEnvContract.${n.exportName}>;`:"",be=n?' | "env"':"",ye=n?"\n /** Validated, typed environment declared by `defineEnv` in `lunora/env.ts` — parsed & coercion-aware config values (`ctx.env.STRIPE_KEY`); a missing or invalid value throws at read time. */\n readonly env: LunoraEnv;":"";return`${S}import { createPolicyDsl, defineMutator as defineMutatorBase, initLunora, v as vBase } from "${C.server}";
|
|
464
464
|
import type {
|
|
465
465
|
ActionBuilder,
|
|
466
466
|
ActionCtx as ActionCtxBase,
|
|
@@ -517,7 +517,7 @@ export type {
|
|
|
517
517
|
} from "${C.serverDataModel}";
|
|
518
518
|
|
|
519
519
|
import type { DataModel, Doc, GeoIndexNamesByTable, Id as IdOfTable, IndexNamesByTable, Insert, InsertModel, RankIndexNamesByTable, Relations, SearchIndexNamesByTable, TableName } from "./dataModel.js";
|
|
520
|
-
${z}${P}${ie}${Z}${
|
|
520
|
+
${z}${P}${ie}${Z}${D}${ne}${Le}${_e}${Me}${qe}
|
|
521
521
|
export type { AppTableName, DataModel, Doc, Id, TableName } from "./dataModel.js";
|
|
522
522
|
|
|
523
523
|
/**
|
|
@@ -577,7 +577,7 @@ export interface OrmWriter extends OrmReader {
|
|
|
577
577
|
}
|
|
578
578
|
|
|
579
579
|
/** Storage buckets this schema declares (\`v.storage("name")\`), narrowing \`ctx.storage.bucket(name)\`. */
|
|
580
|
-
export type StorageBucketName = ${w};${Ae}${
|
|
580
|
+
export type StorageBucketName = ${w};${Ae}${De}${Ee}${Pe}${Fe}${je}
|
|
581
581
|
|
|
582
582
|
/**
|
|
583
583
|
* Project-typed contexts. The base contexts from \`@lunora/server\` are
|
|
@@ -649,13 +649,13 @@ export interface QueryCtx extends Omit<QueryCtxBase, "db" | "storage"${J}${ge}${
|
|
|
649
649
|
export interface MutationCtx extends Omit<MutationCtxBase, "db" | "storage"${J}${ve}${ge}${be}> {
|
|
650
650
|
readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
|
|
651
651
|
readonly orm: OrmWriter;
|
|
652
|
-
readonly storage: MutationStorage<StorageBucketName>;${te}${j}${ce}${W}${U}${de}${ye}${
|
|
652
|
+
readonly storage: MutationStorage<StorageBucketName>;${te}${j}${ce}${W}${U}${de}${ye}${Se}${Re}${$e}${fe}
|
|
653
653
|
}
|
|
654
654
|
|
|
655
655
|
export interface ActionCtx extends Omit<ActionCtxBase, "db" | "storage"${J}${ve}${ge}${be}> {
|
|
656
656
|
readonly db: Omit<DatabaseWriter, "asId" | "query" | "get"> & DatabaseWriterFacade & { asId: TypedAsId; query: TypedTableQuery; get: TypedTableGet };
|
|
657
657
|
readonly orm: OrmWriter;
|
|
658
|
-
readonly storage: StorageBase<StorageBucketName>;${te}${j}${M}${le}${H}${ee}${ce}${W}${U}${Oe}${Ie}${Ce}${de}${ue}${G}${ye}${
|
|
658
|
+
readonly storage: StorageBase<StorageBucketName>;${te}${j}${M}${le}${H}${ee}${ce}${W}${U}${Oe}${Ie}${Ce}${de}${ue}${G}${ye}${Se}${Re}${$e}${fe}
|
|
659
659
|
}
|
|
660
660
|
|
|
661
661
|
/**
|
|
@@ -730,13 +730,13 @@ export const definePolicy = createPolicyDsl<DataModel, Relations${Be}>();
|
|
|
730
730
|
export const v = vBase as unknown as Omit<typeof vBase, "id"> & {
|
|
731
731
|
id: <T extends TableName>(table: T) => ColumnValidator<IdOfTable<T>, IdOfTable<T>>;
|
|
732
732
|
};
|
|
733
|
-
`},fr=e=>{const t={connect:[],disconnect:[],init:[],reactor:[]};for(const n of e)n.lifecycle&&t[n.lifecycle].push(`${N(n.filePath)}:${n.exportName}`);return t},fo=e=>{const{agents:t=[],functions:n,migrations:r=[],mutators:o=[],shapes:
|
|
733
|
+
`},fr=e=>{const t={connect:[],disconnect:[],init:[],reactor:[]};for(const n of e)n.lifecycle&&t[n.lifecycle].push(`${N(n.filePath)}:${n.exportName}`);return t},fo=e=>{const{agents:t=[],functions:n,migrations:r=[],mutators:o=[],shapes:a=[],useUmbrella:i=!1,usesSandbox:s=!1}=e,c=n.length>0,d=ae(i),{dispatchBody:h,importBlock:g,installBlock:y,migrationBody:u,mutatorPaths:l,shapeBody:b}=pr(n,r,o,a),R=sr(t,n),x=ir(s,n),v=[R.lines,x.lines].filter(k=>k.length>0).join(`
|
|
734
734
|
`);let $=h;v.length>0&&($=h.length>0?`${h.trimEnd()}
|
|
735
735
|
${v}
|
|
736
736
|
`:`
|
|
737
737
|
${v}
|
|
738
|
-
`);const A=fr(n),V=
|
|
739
|
-
`:"",O=
|
|
738
|
+
`);const A=fr(n),V=a.length>0?`import type { RegisteredShape } from "${d.server}";
|
|
739
|
+
`:"",O=a.length>0?`
|
|
740
740
|
/**
|
|
741
741
|
* Replication-shape registry — one entry per \`defineShape\` in \`lunora/shapes.ts\`.
|
|
742
742
|
* The generated ShardDO's \`resolveShape\` override looks a shape up by name and
|
|
@@ -764,9 +764,9 @@ ${M.types}
|
|
|
764
764
|
`:"",le=M.implementation?`
|
|
765
765
|
${M.implementation}
|
|
766
766
|
`:"",Z=ze(M.types),H=Z.length>0?`import type { ${Z.join(", ")} } from "./dataModel.js";
|
|
767
|
-
`:"",
|
|
767
|
+
`:"",D=c?"context":"_context",ee=c?`${hr}
|
|
768
768
|
|
|
769
|
-
`:"";return
|
|
769
|
+
`:"";return Rt(`${S}${g}${R.importLine}${x.importLine}${w}${V}import { LunoraError } from "${d.server}";
|
|
770
770
|
import type { ActionCtx, MutationCtx, QueryCtx } from "./server.js";
|
|
771
771
|
${H}
|
|
772
772
|
/**
|
|
@@ -805,7 +805,7 @@ export interface RegisteredLunoraFunction {
|
|
|
805
805
|
*/
|
|
806
806
|
x402?: { readonly price: number | string };
|
|
807
807
|
}
|
|
808
|
-
${
|
|
808
|
+
${R.prelude}${x.prelude}
|
|
809
809
|
/**
|
|
810
810
|
* Static dispatch table. The key matches the \`__lunoraRef\` the client
|
|
811
811
|
* emits (\`api[namespace][fn].__lunoraRef === "namespace:fn"\`).
|
|
@@ -859,7 +859,7 @@ export type CallerCtx = ActionCtx | MutationCtx | QueryCtx;
|
|
|
859
859
|
export interface Caller {${ie}}
|
|
860
860
|
|
|
861
861
|
${ee}/** Build a {@link Caller} bound to \`context\` (typically a handler's \`ctx\`). */
|
|
862
|
-
export const createCaller = (${
|
|
862
|
+
export const createCaller = (${D}: CallerCtx): Caller => ({${le}});
|
|
863
863
|
|
|
864
864
|
/**
|
|
865
865
|
* Single registered data migration, narrowed to the shape the per-shard runner
|
|
@@ -879,7 +879,7 @@ export interface RegisteredDataMigration {
|
|
|
879
879
|
* shard DO's admin RPC and the CLI resolve migrations to run through this map.
|
|
880
880
|
*/
|
|
881
881
|
export const LUNORA_MIGRATIONS: Record<string, RegisteredDataMigration> = {${u}};
|
|
882
|
-
`,i)},br=e=>{const t={};for(const n of e.tables){const r={};for(const[o,
|
|
882
|
+
`,i)},br=e=>{const t={};for(const n of e.tables){const r={};for(const[o,a]of Object.entries(n.shape)){const i=se(a);i.kind==="id"&&i.tableName!==void 0&&(r[o]=i.tableName)}Object.keys(r).length>0&&(t[n.name]=r)}return t},yr=e=>{const t={};for(const n of e.tables){const r=[];for(const[o,a]of Object.entries(n.shape))se(a).kind==="storage"&&r.push(o);r.length>0&&(t[n.name]=r)}return t},wr=e=>{const t={};for(const n of e.tables){const r=[...n.indexes.map(o=>({fields:[...o.fields],name:o.name,type:"index",...o.unique===!0?{unique:!0}:{}})),...n.searchIndexes.map(o=>({fields:[o.field,...o.filterFields??[]],name:o.name,type:"search"})),...(n.geoIndexes??[]).map(o=>({fields:[o.field],name:o.name,type:"geo"})),...n.rankIndexes.map(o=>({fields:o.sortBy.map(a=>a.field),name:o.name,type:"rank"})),...n.vectorIndexes.map(o=>({fields:o.field===void 0?[]:[o.field],name:o.name,type:"vector"}))];r.length>0&&(t[n.name]=r)}return t},kr=e=>{const t=[];for(const n of e.tables)!n.ttl||n.shardMode==="global"||t.push({...n.ttl.after===void 0?{}:{after:n.ttl.after},field:n.ttl.field,...n.softDelete?{softDeleteField:n.softDelete.field}:{},table:n.name});return t},xr=e=>{if(e.kind!=="union"||e.members===void 0||e.members.length===0)return;const t=[];for(const n of e.members){if(n.kind!=="literal"||n.literalValue===void 0)return;try{const r=JSON.parse(n.literalValue);if(typeof r!="string")return;t.push(r)}catch{return}}return t},vr=(e,t,n)=>{const r=se(t),o={name:e,optional:xt(t),type:r.kind};if(r.kind==="id"&&r.tableName!==void 0){o.ref=r.tableName;const i=n.get(e);i!==void 0&&(o.onDelete=i)}r.kind==="storage"&&(o.isStorage=!0,r.bucket!==void 0&&(o.bucket=r.bucket));const a=xr(r);return a!==void 0&&(o.enumValues=a),r.column?.notNull===!1&&(o.nullable=!0),o},Sr=e=>{const t={};for(const n of e.tables){const r=[{name:"_id",optional:!1,pk:!0,type:"id"},{name:"_creationTime",optional:!1,type:"number"},...n.commitOrdered===!0?[{name:"_commitSeq",optional:!1,type:"number"}]:[]],o=new Map(n.relations.filter(a=>a.kind==="one").map(a=>[a.field,a.onDelete]));for(const[a,i]of Object.entries(n.shape))r.push(vr(a,i,o));t[n.name]=r}return t},Rr=e=>e?{importFragment:"serveRelationFanout, ",override:`
|
|
883
883
|
protected override async runRelationFanoutRead(functionPath: string, args: Record<string, unknown>): Promise<unknown> {
|
|
884
884
|
this.ensureMigrated();
|
|
885
885
|
|
|
@@ -918,12 +918,12 @@ const aiStub: LunoraAi = {
|
|
|
918
918
|
${t}
|
|
919
919
|
}) as unknown as LunoraAi["workersai"],
|
|
920
920
|
};
|
|
921
|
-
`}},I=(e,t,n,{cast:r="",sync:o=[]}={})=>{const
|
|
921
|
+
`}},I=(e,t,n,{cast:r="",sync:o=[]}={})=>{const a=n.map(i=>` ${i}: ${o.includes(i)?"":"async "}() => {
|
|
922
922
|
${t}
|
|
923
923
|
},`).join(`
|
|
924
924
|
`);return`
|
|
925
925
|
const ${e} = {
|
|
926
|
-
${
|
|
926
|
+
${a}
|
|
927
927
|
}${r};
|
|
928
928
|
`},E={build:"",configField:"",contextField:"",importLines:[],stub:""},Tr=e=>e?{build:`
|
|
929
929
|
const kvBinding = config.kv?.(env) ?? (env as Record<string, unknown>).KV;
|
|
@@ -956,15 +956,15 @@ ${s}
|
|
|
956
956
|
env: envConfig,`,importLines:['import * as lunoraEnvContract from "../env.js";'],stub:""}:E,Ir=e=>e?{build:`
|
|
957
957
|
const access = accessFacade(identity, userId);
|
|
958
958
|
`,configField:"",contextField:`
|
|
959
|
-
access,`,importLines:['import { accessFacade } from "@lunora/cloudflare-access/context";'],stub:""}:E,Cr=(e,t,n)=>{if(!t)return{constant:"",evaluateOverride:"",subscriptionOverride:""};const r=
|
|
959
|
+
access,`,importLines:['import { accessFacade } from "@lunora/cloudflare-access/context";'],stub:""}:E,Cr=(e,t,n)=>{if(!t)return{constant:"",evaluateOverride:"",subscriptionOverride:""};const r=s=>`
|
|
960
960
|
const env = (this.env ?? {}) as Record<string, unknown>;
|
|
961
961
|
const flags: import("${n}").LunoraFlags = createFlags(flagsConfig, env, {
|
|
962
962
|
provider: () => config.flags?.(env),
|
|
963
|
-
targetingKey: ${
|
|
963
|
+
targetingKey: ${s},
|
|
964
964
|
});`,o=`
|
|
965
965
|
/** Statically-discovered feature flags (\`ctx.flags.<type>("key")\` reads) served via \`__lunora_admin__:listFlags\` + the reactive \`__lunora_flags__:\` channel. */
|
|
966
966
|
const LUNORA_FLAG_KEYS: ReadonlyArray<{ key: string; type: "boolean" | "number" | "object" | "string" }> = ${JSON.stringify(e,void 0,4)};
|
|
967
|
-
`,
|
|
967
|
+
`,a=`
|
|
968
968
|
protected override async evaluateFlags(context?: Record<string, unknown>): Promise<FlagsResult> {${r("undefined")}
|
|
969
969
|
const evalContext = context as import("${n}").EvaluationContext | undefined;
|
|
970
970
|
const evaluations: FlagsResult["flags"] = [];
|
|
@@ -986,7 +986,7 @@ const LUNORA_FLAG_KEYS: ReadonlyArray<{ key: string; type: "boolean" | "number"
|
|
|
986
986
|
return { configured: true, flags: evaluations };
|
|
987
987
|
}
|
|
988
988
|
`,i=`
|
|
989
|
-
protected override runFlagSubscriptionRead(_functionPath: string, args: Record<string, unknown>, identity?:
|
|
989
|
+
protected override runFlagSubscriptionRead(_functionPath: string, args: Record<string, unknown>, identity?: SubscriptionIdentity): Promise<unknown> {${r("() => flagsConfig.identify?.({ identity: identity?.identity ?? null, userId: identity?.userId ?? null })")}
|
|
990
990
|
const key = typeof args.key === "string" ? args.key : "";
|
|
991
991
|
|
|
992
992
|
// SECURITY: the reactive channel is public (any socket, no auth). Serve
|
|
@@ -1018,12 +1018,12 @@ const LUNORA_FLAG_KEYS: ReadonlyArray<{ key: string; type: "boolean" | "number"
|
|
|
1018
1018
|
|
|
1019
1019
|
return flags.boolean(key, typeof args.default === "boolean" ? args.default : false, context);
|
|
1020
1020
|
}
|
|
1021
|
-
`;return{constant:o,evaluateOverride:
|
|
1021
|
+
`;return{constant:o,evaluateOverride:a,subscriptionOverride:i}},Dr=e=>e?{build:`
|
|
1022
1022
|
const analyticsBinding = config.analytics?.(env) ?? (env as Record<string, unknown>).ANALYTICS;
|
|
1023
1023
|
const analytics: AnalyticsClient = analyticsBinding ? createAnalytics(analyticsBinding as AnalyticsEngineDatasetLike) : analyticsStub;
|
|
1024
1024
|
`,configField:`
|
|
1025
1025
|
analytics?: (env: Record<string, unknown>) => AnalyticsEngineDatasetLike;`,contextField:`
|
|
1026
|
-
analytics,`,importLines:['import type { AnalyticsClient, AnalyticsEngineDatasetLike } from "@lunora/bindings/analytics";','import { createAnalytics } from "@lunora/bindings/analytics";'],stub:I("analyticsStub: AnalyticsClient",'throw new Error("ctx.analytics: no Analytics Engine binding found. Add an \\`analytics_engine_datasets\\` binding (env.ANALYTICS) to wrangler.jsonc, or pass \\`analytics\\` to createShardDO().");',["track","writeDataPoint"],{sync:["track","writeDataPoint"]})}:E,
|
|
1026
|
+
analytics,`,importLines:['import type { AnalyticsClient, AnalyticsEngineDatasetLike } from "@lunora/bindings/analytics";','import { createAnalytics } from "@lunora/bindings/analytics";'],stub:I("analyticsStub: AnalyticsClient",'throw new Error("ctx.analytics: no Analytics Engine binding found. Add an \\`analytics_engine_datasets\\` binding (env.ANALYTICS) to wrangler.jsonc, or pass \\`analytics\\` to createShardDO().");',["track","writeDataPoint"],{sync:["track","writeDataPoint"]})}:E,Lr=e=>e?{build:`
|
|
1027
1027
|
const imagesBinding = config.images?.(env) ?? (env as Record<string, unknown>).IMAGES;
|
|
1028
1028
|
const images: Images = imagesBinding ? createImages({ binding: imagesBinding as ImagesBindingLike }) : imagesStub;
|
|
1029
1029
|
`,configField:`
|
|
@@ -1051,14 +1051,14 @@ const LUNORA_FLAG_KEYS: ReadonlyArray<{ key: string; type: "boolean" | "number"
|
|
|
1051
1051
|
const pipelinesBinding = config.pipelines?.(env) ?? (env as Record<string, unknown>).PIPELINES;
|
|
1052
1052
|
const pipelines: PipelineClient = pipelinesBinding ? createPipelines({ binding: pipelinesBinding as PipelineBindingLike }) : pipelinesStub;
|
|
1053
1053
|
`,configField:`
|
|
1054
|
-
pipelines?: (env: Record<string, unknown>) => PipelineBindingLike;`,contextField:"",importLines:['import type { PipelineBindingLike, PipelineClient } from "@lunora/bindings/pipelines";','import { createPipelines } from "@lunora/bindings/pipelines";'],stub:I("pipelinesStub: PipelineClient",'throw new Error("ctx.pipelines: no Pipelines binding found. Add a \\`pipelines\\` binding (env.PIPELINES) to wrangler.jsonc, or pass \\`pipelines\\` to createShardDO().");',["send"])}:E,bo=(e,t)=>{if(e.length===0)return"";const n=t?`, ${JSON.stringify(t)}`:"",r=e.map(
|
|
1055
|
-
export class ${
|
|
1054
|
+
pipelines?: (env: Record<string, unknown>) => PipelineBindingLike;`,contextField:"",importLines:['import type { PipelineBindingLike, PipelineClient } from "@lunora/bindings/pipelines";','import { createPipelines } from "@lunora/bindings/pipelines";'],stub:I("pipelinesStub: PipelineClient",'throw new Error("ctx.pipelines: no Pipelines binding found. Add a \\`pipelines\\` binding (env.PIPELINES) to wrangler.jsonc, or pass \\`pipelines\\` to createShardDO().");',["send"])}:E,bo=(e,t)=>{if(e.length===0)return"";const n=t?`, ${JSON.stringify(t)}`:"",r=e.map(a=>(f(a.exportName,`container export "${a.exportName}"`),f(a.className,`container class "${a.className}"`),`/** Container DO for the \`${a.exportName}\` definition (binding \`${a.bindingName}\`). */
|
|
1055
|
+
export class ${a.className} extends LunoraContainer {
|
|
1056
1056
|
public constructor(ctx: ConstructorParameters<typeof LunoraContainer>[0], env: Record<string, unknown>) {
|
|
1057
|
-
super(ctx, env, ${
|
|
1057
|
+
super(ctx, env, ${a.exportName}, "${a.exportName}"${n});
|
|
1058
1058
|
}
|
|
1059
1059
|
}
|
|
1060
1060
|
`)).join(`
|
|
1061
|
-
`),o=e.map(
|
|
1061
|
+
`),o=e.map(a=>a.exportName).join(", ");return`${S}/**
|
|
1062
1062
|
* Container-enabled Durable Object classes for the containers declared in
|
|
1063
1063
|
* \`lunora/containers.ts\`. Re-export them from your worker entry — wrangler
|
|
1064
1064
|
* requires each \`containers[].class_name\` to be exported by the worker:
|
|
@@ -1092,7 +1092,7 @@ export class ${r.className} extends LunoraWorkflow<WorkflowParamsOf<typeof ${r.e
|
|
|
1092
1092
|
}
|
|
1093
1093
|
}
|
|
1094
1094
|
`)).join(`
|
|
1095
|
-
`),n=e.map(r=>r.exportName).join(", ");return`${
|
|
1095
|
+
`),n=e.map(r=>r.exportName).join(", ");return`${S}/**
|
|
1096
1096
|
* WorkflowEntrypoint classes for the workflows declared in
|
|
1097
1097
|
* \`lunora/workflows.ts\`. Re-export them from your worker entry — wrangler
|
|
1098
1098
|
* requires each \`workflows[].class_name\` to be exported by the worker:
|
|
@@ -1113,21 +1113,21 @@ type WorkflowParamsOf<Definition> = Definition extends { __params?: infer Params
|
|
|
1113
1113
|
/** Output type carried by a \`defineWorkflow\` definition (its phantom \`__output\`), so each entrypoint keeps the authored return type. */
|
|
1114
1114
|
type WorkflowOutputOf<Definition> = Definition extends { __output?: infer Output } ? Output : unknown;
|
|
1115
1115
|
|
|
1116
|
-
${t}`},wo=e=>{if(e.length===0)return"";const n=e.filter(
|
|
1117
|
-
export class ${
|
|
1116
|
+
${t}`},wo=e=>{if(e.length===0)return"";const n=e.filter(s=>s.voice).length>0,r=e.map(s=>{f(s.exportName,`agent export "${s.exportName}"`),f(s.className,`agent class "${s.className}"`);const c=`/** WorkflowEntrypoint for the \`${s.exportName}\` agent (binding \`${s.bindingName}\`). */
|
|
1117
|
+
export class ${s.className} extends LunoraWorkflow<AgentRunInput, AgentRunResult> {
|
|
1118
1118
|
public constructor(ctx: ConstructorParameters<typeof LunoraWorkflow>[0], env: Record<string, unknown>) {
|
|
1119
|
-
super(ctx, env, compileAgentWorkflow(${
|
|
1119
|
+
super(ctx, env, compileAgentWorkflow(${s.exportName}, "${s.exportName}"), "${s.exportName}");
|
|
1120
1120
|
}
|
|
1121
1121
|
}
|
|
1122
|
-
`;if(!
|
|
1123
|
-
/** Voice-session Durable Object for the \`${
|
|
1122
|
+
`;if(!s.voice)return c;const d=s.voiceClassName??"",h=s.voiceBindingName??"";f(d,`agent voice class "${d}"`);const g=`
|
|
1123
|
+
/** Voice-session Durable Object for the \`${s.exportName}\` agent (binding \`${h}\`). */
|
|
1124
1124
|
export class ${d} extends VoiceSessionDO {
|
|
1125
1125
|
public constructor(ctx: ConstructorParameters<typeof VoiceSessionDO>[0], env: Record<string, unknown>) {
|
|
1126
|
-
super(ctx, env, ${
|
|
1126
|
+
super(ctx, env, ${s.exportName}, "${s.exportName}");
|
|
1127
1127
|
}
|
|
1128
1128
|
}
|
|
1129
1129
|
`;return`${c}${g}`}).join(`
|
|
1130
|
-
`),o=e.map(
|
|
1130
|
+
`),o=e.map(s=>s.exportName).join(", ");return`${S}/**
|
|
1131
1131
|
* WorkflowEntrypoint classes for the agents declared in \`lunora/agents.ts\`.
|
|
1132
1132
|
* Each \`defineAgent\` compiles a replay-safe tool-loop onto a Cloudflare
|
|
1133
1133
|
* Workflow. Re-export them from your worker entry — wrangler requires each
|
|
@@ -1142,7 +1142,7 @@ import type { AgentRunInput, AgentRunResult } from "@lunora/agent";
|
|
|
1142
1142
|
import { ${o} } from "../agents.js";
|
|
1143
1143
|
|
|
1144
1144
|
${r}`},ko=e=>{const t=e.filter(o=>o.mode==="push");if(t.length===0)return"";for(const o of t)f(o.exportName,`queue export "${o.exportName}"`);const n=t.map(o=>o.exportName).join(", "),r=t.map(o=>` ${JSON.stringify(o.name)}: { definition: ${o.exportName}, exportName: ${JSON.stringify(o.exportName)} },`).join(`
|
|
1145
|
-
`);return`${
|
|
1145
|
+
`);return`${S}/**
|
|
1146
1146
|
* Push-consumer registry for the queues declared in \`lunora/queues.ts\`. The
|
|
1147
1147
|
* composed worker's \`queue(batch, env, ctx)\` entry routes each delivered batch
|
|
1148
1148
|
* by \`batch.queue\` to the matching \`defineQueue\` handler. Wired automatically
|
|
@@ -1201,11 +1201,11 @@ const ${e}: ${t} = ${JSON.stringify(r,void 0,4)};
|
|
|
1201
1201
|
? lazyX402Pay(config.x402(env), { getSecret: (name: string) => secrets.get(name) })
|
|
1202
1202
|
: x402Stub;
|
|
1203
1203
|
`,configField:`
|
|
1204
|
-
x402?: (env: Record<string, unknown>) => X402PayConfig;`,stub:I("x402Stub: X402Pay",'throw new Error("ctx.x402: no pay rail configured. Pass \\`x402\\` to createShardDO().");',["fetch"],{cast:" as unknown as X402Pay",sync:["fetch"]})}:{build:"",configField:"",imports:[],stub:""},Vr=(e,t,n,r,o)=>["AdvisorProcedure","AdvisoryFinding","DatabaseWriterLike","DataMigrationLike","DispatchBookmark","ExportRow",...r?["FlagsResult"]:[],"ImportShardResult","KeyRange","MaskPoliciesResult","MigrationRunResult","QueryReadScope",...n?["QueuesResult"]:[],"RelatedPage","RunShardApplyCdcArgs","RunShardExportArgs","RunShardFindRelatedArgs","RunShardImportArgs","RunShardMigrationArgs","RlsPoliciesResult","RunShardRankBeforeArgs","RunShardRankPageArgs","RunShardWriteArgs","RunShardWriteResult","SchedulerLike",...o?["SearchBackfillProgress"]:[],"TransactionHeadroomTracker","SchemaLike","ShardDOState","ShardRankPageResult","SqlExec","StorageRulesResult","StudioFeaturesResult","SystemReaderStorageLike","TelemetrySink",...t?["WorkflowsResult"]:[],...e?["WriteHook"]:[]],xo=({advisories:e=[],advisorProcedures:t=[],agents:n=[],containers:r=[],env:o,flagKeys:
|
|
1204
|
+
x402?: (env: Record<string, unknown>) => X402PayConfig;`,stub:I("x402Stub: X402Pay",'throw new Error("ctx.x402: no pay rail configured. Pass \\`x402\\` to createShardDO().");',["fetch"],{cast:" as unknown as X402Pay",sync:["fetch"]})}:{build:"",configField:"",imports:[],stub:""},Vr=(e,t,n,r,o)=>["AdvisorProcedure","AdvisoryFinding","DatabaseWriterLike","DataMigrationLike","DispatchBookmark","ExportRow",...r?["FlagsResult"]:[],"ImportShardResult","KeyRange","MaskPoliciesResult","MigrationRunResult","QueryReadScope",...n?["QueuesResult"]:[],"RelatedPage","RunShardApplyCdcArgs","RunShardExportArgs","RunShardFindRelatedArgs","RunShardImportArgs","RunShardMigrationArgs","RlsPoliciesResult","RunShardRankBeforeArgs","RunShardRankPageArgs","RunShardWriteArgs","RunShardWriteResult","SchedulerLike",...o?["SearchBackfillProgress"]:[],"TransactionHeadroomTracker","SchemaLike","ShardDOState","ShardRankPageResult","SqlExec","StorageRulesResult","StudioFeaturesResult","SubscriptionIdentity","SystemReaderStorageLike","TelemetrySink",...t?["WorkflowsResult"]:[],...e?["WriteHook"]:[]],xo=({advisories:e=[],advisorProcedures:t=[],agents:n=[],containers:r=[],env:o,flagKeys:a=[],hasAccessFacade:i=!1,hasAi:s=!1,hasAnalytics:c=!1,hasBrowser:d=!1,hasFlags:h=!1,hasHyperdrive:g=!1,hasImages:y=!1,hasKv:u=!1,hasNotify:l=!1,hasPayments:b=!1,hasPipelines:R=!1,hasR2sql:x=!1,hasVectors:v=!0,hasX402:$=!1,maskMetadata:A,mutators:V=[],queues:O=[],rlsMetadata:C,schema:w,schemaSnapshot:P,shapes:M=[],storageRules:ie,studioFeatures:le,useUmbrella:Z=!1,workflows:H=[]})=>{const D=ae(Z),ee=V.length>0,k=M.length>0,Ae=P===void 0?"":$n(P),F=P===void 0?"":`
|
|
1205
1205
|
/** 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. */
|
|
1206
1206
|
const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.stringify(Tn(P))}, json: ${JSON.stringify(Ae)} };
|
|
1207
|
-
`,ce=P===void 0?"":", schemaSnapshot: LUNORA_SCHEMA_SNAPSHOT",{build:de,configField:Oe,contextField:Ie,stub:Ce}=$r(
|
|
1208
|
-
protected override resolveShape(name: string, args: Record<string, unknown>, identity?:
|
|
1207
|
+
`,ce=P===void 0?"":", schemaSnapshot: LUNORA_SCHEMA_SNAPSHOT",{build:de,configField:Oe,contextField:Ie,stub:Ce}=$r(s),ue=Ir(i),G=Tr(u),_=Nr(h,D.flags),J=Cr(a,h,D.flags),te=Ar(l),he=Or(o),z=Dr(c),j=Lr(y),W=Er(g),U=_r(d),B=Pr(x),ne=Mr(R),{build:De,contextField:ve,importLines:Se,specs:pe}=qr(O),{build:Le,contextField:Ee,importLines:Re,specs:me}=Fr(r,w.jurisdiction),{build:_e,contextField:Pe,importLines:$e,specs:Me}=Br(H),{build:Fe,contextField:ge,importLines:fe,specs:Be}=jr(n),{build:qe,configField:je,contextField:be,imports:ye,stub:Ze}=Kr(b),{build:p,configField:We,imports:Te,stub:re}=Qr($),Ot=e,It=t,et=C??{policies:[],roles:[]},Ct=A??{columns:[]},Dt=ie??{rules:[]},Lt=le??{analytics:!1,auth:!1,containers:!1,flags:!1,kv:!1,mail:!1,notifications:!1,payments:!1,queues:!1,scheduler:!1,storage:!1,vectors:!1,workflows:!1},{constant:Et,override:_t}=Wr(H),{constant:Pt,override:Mt}=Ur(O),K=v&&w.vectorIndexes.length>0,tt=new Set(w.tables.filter(m=>typeof m.shardMode=="object"&&m.shardMode.kind==="shardBy").map(m=>m.name)),Ne=K&&w.vectorIndexes.some(m=>tt.has(m.table)),we=w.tables.some(m=>m.shardMode==="global"),Ue=w.tables.some(m=>Nn(m)),nt=w.tables.some(m=>An(m)),oe=w.tables.some(m=>m.externalSource!==void 0),rt=w.tables.some(m=>m.memory===!0),Ke=w.tables.some(m=>m.shardMode!=="global"&&m.searchIndexes.length>0);if(nt&&Ue)throw new X("INTERNAL",'lunora codegen: mixing `.global()` (D1) and `.global({ backend: "hyperdrive" })` tables in one app is not supported yet — use a single global backend.');const Qe=w.tables.length>0,Ft=br(w),Bt=wr(w),qt=Sr(w),jt=yr(w),ot=kr(w),at=Vr(K,H.length>0,O.length>0,h,Ke);k&&at.push("WhereInput");const st=Rr(we),Wt=k?`
|
|
1208
|
+
protected override resolveShape(name: string, args: Record<string, unknown>, identity?: SubscriptionIdentity): { columns?: readonly string[]; effectiveWhere?: WhereInput; global?: boolean; table: string } | undefined {
|
|
1209
1209
|
const shape = LUNORA_SHAPES[name];
|
|
1210
1210
|
|
|
1211
1211
|
if (!shape) {
|
|
@@ -1268,14 +1268,14 @@ const LUNORA_SCHEMA_SNAPSHOT: { hash: string; json: string } = { hash: ${JSON.st
|
|
|
1268
1268
|
|
|
1269
1269
|
return { columns: shape.columns, effectiveWhere, global: isGlobal, table: shape.table };
|
|
1270
1270
|
}
|
|
1271
|
-
`:"",it=k?[...new Set(et.policies.filter(m=>m.on==="read"&&m.table!=="").map(m=>m.table))].toSorted((m,
|
|
1271
|
+
`:"",it=k?[...new Set(et.policies.filter(m=>m.on==="read"&&m.table!=="").map(m=>m.table))].toSorted((m,Rn)=>m.localeCompare(Rn)):[],lt=it.length>0?`
|
|
1272
1272
|
/** Refuses to boot a shape that would replicate around the read policies its table is governed by (\`defineShape({ use })\` is how a shape opts in; \`use: []\` acknowledges an ungoverned one). */
|
|
1273
1273
|
assertShapesDeclareReadPolicies(LUNORA_SHAPES, ${JSON.stringify(it)}, (schema as unknown as { rlsMode?: string }).rlsMode === "required");
|
|
1274
1274
|
`:"",Ut=ee?`
|
|
1275
1275
|
protected override isCustomMutator(functionPath: string): boolean {
|
|
1276
1276
|
return LUNORA_MUTATOR_PATHS.has(functionPath);
|
|
1277
1277
|
}
|
|
1278
|
-
`:"",Kt=k?"assertShapeShardable, ":"",Qt=lt===""?"":"assertShapesDeclareReadPolicies, ",ke=[`import type { ${at.join(", ")} } from "${
|
|
1278
|
+
`:"",Kt=k?"assertShapeShardable, ":"",Qt=lt===""?"":"assertShapesDeclareReadPolicies, ",ke=[`import type { ${at.join(", ")} } from "${D.do}";`,`import { applyCdcChanges, ${Ke?"backfillSearchIndexes, ":""}buildReprojectionMigration, ${rt?"clearMemoryTables, ":""}${Kt}createReadFootprint, createShardCtxDb, exportShardRows, importShardRows, ${oe?"isSourceDue, pullExternalSourceIncrementalTick, pullExternalSourceTick, ":""}markUnvouchableReads, ${Ne?"ROOT_SHARD_NAME, ":""}runDataMigration, runShardMigrations, ${st.importFragment}ShardDO as ShardDOBase } from "${D.do}";`,...oe?[`import type { ExternalSourceLike, SourceClientLike, TraceRefLike } from "${D.do}";`]:[],k?`import { asBucketStorage, ${Qt}beginDeferredDeletes, beginDeferredSchedules, composeShapeReadWhere, createSecrets, flushDeferredDeletes, LunoraError, withDeferredDeletes, withDeferredSchedules } from "${D.server}";`:`import { asBucketStorage, beginDeferredDeletes, beginDeferredSchedules, createSecrets, flushDeferredDeletes, LunoraError, withDeferredDeletes, withDeferredSchedules } from "${D.server}";`];Qe&&ke.push(`import { bindOrm, bindTableFacade } from "${D.server}";`),K&&ke.push('import type { SchemaLike as VectorSchemaLike, VectorizeIndexLike, VectorSearchLike } from "@lunora/bindings/vectors";','import { createContextVectors, createVectors, createVectorSyncHook } from "@lunora/bindings/vectors";'),s&&ke.push('import type { AiBindingLike, LunoraAi } from "@lunora/ai";','import { createAi } from "@lunora/ai";'),ke.push(...ue.importLines,...G.importLines,..._.importLines,...te.importLines,...he.importLines,...z.importLines,...j.importLines,...W.importLines,...U.importLines,...B.importLines,...ne.importLines,...Re,...$e,...Se,...fe,...ye,...Te,"",'import schema from "../schema.js";',`import { ${["LUNORA_FUNCTIONS","LUNORA_LIFECYCLE_HOOKS","LUNORA_MIGRATIONS",...ee?["LUNORA_MUTATOR_PATHS"]:[],...k?["LUNORA_SHAPES"]:[]].join(", ")} } from "./functions.js";`);const Vt=K?`
|
|
1279
1279
|
vectors?: (env: Record<string, unknown>) => Record<string, VectorizeIndexLike>;`:"",Ht=nt?`
|
|
1280
1280
|
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;`:"",Gt=Ue?`
|
|
1281
1281
|
hyperdriveGlobal?: (env: Record<string, unknown>, request?: { cdc?: boolean; cdcRetentionMs?: number; identity?: Record<string, unknown>; userId?: string }) => DatabaseWriterLike | undefined;`:"",Jt=oe?`
|
|
@@ -1376,12 +1376,19 @@ ${nn}
|
|
|
1376
1376
|
orm: bindOrm(facade),`:"",Ve=Ue?"config.hyperdriveGlobal":"config.d1",un=we?` const globalRequest = { ...this.globalCdcOptions(config.cdc ?? false), bookmark: this.getInboundBookmark(), identity, onBookmark: (bookmarkValue: string | undefined) => { if (options.bookmarks !== undefined) { options.bookmarks.value = bookmarkValue; } }, userId };
|
|
1377
1377
|
const globalDb: DatabaseWriterLike = ${Ve}?.(env, globalRequest) ?? globalDbStub;
|
|
1378
1378
|
`:"",hn=k&&we?`
|
|
1379
|
-
protected override async readGlobalShapeRows(resolved: { columns?: readonly string[]; effectiveWhere?: WhereInput; global?: boolean; table: string }, identity?:
|
|
1379
|
+
protected override async readGlobalShapeRows(resolved: { columns?: readonly string[]; effectiveWhere?: WhereInput; global?: boolean; table: string }, identity?: SubscriptionIdentity): Promise<Array<{ doc: Record<string, unknown>; id: string }>> {
|
|
1380
1380
|
const env = this.env as Record<string, unknown>;
|
|
1381
1381
|
// A shape read performs no writes, so the widened request only needs
|
|
1382
1382
|
// the inbound bookmark (pin the membership drain to the caller's own
|
|
1383
1383
|
// prior writes) — no \`onBookmark\` here.
|
|
1384
|
-
|
|
1384
|
+
//
|
|
1385
|
+
// The two identity members are named rather than spread, matching the
|
|
1386
|
+
// dispatch-path request built in \`buildCtx\`. A spread would also hand
|
|
1387
|
+
// the global writer \`ip\`, and \`globalShapeReadKey\` — the per-flush
|
|
1388
|
+
// cache in front of this read — keys on identity + userId only. Equal
|
|
1389
|
+
// keys must mean equal rows, so a field the writer can scope by has to
|
|
1390
|
+
// be either in the key or out of the request; it is out.
|
|
1391
|
+
const globalRequest = { ...this.globalCdcOptions(config.cdc ?? false), bookmark: this.getInboundBookmark(), identity: identity?.identity, userId: identity?.userId };
|
|
1385
1392
|
const globalDb: DatabaseWriterLike = ${Ve}?.(env, globalRequest) ?? globalDbStub;
|
|
1386
1393
|
const rows: Array<{ doc: Record<string, unknown>; id: string }> = [];
|
|
1387
1394
|
|
|
@@ -1613,15 +1620,15 @@ ${w.tables.map(m=>` facade[${JSON.stringify(m.name)}] = bindTableFaca
|
|
|
1613
1620
|
`:"",wn=`${ue.build}${G.build}${_.build}${z.build}${he.build}
|
|
1614
1621
|
const secrets = createSecrets(env);
|
|
1615
1622
|
`,kn=`${ue.contextField}${G.contextField}${_.contextField}${te.contextField}${z.contextField}${he.contextField}
|
|
1616
|
-
secrets,`,xn=te.build,ct=y||g||d||x||
|
|
1623
|
+
secrets,`,xn=te.build,ct=y||g||d||x||R||$,vn=ct?`
|
|
1617
1624
|
// ActionCtx-only helpers (external, non-deterministic I/O): constructed
|
|
1618
1625
|
// and attached only for an \`action\` so query/mutation ctx never carry them.
|
|
1619
1626
|
if (isAction) {
|
|
1620
|
-
${j.build}${W.build}${U.build}${B.build}${ne.build}${p}${[...y?[" ctx.images = images;"]:[],...g?[" ctx.sql = sql;"]:[],...d?[" ctx.browser = browser;"]:[],...x?[" ctx.r2sql = r2sql;"]:[],...
|
|
1627
|
+
${j.build}${W.build}${U.build}${B.build}${ne.build}${p}${[...y?[" ctx.images = images;"]:[],...g?[" ctx.sql = sql;"]:[],...d?[" ctx.browser = browser;"]:[],...x?[" ctx.r2sql = r2sql;"]:[],...R?[" ctx.pipelines = pipelines;"]:[],...$?[" ctx.x402 = x402;"]:[]].join(`
|
|
1621
1628
|
`)}
|
|
1622
1629
|
}
|
|
1623
|
-
`:"",
|
|
1624
|
-
`:"";return`${
|
|
1630
|
+
`:"",Sn=ct?` const isAction = LUNORA_FUNCTIONS[options.functionPath ?? ""]?.kind === "action";
|
|
1631
|
+
`:"";return`${S}${ke.join(`
|
|
1625
1632
|
`)}
|
|
1626
1633
|
|
|
1627
1634
|
type FunctionKind = "action" | "mutation" | "query";
|
|
@@ -1639,7 +1646,18 @@ const LUNORA_TABLE_INDEXES: Record<string, Array<{ fields: string[]; name: strin
|
|
|
1639
1646
|
/** Columns per table (typed, with PK/FK markers) for the studio's schema diagram, served via \`__lunora_admin__:describeTable\`. */
|
|
1640
1647
|
const LUNORA_TABLE_COLUMNS: Record<
|
|
1641
1648
|
string,
|
|
1642
|
-
Array<{
|
|
1649
|
+
Array<{
|
|
1650
|
+
bucket?: string;
|
|
1651
|
+
enumValues?: string[];
|
|
1652
|
+
isStorage?: boolean;
|
|
1653
|
+
name: string;
|
|
1654
|
+
nullable?: boolean;
|
|
1655
|
+
onDelete?: "cascade" | "restrict" | "set null";
|
|
1656
|
+
optional: boolean;
|
|
1657
|
+
pk?: boolean;
|
|
1658
|
+
ref?: string;
|
|
1659
|
+
type: string;
|
|
1660
|
+
}>
|
|
1643
1661
|
> = ${JSON.stringify(qt,void 0,4)};
|
|
1644
1662
|
|
|
1645
1663
|
/** Storage-key columns per table (\`v.storage(...)\` fields) for the file browser's records↔files join. */
|
|
@@ -1661,10 +1679,10 @@ ${lt}
|
|
|
1661
1679
|
const LUNORA_MASK_METADATA: MaskPoliciesResult = ${JSON.stringify(Ct,void 0,4)};
|
|
1662
1680
|
|
|
1663
1681
|
/** Read-only storage access-rule metadata (discovered from \`.use(storageRules(...))\` chains) served via \`__lunora_admin__:storageRules\` for the studio's access-rules view. */
|
|
1664
|
-
const LUNORA_STORAGE_RULES: StorageRulesResult = ${JSON.stringify(
|
|
1682
|
+
const LUNORA_STORAGE_RULES: StorageRulesResult = ${JSON.stringify(Dt,void 0,4)};
|
|
1665
1683
|
|
|
1666
1684
|
/** 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. */
|
|
1667
|
-
const LUNORA_STUDIO_FEATURES: StudioFeaturesResult = ${JSON.stringify(
|
|
1685
|
+
const LUNORA_STUDIO_FEATURES: StudioFeaturesResult = ${JSON.stringify(Lt,void 0,4)};
|
|
1668
1686
|
${F}${J.constant}${Et}${Pt}${me}${Me}${pe}${Be}
|
|
1669
1687
|
export interface ShardDOConfig {
|
|
1670
1688
|
/** Opt into change-data-capture: records a post-image to \`__cdc_log\` on every write (backs streaming export + replay-PITR). */
|
|
@@ -1928,7 +1946,7 @@ export const createShardDO = (config: ShardDOConfig = {}): new (state: ShardDOSt
|
|
|
1928
1946
|
return LUNORA_FUNCTIONS[functionPath]?.kind === "mutation";
|
|
1929
1947
|
}
|
|
1930
1948
|
${st.override}
|
|
1931
|
-
protected override async executeSubscription(functionPath: string, args: Record<string, unknown>, identity?:
|
|
1949
|
+
protected override async executeSubscription(functionPath: string, args: Record<string, unknown>, identity?: SubscriptionIdentity): Promise<{ ranges?: Map<string, KeyRange[]>; result: unknown; tables: Set<string> } | null> {
|
|
1932
1950
|
const registered = LUNORA_FUNCTIONS[functionPath];
|
|
1933
1951
|
|
|
1934
1952
|
if (!registered || registered.kind !== "query" || registered.visibility === "internal") {
|
|
@@ -1949,7 +1967,7 @@ ${st.override}
|
|
|
1949
1967
|
return { ranges: footprint.ranges(), result, tables: footprint.tables };
|
|
1950
1968
|
}
|
|
1951
1969
|
|
|
1952
|
-
protected override executeStream(functionPath: string, args: Record<string, unknown>, identity?:
|
|
1970
|
+
protected override executeStream(functionPath: string, args: Record<string, unknown>, identity?: SubscriptionIdentity): null | { durable?: { ttlMs?: number }; iterator: (signal: AbortSignal) => AsyncIterable<unknown> } {
|
|
1953
1971
|
const registered = LUNORA_FUNCTIONS[functionPath];
|
|
1954
1972
|
|
|
1955
1973
|
if (!registered || registered.kind !== "stream" || registered.visibility === "internal") {
|
|
@@ -2026,9 +2044,18 @@ ${mn}
|
|
|
2026
2044
|
return LUNORA_TTL_SWEEPS;
|
|
2027
2045
|
}
|
|
2028
2046
|
|
|
2029
|
-
protected override tableColumns(
|
|
2030
|
-
|
|
2031
|
-
|
|
2047
|
+
protected override tableColumns(table: string): Array<{
|
|
2048
|
+
bucket?: string;
|
|
2049
|
+
enumValues?: string[];
|
|
2050
|
+
isStorage?: boolean;
|
|
2051
|
+
name: string;
|
|
2052
|
+
nullable?: boolean;
|
|
2053
|
+
onDelete?: "cascade" | "restrict" | "set null";
|
|
2054
|
+
optional: boolean;
|
|
2055
|
+
pk?: boolean;
|
|
2056
|
+
ref?: string;
|
|
2057
|
+
type: string;
|
|
2058
|
+
}> {
|
|
2032
2059
|
return LUNORA_TABLE_COLUMNS[table] ?? [];
|
|
2033
2060
|
}
|
|
2034
2061
|
|
|
@@ -2271,16 +2298,28 @@ ${Ke?`
|
|
|
2271
2298
|
return backfillSearchIndexes(this.sql as SqlExec, schema as unknown as SchemaLike, options);
|
|
2272
2299
|
}
|
|
2273
2300
|
`:""}
|
|
2274
|
-
private buildCtx(options: { bookmarks?: DispatchBookmark; functionPath?: string; headroom?: TransactionHeadroomTracker; identity?:
|
|
2301
|
+
private buildCtx(options: { bookmarks?: DispatchBookmark; functionPath?: string; headroom?: TransactionHeadroomTracker; identity?: SubscriptionIdentity; onRead?: (table: string, idOrScan?: string) => void; onReadRange?: (range: KeyRange) => void; scope?: QueryReadScope; trusted?: boolean } = {}): unknown {
|
|
2275
2302
|
const env = (this.env ?? {}) as Record<string, unknown>;
|
|
2276
|
-
//
|
|
2277
|
-
//
|
|
2278
|
-
//
|
|
2279
|
-
//
|
|
2280
|
-
//
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2303
|
+
// The caller context this ctx runs under, resolved ONCE on one
|
|
2304
|
+
// discriminant. When the caller threads an explicit identity
|
|
2305
|
+
// (subscription seed / refresh / stream pull / shape resolve — all
|
|
2306
|
+
// deferred or interleaved), it is used by value and the shared
|
|
2307
|
+
// per-request fields are never read, because a concurrent RPC owns
|
|
2308
|
+
// them: a refresh in particular runs inside the writing dispatch's
|
|
2309
|
+
// \`flushChangedTables\`, BEFORE its \`endDispatch\`, so \`getCurrentIp()\`
|
|
2310
|
+
// there is the MUTATING caller's address. Otherwise (the synchronous
|
|
2311
|
+
// RPC dispatch path) it falls back to those fields as before.
|
|
2312
|
+
//
|
|
2313
|
+
// One expression, not one per field: three parallel ternaries on the
|
|
2314
|
+
// same discriminant is how \`ip\` came to be the only one still reading
|
|
2315
|
+
// the shared field.
|
|
2316
|
+
const caller: SubscriptionIdentity = options.identity ?? {
|
|
2317
|
+
identity: this.getCurrentIdentity(),
|
|
2318
|
+
ip: this.getCurrentIp(),
|
|
2319
|
+
userId: this.getCurrentUserId(),
|
|
2320
|
+
};
|
|
2321
|
+
const { identity, ip, userId } = caller;
|
|
2322
|
+
${an}${de}${wn}${Le}${_e}${De}${Fe}
|
|
2284
2323
|
// Which dispatch this ctx belongs to. Drives the two deferral facades
|
|
2285
2324
|
// below and the \`ctx.run*\` caller guard; a ctx built for an
|
|
2286
2325
|
// admin/lifecycle path has no registered function, and so no kind.
|
|
@@ -2401,7 +2440,7 @@ ${xn}
|
|
|
2401
2440
|
// is visible and its spans join this trace. Degrades to the bare
|
|
2402
2441
|
// global when no sink is configured.
|
|
2403
2442
|
fetch: this.makeFetch(logFunctionPath, traceAnchor, observability),
|
|
2404
|
-
ip
|
|
2443
|
+
ip,
|
|
2405
2444
|
log,
|
|
2406
2445
|
metrics,
|
|
2407
2446
|
now,${dn}
|
|
@@ -2410,7 +2449,7 @@ ${xn}
|
|
|
2410
2449
|
storage: contextStorage,
|
|
2411
2450
|
trace,${cn}${Ie}${kn}${be}${Ee}${Pe}${ve}${ge}
|
|
2412
2451
|
};
|
|
2413
|
-
${
|
|
2452
|
+
${Sn}${vn}
|
|
2414
2453
|
ctx.runAction = (reference: FunctionReference, fnArgs: Record<string, unknown>) => dispatchRun("action", reference.__lunoraRef, fnArgs, ctx, contextKind);
|
|
2415
2454
|
// The composed mutation runs under the SAME wrapper the top-level RPC
|
|
2416
2455
|
// uses, so "do the transactional work in a mutation and call it from the
|
|
@@ -2425,17 +2464,19 @@ ${Rn}${vn}
|
|
|
2425
2464
|
// sub-query must not escape this dispatch's resource ceiling),
|
|
2426
2465
|
// \`scope\` (the reactive-cache capture — an untracked sub-query's reads
|
|
2427
2466
|
// must still be deps of the entry the OUTER query is memoized as, or
|
|
2428
|
-
// the memo goes stale), and — load-bearing — the
|
|
2429
|
-
//
|
|
2430
|
-
//
|
|
2431
|
-
//
|
|
2467
|
+
// the memo goes stale), and — load-bearing — the resolved \`caller\` BY VALUE
|
|
2468
|
+
// (identity, userId AND ip). Omitting it would let \`buildCtx\` fall back
|
|
2469
|
+
// to the shared per-request fields, which a concurrent RPC may have
|
|
2470
|
+
// re-set, and an RLS-scoped sub-query would then read as the wrong user
|
|
2471
|
+
// from the wrong address. A tracked call keeps sharing \`ctx\` exactly as
|
|
2472
|
+
// before.
|
|
2432
2473
|
ctx.runQuery = (reference: FunctionReference, fnArgs: Record<string, unknown>, runOptions?: { untracked?: boolean }) =>
|
|
2433
2474
|
dispatchRun(
|
|
2434
2475
|
"query",
|
|
2435
2476
|
reference.__lunoraRef,
|
|
2436
2477
|
fnArgs,
|
|
2437
2478
|
runOptions?.untracked === true
|
|
2438
|
-
? this.buildCtx({ bookmarks: options.bookmarks, functionPath: options.functionPath, headroom: options.headroom, identity:
|
|
2479
|
+
? this.buildCtx({ bookmarks: options.bookmarks, functionPath: options.functionPath, headroom: options.headroom, identity: caller, scope: options.scope })
|
|
2439
2480
|
: ctx,
|
|
2440
2481
|
contextKind,
|
|
2441
2482
|
);
|
|
@@ -2443,21 +2484,21 @@ ${Rn}${vn}
|
|
|
2443
2484
|
return ctx;
|
|
2444
2485
|
}
|
|
2445
2486
|
};
|
|
2446
|
-
`},Xe=e=>{switch(e.kind){case"array":case"object":case"record":case"union":return{builder:"text",mode:"json",notNull:!0,typeAnnotation:T(e)};case"bigint":return{builder:"blob",mode:"bigint",notNull:!0};case"boolean":return{builder:"integer",mode:"boolean",notNull:!0};case"bytes":return{builder:"blob",mode:"buffer",notNull:!0};case"date":case"timestamp":return{builder:"integer",notNull:!0};case"from":return{builder:"text",notNull:!0,typeAnnotation:T(e)};case"id":return{builder:"text",notNull:!0};case"literal":{const t=e.literalValue??"";return t.startsWith('"')||t.startsWith("'")?{builder:"text",notNull:!0}:t==="true"||t==="false"?{builder:"integer",mode:"boolean",notNull:!0}:t==="null"?{builder:"text",notNull:!0}:{builder:"real",notNull:!0}}case"null":return{builder:"text",notNull:!0};case"number":return{builder:"real",notNull:!0};case"optional":return{...e.inner?Xe(e.inner):{builder:"text",notNull:!1},notNull:!1};case"storage":case"string":return{builder:"text",notNull:!0};default:return{builder:"text",notNull:!0}}},At=(e,t)=>{const n=se(e);return n.kind==="id"&&n.tableName!==void 0&&t.has(n.tableName)?n.tableName:void 0},Hr=(e,t,n)=>{f(e,"drizzle column name");const r=Xe(t),o=r.mode?`, { mode: "${r.mode}" }`:"";let
|
|
2487
|
+
`},Xe=e=>{switch(e.kind){case"array":case"object":case"record":case"union":return{builder:"text",mode:"json",notNull:!0,typeAnnotation:T(e)};case"bigint":return{builder:"blob",mode:"bigint",notNull:!0};case"boolean":return{builder:"integer",mode:"boolean",notNull:!0};case"bytes":return{builder:"blob",mode:"buffer",notNull:!0};case"date":case"timestamp":return{builder:"integer",notNull:!0};case"from":return{builder:"text",notNull:!0,typeAnnotation:T(e)};case"id":return{builder:"text",notNull:!0};case"literal":{const t=e.literalValue??"";return t.startsWith('"')||t.startsWith("'")?{builder:"text",notNull:!0}:t==="true"||t==="false"?{builder:"integer",mode:"boolean",notNull:!0}:t==="null"?{builder:"text",notNull:!0}:{builder:"real",notNull:!0}}case"null":return{builder:"text",notNull:!0};case"number":return{builder:"real",notNull:!0};case"optional":return{...e.inner?Xe(e.inner):{builder:"text",notNull:!1},notNull:!1};case"storage":case"string":return{builder:"text",notNull:!0};default:return{builder:"text",notNull:!0}}},At=(e,t)=>{const n=se(e);return n.kind==="id"&&n.tableName!==void 0&&t.has(n.tableName)?n.tableName:void 0},Hr=(e,t,n)=>{f(e,"drizzle column name");const r=Xe(t),o=r.mode?`, { mode: "${r.mode}" }`:"";let a=`${r.builder}("${e}"${o})`;r.typeAnnotation&&(a+=`.$type<${r.typeAnnotation}>()`);const i=At(t,n);return i!==void 0&&(a+=`.references((): AnySQLiteColumn => ${i}._id)`),r.notNull&&(a+=".notNull()"),a},Gr=e=>{const t=e.unique?"uniqueIndex":"index",n=e.fields.map(r=>(f(r,"drizzle index field"),`t.${r}`)).join(", ");return` ${Y(e.name)}: ${t}(${JSON.stringify(e.name)}).on(${n}),`},Jr=(e,t)=>{f(e.name,"table name");const n=[' _id: text("_id").primaryKey(),',' _creationTime: integer("_creationTime").notNull(),',...Object.entries(e.shape).map(([o,a])=>` ${o}: ${Hr(o,a,t)},`)].join(`
|
|
2447
2488
|
`),r=e.indexes.length>0?`, (t) => ({
|
|
2448
2489
|
${e.indexes.map(o=>Gr(o)).join(`
|
|
2449
2490
|
`)}
|
|
2450
2491
|
})`:"";return`export const ${e.name} = sqliteTable("${e.name}", {
|
|
2451
2492
|
${n}
|
|
2452
|
-
}${r});`},zr=e=>e.typeAnnotation?.includes('Id<"')??!1,Yr=(e,t)=>{const n=new Set(["integer","sqliteTable","text"]),r=new Set;let o=!1,
|
|
2453
|
-
`;const n=ae(t),r=new Set(e.map(g=>g.name)),{columns:o,indexes:
|
|
2493
|
+
}${r});`},zr=e=>e.typeAnnotation?.includes('Id<"')??!1,Yr=(e,t)=>{const n=new Set(["integer","sqliteTable","text"]),r=new Set;let o=!1,a=!1;for(const i of e){for(const s of Object.values(i.shape)){const c=Xe(s);n.add(c.builder),a=a||zr(c),o=o||At(s,t)!==void 0}for(const s of i.indexes)r.add(s.unique?"uniqueIndex":"index")}return{columns:[...n].toSorted((i,s)=>i.localeCompare(s)),indexes:[...r].toSorted((i,s)=>i.localeCompare(s)),needsAnyColumn:o,needsId:a}},ht=(e,t=!1)=>{if(e.length===0)return`${S}export {};
|
|
2494
|
+
`;const n=ae(t),r=new Set(e.map(g=>g.name)),{columns:o,indexes:a,needsAnyColumn:i,needsId:s}=Yr(e,r),c=[...a,...o].toSorted((g,y)=>g.localeCompare(y)),d=e.map(g=>Jr(g,r)).join(`
|
|
2454
2495
|
|
|
2455
2496
|
`),h=[i?`import type { AnySQLiteColumn } from "${n.serverDrizzle}";
|
|
2456
|
-
`:"",
|
|
2457
|
-
`:""].join("");return`${
|
|
2497
|
+
`:"",s?`import type { Id } from "./dataModel.js";
|
|
2498
|
+
`:""].join("");return`${S}import { ${c.join(", ")} } from "${n.serverDrizzle}";
|
|
2458
2499
|
${h}
|
|
2459
2500
|
${d}
|
|
2460
|
-
`},vo=(e,t=!1)=>{const n=e.tables.filter(o=>o.shardMode==="global"),r=e.tables.filter(o=>o.shardMode!=="global");return{global:
|
|
2501
|
+
`},vo=(e,t=!1)=>{const n=e.tables.filter(o=>o.shardMode==="global"),r=e.tables.filter(o=>o.shardMode!=="global");return{global:L(ht(n,t),Je),shard:L(ht(r,t),Je)}},So=e=>e?`${S}/**
|
|
2461
2502
|
* The \`SchedulerDO\` Durable Object class, re-exported so a worker entry can
|
|
2462
2503
|
* forward it — wrangler binds only what the entry exports:
|
|
2463
2504
|
*
|
|
@@ -2467,16 +2508,16 @@ ${d}
|
|
|
2467
2508
|
* forwards this module for you whenever it exists.
|
|
2468
2509
|
*/
|
|
2469
2510
|
export { SchedulerDO } from "@lunora/scheduler";
|
|
2470
|
-
`:"",
|
|
2511
|
+
`:"",Ro=e=>{const t=new Map;for(const i of e){const s=t.get(i.cron);s?s.push(i):t.set(i.cron,[i])}const n=[...t.keys()].map(i=>` ${JSON.stringify(i)},`).join(`
|
|
2471
2512
|
`),r=n.length>0?`
|
|
2472
2513
|
${n}
|
|
2473
|
-
`:"",o=[...t.entries()].map(([i,
|
|
2514
|
+
`:"",o=[...t.entries()].map(([i,s])=>{const c=s.map(d=>{const h=d.workflow?`workflow: ${JSON.stringify(d.workflow.binding)}`:`functionPath: ${JSON.stringify(d.functionPath)}`;return` { name: ${JSON.stringify(d.name)}, ${h}, args: ${JSON.stringify(d.args)} },`}).join(`
|
|
2474
2515
|
`);return` ${JSON.stringify(i)}: [
|
|
2475
2516
|
${c}
|
|
2476
2517
|
],`}).join(`
|
|
2477
|
-
`),
|
|
2518
|
+
`),a=o.length>0?`
|
|
2478
2519
|
${o}
|
|
2479
|
-
`:"";return`${
|
|
2520
|
+
`:"";return`${S}/**
|
|
2480
2521
|
* One scheduled cron invocation. Exactly one target is set: \`functionPath\` is
|
|
2481
2522
|
* the \`namespace:fn\` dispatch ref (matches \`__lunoraRef\`), invoked on the
|
|
2482
2523
|
* shard; \`workflow\` is a \`WORKFLOW_*\` binding name whose durable workflow is
|
|
@@ -2500,11 +2541,11 @@ export const LUNORA_CRON_TRIGGERS: ReadonlyArray<string> = [${r}];
|
|
|
2500
2541
|
* Dispatcher map keyed by cron expression. The Worker's \`scheduled()\` handler
|
|
2501
2542
|
* looks up \`event.cron\` here and dispatches every job in the list.
|
|
2502
2543
|
*/
|
|
2503
|
-
export const LUNORA_CRONS: Record<string, ReadonlyArray<LunoraCronJob>> = {${
|
|
2544
|
+
export const LUNORA_CRONS: Record<string, ReadonlyArray<LunoraCronJob>> = {${a}};
|
|
2504
2545
|
`},$o=e=>{const t=[...e].toSorted((r,o)=>r.name.localeCompare(o.name)).map(r=>{const o=[`name: ${JSON.stringify(r.name)}`,`table: ${JSON.stringify(r.table)}`];return r.field!==void 0&&o.push(`field: ${JSON.stringify(r.field)}`),r.dimensions!==void 0&&o.push(`dimensions: ${JSON.stringify(r.dimensions)}`),r.metric!==void 0&&o.push(`metric: ${JSON.stringify(r.metric)}`),r.metadata!==void 0&&o.push(`metadata: ${JSON.stringify(r.metadata)}`),` { ${o.join(", ")} },`}).join(`
|
|
2505
2546
|
`),n=t.length>0?`
|
|
2506
2547
|
${t}
|
|
2507
|
-
`:"";return`${
|
|
2548
|
+
`:"";return`${S}/**
|
|
2508
2549
|
* One vector index declared in \`schema.ts\` — an inline \`.vectorize()\` column
|
|
2509
2550
|
* or a standalone \`defineVectorIndex()\`. \`field\` is the source column (absent
|
|
2510
2551
|
* for a \`select\`-derived Shape B index); \`metadata\` lists the row fields
|
|
@@ -2525,4 +2566,4 @@ export interface LunoraVectorIndex {
|
|
|
2525
2566
|
* \`createWorker({ vectorIntrospector })\` to back the studio's vector browser.
|
|
2526
2567
|
*/
|
|
2527
2568
|
export const LUNORA_VECTOR_INDEXES: ReadonlyArray<LunoraVectorIndex> = [${n}];
|
|
2528
|
-
`},To=e=>[...new Set(e.map(t=>t.cron))];export{co as A,In as C,
|
|
2569
|
+
`},To=e=>[...new Set(e.map(t=>t.cron))];export{co as A,In as C,S as G,er as U,ho as a,mo as b,bo as c,Ro as d,wo as e,uo as f,vo as g,fo as h,So as i,go as j,xo as k,$o as l,yo as m,To as n,yr as o,ko as p,po as q};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{A as w,G as k}from"./emit-
|
|
1
|
+
import{A as w,G as k}from"./emit-pX7uKd5t.mjs";const y=e=>`has${e.charAt(0).toUpperCase()}${e.slice(1)}`,b=w.map(({appMethod:e,key:t})=>[y(t),e.method,e.configKey,e.doc]),m=e=>b.some(([t])=>e[t]),S=e=>e?['import * as lunoraIdentityContract from "../identity.js";']:[],E=(e,t)=>e?['import type { CreateAccessResolverOptions } from "@lunora/cloudflare-access";',`import { createAccessResolver${t?", composeResolvers":""} } from "@lunora/cloudflare-access";`]:[],D=e=>e?['import { createKvIntrospectorFromEnv } from "@lunora/bindings/kv";']:[],x=e=>e?['import { createVectorAdminIntrospector } from "@lunora/bindings/vectors";']:[],R=e=>e?['import type { D1CtxDbOptions, D1DatabaseLike, D1Exec } from "@lunora/d1";','import { applyCdcChanges, createD1CtxDb, emitD1QueryCost, exportGlobalRows, facetGlobalColumn, importGlobalRows, listGlobalTables, readD1CdcChanges, readGlobalTablePage, retryingExec } from "@lunora/d1";']:[],A=e=>e?['import notifyConfig from "../notify.js";']:[],g=e=>(e.emailAgents?.length??0)>0,C=e=>g(e)?['import { dispatchAgentEmail } from "@lunora/agent/inbound";']:[],O=e=>g(e)?['import * as lunoraAgentDefinitions from "../agents.js";']:[],T=e=>{const{hasFramework:t,hasGlobal:a,hasHyperdriveGlobal:r,hasQueue:n,useUmbrella:i}=e,o=i?"lunorash/runtime":"@lunora/runtime",l=["ExecutionContextLike","HttpRouterLike","LunoraWorker","Route","ScheduledControllerLike","ShardNamespaceLike","WorkerOptions",...n?["TriggerTrace"]:[],...a?["GlobalIntrospector","AdminTableResolver"]:[],...t?["FrameworkHostHandler"]:[]],s=[...a||r?["createCrossShardRelationCapabilities"]:[],"createWorker","resolveLogArchiveFromEnv",...t?["withFrameworkWorker"]:[]].join(", ");return[`import type { ${[...l].toSorted((c,d)=>c.localeCompare(d)).join(", ")} } from "${o}";`,`import { ${s} } from "${o}";`]},I=e=>{const{hasAccess:t,hasAuth:a,hasGlobal:r,hasHyperdriveGlobal:n,hasKvIntrospector:i,hasQueue:o,hasScheduler:l,hasStorage:s,hasWorkflow:c,wantsOpenApi:d,wantsOpenRpc:h}=e;return[...a?['import type { AuthNamespaceLike, LunoraAuth, LunoraAuthOptions } from "@lunora/auth";','import { createAuth, createAuthAdmin, createAuthAuditReader, createDoAuthWiring, d1Executor, ensureMigrated, handleAuthRequest, lunoraD1Adapter } from "@lunora/auth";']:[],...E(t,a),...R(r),...n?['import type { HyperdriveEngine } from "@lunora/hyperdrive/global";','import { createHyperdriveGlobalCtxDb } from "@lunora/hyperdrive/global";','import type { SqlCtxDbOptions, SqlExec } from "@lunora/sql-store";']:[],...D(i),...x(e.hasVectors===!0),...l?['import type { DurableObjectNamespaceLike } from "@lunora/scheduler";','import { createScheduler } from "@lunora/scheduler";']:[],...s?['import type { R2BucketLike, R2S3Credentials, Storage } from "@lunora/storage";','import { createBucketStorage, createStorage } from "@lunora/storage";']:[],...c?['import { createWorkflowsRestClient } from "@lunora/workflow";']:[],...C(e),...T(e),"",...S(e.identity),...O(e),...r||n?['import schema from "../schema.js";']:[],...A(e.hasNotify),'import { LUNORA_CRONS } from "./crons.js";','import { LUNORA_FUNCTIONS } from "./functions.js";',...o?['import { createQueueCaptureSink, dispatchQueueBatch, shouldCaptureQueue } from "@lunora/queue";','import { LUNORA_QUEUE_REGISTRY } from "./queues.js";']:[],...d?['import { openApiSpec } from "./openapi.js";']:[],...h?['import { openRpcSpec } from "./openrpc.js";']:[],'import { createShardDO } from "./shard.js";',...e.hasVectors===!0?['import { LUNORA_VECTOR_INDEXES } from "./vectors.js";']:[]]},L=e=>[...e.hasStorage?['/** `.storage(...)` declaration — one bucket (required) plus optional extra named buckets and signed-URL config. Backs `ctx.storage` AND the studio file browser. */\ninterface StorageDeclaration<Env> {\n /** The default R2 bucket binding (the bare `ctx.storage`). */\n bucket: Selector<Env, R2BucketLike>;\n /** Extra named buckets, reached via `ctx.storage.bucket("name")` and the studio\'s bucket picker. */\n buckets?: Record<string, Selector<Env, R2BucketLike>>;\n /** Public base URL signed/public object URLs resolve against. */\n publicBaseUrl?: Selector<Env, string>;\n /** R2 S3-API credentials (`{ accountId, accessKeyId, secretAccessKey, bucket, jurisdiction? }`) enabling `ctx.storage.getPresignedUrl` — native S3 presigned URLs that hit R2 directly, bypassing the worker. Omit to use only the worker-signed `getSignedUrl` path. */\n s3?: Selector<Env, R2S3Credentials>;\n /** HMAC secret for signed URLs. */\n signingSecret?: Selector<Env, string>;\n}']:[],...e.hasScheduler?["/** `.scheduler(...)` declaration — the `SchedulerDO` namespace. Backs `ctx.scheduler` AND the studio's scheduled-jobs view. The origin its callbacks dispatch back to is not declared here: the DO reads `env.LUNORA_ORIGIN_URL` at fire time, because a caller-supplied dispatch target would be an SSRF vector. */\ninterface SchedulerDeclaration<Env> {\n /** The `SchedulerDO` namespace binding (typically `env.SCHEDULER`). */\n namespace: Selector<Env, DurableObjectNamespaceLike & ShardNamespaceLike>;\n}"]:[],...e.hasGlobal?["/** `.global(...)` declaration — the D1 binding backing `.global()` tables. Backs cross-tenant `ctx.db` reads/writes AND the studio's global data browser. */\ninterface GlobalDeclaration<Env> {\n /** The D1 binding (typically `env.DB`). */\n d1: Selector<Env, D1DatabaseLike>;\n /** The worker origin used to fan reverse cross-backend relations across shards. Without it, such a relation throws a clear error. */\n origin?: Selector<Env, string>;\n}"]:[],...e.hasHyperdriveGlobal?['/** `.hyperdriveGlobal(...)` declaration — backs `.global({ backend: "hyperdrive" })` tables on a Postgres/MySQL database via Hyperdrive. Stays reactive: the writer is injected as `globalDb` and the broadcast hook drives live queries. */\ninterface HyperdriveGlobalDeclaration<Env> {\n /** The Hyperdrive engine — selects the Postgres or MySQL dialect. */\n engine: HyperdriveEngine;\n /** Build the `SqlExec` from `env` — e.g. `buildPgExec(fromPostgresJs(postgres(env.HYPERDRIVE.connectionString)))`. Cache the driver on the DO instance; rebuild lazily after hibernation. */\n exec: (env: Env) => SqlExec;\n /** The worker origin used to fan reverse cross-backend relations across shards. Without it, such a relation throws a clear error. */\n origin?: Selector<Env, string>;\n}']:[],...e.hasAuth?['/** `.auth(...)` declaration — better-auth options plus the storage the adapter reads. Give it `d1` (the default) or `namespace` (a Durable Object that hosts the auth tables), never both. The builder owns the lazy build + `ensureMigrated` dance and wires `authHandler` / `resolveIdentity` / `authAdmin`. */\ninterface AuthDeclaration<Env> {\n /** The D1 binding the auth SQL adapter is wired over (via `lunoraD1Adapter`). Omit only when using `namespace`. */\n d1?: Selector<Env, unknown>;\n /** Shared secret the worker presents on the object\'s internal session route. REQUIRED with `namespace`: the binding is reachable from any worker bound to it, so the secret — not the binding — is the authorization boundary. Without it identity resolution fails closed. */\n internalSecret?: Selector<Env, string>;\n /** Name of the Durable Object instance holding the auth tables. Defaults to `"auth"`. Set it to run separate auth objects (per deployment, per tenant) off one namespace. */\n objectName?: Selector<Env, string>;\n /** The auth Durable Object namespace — the DO-backed mode. Needed for `@better-auth/scim`, which requires native transactions that D1 has none of. The object owns the auth tables, so `/api/auth/*` and identity resolution both go through it. Typed as `AuthNamespaceLike` because `createDoAuthWiring` resolves through `idFromName` + `get` and has no `getByName` fallback — both members are load-bearing here, and `ShardNamespaceLike` leaves both optional. */\n namespace?: Selector<Env, AuthNamespaceLike>;\n /** Build the better-auth options from `env` (secret, plugins, email/password, …). */\n options: (env: Env) => LunoraAuthOptions;\n}']:[]],N=e=>[...e.hasAccess?[" private accessSelector?: Selector<Env, CreateAccessResolverOptions | undefined>;"]:[]," private adminToken?: Selector<Env, string>;",...e.hasAuth?[" private authDeclaration?: AuthDeclaration<Env>;"]:[]," private cdcEnabled = false;"," private reactiveCacheConfig: boolean | { maxBytes?: number; maxEntries?: number } = false;",' private maxRelationKeysLimit?: ShardConfig["maxRelationKeys"];',' private observabilitySink?: ShardConfig["observability"];',' private relationExistsPushDownMode?: ShardConfig["relationExistsPushDown"];'," private readonly extendFns: ((env: Env, derived: Readonly<WorkerOptions>) => Partial<WorkerOptions>)[] = [];",...e.hasGlobal?[" private globalDeclaration?: GlobalDeclaration<Env>;"]:[],...e.hasHyperdriveGlobal?[" private hyperdriveGlobalDeclaration?: HyperdriveGlobalDeclaration<Env>;"]:[]," private httpRouterApp?: HttpRouterLike;"," private readonly routeMap: Record<string, Route> = {};",...e.hasScheduler?[" private schedulerDeclaration?: SchedulerDeclaration<Env>;"]:[],...m(e)?[" private readonly shardExtras: Partial<ShardConfig> = {};"]:[]," private shardSelector?: Selector<Env, ShardNamespaceLike>;",...e.hasStorage?[" private storageDeclaration?: StorageDeclaration<Env>;"]:[]],q=e=>b.filter(([t])=>e[t]).map(([,t,a,r])=>` /** ${r} */
|
|
2
2
|
public ${t}(factory: (env: Env) => ReturnType<NonNullable<ShardConfig["${a}"]>>): this {
|
|
3
3
|
this.shardExtras.${a} = factory as NonNullable<ShardConfig["${a}"]>;
|
|
4
4
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/codegen",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.182",
|
|
4
4
|
"description": "Code generator for Lunora: emits _generated/{api,server,dataModel}.ts from your schema",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -46,13 +46,13 @@
|
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@lunora/advisor": "1.0.0-alpha.
|
|
50
|
-
"@lunora/agent": "1.0.0-alpha.
|
|
49
|
+
"@lunora/advisor": "1.0.0-alpha.132",
|
|
50
|
+
"@lunora/agent": "1.0.0-alpha.111",
|
|
51
51
|
"@lunora/container": "1.0.0-alpha.49",
|
|
52
52
|
"@lunora/errors": "1.0.0-alpha.36",
|
|
53
|
-
"@lunora/platform": "1.0.0-alpha.
|
|
54
|
-
"@lunora/queue": "1.0.0-alpha.
|
|
55
|
-
"@lunora/scheduler": "1.0.0-alpha.
|
|
53
|
+
"@lunora/platform": "1.0.0-alpha.31",
|
|
54
|
+
"@lunora/queue": "1.0.0-alpha.55",
|
|
55
|
+
"@lunora/scheduler": "1.0.0-alpha.72",
|
|
56
56
|
"@lunora/values": "1.0.0-alpha.46",
|
|
57
57
|
"@lunora/workflow": "1.0.0-alpha.52",
|
|
58
58
|
"jiti": "^2.7.0",
|