@lunora/config 1.0.0-alpha.35 → 1.0.0-alpha.351
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/LICENSE.md +135 -0
- package/README.md +3 -3
- package/dist/cloudflare/index.d.mts +1252 -0
- package/dist/cloudflare/index.d.ts +1252 -0
- package/dist/cloudflare/index.mjs +1 -0
- package/dist/index.d.mts +1048 -917
- package/dist/index.d.ts +1048 -917
- package/dist/index.mjs +1 -23
- package/dist/packem_shared/ACCENT-CotPTfv7.mjs +7 -0
- package/dist/packem_shared/AGENT_MODE_ENV-D8MvSwPE.mjs +1 -0
- package/dist/packem_shared/AGENT_RULES_DIR-HrrbNZPy.mjs +1 -0
- package/dist/packem_shared/ALLOW_FORWARDED_ENV-BUndghJx.mjs +1 -0
- package/dist/packem_shared/BINDING_MANIFEST_VERSION-CfXEYG8e.mjs +1 -0
- package/dist/packem_shared/CLOUDFLARE_CLI_CONFIG_WARNING_ENV-BKMrOuXV.mjs +1 -0
- package/dist/packem_shared/CLOUDFLARE_DRIVER-CULavrYO.mjs +1 -0
- package/dist/packem_shared/CLOUDFLARE_TOOLCHAIN_VERSIONS-DV5E_f_q.mjs +1 -0
- package/dist/packem_shared/CODEGEN_ENV-ZsCxV1kP.mjs +1 -0
- package/dist/packem_shared/COMPOSED_WORKER_ENTRY-Ciiba5g_.mjs +1 -0
- package/dist/packem_shared/DEFAULT_DEPLOY_TARGET-rR7buNQw.mjs +1 -0
- package/dist/packem_shared/DEFAULT_OBSERVABILITY-bN6UkTMx.mjs +1 -0
- package/dist/packem_shared/DEV_BINDINGS_FILE-C0ZN_XlP.mjs +4 -0
- package/dist/packem_shared/DEV_VARS_EXAMPLE_FILE-CqLorAxT.mjs +6 -0
- package/dist/packem_shared/DEV_WORKER_ENV_VALUE-2XFXmRrP.mjs +1 -0
- package/dist/packem_shared/GLOBAL_FETCH_STRICTLY_PUBLIC_FLAG-f8CnJha3.mjs +1 -0
- package/dist/packem_shared/LINKED_PROJECT_DIR-Ba5qPEwo.mjs +2 -0
- package/dist/packem_shared/LUNORA_EVENT_SOURCE-B9ZVohjO.mjs +1 -0
- package/dist/packem_shared/LUNORA_IGNORED_PATHS-U93uPxrW.mjs +19 -0
- package/dist/packem_shared/LUNORA_TAG-CiQM3BkI.mjs +1 -0
- package/dist/packem_shared/LunoraReporter-f277GLNT.mjs +6 -0
- package/dist/packem_shared/PACKAGE_SECRETS_REGISTRY-38Plje8b.mjs +1 -0
- package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-BmJYwAy2.mjs +1 -0
- package/dist/packem_shared/REMOTE_ELIGIBLE_KEYS-PLeh_74E.mjs +1 -0
- package/dist/packem_shared/REQUIRED_COMPATIBILITY_DATE-OLQlG0oj.mjs +1 -0
- package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-BeTxqCuQ.mjs +1 -0
- package/dist/packem_shared/SEED_ENDPOINT-2B56PN_H.mjs +1 -0
- package/dist/packem_shared/STUDIO_PATH-CSx_psKS.mjs +1 -0
- package/dist/packem_shared/UNEXPORTED_CLASS_MARKER-DwJCN8fX.mjs +1 -0
- package/dist/packem_shared/WORKERS_CACHE_MIN_DATE-0k9ABJtF.mjs +1 -0
- package/dist/packem_shared/WRANGLER_FILES-UNW-xY5u.mjs +1 -0
- package/dist/packem_shared/acceptsConnection-DHhUYGjT.mjs +2 -0
- package/dist/packem_shared/addArgsFor-CYZKhNIo.mjs +1 -0
- package/dist/packem_shared/applyAdditiveEdit-CH0VhMJ2.mjs +6 -0
- package/dist/packem_shared/applyModify-DKP2l6S9.mjs +1 -0
- package/dist/packem_shared/applyStudioAssetCache-DHQEJuuv.mjs +1 -0
- package/dist/packem_shared/assertWranglerSatisfiesSchema-Dd7ZPhw7.mjs +3 -0
- package/dist/packem_shared/assetContentType-CUb5bpbI.mjs +1 -0
- package/dist/packem_shared/buildPackageSecretsBlock-BWV_VxqV.mjs +19 -0
- package/dist/packem_shared/celld-config-D-L6uskI.mjs +3 -0
- package/dist/packem_shared/classifyPolicyEdit-DJi9Fk8G.mjs +24 -0
- package/dist/packem_shared/collectExportGaps-BPuhGH2J.mjs +2 -0
- package/dist/packem_shared/createConfirm-D5mKTMHj.mjs +7 -0
- package/dist/packem_shared/createDiscoveryCache-npJI4uej.mjs +1 -0
- package/dist/packem_shared/describePreservedCrons-C5KPuPy3.mjs +1 -0
- package/dist/packem_shared/describeWithheldWorkersAi-IIxe3TuI.mjs +1 -0
- package/dist/packem_shared/detectFramework-Dfpvu6rD.mjs +1 -0
- package/dist/packem_shared/discover-info-DC2MrAIM.mjs +1 -0
- package/dist/packem_shared/discoverAgentInfo-pqFMJBtJ.mjs +1 -0
- package/dist/packem_shared/discoverContainerInfo-DzXr7Vm3.mjs +1 -0
- package/dist/packem_shared/discoverSchemaInfo-BBRlXZop.mjs +1 -0
- package/dist/packem_shared/discoverWorkflowInfo-zW7Tt0Tn.mjs +1 -0
- package/dist/packem_shared/guards-Buu_E7mP.mjs +1 -0
- package/dist/packem_shared/hasCloudflareCredentials-byvHpEiD.mjs +1 -0
- package/dist/packem_shared/infer-bindings-C1NFOdMi.mjs +1 -0
- package/dist/packem_shared/infer-bindings.d-CFxssIAC.d.mts +480 -0
- package/dist/packem_shared/infer-bindings.d-CFxssIAC.d.ts +480 -0
- package/dist/packem_shared/inferLunoraBindings-Gp_7yyIo.mjs +1 -0
- package/dist/packem_shared/interpretRemote-CcmGeGZ_.mjs +1 -0
- package/dist/packem_shared/lunora-manifest-DuH_Cmyu.mjs +6 -0
- package/dist/packem_shared/materializeServiceDevConfigs-DLUHefD-.mjs +1 -0
- package/dist/packem_shared/mergeWranglerEnvironment-DXiB-HcS.mjs +1 -0
- package/dist/packem_shared/package-secrets-registry-BeheNwsP.mjs +1 -0
- package/dist/packem_shared/parseDevVariable-teAAahVD.mjs +1 -0
- package/dist/packem_shared/parseSchema-D1Wbr1qv.mjs +1 -0
- package/dist/packem_shared/policy-scaffold.d-D2H4_G01.d.mts +86 -0
- package/dist/packem_shared/policy-scaffold.d-D2H4_G01.d.ts +86 -0
- package/dist/packem_shared/process-tree-once-Ou4SfxKM.mjs +1 -0
- package/dist/packem_shared/readProjectDependencies-l3uhUKjo.mjs +1 -0
- package/dist/packem_shared/reconcile-services-DFqH4eMQ.mjs +1 -0
- package/dist/packem_shared/reconcileBindingsSafely-7IJ58Uit.mjs +1 -0
- package/dist/packem_shared/reconcileWranglerCompatibilityDate-hocXEuRA.mjs +1 -0
- package/dist/packem_shared/renderStudioHtml-ByowDtMl.mjs +15 -0
- package/dist/packem_shared/resolveSchemaDirectory-Ca5P6KuP.mjs +1 -0
- package/dist/packem_shared/runPostCodegenHook-Dx3yTsYZ.mjs +1 -0
- package/dist/packem_shared/scanWranglerVariablesForSecrets-BFTVje1q.mjs +1 -0
- package/dist/packem_shared/serveJsonHandler-Dv0EdCb9.mjs +1 -0
- package/dist/packem_shared/startCelldDevSession-BLFsd6jG.mjs +1 -0
- package/dist/packem_shared/streamContainerLogs-0nko1qpv.mjs +2 -0
- package/dist/packem_shared/validate-bindings-CvNBF3U4.mjs +1 -0
- package/dist/packem_shared/withTailConsumer-DngzpJMK.mjs +1 -0
- package/dist/packem_shared/worker-entry-checks-AIASCYl7.mjs +1 -0
- package/dist/packem_shared/wranglerCodegenInputs-CbisphsH.mjs +1 -0
- package/dist/packem_shared/wranglerToAlchemy-CBO2ucRm.mjs +6 -0
- package/dist/packem_shared/write-atomic-CK6VZaPI.mjs +1 -0
- package/dist/studio-host/index.d.mts +314 -110
- package/dist/studio-host/index.d.ts +314 -110
- package/dist/studio-host/index.mjs +1 -7
- package/package.json +16 -7
- package/dist/packem_shared/ACCENT-DW1XJn8i.mjs +0 -40
- package/dist/packem_shared/AGENT_RULES_DIR-lcgC08aE.mjs +0 -40
- package/dist/packem_shared/DEV_VARS_EXAMPLE_FILE-dJPNTEnK.mjs +0 -37
- package/dist/packem_shared/LINKED_PROJECT_DIR-CXwXzV_C.mjs +0 -52
- package/dist/packem_shared/LUNORA_CONFIG_FILE-CtcIcB5-.mjs +0 -34
- package/dist/packem_shared/LUNORA_EVENT_SOURCE-D2fDeGB6.mjs +0 -86
- package/dist/packem_shared/LunoraReporter-Ci-bDCK9.mjs +0 -70
- package/dist/packem_shared/PACKAGE_SECRETS_REGISTRY-B8t_SdoZ.mjs +0 -70
- package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-CiC2IGKx.mjs +0 -103
- package/dist/packem_shared/REMOTE_ELIGIBLE_KEYS-BC7_e9Bz.mjs +0 -105
- package/dist/packem_shared/REQUIRED_COMPATIBILITY_DATE-2YYyWJUq.mjs +0 -561
- package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-Df-Wrix-.mjs +0 -99
- package/dist/packem_shared/SEED_ENDPOINT-DVCjaGO-.mjs +0 -61
- package/dist/packem_shared/WRANGLER_FILES-DwSuC-Kn.mjs +0 -25
- package/dist/packem_shared/applyAdditiveEdit-C-snTFEV.mjs +0 -228
- package/dist/packem_shared/buildPackageSecretsBlock-DWDKHViT.mjs +0 -243
- package/dist/packem_shared/classifyPolicyEdit-BHeAqF8P.mjs +0 -99
- package/dist/packem_shared/createConfirm-fvpdgJ9s.mjs +0 -100
- package/dist/packem_shared/detectFramework-Br-BcPBq.mjs +0 -41
- package/dist/packem_shared/discoverContainerInfo-BXFs6Wav.mjs +0 -19
- package/dist/packem_shared/discoverSchemaInfo-BB-CKlTK.mjs +0 -25
- package/dist/packem_shared/discoverWorkflowInfo-CedvR0mn.mjs +0 -19
- package/dist/packem_shared/inferLunoraBindings-ByMwG-gH.mjs +0 -352
- package/dist/packem_shared/loadStudioAssets-Csk5RS4E.mjs +0 -28
- package/dist/packem_shared/parseDevVariable-CJiq2IwE.mjs +0 -30
- package/dist/packem_shared/parseSchema-DSeyktvG.mjs +0 -107
- package/dist/packem_shared/policy-scaffold.d-DCmwn7zQ.d.mts +0 -74
- package/dist/packem_shared/policy-scaffold.d-DCmwn7zQ.d.ts +0 -74
- package/dist/packem_shared/reconcileWranglerBindings-Cruwwx1M.mjs +0 -334
- package/dist/packem_shared/renderStudioHtml-449Ysn75.mjs +0 -37
- package/dist/packem_shared/serveJsonHandler-B4OLTGLS.mjs +0 -86
- package/dist/packem_shared/streamContainerLogs-BZ4cOZwH.mjs +0 -157
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as d}from"node:fs";import{discoverSchema as l,isHyperdriveGlobalTable as f,isD1GlobalTable as b}from"@lunora/codegen";import{Project as u}from"ts-morph";import{join as p}from"node:path";const a=e=>{if(e?.kind==="optional")return a(e.inner);if(e?.kind==="union"){const s=new Set((e.members??[]).filter(i=>i.kind!=="null").map(i=>a(i)));return s.size===1?[...s][0]:e.kind}return e?.kind},m=(e,s)=>{const i=p(e,s,"schema.ts");if(!d(i))return{info:void 0};try{const o=new u({skipAddingFilesFromTsConfig:!0,useInMemoryFileSystem:!1}),r=l(o,i,e),c=n=>r.tables.find(t=>t.name===n)?.shape??{};return{info:{hasD1GlobalTable:r.tables.some(n=>b(n)),hasHyperdriveGlobalTable:r.tables.some(n=>f(n)),...r.jurisdiction===void 0?{}:{jurisdiction:r.jurisdiction},vectorIndexNames:r.vectorIndexes.map(n=>n.name),vectorMetadata:r.vectorIndexes.flatMap(n=>(n.metadata??[]).map(t=>({index:n.name,kind:a(c(n.table)[t]),property:t})))}}}catch(o){return{error:o instanceof Error?o.message:String(o),info:void 0}}},I=(e,s,i)=>i===void 0?m(e,s):i.memo(`schema:${e}:${s}`,()=>m(e,s));export{I as discoverSchemaInfo};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{discoverWorkflows as f,WORKFLOWS_FILENAME as i}from"@lunora/codegen";import{d as t}from"./discover-info-DC2MrAIM.mjs";const d=(r,s)=>{const{error:o,value:e}=t(r,s,i,f);return o===void 0?{workflows:e??[]}:{error:o,workflows:[]}};export{d as discoverWorkflowInfo};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const n=t=>typeof t=="object"&&t!==null&&!Array.isArray(t),s=t=>typeof t=="string"&&t.length>0;export{s as a,n as i};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{readFileSync as d,readdirSync as m}from"node:fs";import{homedir as L}from"node:os";import{join as r}from"node:path";const u=[".env",".env.local",".env.development",".env.development.local"],l=["CLOUDFLARE_API_TOKEN","CF_API_TOKEN"],f=["CLOUDFLARE_API_KEY","CF_API_KEY"],A=["CLOUDFLARE_EMAIL","CF_EMAIL"],v=new Set([...l,...f,...A]),O=/^export\s+/u,S=/\r?\n/u,p=/^(["'])(.*)\1$/u,E=t=>t!==void 0&&t.trim()!=="",C=(t,o)=>[o,t.XDG_CONFIG_HOME,r(o,"Library","Preferences"),r(o,".config"),t.APPDATA===void 0?void 0:r(t.APPDATA,"xdg.config"),r(o,"AppData","Roaming","xdg.config")].filter(s=>E(s)),I=t=>{try{return m(t).length>0}catch{return!1}},K=t=>{const o=new Set;for(const s of u){let n;try{n=d(r(t,s),"utf8")}catch{continue}for(const e of n.split(S)){const c=e.trim().replace(O,""),i=c.indexOf("=");if(c.startsWith("#")||i===-1)continue;const a=c.slice(0,i).trim(),_=c.slice(i+1).trim().replace(p,"$2");v.has(a)&&E(_)&&o.add(a)}}return o},F=(t={})=>{const o=t.env??process.env,s=t.projectRoot===void 0?new Set:K(t.projectRoot),n=e=>E(o[e])||s.has(e);return l.some(e=>n(e))||f.some(e=>n(e))&&A.some(e=>n(e))?!0:C(o,t.home??L()).some(e=>I(r(e,".wrangler","config")))};export{F as hasCloudflareCredentials};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{existsSync as P,statSync as j,readFileSync as F,readdirSync as B}from"node:fs";import{discoverFlags as L,FLAGS_FILENAME as k,discoverQueues as G,CAPABILITY_PROBES as N,readServiceBindings as W,discoverNotifyChannels as Y,NOTIFY_FILENAME as K,mayReadCapabilityContext as q,foldCapabilitySignals as C,capabilitiesUsedBy as M,sourceCapabilitySignals as U}from"@lunora/codegen";import{init as H}from"es-module-lexer";import{Project as X}from"ts-morph";import{discoverAgentInfo as Q}from"./discoverAgentInfo-pqFMJBtJ.mjs";import{discoverContainerInfo as V}from"./discoverContainerInfo-DzXr7Vm3.mjs";import{escapeRegExp as J}from"./DEV_VARS_EXAMPLE_FILE-CqLorAxT.mjs";import{d as _}from"./discover-info-DC2MrAIM.mjs";import{relative as z,sep as Z,isAbsolute as ee,join as b}from"node:path";import{P as se}from"./package-secrets-registry-BeheNwsP.mjs";import{discoverSchemaInfo as te}from"./discoverSchemaInfo-BBRlXZop.mjs";import{resolveWorkerEntry as re,composedEntryDurableObjects as ne,GENERATED_DIRECTORY as I,DURABLE_OBJECT_BINDINGS as oe,detectExportedDurableObjects as ae,detectClassExports as x,isMergedProject as ie}from"./COMPOSED_WORKER_ENTRY-Ciiba5g_.mjs";import{discoverWorkflowInfo as ce}from"./discoverWorkflowInfo-zW7Tt0Tn.mjs";const de="https://api.cloudflare.com/client/v4/accounts/<ACCOUNT_ID>/artifacts/namespaces",ue=e=>{const s='add an "artifacts" binding ({ binding: "ARTIFACTS", namespace }) — codegen reads env.ARTIFACTS unless `.artifacts()` on defineApp points ctx.artifacts at another binding';return e===void 0?`ctx.artifacts is used; ${s}. The namespace is created by the first repo create() if it does not exist yet.`:`ctx.artifacts is used and the schema pins data to "${e}"; create the namespace in that jurisdiction BEFORE the first repo, with POST ${de} and body { "namespace": "<name>", "jurisdiction": "${e}" }, then ${s}. A namespace's jurisdiction cannot be changed, and one created implicitly by the first repo create() is unrestricted.`},le=(e,s)=>{const{error:r,value:t}=_(e,s,k,L);return r===void 0?{flags:t}:{error:r}},me=(e,s)=>{const r=z(s,e);return r!==""&&r!==".."&&!r.startsWith(`..${Z}`)&&!ee(r)},pe=(e,s)=>{const{error:r,value:t}=_(e,s,void 0,G);return r===void 0?{queues:t??[]}:{error:r,queues:[]}},he=new Set([".cjs",".cts",".js",".jsx",".mjs",".mts",".ts",".tsx"]),fe=new Set([".git",".lunora-cache",".wrangler","dist",I,"node_modules"]),ge=["lunora","src"],be=/\benv\s*\.\s*DB\b/,ye=/\benv\s*\.\s*AI\b/,$=["ai","aiSearch","analytics","analyticsSql","artifacts","browser","hyperdrive","images","kv","mail","notify","payments","pipelines","r2sql","scheduler","storage","x402"],D=e=>`uses${e.charAt(0).toUpperCase()}${e.slice(1)}`,T=[["usesAuth","@lunora/auth"],["usesCimdWorkers","@lunora/auth/cimd/workers"],["usesX402Charge","@lunora/x402/charge"],["usesPaymentAutumn","@lunora/payment/autumn"],["usesPaymentCreem","@lunora/payment/creem"],["usesPaymentDodopayments","@lunora/payment/dodopayments"],["usesPaymentPolar","@lunora/payment/polar"],["usesPaymentStripe","@lunora/payment/stripe"]],O=[...$.map(e=>[D(e),N[e].moduleSpecifier]),...T].toSorted(([e],[s])=>e.localeCompare(s)),Se=[["usesNotifyFcm","@lunora/notify:fcm"],["usesNotifyWebPush","@lunora/notify:webPush"]],ve=["@lunora/agent","@lunora/agent/sandbox"],Ee=new RegExp(String.raw`["'\x60](?:${[...O.map(([,e])=>e),...ve].map(e=>J(e)).join("|")})["'\x60]`,"u"),a=e=>{const{contextProperty:s,moduleSpecifier:r}=N[e];return s===void 0?`${r} is imported`:`${r} is imported or ctx.${s} is read`},Ae="STRIPE_SECRET_KEY + STRIPE_WEBHOOK_SECRET (Stripe) or POLAR_ACCESS_TOKEN + POLAR_WEBHOOK_SECRET (Polar)",xe=()=>{let e;return()=>(e??=new X({compilerOptions:{allowJs:!0},useInMemoryFileSystem:!0}),e)},Ie=(e,s,r)=>{const t=r(),n=t.createSourceFile(`/scan/${s.slice(s.lastIndexOf("/")+1)}`,e,{overwrite:!0}),o=U(n);return t.removeSourceFile(n),o},w=(e,s)=>{let r;try{r=B(e,{withFileTypes:!0})}catch{return}for(const t of r){if(t.isDirectory()){fe.has(t.name)||w(b(e,t.name),s);continue}const n=t.name.lastIndexOf(".");n!==-1&&he.has(t.name.slice(n))&&s.push(b(e,t.name))}},_e=(e,s,r)=>{const{info:t}=te(e,s,r);return{jurisdiction:t?.jurisdiction,needsD1:t?.hasD1GlobalTable??!1}},Re=(e,s,r)=>{const t=xe(),n=b(e,r),o=[],d=[];let u=!1,i=!1;for(const l of s){const p=b(e,l);if(!P(p)||!j(p).isDirectory())continue;const f=[];w(p,f);for(const m of f){const c=F(m,"utf8"),A=me(m,n);u||=ye.test(c),i||=be.test(c),(Ee.test(c)||A&&q(c))&&(A?o:d).push(Ie(c,m,t))}}const h=C(o),y=C([h,...d]),S=new Set([...y.valueImports,...y.dynamicImports]),v=M({contextReads:h.contextReads,valueImports:S});return{...Object.fromEntries([...$.map(l=>[D(l),v.has(l)]),...T.map(([l,p])=>[l,S.has(p)])]),needsD1:i,usesAi:v.has("ai")||u,usesBrowser:v.has("browser")||h.sandboxTools.usesSandboxBrowser,usesWorkerLoader:h.sandboxTools.usesSandboxLoader}},Ce=(e,s,r)=>[...e.map(t=>t.exported?`${t.bindingName}/${t.className} (container "${t.exportName}" declared and exported)`:`hint: container "${t.exportName}" is declared but ${t.className} is not exported by the worker entry — add \`export * from "./lunora/_generated/containers"\``),...s.map(t=>t.exported?`exports.${t.className} (workflow "${t.exportName}" declared and exported)`:`hint: workflow "${t.exportName}" is declared but ${t.className} is not exported by the worker entry — add \`export * from "./lunora/_generated/workflows"\``),...r.map(t=>t.exported?`exports.${t.className} (agent "${t.exportName}" declared and exported)`:`hint: agent "${t.exportName}" is declared but ${t.className} is not exported by the worker entry — add \`export * from "./lunora/_generated/agents"\``)],Ne=(e,s,r)=>[[e.usesAi,`AI (${a("ai")}, or env.AI is used)`],[e.usesAuth&&!s.has("SessionDO"),"hint: @lunora/auth is imported; its tables are D1-backed by default. For DO-backed auth (what @better-auth/scim needs), pass `namespace` to .auth() and export the generated auth DO class"],[e.usesScheduler&&!s.has("SchedulerDO"),`hint: ${a("scheduler")}, but no SchedulerDO is exported by the worker entry`],[e.usesStorage,`hint: ${a("storage")}; add an r2_buckets binding (bucket binding names are user-defined)`],[e.usesMail,`hint: ${a("mail")}; set RESEND_API_KEY in .dev.vars (obtain at https://resend.com/api-keys)`],[e.usesPayments,`hint: ${a("payments")}; set the provider secrets in .dev.vars — ${Ae}`],[e.usesBrowser,`browser (${a("browser")}, or a sandbox browserTool imported in lunora/) — self-describing { binding: BROWSER }`],[e.usesImages,`images (${a("images")}) — self-describing { binding: IMAGES }`],[e.usesAnalytics,`analytics_engine_datasets (${a("analytics")}) — self-describing { binding: ANALYTICS, dataset }`],[e.usesWorkerLoader,"worker_loaders (jsCodeTool imported in lunora/) — self-describing { binding: LOADER }"],[e.usesAiSearch,`ai_search_namespaces (${a("aiSearch")}) — self-describing { binding: AI_SEARCH, namespace: "default" }; remote-only, so \`lunora dev\` reaches the deployed AI Search service`],[e.usesAnalyticsSql,`analytics (${a("analyticsSql")}) — self-describing { binding: ANALYTICS_SQL }; needs wrangler >= 4.145.0, and is remote-only, so \`lunora dev\` queries the account's live analytics`],[e.usesKv,`hint: ${a("kv")}; add a kv_namespaces binding ({ binding, id }) and pass env.<BINDING> to createKv() — the namespace id can't be auto-provisioned`],[e.usesHyperdrive,`hint: ${a("hyperdrive")}; run 'wrangler hyperdrive create' and add a 'hyperdrive' binding ({ binding, id }) — the id can't be auto-provisioned`],[e.usesPipelines,`hint: ${a("pipelines")}; run 'wrangler pipelines create <name>' and add a 'pipelines' binding ({ binding, stream }) — the pipeline resource can't be auto-provisioned`],[e.usesArtifacts,`hint: ${ue(r.jurisdiction)}`],[e.usesX402Charge,"hint: @lunora/x402/charge is imported; set the recipient wallet address as a [vars] entry (the var name is yours to choose) and pass it to the charge config — the x402 facilitator settles USDC to that address"],[e.usesX402,`hint: ${a("x402")} (ActionCtx-only, spends real funds); add a secrets_store_secrets[] binding for the agent wallet key (name it to match signer.secretName) and pair the pay rail with a spend policy — ctx.secrets reads a Secrets Store binding, not .dev.vars, so the key can't be auto-provisioned`]].filter(([n])=>n).map(([,n])=>n),$e=(e,s,r,t=[],n=[],o=[])=>{const d=new Set(e.map(i=>i.className)),u=e.map(i=>`${i.binding}/${i.className} (exported by worker entry)`);return s.needsD1&&u.push("DB (.global() table declared)"),u.push(...Ce(t,n,o),...Ne(r,d,s)),u},Ke=async e=>{await H;const s=e.schemaDir??"lunora",r=e.scanDirs??ge,t=()=>Re(e.projectRoot,r,s),n=e.cache===void 0?t():e.cache.memo(`capabilities:${e.projectRoot}:${s}:${r.join(",")}`,t),o=re(e.projectRoot);let d;o.composed?d=ne(b(e.projectRoot,s,I)).map(R=>({binding:oe[R],className:R})):d=o.path===void 0?[]:ae(o.path);const u=_e(e.projectRoot,s,e.cache),i={...u,needsD1:n.needsD1||u.needsD1},h=x(o,V(e.projectRoot,s,e.cache).containers,"containers"),y=x(o,ce(e.projectRoot,s).workflows,"workflows"),S=x(o,Q(e.projectRoot,s).agents,"agents"),v=[...pe(e.projectRoot,s).queues],{flags:E}=le(e.projectRoot,s),l=_(e.projectRoot,s,K,Y),p=l.error===void 0?l.value:{hasFcm:!0,hasWebPush:!0},f=E?.provider==="flagship"&&E.mode==="binding"?E.bindingName:void 0,m=$e(d,i,n,h,y,S);!o.composed&&ie(b(e.projectRoot,s,I))&&!d.some(g=>g.className==="LunoraDO")&&m.push("hint: durableObjects.merge is set, but the worker entry exports no LunoraDO — export one built with mergeDurableObjects, or the classes stay separate"),f!==void 0&&m.push(`hint: lunora/flags.ts uses Flagship in binding mode; add a flagship binding ({ binding: "${f}", app_id }) — the app_id can't be auto-provisioned`);const c=W(e.projectRoot),A=c.error===void 0?c.services:void 0;return c.error!==void 0&&m.push(`hint: lunora.config \`services\` not reconciled — ${c.error}`),m.push(...c.services.map(g=>`${g.binding} → ${g.worker} (lunora.config services.${g.name})`)),{...n,agents:S,containers:h,durableObjects:d,flagshipBinding:f,...i.jurisdiction===void 0?{}:{jurisdiction:i.jurisdiction},needsD1:i.needsD1,queues:v,services:A,signals:m,usesFlags:E!==void 0,usesNotifyFcm:p?.hasFcm??!1,usesNotifyWebPush:p?.hasWebPush??!1,workflows:y}},qe=e=>[...O,...Se].filter(([s,r])=>e[s]&&se[r]!==void 0).map(([,s])=>s);export{ue as a,Ke as i,qe as s};
|
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
import { SchemaIR, AgentIR, ContainerIR, QueueIR, ServiceBindingIR, WorkflowIR } from '@lunora/codegen';
|
|
2
|
+
/**
|
|
3
|
+
* `DeployDriver` — the provider-neutral seam between a Lunora command and the
|
|
4
|
+
* host CLI that carries it out (plan 114, §5.3).
|
|
5
|
+
*
|
|
6
|
+
* The seam is the **toolchain surface**: which command a host runs to deploy,
|
|
7
|
+
* serve, tail, or set a secret. A driver only *describes* that command
|
|
8
|
+
* ({@link ToolchainCommand}); it never spawns. The CLI keeps ownership of
|
|
9
|
+
* running it — package-manager resolution (`pnpm exec` / `npx --` / `bun x`)
|
|
10
|
+
* and the injected spawner its tests substitute — so the driver stays free of
|
|
11
|
+
* process concerns and remains trivially testable as a pure function.
|
|
12
|
+
*
|
|
13
|
+
* Each request type below is deliberately neutral: `preview`, `environment`,
|
|
14
|
+
* `temporary` are concepts, not wrangler flags. A second host maps the same
|
|
15
|
+
* request onto its own CLI without the caller changing.
|
|
16
|
+
*
|
|
17
|
+
* Three drivers are registered: Cloudflare (`cloudflare/cloudflare-driver.ts`)
|
|
18
|
+
* and celld (`celld/celld-driver.ts`), which ship toolchains, and Node
|
|
19
|
+
* (`node/node-driver.ts`), which has none — it is a codegen target, and
|
|
20
|
+
* `lunora deploy` / `lunora dev` refuse it at selection.
|
|
21
|
+
*
|
|
22
|
+
* **What this seam deliberately does NOT carry: configuration inference.** It
|
|
23
|
+
* used to, through an `infer`/`provision` pair over a provider-neutral
|
|
24
|
+
* `ResourceGraph`. Nothing ever called either one — every consumer reads
|
|
25
|
+
* `.toolchain` or just validates the target — and the arm rotted in place: the
|
|
26
|
+
* Node driver was *only* `infer` + `provision`, so its report of what that
|
|
27
|
+
* target cannot serve (containers, undispatched crons) could not reach an
|
|
28
|
+
* operator however wrong the app was. The reason it never got wired is worth
|
|
29
|
+
* keeping: writing real host configuration needs the host's own encodings —
|
|
30
|
+
* binding names, DO class wiring, migration tags — which a neutral graph
|
|
31
|
+
* necessarily discards, so `provision` re-derived them anyway and the graph was
|
|
32
|
+
* decorative. A second target that needs to share inference should grow the
|
|
33
|
+
* seam back with a caller attached, and with an encoding escape hatch.
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* A host CLI invocation, described but not run.
|
|
37
|
+
*
|
|
38
|
+
* `tool` is the binary name only (`"wrangler"`); the caller resolves how to
|
|
39
|
+
* execute it through the project's package manager (see `toolchainExecArgs`).
|
|
40
|
+
* Keeping that split means a driver never has to know whether the project uses
|
|
41
|
+
* pnpm, npm, yarn, or bun.
|
|
42
|
+
*/
|
|
43
|
+
interface ToolchainCommand {
|
|
44
|
+
/** Arguments for {@link ToolchainCommand.tool}. */
|
|
45
|
+
args: ReadonlyArray<string>;
|
|
46
|
+
/**
|
|
47
|
+
* The tool is a standalone binary installed on `PATH`, not a project
|
|
48
|
+
* dependency: run it directly. Going through the package manager would be
|
|
49
|
+
* wrong for it — `npx --` / `bun x` fetch an npm package of the same name
|
|
50
|
+
* when none is installed locally, which for a non-npm binary is somebody
|
|
51
|
+
* else's code.
|
|
52
|
+
*/
|
|
53
|
+
onPath?: boolean;
|
|
54
|
+
/** The host CLI binary, e.g. `"wrangler"`. */
|
|
55
|
+
tool: string;
|
|
56
|
+
}
|
|
57
|
+
/** Neutral options for a deploy. */
|
|
58
|
+
interface DeployRequest {
|
|
59
|
+
/** Host config file to deploy, when the flow uses a projected one (see {@link DeployDriver.projectConfig}). */
|
|
60
|
+
configPath?: string;
|
|
61
|
+
/** Validate and bundle without publishing — nothing ships. */
|
|
62
|
+
dryRun?: boolean;
|
|
63
|
+
/** Deploy this entry file instead of the host config's default (framework composition). */
|
|
64
|
+
entry?: string;
|
|
65
|
+
/** Named deployment environment, when the host supports them. */
|
|
66
|
+
environment?: string;
|
|
67
|
+
/** Write the built bundle (and any build metadata) to this directory. */
|
|
68
|
+
outDir?: string;
|
|
69
|
+
/** Upload a preview/versioned artifact instead of taking production traffic. */
|
|
70
|
+
preview?: boolean;
|
|
71
|
+
/** Deploy to a short-lived, unauthenticated account where the host offers one. */
|
|
72
|
+
temporary?: boolean;
|
|
73
|
+
}
|
|
74
|
+
/** Neutral options for a local dev server. */
|
|
75
|
+
interface DevRequest {
|
|
76
|
+
/** Host config file to run against, when the flow uses a generated one. */
|
|
77
|
+
configPath?: string;
|
|
78
|
+
/** Named environment. */
|
|
79
|
+
environment?: string;
|
|
80
|
+
/** Extra host-specific flags the caller has already resolved. */
|
|
81
|
+
extraArgs?: ReadonlyArray<string>;
|
|
82
|
+
}
|
|
83
|
+
/** Neutral options for tailing live logs. */
|
|
84
|
+
interface TailRequest {
|
|
85
|
+
/** Named environment. */
|
|
86
|
+
environment?: string;
|
|
87
|
+
/** Output format the host tail supports (`"json"`, `"pretty"`, …). */
|
|
88
|
+
format?: string;
|
|
89
|
+
/** Free-text filter. */
|
|
90
|
+
search?: string;
|
|
91
|
+
/** Status filter (`"error"`, `"ok"`, …). */
|
|
92
|
+
status?: string;
|
|
93
|
+
/** Tail a short-lived account's deployment. */
|
|
94
|
+
temporary?: boolean;
|
|
95
|
+
/** Tail a specific deployed worker/service by name, when the host addresses them individually. */
|
|
96
|
+
worker?: string;
|
|
97
|
+
}
|
|
98
|
+
/** Neutral options for reading or writing deployment secrets. */
|
|
99
|
+
interface SecretRequest {
|
|
100
|
+
/** Named environment. */
|
|
101
|
+
environment?: string;
|
|
102
|
+
/** The secret's name — required for `put`, unused for `list`. */
|
|
103
|
+
key?: string;
|
|
104
|
+
/** Operate against a short-lived account. */
|
|
105
|
+
temporary?: boolean;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* The host's command-line surface. Optional as a whole: a host with no vendor
|
|
109
|
+
* CLI (the Node target; a hypothetical API-driven one) declares none, and
|
|
110
|
+
* `isRunnableTarget` refuses it for the commands that would have to shell out.
|
|
111
|
+
*
|
|
112
|
+
* `deploy` and `dev` are what make a target runnable. The secret and tail
|
|
113
|
+
* commands are optional on their own, because a runnable host can simply not
|
|
114
|
+
* have them — celld keeps configuration in plain `vars` and has no log tail —
|
|
115
|
+
* and the commands that need one say so rather than guessing a substitute.
|
|
116
|
+
*/
|
|
117
|
+
interface DriverToolchain {
|
|
118
|
+
/** The command that deploys the app. */
|
|
119
|
+
deploy: (request: DeployRequest) => ToolchainCommand;
|
|
120
|
+
/** The command that runs a local dev server. */
|
|
121
|
+
dev: (request: DevRequest) => ToolchainCommand;
|
|
122
|
+
/**
|
|
123
|
+
* Where `lunora dev` runs the worker. `"workerd"`: `wrangler dev`, or the
|
|
124
|
+
* Vite plugin's `@cloudflare/vite-plugin`, whichever flavor the project
|
|
125
|
+
* picks. `"own"`: the host's dev server ({@link DriverToolchain.dev}) on
|
|
126
|
+
* the projected config, always the standalone flavor — neither Vite nor a
|
|
127
|
+
* framework sidecar can serve the worker on that runtime.
|
|
128
|
+
*/
|
|
129
|
+
readonly devServer: "own" | "workerd";
|
|
130
|
+
/**
|
|
131
|
+
* Whether `lunora deploy` builds and pushes container images itself
|
|
132
|
+
* (railpack, into the host's registry) before `deploy`. `false` when the
|
|
133
|
+
* host CLI builds each image from its Dockerfile during the deploy.
|
|
134
|
+
*/
|
|
135
|
+
readonly prebuildsContainerImages: boolean;
|
|
136
|
+
/** The command that writes many secrets in one call, as a JSON object of name to value on stdin. Optional: hosts without it get one `secretPut` per key. */
|
|
137
|
+
secretBulk?: (request: SecretRequest) => ToolchainCommand;
|
|
138
|
+
/** The command that lists remote secret names, when the host has a secret store. */
|
|
139
|
+
secretList?: (request: SecretRequest) => ToolchainCommand;
|
|
140
|
+
/** The command that writes one secret, when the host has a secret store. Its value is passed on stdin, never argv. */
|
|
141
|
+
secretPut?: (request: SecretRequest) => ToolchainCommand;
|
|
142
|
+
/** The command that tails live logs, when the host has one. */
|
|
143
|
+
tail?: (request: TailRequest) => ToolchainCommand;
|
|
144
|
+
}
|
|
145
|
+
/** What a {@link DeployDriver.projectConfig} projection is for — a dev server may need a different source than a deploy. */
|
|
146
|
+
type ProjectionPurpose = "deploy" | "dev";
|
|
147
|
+
/**
|
|
148
|
+
* The result of {@link DeployDriver.projectConfig}: a plan, not yet on disk.
|
|
149
|
+
* The caller validates the request it is for (the toolchain's argv builder
|
|
150
|
+
* refuses unsupported options), then calls `write` — so a refused command
|
|
151
|
+
* changes nothing.
|
|
152
|
+
*/
|
|
153
|
+
interface ProjectedConfig {
|
|
154
|
+
/** Where the projection goes, to pass as the request's `configPath`. */
|
|
155
|
+
configPath: string;
|
|
156
|
+
/** Every key removed, as a dotted path (`observability`, `containers[0].rollout_step_percentage`). */
|
|
157
|
+
dropped: ReadonlyArray<string>;
|
|
158
|
+
/** Write the projection (and any build-artifact cleanup it planned). */
|
|
159
|
+
write: () => void;
|
|
160
|
+
}
|
|
161
|
+
/** A deploy target's implementation: an identity the registry resolves, and the host CLI surface (if any) behind it. */
|
|
162
|
+
interface DeployDriver {
|
|
163
|
+
/** The target id this driver serves (`"cloudflare"`, …) — matches codegen's `target`. */
|
|
164
|
+
readonly id: string;
|
|
165
|
+
/** Human-readable target name, for logs. */
|
|
166
|
+
readonly name: string;
|
|
167
|
+
/**
|
|
168
|
+
* Rewrite the project's wrangler config into the form this host's CLI
|
|
169
|
+
* accepts, and return the file to hand `deploy`/`dev` as `configPath`.
|
|
170
|
+
* Absent when the host reads the project's config as-is (Cloudflare).
|
|
171
|
+
*
|
|
172
|
+
* Needed because Lunora's reconcilers and templates write Cloudflare-only
|
|
173
|
+
* keys (`observability`, `limits`, …) that a Workers-compatible host with a
|
|
174
|
+
* strict config reader refuses outright. `dropped` names what was removed,
|
|
175
|
+
* so the caller can say so instead of silently deploying less than the
|
|
176
|
+
* config describes.
|
|
177
|
+
*/
|
|
178
|
+
readonly projectConfig?: (projectRoot: string, purpose: ProjectionPurpose) => ProjectedConfig;
|
|
179
|
+
/**
|
|
180
|
+
* The host's command-line surface, or `undefined` for a host that has none.
|
|
181
|
+
* Pure: these build argv, they never spawn.
|
|
182
|
+
*/
|
|
183
|
+
readonly toolchain?: DriverToolchain;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* An invocation-scoped memo for project discovery. A CLI command creates one,
|
|
187
|
+
* threads it through every `discover*` / `inferLunoraBindings` call it makes,
|
|
188
|
+
* and clears it after anything rewrites the sources discovery reads (codegen).
|
|
189
|
+
* Deliberately not module-level: tests and long-lived processes never see a
|
|
190
|
+
* stale result.
|
|
191
|
+
*/
|
|
192
|
+
interface DiscoveryCache {
|
|
193
|
+
/** Drop every memoised result. */
|
|
194
|
+
clear: () => void;
|
|
195
|
+
/** Return the result memoised under `key`, computing it on first use. */
|
|
196
|
+
memo: <T>(key: string, compute: () => T) => T;
|
|
197
|
+
}
|
|
198
|
+
declare const createDiscoveryCache: () => DiscoveryCache;
|
|
199
|
+
/** One filterable Vectorize metadata property a schema declares. */
|
|
200
|
+
interface VectorMetadataDeclaration {
|
|
201
|
+
/** The vector index the property belongs to. */
|
|
202
|
+
index: string;
|
|
203
|
+
/**
|
|
204
|
+
* The validator kind behind the column, with `v.optional(...)` and a
|
|
205
|
+
* nullable union unwrapped (metadata columns are usually optional), or
|
|
206
|
+
* `undefined` when the column isn't in the owning table's shape. Callers map it to the Vectorize
|
|
207
|
+
* metadata type; a kind that can't be filtered on is reported, not indexed.
|
|
208
|
+
*/
|
|
209
|
+
kind: string | undefined;
|
|
210
|
+
/** Column mirrored into vector metadata. */
|
|
211
|
+
property: string;
|
|
212
|
+
}
|
|
213
|
+
interface SchemaInfo {
|
|
214
|
+
/**
|
|
215
|
+
* Whether the schema declares a **D1-backed** `.global()` table — the only
|
|
216
|
+
* flavour that needs the `DB` binding and the app's `.global({ d1 })` chain.
|
|
217
|
+
* A `.global({ backend: "hyperdrive" })` table needs neither, and counting it
|
|
218
|
+
* here demanded a D1 database of a project that has none.
|
|
219
|
+
*/
|
|
220
|
+
hasD1GlobalTable: boolean;
|
|
221
|
+
/** Whether the schema declares a `.global({ backend: "hyperdrive" })` table — needs the app's `.hyperdriveGlobal(...)` chain instead. Required, not optional: the only producer always knows the answer, and `?` made every consumer read a two-valued fact as three-valued. */
|
|
222
|
+
hasHyperdriveGlobalTable: boolean;
|
|
223
|
+
/**
|
|
224
|
+
* Data-residency jurisdiction declared via `defineSchema(...).jurisdiction("…")`.
|
|
225
|
+
* It pins the app's Durable Objects only; KV namespaces and R2 buckets carry
|
|
226
|
+
* their own jurisdiction, set when they are created.
|
|
227
|
+
*/
|
|
228
|
+
jurisdiction?: SchemaIR["jurisdiction"];
|
|
229
|
+
/** Names of vector indexes declared via `.vectorize()` / `defineVectorIndex()`. */
|
|
230
|
+
vectorIndexNames?: ReadonlyArray<string>;
|
|
231
|
+
/**
|
|
232
|
+
* Metadata properties declared filterable on a vector index. Cloudflare
|
|
233
|
+
* needs an explicit metadata index per property before a `filter` can match
|
|
234
|
+
* anything, so deploy provisions these and doctor reports them.
|
|
235
|
+
*/
|
|
236
|
+
vectorMetadata?: ReadonlyArray<VectorMetadataDeclaration>;
|
|
237
|
+
}
|
|
238
|
+
interface DiscoverSchemaInfoResult {
|
|
239
|
+
/** Parse error message, when the schema exists but could not be analyzed. */
|
|
240
|
+
error?: string;
|
|
241
|
+
/** Schema facts, or `undefined` when no `schema.ts` exists or parsing failed. */
|
|
242
|
+
info: SchemaInfo | undefined;
|
|
243
|
+
}
|
|
244
|
+
/** Discover the schema facts, memoised on `cache` when one is given. */
|
|
245
|
+
declare const discoverSchemaInfo: (projectRoot: string, schemaDirectory: string, cache?: DiscoveryCache) => DiscoverSchemaInfoResult;
|
|
246
|
+
interface DurableObjectSpec {
|
|
247
|
+
binding: string;
|
|
248
|
+
className: string;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Canonical Durable Object class → binding name. wrangler requires the worker
|
|
252
|
+
* to export a class of this exact name, so detection keys on the class name.
|
|
253
|
+
*/
|
|
254
|
+
declare const DURABLE_OBJECT_BINDINGS: {
|
|
255
|
+
readonly LunoraDO: "SHARD";
|
|
256
|
+
readonly SchedulerDO: "SCHEDULER";
|
|
257
|
+
readonly SessionDO: "SESSION";
|
|
258
|
+
readonly ShardDO: "SHARD";
|
|
259
|
+
readonly ShardRegistryDO: "SHARD_REGISTRY";
|
|
260
|
+
};
|
|
261
|
+
type DurableObjectClass = keyof typeof DURABLE_OBJECT_BINDINGS;
|
|
262
|
+
/**
|
|
263
|
+
* The `_generated/` modules that hold a generated Durable Object / Workflow
|
|
264
|
+
* class — one per class kind a project can declare. wrangler validates every
|
|
265
|
+
* `class_name` against the worker's exports, so this is the set a worker entry
|
|
266
|
+
* re-exports (and the set the composed class-A entry star-re-exports for the
|
|
267
|
+
* kinds the project has).
|
|
268
|
+
*
|
|
269
|
+
* Owned here because four places need it and they must not drift:
|
|
270
|
+
* `@lunora/vite` emits one star re-export per entry, the wrangler validator
|
|
271
|
+
* DECIDES the composed entry's exports from it, `reconcile-bindings` types its
|
|
272
|
+
* export-gap `module` field on it, and this module's own `detectClassExports`
|
|
273
|
+
* probes the same names.
|
|
274
|
+
*
|
|
275
|
+
* `scheduler` carries no `define*` declarations of its own — codegen writes it
|
|
276
|
+
* off `hasScheduler` purely so the composed class-A entry has a `SchedulerDO`
|
|
277
|
+
* to forward. Its presence is therefore the ONLY signal the plugin and the
|
|
278
|
+
* validator need, and it is the same signal that decides whether the builder
|
|
279
|
+
* has a `.scheduler()` method at all. `@lunora/vite` depends on `@lunora/config`, so config
|
|
280
|
+
* owning it is the direction the dependency graph allows.
|
|
281
|
+
*/
|
|
282
|
+
declare const GENERATED_CLASS_MODULES: readonly ["agents", "containers", "scheduler", "shardRegistry", "workflows"];
|
|
283
|
+
/** One {@link GENERATED_CLASS_MODULES} entry. */
|
|
284
|
+
type GeneratedClassModule = (typeof GENERATED_CLASS_MODULES)[number];
|
|
285
|
+
/**
|
|
286
|
+
* The framework Durable Object each class module forwards, for the modules that
|
|
287
|
+
* carry one: codegen writes them off the same signal that gives the builder the
|
|
288
|
+
* matching method, so the module's existence means the composed entry exports
|
|
289
|
+
* the class.
|
|
290
|
+
*/
|
|
291
|
+
declare const GENERATED_MODULE_DURABLE_OBJECTS: Partial<Record<GeneratedClassModule, DurableObjectClass>>;
|
|
292
|
+
/** The `_generated/` module codegen writes when `lunora.config` opts in to the merge. */
|
|
293
|
+
declare const MERGED_DURABLE_OBJECTS_MODULE: "durableObjects";
|
|
294
|
+
/**
|
|
295
|
+
* Whether the project merges its Durable Objects: codegen wrote the merge
|
|
296
|
+
* module. The one test the composed entry, binding inference and the export
|
|
297
|
+
* validator all ask — the same "module existence is the signal" rule the
|
|
298
|
+
* scheduler and registry modules follow.
|
|
299
|
+
*/
|
|
300
|
+
declare const isMergedProject: (generatedDirectory: string) => boolean;
|
|
301
|
+
/** Whether `module` holds a class the merged class hosts — imported into it, never re-exported. */
|
|
302
|
+
declare const isMergedRoleModule: (module: string) => boolean;
|
|
303
|
+
/**
|
|
304
|
+
* The class-B composed entry. `lunora deploy` passes this file to wrangler as
|
|
305
|
+
* the positional script whenever it exists, overriding `wrangler.main` — so it
|
|
306
|
+
* is what actually gets bundled and what wrangler checks its DO/Workflow
|
|
307
|
+
* bindings against. `main` in a class-B project names the framework adapter's
|
|
308
|
+
* build output (`.svelte-kit/cloudflare/_worker.js`, `dist/_worker.js`), which
|
|
309
|
+
* exists after `vite build` and exports only the SSR fetch handler. Lexing that
|
|
310
|
+
* instead read every declared class as unexported: nothing provisioned, plus a
|
|
311
|
+
* "add `export * from …`" warning the user cannot silence.
|
|
312
|
+
*
|
|
313
|
+
* Exported, not documented-as-duplicated: the CLI's `resolveComposedWorkerEntry`
|
|
314
|
+
* imports this constant, so the deploy's positional entry and the file this
|
|
315
|
+
* module lexes for exported classes cannot drift apart.
|
|
316
|
+
*/
|
|
317
|
+
declare const COMPOSED_WORKER_ENTRY = "src/worker.ts";
|
|
318
|
+
/**
|
|
319
|
+
* A `defineContainer` declaration plus whether its generated DO class is
|
|
320
|
+
* exported by the worker entry. Only exported containers are safe to
|
|
321
|
+
* provision — wrangler rejects a `containers[].class_name` (and its Durable
|
|
322
|
+
* Object binding) that the worker doesn't export.
|
|
323
|
+
*/
|
|
324
|
+
type InferredContainer = ContainerIR & {
|
|
325
|
+
exported: boolean;
|
|
326
|
+
};
|
|
327
|
+
/**
|
|
328
|
+
* A `defineWorkflow` declaration plus whether its generated
|
|
329
|
+
* `WorkflowEntrypoint` class is exported by the worker entry. Only exported
|
|
330
|
+
* workflows are safe to provision — wrangler rejects an `exports.<Class>`
|
|
331
|
+
* workflow the worker doesn't export. Workflows are NOT Durable Objects, so this never
|
|
332
|
+
* implies a `durable_objects` binding or migration.
|
|
333
|
+
*/
|
|
334
|
+
interface InferredWorkflow extends WorkflowIR {
|
|
335
|
+
exported: boolean;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* A `defineAgent` declaration plus whether its generated agent
|
|
339
|
+
* `WorkflowEntrypoint` class (e.g. `SupportAgentWorkflow`) is exported by the
|
|
340
|
+
* worker entry. An agent compiles onto a Cloudflare Workflow, so — exactly like
|
|
341
|
+
* {@link InferredWorkflow} — only exported agents are safe to provision
|
|
342
|
+
* (wrangler rejects an `exports.<Class>` workflow the worker doesn't export), and
|
|
343
|
+
* an agent is NOT a Durable Object (no `durable_objects` binding or migration).
|
|
344
|
+
*/
|
|
345
|
+
interface InferredAgent extends AgentIR {
|
|
346
|
+
exported: boolean;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* A queue declared in `lunora/queues.ts`. Unlike workflows, a queue needs no
|
|
350
|
+
* worker-entry class export (its `queue()` handler rides `createWorker`), so
|
|
351
|
+
* there is no `exported` flag — every declared queue is reconcilable into the
|
|
352
|
+
* wrangler `queues.producers[]` / `queues.consumers[]`.
|
|
353
|
+
*/
|
|
354
|
+
type InferredQueue = QueueIR;
|
|
355
|
+
interface InferredBindings {
|
|
356
|
+
/** Agents declared in `lunora/agents.ts` (exported or not — see {@link InferredAgent.exported}); reconciled into wrangler `exports`. */
|
|
357
|
+
agents: InferredAgent[];
|
|
358
|
+
/** Containers declared in `lunora/containers.ts` (exported or not — see {@link InferredContainer.exported}). */
|
|
359
|
+
containers: InferredContainer[];
|
|
360
|
+
/** Durable Objects the worker entry exports → safe to bind. */
|
|
361
|
+
durableObjects: DurableObjectSpec[];
|
|
362
|
+
/**
|
|
363
|
+
* The wrangler `flagship[].binding` name implied by `lunora/flags.ts` when it
|
|
364
|
+
* uses the Flagship provider in binding mode — `undefined` for HTTP-mode
|
|
365
|
+
* Flagship, a custom OpenFeature provider, or no flags. The binding needs an
|
|
366
|
+
* un-mintable `app_id`, so it is reconciled as a hint, not auto-written.
|
|
367
|
+
*/
|
|
368
|
+
flagshipBinding?: string;
|
|
369
|
+
/**
|
|
370
|
+
* The schema's `.jurisdiction("…")`, when it declares one. Read by the binding
|
|
371
|
+
* hints whose resource takes its residency at creation (Artifacts), so the
|
|
372
|
+
* hint can name the jurisdiction to create it in.
|
|
373
|
+
*/
|
|
374
|
+
jurisdiction?: SchemaInfo["jurisdiction"];
|
|
375
|
+
/** Schema declares a `.global()` table → needs the `DB` D1 binding. */
|
|
376
|
+
needsD1: boolean;
|
|
377
|
+
/** Queues declared in `lunora/queues.ts` → reconciled into `queues.producers[]` / `queues.consumers[]`. */
|
|
378
|
+
queues: InferredQueue[];
|
|
379
|
+
/**
|
|
380
|
+
* Sibling Workers declared in `lunora.config` `services` → reconciled into
|
|
381
|
+
* `services[]` (plan 457). `undefined` when the declaration is unreadable, so
|
|
382
|
+
* reconcile leaves every entry alone rather than removing the owned ones.
|
|
383
|
+
*/
|
|
384
|
+
services: ServiceBindingIR[] | undefined;
|
|
385
|
+
/** Human-readable provenance for each inferred binding / hint, for logging. */
|
|
386
|
+
signals: string[];
|
|
387
|
+
/** `@lunora/ai` is imported, `ctx.ai` read, or `env.AI` used → needs the `ai` Workers AI binding. */
|
|
388
|
+
usesAi: boolean;
|
|
389
|
+
/** `@lunora/bindings/ai-search` is value-imported or `ctx.aiSearch` read → self-describing `ai_search_namespaces` binding (`AI_SEARCH` on namespace `default`; auto-writeable). */
|
|
390
|
+
usesAiSearch: boolean;
|
|
391
|
+
/** `@lunora/bindings/analytics` is imported or `ctx.analytics` read → self-describing `analytics_engine_datasets` binding (auto-writeable). */
|
|
392
|
+
usesAnalytics: boolean;
|
|
393
|
+
/** `@lunora/bindings/analytics-sql` is value-imported or `ctx.analyticsSql` read → self-describing `analytics` binding (`{ binding: ANALYTICS_SQL }`; auto-writeable, wrangler >= 4.145.0). */
|
|
394
|
+
usesAnalyticsSql: boolean;
|
|
395
|
+
/**
|
|
396
|
+
* `ctx.artifacts` is read or `@lunora/bindings/artifacts` value-imported.
|
|
397
|
+
* Hint-only: the first repo `create()` against a missing namespace creates it
|
|
398
|
+
* UNRESTRICTED, and a namespace's jurisdiction can never change after that,
|
|
399
|
+
* so Lunora never writes the binding for you.
|
|
400
|
+
*/
|
|
401
|
+
usesArtifacts: boolean;
|
|
402
|
+
/** `@lunora/auth` is imported (sessions may be D1- or `SessionDO`-backed). */
|
|
403
|
+
usesAuth: boolean;
|
|
404
|
+
/** `@lunora/browser` is imported or `ctx.browser` read → self-describing `browser` binding (auto-writeable). */
|
|
405
|
+
usesBrowser: boolean;
|
|
406
|
+
/** `@lunora/auth/cimd/workers` is imported → needs the `global_fetch_strictly_public` compatibility flag (no binding; `lunora doctor` checks it). */
|
|
407
|
+
usesCimdWorkers: boolean;
|
|
408
|
+
/** `lunora/flags.ts` declares a feature-flag provider (any OpenFeature provider — Flagship or custom). */
|
|
409
|
+
usesFlags: boolean;
|
|
410
|
+
/** `@lunora/hyperdrive` is imported or `ctx.sql` read (binding needs an un-mintable remote `id`; hint-only). */
|
|
411
|
+
usesHyperdrive: boolean;
|
|
412
|
+
/** `@lunora/bindings/images` is imported or `ctx.images` read → self-describing `images` binding (auto-writeable). */
|
|
413
|
+
usesImages: boolean;
|
|
414
|
+
/** `@lunora/bindings/kv` is imported or `ctx.kv` read (namespace binding name + id are user-defined; hint-only). */
|
|
415
|
+
usesKv: boolean;
|
|
416
|
+
/** `@lunora/mail` is imported (Resend API key must be set in `.dev.vars`; no binding). No `ctx.mail` helper exists, so only the import counts. */
|
|
417
|
+
usesMail: boolean;
|
|
418
|
+
/** `@lunora/notify` is imported or `ctx.notify` read (no binding; channel secrets ride `usesNotifyFcm` / `usesNotifyWebPush`). */
|
|
419
|
+
usesNotify: boolean;
|
|
420
|
+
/** `lunora/notify.ts` configures the `fcm` channel → the `FCM_*` secrets in `.dev.vars`. */
|
|
421
|
+
usesNotifyFcm: boolean;
|
|
422
|
+
/** `lunora/notify.ts` configures the `webPush` channel → the `VAPID_*` secrets in `.dev.vars`. */
|
|
423
|
+
usesNotifyWebPush: boolean;
|
|
424
|
+
/** `@lunora/payment/autumn` is imported → the Autumn secrets in `.dev.vars` (no binding). */
|
|
425
|
+
usesPaymentAutumn: boolean;
|
|
426
|
+
/** `@lunora/payment/creem` is imported → the Creem secrets in `.dev.vars` (no binding). */
|
|
427
|
+
usesPaymentCreem: boolean;
|
|
428
|
+
/** `@lunora/payment/dodopayments` is imported → the Dodo Payments secrets in `.dev.vars` (no binding). */
|
|
429
|
+
usesPaymentDodopayments: boolean;
|
|
430
|
+
/** `@lunora/payment/polar` is imported → the Polar secrets in `.dev.vars` (no binding). */
|
|
431
|
+
usesPaymentPolar: boolean;
|
|
432
|
+
/** `@lunora/payment` is imported or `ctx.payments` read (provider secrets must be set in `.dev.vars`; no binding). */
|
|
433
|
+
usesPayments: boolean;
|
|
434
|
+
/** `@lunora/payment/stripe` is imported → the Stripe secrets in `.dev.vars` (no binding). */
|
|
435
|
+
usesPaymentStripe: boolean;
|
|
436
|
+
/** `@lunora/bindings/pipelines` is value-imported or `ctx.pipelines` read (binding needs an un-mintable remote pipeline name; hint-only). */
|
|
437
|
+
usesPipelines: boolean;
|
|
438
|
+
/** `@lunora/bindings/r2sql` is value-imported or `ctx.r2sql` read (needs the `R2_SQL_*` secrets in `.dev.vars`; no binding). */
|
|
439
|
+
usesR2sql: boolean;
|
|
440
|
+
/** `@lunora/scheduler` is imported or `ctx.scheduler` read. */
|
|
441
|
+
usesScheduler: boolean;
|
|
442
|
+
/** `@lunora/storage` is imported or `ctx.storage` read under `lunora/` (R2 bucket binding name is user-defined). */
|
|
443
|
+
usesStorage: boolean;
|
|
444
|
+
/** `jsCodeTool` is imported from `@lunora/agent` in `lunora/` → self-describing `worker_loaders` binding (`LOADER`). */
|
|
445
|
+
usesWorkerLoader: boolean;
|
|
446
|
+
/** `@lunora/x402/pay` is imported or `ctx.x402` read — the agent-wallet pay rail signs from a Secrets Store binding paired with a spend policy (ActionCtx-only; hint-only). */
|
|
447
|
+
usesX402: boolean;
|
|
448
|
+
/** `@lunora/x402/charge` is imported — the charge rail settles USDC to a recipient address (a public `[vars]` entry, user-named; hint-only). */
|
|
449
|
+
usesX402Charge: boolean;
|
|
450
|
+
/** Workflows declared in `lunora/workflows.ts` (exported or not — see {@link InferredWorkflow.exported}). */
|
|
451
|
+
workflows: InferredWorkflow[];
|
|
452
|
+
}
|
|
453
|
+
interface InferOptions {
|
|
454
|
+
/** Memoises the source scans, so one CLI invocation parses the project once. */
|
|
455
|
+
cache?: DiscoveryCache;
|
|
456
|
+
projectRoot: string;
|
|
457
|
+
/** Directories (relative to root) to scan. Defaults to `lunora` + `src`. */
|
|
458
|
+
scanDirs?: ReadonlyArray<string>;
|
|
459
|
+
/** Lunora source directory holding `schema.ts`. Defaults to `lunora`. */
|
|
460
|
+
schemaDir?: string;
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Scan a Lunora project and report which Cloudflare bindings its code implies.
|
|
464
|
+
* Read-only: performs no writes. Binding provisioning is driven by the worker
|
|
465
|
+
* entry's Durable Object exports plus the schema's D1 need; capability imports
|
|
466
|
+
* surface as hints.
|
|
467
|
+
*/
|
|
468
|
+
declare const inferLunoraBindings: (options: InferOptions) => Promise<InferredBindings>;
|
|
469
|
+
/**
|
|
470
|
+
* The secret sources a project uses — the {@link PACKAGE_SECRETS_REGISTRY} keys
|
|
471
|
+
* whose secrets it needs, derived from its already-resolved {@link InferredBindings}.
|
|
472
|
+
*
|
|
473
|
+
* This is the canonical bridge between binding inference and the
|
|
474
|
+
* `.dev.vars.example` scaffolding in `scaffold-dev-variables.ts`. The result is
|
|
475
|
+
* {@link FLAG_PACKAGES}' sources whose flag is `true` in `bindings` — in
|
|
476
|
+
* flag-name order — followed by the configured `@lunora/notify` channels
|
|
477
|
+
* ({@link NOTIFY_CHANNEL_SECRETS}), keeping only sources that carry secrets.
|
|
478
|
+
*/
|
|
479
|
+
declare const secretSourcesFromBindings: (bindings: InferredBindings) => string[];
|
|
480
|
+
export { COMPOSED_WORKER_ENTRY as C, DeployDriver as D, GeneratedClassModule as G, InferredBindings as I, MERGED_DURABLE_OBJECTS_MODULE as M, ProjectionPurpose as P, SchemaInfo as S, ToolchainCommand as T, DiscoveryCache as a, DURABLE_OBJECT_BINDINGS as b, DeployRequest as c, DevRequest as d, DiscoverSchemaInfoResult as e, DriverToolchain as f, GENERATED_CLASS_MODULES as g, GENERATED_MODULE_DURABLE_OBJECTS as h, InferOptions as i, InferredAgent as j, InferredContainer as k, InferredWorkflow as l, ProjectedConfig as m, SecretRequest as n, TailRequest as o, createDiscoveryCache as p, discoverSchemaInfo as q, inferLunoraBindings as r, isMergedProject as s, isMergedRoleModule as t, secretSourcesFromBindings as u };
|