@lunora/config 1.0.0-alpha.61 → 1.0.0-alpha.62

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 (19) hide show
  1. package/dist/index.mjs +6 -6
  2. package/dist/packem_shared/{POLICY_SCAFFOLD_ENDPOINT-8bNMHGiu.mjs → POLICY_SCAFFOLD_ENDPOINT-CvTZpaZF.mjs} +5 -9
  3. package/dist/packem_shared/{REMOTE_ELIGIBLE_KEYS-BC7_e9Bz.mjs → REMOTE_ELIGIBLE_KEYS-C-F_Flgy.mjs} +1 -6
  4. package/dist/packem_shared/{REQUIRED_COMPATIBILITY_DATE-DYYxY_If.mjs → REQUIRED_COMPATIBILITY_DATE-CoKkA1uk.mjs} +4 -3
  5. package/dist/packem_shared/{SCHEMA_EDIT_ENDPOINT-Df-Wrix-.mjs → SCHEMA_EDIT_ENDPOINT-Bt2SNkpV.mjs} +4 -8
  6. package/dist/packem_shared/{SEED_ENDPOINT-DVCjaGO-.mjs → SEED_ENDPOINT-7izz_Jao.mjs} +1 -1
  7. package/dist/packem_shared/{buildPackageSecretsBlock-BDXX0mKG.mjs → buildPackageSecretsBlock-B-dWb-Sa.mjs} +1 -1
  8. package/dist/packem_shared/{collectWranglerSecretVariables-Red5H-4V.mjs → collectWranglerSecretVariables-p4ezBYQ4.mjs} +1 -1
  9. package/dist/packem_shared/jsonc-edit-SbcD7MAe.mjs +9 -0
  10. package/dist/packem_shared/parseDevVariable-B0FEvfHC.mjs +21 -0
  11. package/dist/packem_shared/{reconcileWranglerBindings-BZdPBnpZ.mjs → reconcileWranglerBindings-BhQN61qp.mjs} +1 -6
  12. package/dist/packem_shared/{reconcileWranglerCompatibilityDate-CYY0rVnJ.mjs → reconcileWranglerCompatibilityDate-D5Bqjk4P.mjs} +1 -1
  13. package/dist/packem_shared/{serveJsonHandler-B4OLTGLS.mjs → serveJsonHandler-Cl2Wqkv8.mjs} +2 -2
  14. package/dist/packem_shared/write-atomic-B2REqapi.mjs +14 -0
  15. package/dist/studio-host/index.d.mts +12 -2
  16. package/dist/studio-host/index.d.ts +12 -2
  17. package/dist/studio-host/index.mjs +5 -5
  18. package/package.json +6 -6
  19. package/dist/packem_shared/parseDevVariable-CJiq2IwE.mjs +0 -30
package/dist/index.mjs CHANGED
@@ -12,10 +12,10 @@ export { default as LunoraReporter } from './packem_shared/LunoraReporter-Ci-bDC
12
12
  export { PACKAGE_SECRETS_REGISTRY, secretsForPackages } from './packem_shared/PACKAGE_SECRETS_REGISTRY-BeRSvrl5.mjs';
13
13
  export { LUNORA_CONFIG_FILE, interpretRemote, readProjectRemotePreference } from './packem_shared/LUNORA_CONFIG_FILE-CtcIcB5-.mjs';
14
14
  export { createConfirm, isInteractive, promptMultiSelect, promptSelect, promptYesNo } from './packem_shared/createConfirm-fvpdgJ9s.mjs';
