@lunora/config 1.0.0-alpha.192 → 1.0.0-alpha.193

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.
Files changed (40) hide show
  1. package/dist/cloudflare/index.d.mts +17 -13
  2. package/dist/cloudflare/index.d.ts +17 -13
  3. package/dist/cloudflare/index.mjs +1 -1
  4. package/dist/index.d.mts +15 -7
  5. package/dist/index.d.ts +15 -7
  6. package/dist/index.mjs +1 -1
  7. package/dist/packem_shared/AGENT_RULES_DIR-C54Ta_vz.mjs +1 -0
  8. package/dist/packem_shared/{BINDING_MANIFEST_VERSION-Cd00jVOf.mjs → BINDING_MANIFEST_VERSION-B8dwEKLn.mjs} +1 -1
  9. package/dist/packem_shared/CLOUDFLARE_DRIVER-Ci9oJMYb.mjs +1 -0
  10. package/dist/packem_shared/COMPOSED_WORKER_ENTRY-CbtPPFQK.mjs +1 -0
  11. package/dist/packem_shared/DEFAULT_DEPLOY_TARGET-B-e9mqgX.mjs +1 -0
  12. package/dist/packem_shared/{LUNORA_CONFIG_FILE-DFoqHCyP.mjs → LUNORA_CONFIG_FILE-D0F9TWxc.mjs} +1 -1
  13. package/dist/packem_shared/{PACKAGE_SECRETS_REGISTRY-CYrVk48t.mjs → PACKAGE_SECRETS_REGISTRY-De7gLGIy.mjs} +1 -1
  14. package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-0QiGKazX.mjs +1 -0
  15. package/dist/packem_shared/{REQUIRED_COMPATIBILITY_DATE-iWKnSx2C.mjs → REQUIRED_COMPATIBILITY_DATE-vJI8hq20.mjs} +1 -1
  16. package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-Dbt0faMd.mjs +1 -0
  17. package/dist/packem_shared/addArgsFor-CWb4cPij.mjs +1 -0
  18. package/dist/packem_shared/{buildPackageSecretsBlock-8PWr25wv.mjs → buildPackageSecretsBlock-yv9mjKEW.mjs} +1 -1
  19. package/dist/packem_shared/collectExportGaps-BtNtwL7x.mjs +1 -0
  20. package/dist/packem_shared/{collectWranglerSecretVariables-DSTHPYsC.mjs → collectWranglerSecretVariables-D-usPfT8.mjs} +1 -1
  21. package/dist/packem_shared/package-secrets-registry-DvtTiK4b.mjs +1 -0
  22. package/dist/packem_shared/{runPostCodegenHook-BF3XTBFz.mjs → runPostCodegenHook-CVrOTiGB.mjs} +1 -1
  23. package/dist/packem_shared/{schema-info.d-BRnrGpR1.d.ts → schema-info.d-C0DbTKbx.d.mts} +27 -120
  24. package/dist/packem_shared/{schema-info.d-BRnrGpR1.d.mts → schema-info.d-C0DbTKbx.d.ts} +27 -120
  25. package/dist/packem_shared/wranglerToAlchemy-SDoS_XY0.mjs +6 -0
  26. package/dist/packem_shared/write-atomic-9d9xs5ON.mjs +1 -0
  27. package/dist/studio-host/index.mjs +1 -1
  28. package/package.json +5 -5
  29. package/dist/packem_shared/AGENT_RULES_DIR-3-Sx1gHU.mjs +0 -1
  30. package/dist/packem_shared/CLOUDFLARE_DRIVER-CoS6u6zD.mjs +0 -1
  31. package/dist/packem_shared/COMPOSED_WORKER_ENTRY-CAPCs3GJ.mjs +0 -1
  32. package/dist/packem_shared/DEFAULT_DEPLOY_TARGET-De4Ps8C8.mjs +0 -1
  33. package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-DL4UFAeK.mjs +0 -1
  34. package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-IkAx-ScX.mjs +0 -1
  35. package/dist/packem_shared/addArgsFor-B4D4zvM0.mjs +0 -1
  36. package/dist/packem_shared/cloudflare-driver-CWf_lB-q.mjs +0 -1
  37. package/dist/packem_shared/collectExportGaps-CHgJxlgR.mjs +0 -1
  38. package/dist/packem_shared/package-secrets-registry-CFZ5bA8L.mjs +0 -1
  39. package/dist/packem_shared/wranglerToAlchemy-CX9nCwtu.mjs +0 -6
  40. package/dist/packem_shared/write-atomic-D88PwWJc.mjs +0 -1
@@ -1,4 +1,4 @@
1
- import { D as DeployDriver, I as InferredBindings, S as SchemaInfo } from "../packem_shared/schema-info.d-BRnrGpR1.mjs";
1
+ import { D as DeployDriver, I as InferredBindings, S as SchemaInfo } from "../packem_shared/schema-info.d-C0DbTKbx.mjs";
2
2
  import { WranglerVariableIR } from '@lunora/codegen';
