@lunora/config 1.0.0-alpha.27 → 1.0.0-alpha.271

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 (100) hide show
  1. package/LICENSE.md +135 -0
  2. package/README.md +3 -3
  3. package/dist/cloudflare/index.d.mts +969 -0
  4. package/dist/cloudflare/index.d.ts +969 -0
  5. package/dist/cloudflare/index.mjs +1 -0
  6. package/dist/index.d.mts +864 -921
  7. package/dist/index.d.ts +864 -921
  8. package/dist/index.mjs +1 -23
  9. package/dist/packem_shared/ACCENT-CotPTfv7.mjs +7 -0
  10. package/dist/packem_shared/AGENT_MODE_ENV-D8MvSwPE.mjs +1 -0
  11. package/dist/packem_shared/AGENT_RULES_DIR-C54Ta_vz.mjs +1 -0
  12. package/dist/packem_shared/ALLOW_FORWARDED_ENV-BUndghJx.mjs +1 -0
  13. package/dist/packem_shared/BINDING_MANIFEST_VERSION-B8dwEKLn.mjs +1 -0
  14. package/dist/packem_shared/CLOUDFLARE_DRIVER-Ci9oJMYb.mjs +1 -0
  15. package/dist/packem_shared/CODEGEN_ENV-ZsCxV1kP.mjs +1 -0
  16. package/dist/packem_shared/COMPOSED_WORKER_ENTRY-Bj793dir.mjs +1 -0
  17. package/dist/packem_shared/DEFAULT_DEPLOY_TARGET-B-e9mqgX.mjs +1 -0
  18. package/dist/packem_shared/DEV_BINDINGS_FILE-pyOiNLP4.mjs +4 -0
  19. package/dist/packem_shared/DEV_VARS_EXAMPLE_FILE-CqLorAxT.mjs +6 -0
  20. package/dist/packem_shared/LINKED_PROJECT_DIR-Ba5qPEwo.mjs +2 -0
  21. package/dist/packem_shared/LUNORA_EVENT_SOURCE-DYdcDU9G.mjs +1 -0
  22. package/dist/packem_shared/LUNORA_IGNORED_PATHS-BHABA9u-.mjs +19 -0
  23. package/dist/packem_shared/LunoraReporter-f277GLNT.mjs +6 -0
  24. package/dist/packem_shared/PACKAGE_SECRETS_REGISTRY-De7gLGIy.mjs +1 -0
  25. package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-0QiGKazX.mjs +1 -0
  26. package/dist/packem_shared/REMOTE_ELIGIBLE_KEYS-D-edJjVY.mjs +1 -0
  27. package/dist/packem_shared/REQUIRED_COMPATIBILITY_DATE-SdRHaUwh.mjs +1 -0
  28. package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-Dbt0faMd.mjs +1 -0
  29. package/dist/packem_shared/SEED_ENDPOINT-2B56PN_H.mjs +1 -0
  30. package/dist/packem_shared/WORKERS_CACHE_MIN_DATE-0k9ABJtF.mjs +1 -0
  31. package/dist/packem_shared/WRANGLER_FILES-UNW-xY5u.mjs +1 -0
  32. package/dist/packem_shared/addArgsFor-CWb4cPij.mjs +1 -0
  33. package/dist/packem_shared/applyAdditiveEdit-CH0VhMJ2.mjs +6 -0
  34. package/dist/packem_shared/applyStudioAssetCache-DHQEJuuv.mjs +1 -0
  35. package/dist/packem_shared/assetContentType-CUb5bpbI.mjs +1 -0
  36. package/dist/packem_shared/buildPackageSecretsBlock-yv9mjKEW.mjs +19 -0
  37. package/dist/packem_shared/classifyPolicyEdit-D8NwrHxR.mjs +24 -0
  38. package/dist/packem_shared/collectExportGaps-BJw9LdRV.mjs +2 -0
  39. package/dist/packem_shared/collectWranglerSecretVariables-D-usPfT8.mjs +1 -0
  40. package/dist/packem_shared/createConfirm-D5mKTMHj.mjs +7 -0
  41. package/dist/packem_shared/describePreservedCrons-Ci5r2aph.mjs +1 -0
  42. package/dist/packem_shared/detectFramework-CUiVEHDQ.mjs +1 -0
  43. package/dist/packem_shared/discover-info-Vj9d4qYt.mjs +1 -0
  44. package/dist/packem_shared/discoverAgentInfo-CTdCSfYM.mjs +1 -0
  45. package/dist/packem_shared/discoverContainerInfo-EhZtEBQs.mjs +1 -0
  46. package/dist/packem_shared/discoverSchemaInfo-DJvevsCm.mjs +1 -0
  47. package/dist/packem_shared/discoverWorkflowInfo-BsPvlo6O.mjs +1 -0
  48. package/dist/packem_shared/interpretRemote-CQ06qpjM.mjs +1 -0
  49. package/dist/packem_shared/jsonc-edit-BZgQIdAH.mjs +1 -0
  50. package/dist/packem_shared/lunora-manifest-V77OcyFC.mjs +6 -0
  51. package/dist/packem_shared/package-secrets-registry-DvtTiK4b.mjs +1 -0
  52. package/dist/packem_shared/parseDevVariable-teAAahVD.mjs +1 -0
  53. package/dist/packem_shared/parseSchema-D1Wbr1qv.mjs +1 -0
  54. package/dist/packem_shared/policy-scaffold.d-D2H4_G01.d.mts +86 -0
  55. package/dist/packem_shared/policy-scaffold.d-D2H4_G01.d.ts +86 -0
  56. package/dist/packem_shared/reconcileWranglerCompatibilityDate-7OO_xaKR.mjs +1 -0
  57. package/dist/packem_shared/renderStudioHtml-ByowDtMl.mjs +15 -0
  58. package/dist/packem_shared/runPostCodegenHook-CVrOTiGB.mjs +1 -0
  59. package/dist/packem_shared/schema-info.d-DvKkJ7HJ.d.mts +331 -0
  60. package/dist/packem_shared/schema-info.d-DvKkJ7HJ.d.ts +331 -0
  61. package/dist/packem_shared/serveJsonHandler-Dv0EdCb9.mjs +1 -0
  62. package/dist/packem_shared/streamContainerLogs-0nko1qpv.mjs +2 -0
  63. package/dist/packem_shared/wranglerToAlchemy-SDoS_XY0.mjs +6 -0
  64. package/dist/packem_shared/write-atomic-9d9xs5ON.mjs +1 -0
  65. package/dist/studio-host/index.d.mts +250 -95
  66. package/dist/studio-host/index.d.ts +250 -95
  67. package/dist/studio-host/index.mjs +1 -7
  68. package/package.json +15 -7
  69. package/dist/packem_shared/ACCENT-DW1XJn8i.mjs +0 -40
  70. package/dist/packem_shared/AGENT_RULES_DIR-lcgC08aE.mjs +0 -40
  71. package/dist/packem_shared/DEV_VARS_EXAMPLE_FILE-dJPNTEnK.mjs +0 -37
  72. package/dist/packem_shared/LINKED_PROJECT_DIR-CXwXzV_C.mjs +0 -52
  73. package/dist/packem_shared/LUNORA_CONFIG_FILE-CtcIcB5-.mjs +0 -34
  74. package/dist/packem_shared/LUNORA_EVENT_SOURCE-D2fDeGB6.mjs +0 -86
  75. package/dist/packem_shared/LunoraReporter-Ci-bDCK9.mjs +0 -70
  76. package/dist/packem_shared/PACKAGE_SECRETS_REGISTRY-B8t_SdoZ.mjs +0 -70
  77. package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-CiC2IGKx.mjs +0 -103
  78. package/dist/packem_shared/REMOTE_ELIGIBLE_KEYS-BC7_e9Bz.mjs +0 -105
  79. package/dist/packem_shared/REQUIRED_COMPATIBILITY_DATE-2YYyWJUq.mjs +0 -561
  80. package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-Df-Wrix-.mjs +0 -99
  81. package/dist/packem_shared/SEED_ENDPOINT-DVCjaGO-.mjs +0 -61
  82. package/dist/packem_shared/WRANGLER_FILES-DwSuC-Kn.mjs +0 -25
  83. package/dist/packem_shared/applyAdditiveEdit-C-snTFEV.mjs +0 -228
  84. package/dist/packem_shared/buildPackageSecretsBlock-DWDKHViT.mjs +0 -243
  85. package/dist/packem_shared/classifyPolicyEdit-BHeAqF8P.mjs +0 -99
  86. package/dist/packem_shared/createConfirm-fvpdgJ9s.mjs +0 -100
  87. package/dist/packem_shared/detectFramework-Br-BcPBq.mjs +0 -41
  88. package/dist/packem_shared/discoverContainerInfo-BXFs6Wav.mjs +0 -19
  89. package/dist/packem_shared/discoverSchemaInfo-BB-CKlTK.mjs +0 -25
  90. package/dist/packem_shared/discoverWorkflowInfo-CedvR0mn.mjs +0 -19
  91. package/dist/packem_shared/inferLunoraBindings-ByMwG-gH.mjs +0 -352
  92. package/dist/packem_shared/loadStudioAssets-Csk5RS4E.mjs +0 -28
  93. package/dist/packem_shared/parseDevVariable-CJiq2IwE.mjs +0 -30
  94. package/dist/packem_shared/parseSchema-DSeyktvG.mjs +0 -107
  95. package/dist/packem_shared/policy-scaffold.d-DCmwn7zQ.d.mts +0 -74
  96. package/dist/packem_shared/policy-scaffold.d-DCmwn7zQ.d.ts +0 -74
  97. package/dist/packem_shared/reconcileWranglerBindings-Cruwwx1M.mjs +0 -334
  98. package/dist/packem_shared/renderStudioHtml-449Ysn75.mjs +0 -37
  99. package/dist/packem_shared/serveJsonHandler-B4OLTGLS.mjs +0 -86
  100. package/dist/packem_shared/streamContainerLogs-BZ4cOZwH.mjs +0 -157