15
- export { reconcileWranglerBindings } from './packem_shared/reconcileWranglerBindings-BZdPBnpZ.mjs';
16
- export { reconcileWranglerCompatibilityDate } from './packem_shared/reconcileWranglerCompatibilityDate-CYY0rVnJ.mjs';
17
- export { REMOTE_ELIGIBLE_KEYS, injectRemoteFlags, isRemoteEnvEnabled, materializeRemoteWranglerConfig, planRemoteBindings, resolveRemoteEnabled } from './packem_shared/REMOTE_ELIGIBLE_KEYS-BC7_e9Bz.mjs';
18
- export { buildPackageSecretsBlock, ensureDevVariables, ensureDevVarsExample, fillDevSecrets, generateSecretValue, isMintableSecretKey, isPlaceholderValue, planDevSecretsFill, planDevVariablesAugment, planDevVariablesScaffold, requiredSecrets } from './packem_shared/buildPackageSecretsBlock-BDXX0mKG.mjs';
15
+ export { reconcileWranglerBindings } from './packem_shared/reconcileWranglerBindings-BhQN61qp.mjs';
16
+ export { reconcileWranglerCompatibilityDate } from './packem_shared/reconcileWranglerCompatibilityDate-D5Bqjk4P.mjs';
17
+ export { REMOTE_ELIGIBLE_KEYS, injectRemoteFlags, isRemoteEnvEnabled, materializeRemoteWranglerConfig, planRemoteBindings, resolveRemoteEnabled } from './packem_shared/REMOTE_ELIGIBLE_KEYS-C-F_Flgy.mjs';
18
+ export { buildPackageSecretsBlock, ensureDevVariables, ensureDevVarsExample, fillDevSecrets, generateSecretValue, isMintableSecretKey, isPlaceholderValue, planDevSecretsFill, planDevVariablesAugment, planDevVariablesScaffold, requiredSecrets } from './packem_shared/buildPackageSecretsBlock-B-dWb-Sa.mjs';
19
19
  export { applyAdditiveEdit, classifyEdit } from './packem_shared/applyAdditiveEdit-C-snTFEV.mjs';
20
20
  export { parseSchema } from './packem_shared/parseSchema-DSeyktvG.mjs';
21
21
  export { classifyPolicyEdit, scaffoldPolicyFile, wireRlsIntoProcedure } from './packem_shared/classifyPolicyEdit-BHeAqF8P.mjs';
@@ -23,5 +23,5 @@ export { discoverSchemaInfo } from './packem_shared/discoverSchemaInfo-BB-CKlTK.
23
23
  export { ACCENT, BADGES, BADGE_COLUMN_WIDTH, LUNA_ART, LUNA_BUNNY, LUNA_NAME, LUNA_SIGNOFF, STEP_BADGE_NAMES, badgeLead, badgeWidth, padBadge, paintAnswer, paintBadge } from './packem_shared/ACCENT-DW1XJn8i.mjs';
24
24
  export { discoverWorkflowInfo } from './packem_shared/discoverWorkflowInfo-CedvR0mn.mjs';
25
25
  export { WRANGLER_FILES, findWranglerFile, readWranglerJsonc } from './packem_shared/WRANGLER_FILES-DwSuC-Kn.mjs';
26
- export { collectWranglerSecretVariables, scanWranglerVariablesForSecrets } from './packem_shared/collectWranglerSecretVariables-Red5H-4V.mjs';
27
- export { REQUIRED_COMPATIBILITY_DATE, REQUIRED_FLAG, validateWrangler, validateWranglerConfig, validateWranglerProject, withTailConsumer } from './packem_shared/REQUIRED_COMPATIBILITY_DATE-DYYxY_If.mjs';
26
+ export { collectWranglerSecretVariables, scanWranglerVariablesForSecrets } from './packem_shared/collectWranglerSecretVariables-p4ezBYQ4.mjs';
27
+ export { REQUIRED_COMPATIBILITY_DATE, REQUIRED_FLAG, validateWrangler, validateWranglerConfig, validateWranglerProject, withTailConsumer } from './packem_shared/REQUIRED_COMPATIBILITY_DATE-CoKkA1uk.mjs';
@@ -1,8 +1,9 @@
1
- import { existsSync, readFileSync, writeFileSync, renameSync } from 'node:fs';
1
+ import { existsSync, readFileSync } from 'node:fs';
2
2
  import { join, isAbsolute, relative } from 'node:path';
3
3
  import { runCodegen, CodegenDiagnosticError } from '@lunora/codegen';
4
4
  import { LunoraError } from '@lunora/errors';
5
5
  import { classifyPolicyEdit, scaffoldPolicyFile, wireRlsIntoProcedure } from './classifyPolicyEdit-BHeAqF8P.mjs';
6
+ import { w as writeFileAtomic } from './write-atomic-B2REqapi.mjs';
6
7
 
7
8
  const POLICY_SCAFFOLD_ENDPOINT = "/__lunora/policy-scaffold";
