@lunora/config 1.0.0-alpha.13 → 1.0.0-alpha.131

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 (93) hide show
  1. package/LICENSE.md +6 -0
  2. package/README.md +2 -2
  3. package/__assets__/package-og.svg +1 -1
  4. package/dist/cloudflare/index.d.mts +790 -0
  5. package/dist/cloudflare/index.d.ts +790 -0
  6. package/dist/cloudflare/index.mjs +1 -0
  7. package/dist/index.d.mts +702 -855
  8. package/dist/index.d.ts +702 -855
  9. package/dist/index.mjs +1 -22
  10. package/dist/packem_shared/ACCENT-CLeV5v0K.mjs +7 -0
  11. package/dist/packem_shared/AGENT_MODE_ENV-B54hVQ_w.mjs +1 -0
  12. package/dist/packem_shared/AGENT_RULES_DIR-hP9TiDNx.mjs +1 -0
  13. package/dist/packem_shared/ALLOW_FORWARDED_ENV-DGdbCDre.mjs +1 -0
  14. package/dist/packem_shared/BINDING_MANIFEST_VERSION-DOlqQgYt.mjs +1 -0
  15. package/dist/packem_shared/CLOUDFLARE_DRIVER-B_MaIVFz.mjs +1 -0
  16. package/dist/packem_shared/DEFAULT_DEPLOY_TARGET-cfA_ogWA.mjs +1 -0
  17. package/dist/packem_shared/DEV_DAEMON_ENV-D9Z83rlU.mjs +4 -0
  18. package/dist/packem_shared/DEV_VARS_EXAMPLE_FILE-BL0hrPx3.mjs +6 -0
  19. package/dist/packem_shared/LINKED_PROJECT_DIR-CMzUvj-1.mjs +2 -0
  20. package/dist/packem_shared/LUNORA_CONFIG_FILE-11ax8L-y.mjs +1 -0
  21. package/dist/packem_shared/LUNORA_EVENT_SOURCE-ZclWASXS.mjs +1 -0
  22. package/dist/packem_shared/LUNORA_IGNORED_PATHS-DIdyP0js.mjs +19 -0
  23. package/dist/packem_shared/LunoraReporter-BnXUqh8t.mjs +6 -0
  24. package/dist/packem_shared/PACKAGE_SECRETS_REGISTRY-BgmvEPA-.mjs +1 -0
  25. package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-CUYWD0Mh.mjs +1 -0
  26. package/dist/packem_shared/REMOTE_ELIGIBLE_KEYS-ws6iE0y-.mjs +1 -0
  27. package/dist/packem_shared/REQUIRED_COMPATIBILITY_DATE-BN97lRmC.mjs +1 -0
  28. package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-BNB1ogaj.mjs +1 -0
  29. package/dist/packem_shared/SEED_ENDPOINT-BaYShU8q.mjs +1 -0
  30. package/dist/packem_shared/WORKERS_CACHE_MIN_DATE-B1h_wNDN.mjs +1 -0
  31. package/dist/packem_shared/WRANGLER_FILES-Bi_18Pj6.mjs +1 -0
  32. package/dist/packem_shared/applyAdditiveEdit-Cff30cSa.mjs +6 -0
  33. package/dist/packem_shared/assetContentType-DNZyUOuF.mjs +1 -0
  34. package/dist/packem_shared/buildPackageSecretsBlock-D2oDEMcf.mjs +18 -0
  35. package/dist/packem_shared/classifyPolicyEdit-BzC_MfYK.mjs +24 -0
  36. package/dist/packem_shared/cloudflare-driver-BHtz6vmK.mjs +1 -0
  37. package/dist/packem_shared/collectExportGaps-ajyIOfom.mjs +1 -0
  38. package/dist/packem_shared/collectWranglerSecretVariables-DZE0RIsW.mjs +1 -0
  39. package/dist/packem_shared/createConfirm-C5G4-dT6.mjs +7 -0
  40. package/dist/packem_shared/detectFramework-VTQfCNXy.mjs +1 -0
  41. package/dist/packem_shared/discover-info-DRQ0Ote0.mjs +1 -0
  42. package/dist/packem_shared/discoverAgentInfo-C8LTinx8.mjs +1 -0
  43. package/dist/packem_shared/discoverContainerInfo-C1zY2O8F.mjs +1 -0
  44. package/dist/packem_shared/discoverSchemaInfo-C8X9mo-i.mjs +1 -0
  45. package/dist/packem_shared/discoverWorkflowInfo-DHzCyLRj.mjs +1 -0
  46. package/dist/packem_shared/inferLunoraBindings-_ESCdL9P.mjs +1 -0
  47. package/dist/packem_shared/jsonc-edit-BZVpxVA0.mjs +1 -0
  48. package/dist/packem_shared/parseDevVariable-B193_28t.mjs +1 -0
  49. package/dist/packem_shared/parseSchema-BQjgz6bk.mjs +1 -0
  50. package/dist/packem_shared/{policy-scaffold.d-DCmwn7zQ.d.mts → policy-scaffold.d-fV3db0S_.d.mts} +23 -23
  51. package/dist/packem_shared/{policy-scaffold.d-DCmwn7zQ.d.ts → policy-scaffold.d-fV3db0S_.d.ts} +23 -23
  52. package/dist/packem_shared/reconcileWranglerCompatibilityDate-BXNiEQ7p.mjs +1 -0
  53. package/dist/packem_shared/reconcileWranglerCrons-BmQa_kGL.mjs +1 -0
  54. package/dist/packem_shared/renderStudioHtml-B2AkxcW1.mjs +15 -0
  55. package/dist/packem_shared/schema-info.d-DS0bUsWE.d.mts +375 -0
  56. package/dist/packem_shared/schema-info.d-DS0bUsWE.d.ts +375 -0
  57. package/dist/packem_shared/serveJsonHandler-DQ-Yqa4J.mjs +1 -0
  58. package/dist/packem_shared/streamContainerLogs-BPYBNrWS.mjs +2 -0
  59. package/dist/packem_shared/wranglerToAlchemy-BXagFk92.mjs +6 -0
  60. package/dist/packem_shared/write-atomic-Cdr2oQb-.mjs +1 -0
  61. package/dist/studio-host/index.d.mts +166 -92
  62. package/dist/studio-host/index.d.ts +166 -92
  63. package/dist/studio-host/index.mjs +1 -7
  64. package/package.json +15 -8
  65. package/dist/packem_shared/ACCENT-DW1XJn8i.mjs +0 -40
  66. package/dist/packem_shared/AGENT_RULES_DIR-lcgC08aE.mjs +0 -40
  67. package/dist/packem_shared/DEV_VARS_EXAMPLE_FILE-dJPNTEnK.mjs +0 -37
  68. package/dist/packem_shared/LINKED_PROJECT_DIR-CXwXzV_C.mjs +0 -52
  69. package/dist/packem_shared/LUNORA_CONFIG_FILE-CtcIcB5-.mjs +0 -34
  70. package/dist/packem_shared/LUNORA_EVENT_SOURCE-D2fDeGB6.mjs +0 -86
  71. package/dist/packem_shared/LunoraReporter-Ci-bDCK9.mjs +0 -70
  72. package/dist/packem_shared/PACKAGE_SECRETS_REGISTRY-B8t_SdoZ.mjs +0 -70
  73. package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-CiC2IGKx.mjs +0 -103
  74. package/dist/packem_shared/REMOTE_ELIGIBLE_KEYS-BC7_e9Bz.mjs +0 -105
  75. package/dist/packem_shared/REQUIRED_COMPATIBILITY_DATE-DRSNSOOp.mjs +0 -476
  76. package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-Df-Wrix-.mjs +0 -99
  77. package/dist/packem_shared/SEED_ENDPOINT-DVCjaGO-.mjs +0 -61
  78. package/dist/packem_shared/WRANGLER_FILES-DwSuC-Kn.mjs +0 -25
  79. package/dist/packem_shared/applyAdditiveEdit-C-snTFEV.mjs +0 -228
  80. package/dist/packem_shared/buildPackageSecretsBlock-DWDKHViT.mjs +0 -243
  81. package/dist/packem_shared/classifyPolicyEdit-BHeAqF8P.mjs +0 -99
  82. package/dist/packem_shared/createConfirm-fvpdgJ9s.mjs +0 -100
  83. package/dist/packem_shared/detectFramework-Br-BcPBq.mjs +0 -41
  84. package/dist/packem_shared/discoverContainerInfo-BXFs6Wav.mjs +0 -19
  85. package/dist/packem_shared/discoverSchemaInfo-BB-CKlTK.mjs +0 -25
  86. package/dist/packem_shared/discoverWorkflowInfo-CedvR0mn.mjs +0 -19
  87. package/dist/packem_shared/inferLunoraBindings-DIku9mTN.mjs +0 -302
  88. package/dist/packem_shared/loadStudioAssets-Csk5RS4E.mjs +0 -28
  89. package/dist/packem_shared/parseDevVariable-CJiq2IwE.mjs +0 -30
  90. package/dist/packem_shared/parseSchema-DSeyktvG.mjs +0 -107
  91. package/dist/packem_shared/reconcileWranglerBindings-DTHmqTbL.mjs +0 -277
  92. package/dist/packem_shared/renderStudioHtml-449Ysn75.mjs +0 -37
  93. package/dist/packem_shared/serveJsonHandler-B4OLTGLS.mjs +0 -86