@@ -1,15 +1,53 @@
1
- import { D as DestructivePolicyEdit, S as ScaffoldPolicyEdit, W as WireRlsEdit } from "../packem_shared/policy-scaffold.d-DCmwn7zQ.js";
2
1
  import { IncomingMessage, ServerResponse } from 'node:http';
3
- /** Parse a single `KEY=value` (optionally quoted) out of a `.dev.vars` body. */
2
+ import { CodegenOptions } from '@lunora/codegen';
3
+ import { D as DestructivePolicyEdit, S as ScaffoldPolicyEdit, W as WireRlsEdit } from "../packem_shared/policy-scaffold.d-D2H4_G01.js";
4
+ /**
5
+ * Parse a single `KEY=value` (optionally quoted) out of a `.dev.vars` body,
6
+ * returning `undefined` when the key is absent or its value is empty. A thin
7
+ * wrapper over {@link parseDevVariableEntries} — the single owner of the
8
+ * `.dev.vars` line grammar — so the key-validation, comment-skip, and quote-strip
9
+ * rules can't drift from every other reader/writer of the file.
10
+ */
4
11
  declare const parseDevVariable: (contents: string, key: string) => string | undefined;
5
12
  /**
6
- * Resolve the worker's admin token so the studio can auto-authenticate in
7
- * dev. Prefers the `LUNORA_ADMIN_TOKEN` env var, then the project's `.dev.vars`
8
- * — the same file `@cloudflare/vite-plugin` / `wrangler dev` feed the worker, so
9
- * the token the studio sends matches the one the worker's admin gate
10
- * verifies. Returns `undefined` when neither is set (the studio then prompts).
11
- */
13
+ * Resolve the worker's admin token so the studio can auto-authenticate in dev.
14
+ *
15
+ * The ONLY source is the project's `.dev.vars` — the file
16
+ * `@cloudflare/vite-plugin` / `wrangler dev` feed the local worker, and
17
+ * therefore the only token the worker's admin gate can verify. A shell-exported
18
+ * `LUNORA_ADMIN_TOKEN` (the documented way to run `lunora backup` /
19
+ * `lunora deploy --migrate` against **production**) never reaches the local
20
+ * worker's `env`, so embedding it would both fail the gate and put a production
21
+ * bearer into every `/__lunora` document served on the developer's machine.
22
+ * When the two disagree we say so once and keep using `.dev.vars`.
23
+ *
24
+ * Returns `undefined` when `.dev.vars` carries no token (the studio then prompts).
25
+ */
12
26
  declare const resolveAdminToken: (root: string) => string | undefined;
