@lunora/config 1.0.0-alpha.11 → 1.0.0-alpha.111
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 +6 -0
- package/README.md +2 -2
- package/__assets__/package-og.svg +1 -1
- package/dist/cloudflare/index.d.mts +661 -0
- package/dist/cloudflare/index.d.ts +661 -0
- package/dist/cloudflare/index.mjs +1 -0
- package/dist/index.d.mts +689 -824
- package/dist/index.d.ts +689 -824
- package/dist/index.mjs +1 -22
- package/dist/packem_shared/ACCENT-CLeV5v0K.mjs +7 -0
- package/dist/packem_shared/AGENT_MODE_ENV-B54hVQ_w.mjs +1 -0
- package/dist/packem_shared/AGENT_RULES_DIR-hP9TiDNx.mjs +1 -0
- package/dist/packem_shared/ALLOW_FORWARDED_ENV-DGdbCDre.mjs +1 -0
- package/dist/packem_shared/CLOUDFLARE_DRIVER-DS7cF7Cl.mjs +1 -0
- package/dist/packem_shared/DEFAULT_DEPLOY_TARGET-CBoD0Zha.mjs +1 -0
- package/dist/packem_shared/DEV_DAEMON_ENV-D9Z83rlU.mjs +4 -0
- package/dist/packem_shared/DEV_VARS_EXAMPLE_FILE-BL0hrPx3.mjs +6 -0
- package/dist/packem_shared/LINKED_PROJECT_DIR-CMzUvj-1.mjs +2 -0
- package/dist/packem_shared/LUNORA_CONFIG_FILE-DoVUD52W.mjs +1 -0
- package/dist/packem_shared/LUNORA_EVENT_SOURCE-ZclWASXS.mjs +1 -0
- package/dist/packem_shared/LunoraReporter-BnXUqh8t.mjs +6 -0
- package/dist/packem_shared/PACKAGE_SECRETS_REGISTRY-BgmvEPA-.mjs +1 -0
- package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-CUYWD0Mh.mjs +1 -0
- package/dist/packem_shared/REMOTE_ELIGIBLE_KEYS-ws6iE0y-.mjs +1 -0
- package/dist/packem_shared/REQUIRED_COMPATIBILITY_DATE-BwmyesjD.mjs +1 -0
- package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-BNB1ogaj.mjs +1 -0
- package/dist/packem_shared/SEED_ENDPOINT-BaYShU8q.mjs +1 -0
- package/dist/packem_shared/WORKERS_CACHE_MIN_DATE-B1h_wNDN.mjs +1 -0
- package/dist/packem_shared/WRANGLER_FILES-Bi_18Pj6.mjs +1 -0
- package/dist/packem_shared/applyAdditiveEdit-Cff30cSa.mjs +6 -0
- package/dist/packem_shared/assetContentType-DNZyUOuF.mjs +1 -0
- package/dist/packem_shared/buildPackageSecretsBlock-DlAPMSwt.mjs +18 -0
- package/dist/packem_shared/classifyPolicyEdit-BzC_MfYK.mjs +24 -0
- package/dist/packem_shared/collectWranglerSecretVariables-jPUxMC9j.mjs +1 -0
- package/dist/packem_shared/createConfirm-7IL0kZyE.mjs +7 -0
- package/dist/packem_shared/detectFramework-VTQfCNXy.mjs +1 -0
- package/dist/packem_shared/discoverAgentInfo-BJm0QtoI.mjs +1 -0
- package/dist/packem_shared/discoverContainerInfo-CYG9j2LY.mjs +1 -0
- package/dist/packem_shared/discoverSchemaInfo-C8X9mo-i.mjs +1 -0
- package/dist/packem_shared/discoverWorkflowInfo-Bbc0u2gE.mjs +1 -0
- package/dist/packem_shared/inferLunoraBindings-tf2nExl_.mjs +1 -0
- package/dist/packem_shared/jsonc-edit-BZVpxVA0.mjs +1 -0
- package/dist/packem_shared/parseDevVariable-B193_28t.mjs +1 -0
- package/dist/packem_shared/parseSchema-BQjgz6bk.mjs +1 -0
- package/dist/packem_shared/{policy-scaffold.d-DCmwn7zQ.d.mts → policy-scaffold.d-CFd2FlqG.d.mts} +22 -22
- package/dist/packem_shared/{policy-scaffold.d-DCmwn7zQ.d.ts → policy-scaffold.d-CFd2FlqG.d.ts} +22 -22
- package/dist/packem_shared/reconcileWranglerBindings-BCwTpuLO.mjs +1 -0
- package/dist/packem_shared/reconcileWranglerCompatibilityDate-BXNiEQ7p.mjs +1 -0
- package/dist/packem_shared/reconcileWranglerCrons-BmQa_kGL.mjs +1 -0
- package/dist/packem_shared/renderStudioHtml-B2AkxcW1.mjs +15 -0
- package/dist/packem_shared/schema-info.d-DS0bUsWE.d.mts +375 -0
- package/dist/packem_shared/schema-info.d-DS0bUsWE.d.ts +375 -0
- package/dist/packem_shared/serveJsonHandler-DQ-Yqa4J.mjs +1 -0
- package/dist/packem_shared/streamContainerLogs-BPYBNrWS.mjs +2 -0
- package/dist/packem_shared/wranglerToAlchemy-Fh5KfTPB.mjs +6 -0
- package/dist/packem_shared/write-atomic-Cdr2oQb-.mjs +1 -0
- package/dist/studio-host/index.d.mts +166 -92
- package/dist/studio-host/index.d.ts +166 -92
- package/dist/studio-host/index.mjs +1 -7
- package/package.json +15 -8
- 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-DRSNSOOp.mjs +0 -476
- 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-DNzNRu7T.mjs +0 -188
- 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-DIku9mTN.mjs +0 -302
- 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/reconcileWranglerBindings-DTHmqTbL.mjs +0 -277
- package/dist/packem_shared/renderStudioHtml-449Ysn75.mjs +0 -37
- package/dist/packem_shared/serveJsonHandler-B4OLTGLS.mjs +0 -86
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{writeFileSync as S,readFileSync as k}from"node:fs";import{join as E}from"node:path";import{containerBuildTag as D}from"@lunora/container";import{DEV_VARS_FILE as A,parseDevVariableEntries as B}from"./DEV_VARS_EXAMPLE_FILE-BL0hrPx3.mjs";import{e as b}from"./jsonc-edit-BZVpxVA0.mjs";import{findWranglerFile as O,readWranglerJsonc as C}from"./WRANGLER_FILES-Bi_18Pj6.mjs";const x="<replace-with-d1-create-id>",R=e=>{const a=[];for(const n of e.containers)n.exported||a.push({className:n.className,exportName:n.exportName,kind:"container",module:"containers"});for(const n of e.workflows)n.exported||a.push({className:n.className,exportName:n.exportName,kind:"workflow",module:"workflows"});for(const n of e.agents)n.exported||a.push({className:n.className,exportName:n.exportName,kind:"agent",module:"agents"});return a},I=(e,a)=>{const n=e.flagshipBinding!==void 0&&!(a?.flagship??[]).some(s=>s.binding===e.flagshipBinding);return[[e.usesKv&&(a?.kv_namespaces?.length??0)===0,"@lunora/bindings/kv is used but no kv_namespaces binding exists; add a kv_namespaces entry ({ binding, id }) and pass env.<BINDING> to createKv() — the namespace id can't be auto-provisioned."],[e.usesHyperdrive&&(a?.hyperdrive?.length??0)===0,"@lunora/hyperdrive is used but no hyperdrive binding exists; run 'wrangler hyperdrive create' and add a 'hyperdrive' binding ({ binding, id }) — the id can't be auto-provisioned."],[e.usesPipelines&&(a?.pipelines?.length??0)===0,"ctx.pipelines is used but no pipelines binding exists; run 'wrangler pipelines create <name>' and add a 'pipelines' binding ({ binding, pipeline }) — the pipeline resource can't be auto-provisioned."],[n,`lunora/flags.ts uses Flagship in binding mode but no flagship binding "${e.flagshipBinding??""}" exists; add a flagship entry ({ binding: "${e.flagshipBinding??""}", app_id }) — the app_id can't be auto-provisioned.`]].filter(([s])=>s).map(([,s])=>s)},P=e=>[[e.usesX402Charge,"@lunora/x402/charge is used; set the recipient wallet address as a [vars] entry (the var name is your choice) and pass it to the charge config — the x402 facilitator settles USDC to that address."],[e.usesX402Pay,"@lunora/x402/pay is used (ActionCtx-only, spends real funds); add a secrets_store_secrets[] binding holding the agent wallet key (binding name == signer.secretName) and pair the pay rail with a spend policy — ctx.secrets reads a Secrets Store binding, not .dev.vars."]].filter(([a])=>a).map(([,a])=>a),_=(e,a,n)=>n.filter(s=>!s.exported).map(s=>`${e} "${s.exportName}" is declared but ${s.className} is not exported by the worker entry; add \`export * from "./lunora/_generated/${a}"\` so its binding can be provisioned.`),N=[{keys:["STRIPE_SECRET_KEY","STRIPE_WEBHOOK_SECRET"],label:"Stripe"},{keys:["POLAR_ACCESS_TOKEN","POLAR_WEBHOOK_SECRET"],label:"Polar"},{keys:["CREEM_API_KEY","CREEM_WEBHOOK_SECRET"],label:"Creem"},{keys:["AUTUMN_SECRET_KEY","AUTUMN_WEBHOOK_SECRET"],label:"Autumn"},{keys:["DODO_PAYMENTS_API_KEY","DODO_PAYMENTS_WEBHOOK_KEY"],label:"Dodo Payments"}],T=()=>N.map(({keys:e,label:a})=>`${e[0]} + ${e[1]} (${a})`).join(" or "),$=e=>{let a;try{a=k(E(e,A),"utf8")}catch{return!1}const n=new Map(B(a).map(s=>[s.key,s.value]));return N.some(({keys:s})=>s.every(r=>(n.get(r)??"")!==""))},v=(e,a,n)=>{const s=new Set(e.durableObjects.map(o=>o.className)),r=[],i=(n?.r2_buckets?.length??0)>0,u=(n?.d1_databases?.some(o=>o.binding==="DB")??!1)||e.needsD1;return e.usesStorage&&!i&&r.push("@lunora/storage is used but R2 bucket bindings have user-defined names; add an r2_buckets entry and pass env.<BINDING> to createStorage()."),e.usesAuth&&!s.has("SessionDO")&&!u&&r.push("@lunora/auth is used but the worker entry exports no SessionDO; sessions are D1-backed, or export SessionDO to enable DO-backed sessions."),e.usesScheduler&&!s.has("SchedulerDO")&&r.push("@lunora/scheduler is used but the worker entry exports no SchedulerDO; export it so the SCHEDULER binding can be provisioned."),r.push(..._("container","containers",e.containers),..._("workflow","workflows",e.workflows),..._("agent","agents",e.agents)),e.containers.length>0&&n?.observability?.enabled===!1&&r.push("containers are declared but observability is explicitly disabled in wrangler.jsonc — container logs will not be captured."),e.usesPayment&&!$(a)&&r.push(`@lunora/payment is used; set one provider's secret pair in .dev.vars — ${T()}.`),r.push(...P(e),...I(e,n)),r},M=e=>{const a=new Set(e.map(s=>s.tag));let n=1;for(;a.has(`v${String(n)}`);)n+=1;return`v${String(n)}`},q=(e,a,n)=>{const s=a.durable_objects?.bindings??[],r=new Set(s.map(c=>c.name)),i=n.filter(c=>!r.has(c.binding));let u=e;const o=[];if(i.length>0){const c=[...s,...i.map(m=>({class_name:m.className,name:m.binding}))];u=b(u,["durable_objects","bindings"],c),o.push(...i.map(m=>`${m.binding}/${m.className}`))}const p=a.migrations??[],l=new Set(p.flatMap(c=>[...c.new_sqlite_classes??[],...c.new_classes??[]])),h=n.map(c=>c.className).filter(c=>!l.has(c));if(h.length>0){const c=[...p,{new_sqlite_classes:h,tag:M(p)}];u=b(u,["migrations"],c)}return{added:o,text:u}},K=(e,a)=>{const n=a.d1_databases??[];if(n.some(i=>i.binding==="DB"))return{added:[],text:e};const s=typeof a.name=="string"&&a.name.length>0?a.name:"lunora",r=[...n,{binding:"DB",database_id:x,database_name:s}];return{added:["DB (D1)"],text:b(e,["d1_databases"],r)}},y=(e,a,n,s,r)=>{const i=a[n]?.binding;return typeof i=="string"&&i.length>0?{added:[],text:e}:{added:[r],text:b(e,[n],{binding:s})}},W=(e,a)=>(a.analytics_engine_datasets?.length??0)>0?{added:[],text:e}:{added:["ANALYTICS (Analytics Engine)"],text:b(e,["analytics_engine_datasets"],[{binding:"ANALYTICS",dataset:"ANALYTICS"}])},j=e=>{if(typeof e=="string")return e;const a={};return e.diskMb!==void 0&&(a.disk_mb=e.diskMb),e.memoryMib!==void 0&&(a.memory_mib=e.memoryMib),e.vcpu!==void 0&&(a.vcpu=e.vcpu),a},Y=e=>e.image.kind==="dockerfile"?e.image.dockerfilePath:e.image.kind==="registry"?e.image.reference:D(e.exportName),L=e=>{const a={class_name:e.className,image:Y(e)};return e.image.kind==="dockerfile"&&(a.image_build_context=e.image.buildContext),e.buildArgs!==void 0&&e.image.kind!=="registry"&&(a.image_vars=e.buildArgs),e.instanceType!==void 0&&(a.instance_type=j(e.instanceType)),e.maxInstances!==void 0&&(a.max_instances=e.maxInstances),e.name!==void 0&&(a.name=e.name),e.rollout?.stepPercentage!==void 0&&(a.rollout_step_percentage=e.rollout.stepPercentage),e.rollout?.gracePeriodSeconds!==void 0&&(a.rollout_active_grace_period=e.rollout.gracePeriodSeconds),a},G=(e,a,n)=>{const s=a.containers??[],r=new Set(s.map(o=>o.class_name)),i=n.filter(o=>!r.has(o.className));if(i.length===0)return{added:[],text:e};const u=b(e,["containers"],[...s,...i.map(o=>L(o))]);return{added:i.map(o=>`containers/${o.className}`),text:u}},H=(e,a)=>{if(a.observability!==void 0)return{added:[],text:e};const n=b(e,["observability"],{enabled:!0,head_sampling_rate:1});return{added:["observability"],text:n}},U=e=>({binding:e.bindingName,class_name:e.className,name:e.name}),F=e=>({binding:e.bindingName,class_name:e.className,name:e.name}),z=(e,a,n,s=[])=>{const r=a.workflows??[],i=new Set(r.map(l=>l.class_name)),u=n.filter(l=>!i.has(l.className)),o=s.filter(l=>!i.has(l.className));if(u.length===0&&o.length===0)return{added:[],text:e};const p=b(e,["workflows"],[...r,...u.map(l=>U(l)),...o.map(l=>F(l))]);return{added:[...u.map(l=>`workflows/${l.className}`),...o.map(l=>`workflows/${l.className}`)],text:p}},V=(e,a,n)=>{const s=a.queues??{},r=s.producers??[],i=s.consumers??[],u=new Set(r.map(d=>d.binding)),o=new Set(i.map(d=>d.queue)),p=n.filter(d=>!u.has(d.bindingName)),l=n.filter(d=>!o.has(d.name));if(p.length===0&&l.length===0)return{added:[],text:e};const h=[...r,...p.map(d=>({binding:d.bindingName,queue:d.name}))],c=[...i,...l.map(d=>{const g={queue:d.name};return d.mode==="pull"&&(g.type="http_pull"),d.tuning.maxBatchSize!==void 0&&(g.max_batch_size=d.tuning.maxBatchSize),d.tuning.maxBatchTimeout!==void 0&&(g.max_batch_timeout=d.tuning.maxBatchTimeout),d.tuning.maxRetries!==void 0&&(g.max_retries=d.tuning.maxRetries),d.tuning.deadLetterQueue!==void 0&&(g.dead_letter_queue=d.tuning.deadLetterQueue),d.tuning.retryDelay!==void 0&&(g.retry_delay=d.tuning.retryDelay),g})],m=b(e,["queues"],{consumers:c,producers:h});return{added:[...p.map(d=>`queues.producers/${d.bindingName}`),...l.map(d=>`queues.consumers/${d.name}`)],text:m}},ne=(e,a,n)=>{const s=O(e),r=R(a);if(!s)return{added:[],changed:!1,exportGaps:r,reason:"wrangler.jsonc not found",warnings:v(a,e)};const{parsed:i,text:u}=C(s);if(i===void 0)return{added:[],changed:!1,exportGaps:r,reason:`failed to parse ${s} as JSONC`,warnings:v(a,e),wranglerPath:s};const o=v(a,e,i);if(n!==void 0){const t=i.env?.[n]!==void 0;o.push(t?`auto-provisioned bindings are written to the top level of wrangler.jsonc only — "env.${n}" has its own (non-inheritable) bindings and must be reconciled by hand; \`lunora deploy --env ${n}\` now validates them, so a gap here will be reported at deploy time.`:`--env "${n}" was requested but wrangler.jsonc declares no "env.${n}" block — auto-provisioned bindings are written to the top level only and will not apply to that environment.`)}const p=a.containers.filter(t=>t.exported),l=a.agents.filter(t=>t.exported&&t.voice===!0&&t.voiceBindingName!==void 0&&t.voiceClassName!==void 0),h=[...a.durableObjects,...p.map(t=>({binding:t.bindingName,className:t.className})),...l.map(t=>({binding:t.voiceBindingName,className:t.voiceClassName}))],c=a.workflows.filter(t=>t.exported),m=a.agents.filter(t=>t.exported),d=[{enabled:!0,run:t=>q(t,i,h)},{enabled:a.needsD1,run:t=>K(t,i)},{enabled:a.usesAi,run:t=>y(t,i,"ai","AI","AI (Workers AI)")},{enabled:a.usesBrowser,run:t=>y(t,i,"browser","BROWSER","BROWSER (Browser Rendering)")},{enabled:a.usesImages,run:t=>y(t,i,"images","IMAGES","IMAGES (Cloudflare Images)")},{enabled:a.usesAnalytics,run:t=>W(t,i)},{enabled:!0,run:t=>H(t,i)},{enabled:p.length>0,run:t=>G(t,i,p)},{enabled:c.length>0||m.length>0,run:t=>z(t,i,c,m)},{enabled:a.queues.length>0,run:t=>V(t,i,a.queues)}];let g=u;const f=[];for(const t of d){if(!t.enabled)continue;const w=t.run(g);g=w.text,f.push(...w.added)}return f.includes("DB (D1)")&&o.push(`wrote a DB binding with a placeholder database_id ("${x}") — run \`wrangler d1 create <name>\` and replace it before deploying.`),g===u?{added:[],changed:!1,exportGaps:r,reason:"bindings already in sync",warnings:o,wranglerPath:s}:(S(s,g,"utf8"),{added:f,changed:!0,exportGaps:r,warnings:o,wranglerPath:s})};export{ne as reconcileWranglerBindings};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{writeFileSync as d}from"node:fs";import{modify as l,applyEdits as c}from"jsonc-parser";import{r as s}from"./jsonc-edit-BZVpxVA0.mjs";import{isCacheEnabled as f,WORKERS_CACHE_MIN_DATE as r}from"./WORKERS_CACHE_MIN_DATE-B1h_wNDN.mjs";import{findWranglerFile as g,readWranglerJsonc as m}from"./WRANGLER_FILES-Bi_18Pj6.mjs";const b=i=>{const e=g(i);if(!e)return{changed:!1,date:void 0,reason:"wrangler.jsonc not found"};const{parsed:t,text:n}=m(e);if(t===void 0)return{changed:!1,date:void 0,reason:`failed to parse ${e} as JSONC`,wranglerPath:e};const a=t.compatibility_date??"";if(!f(t))return{changed:!1,date:a||void 0,reason:"cache not enabled",wranglerPath:e};if(a>=r)return{changed:!1,date:a,reason:`compatibility_date already >= ${r}`,wranglerPath:e};const o=l(n,["compatibility_date"],r,s);return o.length===0?{changed:!1,date:a||void 0,reason:"no structural edit produced",wranglerPath:e}:(d(e,c(n,o),"utf8"),{changed:!0,date:r,wranglerPath:e})};export{b as reconcileWranglerCompatibilityDate};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{writeFileSync as g}from"node:fs";import{modify as c,applyEdits as l}from"jsonc-parser";import{findWranglerFile as d,readWranglerJsonc as f}from"./WRANGLER_FILES-Bi_18Pj6.mjs";const h=(t,e)=>t.length===e.length&&t.every((r,n)=>r===e[n]),m=(t,e)=>{const r=d(t);if(!r)return{changed:!1,reason:"wrangler.jsonc not found"};const{parsed:n,text:a}=f(r);if(n===void 0)return{changed:!1,reason:`failed to parse ${r} as JSONC`,wranglerPath:r};const o=Array.isArray(n.triggers?.crons)?n.triggers.crons.filter(i=>typeof i=="string"):[];if(h(o,e))return{changed:!1,reason:"triggers.crons already in sync",wranglerPath:r};const s=c(a,["triggers","crons"],[...e],{formattingOptions:{insertSpaces:!0,tabSize:4}});return s.length===0?{changed:!1,reason:"no structural edit produced",wranglerPath:r}:(g(r,l(a,s),"utf8"),{changed:!0,wranglerPath:r})};export{m as reconcileWranglerCrons};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const i=e=>JSON.stringify(e).replaceAll("<",String.raw`\u003c`),_=e=>e.replaceAll("&","&").replaceAll('"',""").replaceAll("<","<"),l=e=>{const t=[`window.__LUNORA_BASE_PATH__=${i(e.basePath)};`];return e.adminToken!==void 0&&e.adminToken!==""&&t.push(`window.__LUNORA_ADMIN_TOKEN__=${i(e.adminToken)};`),e.dataEditable===!0&&t.push("window.__LUNORA_DATA_EDITABLE__=true;"),e.runAsIdentity===!0&&t.push("window.__LUNORA_RUN_AS_IDENTITY__=true;"),e.schemaEditable===!0&&t.push("window.__LUNORA_SCHEMA_EDITABLE__=true;"),e.rulesInstalled===!1&&t.push("window.__LUNORA_RULES_INSTALLED__=false;"),`<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Lunora Studio</title>
|
|
7
|
+
<script>${t.join("")}<\/script>
|
|
8
|
+
<link rel="stylesheet" href="${_(e.styleHref)}" />
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
<script type="module" src="${_(e.scriptSrc)}"><\/script>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
15
|
+
`};export{l as default};
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import { AgentIR, ContainerIR, QueueIR, WorkflowIR } from '@lunora/codegen';
|
|
2
|
+
/**
|
|
3
|
+
* `DeployDriver` — the provider-neutral seam between what an app needs and
|
|
4
|
+
* how a host provides it (plan 114, §5.3).
|
|
5
|
+
*
|
|
6
|
+
* Configuration inference is two jobs welded together today. Deciding that an
|
|
7
|
+
* app needs a shard namespace, a queue, and an object-storage bucket is
|
|
8
|
+
* host-neutral: it falls out of the app's schema and imports, and every target
|
|
9
|
+
* reaches the same conclusion. Writing `durable_objects.bindings[]` into a
|
|
10
|
+
* `wrangler.jsonc` is not — it is one host's encoding of that conclusion.
|
|
11
|
+
*
|
|
12
|
+
* The split here names both halves. {@link ResourceGraph} is the neutral answer
|
|
13
|
+
* to "what does this app need?"; a {@link DeployDriver} turns that graph into
|
|
14
|
+
* one host's configuration and owns the host's toolchain surface. A second
|
|
15
|
+
* target implements the driver rather than forking the inference.
|
|
16
|
+
*
|
|
17
|
+
* Only the Cloudflare driver exists today (`cloudflare-driver.ts`), and it is
|
|
18
|
+
* deliberately thin: it delegates to the same `inferLunoraBindings` /
|
|
19
|
+
* `reconcileWrangler*` functions the CLI called directly before, so routing a
|
|
20
|
+
* command through the driver is behavior-preserving by construction.
|
|
21
|
+
*
|
|
22
|
+
* The second half is the **toolchain surface**: which command a host runs to
|
|
23
|
+
* deploy, serve, tail, or set a secret. A driver only *describes* that command
|
|
24
|
+
* ({@link ToolchainCommand}); it never spawns. The CLI keeps ownership of
|
|
25
|
+
* running it — package-manager resolution (`pnpm exec` / `npx --` / `bun x`)
|
|
26
|
+
* and the injected spawner its tests substitute — so the driver stays free of
|
|
27
|
+
* process concerns and remains trivially testable as a pure function.
|
|
28
|
+
*
|
|
29
|
+
* Each request type below is deliberately neutral: `preview`, `environment`,
|
|
30
|
+
* `temporary` are concepts, not wrangler flags. A second host maps the same
|
|
31
|
+
* request onto its own CLI without the caller changing.
|
|
32
|
+
*/
|
|
33
|
+
/** A durable, single-writer shard namespace (a Durable Object namespace on Cloudflare). */
|
|
34
|
+
interface ShardNamespaceResource {
|
|
35
|
+
/** The implementing class name the host binds to. */
|
|
36
|
+
className: string;
|
|
37
|
+
/** Whether the worker entry re-exports the class — an unexported class cannot be bound. */
|
|
38
|
+
exported: boolean;
|
|
39
|
+
/** The binding name the app reaches it through (e.g. `SHARD`). */
|
|
40
|
+
name: string;
|
|
41
|
+
}
|
|
42
|
+
/** A named resource the app declares and the host must provision (queue, workflow, container). */
|
|
43
|
+
interface NamedResource {
|
|
44
|
+
/** Whether the declaration is re-exported from the worker entry, where that applies. */
|
|
45
|
+
exported?: boolean;
|
|
46
|
+
/** The declared name. */
|
|
47
|
+
name: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The provider-neutral statement of what an app needs, derived from its schema
|
|
51
|
+
* and imports. Every field is a *requirement*, not a host encoding: a driver
|
|
52
|
+
* decides what `objectStorage: true` means for its target.
|
|
53
|
+
*/
|
|
54
|
+
interface ResourceGraph {
|
|
55
|
+
/** Container images the app declares. */
|
|
56
|
+
containers: ReadonlyArray<NamedResource>;
|
|
57
|
+
/** Cron expressions the app schedules. */
|
|
58
|
+
crons: ReadonlyArray<string>;
|
|
59
|
+
/**
|
|
60
|
+
* The app declares a `.global()` table, so it needs a replicated SQL store
|
|
61
|
+
* (D1 on Cloudflare; Aurora/RDS elsewhere).
|
|
62
|
+
*/
|
|
63
|
+
globalDatabase: boolean;
|
|
64
|
+
/** The app reads or writes a key-value store. */
|
|
65
|
+
keyValueStore: boolean;
|
|
66
|
+
/** The app needs object storage (R2 on Cloudflare; S3-compatible elsewhere). */
|
|
67
|
+
objectStorage: boolean;
|
|
68
|
+
/** Queues the app declares. */
|
|
69
|
+
queues: ReadonlyArray<NamedResource>;
|
|
70
|
+
/** Shard namespaces the app needs. */
|
|
71
|
+
shardNamespaces: ReadonlyArray<ShardNamespaceResource>;
|
|
72
|
+
/**
|
|
73
|
+
* Human-readable provenance for each requirement — why inference concluded
|
|
74
|
+
* the app needs it. Surfaced in CLI logs; never load-bearing.
|
|
75
|
+
*/
|
|
76
|
+
signals: ReadonlyArray<string>;
|
|
77
|
+
/** Workflows the app declares. */
|
|
78
|
+
workflows: ReadonlyArray<NamedResource>;
|
|
79
|
+
}
|
|
80
|
+
/** The outcome of writing a {@link ResourceGraph} into a host's configuration. */
|
|
81
|
+
interface ProvisionResult {
|
|
82
|
+
/** Short labels for each resource written, for logging. */
|
|
83
|
+
added: ReadonlyArray<string>;
|
|
84
|
+
/** Whether the host's configuration file was rewritten. */
|
|
85
|
+
changed: boolean;
|
|
86
|
+
/** Resolved configuration path, when the host has one. */
|
|
87
|
+
configPath?: string;
|
|
88
|
+
/** Non-fatal hints for requirements the driver cannot auto-provision. */
|
|
89
|
+
warnings: ReadonlyArray<string>;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A host CLI invocation, described but not run.
|
|
93
|
+
*
|
|
94
|
+
* `tool` is the binary name only (`"wrangler"`); the caller resolves how to
|
|
95
|
+
* execute it through the project's package manager. Keeping that split means a
|
|
96
|
+
* driver never has to know whether the project uses pnpm, npm, yarn, or bun.
|
|
97
|
+
*/
|
|
98
|
+
interface ToolchainCommand {
|
|
99
|
+
/** Arguments for {@link ToolchainCommand.tool}. */
|
|
100
|
+
args: ReadonlyArray<string>;
|
|
101
|
+
/** The host CLI binary, e.g. `"wrangler"`. */
|
|
102
|
+
tool: string;
|
|
103
|
+
}
|
|
104
|
+
/** Neutral options for a deploy. */
|
|
105
|
+
interface DeployRequest {
|
|
106
|
+
/** Validate and bundle without publishing — nothing ships. */
|
|
107
|
+
dryRun?: boolean;
|
|
108
|
+
/** Deploy this entry file instead of the host config's default (framework composition). */
|
|
109
|
+
entry?: string;
|
|
110
|
+
/** Named deployment environment, when the host supports them. */
|
|
111
|
+
environment?: string;
|
|
112
|
+
/** Write the built bundle (and any build metadata) to this directory. */
|
|
113
|
+
outDir?: string;
|
|
114
|
+
/** Upload a preview/versioned artifact instead of taking production traffic. */
|
|
115
|
+
preview?: boolean;
|
|
116
|
+
/** Deploy to a short-lived, unauthenticated account where the host offers one. */
|
|
117
|
+
temporary?: boolean;
|
|
118
|
+
}
|
|
119
|
+
/** Neutral options for a local dev server. */
|
|
120
|
+
interface DevRequest {
|
|
121
|
+
/** Host config file to run against, when the flow uses a generated one. */
|
|
122
|
+
configPath?: string;
|
|
123
|
+
/** Named environment. */
|
|
124
|
+
environment?: string;
|
|
125
|
+
/** Extra host-specific flags the caller has already resolved. */
|
|
126
|
+
extraArgs?: ReadonlyArray<string>;
|
|
127
|
+
}
|
|
128
|
+
/** Neutral options for tailing live logs. */
|
|
129
|
+
interface TailRequest {
|
|
130
|
+
/** Named environment. */
|
|
131
|
+
environment?: string;
|
|
132
|
+
/** Output format the host tail supports (`"json"`, `"pretty"`, …). */
|
|
133
|
+
format?: string;
|
|
134
|
+
/** Free-text filter. */
|
|
135
|
+
search?: string;
|
|
136
|
+
/** Status filter (`"error"`, `"ok"`, …). */
|
|
137
|
+
status?: string;
|
|
138
|
+
/** Tail a short-lived account's deployment. */
|
|
139
|
+
temporary?: boolean;
|
|
140
|
+
/** Tail a specific deployed worker/service by name, when the host addresses them individually. */
|
|
141
|
+
worker?: string;
|
|
142
|
+
}
|
|
143
|
+
/** Neutral options for reading or writing deployment secrets. */
|
|
144
|
+
interface SecretRequest {
|
|
145
|
+
/** Named environment. */
|
|
146
|
+
environment?: string;
|
|
147
|
+
/** The secret's name — required for `put`, unused for `list`. */
|
|
148
|
+
key?: string;
|
|
149
|
+
/** Operate against a short-lived account. */
|
|
150
|
+
temporary?: boolean;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* The host's command-line surface. Optional as a whole: a host with no CLI (a
|
|
154
|
+
* hypothetical API-driven target) implements `infer`/`provision` only, and the
|
|
155
|
+
* caller falls back to its own handling.
|
|
156
|
+
*/
|
|
157
|
+
interface DriverToolchain {
|
|
158
|
+
/** The command that deploys the app. */
|
|
159
|
+
deploy: (request: DeployRequest) => ToolchainCommand;
|
|
160
|
+
/** The command that runs a local dev server. */
|
|
161
|
+
dev: (request: DevRequest) => ToolchainCommand;
|
|
162
|
+
/** The command that lists remote secret names. */
|
|
163
|
+
secretList: (request: SecretRequest) => ToolchainCommand;
|
|
164
|
+
/** The command that writes one secret. Its value is passed on stdin, never argv. */
|
|
165
|
+
secretPut: (request: SecretRequest) => ToolchainCommand;
|
|
166
|
+
/** The command that tails live logs. */
|
|
167
|
+
tail: (request: TailRequest) => ToolchainCommand;
|
|
168
|
+
}
|
|
169
|
+
/** Options every driver method receives. */
|
|
170
|
+
interface DriverContext {
|
|
171
|
+
/** Cron expressions codegen discovered, threaded in because they come from the app's code rather than its config. */
|
|
172
|
+
crons?: ReadonlyArray<string>;
|
|
173
|
+
/** Project root containing the `lunora/` directory. */
|
|
174
|
+
projectRoot: string;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* A deploy target's implementation: report what the app needs, and encode it
|
|
178
|
+
* into that host's configuration.
|
|
179
|
+
*
|
|
180
|
+
* **Why `provision` does not take a {@link ResourceGraph}.** The obvious
|
|
181
|
+
* signature is `provision(graph, context)`, and it is wrong. Writing real host
|
|
182
|
+
* configuration needs the host's own encodings — binding names, DO class
|
|
183
|
+
* wiring, migration tags — which the neutral graph deliberately discards. A
|
|
184
|
+
* driver handed only the graph would have to re-derive them, so passing it
|
|
185
|
+
* would be decorative. `infer` is therefore the *reporting* surface (a portable
|
|
186
|
+
* picture of the app's requirements, for logs, diagnostics, and cross-target
|
|
187
|
+
* comparison) and `provision` is the *doing* surface, which owns its own
|
|
188
|
+
* inference end-to-end.
|
|
189
|
+
*
|
|
190
|
+
* That asymmetry is a genuine finding about this seam, not a shortcut: it says
|
|
191
|
+
* the neutral graph is not a sufficient intermediate representation for config
|
|
192
|
+
* emission. If a future target needs one, the graph must grow a host-extension
|
|
193
|
+
* escape hatch rather than pretend it already carries the detail.
|
|
194
|
+
*/
|
|
195
|
+
interface DeployDriver {
|
|
196
|
+
/** The target id this driver serves (`"cloudflare"`, …) — matches codegen's `target`. */
|
|
197
|
+
readonly id: string;
|
|
198
|
+
/**
|
|
199
|
+
* Read the app and report what it needs, in provider-neutral terms. Pure
|
|
200
|
+
* with respect to the project: it never writes configuration.
|
|
201
|
+
*/
|
|
202
|
+
infer: (context: DriverContext) => Promise<ResourceGraph>;
|
|
203
|
+
/** Human-readable target name, for logs. */
|
|
204
|
+
readonly name: string;
|
|
205
|
+
/**
|
|
206
|
+
* Write the app's requirements into the host's configuration, adding what is
|
|
207
|
+
* missing and leaving existing entries alone. Must be idempotent:
|
|
208
|
+
* provisioning an already-provisioned project reports `changed: false`, and
|
|
209
|
+
* must fold a failed step into a warning rather than throwing.
|
|
210
|
+
*/
|
|
211
|
+
provision: (context: DriverContext) => Promise<ProvisionResult>;
|
|
212
|
+
/**
|
|
213
|
+
* The host's command-line surface, or `undefined` for a host that has none.
|
|
214
|
+
* Pure: these build argv, they never spawn.
|
|
215
|
+
*/
|
|
216
|
+
readonly toolchain?: DriverToolchain;
|
|
217
|
+
}
|
|
218
|
+
interface DurableObjectSpec {
|
|
219
|
+
binding: string;
|
|
220
|
+
className: string;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* A `defineContainer` declaration plus whether its generated DO class is
|
|
224
|
+
* exported by the worker entry. Only exported containers are safe to
|
|
225
|
+
* provision — wrangler rejects a `containers[].class_name` (and its Durable
|
|
226
|
+
* Object binding) that the worker doesn't export.
|
|
227
|
+
*/
|
|
228
|
+
interface InferredContainer extends ContainerIR {
|
|
229
|
+
exported: boolean;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* A `defineWorkflow` declaration plus whether its generated
|
|
233
|
+
* `WorkflowEntrypoint` class is exported by the worker entry. Only exported
|
|
234
|
+
* workflows are safe to provision — wrangler rejects a `workflows[].class_name`
|
|
235
|
+
* the worker doesn't export. Workflows are NOT Durable Objects, so this never
|
|
236
|
+
* implies a `durable_objects` binding or migration.
|
|
237
|
+
*/
|
|
238
|
+
interface InferredWorkflow extends WorkflowIR {
|
|
239
|
+
exported: boolean;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* A `defineAgent` declaration plus whether its generated agent
|
|
243
|
+
* `WorkflowEntrypoint` class (e.g. `SupportAgentWorkflow`) is exported by the
|
|
244
|
+
* worker entry. An agent compiles onto a Cloudflare Workflow, so — exactly like
|
|
245
|
+
* {@link InferredWorkflow} — only exported agents are safe to provision
|
|
246
|
+
* (wrangler rejects a `workflows[].class_name` the worker doesn't export), and
|
|
247
|
+
* an agent is NOT a Durable Object (no `durable_objects` binding or migration).
|
|
248
|
+
*/
|
|
249
|
+
interface InferredAgent extends AgentIR {
|
|
250
|
+
exported: boolean;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* A queue declared in `lunora/queues.ts`. Unlike workflows, a queue needs no
|
|
254
|
+
* worker-entry class export (its `queue()` handler rides `createWorker`), so
|
|
255
|
+
* there is no `exported` flag — every declared queue is reconcilable into the
|
|
256
|
+
* wrangler `queues.producers[]` / `queues.consumers[]`.
|
|
257
|
+
*/
|
|
258
|
+
type InferredQueue = QueueIR;
|
|
259
|
+
interface InferredBindings {
|
|
260
|
+
/** Agents declared in `lunora/agents.ts` (exported or not — see {@link InferredAgent.exported}); reconciled into `workflows[]`. */
|
|
261
|
+
agents: InferredAgent[];
|
|
262
|
+
/** Containers declared in `lunora/containers.ts` (exported or not — see {@link InferredContainer.exported}). */
|
|
263
|
+
containers: InferredContainer[];
|
|
264
|
+
/** Durable Objects the worker entry exports → safe to bind. */
|
|
265
|
+
durableObjects: DurableObjectSpec[];
|
|
266
|
+
/**
|
|
267
|
+
* The wrangler `flagship[].binding` name implied by `lunora/flags.ts` when it
|
|
268
|
+
* uses the Flagship provider in binding mode — `undefined` for HTTP-mode
|
|
269
|
+
* Flagship, a custom OpenFeature provider, or no flags. The binding needs an
|
|
270
|
+
* un-mintable `app_id`, so it is reconciled as a hint, not auto-written.
|
|
271
|
+
*/
|
|
272
|
+
flagshipBinding?: string;
|
|
273
|
+
/** Schema declares a `.global()` table → needs the `DB` D1 binding. */
|
|
274
|
+
needsD1: boolean;
|
|
275
|
+
/** Queues declared in `lunora/queues.ts` → reconciled into `queues.producers[]` / `queues.consumers[]`. */
|
|
276
|
+
queues: InferredQueue[];
|
|
277
|
+
/** Human-readable provenance for each inferred binding / hint, for logging. */
|
|
278
|
+
signals: string[];
|
|
279
|
+
/** `@lunora/ai` is imported or `env.AI` is used → needs the `ai` Workers AI binding. */
|
|
280
|
+
usesAi: boolean;
|
|
281
|
+
/** `@lunora/bindings/analytics` is imported → self-describing `analytics_engine_datasets` binding (auto-writeable). */
|
|
282
|
+
usesAnalytics: boolean;
|
|
283
|
+
/** `@lunora/auth` is imported (sessions may be D1- or `SessionDO`-backed). */
|
|
284
|
+
usesAuth: boolean;
|
|
285
|
+
/** `@lunora/browser` is imported → self-describing `browser` binding (auto-writeable). */
|
|
286
|
+
usesBrowser: boolean;
|
|
287
|
+
/** `lunora/flags.ts` declares a feature-flag provider (any OpenFeature provider — Flagship or custom). */
|
|
288
|
+
usesFlags: boolean;
|
|
289
|
+
/** `@lunora/hyperdrive` is imported (binding needs an un-mintable remote `id`; hint-only). */
|
|
290
|
+
usesHyperdrive: boolean;
|
|
291
|
+
/** `@lunora/bindings/images` is imported → self-describing `images` binding (auto-writeable). */
|
|
292
|
+
usesImages: boolean;
|
|
293
|
+
/** `@lunora/bindings/kv` is imported (namespace binding name + id are user-defined; hint-only). */
|
|
294
|
+
usesKv: boolean;
|
|
295
|
+
/** `@lunora/mail` is imported (Resend API key must be set in `.dev.vars`; no binding). */
|
|
296
|
+
usesMail: boolean;
|
|
297
|
+
/** `@lunora/payment` is imported (provider secrets must be set in `.dev.vars`; no binding). */
|
|
298
|
+
usesPayment: boolean;
|
|
299
|
+
/** `ctx.pipelines` is used (binding needs an un-mintable remote pipeline name; hint-only). */
|
|
300
|
+
usesPipelines: boolean;
|
|
301
|
+
/** `@lunora/scheduler` is imported. */
|
|
302
|
+
usesScheduler: boolean;
|
|
303
|
+
/** `@lunora/storage` is imported (R2 bucket binding name is user-defined). */
|
|
304
|
+
usesStorage: boolean;
|
|
305
|
+
/** `@lunora/x402/charge` is imported — the charge rail settles USDC to a recipient address (a public `[vars]` entry, user-named; hint-only). */
|
|
306
|
+
usesX402Charge: boolean;
|
|
307
|
+
/** `@lunora/x402/pay` is imported — the agent-wallet pay rail signs from a Secrets Store binding paired with a spend policy (ActionCtx-only; hint-only). */
|
|
308
|
+
usesX402Pay: boolean;
|
|
309
|
+
/** Workflows declared in `lunora/workflows.ts` (exported or not — see {@link InferredWorkflow.exported}). */
|
|
310
|
+
workflows: InferredWorkflow[];
|
|
311
|
+
}
|
|
312
|
+
interface InferOptions {
|
|
313
|
+
projectRoot: string;
|
|
314
|
+
/** Directories (relative to root) to scan. Defaults to `lunora` + `src`. */
|
|
315
|
+
scanDirs?: ReadonlyArray<string>;
|
|
316
|
+
/** Lunora source directory holding `schema.ts`. Defaults to `lunora`. */
|
|
317
|
+
schemaDir?: string;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Scan a Lunora project and report which Cloudflare bindings its code implies.
|
|
321
|
+
* Read-only: performs no writes. Binding provisioning is driven by the worker
|
|
322
|
+
* entry's Durable Object exports plus the schema's D1 need; capability imports
|
|
323
|
+
* surface as hints.
|
|
324
|
+
*/
|
|
325
|
+
declare const inferLunoraBindings: (options: InferOptions) => Promise<InferredBindings>;
|
|
326
|
+
/**
|
|
327
|
+
* Derive the list of `@lunora/*` package names that are actively used by a
|
|
328
|
+
* project, based on its already-resolved {@link InferredBindings}.
|
|
329
|
+
*
|
|
330
|
+
* This is the canonical bridge between binding inference and the package-aware
|
|
331
|
+
* `.dev.vars.example` scaffolding in `scaffold-dev-variables.ts`. The result is
|
|
332
|
+
* a stable, predictable slice of {@link CAPABILITY_SOURCES} source values,
|
|
333
|
+
* filtered to the flags that are `true` in `bindings` — in CAPABILITY_SOURCES
|
|
334
|
+
* declaration order.
|
|
335
|
+
*/
|
|
336
|
+
declare const packageNamesFromBindings: (bindings: InferredBindings) => string[];
|
|
337
|
+
/** One filterable Vectorize metadata property a schema declares. */
|
|
338
|
+
interface VectorMetadataDeclaration {
|
|
339
|
+
/** The vector index the property belongs to. */
|
|
340
|
+
index: string;
|
|
341
|
+
/**
|
|
342
|
+
* The validator kind behind the column, or `undefined` when the column
|
|
343
|
+
* isn't in the owning table's shape. Callers map it to the Vectorize
|
|
344
|
+
* metadata type; a kind that can't be filtered on is reported, not indexed.
|
|
345
|
+
*/
|
|
346
|
+
kind: string | undefined;
|
|
347
|
+
/** Column mirrored into vector metadata. */
|
|
348
|
+
property: string;
|
|
349
|
+
}
|
|
350
|
+
interface SchemaInfo {
|
|
351
|
+
/** Whether the lunora schema declares any `.global()` table. */
|
|
352
|
+
hasGlobalTable: boolean;
|
|
353
|
+
/** Names of vector indexes declared via `.vectorize()` / `defineVectorIndex()`. */
|
|
354
|
+
vectorIndexNames?: ReadonlyArray<string>;
|
|
355
|
+
/**
|
|
356
|
+
* Metadata properties declared filterable on a vector index. Cloudflare
|
|
357
|
+
* needs an explicit metadata index per property before a `filter` can match
|
|
358
|
+
* anything, so deploy provisions these and doctor reports them.
|
|
359
|
+
*/
|
|
360
|
+
vectorMetadata?: ReadonlyArray<VectorMetadataDeclaration>;
|
|
361
|
+
}
|
|
362
|
+
interface DiscoverSchemaInfoResult {
|
|
363
|
+
/** Parse error message, when the schema exists but could not be analyzed. */
|
|
364
|
+
error?: string;
|
|
365
|
+
/** Schema facts, or `undefined` when no `schema.ts` exists or parsing failed. */
|
|
366
|
+
info: SchemaInfo | undefined;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Discover {@link SchemaInfo} for a project. Returns `{ info: undefined }` when
|
|
370
|
+
* the project declares no `schema.ts` (not an error), or `{ info: undefined,
|
|
371
|
+
* error }` when a present schema could not be parsed — callers decide whether a
|
|
372
|
+
* parse failure is a warning (validator) or simply ignorable (inference).
|
|
373
|
+
*/
|
|
374
|
+
declare const discoverSchemaInfo: (projectRoot: string, schemaDirectory: string) => DiscoverSchemaInfoResult;
|
|
375
|
+
export { DeployDriver as D, InferredBindings as I, NamedResource as N, ProvisionResult as P, ResourceGraph as R, SchemaInfo as S, TailRequest as T, DeployRequest as a, DevRequest as b, DiscoverSchemaInfoResult as c, DriverContext as d, DriverToolchain as e, InferOptions as f, InferredAgent as g, InferredContainer as h, InferredWorkflow as i, SecretRequest as j, ShardNamespaceResource as k, ToolchainCommand as l, discoverSchemaInfo as m, inferLunoraBindings as n, packageNamesFromBindings as p };
|