8
9
  const statusForFailure = (reason) => {
@@ -14,11 +15,6 @@ const statusForFailure = (reason) => {
14
15
  }
15
16
  return reason === "destructive" ? 409 : 422;
16
17
  };
17
- const writeAtomic = (path, text) => {
18
- const temporaryPath = `${path}.lunora-tmp`;
19
- writeFileSync(temporaryPath, text, "utf8");
20
- renameSync(temporaryPath, path);
21
- };
22
18
  const runCodegenForResponse = (request, okBody) => {
23
19
  let diagnostics = [];
24
20
  try {
@@ -53,7 +49,7 @@ const handleScaffoldPolicy = (request, edit) => {
53
49
  if (existsSync(targetPath)) {
54
50
  return { body: { error: "file-exists", fileName: result.fileName, ok: false }, status: 409 };
55
51
  }
56
- writeAtomic(targetPath, result.source);
52
+ writeFileAtomic(targetPath, result.source);
57
53
  return runCodegenForResponse(request, { fileName: result.fileName });
58
54
  };
59
55
  const resolveProcedureFile = (projectRoot, lunoraDirectory, filePath) => {
@@ -77,7 +73,7 @@ const handleWireRls = (request, edit) => {
77
73
  if (!wired.ok) {
78
74
  return { body: { error: wired.reason, ok: false }, status: statusForFailure(wired.reason) };
79
75
  }
80
- writeAtomic(procedurePath, wired.text);
76
+ writeFileAtomic(procedurePath, wired.text);
81
77
  return runCodegenForResponse(request, { exportName: edit.exportName });
82
78
  };
83
79
  const handlePolicyScaffoldRequest = (request) => {
@@ -85,7 +81,7 @@ const handlePolicyScaffoldRequest = (request) => {
85
81
  return { body: { error: "method-not-allowed", ok: false }, status: 405 };
86
82
  }
87
83
  const { body } = request;
88
- if (body === void 0 || typeof body !== "object" || typeof body.kind !== "string") {
84
+ if (body === void 0 || body === null || typeof body !== "object" || typeof body.kind !== "string") {
89
85
  return { body: { error: "invalid-edit", ok: false }, status: 400 };
90
86
  }
91
87
  const edit = body;
@@ -1,9 +1,8 @@
1
1
  import { writeFileSync, rmSync } from 'node:fs';
2
- import { modify, applyEdits } from 'jsonc-parser';
2
+ import { a as applyModify } from './jsonc-edit-SbcD7MAe.mjs';
3
3
  import { findWranglerFile, readWranglerJsonc } from './WRANGLER_FILES-DwSuC-Kn.mjs';
4
4
  import { join } from 'node:path';
5
5
 
6
- const FORMATTING = { formattingOptions: { insertSpaces: true, tabSize: 4 } };
7
6
  const REMOTE_ELIGIBLE_KEYS = {
8
7
  ai: { label: "AI", shape: "object" },
9
8
  d1_databases: { label: "D1", shape: "array" },
@@ -38,10 +37,6 @@ const planSection = (section, parsed) => {
38
37
  return entry === null || entry === void 0 ? [] : [{ binding: entryName(entry, section), kind: label, path: [], section }];
39
38
  };
40
39
  const planRemoteBindings = (parsed) => REMOTE_ELIGIBLE_KEY_LIST.flatMap((section) => planSection(section, parsed));
41
- const applyModify = (text, path, value) => {
42
- const edits = modify(text, [...path], value, FORMATTING);
43
- return edits.length > 0 ? applyEdits(text, edits) : text;
44
- };
45
40
  const injectRemoteFlags = (text, plans) => {
46
41
  let next = text;
47
42
  for (const plan of plans) {
@@ -76,6 +76,7 @@ const validateContainerEntry = (entry, label, checks) => {
76
76
  warnings.push(`${label} ("${entry.class_name}") declares no max_instances — set a cap so a traffic spike can't fan out unbounded container spend`);
77
77
  }
78
78
  };
79
+ const objectBindingEntries = (value) => Array.isArray(value) ? value.filter((entry) => entry !== null && typeof entry === "object") : [];
79
80
  const validateContainers = (wrangler, errors, warnings) => {
80
81
  if (wrangler.containers === void 0) {
81
82
  return;
@@ -88,7 +89,7 @@ const validateContainers = (wrangler, errors, warnings) => {
88
89
  if (entries.length === 0) {
89
90
  return;
90
91
  }
91
- const boundClasses = new Set((wrangler.durable_objects?.bindings ?? []).map((binding) => binding.class_name));
92
+ const boundClasses = new Set(objectBindingEntries(wrangler.durable_objects?.bindings).map((binding) => binding.class_name));
92
93
  const migrations = wrangler.migrations ?? [];
93
94
  const sqliteClasses = new Set(migrations.flatMap((migration) => [...migration?.new_sqlite_classes ?? []]));
94
95
  const nonSqliteClasses = new Set(migrations.flatMap((migration) => [...migration?.new_classes ?? []]));
@@ -494,7 +495,7 @@ const validateWranglerConfig = (wrangler, schema) => {
494
495
  errors.push("wrangler config is not a valid object");
495
496
  return { errors, valid: false, warnings };
496
497
  }
497
- const durableObjectBindings = wrangler.durable_objects?.bindings ?? [];
498
+ const durableObjectBindings = objectBindingEntries(wrangler.durable_objects?.bindings);
498
499
  const shardBinding = durableObjectBindings.find((binding) => binding.name === "SHARD" && binding.class_name === "ShardDO");
499
500
  if (!shardBinding) {
500
501
  errors.push(
@@ -514,7 +515,7 @@ const validateWranglerConfig = (wrangler, schema) => {
514
515
  errors.push(`cache.enabled requires compatibility_date >= "${WORKERS_CACHE_MIN_DATE}" (got "${compatibilityDate || "<missing>"}")`);
515
516
  }
516
517
  if (schema?.hasGlobalTable) {
517
- const d1Bindings = wrangler.d1_databases ?? [];
518
+ const d1Bindings = objectBindingEntries(wrangler.d1_databases);
518
519
  const databaseBinding = d1Bindings.find((binding) => binding.binding === "DB");
519
520
  if (!databaseBinding) {
520
521
  errors.push(
@@ -1,7 +1,8 @@
1
- import { existsSync, readFileSync, writeFileSync, renameSync } from 'node:fs';
1
+ import { existsSync, readFileSync } from 'node:fs';
2
2
  import { runCodegen, CodegenDiagnosticError } from '@lunora/codegen';
3
3
  import { classifyEdit, applyAdditiveEdit } from './applyAdditiveEdit-C-snTFEV.mjs';
4
4
  import { parseSchema } from './parseSchema-DSeyktvG.mjs';
5
+ import { w as writeFileAtomic } from './write-atomic-B2REqapi.mjs';
5
6
  import { join } from 'node:path';
6
7
 
7
8
  const SCHEMA_EDIT_ENDPOINT = "/__lunora/schema-edit";
@@ -36,11 +37,6 @@ const readSchema = (schemaPath) => {
36
37
  }
37
38
  return { tables: parsed.tables };
38
39
  };
39
- const writeSchemaAtomic = (schemaPath, text) => {
40
- const temporaryPath = `${schemaPath}.lunora-tmp`;
41
- writeFileSync(temporaryPath, text, "utf8");
42
- renameSync(temporaryPath, schemaPath);
43
- };
44
40
  const needsMigrationResponse = (edit) => {
45
41
  return {
46
42
  body: {
@@ -54,7 +50,7 @@ const needsMigrationResponse = (edit) => {
54
50
  };
55
51
  const handlePost = (request, schemaPath) => {
56
52
  const edit = request.body;
57
- if (edit === void 0 || typeof edit !== "object" || typeof edit.kind !== "string") {
53
+ if (edit === void 0 || edit === null || typeof edit !== "object" || typeof edit.kind !== "string") {
58
54
  return { body: { error: "invalid-edit", ok: false }, status: 400 };
59
55
  }
60
56
  if (classifyEdit(edit) === "destructive") {
@@ -67,7 +63,7 @@ const handlePost = (request, schemaPath) => {
67
63
  if (!applied.ok) {
68
64
  return { body: { error: applied.reason, ok: false }, status: statusForFailure(applied.reason) };
69
65
  }
70
- writeSchemaAtomic(schemaPath, applied.text);
66
+ writeFileAtomic(schemaPath, applied.text);
71
67
  let diagnostics = [];
72
68
  try {
73
69
  runCodegen({ lunoraDirectory: request.schemaDirectory ?? "lunora", projectRoot: request.projectRoot });
@@ -26,7 +26,7 @@ const handleSeedRequest = (request) => {
26
26
  return { body: { error: "method-not-allowed", ok: false }, status: 405 };
27
27
  }
28
28
  const { body } = request;
29
- if (body === void 0 || typeof body !== "object") {
29
+ if (body === void 0 || body === null || typeof body !== "object") {
30
30
  return { body: { error: "invalid-request", ok: false }, status: 400 };
31
31
  }
32
32
  const { count, existingIds, seed, table } = body;
@@ -46,11 +46,11 @@ const isPlaceholderValue = (value) => {
46
46
  };
47
47
  const isPlaceholder = (rawValue) => isPlaceholderValue(unquoteDevVariable(rawValue.trim()));
48
48
  const defaultRandomHex = (bytes) => randomBytes(bytes).toString("hex");
49
- const generatedSecretFor = (key, rawValue, randomHex) => SECRET_KEY.test(key) && isPlaceholder(rawValue) ? randomHex(SECRET_BYTES) : void 0;
50
49
  const PROVIDER_SECRET_KEYS = new Set(
51
50
  [...CORE_SECRETS, ...Object.values(PACKAGE_SECRETS_REGISTRY).flat()].filter((entry) => SECRET_KEY.test(entry.key) && entry.placeholderValue.startsWith("<")).map((entry) => entry.key)
52
51
  );
53
52
  const isMintableSecretKey = (key) => SECRET_KEY.test(key) && !PROVIDER_SECRET_KEYS.has(key);
53
+ const generatedSecretFor = (key, rawValue, randomHex) => isMintableSecretKey(key) && isPlaceholder(rawValue) ? randomHex(SECRET_BYTES) : void 0;
54
54
  const generateSecretValue = (randomHex = defaultRandomHex) => randomHex(SECRET_BYTES);
55
55
  const planDevVariablesScaffold = (input) => {
56
56
  if (input.devVarsExists) {
@@ -1,6 +1,6 @@
1
1
  import { relative } from 'node:path';
2
2
  import { secretKindOf, redact } from '@lunora/codegen';
3
- import { isPlaceholderValue } from './buildPackageSecretsBlock-BDXX0mKG.mjs';
3
+ import { isPlaceholderValue } from './buildPackageSecretsBlock-B-dWb-Sa.mjs';
4
4
  import { findWranglerFile, readWranglerJsonc } from './WRANGLER_FILES-DwSuC-Kn.mjs';
5
5
 
6
6
  const MIN_SECRET_NAMED_VALUE_LENGTH = 8;
@@ -0,0 +1,9 @@
1
+ import { modify, applyEdits } from 'jsonc-parser';
2
+
3
+ const FORMATTING = { formattingOptions: { insertSpaces: true, tabSize: 4 } };
4
+ const applyModify = (text, path, value) => {
5
+ const edits = modify(text, [...path], value, FORMATTING);
6
+ return edits.length > 0 ? applyEdits(text, edits) : text;
7
+ };
8
+
9
+ export { FORMATTING as F, applyModify as a };
@@ -0,0 +1,21 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { parseDevVariableEntries } from './DEV_VARS_EXAMPLE_FILE-dJPNTEnK.mjs';
4
+
5
+ const parseDevVariable = (contents, key) => {
6
+ const entry = parseDevVariableEntries(contents).find((candidate) => candidate.key === key);
7
+ return entry === void 0 || entry.value === "" ? void 0 : entry.value;
8
+ };
9
+ const resolveAdminToken = (root) => {
10
+ const fromEnv = process.env["LUNORA_ADMIN_TOKEN"];
11
+ if (typeof fromEnv === "string" && fromEnv !== "") {
12
+ return fromEnv;
13
+ }
14
+ try {
15
+ return parseDevVariable(readFileSync(join(root, ".dev.vars"), "utf8"), "LUNORA_ADMIN_TOKEN");
16
+ } catch {
17
+ return void 0;
18
+ }
19
+ };
20
+
21
+ export { parseDevVariable, resolveAdminToken };
@@ -1,9 +1,8 @@
1
1
  import { writeFileSync } from 'node:fs';
2
2
  import { containerBuildTag } from '@lunora/container';
3
- import { modify, applyEdits } from 'jsonc-parser';
3
+ import { a as applyModify } from './jsonc-edit-SbcD7MAe.mjs';
4
4
  import { findWranglerFile, readWranglerJsonc } from './WRANGLER_FILES-DwSuC-Kn.mjs';
5
5
 
6
- const FORMATTING = { formattingOptions: { insertSpaces: true, tabSize: 4 } };
7
6
  const D1_PLACEHOLDER_ID = "<replace-with-d1-create-id>";
8
7
  const collectExportGaps = (inferred) => {
9
8
  const gaps = [];
@@ -97,10 +96,6 @@ const collectWarnings = (inferred, parsed) => {
97
96
  warnings.push(...collectX402Warnings(inferred), ...collectHintBindingWarnings(inferred, parsed));
98
97
  return warnings;
99
98
  };
100
- const applyModify = (text, path, value) => {
101
- const edits = modify(text, [...path], value, FORMATTING);
102
- return edits.length > 0 ? applyEdits(text, edits) : text;
103
- };
104
99
  const nextMigrationTag = (migrations) => {
105
100
  const used = new Set(migrations.map((migration) => migration.tag));
106
101
  let index = 1;
@@ -1,9 +1,9 @@
1
1
  import { writeFileSync } from 'node:fs';
2
2
  import { modify, applyEdits } from 'jsonc-parser';
3
+ import { F as FORMATTING } from './jsonc-edit-SbcD7MAe.mjs';
3
4
  import { findWranglerFile, readWranglerJsonc } from './WRANGLER_FILES-DwSuC-Kn.mjs';
4
5
 
5
6
  const WORKERS_CACHE_MIN_DATE = "2026-05-01";
6
- const FORMATTING = { formattingOptions: { insertSpaces: true, tabSize: 4 } };
7
7
  const reconcileWranglerCompatibilityDate = (projectRoot) => {
8
8
  const wranglerPath = findWranglerFile(projectRoot);
9
9
  if (!wranglerPath) {
@@ -57,7 +57,7 @@ const csrfRejectionReason = (request) => {
57
57
  }
58
58
  return void 0;
59
59
  };
60
- const serveJsonHandler = (request, response, handle, projectRoot) => {
60
+ const serveJsonHandler = (request, response, handle, projectRoot, schemaDirectory) => {
61
61
  const run = async () => {
62
62
  try {
63
63
  const rejection = csrfRejectionReason(request);
@@ -73,7 +73,7 @@ const serveJsonHandler = (request, response, handle, projectRoot) => {
73
73
  respondJson(response, 400, { error: "invalid-json", ok: false });
74
74
  return;
75
75
  }
76
- const result = handle({ body: parsed, method: request.method ?? "POST", projectRoot });
76
+ const result = handle({ body: parsed, method: request.method ?? "POST", projectRoot, schemaDirectory });
77
77
  respondJson(response, result.status, result.body);
78
78
  } catch (error) {
79
79
  respondJson(response, 500, { error: error instanceof Error ? error.message : String(error), ok: false });
@@ -0,0 +1,14 @@
1
+ import { writeFileSync, renameSync, rmSync } from 'node:fs';
2
+
3
+ const writeFileAtomic = (path, text) => {
4
+ const temporaryPath = `${path}.lunora-tmp`;
5
+ try {
6
+ writeFileSync(temporaryPath, text, "utf8");
7
+ renameSync(temporaryPath, path);
8
+ } catch (error) {
9
+ rmSync(temporaryPath, { force: true });
10
+ throw error;
11
+ }
12
+ };
13
+
14
+ export { writeFileAtomic as w };
@@ -1,6 +1,12 @@
1
1
  import { D as DestructivePolicyEdit, S as ScaffoldPolicyEdit, W as WireRlsEdit } from "../packem_shared/policy-scaffold.d-DCmwn7zQ.mjs";
2
2
  import { IncomingMessage, ServerResponse } from 'node:http';
3
- /** Parse a single `KEY=value` (optionally quoted) out of a `.dev.vars` body. */
3
+ /**
4
+ * Parse a single `KEY=value` (optionally quoted) out of a `.dev.vars` body,
5
+ * returning `undefined` when the key is absent or its value is empty. A thin
6
+ * wrapper over {@link parseDevVariableEntries} — the single owner of the
7
+ * `.dev.vars` line grammar — so the key-validation, comment-skip, and quote-strip
8
+ * rules can't drift from every other reader/writer of the file.
9
+ */
4
10
  declare const parseDevVariable: (contents: string, key: string) => string | undefined;
5
11
  /**
6
12
  * Resolve the worker's admin token so the studio can auto-authenticate in
@@ -254,6 +260,10 @@ type LocalEndpointHandler = (request: LocalEndpointRequest) => LocalEndpointResp
254
260
  * schema); every other method has its body read + JSON-parsed first. The
255
261
  * handler's `{ status, body }` is serialised back as JSON. A malformed body is a
256
262
  * `400`; an unexpected throw (e.g. the body-size guard) is a `500`.
263
+ *
264
+ * `schemaDirectory` (when the host configures a custom `schemaDir`) is forwarded
265
+ * to the handler so the schema/seed/policy endpoints target the right directory
266
+ * instead of always defaulting to `"lunora"`.
257
267
  */
258
- declare const serveJsonHandler: (request: IncomingMessage, response: ServerResponse, handle: LocalEndpointHandler, projectRoot: string) => void;
268
+ declare const serveJsonHandler: (request: IncomingMessage, response: ServerResponse, handle: LocalEndpointHandler, projectRoot: string, schemaDirectory?: string) => void;
259
269
  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, assetContentType, handlePolicyScaffoldRequest, handleSchemaEditRequest, handleSeedRequest, isStandaloneModulePath, loadStudioAssets, parseDevVariable, readStandaloneAsset, renderStudioHtml, resolveAdminToken, resolveStandaloneDirectory, serveJsonHandler, studioAssetsStamp };
@@ -1,6 +1,12 @@
1
1
  import { D as DestructivePolicyEdit, S as ScaffoldPolicyEdit, W as WireRlsEdit } from "../packem_shared/policy-scaffold.d-DCmwn7zQ.js";
2
2
  import { IncomingMessage, ServerResponse } from 'node:http';
3
- /** Parse a single `KEY=value` (optionally quoted) out of a `.dev.vars` body. */
3
+ /**
4
+ * Parse a single `KEY=value` (optionally quoted) out of a `.dev.vars` body,
5
+ * returning `undefined` when the key is absent or its value is empty. A thin
6
+ * wrapper over {@link parseDevVariableEntries} — the single owner of the
7
+ * `.dev.vars` line grammar — so the key-validation, comment-skip, and quote-strip
8
+ * rules can't drift from every other reader/writer of the file.
9
+ */
4
10
  declare const parseDevVariable: (contents: string, key: string) => string | undefined;
5
11
  /**
6
12
  * Resolve the worker's admin token so the studio can auto-authenticate in
@@ -254,6 +260,10 @@ type LocalEndpointHandler = (request: LocalEndpointRequest) => LocalEndpointResp
254
260
  * schema); every other method has its body read + JSON-parsed first. The
255
261
  * handler's `{ status, body }` is serialised back as JSON. A malformed body is a
256
262
  * `400`; an unexpected throw (e.g. the body-size guard) is a `500`.
263
+ *
264
+ * `schemaDirectory` (when the host configures a custom `schemaDir`) is forwarded
265
+ * to the handler so the schema/seed/policy endpoints target the right directory
266
+ * instead of always defaulting to `"lunora"`.
257
267
  */
258
- declare const serveJsonHandler: (request: IncomingMessage, response: ServerResponse, handle: LocalEndpointHandler, projectRoot: string) => void;
268
+ declare const serveJsonHandler: (request: IncomingMessage, response: ServerResponse, handle: LocalEndpointHandler, projectRoot: string, schemaDirectory?: string) => void;
259
269
  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, assetContentType, handlePolicyScaffoldRequest, handleSchemaEditRequest, handleSeedRequest, isStandaloneModulePath, loadStudioAssets, parseDevVariable, readStandaloneAsset, renderStudioHtml, resolveAdminToken, resolveStandaloneDirectory, serveJsonHandler, studioAssetsStamp };
@@ -1,7 +1,7 @@
1
- export { parseDevVariable, resolveAdminToken } from '../packem_shared/parseDevVariable-CJiq2IwE.mjs';
1
+ export { parseDevVariable, resolveAdminToken } from '../packem_shared/parseDevVariable-B0FEvfHC.mjs';
2
2
  export { assetContentType, isStandaloneModulePath, loadStudioAssets, readStandaloneAsset, resolveStandaloneDirectory, studioAssetsStamp } from '../packem_shared/assetContentType-ByZjeV3D.mjs';
3
- export { POLICY_SCAFFOLD_ENDPOINT, handlePolicyScaffoldRequest } from '../packem_shared/POLICY_SCAFFOLD_ENDPOINT-8bNMHGiu.mjs';
3
+ export { POLICY_SCAFFOLD_ENDPOINT, handlePolicyScaffoldRequest } from '../packem_shared/POLICY_SCAFFOLD_ENDPOINT-CvTZpaZF.mjs';
4
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';
5
+ export { SCHEMA_EDIT_ENDPOINT, handleSchemaEditRequest } from '../packem_shared/SCHEMA_EDIT_ENDPOINT-Bt2SNkpV.mjs';
6
+ export { SEED_ENDPOINT, handleSeedRequest } from '../packem_shared/SEED_ENDPOINT-7izz_Jao.mjs';
7
+ export { serveJsonHandler } from '../packem_shared/serveJsonHandler-Cl2Wqkv8.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/config",
3
- "version": "1.0.0-alpha.61",
3
+ "version": "1.0.0-alpha.62",
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",
@@ -50,10 +50,10 @@
50
50
  "access": "public"
51
51
  },
52
52
  "dependencies": {
53
- "@lunora/codegen": "1.0.0-alpha.39",
54
- "@lunora/container": "1.0.0-alpha.8",
55
- "@lunora/errors": "1.0.0-alpha.3",
56
- "@lunora/seed": "1.0.0-alpha.21",
53
+ "@lunora/codegen": "1.0.0-alpha.40",
54
+ "@lunora/container": "1.0.0-alpha.9",
55
+ "@lunora/errors": "1.0.0-alpha.4",
56
+ "@lunora/seed": "1.0.0-alpha.22",
57
57
  "@visulima/colorize": "2.0.0",
58
58
  "@visulima/find-ai-runner": "1.0.0",
59
59
  "dockerode": "^5.0.1",
@@ -62,7 +62,7 @@
62
62
  "ts-morph": "^28.0.0"
63
63
  },
64
64
  "peerDependencies": {
65
- "@lunora/studio": "1.0.0-alpha.46"
65
+ "@lunora/studio": "1.0.0-alpha.47"
66
66
  },
67
67
  "peerDependenciesMeta": {
68
68
  "@lunora/studio": {
@@ -1,30 +0,0 @@
1
- import { readFileSync } from 'node:fs';
2
- import { join } from 'node:path';
3
-
4
- const LINE_BREAK = /\r?\n/u;
5
- const parseDevVariable = (contents, key) => {
6
- for (const raw of contents.split(LINE_BREAK)) {
7
- const line = raw.trim();
8
- const eq = line.indexOf("=");
9
- if (line === "" || line.startsWith("#") || eq === -1 || line.slice(0, eq).trim() !== key) {
10
- continue;
11
- }
12
- const value = line.slice(eq + 1).trim();
13
- const unquoted = value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'") ? value.slice(1, -1) : value;
14
- return unquoted === "" ? void 0 : unquoted;
15
- }
16
- return void 0;
17
- };
18
- const resolveAdminToken = (root) => {
19
- const fromEnv = process.env["LUNORA_ADMIN_TOKEN"];
20
- if (typeof fromEnv === "string" && fromEnv !== "") {
21
- return fromEnv;
22
- }
23
- try {
24
- return parseDevVariable(readFileSync(join(root, ".dev.vars"), "utf8"), "LUNORA_ADMIN_TOKEN");
25
- } catch {
26
- return void 0;
27
- }
28
- };
29
-
30
- export { parseDevVariable, resolveAdminToken };