27
+ /**
28
+ * Set the asset cache headers, answering `304` when the request already holds
29
+ * this version. Returns true when the response is finished, false when the
30
+ * caller should go on to write the body.
31
+ *
32
+ * `no-cache` forces revalidation on every load: an unchanged asset costs a
33
+ * cheap `304`, a rebuild (new stamp, new chunk names) is always fetched fresh.
34
+ * The ETag is keyed on the requested file (not just its kind) so each chunk
35
+ * revalidates independently, while the rebuild stamp busts them all at once. No
36
+ * stamp (the studio isn't resolvable) means no ETag and no `304` — `no-cache`
37
+ * alone.
38
+ *
39
+ * `If-None-Match` is compared byte-for-byte, per RFC 7232: entity tags are
40
+ * case-sensitive, and these are keyed on file names that can differ only in
41
+ * case (base64url chunk names), so a case-insensitive compare would cross-match
42
+ * two distinct chunks into a wrong `304`.
43
+ */
44
+ declare const applyStudioAssetCache: (request: IncomingMessage, response: ServerResponse, fileName: string, stamp: number | undefined) => boolean;
45
+ /**
46
+ * Send the studio's SPA document. It embeds the admin token, so it is
47
+ * `no-store` — not merely revalidated — and carries no ETag: a cached `304` for
48
+ * a token-bearing document would be its own bug.
49
+ */
50
+ declare const sendStudioDocument: (response: ServerResponse, body: Buffer | string) => void;
13
51
  /** Config injected into the studio document before the bundle loads. */
