@lunora/config 1.0.0-alpha.35 → 1.0.0-alpha.351

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 (129) hide show
  1. package/LICENSE.md +135 -0
  2. package/README.md +3 -3
  3. package/dist/cloudflare/index.d.mts +1252 -0
  4. package/dist/cloudflare/index.d.ts +1252 -0
  5. package/dist/cloudflare/index.mjs +1 -0
  6. package/dist/index.d.mts +1048 -917
  7. package/dist/index.d.ts +1048 -917
  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-HrrbNZPy.mjs +1 -0
  12. package/dist/packem_shared/ALLOW_FORWARDED_ENV-BUndghJx.mjs +1 -0
  13. package/dist/packem_shared/BINDING_MANIFEST_VERSION-CfXEYG8e.mjs +1 -0
  14. package/dist/packem_shared/CLOUDFLARE_CLI_CONFIG_WARNING_ENV-BKMrOuXV.mjs +1 -0
  15. package/dist/packem_shared/CLOUDFLARE_DRIVER-CULavrYO.mjs +1 -0
  16. package/dist/packem_shared/CLOUDFLARE_TOOLCHAIN_VERSIONS-DV5E_f_q.mjs +1 -0
  17. package/dist/packem_shared/CODEGEN_ENV-ZsCxV1kP.mjs +1 -0
  18. package/dist/packem_shared/COMPOSED_WORKER_ENTRY-Ciiba5g_.mjs +1 -0
  19. package/dist/packem_shared/DEFAULT_DEPLOY_TARGET-rR7buNQw.mjs +1 -0
  20. package/dist/packem_shared/DEFAULT_OBSERVABILITY-bN6UkTMx.mjs +1 -0
  21. package/dist/packem_shared/DEV_BINDINGS_FILE-C0ZN_XlP.mjs +4 -0
  22. package/dist/packem_shared/DEV_VARS_EXAMPLE_FILE-CqLorAxT.mjs +6 -0
  23. package/dist/packem_shared/DEV_WORKER_ENV_VALUE-2XFXmRrP.mjs +1 -0
  24. package/dist/packem_shared/GLOBAL_FETCH_STRICTLY_PUBLIC_FLAG-f8CnJha3.mjs +1 -0
  25. package/dist/packem_shared/LINKED_PROJECT_DIR-Ba5qPEwo.mjs +2 -0
  26. package/dist/packem_shared/LUNORA_EVENT_SOURCE-B9ZVohjO.mjs +1 -0
  27. package/dist/packem_shared/LUNORA_IGNORED_PATHS-U93uPxrW.mjs +19 -0
  28. package/dist/packem_shared/LUNORA_TAG-CiQM3BkI.mjs +1 -0
  29. package/dist/packem_shared/LunoraReporter-f277GLNT.mjs +6 -0
  30. package/dist/packem_shared/PACKAGE_SECRETS_REGISTRY-38Plje8b.mjs +1 -0
  31. package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-BmJYwAy2.mjs +1 -0
  32. package/dist/packem_shared/REMOTE_ELIGIBLE_KEYS-PLeh_74E.mjs +1 -0
  33. package/dist/packem_shared/REQUIRED_COMPATIBILITY_DATE-OLQlG0oj.mjs +1 -0
  34. package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-BeTxqCuQ.mjs +1 -0
  35. package/dist/packem_shared/SEED_ENDPOINT-2B56PN_H.mjs +1 -0
  36. package/dist/packem_shared/STUDIO_PATH-CSx_psKS.mjs +1 -0
  37. package/dist/packem_shared/UNEXPORTED_CLASS_MARKER-DwJCN8fX.mjs +1 -0
  38. package/dist/packem_shared/WORKERS_CACHE_MIN_DATE-0k9ABJtF.mjs +1 -0
  39. package/dist/packem_shared/WRANGLER_FILES-UNW-xY5u.mjs +1 -0
  40. package/dist/packem_shared/acceptsConnection-DHhUYGjT.mjs +2 -0
  41. package/dist/packem_shared/addArgsFor-CYZKhNIo.mjs +1 -0
  42. package/dist/packem_shared/applyAdditiveEdit-CH0VhMJ2.mjs +6 -0
  43. package/dist/packem_shared/applyModify-DKP2l6S9.mjs +1 -0
  44. package/dist/packem_shared/applyStudioAssetCache-DHQEJuuv.mjs +1 -0
  45. package/dist/packem_shared/assertWranglerSatisfiesSchema-Dd7ZPhw7.mjs +3 -0
  46. package/dist/packem_shared/assetContentType-CUb5bpbI.mjs +1 -0
  47. package/dist/packem_shared/buildPackageSecretsBlock-BWV_VxqV.mjs +19 -0
  48. package/dist/packem_shared/celld-config-D-L6uskI.mjs +3 -0
  49. package/dist/packem_shared/classifyPolicyEdit-DJi9Fk8G.mjs +24 -0
  50. package/dist/packem_shared/collectExportGaps-BPuhGH2J.mjs +2 -0
  51. package/dist/packem_shared/createConfirm-D5mKTMHj.mjs +7 -0
  52. package/dist/packem_shared/createDiscoveryCache-npJI4uej.mjs +1 -0
  53. package/dist/packem_shared/describePreservedCrons-C5KPuPy3.mjs +1 -0
  54. package/dist/packem_shared/describeWithheldWorkersAi-IIxe3TuI.mjs +1 -0
  55. package/dist/packem_shared/detectFramework-Dfpvu6rD.mjs +1 -0
  56. package/dist/packem_shared/discover-info-DC2MrAIM.mjs +1 -0
  57. package/dist/packem_shared/discoverAgentInfo-pqFMJBtJ.mjs +1 -0
  58. package/dist/packem_shared/discoverContainerInfo-DzXr7Vm3.mjs +1 -0
  59. package/dist/packem_shared/discoverSchemaInfo-BBRlXZop.mjs +1 -0
  60. package/dist/packem_shared/discoverWorkflowInfo-zW7Tt0Tn.mjs +1 -0
  61. package/dist/packem_shared/guards-Buu_E7mP.mjs +1 -0
  62. package/dist/packem_shared/hasCloudflareCredentials-byvHpEiD.mjs +1 -0
  63. package/dist/packem_shared/infer-bindings-C1NFOdMi.mjs +1 -0
  64. package/dist/packem_shared/infer-bindings.d-CFxssIAC.d.mts +480 -0
  65. package/dist/packem_shared/infer-bindings.d-CFxssIAC.d.ts +480 -0
  66. package/dist/packem_shared/inferLunoraBindings-Gp_7yyIo.mjs +1 -0
  67. package/dist/packem_shared/interpretRemote-CcmGeGZ_.mjs +1 -0
  68. package/dist/packem_shared/lunora-manifest-DuH_Cmyu.mjs +6 -0
  69. package/dist/packem_shared/materializeServiceDevConfigs-DLUHefD-.mjs +1 -0
  70. package/dist/packem_shared/mergeWranglerEnvironment-DXiB-HcS.mjs +1 -0
  71. package/dist/packem_shared/package-secrets-registry-BeheNwsP.mjs +1 -0
  72. package/dist/packem_shared/parseDevVariable-teAAahVD.mjs +1 -0
  73. package/dist/packem_shared/parseSchema-D1Wbr1qv.mjs +1 -0
  74. package/dist/packem_shared/policy-scaffold.d-D2H4_G01.d.mts +86 -0
  75. package/dist/packem_shared/policy-scaffold.d-D2H4_G01.d.ts +86 -0
  76. package/dist/packem_shared/process-tree-once-Ou4SfxKM.mjs +1 -0
  77. package/dist/packem_shared/readProjectDependencies-l3uhUKjo.mjs +1 -0
  78. package/dist/packem_shared/reconcile-services-DFqH4eMQ.mjs +1 -0
  79. package/dist/packem_shared/reconcileBindingsSafely-7IJ58Uit.mjs +1 -0
  80. package/dist/packem_shared/reconcileWranglerCompatibilityDate-hocXEuRA.mjs +1 -0
  81. package/dist/packem_shared/renderStudioHtml-ByowDtMl.mjs +15 -0
  82. package/dist/packem_shared/resolveSchemaDirectory-Ca5P6KuP.mjs +1 -0
  83. package/dist/packem_shared/runPostCodegenHook-Dx3yTsYZ.mjs +1 -0
  84. package/dist/packem_shared/scanWranglerVariablesForSecrets-BFTVje1q.mjs +1 -0
  85. package/dist/packem_shared/serveJsonHandler-Dv0EdCb9.mjs +1 -0
  86. package/dist/packem_shared/startCelldDevSession-BLFsd6jG.mjs +1 -0
  87. package/dist/packem_shared/streamContainerLogs-0nko1qpv.mjs +2 -0
  88. package/dist/packem_shared/validate-bindings-CvNBF3U4.mjs +1 -0
  89. package/dist/packem_shared/withTailConsumer-DngzpJMK.mjs +1 -0
  90. package/dist/packem_shared/worker-entry-checks-AIASCYl7.mjs +1 -0
  91. package/dist/packem_shared/wranglerCodegenInputs-CbisphsH.mjs +1 -0
  92. package/dist/packem_shared/wranglerToAlchemy-CBO2ucRm.mjs +6 -0
  93. package/dist/packem_shared/write-atomic-CK6VZaPI.mjs +1 -0
  94. package/dist/studio-host/index.d.mts +314 -110
  95. package/dist/studio-host/index.d.ts +314 -110
  96. package/dist/studio-host/index.mjs +1 -7
  97. package/package.json +16 -7
  98. package/dist/packem_shared/ACCENT-DW1XJn8i.mjs +0 -40
  99. package/dist/packem_shared/AGENT_RULES_DIR-lcgC08aE.mjs +0 -40
  100. package/dist/packem_shared/DEV_VARS_EXAMPLE_FILE-dJPNTEnK.mjs +0 -37
  101. package/dist/packem_shared/LINKED_PROJECT_DIR-CXwXzV_C.mjs +0 -52
  102. package/dist/packem_shared/LUNORA_CONFIG_FILE-CtcIcB5-.mjs +0 -34
  103. package/dist/packem_shared/LUNORA_EVENT_SOURCE-D2fDeGB6.mjs +0 -86
  104. package/dist/packem_shared/LunoraReporter-Ci-bDCK9.mjs +0 -70
  105. package/dist/packem_shared/PACKAGE_SECRETS_REGISTRY-B8t_SdoZ.mjs +0 -70
  106. package/dist/packem_shared/POLICY_SCAFFOLD_ENDPOINT-CiC2IGKx.mjs +0 -103
  107. package/dist/packem_shared/REMOTE_ELIGIBLE_KEYS-BC7_e9Bz.mjs +0 -105
  108. package/dist/packem_shared/REQUIRED_COMPATIBILITY_DATE-2YYyWJUq.mjs +0 -561
  109. package/dist/packem_shared/SCHEMA_EDIT_ENDPOINT-Df-Wrix-.mjs +0 -99
  110. package/dist/packem_shared/SEED_ENDPOINT-DVCjaGO-.mjs +0 -61
  111. package/dist/packem_shared/WRANGLER_FILES-DwSuC-Kn.mjs +0 -25
  112. package/dist/packem_shared/applyAdditiveEdit-C-snTFEV.mjs +0 -228
  113. package/dist/packem_shared/buildPackageSecretsBlock-DWDKHViT.mjs +0 -243
  114. package/dist/packem_shared/classifyPolicyEdit-BHeAqF8P.mjs +0 -99
  115. package/dist/packem_shared/createConfirm-fvpdgJ9s.mjs +0 -100
  116. package/dist/packem_shared/detectFramework-Br-BcPBq.mjs +0 -41
  117. package/dist/packem_shared/discoverContainerInfo-BXFs6Wav.mjs +0 -19
  118. package/dist/packem_shared/discoverSchemaInfo-BB-CKlTK.mjs +0 -25
  119. package/dist/packem_shared/discoverWorkflowInfo-CedvR0mn.mjs +0 -19
  120. package/dist/packem_shared/inferLunoraBindings-ByMwG-gH.mjs +0 -352
  121. package/dist/packem_shared/loadStudioAssets-Csk5RS4E.mjs +0 -28
  122. package/dist/packem_shared/parseDevVariable-CJiq2IwE.mjs +0 -30
  123. package/dist/packem_shared/parseSchema-DSeyktvG.mjs +0 -107
  124. package/dist/packem_shared/policy-scaffold.d-DCmwn7zQ.d.mts +0 -74
  125. package/dist/packem_shared/policy-scaffold.d-DCmwn7zQ.d.ts +0 -74
  126. package/dist/packem_shared/reconcileWranglerBindings-Cruwwx1M.mjs +0 -334
  127. package/dist/packem_shared/renderStudioHtml-449Ysn75.mjs +0 -37
  128. package/dist/packem_shared/serveJsonHandler-B4OLTGLS.mjs +0 -86
  129. package/dist/packem_shared/streamContainerLogs-BZ4cOZwH.mjs +0 -157