3
3
  /**
4
4
  * Translate a `wrangler.jsonc` into an [Alchemy](https://alchemy.run) program.
@@ -65,7 +65,11 @@ interface WranglerConfigShape {
65
65
  new_sqlite_classes?: ReadonlyArray<string>;
66
66
  }>;
67
67
  name?: string;
68
+ /** Only `producers` translate; a `consumers` entry is dropped and reported as `queues.consumers`. */
68
69
  queues?: {
70
+ consumers?: ReadonlyArray<{
71
+ queue?: string;
72
+ }>;
69
73
  producers?: ReadonlyArray<{
70
74
  binding?: string;
71
75
  queue?: string;
@@ -832,10 +836,10 @@ export { type AlchemyTranslation, BINDING_MANIFEST_VERSION,
832
836
  * `DeployDriver` that ties them together for `--target cloudflare`.
833
837
  *
834
838
  * Split out from the package root so `@lunora/config` itself stays
835
- * provider-neutral. The root keeps what any target needs — the `ResourceGraph`
836
- * and `DeployDriver` contracts, the driver registry, project config and target
837
- * resolution, `.dev.vars` grammar, binding *inference* — while emission and
838
- * validation, which are wrangler-shaped by definition, live behind this subpath.
839
+ * provider-neutral. The root keeps what any target needs — the `DeployDriver`
840
+ * contract, the driver registry, project config and target resolution,
841
+ * `.dev.vars` grammar, binding *inference* — while emission and validation,
842
+ * which are wrangler-shaped by definition, live behind this subpath.
839
843
  * Plan 114 §5.3 (D6): a package carrying real provider code isolates it behind a
840
844
  * subpath rather than relocating wholesale.
841
845
  */
@@ -848,10 +852,10 @@ type BindingManifest,
848
852
  * `DeployDriver` that ties them together for `--target cloudflare`.
849
853
  *
850
854
  * Split out from the package root so `@lunora/config` itself stays
851
- * provider-neutral. The root keeps what any target needs — the `ResourceGraph`
852
- * and `DeployDriver` contracts, the driver registry, project config and target
853
- * resolution, `.dev.vars` grammar, binding *inference* — while emission and
854
- * validation, which are wrangler-shaped by definition, live behind this subpath.
855
+ * provider-neutral. The root keeps what any target needs — the `DeployDriver`
856
+ * contract, the driver registry, project config and target resolution,
857
+ * `.dev.vars` grammar, binding *inference* — while emission and validation,
858
+ * which are wrangler-shaped by definition, live behind this subpath.
855
859
  * Plan 114 §5.3 (D6): a package carrying real provider code isolates it behind a
856
860
  * subpath rather than relocating wholesale.
857
861
  */
@@ -864,10 +868,10 @@ type BindingRequirement, CLOUDFLARE_DRIVER, type ExportGap,
864
868
  * `DeployDriver` that ties them together for `--target cloudflare`.
865
869
  *
866
870
  * Split out from the package root so `@lunora/config` itself stays
867
- * provider-neutral. The root keeps what any target needs — the `ResourceGraph`
868
- * and `DeployDriver` contracts, the driver registry, project config and target
869
- * resolution, `.dev.vars` grammar, binding *inference* — while emission and
870
- * validation, which are wrangler-shaped by definition, live behind this subpath.
871
+ * provider-neutral. The root keeps what any target needs — the `DeployDriver`
872
+ * contract, the driver registry, project config and target resolution,
873
+ * `.dev.vars` grammar, binding *inference* — while emission and validation,
874
+ * which are wrangler-shaped by definition, live behind this subpath.
871
875
  * Plan 114 §5.3 (D6): a package carrying real provider code isolates it behind a
872
876
  * subpath rather than relocating wholesale.
873
877
  */
@@ -1,4 +1,4 @@
1
- import { D as DeployDriver, I as InferredBindings, S as SchemaInfo } from "../packem_shared/schema-info.d-BRnrGpR1.js";
1
+ import { D as DeployDriver, I as InferredBindings, S as SchemaInfo } from "../packem_shared/schema-info.d-C0DbTKbx.js";
2
2
  import { WranglerVariableIR } from '@lunora/codegen';
3
3
  /**
4
4
  * Translate a `wrangler.jsonc` into an [Alchemy](https://alchemy.run) program.
@@ -65,7 +65,11 @@ interface WranglerConfigShape {
65
65
  new_sqlite_classes?: ReadonlyArray<string>;
66
66
  }>;
67
67
  name?: string;
68
+ /** Only `producers` translate; a `consumers` entry is dropped and reported as `queues.consumers`. */
68
69
  queues?: {
70
+ consumers?: ReadonlyArray<{
71
+ queue?: string;
72
+ }>;
69
73
  producers?: ReadonlyArray<{
70
74
  binding?: string;
71
75
  queue?: string;
@@ -832,10 +836,10 @@ export { type AlchemyTranslation, BINDING_MANIFEST_VERSION,
832
836
  * `DeployDriver` that ties them together for `--target cloudflare`.
833
837
  *
834
838
  * Split out from the package root so `@lunora/config` itself stays
835
- * provider-neutral. The root keeps what any target needs — the `ResourceGraph`
836
- * and `DeployDriver` contracts, the driver registry, project config and target
837
- * resolution, `.dev.vars` grammar, binding *inference* — while emission and
838
- * validation, which are wrangler-shaped by definition, live behind this subpath.
839
+ * provider-neutral. The root keeps what any target needs — the `DeployDriver`
840
+ * contract, the driver registry, project config and target resolution,
841
+ * `.dev.vars` grammar, binding *inference* — while emission and validation,
842
+ * which are wrangler-shaped by definition, live behind this subpath.
839
843
  * Plan 114 §5.3 (D6): a package carrying real provider code isolates it behind a
840
844
  * subpath rather than relocating wholesale.
841
845
  */
@@ -848,10 +852,10 @@ type BindingManifest,
848
852
  * `DeployDriver` that ties them together for `--target cloudflare`.
849
853
  *
850
854
  * Split out from the package root so `@lunora/config` itself stays
851
- * provider-neutral. The root keeps what any target needs — the `ResourceGraph`
852
- * and `DeployDriver` contracts, the driver registry, project config and target
853
- * resolution, `.dev.vars` grammar, binding *inference* — while emission and
854
- * validation, which are wrangler-shaped by definition, live behind this subpath.
855
+ * provider-neutral. The root keeps what any target needs — the `DeployDriver`
856
+ * contract, the driver registry, project config and target resolution,
857
+ * `.dev.vars` grammar, binding *inference* — while emission and validation,
858
+ * which are wrangler-shaped by definition, live behind this subpath.
855
859
  * Plan 114 §5.3 (D6): a package carrying real provider code isolates it behind a
856
860
  * subpath rather than relocating wholesale.
857
861
  */
@@ -864,10 +868,10 @@ type BindingRequirement, CLOUDFLARE_DRIVER, type ExportGap,
864
868
  * `DeployDriver` that ties them together for `--target cloudflare`.
865
869
  *
866
870
  * Split out from the package root so `@lunora/config` itself stays
867
- * provider-neutral. The root keeps what any target needs — the `ResourceGraph`
868
- * and `DeployDriver` contracts, the driver registry, project config and target
869
- * resolution, `.dev.vars` grammar, binding *inference* — while emission and
870
- * validation, which are wrangler-shaped by definition, live behind this subpath.
871
+ * provider-neutral. The root keeps what any target needs — the `DeployDriver`
872
+ * contract, the driver registry, project config and target resolution,
873
+ * `.dev.vars` grammar, binding *inference* — while emission and validation,
874
+ * which are wrangler-shaped by definition, live behind this subpath.
871
875
  * Plan 114 §5.3 (D6): a package carrying real provider code isolates it behind a
872
876
  * subpath rather than relocating wholesale.
873
877
  */
@@ -1 +1 @@
1
- import{BINDING_MANIFEST_VERSION as o,buildBindingManifest as a}from"../packem_shared/BINDING_MANIFEST_VERSION-Cd00jVOf.mjs";import{C as l}from"../packem_shared/cloudflare-driver-CWf_lB-q.mjs";import{collectExportGaps as i,reconcileWranglerBindings as E}from"../packem_shared/collectExportGaps-CHgJxlgR.mjs";import{reconcileWranglerCompatibilityDate as g}from"../packem_shared/reconcileWranglerCompatibilityDate-7OO_xaKR.mjs";import{reconcileWranglerCrons as R}from"../packem_shared/reconcileWranglerCrons-COMb6ICf.mjs";import{REMOTE_ELIGIBLE_KEYS as f,injectRemoteFlags as p,isRemoteEnvEnabled as I,materializeRemoteWranglerConfig as W,planRemoteBindings as d,resolveRemoteEnabled as x}from"../packem_shared/REMOTE_ELIGIBLE_KEYS-D-edJjVY.mjs";import{WORKERS_CACHE_MIN_DATE as C,isCacheEnabled as A}from"../packem_shared/WORKERS_CACHE_MIN_DATE-0k9ABJtF.mjs";import{WRANGLER_FILES as L,findWranglerFile as T,readWranglerJsonc as b}from"../packem_shared/WRANGLER_FILES-UNW-xY5u.mjs";import{collectWranglerSecretVariables as S,scanWranglerVariablesForSecrets as v}from"../packem_shared/collectWranglerSecretVariables-DSTHPYsC.mjs";import{wranglerToAlchemy as N}from"../packem_shared/wranglerToAlchemy-CX9nCwtu.mjs";import{REQUIRED_COMPATIBILITY_DATE as M,REQUIRED_FLAG as O,mergeWranglerEnvironment as V,validateWrangler as h,validateWranglerConfig as U,validateWranglerProject as j,withTailConsumer as u}from"../packem_shared/REQUIRED_COMPATIBILITY_DATE-iWKnSx2C.mjs";export{o as BINDING_MANIFEST_VERSION,l as CLOUDFLARE_DRIVER,f as REMOTE_ELIGIBLE_KEYS,M as REQUIRED_COMPATIBILITY_DATE,O as REQUIRED_FLAG,C as WORKERS_CACHE_MIN_DATE,L as WRANGLER_FILES,a as buildBindingManifest,i as collectExportGaps,S as collectWranglerSecretVariables,T as findWranglerFile,p as injectRemoteFlags,A as isCacheEnabled,I as isRemoteEnvEnabled,W as materializeRemoteWranglerConfig,V as mergeWranglerEnvironment,d as planRemoteBindings,b as readWranglerJsonc,E as reconcileWranglerBindings,g as reconcileWranglerCompatibilityDate,R as reconcileWranglerCrons,x as resolveRemoteEnabled,v as scanWranglerVariablesForSecrets,h as validateWrangler,U as validateWranglerConfig,j as validateWranglerProject,u as withTailConsumer,N as wranglerToAlchemy};
1
+ import{BINDING_MANIFEST_VERSION as o,buildBindingManifest as a}from"../packem_shared/BINDING_MANIFEST_VERSION-B8dwEKLn.mjs";import{default as l}from"../packem_shared/CLOUDFLARE_DRIVER-Ci9oJMYb.mjs";import{collectExportGaps as i,reconcileWranglerBindings as E}from"../packem_shared/collectExportGaps-BtNtwL7x.mjs";import{reconcileWranglerCompatibilityDate as g}from"../packem_shared/reconcileWranglerCompatibilityDate-7OO_xaKR.mjs";import{reconcileWranglerCrons as R}from"../packem_shared/reconcileWranglerCrons-COMb6ICf.mjs";import{REMOTE_ELIGIBLE_KEYS as s,injectRemoteFlags as p,isRemoteEnvEnabled as I,materializeRemoteWranglerConfig as W,planRemoteBindings as d,resolveRemoteEnabled as x}from"../packem_shared/REMOTE_ELIGIBLE_KEYS-D-edJjVY.mjs";import{WORKERS_CACHE_MIN_DATE as C,isCacheEnabled as A}from"../packem_shared/WORKERS_CACHE_MIN_DATE-0k9ABJtF.mjs";import{WRANGLER_FILES as L,findWranglerFile as T,readWranglerJsonc as b}from"../packem_shared/WRANGLER_FILES-UNW-xY5u.mjs";import{collectWranglerSecretVariables as S,scanWranglerVariablesForSecrets as v}from"../packem_shared/collectWranglerSecretVariables-D-usPfT8.mjs";import{wranglerToAlchemy as N}from"../packem_shared/wranglerToAlchemy-SDoS_XY0.mjs";import{REQUIRED_COMPATIBILITY_DATE as M,REQUIRED_FLAG as O,mergeWranglerEnvironment as V,validateWrangler as h,validateWranglerConfig as u,validateWranglerProject as U,withTailConsumer as j}from"../packem_shared/REQUIRED_COMPATIBILITY_DATE-vJI8hq20.mjs";export{o as BINDING_MANIFEST_VERSION,l as CLOUDFLARE_DRIVER,s as REMOTE_ELIGIBLE_KEYS,M as REQUIRED_COMPATIBILITY_DATE,O as REQUIRED_FLAG,C as WORKERS_CACHE_MIN_DATE,L as WRANGLER_FILES,a as buildBindingManifest,i as collectExportGaps,S as collectWranglerSecretVariables,T as findWranglerFile,p as injectRemoteFlags,A as isCacheEnabled,I as isRemoteEnvEnabled,W as materializeRemoteWranglerConfig,V as mergeWranglerEnvironment,d as planRemoteBindings,b as readWranglerJsonc,E as reconcileWranglerBindings,g as reconcileWranglerCompatibilityDate,R as reconcileWranglerCrons,x as resolveRemoteEnabled,v as scanWranglerVariablesForSecrets,h as validateWrangler,u as validateWranglerConfig,U as validateWranglerProject,j as withTailConsumer,N as wranglerToAlchemy};
package/dist/index.d.mts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { AgentIR, ContainerIR, WorkflowIR } from '@lunora/codegen';
2
2
  export type { AgentIR, ContainerIR, WorkflowIR } from '@lunora/codegen';
3
3
  import { Writable } from 'node:stream';
4
- import { D as DeployDriver } from "./packem_shared/schema-info.d-BRnrGpR1.mjs";
5
- export { C as COMPOSED_WORKER_ENTRY, type a as DeployRequest, type b as DevRequest, type c as DiscoverSchemaInfoResult, type d as DriverContext, type e as DriverToolchain, type f as InferOptions, type g as InferredAgent, type I as InferredBindings, type h as InferredContainer, type i as InferredWorkflow, type N as NamedResource, type P as ProvisionResult, type R as ResourceGraph, type S as SchemaInfo, type j as SecretRequest, type k as ShardNamespaceResource, type T as TailRequest, type l as ToolchainCommand, m as discoverSchemaInfo, n as inferLunoraBindings, p as packageNamesFromBindings } from "./packem_shared/schema-info.d-BRnrGpR1.mjs";
4
+ import { D as DeployDriver } from "./packem_shared/schema-info.d-C0DbTKbx.mjs";
5
+ export { C as COMPOSED_WORKER_ENTRY, type a as DeployRequest, type b as DevRequest, type c as DiscoverSchemaInfoResult, type d as DriverToolchain, type e as InferOptions, type f as InferredAgent, type I as InferredBindings, type g as InferredContainer, type h as InferredWorkflow, type S as SchemaInfo, type i as SecretRequest, type T as TailRequest, type j as ToolchainCommand, k as discoverSchemaInfo, l as inferLunoraBindings, p as packageNamesFromBindings } from "./packem_shared/schema-info.d-C0DbTKbx.mjs";
6
6
  export { type A as AdditivePolicyEdit, type D as DestructivePolicyEdit, type P as PolicyEdit, type a as PolicyScaffoldFailureReason, type b as ScaffoldFileResult, type S as ScaffoldPolicyEdit, type c as WireResult, type W as WireRlsEdit, d as classifyPolicyEdit, r as resolveServerModule, s as scaffoldPolicyFile, w as wireRlsIntoProcedure } from "./packem_shared/policy-scaffold.d-D2H4_G01.mjs";
7
7
  interface DiscoverAgentInfoResult {
8
8
  /** Discovered agent definitions; `[]` when none are declared or parsing failed. */
@@ -74,6 +74,12 @@ declare const AGENT_RULES_HINT_ENV = "LUNORA_RULES_HINT_SHOWN";
74
74
  * The Lunora agent skills shipped by `@lunora/cli`. The first entry (`lunora`)
75
75
  * is the router skill — its presence is what {@link detectAgentRules} treats as
76
76
  * "rules installed", since every other skill is reachable through it.
77
+ *
78
+ * `lunora rules install` enumerates `@lunora/cli`'s `skills/` directory rather
79
+ * than reading this list, so a skill missing here still installs — but
80
+ * `lunora rules check` counts against it, and reported "9/9 skills" with an
81
+ * empty "Missing:" line for a project holding all 14. The CLI's rules test
82
+ * pins the two together, since this package cannot see that directory.
77
83
  */
78
84
  declare const LUNORA_SKILL_NAMES: ReadonlyArray<string>;
79
85
  /** The router skill whose presence marks the rule set as installed. */
@@ -1055,11 +1061,13 @@ interface DevSecretsFillPlan {
1055
1061
  }
1056
1062
  /**
1057
1063
  * Plan the in-place generation of dev secrets for a `.dev.vars`. First, every
1058
- * line whose KEY looks like a secret (`*_SECRET`, `*_TOKEN`, `*_KEY`,
1059
- * `*_PASSWORD`) and whose value is empty or a placeholder gets a freshly
1060
- * generated value so a `lunora add`-scaffolded `.dev.vars` (which writes each
1061
- * secret blank) becomes usable on `lunora dev` / `vite dev` without the user
1062
- * running `openssl` by hand. Second, any {@link CORE_SECRETS} key absent from
1064
+ * line whose key is {@link isMintableSecretKey mintable} registry membership,
1065
+ * NOT the key's name shape — and whose value is empty or a placeholder gets a
1066
+ * freshly generated value, so a `lunora add`-scaffolded `.dev.vars` (which
1067
+ * writes each secret blank) becomes usable on `lunora dev` / `vite dev` without
1068
+ * the user running `openssl` by hand. A provider-issued key (`OPENAI_API_KEY`,
1069
+ * `STRIPE_SECRET_KEY`) is left verbatim so `lunora env doctor` can still report
1070
+ * it as unfilled. Second, any {@link CORE_SECRETS} key absent from
1063
1071
  * the file is appended (generated) — notably `LUNORA_ADMIN_TOKEN`, which the
1064
1072
  * local Studio needs to call the worker's admin gate in dev (without it the
1065
1073
  * Studio shows its login gate).
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { AgentIR, ContainerIR, WorkflowIR } from '@lunora/codegen';
2
2
  export type { AgentIR, ContainerIR, WorkflowIR } from '@lunora/codegen';
3
3
  import { Writable } from 'node:stream';
4
- import { D as DeployDriver } from "./packem_shared/schema-info.d-BRnrGpR1.js";
5
- export { C as COMPOSED_WORKER_ENTRY, type a as DeployRequest, type b as DevRequest, type c as DiscoverSchemaInfoResult, type d as DriverContext, type e as DriverToolchain, type f as InferOptions, type g as InferredAgent, type I as InferredBindings, type h as InferredContainer, type i as InferredWorkflow, type N as NamedResource, type P as ProvisionResult, type R as ResourceGraph, type S as SchemaInfo, type j as SecretRequest, type k as ShardNamespaceResource, type T as TailRequest, type l as ToolchainCommand, m as discoverSchemaInfo, n as inferLunoraBindings, p as packageNamesFromBindings } from "./packem_shared/schema-info.d-BRnrGpR1.js";
4
+ import { D as DeployDriver } from "./packem_shared/schema-info.d-C0DbTKbx.js";
5
+ export { C as COMPOSED_WORKER_ENTRY, type a as DeployRequest, type b as DevRequest, type c as DiscoverSchemaInfoResult, type d as DriverToolchain, type e as InferOptions, type f as InferredAgent, type I as InferredBindings, type g as InferredContainer, type h as InferredWorkflow, type S as SchemaInfo, type i as SecretRequest, type T as TailRequest, type j as ToolchainCommand, k as discoverSchemaInfo, l as inferLunoraBindings, p as packageNamesFromBindings } from "./packem_shared/schema-info.d-C0DbTKbx.js";
6
6
  export { type A as AdditivePolicyEdit, type D as DestructivePolicyEdit, type P as PolicyEdit, type a as PolicyScaffoldFailureReason, type b as ScaffoldFileResult, type S as ScaffoldPolicyEdit, type c as WireResult, type W as WireRlsEdit, d as classifyPolicyEdit, r as resolveServerModule, s as scaffoldPolicyFile, w as wireRlsIntoProcedure } from "./packem_shared/policy-scaffold.d-D2H4_G01.js";
7
7
  interface DiscoverAgentInfoResult {
8
8
  /** Discovered agent definitions; `[]` when none are declared or parsing failed. */
@@ -74,6 +74,12 @@ declare const AGENT_RULES_HINT_ENV = "LUNORA_RULES_HINT_SHOWN";
74
74
  * The Lunora agent skills shipped by `@lunora/cli`. The first entry (`lunora`)
75
75
  * is the router skill — its presence is what {@link detectAgentRules} treats as
76
76
  * "rules installed", since every other skill is reachable through it.
77
+ *
78
+ * `lunora rules install` enumerates `@lunora/cli`'s `skills/` directory rather
79
+ * than reading this list, so a skill missing here still installs — but
80
+ * `lunora rules check` counts against it, and reported "9/9 skills" with an
81
+ * empty "Missing:" line for a project holding all 14. The CLI's rules test
82
+ * pins the two together, since this package cannot see that directory.
77
83
  */
78
84
  declare const LUNORA_SKILL_NAMES: ReadonlyArray<string>;
79
85
  /** The router skill whose presence marks the rule set as installed. */
@@ -1055,11 +1061,13 @@ interface DevSecretsFillPlan {
1055
1061
  }
1056
1062
  /**
1057
1063
  * Plan the in-place generation of dev secrets for a `.dev.vars`. First, every
1058
- * line whose KEY looks like a secret (`*_SECRET`, `*_TOKEN`, `*_KEY`,
1059
- * `*_PASSWORD`) and whose value is empty or a placeholder gets a freshly
1060
- * generated value so a `lunora add`-scaffolded `.dev.vars` (which writes each
1061
- * secret blank) becomes usable on `lunora dev` / `vite dev` without the user
1062
- * running `openssl` by hand. Second, any {@link CORE_SECRETS} key absent from
1064
+ * line whose key is {@link isMintableSecretKey mintable} registry membership,
1065
+ * NOT the key's name shape — and whose value is empty or a placeholder gets a
1066
+ * freshly generated value, so a `lunora add`-scaffolded `.dev.vars` (which
1067
+ * writes each secret blank) becomes usable on `lunora dev` / `vite dev` without
1068
+ * the user running `openssl` by hand. A provider-issued key (`OPENAI_API_KEY`,
1069
+ * `STRIPE_SECRET_KEY`) is left verbatim so `lunora env doctor` can still report
1070
+ * it as unfilled. Second, any {@link CORE_SECRETS} key absent from
1063
1071
  * the file is appended (generated) — notably `LUNORA_ADMIN_TOKEN`, which the
1064
1072
  * local Studio needs to call the worker's admin gate in dev (without it the
1065
1073
  * Studio shows its login gate).
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{AGENT_MODE_ENV as o,detectAiAgent as t}from"./packem_shared/AGENT_MODE_ENV-D8MvSwPE.mjs";import{discoverAgentInfo as E}from"./packem_shared/discoverAgentInfo-CTdCSfYM.mjs";import{AGENT_RULES_DIR as i,AGENT_RULES_HINT as l,AGENT_RULES_HINT_ENV as n,LUNORA_SKILL_NAMES as p,ROOT_SKILL_NAME as _,claimAgentRulesHint as c,detectAgentRules as d}from"./packem_shared/AGENT_RULES_DIR-3-Sx1gHU.mjs";import{CODEGEN_ENV as A,isCodegenDisabled as D}from"./packem_shared/CODEGEN_ENV-ZsCxV1kP.mjs";import{discoverContainerInfo as f}from"./packem_shared/discoverContainerInfo-EhZtEBQs.mjs";import{streamContainerLogs as L}from"./packem_shared/streamContainerLogs-0nko1qpv.mjs";import{detectFramework as R,projectUsesUmbrella as T,readProjectDependencyNames as I}from"./packem_shared/detectFramework-CUiVEHDQ.mjs";import{DEV_BINDINGS_FILE as x,DEV_DAEMON_ENV as V,DEV_HANDOFF_ENV as P,DEV_LOG_FILE as u,DEV_LOG_FILE_ENV as F,DEV_STATE_DIR as O,DEV_STATE_FILE as C,claimDevServerState as G,clearDevServerState as U,isDevServerReady as b,isProcessAlive as M,isRecordedProcessCurrent as y,readDevServerState as k,readLiveDevServerState as B,updateDevServerState as w,writeDevServerState as K}from"./packem_shared/DEV_BINDINGS_FILE-pyOiNLP4.mjs";import{DEV_VARS_EXAMPLE_FILE as H,DEV_VARS_FILE as Y,DEV_VARS_KEY_PATTERN as h,escapeRegExp as W,parseDevVariableEntries as J,removeDevVariableLine as q,upsertDevVariableLine as X}from"./packem_shared/DEV_VARS_EXAMPLE_FILE-CqLorAxT.mjs";import{DEFAULT_DEPLOY_TARGET as Q,deployTargetIds as Z,isRunnableTarget as $,resolveDeployDriver as ee,runnableTargetIds as re}from"./packem_shared/DEFAULT_DEPLOY_TARGET-De4Ps8C8.mjs";import{COMPOSED_WORKER_ENTRY as te,inferLunoraBindings as ae,packageNamesFromBindings as Ee}from"./packem_shared/COMPOSED_WORKER_ENTRY-CAPCs3GJ.mjs";import{LINKED_PROJECT_DIR as ie,LINKED_PROJECT_FILE as le,readLinkedProject as ne,writeLinkedProject as pe}from"./packem_shared/LINKED_PROJECT_DIR-Ba5qPEwo.mjs";import{LUNORA_IGNORED_PATHS as ce,applyLintIgnores as de,detectLintTools as me}from"./packem_shared/LUNORA_IGNORED_PATHS-BHABA9u-.mjs";import{LUNORA_EVENT_SOURCE as De,formatLunoraEvent as Se}from"./packem_shared/LUNORA_EVENT_SOURCE-DYdcDU9G.mjs";import{default as Ne}from"./packem_shared/LunoraReporter-f277GLNT.mjs";import{addArgsFor as ve,detectInstalledManagers as Re,detectPackageManager as Te,execArgsFor as Ie,installArgsFor as ge,runScriptArgsFor as xe,runScriptCommand as Ve}from"./packem_shared/addArgsFor-B4D4zvM0.mjs";import{P as ue,s as Fe}from"./packem_shared/package-secrets-registry-CFZ5bA8L.mjs";import{runPostCodegenHook as Ce}from"./packem_shared/runPostCodegenHook-BF3XTBFz.mjs";import{LUNORA_CONFIG_FILE as Ue,interpretRemote as be,readProjectRemotePreference as Me,readProjectTarget as ye,resolveProjectTarget as ke,resolveTargetOrThrow as Be}from"./packem_shared/LUNORA_CONFIG_FILE-DFoqHCyP.mjs";import{createConfirm as Ke,isInteractive as je,promptMultiSelect as He,promptSelect as Ye,promptText as he,promptYesNo as We}from"./packem_shared/createConfirm-D5mKTMHj.mjs";import{buildPackageSecretsBlock as qe,ensureDevVariables as Xe,ensureDevVarsExample as ze,fillDevSecrets as Qe,generateSecretValue as Ze,isMintableSecretKey as $e,isPlaceholderValue as er,planDevSecretsFill as rr,planDevVariablesAugment as or,planDevVariablesScaffold as tr,requiredSecrets as ar,writeDevVariablesFileAtomically as Er}from"./packem_shared/buildPackageSecretsBlock-8PWr25wv.mjs";import{applyAdditiveEdit as ir,classifyEdit as lr}from"./packem_shared/applyAdditiveEdit-CH0VhMJ2.mjs";import{parseSchema as pr}from"./packem_shared/parseSchema-D1Wbr1qv.mjs";import{classifyPolicyEdit as cr,resolveServerModule as dr,scaffoldPolicyFile as mr,wireRlsIntoProcedure as Ar}from"./packem_shared/classifyPolicyEdit-D8NwrHxR.mjs";import{discoverSchemaInfo as Sr}from"./packem_shared/discoverSchemaInfo-Bg2CUZXG.mjs";import{ACCENT as Nr,BADGES as Lr,BADGE_COLUMN_WIDTH as vr,LUNA_ART as Rr,LUNA_BUNNY as Tr,LUNA_NAME as Ir,LUNA_SIGNOFF as gr,STEP_BADGE_NAMES as xr,badgeLead as Vr,badgeWidth as Pr,padBadge as ur,paintAnswer as Fr,paintBadge as Or}from"./packem_shared/ACCENT-CotPTfv7.mjs";import{discoverWorkflowInfo as Gr}from"./packem_shared/discoverWorkflowInfo-BsPvlo6O.mjs";export{Nr as ACCENT,o as AGENT_MODE_ENV,i as AGENT_RULES_DIR,l as AGENT_RULES_HINT,n as AGENT_RULES_HINT_ENV,Lr as BADGES,vr as BADGE_COLUMN_WIDTH,A as CODEGEN_ENV,te as COMPOSED_WORKER_ENTRY,Q as DEFAULT_DEPLOY_TARGET,x as DEV_BINDINGS_FILE,V as DEV_DAEMON_ENV,P as DEV_HANDOFF_ENV,u as DEV_LOG_FILE,F as DEV_LOG_FILE_ENV,O as DEV_STATE_DIR,C as DEV_STATE_FILE,H as DEV_VARS_EXAMPLE_FILE,Y as DEV_VARS_FILE,h as DEV_VARS_KEY_PATTERN,ie as LINKED_PROJECT_DIR,le as LINKED_PROJECT_FILE,Rr as LUNA_ART,Tr as LUNA_BUNNY,Ir as LUNA_NAME,gr as LUNA_SIGNOFF,Ue as LUNORA_CONFIG_FILE,De as LUNORA_EVENT_SOURCE,ce as LUNORA_IGNORED_PATHS,p as LUNORA_SKILL_NAMES,Ne as LunoraReporter,ue as PACKAGE_SECRETS_REGISTRY,_ as ROOT_SKILL_NAME,xr as STEP_BADGE_NAMES,ve as addArgsFor,ir as applyAdditiveEdit,de as applyLintIgnores,Vr as badgeLead,Pr as badgeWidth,qe as buildPackageSecretsBlock,c as claimAgentRulesHint,G as claimDevServerState,lr as classifyEdit,cr as classifyPolicyEdit,U as clearDevServerState,Ke as createConfirm,Z as deployTargetIds,d as detectAgentRules,t as detectAiAgent,R as detectFramework,Re as detectInstalledManagers,me as detectLintTools,Te as detectPackageManager,E as discoverAgentInfo,f as discoverContainerInfo,Sr as discoverSchemaInfo,Gr as discoverWorkflowInfo,Xe as ensureDevVariables,ze as ensureDevVarsExample,W as escapeRegExp,Ie as execArgsFor,Qe as fillDevSecrets,Se as formatLunoraEvent,Ze as generateSecretValue,ae as inferLunoraBindings,ge as installArgsFor,be as interpretRemote,D as isCodegenDisabled,b as isDevServerReady,je as isInteractive,$e as isMintableSecretKey,er as isPlaceholderValue,M as isProcessAlive,y as isRecordedProcessCurrent,$ as isRunnableTarget,Ee as packageNamesFromBindings,ur as padBadge,Fr as paintAnswer,Or as paintBadge,J as parseDevVariableEntries,pr as parseSchema,rr as planDevSecretsFill,or as planDevVariablesAugment,tr as planDevVariablesScaffold,T as projectUsesUmbrella,He as promptMultiSelect,Ye as promptSelect,he as promptText,We as promptYesNo,k as readDevServerState,ne as readLinkedProject,B as readLiveDevServerState,I as readProjectDependencyNames,Me as readProjectRemotePreference,ye as readProjectTarget,q as removeDevVariableLine,ar as requiredSecrets,ee as resolveDeployDriver,ke as resolveProjectTarget,dr as resolveServerModule,Be as resolveTargetOrThrow,Ce as runPostCodegenHook,xe as runScriptArgsFor,Ve as runScriptCommand,re as runnableTargetIds,mr as scaffoldPolicyFile,Fe as secretsForPackages,L as streamContainerLogs,w as updateDevServerState,X as upsertDevVariableLine,Ar as wireRlsIntoProcedure,K as writeDevServerState,Er as writeDevVariablesFileAtomically,pe as writeLinkedProject};
1
+ import{AGENT_MODE_ENV as o,detectAiAgent as t}from"./packem_shared/AGENT_MODE_ENV-D8MvSwPE.mjs";import{discoverAgentInfo as E}from"./packem_shared/discoverAgentInfo-CTdCSfYM.mjs";import{AGENT_RULES_DIR as i,AGENT_RULES_HINT as l,AGENT_RULES_HINT_ENV as n,LUNORA_SKILL_NAMES as p,ROOT_SKILL_NAME as _,claimAgentRulesHint as c,detectAgentRules as d}from"./packem_shared/AGENT_RULES_DIR-C54Ta_vz.mjs";import{CODEGEN_ENV as A,isCodegenDisabled as D}from"./packem_shared/CODEGEN_ENV-ZsCxV1kP.mjs";import{discoverContainerInfo as f}from"./packem_shared/discoverContainerInfo-EhZtEBQs.mjs";import{streamContainerLogs as L}from"./packem_shared/streamContainerLogs-0nko1qpv.mjs";import{detectFramework as R,projectUsesUmbrella as T,readProjectDependencyNames as I}from"./packem_shared/detectFramework-CUiVEHDQ.mjs";import{DEV_BINDINGS_FILE as x,DEV_DAEMON_ENV as V,DEV_HANDOFF_ENV as P,DEV_LOG_FILE as u,DEV_LOG_FILE_ENV as F,DEV_STATE_DIR as O,DEV_STATE_FILE as C,claimDevServerState as G,clearDevServerState as U,isDevServerReady as b,isProcessAlive as M,isRecordedProcessCurrent as y,readDevServerState as k,readLiveDevServerState as B,updateDevServerState as w,writeDevServerState as K}from"./packem_shared/DEV_BINDINGS_FILE-pyOiNLP4.mjs";import{DEV_VARS_EXAMPLE_FILE as H,DEV_VARS_FILE as Y,DEV_VARS_KEY_PATTERN as h,escapeRegExp as W,parseDevVariableEntries as J,removeDevVariableLine as q,upsertDevVariableLine as X}from"./packem_shared/DEV_VARS_EXAMPLE_FILE-CqLorAxT.mjs";import{DEFAULT_DEPLOY_TARGET as Q,deployTargetIds as Z,isRunnableTarget as $,resolveDeployDriver as ee,runnableTargetIds as re}from"./packem_shared/DEFAULT_DEPLOY_TARGET-B-e9mqgX.mjs";import{COMPOSED_WORKER_ENTRY as te,inferLunoraBindings as ae,packageNamesFromBindings as Ee}from"./packem_shared/COMPOSED_WORKER_ENTRY-CbtPPFQK.mjs";import{LINKED_PROJECT_DIR as ie,LINKED_PROJECT_FILE as le,readLinkedProject as ne,writeLinkedProject as pe}from"./packem_shared/LINKED_PROJECT_DIR-Ba5qPEwo.mjs";import{LUNORA_IGNORED_PATHS as ce,applyLintIgnores as de,detectLintTools as me}from"./packem_shared/LUNORA_IGNORED_PATHS-BHABA9u-.mjs";import{LUNORA_EVENT_SOURCE as De,formatLunoraEvent as Se}from"./packem_shared/LUNORA_EVENT_SOURCE-DYdcDU9G.mjs";import{default as Ne}from"./packem_shared/LunoraReporter-f277GLNT.mjs";import{addArgsFor as ve,detectInstalledManagers as Re,detectPackageManager as Te,execArgsFor as Ie,installArgsFor as ge,runScriptArgsFor as xe,runScriptCommand as Ve}from"./packem_shared/addArgsFor-CWb4cPij.mjs";import{P as ue,s as Fe}from"./packem_shared/package-secrets-registry-DvtTiK4b.mjs";import{runPostCodegenHook as Ce}from"./packem_shared/runPostCodegenHook-CVrOTiGB.mjs";import{LUNORA_CONFIG_FILE as Ue,interpretRemote as be,readProjectRemotePreference as Me,readProjectTarget as ye,resolveProjectTarget as ke,resolveTargetOrThrow as Be}from"./packem_shared/LUNORA_CONFIG_FILE-D0F9TWxc.mjs";import{createConfirm as Ke,isInteractive as je,promptMultiSelect as He,promptSelect as Ye,promptText as he,promptYesNo as We}from"./packem_shared/createConfirm-D5mKTMHj.mjs";import{buildPackageSecretsBlock as qe,ensureDevVariables as Xe,ensureDevVarsExample as ze,fillDevSecrets as Qe,generateSecretValue as Ze,isMintableSecretKey as $e,isPlaceholderValue as er,planDevSecretsFill as rr,planDevVariablesAugment as or,planDevVariablesScaffold as tr,requiredSecrets as ar,writeDevVariablesFileAtomically as Er}from"./packem_shared/buildPackageSecretsBlock-yv9mjKEW.mjs";import{applyAdditiveEdit as ir,classifyEdit as lr}from"./packem_shared/applyAdditiveEdit-CH0VhMJ2.mjs";import{parseSchema as pr}from"./packem_shared/parseSchema-D1Wbr1qv.mjs";import{classifyPolicyEdit as cr,resolveServerModule as dr,scaffoldPolicyFile as mr,wireRlsIntoProcedure as Ar}from"./packem_shared/classifyPolicyEdit-D8NwrHxR.mjs";import{discoverSchemaInfo as Sr}from"./packem_shared/discoverSchemaInfo-Bg2CUZXG.mjs";import{ACCENT as Nr,BADGES as Lr,BADGE_COLUMN_WIDTH as vr,LUNA_ART as Rr,LUNA_BUNNY as Tr,LUNA_NAME as Ir,LUNA_SIGNOFF as gr,STEP_BADGE_NAMES as xr,badgeLead as Vr,badgeWidth as Pr,padBadge as ur,paintAnswer as Fr,paintBadge as Or}from"./packem_shared/ACCENT-CotPTfv7.mjs";import{discoverWorkflowInfo as Gr}from"./packem_shared/discoverWorkflowInfo-BsPvlo6O.mjs";export{Nr as ACCENT,o as AGENT_MODE_ENV,i as AGENT_RULES_DIR,l as AGENT_RULES_HINT,n as AGENT_RULES_HINT_ENV,Lr as BADGES,vr as BADGE_COLUMN_WIDTH,A as CODEGEN_ENV,te as COMPOSED_WORKER_ENTRY,Q as DEFAULT_DEPLOY_TARGET,x as DEV_BINDINGS_FILE,V as DEV_DAEMON_ENV,P as DEV_HANDOFF_ENV,u as DEV_LOG_FILE,F as DEV_LOG_FILE_ENV,O as DEV_STATE_DIR,C as DEV_STATE_FILE,H as DEV_VARS_EXAMPLE_FILE,Y as DEV_VARS_FILE,h as DEV_VARS_KEY_PATTERN,ie as LINKED_PROJECT_DIR,le as LINKED_PROJECT_FILE,Rr as LUNA_ART,Tr as LUNA_BUNNY,Ir as LUNA_NAME,gr as LUNA_SIGNOFF,Ue as LUNORA_CONFIG_FILE,De as LUNORA_EVENT_SOURCE,ce as LUNORA_IGNORED_PATHS,p as LUNORA_SKILL_NAMES,Ne as LunoraReporter,ue as PACKAGE_SECRETS_REGISTRY,_ as ROOT_SKILL_NAME,xr as STEP_BADGE_NAMES,ve as addArgsFor,ir as applyAdditiveEdit,de as applyLintIgnores,Vr as badgeLead,Pr as badgeWidth,qe as buildPackageSecretsBlock,c as claimAgentRulesHint,G as claimDevServerState,lr as classifyEdit,cr as classifyPolicyEdit,U as clearDevServerState,Ke as createConfirm,Z as deployTargetIds,d as detectAgentRules,t as detectAiAgent,R as detectFramework,Re as detectInstalledManagers,me as detectLintTools,Te as detectPackageManager,E as discoverAgentInfo,f as discoverContainerInfo,Sr as discoverSchemaInfo,Gr as discoverWorkflowInfo,Xe as ensureDevVariables,ze as ensureDevVarsExample,W as escapeRegExp,Ie as execArgsFor,Qe as fillDevSecrets,Se as formatLunoraEvent,Ze as generateSecretValue,ae as inferLunoraBindings,ge as installArgsFor,be as interpretRemote,D as isCodegenDisabled,b as isDevServerReady,je as isInteractive,$e as isMintableSecretKey,er as isPlaceholderValue,M as isProcessAlive,y as isRecordedProcessCurrent,$ as isRunnableTarget,Ee as packageNamesFromBindings,ur as padBadge,Fr as paintAnswer,Or as paintBadge,J as parseDevVariableEntries,pr as parseSchema,rr as planDevSecretsFill,or as planDevVariablesAugment,tr as planDevVariablesScaffold,T as projectUsesUmbrella,He as promptMultiSelect,Ye as promptSelect,he as promptText,We as promptYesNo,k as readDevServerState,ne as readLinkedProject,B as readLiveDevServerState,I as readProjectDependencyNames,Me as readProjectRemotePreference,ye as readProjectTarget,q as removeDevVariableLine,ar as requiredSecrets,ee as resolveDeployDriver,ke as resolveProjectTarget,dr as resolveServerModule,Be as resolveTargetOrThrow,Ce as runPostCodegenHook,xe as runScriptArgsFor,Ve as runScriptCommand,re as runnableTargetIds,mr as scaffoldPolicyFile,Fe as secretsForPackages,L as streamContainerLogs,w as updateDevServerState,X as upsertDevVariableLine,Ar as wireRlsIntoProcedure,K as writeDevServerState,Er as writeDevVariablesFileAtomically,pe as writeLinkedProject};
@@ -0,0 +1 @@
1
+ import{existsSync as s}from"node:fs";import{join as l}from"node:path";const a=".agents/skills",t="LUNORA_RULES_HINT_SHOWN",i=["lunora","lunora-quickstart","lunora-functions","lunora-realtime","lunora-setup-auth","lunora-setup-hyperdrive","lunora-setup-hyperdrive-global","lunora-setup-mail","lunora-setup-scheduler","lunora-setup-storage","lunora-create-package","lunora-migration-helper","lunora-deploy","lunora-performance-audit"],c="lunora",_="Lunora AI rules not installed — run `lunora rules install` so your coding agent knows how to use Lunora.",m=()=>process.env[t]==="1"?!1:(process.env[t]="1",!0),u=(n,e)=>l(n,a,e,"SKILL.md"),N=n=>{const e=[],o=[];for(const r of i)s(u(n,r))?e.push(r):o.push(r);return{installed:s(u(n,c)),missing:o,present:e}};export{a as AGENT_RULES_DIR,_ as AGENT_RULES_HINT,t as AGENT_RULES_HINT_ENV,i as LUNORA_SKILL_NAMES,c as ROOT_SKILL_NAME,m as claimAgentRulesHint,N as detectAgentRules};
@@ -1 +1 @@
1
- import{sqliteClasses as c}from"./wranglerToAlchemy-CX9nCwtu.mjs";const u=1,l=new Set(["$schema","account_id","compatibility_date","compatibility_flags","keep_vars","main","migrations","minify","name","observability","placement","routes","rules","triggers","upload_source_maps","vars","workers_dev"]),p=e=>Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0)),a=[{bindingKey:"binding",field:"analytics_engine_datasets",resourceKey:"dataset",type:"analytics_engine"},{bindingKey:"class_name",field:"containers",resourceKey:"image",type:"container"},{bindingKey:"binding",field:"d1_databases",resourceIdKey:"database_id",resourceKey:"database_name",type:"d1"},{bindingKey:"binding",field:"hyperdrive",resourceIdKey:"id",type:"hyperdrive"},{bindingKey:"binding",field:"kv_namespaces",resourceIdKey:"id",type:"kv"},{bindingKey:"binding",field:"pipelines",resourceKey:"pipeline",type:"pipeline"},{bindingKey:"binding",field:"r2_buckets",resourceKey:"bucket_name",type:"r2"},{bindingKey:"binding",field:"vectorize",resourceKey:"index_name",type:"vectorize"},{bindingKey:"binding",field:"workflows",resourceKey:"name",type:"workflow"}],d=[{field:"ai",type:"ai"},{field:"assets",type:"assets"},{field:"browser",type:"browser"},{field:"images",type:"images"}],y=new Set([...a.map(e=>e.field),...d.map(e=>e.field),"durable_objects","queues"]),o=(e,t)=>{const s=t===void 0?void 0:e[t];return typeof s=="string"&&s!==""?s:void 0},b=(e,t)=>{const s=[];for(const n of a)for(const i of e[n.field]??[]){const r=o(i,n.bindingKey);if(r===void 0){t.push(n.field);continue}s.push({binding:r,className:o(i,"class_name"),resource:o(i,n.resourceKey),resourceId:o(i,n.resourceIdKey),type:n.type})}return s},m=(e,t)=>{const s=c(e),n=[];for(const i of e.durable_objects?.bindings??[]){if(i.name===void 0||i.name===""){t.push("durable_objects");continue}n.push({binding:i.name,className:i.class_name,sqlite:i.script_name===void 0&&i.class_name!==void 0?s.has(i.class_name):void 0,type:"durable_object"})}return n},_=(e,t)=>{const s=[];for(const n of e.queues?.producers??[]){if(n.binding===void 0||n.binding===""){t.push("queues.producers");continue}s.push({binding:n.binding,resource:n.queue,type:"queue_producer"})}for(const n of e.queues?.consumers??[]){if(n.queue===void 0||n.queue===""){t.push("queues.consumers");continue}s.push({binding:n.queue,resource:n.queue,type:"queue_consumer"})}return s},g=(e,t)=>[...b(e,t),...m(e,t),..._(e,t),...d.filter(s=>e[s.field]?.binding!==void 0).map(s=>({binding:e[s.field]?.binding,type:s.type}))],v=e=>{const t=[],s=g(e,t).map(i=>p(i)).toSorted((i,r)=>i.type.localeCompare(r.type)||i.binding.localeCompare(r.binding)),n=[...Object.keys(e).filter(i=>!l.has(i)&&!y.has(i)),...t.map(i=>`${i} (entry with no binding name)`)].toSorted((i,r)=>i.localeCompare(r));return{bindings:s,...e.compatibility_date===void 0?{}:{compatibilityDate:e.compatibility_date},...e.compatibility_flags===void 0?{}:{compatibilityFlags:e.compatibility_flags},crons:e.triggers?.crons??[],...e.name===void 0?{}:{name:e.name},unknown:n,vars:Object.keys(e.vars??{}).toSorted((i,r)=>i.localeCompare(r)),version:u}};export{u as BINDING_MANIFEST_VERSION,v as buildBindingManifest};
1
+ import{sqliteClasses as c}from"./wranglerToAlchemy-SDoS_XY0.mjs";const u=1,l=new Set(["$schema","account_id","compatibility_date","compatibility_flags","keep_vars","main","migrations","minify","name","observability","placement","routes","rules","triggers","upload_source_maps","vars","workers_dev"]),p=e=>Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0)),a=[{bindingKey:"binding",field:"analytics_engine_datasets",resourceKey:"dataset",type:"analytics_engine"},{bindingKey:"class_name",field:"containers",resourceKey:"image",type:"container"},{bindingKey:"binding",field:"d1_databases",resourceIdKey:"database_id",resourceKey:"database_name",type:"d1"},{bindingKey:"binding",field:"hyperdrive",resourceIdKey:"id",type:"hyperdrive"},{bindingKey:"binding",field:"kv_namespaces",resourceIdKey:"id",type:"kv"},{bindingKey:"binding",field:"pipelines",resourceKey:"pipeline",type:"pipeline"},{bindingKey:"binding",field:"r2_buckets",resourceKey:"bucket_name",type:"r2"},{bindingKey:"binding",field:"vectorize",resourceKey:"index_name",type:"vectorize"},{bindingKey:"binding",field:"workflows",resourceKey:"name",type:"workflow"}],d=[{field:"ai",type:"ai"},{field:"assets",type:"assets"},{field:"browser",type:"browser"},{field:"images",type:"images"}],y=new Set([...a.map(e=>e.field),...d.map(e=>e.field),"durable_objects","queues"]),o=(e,t)=>{const s=t===void 0?void 0:e[t];return typeof s=="string"&&s!==""?s:void 0},b=(e,t)=>{const s=[];for(const n of a)for(const i of e[n.field]??[]){const r=o(i,n.bindingKey);if(r===void 0){t.push(n.field);continue}s.push({binding:r,className:o(i,"class_name"),resource:o(i,n.resourceKey),resourceId:o(i,n.resourceIdKey),type:n.type})}return s},m=(e,t)=>{const s=c(e),n=[];for(const i of e.durable_objects?.bindings??[]){if(i.name===void 0||i.name===""){t.push("durable_objects");continue}n.push({binding:i.name,className:i.class_name,sqlite:i.script_name===void 0&&i.class_name!==void 0?s.has(i.class_name):void 0,type:"durable_object"})}return n},_=(e,t)=>{const s=[];for(const n of e.queues?.producers??[]){if(n.binding===void 0||n.binding===""){t.push("queues.producers");continue}s.push({binding:n.binding,resource:n.queue,type:"queue_producer"})}for(const n of e.queues?.consumers??[]){if(n.queue===void 0||n.queue===""){t.push("queues.consumers");continue}s.push({binding:n.queue,resource:n.queue,type:"queue_consumer"})}return s},g=(e,t)=>[...b(e,t),...m(e,t),..._(e,t),...d.filter(s=>e[s.field]?.binding!==void 0).map(s=>({binding:e[s.field]?.binding,type:s.type}))],v=e=>{const t=[],s=g(e,t).map(i=>p(i)).toSorted((i,r)=>i.type.localeCompare(r.type)||i.binding.localeCompare(r.binding)),n=[...Object.keys(e).filter(i=>!l.has(i)&&!y.has(i)),...t.map(i=>`${i} (entry with no binding name)`)].toSorted((i,r)=>i.localeCompare(r));return{bindings:s,...e.compatibility_date===void 0?{}:{compatibilityDate:e.compatibility_date},...e.compatibility_flags===void 0?{}:{compatibilityFlags:e.compatibility_flags},crons:e.triggers?.crons??[],...e.name===void 0?{}:{name:e.name},unknown:n,vars:Object.keys(e.vars??{}).toSorted((i,r)=>i.localeCompare(r)),version:u}};export{u as BINDING_MANIFEST_VERSION,v as buildBindingManifest};
@@ -0,0 +1 @@
1
+ const r={deploy:o=>{const n=o.preview===!0?["versions","upload"]:["deploy"];return o.entry!==void 0&&n.push(o.entry),o.environment!==void 0&&n.push("--env",o.environment),o.temporary===!0&&n.push("--temporary"),o.dryRun===!0&&n.push("--dry-run"),o.outDir!==void 0&&n.push("--outdir",o.outDir,"--metafile"),{args:n,tool:"wrangler"}},dev:o=>{const n=["dev"];return o.configPath!==void 0&&n.push("--config",o.configPath),o.environment!==void 0&&n.push("--env",o.environment),n.push(...o.extraArgs??[]),{args:n,tool:"wrangler"}},secretList:o=>{const n=["secret","list","--format","json"];return o.environment!==void 0&&n.push("--env",o.environment),o.temporary===!0&&n.push("--temporary"),{args:n,tool:"wrangler"}},secretPut:o=>{const n=["secret","put",o.key??""];return o.environment!==void 0&&n.push("--env",o.environment),o.temporary===!0&&n.push("--temporary"),{args:n,tool:"wrangler"}},tail:o=>{const n=["tail"];return o.worker!==void 0&&n.push(o.worker),o.environment!==void 0&&n.push("--env",o.environment),o.format!==void 0&&n.push("--format",o.format),o.status!==void 0&&n.push("--status",o.status),o.search!==void 0&&n.push("--search",o.search),o.temporary===!0&&n.push("--temporary"),{args:n,tool:"wrangler"}}},i={id:"cloudflare",name:"Cloudflare",toolchain:r};export{i as default};
@@ -0,0 +1 @@
1
+ import{existsSync as l,statSync as v,readFileSync as f,readdirSync as F}from"node:fs";import{init as U,parse as g}from"es-module-lexer";import{discoverAgentInfo as Y}from"./discoverAgentInfo-CTdCSfYM.mjs";import{WRANGLER_FILES as j,readWranglerJsonc as K}from"./WRANGLER_FILES-UNW-xY5u.mjs";import{discoverContainerInfo as W}from"./discoverContainerInfo-EhZtEBQs.mjs";import{escapeRegExp as w}from"./DEV_VARS_EXAMPLE_FILE-CqLorAxT.mjs";import{discoverFlags as M,FLAGS_FILENAME as X,discoverQueues as q,QUEUES_FILENAME as G}from"@lunora/codegen";import{d as T}from"./discover-info-Vj9d4qYt.mjs";import{discoverSchemaInfo as H}from"./discoverSchemaInfo-Bg2CUZXG.mjs";import{discoverWorkflowInfo as Q}from"./discoverWorkflowInfo-BsPvlo6O.mjs";import{join as c}from"node:path";const V=(e,s)=>{const{error:t,value:r}=T(e,s,X,M);return t===void 0?{flags:r}:{error:t}},J=(e,s)=>{const{error:t,value:r}=T(e,s,G,q);return t===void 0?{queues:r??[]}:{error:t,queues:[]}},z=new Set([".cjs",".cts",".js",".jsx",".mjs",".mts",".ts",".tsx"]),Z=new Set([".git",".lunora-cache",".wrangler","_generated","dist","node_modules"]),ee=["lunora","src"],se=["src/server/index.ts","src/server/index.tsx","src/index.ts","src/worker.ts"],_={SchedulerDO:"SCHEDULER",SessionDO:"SESSION",ShardDO:"SHARD"},O=Object.keys(_),re=/\benv\s*\.\s*DB\b/,te=/\benv\s*\.\s*AI\b/,D=/\bctx\s*\.\s*pipelines\b/,C=/\bctx\s*\.\s*r2sql\b/,P=/^\s*import\s+type\b/,ne=new Set(["@lunora/agent","@lunora/agent/sandbox"]),oe=e=>{const s=e.indexOf("{");if(s===-1)return"";const t=e.indexOf("}",s+1);return t===-1?e.slice(s+1):e.slice(s+1,t)},ae=/\btype\s+browserTool\b/,ie=/\bbrowserTool\b/,ce=/import\s+\{[^}]*\bbrowserTool\b[^}]*\}\s+from\s+["']@lunora\/agent(?:\/sandbox)?["']/,ue=e=>{if(P.test(e))return!1;const s=oe(e);return ie.test(s)&&!ae.test(s)},le=e=>{try{const[s]=g(e);return s.some(t=>t.n!==void 0&&ne.has(t.n)&&ue(e.slice(t.ss,t.se)))}catch{return ce.test(e)}},h={usesAi:{pattern:/\bfrom\s+["']@lunora\/ai["']/,source:"@lunora/ai"},usesAnalytics:{pattern:/\bfrom\s+["']@lunora\/bindings\/analytics["']/,source:"@lunora/bindings/analytics"},usesAuth:{pattern:/\bfrom\s+["']@lunora\/auth["']/,source:"@lunora/auth"},usesBrowser:{pattern:/\bfrom\s+["']@lunora\/browser["']/,source:"@lunora/browser"},usesHyperdrive:{pattern:/\bfrom\s+["']@lunora\/hyperdrive["']/,source:"@lunora/hyperdrive"},usesImages:{pattern:/\bfrom\s+["']@lunora\/bindings\/images["']/,source:"@lunora/bindings/images"},usesKv:{pattern:/\bfrom\s+["']@lunora\/bindings\/kv["']/,source:"@lunora/bindings/kv"},usesMail:{pattern:/\bfrom\s+["']@lunora\/mail["']/,source:"@lunora/mail"},usesNotify:{pattern:/\bfrom\s+["']@lunora\/notify["']/,source:"@lunora/notify"},usesPayment:{pattern:/\bfrom\s+["']@lunora\/payment["']/,source:"@lunora/payment"},usesPipelines:{pattern:D,source:"@lunora/bindings/pipelines"},usesR2sql:{pattern:C,source:"@lunora/bindings/r2sql"},usesScheduler:{pattern:/\bfrom\s+["']@lunora\/scheduler["']/,source:"@lunora/scheduler"},usesStorage:{pattern:/\bfrom\s+["']@lunora\/storage["']/,source:"@lunora/storage"},usesX402Charge:{pattern:/\bfrom\s+["']@lunora\/x402\/charge["']/,source:"@lunora/x402/charge"},usesX402Pay:{pattern:/\bfrom\s+["']@lunora\/x402\/pay["']/,source:"@lunora/x402/pay"}},m=Object.keys(h),de="STRIPE_SECRET_KEY + STRIPE_WEBHOOK_SECRET (Stripe) or POLAR_ACCESS_TOKEN + POLAR_WEBHOOK_SECRET (Polar)",L=[...m,"needsD1"],pe=()=>{const e={};for(const s of L)e[s]=!1;return e},d=Object.freeze(pe()),x=(e,s)=>{const t={};for(const r of L)t[r]=e[r]||s[r];return t},me=e=>{for(const s of m)if(h[s].source===e)return{...d,[s]:!0};return d},be=e=>{const[s]=g(e);let t=d;for(const r of s){const n=r.n;!n||P.test(e.slice(r.ss,r.se))||(t=x(t,me(n)))}return t},fe=e=>{const s={...d};for(const t of m)s[t]=h[t].pattern.test(e);return s},ge=e=>{let s;try{s=be(e)}catch{s=fe(e)}return x(s,{...d,needsD1:re.test(e),usesAi:te.test(e),usesPipelines:D.test(e),usesR2sql:C.test(e)})},y=(e,s)=>{let t;try{t=F(e,{withFileTypes:!0})}catch{return}for(const r of t){if(r.isDirectory()){Z.has(r.name)||y(c(e,r.name),s);continue}const n=r.name.lastIndexOf(".");n!==-1&&z.has(r.name.slice(n))&&s.push(c(e,r.name))}},he="virtual:lunora/worker",Ee=["ShardDO"],Se="src/worker.ts",_e=e=>{for(const s of j){const t=c(e,s);if(!l(t))continue;const{parsed:r}=K(t),n=r?.main;if(n===he)return{composed:!0};const a=c(e,Se);if(l(a))return{composed:!1,path:a};if(typeof n=="string"&&l(c(e,n)))return{composed:!1,path:c(e,n)};break}for(const s of se){const t=c(e,s);if(l(t))return{composed:!1,path:t}}return{composed:!1}},xe=/(?:^|[\s,{])type$/u,B=(e,s)=>{const t=s.ls>=0?s.ls:s.s;return xe.test(e.slice(0,t).trimEnd())},k=(e,s)=>{const t=w(s);return new RegExp(String.raw`\bexport\s+type\s+${t}\b`,"u").test(e)||new RegExp(String.raw`\bexport\s+type\s*\{[^}]*\b${t}\b`,"u").test(e)||new RegExp(String.raw`\bexport\s+\{[^}]*\btype\s+${t}\b`,"u").test(e)},ye=e=>{const s=f(e,"utf8");let t;try{const[,r]=g(s);t=new Set(r.filter(n=>!B(s,n)).map(n=>n.n))}catch{t=new Set(O.filter(r=>new RegExp(String.raw`\bexport\b[^\n;]*\b${r}\b`,"u").test(s)&&!k(s,r)))}return O.filter(r=>t.has(r)).map(r=>({binding:_[r],className:r}))},S=(e,s,t)=>{if(s.length===0)return[];if(e.composed)return s.map(o=>({...o,exported:!0}));if(e.path===void 0)return s.map(o=>({...o,exported:!1}));const r=f(e.path,"utf8"),n=new RegExp(String.raw`\bexport\s*\*\s*from\s*["'][^"']*_generated\/${t}(?:\.js)?["']`).test(r);let a;try{const[,o]=g(r);a=new Set(o.filter(i=>!B(r,i)).map(i=>i.n))}catch{a=new Set(s.map(o=>o.className).filter(o=>new RegExp(String.raw`\bexport\b[^\n;]*\b${w(o)}\b`,"u").test(r)&&!k(r,o)))}return s.map(o=>{const i=n||a.has(o.className);return{...o,exported:i}})},Re=(e,s)=>H(e,s).info?.hasGlobalTable??!1,Ie=(e,s)=>{let t=d;for(const r of s){const n=c(e,r);if(!l(n)||!v(n).isDirectory())continue;const a=[];y(n,a);for(const o of a)t=x(t,ge(f(o,"utf8")))}return t},Ae=(e,s)=>{const t=c(e,s);if(!l(t)||!v(t).isDirectory())return!1;const r=[];return y(t,r),r.some(n=>le(f(n,"utf8")))},Ne=(e,s,t)=>[...e.map(r=>r.exported?`${r.bindingName}/${r.className} (container "${r.exportName}" declared and exported)`:`hint: container "${r.exportName}" is declared but ${r.className} is not exported by the worker entry — add \`export * from "./lunora/_generated/containers"\``),...s.map(r=>r.exported?`${r.bindingName}/${r.className} (workflow "${r.exportName}" declared and exported)`:`hint: workflow "${r.exportName}" is declared but ${r.className} is not exported by the worker entry — add \`export * from "./lunora/_generated/workflows"\``),...t.map(r=>r.exported?`${r.bindingName}/${r.className} (agent "${r.exportName}" declared and exported)`:`hint: agent "${r.exportName}" is declared but ${r.className} is not exported by the worker entry — add \`export * from "./lunora/_generated/agents"\``)],Oe=(e,s)=>[[e.usesAi,"AI (@lunora/ai imported or env.AI 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: @lunora/scheduler is imported but no SchedulerDO is exported by the worker entry"],[e.usesStorage,"hint: @lunora/storage is imported; add an r2_buckets binding (bucket binding names are user-defined)"],[e.usesMail,"hint: @lunora/mail is imported; set RESEND_API_KEY in .dev.vars (obtain at https://resend.com/api-keys)"],[e.usesPayment,`hint: @lunora/payment is imported; set the provider secrets in .dev.vars — ${de}`],[e.usesBrowser,"browser (@lunora/browser imported) — self-describing { binding: BROWSER }"],[e.usesImages,"images (@lunora/bindings/images imported) — self-describing { binding: IMAGES }"],[e.usesAnalytics,"analytics_engine_datasets (@lunora/bindings/analytics imported) — self-describing { binding: ANALYTICS, dataset }"],[e.usesKv,"hint: @lunora/bindings/kv is imported; add a kv_namespaces binding ({ binding, id }) and pass env.<BINDING> to createKv() — the namespace id can't be auto-provisioned"],[e.usesHyperdrive,"hint: @lunora/hyperdrive is imported; run 'wrangler hyperdrive create' and add a 'hyperdrive' binding ({ binding, id }) — the id can't be auto-provisioned"],[e.usesPipelines,"hint: ctx.pipelines is used; run 'wrangler pipelines create <name>' and add a 'pipelines' binding ({ binding, pipeline }) — the pipeline resource can't be auto-provisioned"],[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.usesX402Pay,"hint: @lunora/x402/pay is imported (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(([r])=>r).map(([,r])=>r),ve=(e,s,t,r=[],n=[],a=[])=>{const o=new Set(e.map(u=>u.className)),i=e.map(u=>`${u.binding}/${u.className} (exported by worker entry)`);return s&&i.push("DB (.global() table declared)"),i.push(...Ne(r,n,a),...Oe(t,o)),i},Ye=async e=>{await U;const s=e.schemaDir??"lunora",t=e.scanDirs??ee,r=Ie(e.projectRoot,t),n={...r,usesBrowser:r.usesBrowser||Ae(e.projectRoot,s)},a=_e(e.projectRoot);let o;a.composed?o=Ee.map(p=>({binding:_[p],className:p})):o=a.path===void 0?[]:ye(a.path);const i=n.needsD1||Re(e.projectRoot,s),u=S(a,W(e.projectRoot,s).containers,"containers"),R=S(a,Q(e.projectRoot,s).workflows,"workflows"),I=S(a,Y(e.projectRoot,s).agents,"agents"),$=[...J(e.projectRoot,s).queues],{flags:b}=V(e.projectRoot,s),E=b?.provider==="flagship"&&b.mode==="binding"?b.bindingName:void 0,A={};for(const p of m)A[p]=n[p];const N=ve(o,i,n,u,R,I);return E!==void 0&&N.push(`hint: lunora/flags.ts uses Flagship in binding mode; add a flagship binding ({ binding: "${E}", app_id }) — the app_id can't be auto-provisioned`),{agents:I,containers:u,durableObjects:o,flagshipBinding:E,needsD1:i,queues:$,signals:N,usesFlags:b!==void 0,workflows:R,...A}},je=e=>{const s=[];for(const t of m)e[t]&&s.push(h[t].source);return s};export{Se as COMPOSED_WORKER_ENTRY,he as LUNORA_WORKER_VIRTUAL_ID,se as WORKER_ENTRY_FALLBACKS,Ye as inferLunoraBindings,B as isTypeOnlyExportEntry,je as packageNamesFromBindings,_e as resolveWorkerEntry};
@@ -0,0 +1 @@
1
+ import t from"./CLOUDFLARE_DRIVER-Ci9oJMYb.mjs";const l={id:"node",name:"Node"},a="cloudflare",n={cloudflare:t,node:l},r=()=>Object.keys(n).toSorted((o,e)=>o.localeCompare(e)),s=(o=a)=>{const e=n[o];if(e===void 0)throw new Error(`unknown deploy target "${o}" — available targets: ${r().join(", ")}`);return e},c=o=>Object.hasOwn(n,o)&&s(o).toolchain!==void 0,i=()=>r().filter(o=>c(o));export{a as DEFAULT_DEPLOY_TARGET,r as deployTargetIds,c as isRunnableTarget,s as resolveDeployDriver,i as runnableTargetIds};
@@ -1 +1 @@
1
- import{existsSync as c,readFileSync as i}from"node:fs";import{readProjectTarget as s}from"@lunora/codegen";import{parse as a}from"jsonc-parser";import{DEFAULT_DEPLOY_TARGET as f,resolveDeployDriver as m}from"./DEFAULT_DEPLOY_TARGET-De4Ps8C8.mjs";import{join as p}from"node:path";const l="lunora.json",d=r=>{if(typeof r=="boolean")return r;if(r!==null&&typeof r=="object")return!0},u=r=>{const e=p(r,l);if(!c(e))return;let t;try{t=i(e,"utf8")}catch{return}const n=[],o=a(t,n,{allowTrailingComma:!0});if(!(n.length>0||o===null||typeof o!="object"))return o},h=r=>d(u(r)?.remote),g=r=>s(r),j=(r,e)=>e??g(r)??f,D=(r,e)=>{const t=j(r,e);return m(t),t};export{l as LUNORA_CONFIG_FILE,d as interpretRemote,h as readProjectRemotePreference,g as readProjectTarget,j as resolveProjectTarget,D as resolveTargetOrThrow};
1
+ import{existsSync as c,readFileSync as i}from"node:fs";import{readProjectTarget as s}from"@lunora/codegen";import{parse as a}from"jsonc-parser";import{DEFAULT_DEPLOY_TARGET as f,resolveDeployDriver as m}from"./DEFAULT_DEPLOY_TARGET-B-e9mqgX.mjs";import{join as p}from"node:path";const l="lunora.json",d=r=>{if(typeof r=="boolean")return r;if(r!==null&&typeof r=="object")return!0},u=r=>{const e=p(r,l);if(!c(e))return;let t;try{t=i(e,"utf8")}catch{return}const n=[],o=a(t,n,{allowTrailingComma:!0});if(!(n.length>0||o===null||typeof o!="object"))return o},h=r=>d(u(r)?.remote),g=r=>s(r),j=(r,e)=>e??g(r)??f,D=(r,e)=>{const t=j(r,e);return m(t),t};export{l as LUNORA_CONFIG_FILE,d as interpretRemote,h as readProjectRemotePreference,g as readProjectTarget,j as resolveProjectTarget,D as resolveTargetOrThrow};
@@ -1 +1 @@
1
- import{C as S,M as a,P as C,s as R}from"./package-secrets-registry-CFZ5bA8L.mjs";export{S as CORE_SECRETS,a as MINTABLE_SECRET_KEYS,C as PACKAGE_SECRETS_REGISTRY,R as secretsForPackages};
1
+ import{C as S,M as a,P as C,s as R}from"./package-secrets-registry-DvtTiK4b.mjs";export{S as CORE_SECRETS,a as MINTABLE_SECRET_KEYS,C as PACKAGE_SECRETS_REGISTRY,R as secretsForPackages};
@@ -0,0 +1 @@
1
+ import{existsSync as d,readFileSync as y}from"node:fs";import{join as s,isAbsolute as a,relative as m}from"node:path";import{LunoraError as p}from"@lunora/errors";import{classifyPolicyEdit as k,scaffoldPolicyFile as v,resolveServerModule as l,wireRlsIntoProcedure as b}from"./classifyPolicyEdit-D8NwrHxR.mjs";import{w as c,r as h}from"./write-atomic-9d9xs5ON.mjs";const D="/__lunora/policy-scaffold",u=e=>e==="unknown-procedure"?404:e==="already-wired"||e==="destructive"?409:422,f=(e,o)=>{let r;try{r=h(e)}catch(t){return{body:{error:t instanceof Error?t.message:String(t),ok:!1},status:500}}return{body:{...o,diagnostics:r,ok:!0},status:200}},g=e=>({body:{edit:e,message:"Rewriting an existing policy predicate changes evaluation semantics and must be done by hand. The scaffolder only adds new, deny-by-default rules.",needsManualEdit:!0,ok:!1},status:409}),w=(e,o)=>{const r=v(o,l(e.projectRoot));if(!r.ok)return{body:{error:r.reason,ok:!1},status:u(r.reason)};const t=e.schemaDirectory??"lunora",n=s(e.projectRoot,t,r.fileName);return d(n)?{body:{error:"file-exists",fileName:r.fileName,ok:!1},status:409}:(c(n,r.source),f(e,{fileName:r.fileName}))},R=(e,o,r)=>{if(typeof r!="string"||r.length===0||a(r)||r.includes("\\"))return;const t=s(e,o),n=s(t,`${r}.ts`),i=m(t,n);if(!(i.startsWith("..")||a(i)))return n},N=(e,o)=>{const r=R(e.projectRoot,e.schemaDirectory??"lunora",o.filePath);if(r===void 0||!d(r))return{body:{error:"unknown-procedure",ok:!1},status:404};const t=b(y(r,"utf8"),o,l(e.projectRoot));return t.ok?(c(r,t.text),f(e,{exportName:o.exportName})):{body:{error:t.reason,ok:!1},status:u(t.reason)}},E=e=>{if(e.method!=="POST")return{body:{error:"method-not-allowed",ok:!1},status:405};const{body:o}=e;if(o==null||typeof o!="object"||typeof o.kind!="string")return{body:{error:"invalid-edit",ok:!1},status:400};const r=o;if(k(r)==="destructive")return g(r);if(r.kind==="scaffoldPolicy")return w(e,r);if(r.kind==="wireRls")return N(e,r);throw new p("INTERNAL",`unhandled additive policy edit kind: ${String(r.kind)}`)};export{D as POLICY_SCAFFOLD_ENDPOINT,E as handlePolicyScaffoldRequest};
@@ -1 +1 @@
1
- import{existsSync as g,readFileSync as N}from"node:fs";import{dirname as R,join as f}from"node:path";import{COMPOSED_WORKER_ENTRY as x,WORKER_ENTRY_FALLBACKS as I}from"./COMPOSED_WORKER_ENTRY-CAPCs3GJ.mjs";import{discoverSchemaInfo as L}from"./discoverSchemaInfo-Bg2CUZXG.mjs";import{isCacheEnabled as C,WORKERS_CACHE_MIN_DATE as _}from"./WORKERS_CACHE_MIN_DATE-0k9ABJtF.mjs";import{findWranglerFile as T,readWranglerJsonc as B}from"./WRANGLER_FILES-UNW-xY5u.mjs";const W=new Set(["1","enabled","on","true","yes"]),q=e=>typeof e=="string"&&W.has(e.trim().toLowerCase()),v="2026-04-07",We="web_socket_auto_reply_to_close",E=/^\d{4}-\d{2}-\d{2}$/,$=["containers","d1_databases","durable_objects","kv_namespaces","queues","r2_buckets","secrets_store_secrets","services","tail_consumers","vars","vectorize","workflows"],S=["assets","compatibility_date","exports","logpush","main","migrations","observability","placement"],k=(e,s)=>{if(s===void 0)return{merged:e,unverifiedKeys:[]};const t=e.env?.[s];if(t===void 0){const r=Object.keys(e.env??{}).toSorted((c,d)=>c.localeCompare(d)),l=r.length>0?` (declared: ${r.join(", ")}).`:" (no environments are declared).";return{error:`--env "${s}" names no environment declared in wrangler.jsonc's "env" block${l}`,merged:e,unverifiedKeys:[]}}const n={...e},i=Object.keys(t).filter(r=>r!=="env");for(const r of i)S.includes(r)&&(n[r]=t[r]);for(const r of $)n[r]=t[r];const a=new Set([...$,...S]),o=i.filter(r=>!a.has(r)).map(String);return{merged:n,unverifiedKeys:o}},U=(e,s,t)=>{if(s.length===0)return;const n=e.vectorize??[],i=new Set(n.filter(Boolean).map(a=>a?.index_name));for(const a of s)i.has(a)||t.push(`schema declares vector index "${a}"; wrangler "vectorize" must include a binding with index_name "${a}"`)},P=new Set(["basic","dev","lite","standard","standard-1","standard-2","standard-3","standard-4"]),F={disk_mb:2e4,memory_mib:12288,vcpu:4},K=(e,s,t)=>{const n=e.instance_type;if(n===void 0)return;if(typeof n=="string"){P.has(n)||t.push(`${s} has unknown instance_type "${n}" — expected lite, basic, standard-1..4, or a custom { vcpu, memory_mib, disk_mb } object`);return}for(const[r,l]of Object.entries(F)){const c=n[r];c!==void 0&&(typeof c!="number"||c<=0||c>l)&&t.push(`${s} custom instance_type ${r} must be a positive number ≤ ${String(l)} (got ${String(c)})`)}const{disk_mb:i,memory_mib:a,vcpu:o}=n;if(typeof o=="number"&&typeof a=="number"&&a<o*3072&&t.push(`${s} custom instance_type needs ≥ 3 GiB (3072 MiB) memory per vCPU (got ${String(a)} MiB for ${String(o)} vCPU)`),typeof a=="number"&&typeof i=="number"){const r=Math.floor(a/1024*2e3);i>r&&t.push(`${s} custom instance_type allows ≤ 2 GB disk per GiB memory (≤ ${String(r)} MB for ${String(a)} MiB memory; got ${String(i)} MB)`)}},G=(e,s,t)=>{const{boundClasses:n,classKinds:i,errors:a,warnings:o}=t;if(!e||typeof e!="object"||typeof e.class_name!="string"||e.class_name.length===0){a.push(`${s} must have a non-empty "class_name" naming its container-enabled Durable Object class`);return}(typeof e.image!="string"||e.image.length===0)&&a.push(`${s} ("${e.class_name}") must have an "image" — a Dockerfile path or a registry reference`),n.has(e.class_name)||a.push(`${s} class "${e.class_name}" has no matching durable_objects binding — your dev server auto-reconciles this on startup; add { "name": "...", "class_name": "${e.class_name}" } to fix it by hand`);const r=i.get(e.class_name);r!=="sqlite"&&a.push(r==="classic"?`${s} class "${e.class_name}" is registered via "new_classes" but containers require SQLite-backed DOs — move it to "new_sqlite_classes"`:`${s} class "${e.class_name}" is missing from migrations — add a migration entry with "new_sqlite_classes": ["${e.class_name}"]`),K(e,`${s} ("${e.class_name}")`,a),e.max_instances===void 0&&o.push(`${s} ("${e.class_name}") declares no max_instances — set a cap so a traffic spike can't fan out unbounded container spend`)},m=e=>typeof e=="string"&&e.length>0,b=e=>Array.isArray(e)?e.filter(s=>s!==null&&typeof s=="object"):[],h=e=>Array.isArray(e)?e.filter(s=>m(s)):[],M=e=>{const s=new Map;for(const t of b(e)){for(const n of h(t.new_classes))s.set(n,"classic");for(const n of h(t.new_sqlite_classes))s.set(n,"sqlite");for(const n of b(t.renamed_classes))if(m(n.from)&&m(n.to)){const i=s.get(n.from)??"sqlite";s.delete(n.from),s.set(n.to,i)}for(const n of h(t.deleted_classes))s.delete(n)}return s},Y=e=>new Set(M(e).keys()),Q=(e,s)=>{const t=Y(e.migrations);for(const n of b(e.durable_objects?.bindings))n.script_name===void 0&&m(n.class_name)&&!t.has(n.class_name)&&s.push(`durable_objects.bindings declares class "${n.class_name}" but it is missing from migrations — add a migration entry with "new_sqlite_classes": ["${n.class_name}"] (or "new_classes" for a non-SQLite-backed class), or let the dev server auto-reconcile it on the next start`)},H=(e,s,t)=>{if(e.containers===void 0)return;if(!Array.isArray(e.containers)){s.push("containers must be an array of { class_name, image, ... } entries");return}const n=e.containers;if(n.length===0)return;const i=new Set(b(e.durable_objects?.bindings).map(o=>o.class_name)),a=M(e.migrations);for(const[o,r]of n.entries())G(r,`containers[${String(o)}]`,{boundClasses:i,classKinds:a,errors:s,warnings:t});e.observability?.enabled!==!0&&t.push('containers are configured but observability is not enabled — container logs will not be captured (add { "observability": { "enabled": true } })')},y=e=>e,p=(e,s,t,n)=>{if(e!==void 0){if(!Array.isArray(e)){n.push(t.arrayMessage);return}for(const[i,a]of y(e).entries()){const o=`${s}[${String(i)}]`;if(!a||typeof a!="object"){n.push(t.objectMessage(o));continue}for(const r of t.fields)m(a[r.field])||n.push(r.message(o))}}},V={arrayMessage:"workflows must be an array of { name, binding, class_name } entries",fields:[{field:"binding",message:e=>`${e} must have a non-empty "binding" naming the Workflow binding (e.g. WORKFLOW_ORDER_PIPELINE)`},{field:"class_name",message:e=>`${e} must have a non-empty "class_name" naming the exported WorkflowEntrypoint class`},{field:"name",message:e=>`${e} must have a non-empty "name" naming the deployed workflow`}],objectMessage:e=>`${e} must be a { name, binding, class_name } object`},z={arrayMessage:"queues.producers must be an array of { binding, queue } entries",fields:[{field:"binding",message:e=>`${e} must have a non-empty "binding" naming the Queue producer (e.g. QUEUE_EMAIL)`},{field:"queue",message:e=>`${e} must have a non-empty "queue" naming the deployed queue`}],objectMessage:e=>`${e} must be a { binding, queue } object`},X={arrayMessage:"queues.consumers must be an array of { queue } entries",fields:[{field:"queue",message:e=>`${e} must have a non-empty "queue" naming the consumed queue`}],objectMessage:e=>`${e} must be a { queue } object`},J=(e,s)=>{if(e.queues!==void 0){if(typeof e.queues!="object"||Array.isArray(e.queues)){s.push("queues must be a { producers, consumers } object");return}p(e.queues.producers,"queues.producers",z,s),p(e.queues.consumers,"queues.consumers",X,s)}},Z={arrayMessage:"secrets_store_secrets must be an array of { binding, store_id, secret_name } entries",fields:["binding","store_id","secret_name"].map(e=>({field:e,message:s=>`${s} must have a non-empty "${e}"`})),objectMessage:e=>`${e} must be a { binding, store_id, secret_name } object`},ee=[{arrayMessage:"kv_namespaces must be an array of { binding, id } entries",bindingMessage:e=>`${e} must have a non-empty "binding" naming the KV namespace binding`,hintField:"id",hintMessage:(e,s)=>`${e} ("${s}") has no "id" — run \`wrangler kv namespace create\` and set the namespace id, or the binding can't resolve`,key:"kv_namespaces"},{arrayMessage:"flagship must be an array of { binding, app_id } entries",bindingMessage:e=>`${e} must have a non-empty "binding" naming the Flagship binding`,hintField:"app_id",hintMessage:(e,s)=>`${e} ("${s}") has no "app_id" — create a Flagship app and set its id, or the binding can't resolve`,key:"flagship"},{arrayMessage:"hyperdrive must be an array of { binding, id } entries",bindingMessage:e=>`${e} must have a non-empty "binding" naming the Hyperdrive binding`,hintField:"id",hintMessage:(e,s)=>`${e} ("${s}") has no "id" — run \`wrangler hyperdrive create\` and set the id, or the binding can't connect`,key:"hyperdrive"},{arrayMessage:"pipelines must be an array of { binding, stream } entries",bindingMessage:e=>`${e} must have a non-empty "binding" naming the Pipelines binding`,hintField:["stream","pipeline"],hintMessage:(e,s)=>`${e} ("${s}") has no "stream" — run \`wrangler pipelines create <name>\` and set the stream name, or the binding can't resolve`,key:"pipelines"},{arrayMessage:"analytics_engine_datasets must be an array of { binding, dataset } entries",bindingMessage:e=>`${e} must have a non-empty "binding" naming the Analytics Engine binding`,hintField:"dataset",hintMessage:(e,s)=>`${e} ("${s}") has no "dataset" — it defaults to the binding name; set it explicitly to avoid drift`,key:"analytics_engine_datasets"}],se=(e,s,t,n)=>{const i=e[s.key];if(i!==void 0){if(!Array.isArray(i)){t.push(s.arrayMessage);return}for(const[a,o]of y(i).entries()){const r=`${s.key}[${String(a)}]`;if(!o||typeof o!="object"||!m(o.binding)){t.push(s.bindingMessage(r));continue}(typeof s.hintField=="string"?[s.hintField]:s.hintField).some(c=>m(o[c]))||n.push(s.hintMessage(r,o.binding))}}},ne=[{key:"browser",message:'browser must be an object with a non-empty "binding" (e.g. { "binding": "BROWSER" })'},{key:"images",message:'images must be an object with a non-empty "binding" (e.g. { "binding": "IMAGES" })'}],te=(e,s,t)=>{const n=e[s.key];n!==void 0&&(typeof n!="object"||n===null||Array.isArray(n)||!m(n.binding))&&t.push(s.message)},ie=[{arrayMessage:"services must be an array of { binding, service, entrypoint? } entries",fields:[{field:"binding",message:e=>`${e} must have a non-empty "binding" naming the service binding`},{field:"service",message:e=>`${e} must have a non-empty "service" naming the target Worker`}],key:"services",objectMessage:e=>`${e} must be a { binding, service, entrypoint? } object`},{arrayMessage:"dispatch_namespaces must be an array of { binding, namespace } entries",fields:[{field:"binding",message:e=>`${e} must have a non-empty "binding"`},{field:"namespace",message:e=>`${e} must have a non-empty "namespace" naming the dispatch namespace`}],key:"dispatch_namespaces",objectMessage:e=>`${e} must be a { binding, namespace } object`},{arrayMessage:"mtls_certificates must be an array of { binding, certificate_id } entries",fields:[{field:"binding",message:e=>`${e} must have a non-empty "binding"`},{field:"certificate_id",message:e=>`${e} must have a non-empty "certificate_id" (upload via \`wrangler mtls-certificate upload\`)`}],key:"mtls_certificates",objectMessage:e=>`${e} must be a { binding, certificate_id } object`},{arrayMessage:"r2_buckets must be an array of { binding, bucket_name } entries",fields:[{field:"binding",message:e=>`${e} must have a non-empty "binding" naming the R2 bucket binding`},{field:"bucket_name",message:e=>`${e} must have a non-empty "bucket_name" naming the deployed bucket`}],key:"r2_buckets",objectMessage:e=>`${e} must be a { binding, bucket_name } object`}],ae=(e,s)=>{const{d1_databases:t}=e;if(t!==void 0){if(!Array.isArray(t)){s.push("d1_databases must be an array of { binding, database_id | database_name } entries");return}for(const[n,i]of y(t).entries()){const a=`d1_databases[${String(n)}]`;if(!i||typeof i!="object"){s.push(`${a} must be a { binding, database_id | database_name } object`);continue}m(i.binding)||s.push(`${a} must have a non-empty "binding" naming the D1 binding`),!m(i.database_id)&&!m(i.database_name)&&s.push(`${a} must have a "database_id" or a "database_name" — run \`wrangler d1 create\` and set one, or the binding can't resolve`)}}},oe=(e,s,t)=>{const n=e.send_email;if(n===void 0)return;if(!Array.isArray(n)){s.push("send_email must be an array of { name, destination_address? } entries");return}const i=n;for(const[a,o]of i.entries())(!o||typeof o!="object"||typeof o.name!="string"||o.name.length===0)&&t.push(`send_email[${String(a)}] has no non-empty "name" naming the send-email binding — set one before deploying`)},re=(e,s)=>{e.logpush!==void 0&&typeof e.logpush!="boolean"&&s.push('logpush must be a boolean (set "logpush": true to enable Cloudflare Logpush)')},A=new Set(["off","smart","targeted"]),ce=(e,s)=>{const{placement:t}=e;if(t===void 0)return;if(typeof t!="object"||t===null||Array.isArray(t)){s.push('placement must be an object (e.g. { "mode": "smart" })');return}const{mode:n}=t;n!==void 0&&(typeof n!="string"||!A.has(n))&&s.push(`placement.mode must be one of ${[...A].map(i=>`"${i}"`).join(", ")}`)},de=(e,s)=>{const{observability:t}=e;if(t===void 0)return;if(typeof t!="object"||Array.isArray(t)){s.push('observability must be an object (e.g. { "enabled": true, "head_sampling_rate": 1 })');return}const n=(i,a)=>{i!==void 0&&(typeof i!="number"||Number.isNaN(i)||i<0||i>1)&&s.push(`${a} must be a number in [0, 1] (the fraction of requests sampled)`)};n(t.head_sampling_rate,"observability.head_sampling_rate"),t.logs!==void 0&&(typeof t.logs!="object"||Array.isArray(t.logs)?s.push("observability.logs must be an object"):n(t.logs.head_sampling_rate,"observability.logs.head_sampling_rate"))},le=(e,s)=>{const{cache:t}=e;if(t!==void 0){if(typeof t!="object"||t===null||Array.isArray(t)){s.push('cache must be an object (e.g. { "enabled": true })');return}t.enabled!==void 0&&typeof t.enabled!="boolean"&&s.push("cache.enabled must be a boolean (true or false)")}},me=(e,s)=>{const{exports:t}=e;if(t!==void 0){if(typeof t!="object"||t===null||Array.isArray(t)){s.push("exports must be an object keyed by entrypoint name");return}for(const[n,i]of Object.entries(t)){if(typeof i!="object"||i===null){s.push(`exports["${n}"] must be an object`);continue}i.type!==void 0&&typeof i.type!="string"&&s.push(`exports["${n}"].type must be a string`),i.cache!==void 0&&(typeof i.cache!="object"||i.cache===null||Array.isArray(i.cache)?s.push(`exports["${n}"].cache must be an object`):i.cache.enabled!==void 0&&typeof i.cache.enabled!="boolean"&&s.push(`exports["${n}"].cache.enabled must be a boolean`))}}},ue=(e,s)=>{const{assets:t}=e;if(t!==void 0){if(typeof t!="object"||Array.isArray(t)){s.push('assets must be an object (e.g. { "directory": "./dist/client", "binding": "ASSETS" })');return}(typeof t.directory!="string"||t.directory.length===0)&&s.push('assets must declare a non-empty "directory" pointing at the built client output (e.g. "./dist/client")'),t.binding!==void 0&&(typeof t.binding!="string"||t.binding.length===0)&&s.push('assets.binding must be a non-empty string (e.g. "ASSETS")'),t.html_handling!==void 0&&typeof t.html_handling!="string"&&s.push("assets.html_handling must be a string"),t.not_found_handling!==void 0&&typeof t.not_found_handling!="string"&&s.push("assets.not_found_handling must be a string")}},be=(e,s)=>{const t=e.tail_consumers;if(t===void 0)return;if(!Array.isArray(t)){s.push("tail_consumers must be an array of { service, environment? } entries");return}const n=t;for(const[i,a]of n.entries())(!a||typeof a!="object"||typeof a.service!="string"||a.service.length===0)&&s.push(`tail_consumers[${String(i)}] must have a non-empty "service" naming the consumer Worker`)},qe=(e,s)=>{const t=e.tail_consumers??[];return t.some(i=>!!i&&i?.service===s.service&&i?.environment===s.environment)?e:{...e,tail_consumers:[...t,s]}},ge=(e,s)=>{const{vars:t}=e;if(!t||typeof t!="object")return;const n=t.LUNORA_ALLOWED_ORIGINS,i=t.LUNORA_CORS_ALLOW_CREDENTIALS,a=typeof n=="string"&&n.split(",").some(r=>r.trim()==="*"),o=q(i);a&&o&&s.push('vars.LUNORA_ALLOWED_ORIGINS includes a "*" wildcard while vars.LUNORA_CORS_ALLOW_CREDENTIALS is on — browsers reject this combination and it defeats the allowlist; name explicit origins or drop credentials')},fe=(e,s,t)=>{const{error:n,merged:i,unverifiedKeys:a}=k(e,s);return n!==void 0?{error:n,wrangler:i}:(a.length>0&&t.push(`env.${String(s)} overrides ${a.join(", ")}, which this validator doesn't have a verified inheritance rule for — validated against the TOP-LEVEL value only. Double-check ${a.length===1?"it":"them"} by hand for "${String(s)}".`),{wrangler:i})},w=(e,s,t)=>{const n=[],i=[];if(!e||typeof e!="object")return n.push("wrangler config is not a valid object"),{errors:n,valid:!1,warnings:i};const{error:a,wrangler:o}=fe(e,t,i);if(a!==void 0)return n.push(a),{errors:n,valid:!1,warnings:i};b(o.durable_objects?.bindings).find(d=>d.name==="SHARD"&&d.class_name==="ShardDO")||n.push('durable_objects.bindings must include { "name": "SHARD", "class_name": "ShardDO" } — your dev server auto-reconciles this on startup, or add the binding manually'),Q(o,n);const c=o.compatibility_date??"";c&&!E.test(c)?n.push(`compatibility_date must be in YYYY-MM-DD format (got "${c}")`):c<v&&n.push(`compatibility_date must be >= "${v}" (got "${c||"<missing>"}")`),C(o)&&E.test(c)&&c<_&&n.push(`cache.enabled requires compatibility_date >= "${_}" (got "${c||"<missing>"}")`),s?.hasGlobalTable&&(b(o.d1_databases).find(D=>D.binding==="DB")||n.push('schema declares .global() tables; d1_databases must include a binding named "DB" — your dev server auto-reconciles this on startup, or add the binding manually')),ae(o,n),U(o,s?.vectorIndexNames??[],n),be(o,n),H(o,n,i),p(o.workflows,"workflows",V,n),J(o,n),p(o.secrets_store_secrets,"secrets_store_secrets",Z,n);for(const d of ee)se(o,d,n,i);for(const d of ie)p(o[d.key],d.key,d,n);for(const d of ne)te(o,d,n);return oe(o,n,i),re(o,n),ce(o,n),de(o,n),ue(o,n),le(o,n),me(o,n),ge(o,n),{errors:n,valid:n.length===0,warnings:i}},Ue=w,O=e=>Array.isArray(e)?e:[],pe=(e,s,t)=>{const n=[];for(const i of O(e)){const a=i?.image;typeof a!="string"||!(a.startsWith("./")||a.startsWith("../")||a.startsWith("/")||a.includes("Dockerfile"))||g(a.startsWith("/")?a:f(s,a))||n.push(`containers image "${a}" does not exist (resolved relative to ${t}); create the Dockerfile or point image at a registry reference`)}return n},he=(e,s,t)=>{const n=f(s,x);if(g(n))return n;if(typeof e=="string"&&e.length>0){const i=f(R(t),e);return g(i)?i:void 0}return I.map(i=>f(s,i)).find(i=>g(i))},ye=/\/\/[^\n]*|\/\*.*?\*\/|"[^"\n]*"|'[^'\n]*'|`[^`]*`/gsu,_e=e=>e.replaceAll(ye,s=>s.replaceAll(/[^\n]/gu," ")),ve=/\bexport\s*\*\s*(?:as\s+\w+\s*)?from\b/u,Ee=/\bexport\b/gu,$e=/^\s*(?:(?:abstract|async|declare|default)\s+)*/u,Se=/^(?:class|const|function|let|var)\s+(?<name>[$A-Z_a-z][\w$]*)/u,Ae=/^\s*(?:const|let|var)\s*\{/u,je=/^[$A-Z_a-z][\w$]*/u,Re=/^type\b/u,ke=/\s+/u,Me=e=>{const s=[];for(const t of e.split(",")){const n=t.trim().split(ke).filter(Boolean),i=n.at(-1);i!==void 0&&n[0]!=="type"&&s.push(i)}return s},we=e=>{const s=[];for(const t of e.split(",")){const n=t.includes(":")?t.slice(t.indexOf(":")+1):t,i=je.exec(n.trim());i&&s.push(i[0])}return s},j=e=>{const s=e.indexOf("{"),t=e.indexOf("}",s);return s===-1||t===-1?void 0:e.slice(s+1,t)},Oe=e=>{const s=e.trimStart();if(Re.test(s))return[];if(s.startsWith("{")){const n=j(s);return n===void 0?[]:Me(n)}if(Ae.test(e)){const n=j(e);return n===void 0?[]:we(n)}const t=Se.exec(e.replace($e,""));return t?.groups?.name===void 0?[]:[t.groups.name]},De=e=>{const s=new Set;for(const t of e.matchAll(Ee))for(const n of Oe(e.slice(t.index+6)))s.add(n);return s},Ne=(e,s,t)=>{const n=he(e.main,s,t);if(n===void 0)return[];let i;try{i=N(n,"utf8")}catch{return[]}const a=_e(i);if(ve.test(a))return[];const o=[];for(const c of b(e.durable_objects?.bindings))typeof c.class_name=="string"&&c.class_name.length>0&&c.script_name===void 0&&o.push({className:c.class_name,label:"durable_objects.bindings"});for(const c of O(e.workflows))typeof c?.class_name=="string"&&c.class_name.length>0&&c.script_name===void 0&&o.push({className:c.class_name,label:"workflows"});const r=De(a);return o.filter(c=>!r.has(c.className)).map(c=>`${c.label} declares class "${c.className}" but the worker entry (${n}) does not export it — wrangler refuses to bundle a Worker whose Durable Object classes are not exported. Add \`export { ${c.className} } from "…";\` to the entry.`)},Pe=e=>{const s=e.schemaDir??"lunora",t=T(e.projectRoot);if(!t){const u=`wrangler.jsonc not found in ${e.projectRoot}; create one declaring at least the SHARD durable object binding.`;return{problems:[u],report:{errors:[u],valid:!1,warnings:[]},wranglerPath:void 0}}const{parsed:n}=B(t);if(n===void 0){const u=`failed to parse ${t} as JSONC.`;return{problems:[u],report:{errors:[u],valid:!1,warnings:[]},wranglerPath:t}}const{error:i,merged:a}=k(n,e.environment);if(i!==void 0)return{problems:[i],report:{errors:[i],valid:!1,warnings:[]},wranglerPath:t};const{error:o,info:r}=L(e.projectRoot,s),l=w(n,r,e.environment);o!==void 0&&l.warnings.push(`schema parse failed in ${s}/schema.ts: ${o}`);const c=R(t);l.errors.push(...pe(a.containers??[],c,t)),l.warnings.push(...Ne(a,e.projectRoot,t));const d=a.assets?.directory;if(typeof d=="string"&&d.length>0){const u=d.startsWith("/")?d:f(c,d);g(u)||l.warnings.push(`assets.directory "${d}" does not exist yet — it is created by the client build; run the build before deploy`)}return l.valid=l.errors.length===0,{problems:l.errors,report:l,wranglerPath:t}};export{v as REQUIRED_COMPATIBILITY_DATE,We as REQUIRED_FLAG,k as mergeWranglerEnvironment,b as objectBindingEntries,h as stringEntries,Ue as validateWrangler,w as validateWranglerConfig,Pe as validateWranglerProject,qe as withTailConsumer};
1
+ import{existsSync as g,readFileSync as N}from"node:fs";import{dirname as R,join as f}from"node:path";import{COMPOSED_WORKER_ENTRY as x,WORKER_ENTRY_FALLBACKS as I}from"./COMPOSED_WORKER_ENTRY-CbtPPFQK.mjs";import{discoverSchemaInfo as L}from"./discoverSchemaInfo-Bg2CUZXG.mjs";import{isCacheEnabled as C,WORKERS_CACHE_MIN_DATE as _}from"./WORKERS_CACHE_MIN_DATE-0k9ABJtF.mjs";import{findWranglerFile as T,readWranglerJsonc as B}from"./WRANGLER_FILES-UNW-xY5u.mjs";const W=new Set(["1","enabled","on","true","yes"]),q=e=>typeof e=="string"&&W.has(e.trim().toLowerCase()),v="2026-04-07",We="web_socket_auto_reply_to_close",E=/^\d{4}-\d{2}-\d{2}$/,$=["containers","d1_databases","durable_objects","kv_namespaces","queues","r2_buckets","secrets_store_secrets","services","tail_consumers","vars","vectorize","workflows"],S=["assets","compatibility_date","exports","logpush","main","migrations","observability","placement"],k=(e,s)=>{if(s===void 0)return{merged:e,unverifiedKeys:[]};const t=e.env?.[s];if(t===void 0){const r=Object.keys(e.env??{}).toSorted((c,d)=>c.localeCompare(d)),l=r.length>0?` (declared: ${r.join(", ")}).`:" (no environments are declared).";return{error:`--env "${s}" names no environment declared in wrangler.jsonc's "env" block${l}`,merged:e,unverifiedKeys:[]}}const n={...e},i=Object.keys(t).filter(r=>r!=="env");for(const r of i)S.includes(r)&&(n[r]=t[r]);for(const r of $)n[r]=t[r];const a=new Set([...$,...S]),o=i.filter(r=>!a.has(r)).map(String);return{merged:n,unverifiedKeys:o}},U=(e,s,t)=>{if(s.length===0)return;const n=e.vectorize??[],i=new Set(n.filter(Boolean).map(a=>a?.index_name));for(const a of s)i.has(a)||t.push(`schema declares vector index "${a}"; wrangler "vectorize" must include a binding with index_name "${a}"`)},P=new Set(["basic","dev","lite","standard","standard-1","standard-2","standard-3","standard-4"]),F={disk_mb:2e4,memory_mib:12288,vcpu:4},K=(e,s,t)=>{const n=e.instance_type;if(n===void 0)return;if(typeof n=="string"){P.has(n)||t.push(`${s} has unknown instance_type "${n}" — expected lite, basic, standard-1..4, or a custom { vcpu, memory_mib, disk_mb } object`);return}for(const[r,l]of Object.entries(F)){const c=n[r];c!==void 0&&(typeof c!="number"||c<=0||c>l)&&t.push(`${s} custom instance_type ${r} must be a positive number ≤ ${String(l)} (got ${String(c)})`)}const{disk_mb:i,memory_mib:a,vcpu:o}=n;if(typeof o=="number"&&typeof a=="number"&&a<o*3072&&t.push(`${s} custom instance_type needs ≥ 3 GiB (3072 MiB) memory per vCPU (got ${String(a)} MiB for ${String(o)} vCPU)`),typeof a=="number"&&typeof i=="number"){const r=Math.floor(a/1024*2e3);i>r&&t.push(`${s} custom instance_type allows ≤ 2 GB disk per GiB memory (≤ ${String(r)} MB for ${String(a)} MiB memory; got ${String(i)} MB)`)}},G=(e,s,t)=>{const{boundClasses:n,classKinds:i,errors:a,warnings:o}=t;if(!e||typeof e!="object"||typeof e.class_name!="string"||e.class_name.length===0){a.push(`${s} must have a non-empty "class_name" naming its container-enabled Durable Object class`);return}(typeof e.image!="string"||e.image.length===0)&&a.push(`${s} ("${e.class_name}") must have an "image" — a Dockerfile path or a registry reference`),n.has(e.class_name)||a.push(`${s} class "${e.class_name}" has no matching durable_objects binding — your dev server auto-reconciles this on startup; add { "name": "...", "class_name": "${e.class_name}" } to fix it by hand`);const r=i.get(e.class_name);r!=="sqlite"&&a.push(r==="classic"?`${s} class "${e.class_name}" is registered via "new_classes" but containers require SQLite-backed DOs — move it to "new_sqlite_classes"`:`${s} class "${e.class_name}" is missing from migrations — add a migration entry with "new_sqlite_classes": ["${e.class_name}"]`),K(e,`${s} ("${e.class_name}")`,a),e.max_instances===void 0&&o.push(`${s} ("${e.class_name}") declares no max_instances — set a cap so a traffic spike can't fan out unbounded container spend`)},m=e=>typeof e=="string"&&e.length>0,b=e=>Array.isArray(e)?e.filter(s=>s!==null&&typeof s=="object"):[],h=e=>Array.isArray(e)?e.filter(s=>m(s)):[],M=e=>{const s=new Map;for(const t of b(e)){for(const n of h(t.new_classes))s.set(n,"classic");for(const n of h(t.new_sqlite_classes))s.set(n,"sqlite");for(const n of b(t.renamed_classes))if(m(n.from)&&m(n.to)){const i=s.get(n.from)??"sqlite";s.delete(n.from),s.set(n.to,i)}for(const n of h(t.deleted_classes))s.delete(n)}return s},Y=e=>new Set(M(e).keys()),Q=(e,s)=>{const t=Y(e.migrations);for(const n of b(e.durable_objects?.bindings))n.script_name===void 0&&m(n.class_name)&&!t.has(n.class_name)&&s.push(`durable_objects.bindings declares class "${n.class_name}" but it is missing from migrations — add a migration entry with "new_sqlite_classes": ["${n.class_name}"] (or "new_classes" for a non-SQLite-backed class), or let the dev server auto-reconcile it on the next start`)},H=(e,s,t)=>{if(e.containers===void 0)return;if(!Array.isArray(e.containers)){s.push("containers must be an array of { class_name, image, ... } entries");return}const n=e.containers;if(n.length===0)return;const i=new Set(b(e.durable_objects?.bindings).map(o=>o.class_name)),a=M(e.migrations);for(const[o,r]of n.entries())G(r,`containers[${String(o)}]`,{boundClasses:i,classKinds:a,errors:s,warnings:t});e.observability?.enabled!==!0&&t.push('containers are configured but observability is not enabled — container logs will not be captured (add { "observability": { "enabled": true } })')},y=e=>e,p=(e,s,t,n)=>{if(e!==void 0){if(!Array.isArray(e)){n.push(t.arrayMessage);return}for(const[i,a]of y(e).entries()){const o=`${s}[${String(i)}]`;if(!a||typeof a!="object"){n.push(t.objectMessage(o));continue}for(const r of t.fields)m(a[r.field])||n.push(r.message(o))}}},V={arrayMessage:"workflows must be an array of { name, binding, class_name } entries",fields:[{field:"binding",message:e=>`${e} must have a non-empty "binding" naming the Workflow binding (e.g. WORKFLOW_ORDER_PIPELINE)`},{field:"class_name",message:e=>`${e} must have a non-empty "class_name" naming the exported WorkflowEntrypoint class`},{field:"name",message:e=>`${e} must have a non-empty "name" naming the deployed workflow`}],objectMessage:e=>`${e} must be a { name, binding, class_name } object`},z={arrayMessage:"queues.producers must be an array of { binding, queue } entries",fields:[{field:"binding",message:e=>`${e} must have a non-empty "binding" naming the Queue producer (e.g. QUEUE_EMAIL)`},{field:"queue",message:e=>`${e} must have a non-empty "queue" naming the deployed queue`}],objectMessage:e=>`${e} must be a { binding, queue } object`},X={arrayMessage:"queues.consumers must be an array of { queue } entries",fields:[{field:"queue",message:e=>`${e} must have a non-empty "queue" naming the consumed queue`}],objectMessage:e=>`${e} must be a { queue } object`},J=(e,s)=>{if(e.queues!==void 0){if(typeof e.queues!="object"||Array.isArray(e.queues)){s.push("queues must be a { producers, consumers } object");return}p(e.queues.producers,"queues.producers",z,s),p(e.queues.consumers,"queues.consumers",X,s)}},Z={arrayMessage:"secrets_store_secrets must be an array of { binding, store_id, secret_name } entries",fields:["binding","store_id","secret_name"].map(e=>({field:e,message:s=>`${s} must have a non-empty "${e}"`})),objectMessage:e=>`${e} must be a { binding, store_id, secret_name } object`},ee=[{arrayMessage:"kv_namespaces must be an array of { binding, id } entries",bindingMessage:e=>`${e} must have a non-empty "binding" naming the KV namespace binding`,hintField:"id",hintMessage:(e,s)=>`${e} ("${s}") has no "id" — run \`wrangler kv namespace create\` and set the namespace id, or the binding can't resolve`,key:"kv_namespaces"},{arrayMessage:"flagship must be an array of { binding, app_id } entries",bindingMessage:e=>`${e} must have a non-empty "binding" naming the Flagship binding`,hintField:"app_id",hintMessage:(e,s)=>`${e} ("${s}") has no "app_id" — create a Flagship app and set its id, or the binding can't resolve`,key:"flagship"},{arrayMessage:"hyperdrive must be an array of { binding, id } entries",bindingMessage:e=>`${e} must have a non-empty "binding" naming the Hyperdrive binding`,hintField:"id",hintMessage:(e,s)=>`${e} ("${s}") has no "id" — run \`wrangler hyperdrive create\` and set the id, or the binding can't connect`,key:"hyperdrive"},{arrayMessage:"pipelines must be an array of { binding, stream } entries",bindingMessage:e=>`${e} must have a non-empty "binding" naming the Pipelines binding`,hintField:["stream","pipeline"],hintMessage:(e,s)=>`${e} ("${s}") has no "stream" — run \`wrangler pipelines create <name>\` and set the stream name, or the binding can't resolve`,key:"pipelines"},{arrayMessage:"analytics_engine_datasets must be an array of { binding, dataset } entries",bindingMessage:e=>`${e} must have a non-empty "binding" naming the Analytics Engine binding`,hintField:"dataset",hintMessage:(e,s)=>`${e} ("${s}") has no "dataset" — it defaults to the binding name; set it explicitly to avoid drift`,key:"analytics_engine_datasets"}],se=(e,s,t,n)=>{const i=e[s.key];if(i!==void 0){if(!Array.isArray(i)){t.push(s.arrayMessage);return}for(const[a,o]of y(i).entries()){const r=`${s.key}[${String(a)}]`;if(!o||typeof o!="object"||!m(o.binding)){t.push(s.bindingMessage(r));continue}(typeof s.hintField=="string"?[s.hintField]:s.hintField).some(c=>m(o[c]))||n.push(s.hintMessage(r,o.binding))}}},ne=[{key:"browser",message:'browser must be an object with a non-empty "binding" (e.g. { "binding": "BROWSER" })'},{key:"images",message:'images must be an object with a non-empty "binding" (e.g. { "binding": "IMAGES" })'}],te=(e,s,t)=>{const n=e[s.key];n!==void 0&&(typeof n!="object"||n===null||Array.isArray(n)||!m(n.binding))&&t.push(s.message)},ie=[{arrayMessage:"services must be an array of { binding, service, entrypoint? } entries",fields:[{field:"binding",message:e=>`${e} must have a non-empty "binding" naming the service binding`},{field:"service",message:e=>`${e} must have a non-empty "service" naming the target Worker`}],key:"services",objectMessage:e=>`${e} must be a { binding, service, entrypoint? } object`},{arrayMessage:"dispatch_namespaces must be an array of { binding, namespace } entries",fields:[{field:"binding",message:e=>`${e} must have a non-empty "binding"`},{field:"namespace",message:e=>`${e} must have a non-empty "namespace" naming the dispatch namespace`}],key:"dispatch_namespaces",objectMessage:e=>`${e} must be a { binding, namespace } object`},{arrayMessage:"mtls_certificates must be an array of { binding, certificate_id } entries",fields:[{field:"binding",message:e=>`${e} must have a non-empty "binding"`},{field:"certificate_id",message:e=>`${e} must have a non-empty "certificate_id" (upload via \`wrangler mtls-certificate upload\`)`}],key:"mtls_certificates",objectMessage:e=>`${e} must be a { binding, certificate_id } object`},{arrayMessage:"r2_buckets must be an array of { binding, bucket_name } entries",fields:[{field:"binding",message:e=>`${e} must have a non-empty "binding" naming the R2 bucket binding`},{field:"bucket_name",message:e=>`${e} must have a non-empty "bucket_name" naming the deployed bucket`}],key:"r2_buckets",objectMessage:e=>`${e} must be a { binding, bucket_name } object`}],ae=(e,s)=>{const{d1_databases:t}=e;if(t!==void 0){if(!Array.isArray(t)){s.push("d1_databases must be an array of { binding, database_id | database_name } entries");return}for(const[n,i]of y(t).entries()){const a=`d1_databases[${String(n)}]`;if(!i||typeof i!="object"){s.push(`${a} must be a { binding, database_id | database_name } object`);continue}m(i.binding)||s.push(`${a} must have a non-empty "binding" naming the D1 binding`),!m(i.database_id)&&!m(i.database_name)&&s.push(`${a} must have a "database_id" or a "database_name" — run \`wrangler d1 create\` and set one, or the binding can't resolve`)}}},oe=(e,s,t)=>{const n=e.send_email;if(n===void 0)return;if(!Array.isArray(n)){s.push("send_email must be an array of { name, destination_address? } entries");return}const i=n;for(const[a,o]of i.entries())(!o||typeof o!="object"||typeof o.name!="string"||o.name.length===0)&&t.push(`send_email[${String(a)}] has no non-empty "name" naming the send-email binding — set one before deploying`)},re=(e,s)=>{e.logpush!==void 0&&typeof e.logpush!="boolean"&&s.push('logpush must be a boolean (set "logpush": true to enable Cloudflare Logpush)')},A=new Set(["off","smart","targeted"]),ce=(e,s)=>{const{placement:t}=e;if(t===void 0)return;if(typeof t!="object"||t===null||Array.isArray(t)){s.push('placement must be an object (e.g. { "mode": "smart" })');return}const{mode:n}=t;n!==void 0&&(typeof n!="string"||!A.has(n))&&s.push(`placement.mode must be one of ${[...A].map(i=>`"${i}"`).join(", ")}`)},de=(e,s)=>{const{observability:t}=e;if(t===void 0)return;if(typeof t!="object"||Array.isArray(t)){s.push('observability must be an object (e.g. { "enabled": true, "head_sampling_rate": 1 })');return}const n=(i,a)=>{i!==void 0&&(typeof i!="number"||Number.isNaN(i)||i<0||i>1)&&s.push(`${a} must be a number in [0, 1] (the fraction of requests sampled)`)};n(t.head_sampling_rate,"observability.head_sampling_rate"),t.logs!==void 0&&(typeof t.logs!="object"||Array.isArray(t.logs)?s.push("observability.logs must be an object"):n(t.logs.head_sampling_rate,"observability.logs.head_sampling_rate"))},le=(e,s)=>{const{cache:t}=e;if(t!==void 0){if(typeof t!="object"||t===null||Array.isArray(t)){s.push('cache must be an object (e.g. { "enabled": true })');return}t.enabled!==void 0&&typeof t.enabled!="boolean"&&s.push("cache.enabled must be a boolean (true or false)")}},me=(e,s)=>{const{exports:t}=e;if(t!==void 0){if(typeof t!="object"||t===null||Array.isArray(t)){s.push("exports must be an object keyed by entrypoint name");return}for(const[n,i]of Object.entries(t)){if(typeof i!="object"||i===null){s.push(`exports["${n}"] must be an object`);continue}i.type!==void 0&&typeof i.type!="string"&&s.push(`exports["${n}"].type must be a string`),i.cache!==void 0&&(typeof i.cache!="object"||i.cache===null||Array.isArray(i.cache)?s.push(`exports["${n}"].cache must be an object`):i.cache.enabled!==void 0&&typeof i.cache.enabled!="boolean"&&s.push(`exports["${n}"].cache.enabled must be a boolean`))}}},ue=(e,s)=>{const{assets:t}=e;if(t!==void 0){if(typeof t!="object"||Array.isArray(t)){s.push('assets must be an object (e.g. { "directory": "./dist/client", "binding": "ASSETS" })');return}(typeof t.directory!="string"||t.directory.length===0)&&s.push('assets must declare a non-empty "directory" pointing at the built client output (e.g. "./dist/client")'),t.binding!==void 0&&(typeof t.binding!="string"||t.binding.length===0)&&s.push('assets.binding must be a non-empty string (e.g. "ASSETS")'),t.html_handling!==void 0&&typeof t.html_handling!="string"&&s.push("assets.html_handling must be a string"),t.not_found_handling!==void 0&&typeof t.not_found_handling!="string"&&s.push("assets.not_found_handling must be a string")}},be=(e,s)=>{const t=e.tail_consumers;if(t===void 0)return;if(!Array.isArray(t)){s.push("tail_consumers must be an array of { service, environment? } entries");return}const n=t;for(const[i,a]of n.entries())(!a||typeof a!="object"||typeof a.service!="string"||a.service.length===0)&&s.push(`tail_consumers[${String(i)}] must have a non-empty "service" naming the consumer Worker`)},qe=(e,s)=>{const t=e.tail_consumers??[];return t.some(i=>!!i&&i?.service===s.service&&i?.environment===s.environment)?e:{...e,tail_consumers:[...t,s]}},ge=(e,s)=>{const{vars:t}=e;if(!t||typeof t!="object")return;const n=t.LUNORA_ALLOWED_ORIGINS,i=t.LUNORA_CORS_ALLOW_CREDENTIALS,a=typeof n=="string"&&n.split(",").some(r=>r.trim()==="*"),o=q(i);a&&o&&s.push('vars.LUNORA_ALLOWED_ORIGINS includes a "*" wildcard while vars.LUNORA_CORS_ALLOW_CREDENTIALS is on — browsers reject this combination and it defeats the allowlist; name explicit origins or drop credentials')},fe=(e,s,t)=>{const{error:n,merged:i,unverifiedKeys:a}=k(e,s);return n!==void 0?{error:n,wrangler:i}:(a.length>0&&t.push(`env.${String(s)} overrides ${a.join(", ")}, which this validator doesn't have a verified inheritance rule for — validated against the TOP-LEVEL value only. Double-check ${a.length===1?"it":"them"} by hand for "${String(s)}".`),{wrangler:i})},w=(e,s,t)=>{const n=[],i=[];if(!e||typeof e!="object")return n.push("wrangler config is not a valid object"),{errors:n,valid:!1,warnings:i};const{error:a,wrangler:o}=fe(e,t,i);if(a!==void 0)return n.push(a),{errors:n,valid:!1,warnings:i};b(o.durable_objects?.bindings).find(d=>d.name==="SHARD"&&d.class_name==="ShardDO")||n.push('durable_objects.bindings must include { "name": "SHARD", "class_name": "ShardDO" } — your dev server auto-reconciles this on startup, or add the binding manually'),Q(o,n);const c=o.compatibility_date??"";c&&!E.test(c)?n.push(`compatibility_date must be in YYYY-MM-DD format (got "${c}")`):c<v&&n.push(`compatibility_date must be >= "${v}" (got "${c||"<missing>"}")`),C(o)&&E.test(c)&&c<_&&n.push(`cache.enabled requires compatibility_date >= "${_}" (got "${c||"<missing>"}")`),s?.hasGlobalTable&&(b(o.d1_databases).find(D=>D.binding==="DB")||n.push('schema declares .global() tables; d1_databases must include a binding named "DB" — your dev server auto-reconciles this on startup, or add the binding manually')),ae(o,n),U(o,s?.vectorIndexNames??[],n),be(o,n),H(o,n,i),p(o.workflows,"workflows",V,n),J(o,n),p(o.secrets_store_secrets,"secrets_store_secrets",Z,n);for(const d of ee)se(o,d,n,i);for(const d of ie)p(o[d.key],d.key,d,n);for(const d of ne)te(o,d,n);return oe(o,n,i),re(o,n),ce(o,n),de(o,n),ue(o,n),le(o,n),me(o,n),ge(o,n),{errors:n,valid:n.length===0,warnings:i}},Ue=w,O=e=>Array.isArray(e)?e:[],pe=(e,s,t)=>{const n=[];for(const i of O(e)){const a=i?.image;typeof a!="string"||!(a.startsWith("./")||a.startsWith("../")||a.startsWith("/")||a.includes("Dockerfile"))||g(a.startsWith("/")?a:f(s,a))||n.push(`containers image "${a}" does not exist (resolved relative to ${t}); create the Dockerfile or point image at a registry reference`)}return n},he=(e,s,t)=>{const n=f(s,x);if(g(n))return n;if(typeof e=="string"&&e.length>0){const i=f(R(t),e);return g(i)?i:void 0}return I.map(i=>f(s,i)).find(i=>g(i))},ye=/\/\/[^\n]*|\/\*.*?\*\/|"[^"\n]*"|'[^'\n]*'|`[^`]*`/gsu,_e=e=>e.replaceAll(ye,s=>s.replaceAll(/[^\n]/gu," ")),ve=/\bexport\s*\*\s*(?:as\s+\w+\s*)?from\b/u,Ee=/\bexport\b/gu,$e=/^\s*(?:(?:abstract|async|declare|default)\s+)*/u,Se=/^(?:class|const|function|let|var)\s+(?<name>[$A-Z_a-z][\w$]*)/u,Ae=/^\s*(?:const|let|var)\s*\{/u,je=/^[$A-Z_a-z][\w$]*/u,Re=/^type\b/u,ke=/\s+/u,Me=e=>{const s=[];for(const t of e.split(",")){const n=t.trim().split(ke).filter(Boolean),i=n.at(-1);i!==void 0&&n[0]!=="type"&&s.push(i)}return s},we=e=>{const s=[];for(const t of e.split(",")){const n=t.includes(":")?t.slice(t.indexOf(":")+1):t,i=je.exec(n.trim());i&&s.push(i[0])}return s},j=e=>{const s=e.indexOf("{"),t=e.indexOf("}",s);return s===-1||t===-1?void 0:e.slice(s+1,t)},Oe=e=>{const s=e.trimStart();if(Re.test(s))return[];if(s.startsWith("{")){const n=j(s);return n===void 0?[]:Me(n)}if(Ae.test(e)){const n=j(e);return n===void 0?[]:we(n)}const t=Se.exec(e.replace($e,""));return t?.groups?.name===void 0?[]:[t.groups.name]},De=e=>{const s=new Set;for(const t of e.matchAll(Ee))for(const n of Oe(e.slice(t.index+6)))s.add(n);return s},Ne=(e,s,t)=>{const n=he(e.main,s,t);if(n===void 0)return[];let i;try{i=N(n,"utf8")}catch{return[]}const a=_e(i);if(ve.test(a))return[];const o=[];for(const c of b(e.durable_objects?.bindings))typeof c.class_name=="string"&&c.class_name.length>0&&c.script_name===void 0&&o.push({className:c.class_name,label:"durable_objects.bindings"});for(const c of O(e.workflows))typeof c?.class_name=="string"&&c.class_name.length>0&&c.script_name===void 0&&o.push({className:c.class_name,label:"workflows"});const r=De(a);return o.filter(c=>!r.has(c.className)).map(c=>`${c.label} declares class "${c.className}" but the worker entry (${n}) does not export it — wrangler refuses to bundle a Worker whose Durable Object classes are not exported. Add \`export { ${c.className} } from "…";\` to the entry.`)},Pe=e=>{const s=e.schemaDir??"lunora",t=T(e.projectRoot);if(!t){const u=`wrangler.jsonc not found in ${e.projectRoot}; create one declaring at least the SHARD durable object binding.`;return{problems:[u],report:{errors:[u],valid:!1,warnings:[]},wranglerPath:void 0}}const{parsed:n}=B(t);if(n===void 0){const u=`failed to parse ${t} as JSONC.`;return{problems:[u],report:{errors:[u],valid:!1,warnings:[]},wranglerPath:t}}const{error:i,merged:a}=k(n,e.environment);if(i!==void 0)return{problems:[i],report:{errors:[i],valid:!1,warnings:[]},wranglerPath:t};const{error:o,info:r}=L(e.projectRoot,s),l=w(n,r,e.environment);o!==void 0&&l.warnings.push(`schema parse failed in ${s}/schema.ts: ${o}`);const c=R(t);l.errors.push(...pe(a.containers??[],c,t)),l.warnings.push(...Ne(a,e.projectRoot,t));const d=a.assets?.directory;if(typeof d=="string"&&d.length>0){const u=d.startsWith("/")?d:f(c,d);g(u)||l.warnings.push(`assets.directory "${d}" does not exist yet — it is created by the client build; run the build before deploy`)}return l.valid=l.errors.length===0,{problems:l.errors,report:l,wranglerPath:t}};export{v as REQUIRED_COMPATIBILITY_DATE,We as REQUIRED_FLAG,k as mergeWranglerEnvironment,b as objectBindingEntries,h as stringEntries,Ue as validateWrangler,w as validateWranglerConfig,Pe as validateWranglerProject,qe as withTailConsumer};
@@ -0,0 +1 @@
1
+ import{existsSync as a,readFileSync as d}from"node:fs";import{classifyEdit as l,applyAdditiveEdit as c}from"./applyAdditiveEdit-CH0VhMJ2.mjs";import{parseSchema as u}from"./parseSchema-D1Wbr1qv.mjs";import{w as f,r as p}from"./write-atomic-9d9xs5ON.mjs";import{join as m}from"node:path";const F="/__lunora/schema-edit",b=t=>t==="destructive"||t==="duplicate-table"||t==="duplicate-column"||t==="duplicate-index"?409:t==="unknown-table"?404:t==="invalid-identifier"||t==="invalid-validator"?400:422,y=t=>({body:{error:t.reason,ok:!1},status:422}),h=t=>{if(!a(t))return{response:{body:{error:"no-schema-file",ok:!1},status:404}};const r=u(d(t,"utf8"));return r.ok?{tables:r.tables}:{response:y(r)}},k=t=>({body:{edit:t,message:"This edit changes stored data and must go through a migration. Review the migration before applying.",needsMigration:!0,ok:!1},status:409}),g=(t,r)=>{const e=t.body;if(e==null||typeof e!="object"||typeof e.kind!="string")return{body:{error:"invalid-edit",ok:!1},status:400};if(l(e)==="destructive")return k(e);if(!a(r))return{body:{error:"no-schema-file",ok:!1},status:404};const o=c(d(r,"utf8"),e);if(!o.ok)return{body:{error:o.reason,ok:!1},status:b(o.reason)};f(r,o.text);let i;try{i=p(t)}catch(s){return{body:{error:s instanceof Error?s.message:String(s),ok:!1},status:500}}const n=u(o.text);return{body:{diagnostics:i,ok:!0,tables:n.ok?n.tables:[]},status:200}},R=t=>{const r=m(t.projectRoot,t.schemaDirectory??"lunora","schema.ts");if(t.method==="GET"){const e=h(r);return"response"in e?e.response:{body:{ok:!0,tables:e.tables},status:200}}return t.method==="POST"?g(t,r):{body:{error:"method-not-allowed",ok:!1},status:405}};export{F as SCHEMA_EDIT_ENDPOINT,R as handleSchemaEditRequest};
@@ -0,0 +1 @@
1
+ import{spawnSync as o}from"node:child_process";import{LunoraError as s}from"@lunora/errors";import{findPackageManagerSync as i,identifyInitiatingPackageManager as c}from"@visulima/package/package-manager";const a=["pnpm","bun","yarn","npm"],u=new Set(a),d=n=>u.has(n),m=n=>{try{return o(n,["--version"],{shell:process.platform==="win32",stdio:"ignore",timeout:5e3}).status===0}catch{return!1}},p=(n=m)=>a.filter(r=>n(r)),A=n=>({args:["install"],command:n}),y=(n,r,t={})=>{const e=t.dev===!0;return n==="npm"?{args:["install",...e?["--save-dev"]:[],...r],command:"npm"}:n==="bun"?{args:["add",...e?["-d"]:[],...r],command:"bun"}:{args:["add",...e?["-D"]:[],...r],command:n}},M=n=>{try{return i(n).packageManager}catch{}const r=c();if(r!==void 0){const e=r.name==="cnpm"?"npm":r.name;if(d(e))return e}const[t]=p();if(t!==void 0)return t;throw new s("INTERNAL","Could not detect a package manager: no lock file or `packageManager` field was found, and none (pnpm, bun, yarn, npm) is installed on PATH.")},b=(n,r,t)=>n==="yarn"?{args:[r,...t],command:"yarn"}:n==="bun"?{args:["x",r,...t],command:"bun"}:n==="npm"?{args:["--",r,...t],command:"npx"}:{args:["exec",r,...t],command:"pnpm"},E=(n,r)=>({args:["run",r],command:n}),v=(n,r)=>n==="npm"?`npm run ${r}`:n==="bun"?`bun run ${r}`:`${n} ${r}`;export{y as addArgsFor,p as detectInstalledManagers,M as detectPackageManager,b as execArgsFor,A as installArgsFor,E as runScriptArgsFor,v as runScriptCommand};
@@ -1,4 +1,4 @@
1
- import{randomBytes as V}from"node:crypto";import{existsSync as y,readFileSync as f,writeFileSync as _,renameSync as A,rmSync as x,statSync as b}from"node:fs";import{join as g}from"node:path";import{LunoraError as L}from"@lunora/errors";import{DEV_VARS_FILE as u,DEV_VARS_EXAMPLE_FILE as m,parseDevVariableLine as h,parseDevVariableEntries as K,DEV_VARS_NEWLINE as C}from"./DEV_VARS_EXAMPLE_FILE-CqLorAxT.mjs";import{C as R,M,s as F}from"./package-secrets-registry-CFZ5bA8L.mjs";const D=e=>[...R,...F(e)],S=32,j=["replace","openssl","changeme","change-me","change_me","change-this","change_this","your-","your_","example","placeholder","todo","fill-me","fill_me","fill-in","fill_in","xxx"],T=/[.*+?^${}()|[\]\\]/gu,z=/[a-z0-9]$/u,N=e=>{const t=e.trim().toLowerCase();return t===""||t.startsWith("<")&&t.endsWith(">")?!0:j.some(r=>{const s=r.replaceAll(T,String.raw`\$&`),o=z.test(r)?`(^|[^a-z0-9])${s}([^a-z0-9]|$)`:`(^|[^a-z0-9])${s}`;return new RegExp(o,"u").test(t)})},p=e=>V(e).toString("hex"),B=e=>M.has(e),H=(e,t,r)=>B(e)&&N(t)?r(S):void 0,se=(e=p)=>e(S),P=(e,t,r)=>e.split(C).map(s=>{const n=h(s),o=n?H(n.key,n.value,t):void 0;return!n||o===void 0?s:(r.push(n.key),`${n.key}="${o}"`)}),I=e=>{if(e.devVarsExists)return{status:"exists"};if(e.exampleContent===void 0)return{status:"no-example"};const t=[];return{content:P(e.exampleContent,e.randomHex??p,t).join(`
1
+ import{randomBytes as V}from"node:crypto";import{existsSync as y,readFileSync as f,writeFileSync as _,renameSync as A,rmSync as x,statSync as b}from"node:fs";import{join as g}from"node:path";import{LunoraError as L}from"@lunora/errors";import{DEV_VARS_FILE as u,DEV_VARS_EXAMPLE_FILE as m,parseDevVariableLine as h,parseDevVariableEntries as K,DEV_VARS_NEWLINE as C}from"./DEV_VARS_EXAMPLE_FILE-CqLorAxT.mjs";import{C as R,M,s as F}from"./package-secrets-registry-DvtTiK4b.mjs";const D=e=>[...R,...F(e)],S=32,j=["replace","openssl","changeme","change-me","change_me","change-this","change_this","your-","your_","example","placeholder","todo","fill-me","fill_me","fill-in","fill_in","xxx"],T=/[.*+?^${}()|[\]\\]/gu,z=/[a-z0-9]$/u,N=e=>{const t=e.trim().toLowerCase();return t===""||t.startsWith("<")&&t.endsWith(">")?!0:j.some(r=>{const s=r.replaceAll(T,String.raw`\$&`),o=z.test(r)?`(^|[^a-z0-9])${s}([^a-z0-9]|$)`:`(^|[^a-z0-9])${s}`;return new RegExp(o,"u").test(t)})},p=e=>V(e).toString("hex"),B=e=>M.has(e),H=(e,t,r)=>B(e)&&N(t)?r(S):void 0,se=(e=p)=>e(S),P=(e,t,r)=>e.split(C).map(s=>{const n=h(s),o=n?H(n.key,n.value,t):void 0;return!n||o===void 0?s:(r.push(n.key),`${n.key}="${o}"`)}),I=e=>{if(e.devVarsExists)return{status:"exists"};if(e.exampleContent===void 0)return{status:"no-example"};const t=[];return{content:P(e.exampleContent,e.randomHex??p,t).join(`
2
2
  `),generatedKeys:t,status:"generate"}},W=e=>e.includes('"')||e.includes("\\")?"":e.replaceAll("\r",String.raw`\r`).replaceAll(`
3
3
  `,String.raw`\n`),E=e=>{const t=e.randomHex??p,r=new Set(K(e.existingContent).map(d=>d.key)),s=[],n=[],o=[];for(const d of e.exampleContent.split(C)){const i=h(d);if(!i||r.has(i.key))continue;const a=H(i.key,i.value,t);o.push(i.key),a===void 0?s.push(`${i.key}="${W(i.value)}"`):(n.push(i.key),s.push(`${i.key}="${a}"`))}return{additions:s,generatedKeys:n,missingKeys:o}},w=e=>e.length>0?` (generated ${e.join(", ")})`:"",$=(e,t,r={})=>{const s=`${e}.tmp-${String(process.pid)}`;try{_(s,t,{encoding:"utf8",...r}),A(s,e)}catch(n){throw x(s,{force:!0}),n}},re=(e,t)=>{$(e,t,{mode:384})},k=5,v=e=>{try{const t=b(e);return{mtimeMs:t.mtimeMs,size:t.size}}catch{return}},G=(e,t)=>e===void 0||t===void 0?!1:e.mtimeMs===t.mtimeMs&&e.size===t.size,O=(e,t)=>{for(let r=0;r<k;r+=1){const s=v(e),n=f(e,"utf8"),o=t(n);if(o.length===0)return[];const d=n.length>0&&!n.endsWith(`
4
4
  `)?`
@@ -0,0 +1 @@
1
+ import{writeFileSync as B,readFileSync as C}from"node:fs";import{join as A}from"node:path";import{containerBuildTag as P}from"@lunora/container";import{DEV_VARS_FILE as O,parseDevVariableEntries as I}from"./DEV_VARS_EXAMPLE_FILE-CqLorAxT.mjs";import{a as b}from"./jsonc-edit-BZgQIdAH.mjs";import{findWranglerFile as $,readWranglerJsonc as R}from"./WRANGLER_FILES-UNW-xY5u.mjs";import{objectBindingEntries as E,stringEntries as v}from"./REQUIRED_COMPATIBILITY_DATE-vJI8hq20.mjs";const k="<replace-with-d1-create-id>",T=e=>[["container","containers",e.containers],["workflow","workflows",e.workflows],["agent","agents",e.agents]].flatMap(([n,t,o])=>o.filter(a=>!a.exported).map(({className:a,exportName:c})=>({className:a,exportName:c,kind:n,module:t}))),_="PIPELINES",M=(e,s)=>{const n=e.flagshipBinding!==void 0&&!(s?.flagship??[]).some(a=>a.binding===e.flagshipBinding),t=e.usesPipelines&&!(s?.pipelines??[]).some(a=>a.binding===_);return[[e.usesKv&&(s?.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&&(s?.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."],[t,`ctx.pipelines is used but no "${_}" pipelines binding exists; run 'wrangler pipelines create <name>' and add a 'pipelines' binding ({ binding: "${_}", pipeline }) — codegen resolves this one name, and 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(([a])=>a).map(([,a])=>a)},W=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(([n])=>n).map(([,n])=>n),x=(e,s,n)=>n.filter(t=>!t.exported).map(t=>`${e} "${t.exportName}" is declared but ${t.className} is not exported by the worker entry; add \`export * from "./lunora/_generated/${s}"\` so its binding can be provisioned.`),D=[{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"}],K=()=>D.map(({keys:e,label:s})=>`${e[0]} + ${e[1]} (${s})`).join(" or "),L=e=>{let s;try{s=C(A(e,O),"utf8")}catch{return!1}const n=new Map(I(s).map(t=>[t.key,t.value]));return D.some(({keys:t})=>t.every(o=>(n.get(o)??"")!==""))},y=(e,s,n)=>{const t=new Set(e.durableObjects.map(d=>d.className)),o=[],a=(n?.r2_buckets?.length??0)>0,c=(n?.d1_databases?.some(d=>d.binding==="DB")??!1)||e.needsD1;return e.usesStorage&&!a&&o.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&&!t.has("SessionDO")&&!c&&o.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&&!t.has("SchedulerDO")&&o.push("@lunora/scheduler is used but the worker entry exports no SchedulerDO; export it so the SCHEDULER binding can be provisioned."),o.push(...x("container","containers",e.containers),...x("workflow","workflows",e.workflows),...x("agent","agents",e.agents)),e.containers.length>0&&n?.observability?.enabled===!1&&o.push("containers are declared but observability is explicitly disabled in wrangler.jsonc — container logs will not be captured."),e.usesPayment&&!L(s)&&o.push(`@lunora/payment is used; set one provider's secret pair in .dev.vars — ${K()}.`),o.push(...W(e),...M(e,n)),o},Y=e=>{const s=new Set(E(e).map(t=>t.tag));let n=1;for(;s.has(`v${String(n)}`);)n+=1;return`v${String(n)}`},H=e=>{const s=new Set;for(const n of E(e)){for(const t of v(n.deleted_classes))s.delete(t);for(const{from:t,to:o}of E(n.renamed_classes))t!==void 0&&s.delete(t),o!==void 0&&s.add(o);for(const t of[...v(n.new_classes),...v(n.new_sqlite_classes)])s.add(t)}return s},j=(e,s,n)=>{const t=s.durable_objects?.bindings??[],o=new Set(t.map(g=>g.name)),a=n.filter(g=>!o.has(g.binding));let c=e;const d=[];if(a.length>0){const g=[...t,...a.map(p=>({class_name:p.className,name:p.binding}))];c=b(c,["durable_objects","bindings"],g),d.push(...a.map(p=>`${p.binding}/${p.className}`))}const u=s.migrations??[],l=n.map(g=>g.className).filter(g=>!H(u).has(g));if(l.length>0){const g=[...u,{new_sqlite_classes:l,tag:Y(u)}];c=b(c,["migrations"],g)}return{added:d,text:c}},F=(e,s)=>{const n=s.d1_databases??[];if(n.some(a=>a.binding==="DB"))return{added:[],text:e};const t=typeof s.name=="string"&&s.name.length>0?s.name:"lunora",o=[...n,{binding:"DB",database_id:k,database_name:t}];return{added:["DB (D1)"],text:b(e,["d1_databases"],o)}},w=(e,s,n,t,o)=>{const a=s[n]?.binding;return typeof a=="string"&&a.length>0?{added:[],text:e}:{added:[o],text:b(e,[n],{binding:t})}},G=(e,s)=>(s.analytics_engine_datasets?.length??0)>0?{added:[],text:e}:{added:["ANALYTICS (Analytics Engine)"],text:b(e,["analytics_engine_datasets"],[{binding:"ANALYTICS",dataset:"ANALYTICS"}])},U=e=>{if(typeof e=="string")return e;const s={};return e.diskMb!==void 0&&(s.disk_mb=e.diskMb),e.memoryMib!==void 0&&(s.memory_mib=e.memoryMib),e.vcpu!==void 0&&(s.vcpu=e.vcpu),s},V=e=>e.image.kind==="dockerfile"?e.image.dockerfilePath:e.image.kind==="registry"?e.image.reference:P(e.exportName),z=e=>{const s={class_name:e.className,image:V(e)};return e.image.kind==="dockerfile"&&(s.image_build_context=e.image.buildContext),e.buildArgs!==void 0&&e.image.kind!=="registry"&&(s.image_vars=e.buildArgs),e.instanceType!==void 0&&(s.instance_type=U(e.instanceType)),e.maxInstances!==void 0&&(s.max_instances=e.maxInstances),e.name!==void 0&&(s.name=e.name),e.rollout?.stepPercentage!==void 0&&(s.rollout_step_percentage=e.rollout.stepPercentage),e.rollout?.gracePeriodSeconds!==void 0&&(s.rollout_active_grace_period=e.rollout.gracePeriodSeconds),s},Q=(e,s,n)=>{const t=s.containers??[],o=new Set(t.map(d=>d.class_name)),a=n.filter(d=>!o.has(d.className));if(a.length===0)return{added:[],text:e};const c=b(e,["containers"],[...t,...a.map(d=>z(d))]);return{added:a.map(d=>`containers/${d.className}`),text:c}},X=(e,s)=>{if(s.observability!==void 0)return{added:[],text:e};const n=b(e,["observability"],{enabled:!0,head_sampling_rate:1});return{added:["observability"],text:n}},N=e=>({binding:e.bindingName,class_name:e.className,name:e.name}),J=(e,s,n,t=[])=>{const o=s.workflows??[],a=new Set(o.map(l=>l.class_name)),c=n.filter(l=>!a.has(l.className)),d=t.filter(l=>!a.has(l.className));if(c.length===0&&d.length===0)return{added:[],text:e};const u=b(e,["workflows"],[...o,...c.map(l=>N(l)),...d.map(l=>N(l))]);return{added:[...c.map(l=>`workflows/${l.className}`),...d.map(l=>`workflows/${l.className}`)],text:u}},q=(e,s,n)=>{const t=s.queues??{},o=t.producers??[],a=t.consumers??[],c=new Set(o.map(r=>r.binding)),d=new Set(a.map(r=>r.queue)),u=n.filter(r=>!c.has(r.bindingName)),l=n.filter(r=>!d.has(r.name));if(u.length===0&&l.length===0)return{added:[],text:e};const g=[...o,...u.map(r=>({binding:r.bindingName,queue:r.name}))],p=[...a,...l.map(r=>{const m={queue:r.name};return r.mode==="pull"&&(m.type="http_pull"),r.tuning.maxBatchSize!==void 0&&(m.max_batch_size=r.tuning.maxBatchSize),r.tuning.maxBatchTimeout!==void 0&&(m.max_batch_timeout=r.tuning.maxBatchTimeout),r.tuning.maxRetries!==void 0&&(m.max_retries=r.tuning.maxRetries),r.tuning.deadLetterQueue!==void 0&&(m.dead_letter_queue=r.tuning.deadLetterQueue),r.tuning.retryDelay!==void 0&&(m.retry_delay=r.tuning.retryDelay),m})],h=b(e,["queues"],{consumers:p,producers:g});return{added:[...u.map(r=>`queues.producers/${r.bindingName}`),...l.map(r=>`queues.consumers/${r.name}`)],text:h}},oe=(e,s,n)=>{const t=$(e),o=T(s);if(!t)return{added:[],changed:!1,exportGaps:o,reason:"wrangler.jsonc not found",warnings:y(s,e)};const{parsed:a,text:c}=R(t);if(a===void 0)return{added:[],changed:!1,exportGaps:o,reason:`failed to parse ${t} as JSONC`,warnings:y(s,e),wranglerPath:t};const d=y(s,e,a);if(n!==void 0){const i=a.env?.[n]!==void 0;d.push(i?`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 u=s.containers.filter(i=>i.exported),l=s.agents.filter(i=>i.exported&&i.voice===!0&&i.voiceBindingName!==void 0&&i.voiceClassName!==void 0),g=[...s.durableObjects,...u.map(i=>({binding:i.bindingName,className:i.className})),...l.map(i=>({binding:i.voiceBindingName,className:i.voiceClassName}))],p=s.workflows.filter(i=>i.exported),h=s.agents.filter(i=>i.exported),r=[{enabled:!0,run:i=>j(i,a,g)},{enabled:s.needsD1,run:i=>F(i,a)},{enabled:s.usesAi,run:i=>w(i,a,"ai","AI","AI (Workers AI)")},{enabled:s.usesBrowser,run:i=>w(i,a,"browser","BROWSER","BROWSER (Browser Rendering)")},{enabled:s.usesImages,run:i=>w(i,a,"images","IMAGES","IMAGES (Cloudflare Images)")},{enabled:s.usesAnalytics,run:i=>G(i,a)},{enabled:!0,run:i=>X(i,a)},{enabled:u.length>0,run:i=>Q(i,a,u)},{enabled:p.length>0||h.length>0,run:i=>J(i,a,p,h)},{enabled:s.queues.length>0,run:i=>q(i,a,s.queues)}];let m=c;const f=[];for(const i of r){if(!i.enabled)continue;const S=i.run(m);m=S.text,f.push(...S.added)}return f.includes("DB (D1)")&&d.push(`wrote a DB binding with a placeholder database_id ("${k}") — run \`wrangler d1 create <name>\` and replace it before deploying.`),m===c?{added:[],changed:!1,exportGaps:o,reason:"bindings already in sync",warnings:d,wranglerPath:t}:(B(t,m,"utf8"),{added:f,changed:!0,exportGaps:o,warnings:d,wranglerPath:t})};export{T as collectExportGaps,oe as reconcileWranglerBindings};
@@ -1 +1 @@
1
- import{relative as s}from"node:path";import{secretKindOf as a,redact as c}from"@lunora/codegen";import{i as f,a as d}from"./package-secrets-registry-CFZ5bA8L.mjs";import{isPlaceholderValue as l}from"./buildPackageSecretsBlock-8PWr25wv.mjs";import{findWranglerFile as m,readWranglerJsonc as u}from"./WRANGLER_FILES-UNW-xY5u.mjs";const p=8,g=(e,r)=>{if(e===void 0)return[];const n=[];for(const[t,i]of Object.entries(e)){if(typeof i!="string"||l(i)||f(t))continue;const o=a(i)??(d(t)&&i.length>=p?"secret_named_var":void 0);o!==void 0&&n.push({file:r,key:t,kind:o,preview:c(i)})}return n},V=e=>{const r=m(e);if(r===void 0)return[];const{parsed:n}=u(r);return n===void 0?[]:g(n.vars,s(e,r))};export{V as collectWranglerSecretVariables,g as scanWranglerVariablesForSecrets};
1
+ import{relative as s}from"node:path";import{secretKindOf as a,redact as c}from"@lunora/codegen";import{i as f,a as d}from"./package-secrets-registry-DvtTiK4b.mjs";import{isPlaceholderValue as l}from"./buildPackageSecretsBlock-yv9mjKEW.mjs";import{findWranglerFile as m,readWranglerJsonc as u}from"./WRANGLER_FILES-UNW-xY5u.mjs";const p=8,g=(e,r)=>{if(e===void 0)return[];const n=[];for(const[t,i]of Object.entries(e)){if(typeof i!="string"||l(i)||f(t))continue;const o=a(i)??(d(t)&&i.length>=p?"secret_named_var":void 0);o!==void 0&&n.push({file:r,key:t,kind:o,preview:c(i)})}return n},V=e=>{const r=m(e);if(r===void 0)return[];const{parsed:n}=u(r);return n===void 0?[]:g(n.vars,s(e,r))};export{V as collectWranglerSecretVariables,g as scanWranglerVariablesForSecrets};
@@ -0,0 +1 @@
1
+ const a=e=>e.endsWith("S")?e.slice(0,-1):e,r=e=>e.replaceAll(/([a-z\d])([A-Z])/gu,"$1_$2").toUpperCase().split(/[_-]+/u).filter(s=>s.length>0),n=new Set(["CREDENTIAL","DSN","PASSPHRASE","PASSWD","PASSWORD","SECRET","TOKEN"]),c=["ACCESS_KEY","API_KEY","ENCRYPTION_KEY","PRIVATE_KEY","SIGNING_KEY"],i=new RegExp(`(?:${[...n,...c.map(e=>e.replaceAll("_",""))].join("|")})S?$`,"iu"),p=e=>r(e).some(s=>s==="PUBLIC"||s==="PUBLISHABLE"),d=e=>{if(p(e))return!1;const s=r(e);if(s.some(o=>n.has(a(o))))return!0;const t=a(s.join("_"));return c.some(o=>t===o||t.endsWith(`_${o}`))||i.test(e)},h=[{description:"Bearer token the local Lunora Studio uses to call the worker's admin endpoints (data browser, schema edits) in dev. Generate with: openssl rand -hex 32",docsUrl:"https://lunora.sh/docs/packages/studio",key:"LUNORA_ADMIN_TOKEN",placeholderValue:"replace-with-openssl-rand-hex-32"}],u=["BETTER_AUTH_SECRET","STORAGE_SIGNING_SECRET"],l={"@lunora/auth":[{description:"32-byte random secret used to sign sessions and tokens. Generate with: openssl rand -hex 32",docsUrl:"https://lunora.sh/docs/packages/auth#secrets",key:"AUTH_SECRET",placeholderValue:"replace-with-openssl-rand-hex-32"},{description:"Public base URL of your worker (used by better-auth for redirects and cookie domain). For local dev this is typically http://localhost:8787",docsUrl:"https://lunora.sh/docs/packages/auth#secrets",key:"AUTH_URL",placeholderValue:"http://localhost:8787"}],"@lunora/bindings/r2sql":[{description:"Cloudflare API token with R2 SQL read access, for `ctx.r2sql`. Create at https://dash.cloudflare.com/profile/api-tokens with the R2 SQL permission.",docsUrl:"https://lunora.sh/docs/packages/bindings#r2-sql",key:"R2_SQL_TOKEN",placeholderValue:"<your-r2-sql-api-token>"},{description:"Cloudflare account id the R2 SQL queries run against. Falls back to CLOUDFLARE_ACCOUNT_ID when unset.",docsUrl:"https://lunora.sh/docs/packages/bindings#r2-sql",key:"R2_SQL_ACCOUNT_ID",placeholderValue:"<your-cloudflare-account-id>"},{description:"Name of the R2 bucket holding the Iceberg tables `ctx.r2sql` queries.",docsUrl:"https://lunora.sh/docs/packages/bindings#r2-sql",key:"R2_SQL_BUCKET",placeholderValue:"<your-r2-sql-bucket>"}],"@lunora/mail":[{description:"Resend API key for sending transactional email via @lunora/mail. Obtain at https://resend.com/api-keys",docsUrl:"https://lunora.sh/docs/packages/mail#secrets",key:"RESEND_API_KEY",placeholderValue:"<your-resend-api-key>"}],"@lunora/notify":[{description:"Public VAPID key (base64url) for Web Push. Generate a keypair once with: npx web-push generate-vapid-keys — the public key is also shipped to the browser to subscribe.",docsUrl:"https://lunora.sh/docs/packages/notify#web-push",key:"VAPID_PUBLIC_KEY",placeholderValue:"<your-vapid-public-key>"},{description:"Private VAPID key (base64url) for Web Push — the application-server signing key. Generate with: npx web-push generate-vapid-keys",docsUrl:"https://lunora.sh/docs/packages/notify#web-push",key:"VAPID_PRIVATE_KEY",placeholderValue:"<your-vapid-private-key>"},{description:"VAPID `sub` contact — a mailto: or https: URL identifying the application server (e.g. mailto:you@example.com).",docsUrl:"https://lunora.sh/docs/packages/notify#web-push",key:"VAPID_SUBJECT",placeholderValue:"mailto:you@example.com"},{description:"Firebase project id for FCM (HTTP v1) push. Found in the Firebase console project settings.",docsUrl:"https://lunora.sh/docs/packages/notify#fcm",key:"FCM_PROJECT_ID",placeholderValue:"<your-firebase-project-id>"},{description:"OAuth2 access token for FCM (HTTP v1). Convenient for dev but expires — in production supply a getAccessToken() in defineNotify instead. Obtain via the Google Cloud SDK / a service account.",docsUrl:"https://lunora.sh/docs/packages/notify#fcm",key:"FCM_ACCESS_TOKEN",placeholderValue:"<your-fcm-access-token>"}],"@lunora/payment":[{description:"Stripe secret key (sk_test_…). Required when using the Stripe adapter. Obtain at https://dashboard.stripe.com/apikeys",docsUrl:"https://lunora.sh/docs/packages/payment#stripe",key:"STRIPE_SECRET_KEY",placeholderValue:"<your-stripe-secret-key>"},{description:"Stripe webhook signing secret (whsec_…) for verifying event payloads. Obtain at https://dashboard.stripe.com/webhooks",docsUrl:"https://lunora.sh/docs/packages/payment#stripe",key:"STRIPE_WEBHOOK_SECRET",placeholderValue:"<your-stripe-webhook-secret>"},{description:"Polar access token for the Polar payment adapter. Obtain at https://polar.sh/settings/tokens",docsUrl:"https://lunora.sh/docs/packages/payment#polar",key:"POLAR_ACCESS_TOKEN",placeholderValue:"<your-polar-access-token>"},{description:"Polar webhook secret for verifying event payloads from Polar. Obtain at https://polar.sh/settings/webhooks",docsUrl:"https://lunora.sh/docs/packages/payment#polar",key:"POLAR_WEBHOOK_SECRET",placeholderValue:"<your-polar-webhook-secret>"},{description:"Autumn secret key (am_sk_…) for the Autumn payment adapter. Obtain at https://app.useautumn.com/dev",docsUrl:"https://lunora.sh/docs/packages/payment#autumn",key:"AUTUMN_SECRET_KEY",placeholderValue:"<your-autumn-secret-key>"},{description:"Autumn webhook signing secret for verifying Standard Webhooks event payloads. Obtain from your Autumn dashboard webhook settings.",docsUrl:"https://lunora.sh/docs/packages/payment#autumn",key:"AUTUMN_WEBHOOK_SECRET",placeholderValue:"<your-autumn-webhook-secret>"},{description:"Dodo Payments API key (bearer token) for the Dodo Payments adapter. Obtain at https://app.dodopayments.com/developer/api-keys",docsUrl:"https://lunora.sh/docs/packages/payment#dodo-payments",key:"DODO_PAYMENTS_API_KEY",placeholderValue:"<your-dodo-payments-api-key>"},{description:"Dodo Payments webhook signing secret (whsec_…) for verifying event payloads. Obtain at https://app.dodopayments.com/developer/webhooks",docsUrl:"https://lunora.sh/docs/packages/payment#dodo-payments",key:"DODO_PAYMENTS_WEBHOOK_KEY",placeholderValue:"<your-dodo-payments-webhook-secret>"},{description:"Creem API key for the Creem payment adapter. Obtain at https://www.creem.io/dashboard/developers",docsUrl:"https://lunora.sh/docs/packages/payment#creem",key:"CREEM_API_KEY",placeholderValue:"<your-creem-api-key>"},{description:"Creem webhook signing secret for verifying the creem-signature header. Obtain from your Creem dashboard webhook settings.",docsUrl:"https://lunora.sh/docs/packages/payment#creem",key:"CREEM_WEBHOOK_SECRET",placeholderValue:"<your-creem-webhook-secret>"}]},y=new Set([...u,...[...h,...Object.values(l).flat()].filter(e=>d(e.key)&&!e.placeholderValue.startsWith("<")).map(e=>e.key)]),k=e=>{const s=[];for(const t of e){const o=l[t];o!==void 0&&s.push(...o)}return s};export{h as C,y as M,l as P,d as a,p as i,k as s};
@@ -1 +1 @@
1
- import{spawn as i}from"node:child_process";import{existsSync as d,readFileSync as u}from"node:fs";import{join as f}from"node:path";import{runScriptArgsFor as g,detectPackageManager as m}from"./addArgsFor-B4D4zvM0.mjs";const o="postcodegen",l=r=>new Promise((n,s)=>{const e=i(r.command,[...r.args],{cwd:r.cwd??process.cwd(),shell:process.platform==="win32",stdio:["inherit",r.stdoutToStderr===!0?2:"inherit","inherit"]});e.on("error",s),e.on("close",a=>{n({code:a??1})})}),p=r=>{const n=f(r,"package.json");if(!d(n))return!1;try{const e=JSON.parse(u(n,"utf8"))?.scripts;return typeof e?.[o]=="string"&&e[o]!==""}catch{return!1}},P=async r=>{const{cwd:n,logger:s}=r;if(!p(n))return{ran:!1};const e=t=>(s.error(t),{error:t,ran:!0});let a;try{a=g(m(n),o)}catch(t){return e(`cannot run \`${o}\`: ${t instanceof Error?t.message:String(t)}`)}s.info(`running \`${o}\``);let c;try{c=await(r.spawner??l)({args:a.args,command:a.command,cwd:n,stdoutToStderr:r.stdoutToStderr})}catch(t){return e(`\`${o}\` failed to start: ${t instanceof Error?t.message:String(t)}`)}return c.code!==0?e(`\`${o}\` exited ${String(c.code)}`):{ran:!0}};export{P as runPostCodegenHook};
1
+ import{spawn as i}from"node:child_process";import{existsSync as d,readFileSync as u}from"node:fs";import{join as f}from"node:path";import{runScriptArgsFor as g,detectPackageManager as m}from"./addArgsFor-CWb4cPij.mjs";const o="postcodegen",l=r=>new Promise((n,s)=>{const e=i(r.command,[...r.args],{cwd:r.cwd??process.cwd(),shell:process.platform==="win32",stdio:["inherit",r.stdoutToStderr===!0?2:"inherit","inherit"]});e.on("error",s),e.on("close",a=>{n({code:a??1})})}),p=r=>{const n=f(r,"package.json");if(!d(n))return!1;try{const e=JSON.parse(u(n,"utf8"))?.scripts;return typeof e?.[o]=="string"&&e[o]!==""}catch{return!1}},P=async r=>{const{cwd:n,logger:s}=r;if(!p(n))return{ran:!1};const e=t=>(s.error(t),{error:t,ran:!0});let a;try{a=g(m(n),o)}catch(t){return e(`cannot run \`${o}\`: ${t instanceof Error?t.message:String(t)}`)}s.info(`running \`${o}\``);let c;try{c=await(r.spawner??l)({args:a.args,command:a.command,cwd:n,stdoutToStderr:r.stdoutToStderr})}catch(t){return e(`\`${o}\` failed to start: ${t instanceof Error?t.message:String(t)}`)}return c.code!==0?e(`\`${o}\` exited ${String(c.code)}`):{ran:!0}};export{P as runPostCodegenHook};