14
52
  interface StudioHtmlConfig {
15
53
  /** Admin token sent with admin requests; omitted (and not injected) when unset. */
@@ -17,34 +55,34 @@ interface StudioHtmlConfig {
17
55
  /** Router basepath the studio mounts under (e.g. `/__lunora`, or `/` for a root server). */
18
56
  readonly basePath: string;
19
57
  /**
20
- * Make the data browser editable (insert/edit/delete rows). Injected as
21
- * `window.__LUNORA_DATA_EDITABLE__` for the bundle to read. The loopback-only
22
- * dev hosts (the Vite `/__lunora` route, the CLI studio server) set this so a
23
- * developer can edit; a static deploy leaves it off (read-only) by default.
24
- */
58
+ * Make the data browser editable (insert/edit/delete rows). Injected as
59
+ * `window.__LUNORA_DATA_EDITABLE__` for the bundle to read. The loopback-only
60
+ * dev hosts (the Vite `/__lunora` route, the CLI studio server) set this so a
61
+ * developer can edit; a static deploy leaves it off (read-only) by default.
62
+ */
25
63
  readonly dataEditable?: boolean;
26
64
  /**
27
- * Whether the project's Lunora agent skills ("rules") are installed. Injected
28
- * as `window.__LUNORA_RULES_INSTALLED__` **only when `false`**, so the studio
29
- * shows a "rules not installed" banner on the loopback dev hosts (which detect
30
- * it) and stays quiet on a static deploy (which leaves it unset).
31
- */
65
+ * Whether the project's Lunora agent skills ("rules") are installed. Injected
66
+ * as `window.__LUNORA_RULES_INSTALLED__` **only when `false`**, so the studio
67
+ * shows a "rules not installed" banner on the loopback dev hosts (which detect
68
+ * it) and stays quiet on a static deploy (which leaves it unset).
69
+ */
32
70
  readonly rulesInstalled?: boolean;
33
71
  /**
34
- * Enable the function runner's "Run as identity" tool (execute a function as a
35
- * chosen user to test auth/RLS). Injected as `window.__LUNORA_RUN_AS_IDENTITY__`.
36
- * Like {@link StudioHtmlConfig.dataEditable}, only the loopback-only dev hosts set
37
- * this — forging an identity is a developer-only affordance; a static deploy
38
- * leaves it off so the control never renders.
39
- */
72
+ * Enable the function runner's "Run as identity" tool (execute a function as a
73
+ * chosen user to test auth/RLS). Injected as `window.__LUNORA_RUN_AS_IDENTITY__`.
74
+ * Like {@link StudioHtmlConfig.dataEditable}, only the loopback-only dev hosts set
75
+ * this — forging an identity is a developer-only affordance; a static deploy
76
+ * leaves it off so the control never renders.
77
+ */
40
78
  readonly runAsIdentity?: boolean;
41
79
  /**
42
- * Enable the visual schema editor (add table / column / index, written back to
43
- * `lunora/schema.ts` + codegen). Injected as `window.__LUNORA_SCHEMA_EDITABLE__`.
44
- * Like {@link StudioHtmlConfig.dataEditable}, only the loopback-only dev hosts
45
- * set this — editing source + running codegen needs the project's filesystem and
46
- * toolchain, so a static deploy leaves it off and the diagram stays read-only.
47
- */
80
+ * Enable the visual schema editor (add table / column / index, written back to
81
+ * `lunora/schema.ts` + codegen). Injected as `window.__LUNORA_SCHEMA_EDITABLE__`.
82
+ * Like {@link StudioHtmlConfig.dataEditable}, only the loopback-only dev hosts
83
+ * set this — editing source + running codegen needs the project's filesystem and
84
+ * toolchain, so a static deploy leaves it off and the diagram stays read-only.
85
+ */
48
86
  readonly schemaEditable?: boolean;
49
87
  /** URL the studio bundle is served from (absolute, host-relative). */
50
88
  readonly scriptSrc: string;
@@ -61,30 +99,62 @@ interface StudioAssets {
61
99
  readonly styles: Buffer;
62
100
  }
63
101
  /**
64
- * Read the prebuilt static studio files shipped by `@lunora/studio`
65
- * (`dist/standalone/studio.js` + `dist/styles.css`). Returns `undefined` —
66
- * with a one-time warning — when the optional package isn't installed or hasn't
67
- * been built, so a missing studio never breaks the dev server.
68
- *
69
- * `resolveFrom` controls where `@lunora/studio` is resolved from. It defaults
70
- * to this module's own location, which is correct once this code is inlined into
71
- * a host package (`@lunora/vite` / `@lunora/cli`) that has `@lunora/studio`
72
- * installed — node walks up from the host's `dist` to find it.
73
- */
102
+ * Read the prebuilt static studio files shipped by `@lunora/studio`
103
+ * (`dist/standalone/studio.js` + `dist/styles.css`). Returns `undefined` —
104
+ * with a one-time warning — when the optional package isn't installed or hasn't
105
+ * been built, so a missing studio never breaks the dev server.
106
+ *
107
+ * `resolveFrom` controls where `@lunora/studio` is resolved from. It defaults
108
+ * to this module's own location, which is correct once this code is inlined into
109
+ * a host package (`@lunora/vite` / `@lunora/cli`) that has `@lunora/studio`
110
+ * installed — node walks up from the host's `dist` to find it.
111
+ */
74
112
  declare const loadStudioAssets: (logger?: WarnLogger, resolveFrom?: string) => StudioAssets | undefined;
75
113
  /**
76
- * A freshness stamp for the studio assets: the latest mtime (ms) of the resolved
77
- * `studio.js` / `styles.css`, or `undefined` when they can't be resolved. Hosts
78
- * cache {@link loadStudioAssets} for the dev session but compare this stamp per
79
- * request, so a `@lunora/studio` rebuild mid-session is picked up live — no dev
80
- * server restart needed.
81
- */
114
+ * A freshness stamp for the studio assets: the latest mtime (ms) of the resolved
115
+ * `studio.js` / `styles.css`, or `undefined` when they can't be resolved. Hosts
116
+ * cache {@link loadStudioAssets} for the dev session but compare this stamp per
117
+ * request, so a `@lunora/studio` rebuild mid-session is picked up live — no dev
118
+ * server restart needed.
119
+ */
82
120
  declare const studioAssetsStamp: (resolveFrom?: string) => number | undefined;
83
121
  /**
84
- * Endpoint path both dev hosts mount the handler at. A sibling of the schema
85
- * editor's `/__lunora/schema-edit`; the double underscore keeps it clear of the
86
- * CLI's `/_lunora/*` worker proxy (single underscore).
87
- */
122
+ * Absolute path of the built standalone directory — `@lunora/studio`'s
123
+ * `dist/standalone`, where the `studio.js` entry and its code-split `chunk-*.js`
124
+ * siblings live — or `undefined` when the studio isn't installed/built. The
125
+ * standalone bundle is emitted with esbuild `splitting`, so the hosts must serve
126
+ * the whole directory (not two fixed paths); this resolves its root.
127
+ */
128
+ declare const resolveStandaloneDirectory: (resolveFrom?: string) => string | undefined;
129
+ /**
130
+ * Read a single file from the standalone directory by its plain filename (the
131
+ * `studio.js` entry, a `chunk-*.js`, or a `.map`). **Path-traversal-safe** via
132
+ * {@link resolveContainedFile}: only a lone filename resolving to a direct child
133
+ * of the standalone directory is served — any separator, `..`, NUL, or absolute
134
+ * path is rejected — so a request like `../../etc/passwd` can never escape it.
135
+ * Returns the bytes, or `undefined` when the studio isn't built or the name
136
+ * doesn't resolve to a file inside the directory (the host answers that 404).
137
+ */
138
+ declare const readStandaloneAsset: (fileName: string, resolveFrom?: string) => Buffer | undefined;
139
+ /**
140
+ * True when `pathname` addresses a standalone JS module — the `studio.js` entry
141
+ * or one of its code-split `chunk-*.js` siblings (and their `.map`s). Shared by
142
+ * the CLI and Vite hosts so both route the same request shapes to the directory
143
+ * server; the stylesheet is matched separately at each host's own style path.
144
+ */
145
+ declare const isStandaloneModulePath: (pathname: string) => boolean;
146
+ /**
147
+ * Content-Type for a served standalone asset, by extension: `.css` → CSS,
148
+ * `.map` → JSON (a source map), everything else (the `.js` entry + chunks) →
149
+ * JavaScript. Shared by the CLI and Vite hosts so the MIME decision lives in one
150
+ * place.
151
+ */
152
+ declare const assetContentType: (fileName: string) => string;
153
+ /**
154
+ * Endpoint path both dev hosts mount the handler at. A sibling of the schema
155
+ * editor's `/__lunora/schema-edit`; the double underscore keeps it clear of the
156
+ * CLI's `/_lunora/*` worker proxy (single underscore).
157
+ */
88
158
  declare const POLICY_SCAFFOLD_ENDPOINT = "/__lunora/policy-scaffold";
89
159
  /** A `wireRls` request additionally carries the procedure's source-file path. */
90
160
  interface WirePolicyEdit extends WireRlsEdit {
@@ -95,6 +165,8 @@ interface WirePolicyEdit extends WireRlsEdit {
95
165
  type PolicyScaffoldBody = DestructivePolicyEdit | ScaffoldPolicyEdit | WirePolicyEdit;
96
166
  /** A request adapted from the host transport. */
97
167
  interface PolicyScaffoldRequest {
168
+ /** API-spec mode the host runs codegen with; forwarded to the regeneration. */
169
+ readonly apiSpec?: CodegenOptions["apiSpec"];
98
170
  /** Parsed JSON body of the `POST`. */
99
171
  readonly body?: unknown;
100
172
  /** HTTP method — only `POST` is handled. */
@@ -110,29 +182,31 @@ interface PolicyScaffoldResponse {
110
182
  readonly status: number;
111
183
  }
112
184
  /**
113
- * Handle a policy-scaffold request. Pure over its inputs apart from the file
114
- * I/O + codegen it performs on an applied edit; safe to unit-test against a
115
- * temp project directory.
116
- */
185
+ * Handle a policy-scaffold request. Pure over its inputs apart from the file
186
+ * I/O + codegen it performs on an applied edit; safe to unit-test against a
187
+ * temp project directory.
188
+ */
117
189
  declare const handlePolicyScaffoldRequest: (request: PolicyScaffoldRequest) => PolicyScaffoldResponse;
118
190
  /**
119
- * Render the single-page document that boots the studio. Emitted verbatim —
120
- * never through a bundler/transform — so the studio stays a static tool,
121
- * decoupled from the host project's build. A small inline script publishes the
122
- * per-server config on `globalThis` before the bundle loads: the mount basepath
123
- * (so the router stays under its mount), the admin token when present (so the
124
- * studio auto-authenticates instead of prompting), and an editable flag when the
125
- * host is a loopback dev server (so the data browser allows edits).
126
- */
191
+ * Render the single-page document that boots the studio. Emitted verbatim —
192
+ * never through a bundler/transform — so the studio stays a static tool,
193
+ * decoupled from the host project's build. A small inline script publishes the
194
+ * per-server config on `globalThis` before the bundle loads: the mount basepath
195
+ * (so the router stays under its mount), the admin token when present (so the
196
+ * studio auto-authenticates instead of prompting), and an editable flag when the
197
+ * host is a loopback dev server (so the data browser allows edits).
198
+ */
127
199
  declare const renderStudioHtml: (config: StudioHtmlConfig) => string;
128
200
  /**
129
- * Endpoint path both dev hosts mount the handler at. Distinct from the CLI's
130
- * `/_lunora/*` worker proxy (single underscore), so a schema edit is never
131
- * forwarded to the worker.
132
- */
201
+ * Endpoint path both dev hosts mount the handler at. Distinct from the CLI's
202
+ * `/_lunora/*` worker proxy (single underscore), so a schema edit is never
203
+ * forwarded to the worker.
204
+ */
133
205
  declare const SCHEMA_EDIT_ENDPOINT = "/__lunora/schema-edit";
134
206
  /** A request adapted from the host transport. */
135
207
  interface SchemaEditRequest {
208
+ /** API-spec mode the host runs codegen with; forwarded to the regeneration. */
209
+ readonly apiSpec?: CodegenOptions["apiSpec"];
136
210
  /** Parsed JSON body for a `POST`; ignored for `GET`. */
137
211
  readonly body?: unknown;
138
212
  /** HTTP method (`GET` / `POST`). */
@@ -148,28 +222,28 @@ interface SchemaEditResponse {
148
222
  readonly status: number;
149
223
  }
150
224
  /**
151
- * Handle a schema-edit request. Pure over its inputs apart from the file I/O +
152
- * codegen it performs on a `POST` additive edit; safe to unit-test against a
153
- * temp project directory.
154
- */
225
+ * Handle a schema-edit request. Pure over its inputs apart from the file I/O +
226
+ * codegen it performs on a `POST` additive edit; safe to unit-test against a
227
+ * temp project directory.
228
+ */
155
229
  declare const handleSchemaEditRequest: (request: SchemaEditRequest) => SchemaEditResponse;
156
230
  /**
157
- * Endpoint path both dev hosts mount the handler at. A sibling of the schema
158
- * editor's `/__lunora/schema-edit`; the double underscore keeps it clear of the
159
- * CLI's `/_lunora/*` worker proxy (single underscore).
160
- */
231
+ * Endpoint path both dev hosts mount the handler at. A sibling of the schema
232
+ * editor's `/__lunora/schema-edit`; the double underscore keeps it clear of the
233
+ * CLI's `/_lunora/*` worker proxy (single underscore).
234
+ */
161
235
  declare const SEED_ENDPOINT = "/__lunora/seed";
162
236
  /** Body the host transport adapts from a `POST` — one generate-rows request. */
163
237
  interface SeedRequestBody {
164
238
  /** How many rows to generate (clamped to `[1, MAX_SEED_ROWS]`). */
165
239
  readonly count?: number;
166
240
  /**
167
- * Ids of rows that already exist in the live DB, keyed by referenced table.
168
- * Foreign keys resolve against these, and every referenced parent table
169
- * present here is treated as covered — so the generator links to existing
170
- * rows instead of fabricating new parent rows. The studio samples these from
171
- * the target table's FK columns before calling.
172
- */
241
+ * Ids of rows that already exist in the live DB, keyed by referenced table.
242
+ * Foreign keys resolve against these, and every referenced parent table
243
+ * present here is treated as covered — so the generator links to existing
244
+ * rows instead of fabricating new parent rows. The studio samples these from
245
+ * the target table's FK columns before calling.
246
+ */
173
247
  readonly existingIds?: Readonly<Record<string, ReadonlyArray<string>>>;
174
248
  /** Deterministic mapping selector — same value yields identical rows. */
175
249
  readonly seed?: number;
@@ -193,21 +267,35 @@ interface SeedResponse {
193
267
  readonly status: number;
194
268
  }
195
269
  /**
196
- * Handle a generate-rows request: statically lift the schema, generate `count`
197
- * rows for `table` (linking foreign keys to the supplied existing ids rather
198
- * than fabricating parents), and return them JSON-safe for the client to insert.
199
- */
270
+ * Handle a generate-rows request: statically lift the schema, generate `count`
271
+ * rows for `table` (linking foreign keys to the supplied existing ids rather
272
+ * than fabricating parents), and return them JSON-safe for the client to insert.
273
+ *
274
+ * Only the requested table's rows are ever returned, so a foreign key with no
275
+ * `existingIds` to resolve against is answered with `409
276
+ * fk-parents-empty` naming the parent tables — the endpoint refuses
277
+ * rather than hand back children whose parents it just dropped.
278
+ */
200
279
  declare const handleSeedRequest: (request: SeedRequest) => SeedResponse;
280
+ /**
281
+ * The host's project configuration, forwarded verbatim to the handler. Separate
282
+ * from `projectRoot` (which every host has) because these two come from the
283
+ * host's own Lunora options.
284
+ */
285
+ interface LocalEndpointContext {
286
+ /** API-spec mode the host runs codegen with, so a studio edit regenerates the same spec files. */
287
+ readonly apiSpec?: CodegenOptions["apiSpec"];
288
+ /** Override the lunora subdirectory name. Defaults to `"lunora"`. */
289
+ readonly schemaDirectory?: string;
290
+ }
201
291
  /** A request adapted from a host transport, passed to a local-dev handler. */
202
- interface LocalEndpointRequest {
292
+ interface LocalEndpointRequest extends LocalEndpointContext {
203
293
  /** Parsed JSON body of the request (`undefined` for `GET` / an empty body). */
204
294
  readonly body?: unknown;
205
295
  /** HTTP method. */
206
296
  readonly method: string;
207
297
  /** Project root containing the `lunora/` directory. */
208
298
  readonly projectRoot: string;
209
- /** Override the lunora subdirectory name. Defaults to `"lunora"`. */
210
- readonly schemaDirectory?: string;
211
299
  }
212
300
  /** A response a local-dev handler returns, serialised back as JSON with its status. */
213
301
  interface LocalEndpointResponse {
@@ -217,11 +305,78 @@ interface LocalEndpointResponse {
217
305
  /** A transport-agnostic local-dev handler (schema edit, policy scaffold). */
218
306
  type LocalEndpointHandler = (request: LocalEndpointRequest) => LocalEndpointResponse;
219
307
  /**
220
- * Adapt a `node:http` request/response pair to a transport-agnostic local-dev
221
- * handler. `GET` carries no body (the schema editor uses it to read the parsed
222
- * schema); every other method has its body read + JSON-parsed first. The
223
- * handler's `{ status, body }` is serialised back as JSON. A malformed body is a
224
- * `400`; an unexpected throw (e.g. the body-size guard) is a `500`.
225
- */
226
- declare const serveJsonHandler: (request: IncomingMessage, response: ServerResponse, handle: LocalEndpointHandler, projectRoot: string) => void;
227
- export { type LocalEndpointHandler, type LocalEndpointRequest, type LocalEndpointResponse, POLICY_SCAFFOLD_ENDPOINT, type PolicyScaffoldBody, type PolicyScaffoldRequest, type PolicyScaffoldResponse, SCHEMA_EDIT_ENDPOINT, SEED_ENDPOINT, type SchemaEditRequest, type SchemaEditResponse, type SeedRequest, type SeedRequestBody, type SeedResponse, type StudioAssets, type StudioHtmlConfig, type WarnLogger, type WirePolicyEdit, handlePolicyScaffoldRequest, handleSchemaEditRequest, handleSeedRequest, loadStudioAssets, parseDevVariable, renderStudioHtml, resolveAdminToken, serveJsonHandler, studioAssetsStamp };
308
+ * Adapt a `node:http` request/response pair to a transport-agnostic local-dev
309
+ * handler. `GET` carries no body (the schema editor uses it to read the parsed
310
+ * schema); every other method has its body read + JSON-parsed first. The
311
+ * handler's `{ status, body }` is serialised back as JSON. A malformed body is a
312
+ * `400`; an unexpected throw (e.g. the body-size guard) is a `500`.
313
+ *
314
+ * `context` carries the host's own Lunora options through to the handler: its
315
+ * `schemaDirectory` (so a custom `schemaDir` targets the right directory instead
316
+ * of defaulting to `"lunora"`) and its `apiSpec`, so a studio edit regenerates
317
+ * with the same options the host's own codegen run uses.
318
+ */
319
+ declare const serveJsonHandler: (request: IncomingMessage, response: ServerResponse, handle: LocalEndpointHandler, projectRoot: string, context?: LocalEndpointContext) => void;
320
+ /** A single header value, lower-cased and trimmed; `undefined` when absent or array-valued. */
321
+ declare const headerValue: (raw: string | string[] | undefined) => string | undefined;
322
+ /**
323
+ * True for an IPv4/IPv6 loopback peer (`127.0.0.0/8`, `::1`, and the
324
+ * IPv4-mapped `::ffff:127.x`). A missing address means we cannot read the
325
+ * transport (e.g. a mocked request in tests) — treated as loopback so the
326
+ * config-derived gate stays the source of truth there; on a real Vite/Node
327
+ * server `remoteAddress` is always populated.
328
+ */
329
+ declare const isLoopbackAddress: (remoteAddress: string | undefined) => boolean;
330
+ /**
331
+ * Explicit opt-out for the forwarding-header refusal below — set to `"1"` to
332
+ * allow a proxied request through once you've confirmed the forwarding is
333
+ * your own trusted dev tunnel (Codespaces, devcontainers, Gitpod, Cloud
334
+ * Workstations, ngrok, a Docker reverse proxy, …), not an attacker's relay.
335
+ * Does not relax the socket-peer or `Host` checks — only this one.
336
+ */
337
+ declare const ALLOW_FORWARDED_ENV = "LUNORA_STUDIO_ALLOW_FORWARDED";
338
+ /**
339
+ * Per-request transport gate, independent of a host's config-derived bind
340
+ * intent (e.g. Vite's `isNonLoopbackBind`, the CLI's `isLoopback`). In Vite
341
+ * middleware mode the real bind belongs to the embedding server (so the
342
+ * config check measures the wrong thing); here we read the actual socket peer
343
+ * and the `Host` header. Returns a refusal reason, or `undefined` when the
344
+ * connection is loopback-local.
345
+ *
346
+ * `logger`, when supplied, gets a `warnOnce` line for a forwarding-header
347
+ * refusal — naming the specific header seen and the {@link ALLOW_FORWARDED_ENV}
348
+ * escape hatch — so the failure points at its cause in the terminal running
349
+ * the dev server, not just as an opaque 403 in the browser.
350
+ */
351
+ declare const transportRejectionReason: (request: IncomingMessage, logger?: WarnLogger) => string | undefined;
352
+ export { ALLOW_FORWARDED_ENV, type LocalEndpointContext, type LocalEndpointHandler, type LocalEndpointRequest, type LocalEndpointResponse, POLICY_SCAFFOLD_ENDPOINT, type PolicyScaffoldBody, type PolicyScaffoldRequest, type PolicyScaffoldResponse, SCHEMA_EDIT_ENDPOINT, SEED_ENDPOINT, type SchemaEditRequest, type SchemaEditResponse, type SeedRequest, type SeedRequestBody, type SeedResponse, type StudioAssets, type StudioHtmlConfig, type WarnLogger, type WirePolicyEdit, applyStudioAssetCache, assetContentType, handlePolicyScaffoldRequest, handleSchemaEditRequest, handleSeedRequest, headerValue, isLoopbackAddress, isStandaloneModulePath, loadStudioAssets,
353
+ /**
354
+ * `@lunora/config/studio-host` — internal, build-time-shared helpers for hosting
355
+ * the prebuilt `@lunora/studio` SPA during local dev.
356
+ *
357
+ * Two surfaces inline this code so the dev studio behaves identically
358
+ * regardless of how the project is run:
359
+ * - `@lunora/vite` serves the studio from a Vite middleware at `/__lunora`.
360
+ * - `@lunora/cli` (`lunora dev`) serves it from a standalone Node HTTP server.
361
+ *
362
+ * Each owns its own transport (Connect middleware vs `node:http`) and routing;
363
+ * the genuinely shared parts live here: render the host HTML with per-server
364
+ * config injected, resolve the admin token the same way the worker does, and
365
+ * load the prebuilt asset bytes.
366
+ */
367
+ parseDevVariable, readStandaloneAsset, renderStudioHtml,
368
+ /**
369
+ * `@lunora/config/studio-host` — internal, build-time-shared helpers for hosting
370
+ * the prebuilt `@lunora/studio` SPA during local dev.
371
+ *
372
+ * Two surfaces inline this code so the dev studio behaves identically
373
+ * regardless of how the project is run:
374
+ * - `@lunora/vite` serves the studio from a Vite middleware at `/__lunora`.
375
+ * - `@lunora/cli` (`lunora dev`) serves it from a standalone Node HTTP server.
376
+ *
377
+ * Each owns its own transport (Connect middleware vs `node:http`) and routing;
378
+ * the genuinely shared parts live here: render the host HTML with per-server
379
+ * config injected, resolve the admin token the same way the worker does, and
380
+ * load the prebuilt asset bytes.
381
+ */
382
+ resolveAdminToken, resolveStandaloneDirectory, sendStudioDocument, serveJsonHandler, studioAssetsStamp, transportRejectionReason };
@@ -1,7 +1 @@
1
- export { parseDevVariable, resolveAdminToken } from '../packem_shared/parseDevVariable-CJiq2IwE.mjs';
2
- export { default as loadStudioAssets, studioAssetsStamp } from '../packem_shared/loadStudioAssets-Csk5RS4E.mjs';
3
- export { POLICY_SCAFFOLD_ENDPOINT, handlePolicyScaffoldRequest } from '../packem_shared/POLICY_SCAFFOLD_ENDPOINT-CiC2IGKx.mjs';
4
- export { default as renderStudioHtml } from '../packem_shared/renderStudioHtml-449Ysn75.mjs';
5
- export { SCHEMA_EDIT_ENDPOINT, handleSchemaEditRequest } from '../packem_shared/SCHEMA_EDIT_ENDPOINT-Df-Wrix-.mjs';
6
- export { SEED_ENDPOINT, handleSeedRequest } from '../packem_shared/SEED_ENDPOINT-DVCjaGO-.mjs';
7
- export { serveJsonHandler } from '../packem_shared/serveJsonHandler-B4OLTGLS.mjs';
1
+ import{parseDevVariable as t,resolveAdminToken as r}from"../packem_shared/parseDevVariable-teAAahVD.mjs";import{applyStudioAssetCache as s,sendStudioDocument as d}from"../packem_shared/applyStudioAssetCache-DHQEJuuv.mjs";import{assetContentType as l,isStandaloneModulePath as p,loadStudioAssets as m,readStandaloneAsset as S,resolveStandaloneDirectory as i,studioAssetsStamp as f}from"../packem_shared/assetContentType-CUb5bpbI.mjs";import{POLICY_SCAFFOLD_ENDPOINT as D,handlePolicyScaffoldRequest as A}from"../packem_shared/POLICY_SCAFFOLD_ENDPOINT-0QiGKazX.mjs";import{default as x}from"../packem_shared/renderStudioHtml-ByowDtMl.mjs";import{SCHEMA_EDIT_ENDPOINT as h,handleSchemaEditRequest as N}from"../packem_shared/SCHEMA_EDIT_ENDPOINT-Dbt0faMd.mjs";import{SEED_ENDPOINT as R,handleSeedRequest as _}from"../packem_shared/SEED_ENDPOINT-2B56PN_H.mjs";import{serveJsonHandler as T}from"../packem_shared/serveJsonHandler-Dv0EdCb9.mjs";import{ALLOW_FORWARDED_ENV as I,headerValue as L,isLoopbackAddress as v,transportRejectionReason as y}from"../packem_shared/ALLOW_FORWARDED_ENV-BUndghJx.mjs";export{I as ALLOW_FORWARDED_ENV,D as POLICY_SCAFFOLD_ENDPOINT,h as SCHEMA_EDIT_ENDPOINT,R as SEED_ENDPOINT,s as applyStudioAssetCache,l as assetContentType,A as handlePolicyScaffoldRequest,N as handleSchemaEditRequest,_ as handleSeedRequest,L as headerValue,v as isLoopbackAddress,p as isStandaloneModulePath,m as loadStudioAssets,t as parseDevVariable,S as readStandaloneAsset,x as renderStudioHtml,r as resolveAdminToken,i as resolveStandaloneDirectory,d as sendStudioDocument,T as serveJsonHandler,f as studioAssetsStamp,y as transportRejectionReason};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/config",
3
- "version": "1.0.0-alpha.27",
3
+ "version": "1.0.0-alpha.271",
4
4
  "description": "Internal shared CLI + Vite config layer for Lunora: wrangler.jsonc validation, binding inference, and .dev.vars scaffolding",
5
5
  "keywords": [
6
6
  "bindings",
@@ -40,6 +40,10 @@
40
40
  "types": "./dist/index.d.ts",
41
41
  "import": "./dist/index.mjs"
42
42
  },
43
+ "./cloudflare": {
44
+ "types": "./dist/cloudflare/index.d.ts",
45
+ "import": "./dist/cloudflare/index.mjs"
46
+ },
43
47
  "./studio-host": {
44
48
  "types": "./dist/studio-host/index.d.ts",
45
49
  "import": "./dist/studio-host/index.mjs"
@@ -50,17 +54,21 @@
50
54
  "access": "public"
51
55
  },
52
56
  "dependencies": {
53
- "@lunora/codegen": "1.0.0-alpha.17",
54
- "@lunora/container": "1.0.0-alpha.5",
55
- "@lunora/seed": "1.0.0-alpha.7",
56
- "@visulima/colorize": "2.0.0-alpha.14",
57
+ "@lunora/codegen": "1.0.0-alpha.230",
58
+ "@lunora/container": "1.0.0-alpha.61",
59
+ "@lunora/errors": "1.0.0-alpha.45",
60
+ "@lunora/seed": "1.0.0-alpha.162",
61
+ "@visulima/colorize": "2.1.1",
62
+ "@visulima/find-ai-runner": "1.0.2",
63
+ "@visulima/package": "5.0.20",
57
64
  "dockerode": "^5.0.1",
58
- "es-module-lexer": "^2.1.0",
65
+ "dotenv": "17.4.2",
66
+ "es-module-lexer": "^2.3.2",
59
67
  "jsonc-parser": "^3.3.1",
60
68
  "ts-morph": "^28.0.0"
61
69
  },
62
70
  "peerDependencies": {
63
- "@lunora/studio": "1.0.0-alpha.14"
71
+ "@lunora/studio": ">=1.0.0-alpha.50 <2.0.0-0"
64
72
  },
65
73
  "peerDependenciesMeta": {
66
74
  "@lunora/studio": {
@@ -1,40 +0,0 @@
1
- import colorize from '@visulima/colorize';
2
-
3
- const ACCENT = "#a855f7";
4
- const INK = "#0b0b0b";
5
- const STEP_BADGE_NAMES = ["lunora", "dir", "tmpl", "add", "deps", "git", "next"];
6
- const BADGES = {
7
- add: { bg: ACCENT, fg: INK, text: "add" },
8
- debug: { bg: "#6b7280", fg: "#f3f4f6", text: "debug" },
9
- deps: { bg: ACCENT, fg: INK, text: "deps" },
10
- dir: { bg: ACCENT, fg: INK, text: "dir" },
11
- error: { bg: "#ef4444", fg: INK, text: "error" },
12
- git: { bg: "#f59e0b", fg: INK, text: "git" },
13
- info: { bg: "#3b82f6", fg: INK, text: "info" },
14
- lunora: { bg: "#22c55e", fg: INK, text: "lunora" },
15
- next: { bg: "#06b6d4", fg: INK, text: "next" },
16
- success: { bg: "#22c55e", fg: INK, text: "ok" },
17
- tmpl: { bg: ACCENT, fg: INK, text: "tmpl" },
18
- warn: { bg: "#f59e0b", fg: INK, text: "warn" }
19
- };
20
- const LUNA_NAME = "Luna";
21
- const LUNA_SIGNOFF = "Safe travels, voyager.";
22
- const LUNA_BUNNY = String.raw`
23
- .-"""""-.
24
- / (\(\ \
25
- | ( -.-) |
26
- \ o(")(") /
27
- '-._____.-'`;
28
- const LUNA_ART = LUNA_BUNNY.startsWith("\n") ? LUNA_BUNNY.slice(1) : LUNA_BUNNY;
29
- const BADGE_GUTTER = 6;
30
- const padBadge = (text) => ` ${text} `;
31
- const badgeLead = (text) => " ".repeat(Math.max(0, BADGE_GUTTER - text.length));
32
- const BADGE_COLUMN_WIDTH = BADGE_GUTTER + 2;
33
- const badgeWidth = (_spec) => BADGE_COLUMN_WIDTH;
34
- const paintBadge = (spec) => (
35
- // eslint-disable-next-line import/no-named-as-default-member -- see file header.
36
- badgeLead(spec.text) + colorize.bgHex(spec.bg).hex(spec.fg).bold(padBadge(spec.text))
37
- );
38
- const paintAnswer = (text) => colorize.dim(text);
39
-
40
- export { ACCENT, BADGES, BADGE_COLUMN_WIDTH, LUNA_ART, LUNA_BUNNY, LUNA_NAME, LUNA_SIGNOFF, STEP_BADGE_NAMES, badgeLead, badgeWidth, padBadge, paintAnswer, paintBadge };
@@ -1,40 +0,0 @@
1
- import { existsSync } from 'node:fs';
2
- import { join } from 'node:path';
3
-
4
- const AGENT_RULES_DIR = ".agents/skills";
5
- const AGENT_RULES_HINT_ENV = "LUNORA_RULES_HINT_SHOWN";
6
- const LUNORA_SKILL_NAMES = [
7
- "lunora",
8
- "lunora-quickstart",
9
- "lunora-functions",
10
- "lunora-realtime",
11
- "lunora-setup-auth",
12
- "lunora-create-package",
13
- "lunora-migration-helper",
14
- "lunora-deploy",
15
- "lunora-performance-audit"
16
- ];
17
- const ROOT_SKILL_NAME = "lunora";
18
- const AGENT_RULES_HINT = "Lunora AI rules not installed — run `lunora rules install` so your coding agent knows how to use Lunora.";
19
- const claimAgentRulesHint = () => {
20
- if (process.env[AGENT_RULES_HINT_ENV] === "1") {
21
- return false;
22
- }
23
- process.env[AGENT_RULES_HINT_ENV] = "1";
24
- return true;
25
- };
26
- const skillFile = (projectRoot, name) => join(projectRoot, AGENT_RULES_DIR, name, "SKILL.md");
27
- const detectAgentRules = (projectRoot) => {
28
- const present = [];
29
- const missing = [];
30
- for (const name of LUNORA_SKILL_NAMES) {
31
- if (existsSync(skillFile(projectRoot, name))) {
32
- present.push(name);
33
- } else {
34
- missing.push(name);
35
- }
36
- }
37
- return { installed: existsSync(skillFile(projectRoot, ROOT_SKILL_NAME)), missing, present };
38
- };
39
-
40
- export { AGENT_RULES_DIR, AGENT_RULES_HINT, AGENT_RULES_HINT_ENV, LUNORA_SKILL_NAMES, ROOT_SKILL_NAME, claimAgentRulesHint, detectAgentRules };
@@ -1,37 +0,0 @@
1
- const DEV_VARS_FILE = ".dev.vars";
2
- const DEV_VARS_EXAMPLE_FILE = ".dev.vars.example";
3
- const DEV_VARS_KEY_PATTERN = /^[A-Za-z_]\w*$/u;
4
- const DEV_VARS_NEWLINE = /\r?\n/u;
5
- const unquoteDevVariable = (value) => {
6
- if (value.length >= 2 && (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'"))) {
7
- return value.slice(1, -1);
8
- }
9
- return value;
10
- };
11
- const splitDevVariableLine = (line) => {
12
- const trimmed = line.trim();
13
- if (trimmed === "" || trimmed.startsWith("#")) {
14
- return void 0;
15
- }
16
- const equals = trimmed.indexOf("=");
17
- if (equals <= 0) {
18
- return void 0;
19
- }
20
- const key = trimmed.slice(0, equals).trim();
21
- if (!DEV_VARS_KEY_PATTERN.test(key)) {
22
- return void 0;
23
- }
24
- return { key, value: trimmed.slice(equals + 1).trim() };
25
- };
26
- const parseDevVariableEntries = (content) => {
27
- const entries = [];
28
- for (const line of content.split(DEV_VARS_NEWLINE)) {
29
- const parsed = splitDevVariableLine(line);
30
- if (parsed) {
31
- entries.push({ key: parsed.key, value: unquoteDevVariable(parsed.value) });
32
- }
33
- }
34
- return entries;
35
- };
36
-
37
- export { DEV_VARS_EXAMPLE_FILE, DEV_VARS_FILE, DEV_VARS_KEY_PATTERN, DEV_VARS_NEWLINE, parseDevVariableEntries, splitDevVariableLine, unquoteDevVariable };