@@ -1,100 +0,0 @@
1
- import { createInterface } from 'node:readline';
2
-
3
- const MULTI_SELECT_SEPARATOR = /[\s,]+/u;
4
- const isInteractive = () => process.stdin.isTTY;
5
- const promptYesNo = async (prompt, options) => {
6
- const rl = createInterface({ input: process.stdin, output: process.stdout });
7
- try {
8
- const answer = await new Promise((resolve) => {
9
- rl.question(prompt, (input) => {
10
- resolve(input);
11
- });
12
- });
13
- const normalised = answer.trim().toLowerCase();
14
- if (normalised === "") {
15
- return options?.defaultYes === true;
16
- }
17
- return normalised === "y" || normalised === "yes";
18
- } finally {
19
- rl.close();
20
- }
21
- };
22
- const createConfirm = (prefix = "") => isInteractive() ? (message) => promptYesNo(`${prefix}${message} [Y/n] `, { defaultYes: true }) : () => Promise.resolve(false);
23
- const promptSelect = async (message, options, settings) => {
24
- if (!isInteractive() || options.length === 0) {
25
- return settings?.default;
26
- }
27
- const defaultIndex = settings?.default === void 0 ? -1 : options.findIndex((option) => option.value === settings.default);
28
- const lines = options.map(
29
- (option, index) => ` ${String(index + 1)}) ${option.label}${option.description === void 0 ? "" : ` — ${option.description}`}`
30
- );
31
- const promptText = `${message}
32
- ${lines.join("\n")}
33
- > ${defaultIndex >= 0 ? `[${String(defaultIndex + 1)}] ` : ""}`;
34
- const rl = createInterface({ input: process.stdin, output: process.stdout });
35
- try {
36
- const answer = await new Promise((resolve) => {
37
- rl.question(promptText, (input) => {
38
- resolve(input);
39
- });
40
- });
41
- const trimmed = answer.trim();
42
- if (trimmed === "") {
43
- return settings?.default;
44
- }
45
- const choice = Number.parseInt(trimmed, 10);
46
- if (Number.isInteger(choice) && choice >= 1 && choice <= options.length) {
47
- return options[choice - 1]?.value;
48
- }
49
- const byText = options.find((option) => option.value === trimmed || option.label.toLowerCase() === trimmed.toLowerCase());
50
- return byText?.value ?? settings?.default;
51
- } finally {
52
- rl.close();
53
- }
54
- };
55
- const promptMultiSelect = async (message, options, settings) => {
56
- const defaults = settings?.defaults ?? [];
57
- if (!isInteractive() || options.length === 0) {
58
- return [...defaults];
59
- }
60
- const lines = options.map(
61
- (option, index) => ` ${String(index + 1)}) ${option.label}${option.description === void 0 ? "" : ` — ${option.description}`}`
62
- );
63
- const defaultHint = defaults.length === 0 ? "" : `[${defaults.join(", ")}] `;
64
- const promptText = `${message} (comma-separated; Enter for default)
65
- ${lines.join("\n")}
66
- > ${defaultHint}`;
67
- const rl = createInterface({ input: process.stdin, output: process.stdout });
68
- try {
69
- const answer = await new Promise((resolve) => {
70
- rl.question(promptText, (input) => {
71
- resolve(input);
72
- });
73
- });
74
- const trimmed = answer.trim();
75
- if (trimmed === "") {
76
- return [...defaults];
77
- }
78
- const tokens = trimmed.split(MULTI_SELECT_SEPARATOR).map((token) => token.trim()).filter((token) => token !== "");
79
- const picked = /* @__PURE__ */ new Set();
80
- for (const token of tokens) {
81
- const choice = Number.parseInt(token, 10);
82
- if (Number.isInteger(choice) && choice >= 1 && choice <= options.length && String(choice) === token) {
83
- const byIndex = options[choice - 1]?.value;
84
- if (byIndex !== void 0) {
85
- picked.add(byIndex);
86
- }
87
- continue;
88
- }
89
- const byText = options.find((option) => option.value === token || option.label.toLowerCase() === token.toLowerCase());
90
- if (byText !== void 0) {
91
- picked.add(byText.value);
92
- }
93
- }
94
- return options.filter((option) => picked.has(option.value)).map((option) => option.value);
95
- } finally {
96
- rl.close();
97
- }
98
- };
99
-
100
- export { createConfirm, isInteractive, promptMultiSelect, promptSelect, promptYesNo };
@@ -1,41 +0,0 @@
1
- import { existsSync, readFileSync } from 'node:fs';
2
- import { join } from 'node:path';
3
-
4
- const FRAMEWORK_SIGNATURES = [
5
- { class: "A", dependency: "@tanstack/react-start", framework: "tanstack-start" },
6
- { class: "A", dependency: "@tanstack/solid-start", framework: "tanstack-start-solid" },
7
- { class: "A", dependency: "@react-router/dev", framework: "react-router" },
8
- { class: "A", dependency: "@solidjs/start", framework: "solid-start" },
9
- { class: "A", dependency: "solid-start", framework: "solid-start" },
10
- { class: "B", dependency: "@sveltejs/kit", framework: "sveltekit" },
11
- { class: "B", dependency: "nuxt", framework: "nuxt" },
12
- { class: "B", dependency: "astro", framework: "astro" }
13
- ];
14
- const STANDALONE = { class: "C", framework: "none" };
15
- const readDependencyNames = (root) => {
16
- const packageJsonPath = join(root, "package.json");
17
- if (!existsSync(packageJsonPath)) {
18
- return /* @__PURE__ */ new Set();
19
- }
20
- try {
21
- const raw = readFileSync(packageJsonPath, "utf8");
22
- const parsed = JSON.parse(raw);
23
- return /* @__PURE__ */ new Set([...Object.keys(parsed.dependencies ?? {}), ...Object.keys(parsed.devDependencies ?? {})]);
24
- } catch {
25
- return /* @__PURE__ */ new Set();
26
- }
27
- };
28
- const detectFramework = (root) => {
29
- const dependencies = readDependencyNames(root);
30
- if (dependencies.size === 0) {
31
- return STANDALONE;
32
- }
33
- for (const signature of FRAMEWORK_SIGNATURES) {
34
- if (dependencies.has(signature.dependency)) {
35
- return { class: signature.class, framework: signature.framework };
36
- }
37
- }
38
- return STANDALONE;
39
- };
40
-
41
- export { detectFramework };
@@ -1,19 +0,0 @@
1
- import { existsSync } from 'node:fs';
2
- import { CONTAINERS_FILENAME, discoverContainers } from '@lunora/codegen';
3
- import { Project } from 'ts-morph';
4
- import { join } from 'node:path';
5
-
6
- const discoverContainerInfo = (projectRoot, schemaDirectory) => {
7
- const containersPath = join(projectRoot, schemaDirectory, CONTAINERS_FILENAME);
8
- if (!existsSync(containersPath)) {
9
- return { containers: [] };
10
- }
11
- try {
12
- const project = new Project({ skipAddingFilesFromTsConfig: true, skipFileDependencyResolution: true, useInMemoryFileSystem: false });
13
- return { containers: discoverContainers(project, join(projectRoot, schemaDirectory)) };
14
- } catch (error) {
15
- return { containers: [], error: error instanceof Error ? error.message : String(error) };
16
- }
17
- };
18
-
19
- export { discoverContainerInfo };
@@ -1,25 +0,0 @@
1
- import { existsSync } from 'node:fs';
2
- import { discoverSchema } from '@lunora/codegen';
3
- import { Project } from 'ts-morph';
4
- import { join } from 'node:path';
5
-
6
- const discoverSchemaInfo = (projectRoot, schemaDirectory) => {
7
- const schemaPath = join(projectRoot, schemaDirectory, "schema.ts");
8
- if (!existsSync(schemaPath)) {
9
- return { info: void 0 };
10
- }
11
- try {
12
- const project = new Project({ skipAddingFilesFromTsConfig: true, useInMemoryFileSystem: false });
13
- const schema = discoverSchema(project, schemaPath, projectRoot);
14
- return {
15
- info: {
16
- hasGlobalTable: schema.tables.some((table) => table.shardMode === "global"),
17
- vectorIndexNames: schema.vectorIndexes.map((index) => index.name)
18
- }
19
- };
20
- } catch (error) {
21
- return { error: error instanceof Error ? error.message : String(error), info: void 0 };
22
- }
23
- };
24
-
25
- export { discoverSchemaInfo };
@@ -1,19 +0,0 @@
1
- import { existsSync } from 'node:fs';
2
- import { WORKFLOWS_FILENAME, discoverWorkflows } from '@lunora/codegen';
3
- import { Project } from 'ts-morph';
4
- import { join } from 'node:path';
5
-
6
- const discoverWorkflowInfo = (projectRoot, schemaDirectory) => {
7
- const workflowsPath = join(projectRoot, schemaDirectory, WORKFLOWS_FILENAME);
8
- if (!existsSync(workflowsPath)) {
9
- return { workflows: [] };
10
- }
11
- try {
12
- const project = new Project({ skipAddingFilesFromTsConfig: true, useInMemoryFileSystem: false });
13
- return { workflows: discoverWorkflows(project, join(projectRoot, schemaDirectory)) };
14
- } catch (error) {
15
- return { error: error instanceof Error ? error.message : String(error), workflows: [] };
16
- }
17
- };
18
-
19
- export { discoverWorkflowInfo };
@@ -1,352 +0,0 @@
1
- import { existsSync, statSync, readFileSync, readdirSync } from 'node:fs';
2
- import { init, parse } from 'es-module-lexer';
3
- import { discoverContainerInfo } from './discoverContainerInfo-BXFs6Wav.mjs';
4
- import { FLAGS_FILENAME, discoverFlags, QUEUES_FILENAME, discoverQueues } from '@lunora/codegen';
5
- import { Project } from 'ts-morph';
6
- import { join } from 'node:path';
7
- import { discoverSchemaInfo } from './discoverSchemaInfo-BB-CKlTK.mjs';
8
- import { discoverWorkflowInfo } from './discoverWorkflowInfo-CedvR0mn.mjs';
9
- import { WRANGLER_FILES, readWranglerJsonc } from './WRANGLER_FILES-DwSuC-Kn.mjs';
10
-
11
- const discoverFlagsInfo = (projectRoot, schemaDirectory) => {
12
- const flagsPath = join(projectRoot, schemaDirectory, FLAGS_FILENAME);
13
- if (!existsSync(flagsPath)) {
14
- return {};
15
- }
16
- try {
17
- const project = new Project({ skipAddingFilesFromTsConfig: true, useInMemoryFileSystem: false });
18
- return { flags: discoverFlags(project, join(projectRoot, schemaDirectory)) };
19
- } catch (error) {
20
- return { error: error instanceof Error ? error.message : String(error) };
21
- }
22
- };
23
-
24
- const discoverQueueInfo = (projectRoot, schemaDirectory) => {
25
- const queuesPath = join(projectRoot, schemaDirectory, QUEUES_FILENAME);
26
- if (!existsSync(queuesPath)) {
27
- return { queues: [] };
28
- }
29
- try {
30
- const project = new Project({ skipAddingFilesFromTsConfig: true, useInMemoryFileSystem: false });
31
- return { queues: discoverQueues(project, join(projectRoot, schemaDirectory)) };
32
- } catch (error) {
33
- return { error: error instanceof Error ? error.message : String(error), queues: [] };
34
- }
35
- };
36
-
37
- const SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".cjs", ".cts", ".js", ".jsx", ".mjs", ".mts", ".ts", ".tsx"]);
38
- const IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([".git", ".lunora-cache", ".wrangler", "_generated", "dist", "node_modules"]);
39
- const DEFAULT_SCAN_DIRECTORIES = ["lunora", "src"];
40
- const WORKER_ENTRY_FALLBACKS = ["src/server/index.ts", "src/server/index.tsx", "src/index.ts", "src/worker.ts"];
41
- const DURABLE_OBJECT_BINDINGS = {
42
- SchedulerDO: "SCHEDULER",
43
- SessionDO: "SESSION",
44
- ShardDO: "SHARD"
45
- };
46
- const DURABLE_OBJECT_CLASSES = Object.keys(DURABLE_OBJECT_BINDINGS);
47
- const TYPE_ONLY_EXPORT_PATTERNS = {
48
- SchedulerDO: /\btype\s+SchedulerDO\b/,
49
- SessionDO: /\btype\s+SessionDO\b/,
50
- ShardDO: /\btype\s+ShardDO\b/
51
- };
52
- const ENV_DB_PATTERN = /\benv\s*\.\s*DB\b/;
53
- const ENV_AI_PATTERN = /\benv\s*\.\s*AI\b/;
54
- const CTX_PIPELINES_PATTERN = /\bctx\s*\.\s*pipelines\b/;
55
- const TYPE_ONLY_IMPORT_PATTERN = /^\s*import\s+type\b/;
56
- const CAPABILITY_SOURCES = {
57
- usesAi: { pattern: /\bfrom\s+["']@lunora\/ai["']/, source: "@lunora/ai" },
58
- usesAnalytics: { pattern: /\bfrom\s+["']@lunora\/bindings\/analytics["']/, source: "@lunora/bindings/analytics" },
59
- usesAuth: { pattern: /\bfrom\s+["']@lunora\/auth["']/, source: "@lunora/auth" },
60
- usesBrowser: { pattern: /\bfrom\s+["']@lunora\/browser["']/, source: "@lunora/browser" },
61
- usesHyperdrive: { pattern: /\bfrom\s+["']@lunora\/hyperdrive["']/, source: "@lunora/hyperdrive" },
62
- usesImages: { pattern: /\bfrom\s+["']@lunora\/bindings\/images["']/, source: "@lunora/bindings/images" },
63
- usesKv: { pattern: /\bfrom\s+["']@lunora\/bindings\/kv["']/, source: "@lunora/bindings/kv" },
64
- usesMail: { pattern: /\bfrom\s+["']@lunora\/mail["']/, source: "@lunora/mail" },
65
- usesPayment: { pattern: /\bfrom\s+["']@lunora\/payment["']/, source: "@lunora/payment" },
66
- // Keyed off the `ctx.pipelines` access (not an import) — see CTX_PIPELINES_PATTERN.
67
- // Pipelines is codegen-wired onto ActionCtx, so apps reach it via `ctx.pipelines`
68
- // rather than importing `@lunora/bindings/pipelines`; `source` names that subpath
69
- // for the hint message.
70
- usesPipelines: { pattern: CTX_PIPELINES_PATTERN, source: "@lunora/bindings/pipelines" },
71
- usesScheduler: { pattern: /\bfrom\s+["']@lunora\/scheduler["']/, source: "@lunora/scheduler" },
72
- usesStorage: { pattern: /\bfrom\s+["']@lunora\/storage["']/, source: "@lunora/storage" }
73
- };
74
- const CAPABILITY_FLAGS = Object.keys(CAPABILITY_SOURCES);
75
- const PAYMENT_PROVIDER_SECRETS = "STRIPE_SECRET_KEY + STRIPE_WEBHOOK_SECRET (Stripe) or POLAR_ACCESS_TOKEN + POLAR_WEBHOOK_SECRET (Polar)";
76
- const ALL_CAPABILITY_KEYS = [...CAPABILITY_FLAGS, "needsD1"];
77
- const emptyCapabilities = () => {
78
- const base = {};
79
- for (const key of ALL_CAPABILITY_KEYS) {
80
- base[key] = false;
81
- }
82
- return base;
83
- };
84
- const NO_CAPABILITIES = Object.freeze(emptyCapabilities());
85
- const mergeCapabilities = (a, b) => {
86
- const merged = {};
87
- for (const key of ALL_CAPABILITY_KEYS) {
88
- merged[key] = a[key] || b[key];
89
- }
90
- return merged;
91
- };
92
- const capabilityForImportSource = (source) => {
93
- for (const flag of CAPABILITY_FLAGS) {
94
- if (CAPABILITY_SOURCES[flag].source === source) {
95
- return { ...NO_CAPABILITIES, [flag]: true };
96
- }
97
- }
98
- return NO_CAPABILITIES;
99
- };
100
- const lexCapabilities = (code) => {
101
- const [imports] = parse(code);
102
- let capabilities = NO_CAPABILITIES;
103
- for (const entry of imports) {
104
- const source = entry.n;
105
- if (!source || TYPE_ONLY_IMPORT_PATTERN.test(code.slice(entry.ss, entry.se))) {
106
- continue;
107
- }
108
- capabilities = mergeCapabilities(capabilities, capabilityForImportSource(source));
109
- }
110
- return capabilities;
111
- };
112
- const regexCapabilities = (code) => {
113
- const capabilities = { ...NO_CAPABILITIES };
114
- for (const flag of CAPABILITY_FLAGS) {
115
- capabilities[flag] = CAPABILITY_SOURCES[flag].pattern.test(code);
116
- }
117
- return capabilities;
118
- };
119
- const capabilitiesFromSource = (code) => {
120
- let capabilities;
121
- try {
122
- capabilities = lexCapabilities(code);
123
- } catch {
124
- capabilities = regexCapabilities(code);
125
- }
126
- return mergeCapabilities(capabilities, {
127
- ...NO_CAPABILITIES,
128
- needsD1: ENV_DB_PATTERN.test(code),
129
- usesAi: ENV_AI_PATTERN.test(code),
130
- usesPipelines: CTX_PIPELINES_PATTERN.test(code)
131
- });
132
- };
133
- const collectSourceFiles = (directory, accumulator) => {
134
- let entries;
135
- try {
136
- entries = readdirSync(directory, { withFileTypes: true });
137
- } catch {
138
- return;
139
- }
140
- for (const entry of entries) {
141
- if (entry.isDirectory()) {
142
- if (!IGNORED_DIRECTORIES.has(entry.name)) {
143
- collectSourceFiles(join(directory, entry.name), accumulator);
144
- }
145
- continue;
146
- }
147
- const dotIndex = entry.name.lastIndexOf(".");
148
- if (dotIndex !== -1 && SOURCE_EXTENSIONS.has(entry.name.slice(dotIndex))) {
149
- accumulator.push(join(directory, entry.name));
150
- }
151
- }
152
- };
153
- const resolveWorkerEntry = (projectRoot) => {
154
- for (const candidate of WRANGLER_FILES) {
155
- const wranglerPath = join(projectRoot, candidate);
156
- if (!existsSync(wranglerPath)) {
157
- continue;
158
- }
159
- const { parsed } = readWranglerJsonc(wranglerPath);
160
- const main = parsed?.main;
161
- if (typeof main === "string" && existsSync(join(projectRoot, main))) {
162
- return join(projectRoot, main);
163
- }
164
- break;
165
- }
166
- for (const fallback of WORKER_ENTRY_FALLBACKS) {
167
- const fullPath = join(projectRoot, fallback);
168
- if (existsSync(fullPath)) {
169
- return fullPath;
170
- }
171
- }
172
- return void 0;
173
- };
174
- const detectExportedDurableObjects = (entryPath) => {
175
- const code = readFileSync(entryPath, "utf8");
176
- let exportedNames;
177
- try {
178
- const [, exports] = parse(code);
179
- exportedNames = new Set(exports.map((entry) => entry.n));
180
- } catch {
181
- exportedNames = new Set(DURABLE_OBJECT_CLASSES.filter((className) => new RegExp(String.raw`\bexport\b[^\n;]*\b${className}\b`).test(code)));
182
- }
183
- return DURABLE_OBJECT_CLASSES.filter((className) => exportedNames.has(className) && !TYPE_ONLY_EXPORT_PATTERNS[className].test(code)).map((className) => {
184
- return {
185
- binding: DURABLE_OBJECT_BINDINGS[className],
186
- className
187
- };
188
- });
189
- };
190
- const CONTAINERS_STAR_REEXPORT_PATTERN = /\bexport\s*\*\s*from\s*["'][^"']*_generated\/containers(?:\.js)?["']/;
191
- const detectContainerExports = (entryPath, containers) => {
192
- if (containers.length === 0) {
193
- return [];
194
- }
195
- if (entryPath === void 0) {
196
- return containers.map((container) => {
197
- return { ...container, exported: false };
198
- });
199
- }
200
- const code = readFileSync(entryPath, "utf8");
201
- const starReexport = CONTAINERS_STAR_REEXPORT_PATTERN.test(code);
202
- let exportedNames;
203
- try {
204
- const [, exports] = parse(code);
205
- exportedNames = new Set(exports.map((entry) => entry.n));
206
- } catch {
207
- exportedNames = new Set(
208
- containers.map((container) => container.className).filter((className) => new RegExp(String.raw`\bexport\b[^\n;]*\b${className}\b`).test(code))
209
- );
210
- }
211
- return containers.map((container) => {
212
- return { ...container, exported: starReexport || exportedNames.has(container.className) };
213
- });
214
- };
215
- const WORKFLOWS_STAR_REEXPORT_PATTERN = /\bexport\s*\*\s*from\s*["'][^"']*_generated\/workflows(?:\.js)?["']/;
216
- const detectWorkflowExports = (entryPath, workflows) => {
217
- if (workflows.length === 0) {
218
- return [];
219
- }
220
- if (entryPath === void 0) {
221
- return workflows.map((workflow) => {
222
- return { ...workflow, exported: false };
223
- });
224
- }
225
- const code = readFileSync(entryPath, "utf8");
226
- const starReexport = WORKFLOWS_STAR_REEXPORT_PATTERN.test(code);
227
- let exportedNames;
228
- try {
229
- const [, exports] = parse(code);
230
- exportedNames = new Set(exports.map((entry) => entry.n));
231
- } catch {
232
- exportedNames = new Set(
233
- workflows.map((workflow) => workflow.className).filter((className) => new RegExp(String.raw`\bexport\b[^\n;]*\b${className}\b`).test(code))
234
- );
235
- }
236
- return workflows.map((workflow) => {
237
- return { ...workflow, exported: starReexport || exportedNames.has(workflow.className) };
238
- });
239
- };
240
- const schemaNeedsD1 = (projectRoot, schemaDirectory) => discoverSchemaInfo(projectRoot, schemaDirectory).info?.hasGlobalTable ?? false;
241
- const scanCapabilities = (projectRoot, scanDirectories) => {
242
- let merged = NO_CAPABILITIES;
243
- for (const relativeDirectory of scanDirectories) {
244
- const absolute = join(projectRoot, relativeDirectory);
245
- if (!existsSync(absolute) || !statSync(absolute).isDirectory()) {
246
- continue;
247
- }
248
- const files = [];
249
- collectSourceFiles(absolute, files);
250
- for (const file of files) {
251
- merged = mergeCapabilities(merged, capabilitiesFromSource(readFileSync(file, "utf8")));
252
- }
253
- }
254
- return merged;
255
- };
256
- const describeDeclaredExports = (containers, workflows) => [
257
- ...containers.map(
258
- (container) => container.exported ? `${container.bindingName}/${container.className} (container "${container.exportName}" declared and exported)` : `hint: container "${container.exportName}" is declared but ${container.className} is not exported by the worker entry — add \`export * from "./lunora/_generated/containers"\``
259
- ),
260
- ...workflows.map(
261
- (workflow) => workflow.exported ? `${workflow.bindingName}/${workflow.className} (workflow "${workflow.exportName}" declared and exported)` : `hint: workflow "${workflow.exportName}" is declared but ${workflow.className} is not exported by the worker entry — add \`export * from "./lunora/_generated/workflows"\``
262
- )
263
- ];
264
- const describeCapabilitySignals = (capabilities, exported) => {
265
- const rules = [
266
- [capabilities.usesAi, "AI (@lunora/ai imported or env.AI used)"],
267
- [
268
- capabilities.usesAuth && !exported.has("SessionDO"),
269
- "hint: @lunora/auth is imported but no SessionDO is exported (sessions are D1-backed, or export SessionDO for DO-backed sessions)"
270
- ],
271
- [capabilities.usesScheduler && !exported.has("SchedulerDO"), "hint: @lunora/scheduler is imported but no SchedulerDO is exported by the worker entry"],
272
- [capabilities.usesStorage, "hint: @lunora/storage is imported; add an r2_buckets binding (bucket binding names are user-defined)"],
273
- [capabilities.usesMail, "hint: @lunora/mail is imported; set RESEND_API_KEY in .dev.vars (obtain at https://resend.com/api-keys)"],
274
- [capabilities.usesPayment, `hint: @lunora/payment is imported; set the provider secrets in .dev.vars — ${PAYMENT_PROVIDER_SECRETS}`],
275
- // Self-describing bindings: the binding name is the whole config (no remote
276
- // id to mint), so reconcile auto-writes them like the DO/D1 bindings.
277
- [capabilities.usesBrowser, "browser (@lunora/browser imported) — self-describing { binding: BROWSER }"],
278
- [capabilities.usesImages, "images (@lunora/bindings/images imported) — self-describing { binding: IMAGES }"],
279
- [capabilities.usesAnalytics, "analytics_engine_datasets (@lunora/bindings/analytics imported) — self-describing { binding: ANALYTICS, dataset }"],
280
- // Hint bindings: each needs a remote resource Lunora can't fabricate (a KV
281
- // namespace id, a Hyperdrive id, a Pipelines pipeline name), so they surface
282
- // as hints — never an auto-write — exactly like R2's user-defined bucket name.
283
- [
284
- capabilities.usesKv,
285
- "hint: @lunora/bindings/kv is imported; add a kv_namespaces binding ({ binding, id }) and pass env.<BINDING> to createKv() — the namespace id can't be auto-provisioned"
286
- ],
287
- [
288
- capabilities.usesHyperdrive,
289
- "hint: @lunora/hyperdrive is imported; run 'wrangler hyperdrive create' and add a 'hyperdrive' binding ({ binding, id }) — the id can't be auto-provisioned"
290
- ],
291
- [
292
- capabilities.usesPipelines,
293
- "hint: ctx.pipelines is used; run 'wrangler pipelines create <name>' and add a 'pipelines' binding ({ binding, pipeline }) — the pipeline resource can't be auto-provisioned"
294
- ]
295
- ];
296
- return rules.filter(([active]) => active).map(([, signal]) => signal);
297
- };
298
- const describeSignals = (durableObjects, needsD1, capabilities, containers = [], workflows = []) => {
299
- const exported = new Set(durableObjects.map((object) => object.className));
300
- const signals = durableObjects.map((object) => `${object.binding}/${object.className} (exported by worker entry)`);
301
- if (needsD1) {
302
- signals.push("DB (.global() table declared)");
303
- }
304
- signals.push(...describeDeclaredExports(containers, workflows), ...describeCapabilitySignals(capabilities, exported));
305
- return signals;
306
- };
307
- const inferLunoraBindings = async (options) => {
308
- await init;
309
- const schemaDirectory = options.schemaDir ?? "lunora";
310
- const scanDirectories = options.scanDirs ?? DEFAULT_SCAN_DIRECTORIES;
311
- const capabilities = scanCapabilities(options.projectRoot, scanDirectories);
312
- const entryPath = resolveWorkerEntry(options.projectRoot);
313
- const durableObjects = entryPath ? detectExportedDurableObjects(entryPath) : [];
314
- const needsD1 = capabilities.needsD1 || schemaNeedsD1(options.projectRoot, schemaDirectory);
315
- const containers = detectContainerExports(entryPath, discoverContainerInfo(options.projectRoot, schemaDirectory).containers);
316
- const workflows = detectWorkflowExports(entryPath, discoverWorkflowInfo(options.projectRoot, schemaDirectory).workflows);
317
- const queues = [...discoverQueueInfo(options.projectRoot, schemaDirectory).queues];
318
- const { flags } = discoverFlagsInfo(options.projectRoot, schemaDirectory);
319
- const flagshipBinding = flags?.provider === "flagship" && flags.mode === "binding" ? flags.bindingName : void 0;
320
- const capabilityFlags = {};
321
- for (const flag of CAPABILITY_FLAGS) {
322
- capabilityFlags[flag] = capabilities[flag];
323
- }
324
- const signals = describeSignals(durableObjects, needsD1, capabilities, containers, workflows);
325
- if (flagshipBinding !== void 0) {
326
- signals.push(
327
- `hint: lunora/flags.ts uses Flagship in binding mode; add a flagship binding ({ binding: "${flagshipBinding}", app_id }) — the app_id can't be auto-provisioned`
328
- );
329
- }
330
- return {
331
- containers,
332
- durableObjects,
333
- flagshipBinding,
334
- needsD1,
335
- queues,
336
- signals,
337
- usesFlags: flags !== void 0,
338
- workflows,
339
- ...capabilityFlags
340
- };
341
- };
342
- const packageNamesFromBindings = (bindings) => {
343
- const names = [];
344
- for (const flag of CAPABILITY_FLAGS) {
345
- if (bindings[flag]) {
346
- names.push(CAPABILITY_SOURCES[flag].source);
347
- }
348
- }
349
- return names;
350
- };
351
-
352
- export { inferLunoraBindings, packageNamesFromBindings };
@@ -1,28 +0,0 @@
1
- import { readFileSync, statSync } from 'node:fs';
2
- import { createRequire } from 'node:module';
3
-
4
- const loadStudioAssets = (logger, resolveFrom = import.meta.url) => {
5
- try {
6
- const require = createRequire(resolveFrom);
7
- return {
8
- script: readFileSync(require.resolve("@lunora/studio/standalone/studio.js")),
9
- styles: readFileSync(require.resolve("@lunora/studio/styles.css"))
10
- };
11
- } catch (error) {
12
- const message = error instanceof Error ? error.message : String(error);
13
- logger?.warnOnce?.(`[lunora] studio assets unavailable (build @lunora/studio?): ${message}`);
14
- return void 0;
15
- }
16
- };
17
- const studioAssetsStamp = (resolveFrom = import.meta.url) => {
18
- try {
19
- const require = createRequire(resolveFrom);
20
- const scriptMtime = statSync(require.resolve("@lunora/studio/standalone/studio.js")).mtimeMs;
21
- const stylesMtime = statSync(require.resolve("@lunora/studio/styles.css")).mtimeMs;
22
- return Math.max(scriptMtime, stylesMtime);
23
- } catch {
24
- return void 0;
25
- }
26
- };
27
-
28
- export { loadStudioAssets as default, studioAssetsStamp };
@@ -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 };