@@ -1,86 +0,0 @@
1
- const LUNORA_EVENT_SOURCE = "lunora";
2
- const ROOT_SHARD_NAME = "__root__";
3
- const asString = (value) => typeof value === "string" ? value : "";
4
- const asStringList = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
5
- const formatDuration = (value) => typeof value === "number" && Number.isFinite(value) ? `${String(Math.round(value))}ms` : "?ms";
6
- const toLineLevel = (rawLevel) => {
7
- if (rawLevel === "error") {
8
- return "error";
9
- }
10
- if (rawLevel === "warn") {
11
- return "warn";
12
- }
13
- return "info";
14
- };
15
- const parseLunoraEvent = (line) => {
16
- const trimmed = line.trim();
17
- if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) {
18
- return void 0;
19
- }
20
- let parsed;
21
- try {
22
- parsed = JSON.parse(trimmed);
23
- } catch {
24
- return void 0;
25
- }
26
- if (typeof parsed !== "object" || parsed === null) {
27
- return void 0;
28
- }
29
- const event = parsed;
30
- return event.source === LUNORA_EVENT_SOURCE ? event : void 0;
31
- };
32
- const labelFor = (functionPath, event) => {
33
- const shard = asString(event.shard);
34
- return shard === "" || shard === ROOT_SHARD_NAME ? functionPath : `${functionPath}@${shard}`;
35
- };
36
- const formatRequest = (event, functionPath) => {
37
- const failed = event.outcome === "error";
38
- const parts = [labelFor(functionPath, event), failed ? "error" : "ok", formatDuration(event.durationMs)];
39
- const read = asStringList(event.tablesRead);
40
- const written = asStringList(event.tablesWritten);
41
- if (read.length > 0) {
42
- parts.push(`read[${read.join(",")}]`);
43
- }
44
- if (written.length > 0) {
45
- parts.push(`write[${written.join(",")}]`);
46
- }
47
- if (event.cacheHit === true) {
48
- parts.push("cached");
49
- }
50
- const errorMessage = asString(event.error);
51
- if (failed && errorMessage !== "") {
52
- parts.push(errorMessage);
53
- }
54
- return { kind: "rpc", level: failed ? "error" : "info", text: parts.join(" ") };
55
- };
56
- const formatContainer = (event) => {
57
- const name = asString(event.container) || "<unknown>";
58
- const instance = asString(event.instance);
59
- const transition = asString(event.event) || "event";
60
- const shortId = instance === "" || instance === "unknown" ? "" : `#${instance.slice(0, 8)}`;
61
- const message = asString(event.message);
62
- const parts = [`container:${name}${shortId}`, transition];
63
- if (message !== "") {
64
- parts.push(message);
65
- }
66
- return { kind: "log", level: event.event === "error" ? "error" : "info", text: parts.join(" ") };
67
- };
68
- const formatLunoraEvent = (line) => {
69
- const event = parseLunoraEvent(line);
70
- if (!event) {
71
- return void 0;
72
- }
73
- const functionPath = asString(event.function) || "<unknown>";
74
- if (event.type === "log") {
75
- return { kind: "log", level: toLineLevel(asString(event.level)), text: `${labelFor(functionPath, event)} ${asString(event.message)}`.trimEnd() };
76
- }
77
- if (event.type === "request") {
78
- return formatRequest(event, functionPath);
79
- }
80
- if (event.type === "container") {
81
- return formatContainer(event);
82
- }
83
- return void 0;
84
- };
85
-
86
- export { LUNORA_EVENT_SOURCE, formatLunoraEvent };
@@ -1,70 +0,0 @@
1
- import { paintBadge, badgeWidth, BADGES } from './ACCENT-DW1XJn8i.mjs';
2
-
3
- const NAME_ALIASES = {
4
- informational: "info",
5
- warning: "warn"
6
- };
7
- const STDERR_LEVELS = /* @__PURE__ */ new Set(["alert", "critical", "emergency", "error", "warn", "warning"]);
8
- const resolveBadge = (name) => {
9
- if (name in BADGES) {
10
- return BADGES[name];
11
- }
12
- const alias = NAME_ALIASES[name];
13
- return alias === void 0 ? void 0 : BADGES[alias];
14
- };
15
- const renderContextArgument = (value) => {
16
- if (value instanceof Error) {
17
- return `
18
- ${value.stack ?? value.message}`;
19
- }
20
- if (typeof value === "object" && value !== null) {
21
- try {
22
- return ` ${JSON.stringify(value)}`;
23
- } catch {
24
- return " [unserializable]";
25
- }
26
- }
27
- return ` ${String(value)}`;
28
- };
29
- const composeMessage = (meta) => {
30
- const base = typeof meta.message === "string" ? meta.message : String(meta.message);
31
- const context = meta.context ?? [];
32
- return context.length === 0 ? base : base + context.map((value) => renderContextArgument(value)).join("");
33
- };
34
- class LunoraReporter {
35
- #stdout = process.stdout;
36
- #stderr = process.stderr;
37
- setStdout(stdout) {
38
- this.#stdout = stdout;
39
- }
40
- setStderr(stderr) {
41
- this.#stderr = stderr;
42
- }
43
- // Note: pail's other reporter setters (setLoggerTypes / setInteractiveManager /
44
- // setIsInteractive) are optional and intentionally omitted — this reporter keeps
45
- // no type or interactive state; it only needs the two stream setters above.
46
- log(meta) {
47
- const data = meta;
48
- const badge = resolveBadge(data.type.name);
49
- const stream = STDERR_LEVELS.has(data.type.level ?? data.type.name) ? this.#stderr : this.#stdout;
50
- stream.write(LunoraReporter.#render(badge, composeMessage(data)));
51
- }
52
- /**
53
- * Frame `text` under `badge`: `&lt;badge> &lt;first line>`, with any further lines
54
- * indented to align beneath the message. Without a badge (unknown type) the
55
- * message is written plain.
56
- */
57
- static #render(badge, text) {
58
- if (badge === void 0) {
59
- return `${text}
60
- `;
61
- }
62
- const [first = "", ...rest] = text.split("\n");
63
- const indent = " ".repeat(badgeWidth() + 1);
64
- const lines = [`${paintBadge(badge)} ${first}`, ...rest.map((line) => `${indent}${line}`)];
65
- return `${lines.join("\n")}
66
- `;
67
- }
68
- }
69
-
70
- export { LunoraReporter as default };
@@ -1,70 +0,0 @@
1
- const CORE_SECRETS = [
2
- {
3
- 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",
4
- docsUrl: "https://lunora.sh/docs/packages/studio",
5
- key: "LUNORA_ADMIN_TOKEN",
6
- placeholderValue: "replace-with-openssl-rand-hex-32"
7
- }
8
- ];
9
- const PACKAGE_SECRETS_REGISTRY = {
10
- "@lunora/auth": [
11
- {
12
- description: "32-byte random secret used to sign sessions and tokens. Generate with: openssl rand -hex 32",
13
- docsUrl: "https://lunora.sh/docs/packages/auth#secrets",
14
- key: "AUTH_SECRET",
15
- placeholderValue: "replace-with-openssl-rand-hex-32"
16
- },
17
- {
18
- 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",
19
- docsUrl: "https://lunora.sh/docs/packages/auth#secrets",
20
- key: "AUTH_URL",
21
- placeholderValue: "http://localhost:8787"
22
- }
23
- ],
24
- "@lunora/mail": [
25
- {
26
- description: "Resend API key for sending transactional email via @lunora/mail. Obtain at https://resend.com/api-keys",
27
- docsUrl: "https://lunora.sh/docs/packages/mail#secrets",
28
- key: "RESEND_API_KEY",
29
- placeholderValue: "<your-resend-api-key>"
30
- }
31
- ],
32
- "@lunora/payment": [
33
- {
34
- description: "Stripe secret key (sk_test_…). Required when using the Stripe adapter. Obtain at https://dashboard.stripe.com/apikeys",
35
- docsUrl: "https://lunora.sh/docs/packages/payment#stripe",
36
- key: "STRIPE_SECRET_KEY",
37
- placeholderValue: "<your-stripe-secret-key>"
38
- },
39
- {
40
- description: "Stripe webhook signing secret (whsec_…) for verifying event payloads. Obtain at https://dashboard.stripe.com/webhooks",
41
- docsUrl: "https://lunora.sh/docs/packages/payment#stripe",
42
- key: "STRIPE_WEBHOOK_SECRET",
43
- placeholderValue: "<your-stripe-webhook-secret>"
44
- },
45
- {
46
- description: "Polar access token for the Polar payment adapter. Obtain at https://polar.sh/settings/tokens",
47
- docsUrl: "https://lunora.sh/docs/packages/payment#polar",
48
- key: "POLAR_ACCESS_TOKEN",
49
- placeholderValue: "<your-polar-access-token>"
50
- },
51
- {
52
- description: "Polar webhook secret for verifying event payloads from Polar. Obtain at https://polar.sh/settings/webhooks",
53
- docsUrl: "https://lunora.sh/docs/packages/payment#polar",
54
- key: "POLAR_WEBHOOK_SECRET",
55
- placeholderValue: "<your-polar-webhook-secret>"
56
- }
57
- ]
58
- };
59
- const secretsForPackages = (packageNames) => {
60
- const result = [];
61
- for (const name of packageNames) {
62
- const entries = PACKAGE_SECRETS_REGISTRY[name];
63
- if (entries !== void 0) {
64
- result.push(...entries);
65
- }
66
- }
67
- return result;
68
- };
69
-
70
- export { CORE_SECRETS, PACKAGE_SECRETS_REGISTRY, secretsForPackages };
@@ -1,103 +0,0 @@
1
- import { existsSync, readFileSync, writeFileSync, renameSync } from 'node:fs';
2
- import { join, isAbsolute, relative } from 'node:path';
3
- import { runCodegen, CodegenDiagnosticError } from '@lunora/codegen';
4
- import { classifyPolicyEdit, scaffoldPolicyFile, wireRlsIntoProcedure } from './classifyPolicyEdit-BHeAqF8P.mjs';
5
-
6
- const POLICY_SCAFFOLD_ENDPOINT = "/__lunora/policy-scaffold";
7
- const statusForFailure = (reason) => {
8
- if (reason === "unknown-procedure") {
9
- return 404;
10
- }
11
- if (reason === "already-wired") {
12
- return 409;
13
- }
14
- return reason === "destructive" ? 409 : 422;
15
- };
16
- const writeAtomic = (path, text) => {
17
- const temporaryPath = `${path}.lunora-tmp`;
18
- writeFileSync(temporaryPath, text, "utf8");
19
- renameSync(temporaryPath, path);
20
- };
21
- const runCodegenForResponse = (request, okBody) => {
22
- let diagnostics = [];
23
- try {
24
- runCodegen({ lunoraDirectory: request.schemaDirectory ?? "lunora", projectRoot: request.projectRoot });
25
- } catch (error) {
26
- if (error instanceof CodegenDiagnosticError) {
27
- diagnostics = [error.message];
28
- } else {
29
- return { body: { error: error instanceof Error ? error.message : String(error), ok: false }, status: 500 };
30
- }
31
- }
32
- return { body: { ...okBody, diagnostics, ok: true }, status: 200 };
33
- };
34
- const refuseDestructive = (edit) => {
35
- return {
36
- body: {
37
- edit,
38
- message: "Rewriting an existing policy predicate changes evaluation semantics and must be done by hand. The scaffolder only adds new, deny-by-default rules.",
39
- needsManualEdit: true,
40
- ok: false
41
- },
42
- status: 409
43
- };
44
- };
45
- const handleScaffoldPolicy = (request, edit) => {
46
- const result = scaffoldPolicyFile(edit);
47
- if (!result.ok) {
48
- return { body: { error: result.reason, ok: false }, status: statusForFailure(result.reason) };
49
- }
50
- const lunoraDirectory = request.schemaDirectory ?? "lunora";
51
- const targetPath = join(request.projectRoot, lunoraDirectory, result.fileName);
52
- if (existsSync(targetPath)) {
53
- return { body: { error: "file-exists", fileName: result.fileName, ok: false }, status: 409 };
54
- }
55
- writeAtomic(targetPath, result.source);
56
- return runCodegenForResponse(request, { fileName: result.fileName });
57
- };
58
- const resolveProcedureFile = (projectRoot, lunoraDirectory, filePath) => {
59
- if (typeof filePath !== "string" || filePath.length === 0 || isAbsolute(filePath) || filePath.includes("\\")) {
60
- return void 0;
61
- }
62
- const lunoraRoot = join(projectRoot, lunoraDirectory);
63
- const resolved = join(lunoraRoot, `${filePath}.ts`);
64
- const relativePath = relative(lunoraRoot, resolved);
65
- if (relativePath.startsWith("..") || isAbsolute(relativePath)) {
66
- return void 0;
67
- }
68
- return resolved;
69
- };
70
- const handleWireRls = (request, edit) => {
71
- const procedurePath = resolveProcedureFile(request.projectRoot, request.schemaDirectory ?? "lunora", edit.filePath);
72
- if (procedurePath === void 0 || !existsSync(procedurePath)) {
73
- return { body: { error: "unknown-procedure", ok: false }, status: 404 };
74
- }
75
- const wired = wireRlsIntoProcedure(readFileSync(procedurePath, "utf8"), edit);
76
- if (!wired.ok) {
77
- return { body: { error: wired.reason, ok: false }, status: statusForFailure(wired.reason) };
78
- }
79
- writeAtomic(procedurePath, wired.text);
80
- return runCodegenForResponse(request, { exportName: edit.exportName });
81
- };
82
- const handlePolicyScaffoldRequest = (request) => {
83
- if (request.method !== "POST") {
84
- return { body: { error: "method-not-allowed", ok: false }, status: 405 };
85
- }
86
- const { body } = request;
87
- if (body === void 0 || typeof body !== "object" || typeof body.kind !== "string") {
88
- return { body: { error: "invalid-edit", ok: false }, status: 400 };
89
- }
90
- const edit = body;
91
- if (classifyPolicyEdit(edit) === "destructive") {
92
- return refuseDestructive(edit);
93
- }
94
- if (edit.kind === "scaffoldPolicy") {
95
- return handleScaffoldPolicy(request, edit);
96
- }
97
- if (edit.kind === "wireRls") {
98
- return handleWireRls(request, edit);
99
- }
100
- throw new Error(`unhandled additive policy edit kind: ${String(edit.kind)}`);
101
- };
102
-
103
- export { POLICY_SCAFFOLD_ENDPOINT, handlePolicyScaffoldRequest };
@@ -1,105 +0,0 @@
1
- import { writeFileSync, rmSync } from 'node:fs';
2
- import { modify, applyEdits } from 'jsonc-parser';
3
- import { findWranglerFile, readWranglerJsonc } from './WRANGLER_FILES-DwSuC-Kn.mjs';
4
- import { join } from 'node:path';
5
-
6
- const FORMATTING = { formattingOptions: { insertSpaces: true, tabSize: 4 } };
7
- const REMOTE_ELIGIBLE_KEYS = {
8
- ai: { label: "AI", shape: "object" },
9
- d1_databases: { label: "D1", shape: "array" },
10
- kv_namespaces: { label: "KV", shape: "array" },
11
- queues: { label: "Queue", shape: "producers" },
12
- r2_buckets: { label: "R2", shape: "array" },
13
- services: { label: "Service", shape: "array" },
14
- vectorize: { label: "Vectorize", shape: "array" }
15
- };
16
- const REMOTE_ELIGIBLE_KEY_LIST = Object.keys(REMOTE_ELIGIBLE_KEYS);
17
- const entryName = (entry, fallback) => typeof entry.binding === "string" ? entry.binding : fallback;
18
- const planArrayEntries = (section, entries, kind, pathPrefix) => {
19
- const plans = [];
20
- for (const [index, entry] of entries.entries()) {
21
- if (entry === null || entry === void 0) {
22
- continue;
23
- }
24
- plans.push({ binding: entryName(entry, `#${String(index)}`), kind, path: [...pathPrefix, index], section });
25
- }
26
- return plans;
27
- };
28
- const planSection = (section, parsed) => {
29
- const { label, shape } = REMOTE_ELIGIBLE_KEYS[section];
30
- if (shape === "array") {
31
- const entries = parsed[section] ?? [];
32
- return planArrayEntries(section, entries, label, []);
33
- }
34
- if (shape === "producers") {
35
- return planArrayEntries(section, parsed.queues?.producers ?? [], label, ["producers"]);
36
- }
37
- const entry = parsed.ai;
38
- return entry === null || entry === void 0 ? [] : [{ binding: entryName(entry, section), kind: label, path: [], section }];
39
- };
40
- 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
- const injectRemoteFlags = (text, plans) => {
46
- let next = text;
47
- for (const plan of plans) {
48
- next = applyModify(next, [plan.section, ...plan.path, "remote"], true);
49
- }
50
- return next;
51
- };
52
- const noopCleanup = () => {
53
- };
54
- const createCleanup = (path) => {
55
- let done = false;
56
- return () => {
57
- if (done) {
58
- return;
59
- }
60
- done = true;
61
- try {
62
- rmSync(path, { force: true, recursive: true });
63
- } catch {
64
- }
65
- };
66
- };
67
- const remoteConfigBasename = () => `.wrangler.lunora-remote.${String(process.pid)}.jsonc`;
68
- const materializeRemoteWranglerConfig = (options) => {
69
- if (!options.enabled) {
70
- return { cleanup: noopCleanup, enabled: false, remoteBindings: [] };
71
- }
72
- const wranglerPath = findWranglerFile(options.projectRoot);
73
- if (!wranglerPath) {
74
- return { cleanup: noopCleanup, enabled: true, reason: "wrangler.jsonc not found", remoteBindings: [] };
75
- }
76
- const { parsed, text } = readWranglerJsonc(wranglerPath);
77
- if (parsed === void 0) {
78
- return { cleanup: noopCleanup, enabled: true, reason: `failed to parse ${wranglerPath} as JSONC`, remoteBindings: [] };
79
- }
80
- const plans = planRemoteBindings(parsed);
81
- if (plans.length === 0) {
82
- return { cleanup: noopCleanup, enabled: true, reason: "no remote-eligible bindings to proxy", remoteBindings: [] };
83
- }
84
- const configPath = join(options.projectRoot, remoteConfigBasename());
85
- writeFileSync(configPath, injectRemoteFlags(text, plans), "utf8");
86
- return { cleanup: createCleanup(configPath), configPath, enabled: true, remoteBindings: plans };
87
- };
88
- const isRemoteEnvEnabled = (value) => {
89
- if (value === void 0) {
90
- return false;
91
- }
92
- const normalized = value.trim().toLowerCase();
93
- return normalized === "1" || normalized === "true";
94
- };
95
- const resolveRemoteEnabled = (inputs) => {
96
- if (inputs.flag === true) {
97
- return true;
98
- }
99
- if (isRemoteEnvEnabled(inputs.envValue)) {
100
- return true;
101
- }
102
- return inputs.configPreference ?? false;
103
- };
104
-
105
- export { REMOTE_ELIGIBLE_KEYS, injectRemoteFlags, isRemoteEnvEnabled, materializeRemoteWranglerConfig, planRemoteBindings, resolveRemoteEnabled };