@lunora/cli 1.0.0-alpha.21 → 1.0.0-alpha.210

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 (110) hide show
  1. package/LICENSE.md +33 -0
  2. package/README.md +1 -1
  3. package/__assets__/package-og.svg +1 -1
  4. package/dist/bin.mjs +2 -10
  5. package/dist/index.d.mts +731 -341
  6. package/dist/index.d.ts +731 -341
  7. package/dist/index.mjs +1 -19
  8. package/dist/packem_chunks/handler.mjs +1 -150
  9. package/dist/packem_chunks/handler10.mjs +4 -22
  10. package/dist/packem_chunks/handler11.mjs +2 -192
  11. package/dist/packem_chunks/handler12.mjs +1 -131
  12. package/dist/packem_chunks/handler13.mjs +1 -65
  13. package/dist/packem_chunks/handler14.mjs +1 -58
  14. package/dist/packem_chunks/handler15.mjs +1 -79
  15. package/dist/packem_chunks/handler16.mjs +3 -43
  16. package/dist/packem_chunks/handler17.mjs +1 -105
  17. package/dist/packem_chunks/handler18.mjs +1 -170
  18. package/dist/packem_chunks/handler19.mjs +7 -89
  19. package/dist/packem_chunks/handler2.mjs +2 -114
  20. package/dist/packem_chunks/handler20.mjs +1 -94
  21. package/dist/packem_chunks/handler21.mjs +2 -311
  22. package/dist/packem_chunks/handler22.mjs +3 -0
  23. package/dist/packem_chunks/handler23.mjs +3 -0
  24. package/dist/packem_chunks/handler24.mjs +1 -0
  25. package/dist/packem_chunks/handler25.mjs +99 -0
  26. package/dist/packem_chunks/handler26.mjs +10 -0
  27. package/dist/packem_chunks/handler3.mjs +1 -204
  28. package/dist/packem_chunks/handler4.mjs +1 -33
  29. package/dist/packem_chunks/handler5.mjs +1 -49
  30. package/dist/packem_chunks/handler6.mjs +1 -91
  31. package/dist/packem_chunks/handler7.mjs +3 -42
  32. package/dist/packem_chunks/handler8.mjs +1 -174
  33. package/dist/packem_chunks/handler9.mjs +1 -16
  34. package/dist/packem_chunks/planDevCommand.mjs +7 -500
  35. package/dist/packem_chunks/runCodegenCommand.mjs +4 -52
  36. package/dist/packem_chunks/runDeployCommand.mjs +1 -504
  37. package/dist/packem_chunks/runInitCommand.mjs +118 -1383
  38. package/dist/packem_chunks/runMigrateGenerateCommand.mjs +9 -395
  39. package/dist/packem_chunks/runResetCommand.mjs +1 -41
  40. package/dist/packem_chunks/runRpcCommand.mjs +1 -68
  41. package/dist/packem_shared/COMMANDS-BKhYrmpZ.mjs +1 -0
  42. package/dist/packem_shared/DEFAULT_IMPORT_BATCH_SIZE-Nf7GsE6v.mjs +1 -0
  43. package/dist/packem_shared/admin-token-rxXZbVMZ.mjs +1 -0
  44. package/dist/packem_shared/admin-url-Cil3Or6N.mjs +1 -0
  45. package/dist/packem_shared/advisory-gate-Cl8IEFIj.mjs +1 -0
  46. package/dist/packem_shared/api-spec-lYyq4vL6.mjs +1 -0
  47. package/dist/packem_shared/binding-manifest-file-CQ1eQYy1.mjs +2 -0
  48. package/dist/packem_shared/buildRegistryIndex-Zi3bBqpc.mjs +1 -0
  49. package/dist/packem_shared/cli-CrC0a7dH.mjs +3 -0
  50. package/dist/packem_shared/codegen-error-AmH54ofi.mjs +3 -0
  51. package/dist/packem_shared/command-DwC11Cwe.mjs +1 -0
  52. package/dist/packem_shared/commands-BNKj7r1R.mjs +19 -0
  53. package/dist/packem_shared/createLogger-hGafwf-3.mjs +2 -0
  54. package/dist/packem_shared/createRecordingSpawner-DJlNacZ6.mjs +1 -0
  55. package/dist/packem_shared/deploy-target-D9GPy_tq.mjs +1 -0
  56. package/dist/packem_shared/diffSnapshots-CIOFQN_a.mjs +5 -0
  57. package/dist/packem_shared/docker-DpVxvYpL.mjs +1 -0
  58. package/dist/packem_shared/import-CrVGrOt3.mjs +12 -0
  59. package/dist/packem_shared/insertSchemaExtension-DY4pA8wE.mjs +8 -0
  60. package/dist/packem_shared/lint-ignore-report-DKZagpqk.mjs +2 -0
  61. package/dist/packem_shared/open-url-EnKy--w-.mjs +1 -0
  62. package/dist/packem_shared/output-format-DfogXx0p.mjs +2 -0
  63. package/dist/packem_shared/parseManifest-CwPTKdtS.mjs +1 -0
  64. package/dist/packem_shared/path-containment-CgxYZggb.mjs +1 -0
  65. package/dist/packem_shared/platform-diagnostics-uOXqysk3.mjs +4 -0
  66. package/dist/packem_shared/prompt-cancelled-C8Sj7OqI.mjs +1 -0
  67. package/dist/packem_shared/resolve-DZAGzg67.mjs +1 -0
  68. package/dist/packem_shared/resolve-target-BRvw8Pf7.mjs +1 -0
  69. package/dist/packem_shared/runAddCommand-D1Dj8-pK.mjs +1 -0
  70. package/dist/packem_shared/runExportCommand-DmXKEWSq.mjs +5 -0
  71. package/dist/packem_shared/schema-drift-gate-DARCKocg.mjs +1 -0
  72. package/dist/packem_shared/schemaIrToSnapshot-qpRoV7HY.mjs +1 -0
  73. package/dist/packem_shared/shared-D-zCOmgY.mjs +1 -0
  74. package/dist/packem_shared/storage-wIUel5Az.mjs +1 -0
  75. package/dist/packem_shared/tui-prompts-Dd0pDuNr.mjs +4 -0
  76. package/dist/packem_shared/vectorize-metadata-DbziRKpX.mjs +1 -0
  77. package/dist/packem_shared/wrangler-name-Dsk5K1f-.mjs +1 -0
  78. package/dist/packem_shared/wrangler-secrets-CCdt0mUl.mjs +1 -0
  79. package/package.json +39 -17
  80. package/skills/README.md +35 -17
  81. package/skills/lunora/SKILL.md +65 -9
  82. package/skills/lunora-functions/SKILL.md +38 -3
  83. package/skills/lunora-migration-helper/SKILL.md +70 -17
  84. package/skills/lunora-performance-audit/SKILL.md +36 -6
  85. package/skills/lunora-quickstart/SKILL.md +90 -24
  86. package/skills/lunora-realtime/SKILL.md +58 -30
  87. package/dist/packem_shared/COMMANDS-D3h9Iwvl.mjs +0 -944
  88. package/dist/packem_shared/DEFAULT_IMPORT_BATCH_SIZE-Ck-2bU08.mjs +0 -244
  89. package/dist/packem_shared/admin-url-4UzT-CI4.mjs +0 -19
  90. package/dist/packem_shared/api-spec-CtA6ilu4.mjs +0 -13
  91. package/dist/packem_shared/buildRegistryIndex-BcYe607_.mjs +0 -38
  92. package/dist/packem_shared/command-BC30oSBW.mjs +0 -14
  93. package/dist/packem_shared/commands-hl0mRqqg.mjs +0 -845
  94. package/dist/packem_shared/createLogger-B40gPzQo.mjs +0 -78
  95. package/dist/packem_shared/createRecordingSpawner-DxI3mebw.mjs +0 -43
  96. package/dist/packem_shared/detect-package-manager-DYp7n3mJ.mjs +0 -61
  97. package/dist/packem_shared/diffSnapshots-BeDvvNiF.mjs +0 -161
  98. package/dist/packem_shared/docker-hMQ97KSQ.mjs +0 -21
  99. package/dist/packem_shared/insertSchemaExtension-DAqbfr9Z.mjs +0 -64
  100. package/dist/packem_shared/open-url-Dfq6fAyT.mjs +0 -41
  101. package/dist/packem_shared/output-format-wUvAN6AL.mjs +0 -17
  102. package/dist/packem_shared/parseArgs-YXFuKdEk.mjs +0 -56
  103. package/dist/packem_shared/parseManifest--vZf2FY1.mjs +0 -94
  104. package/dist/packem_shared/resolve-target-qbsJ_5sF.mjs +0 -16
  105. package/dist/packem_shared/runAddCommand-vJdgiR5t.mjs +0 -4
  106. package/dist/packem_shared/schema-drift-gate-BtBt0as0.mjs +0 -79
  107. package/dist/packem_shared/schemaIrToSnapshot-DdsljJT-.mjs +0 -43
  108. package/dist/packem_shared/storage-B7hHSTZP.mjs +0 -84
  109. package/dist/packem_shared/tui-prompts-M6OWsuyw.mjs +0 -663
  110. package/dist/packem_shared/wrangler-name-cy4yhm9j.mjs +0 -12
@@ -1,397 +1,11 @@
1
- import { existsSync, mkdirSync, writeFileSync, mkdtempSync, rmSync, readFileSync } from 'node:fs';
2
- import { tmpdir } from 'node:os';
3
- import { discoverSchema, discoverMigrations } from '@lunora/codegen';
4
- import { join } from '@visulima/path';
5
- import { Project } from 'ts-morph';
6
- import { r as resolveAdminBaseUrl } from '../packem_shared/admin-url-4UzT-CI4.mjs';
7
- import { d as defineHandler } from '../packem_shared/command-BC30oSBW.mjs';
8
- import { diffSnapshots, renderMigrationFile } from '../packem_shared/diffSnapshots-BeDvvNiF.mjs';
9
- import { a as resolveProductionWorkerUrl } from '../packem_shared/resolve-target-qbsJ_5sF.mjs';
10
- import schemaIrToSnapshot from '../packem_shared/schemaIrToSnapshot-DdsljJT-.mjs';
11
- import { runExportCommand, runImportCommand } from '../packem_shared/DEFAULT_IMPORT_BATCH_SIZE-Ck-2bU08.mjs';
12
-
13
- const SNAPSHOT_FILENAME = ".snapshot.json";
14
- const NON_ALPHANUMERIC = /[^\da-z]+/gu;
15
- const trimChar = (value, char) => {
16
- let start = 0;
17
- let end = value.length;
18
- while (start < end && value[start] === char) {
19
- start += 1;
20
- }
21
- while (end > start && value[end - 1] === char) {
22
- end -= 1;
23
- }
24
- return value.slice(start, end);
25
- };
26
- const slugify = (input) => {
27
- const slug = trimChar(input.toLowerCase().replaceAll(NON_ALPHANUMERIC, "_"), "_");
28
- return slug === "" ? "auto" : slug;
29
- };
30
- const formatTimestamp = (now) => {
31
- const pad = (n, w = 2) => n.toString().padStart(w, "0");
32
- return `${String(now.getUTCFullYear())}${pad(now.getUTCMonth() + 1)}${pad(now.getUTCDate())}${pad(now.getUTCHours())}${pad(
33
- now.getUTCMinutes()
34
- )}${pad(now.getUTCSeconds())}`;
35
- };
36
- const loadSnapshot = (path) => {
37
- if (!existsSync(path)) {
38
- return void 0;
39
- }
40
- try {
41
- const raw = readFileSync(path, "utf8");
42
- const parsed = JSON.parse(raw);
43
- if (parsed.version !== 1) {
44
- throw new Error(`unsupported snapshot version: ${parsed.version}`);
45
- }
46
- return parsed;
47
- } catch (error) {
48
- const message = error instanceof Error ? error.message : String(error);
49
- throw new Error(`failed to read ${path}: ${message}`, { cause: error });
50
- }
51
- };
52
- const runMigrateGenerateCommand = (options) => {
53
- const cwd = options.cwd ?? process.cwd();
54
- const schemaPath = join(cwd, "lunora", "schema.ts");
55
- if (!existsSync(schemaPath)) {
56
- options.logger.error(`schema not found: ${schemaPath} — run \`vis generate lunora-table --name=<name>\` to create one`);
57
- return { code: 1, empty: true, migrationFile: "" };
58
- }
59
- const project = new Project({ skipAddingFilesFromTsConfig: true });
60
- const schemaIr = discoverSchema(project, schemaPath);
61
- const nextSnapshot = schemaIrToSnapshot(schemaIr);
62
- const migrationsDirectory = join(cwd, "lunora", "migrations");
63
- const snapshotPath = join(migrationsDirectory, SNAPSHOT_FILENAME);
64
- let previousSnapshot;
65
- try {
66
- previousSnapshot = loadSnapshot(snapshotPath);
67
- } catch (error) {
68
- options.logger.error(error instanceof Error ? error.message : String(error));
69
- return { code: 1, empty: true, migrationFile: "" };
70
- }
71
- const diff = diffSnapshots(previousSnapshot, nextSnapshot);
72
- if (diff.empty) {
73
- options.logger.info("no schema changes detected — snapshot is already up to date");
74
- return { code: 0, empty: true, migrationFile: "" };
75
- }
76
- const nowFunction = options.now ?? (() => /* @__PURE__ */ new Date());
77
- const now = nowFunction();
78
- const slug = slugify(options.name ?? "auto");
79
- const timestamp = formatTimestamp(now);
80
- const filename = `${timestamp}_${slug}.sql`;
81
- const migrationFile = join(migrationsDirectory, filename);
82
- mkdirSync(migrationsDirectory, { recursive: true });
83
- const body = renderMigrationFile(slug, diff, now.toISOString());
84
- writeFileSync(migrationFile, body, "utf8");
85
- writeFileSync(snapshotPath, `${JSON.stringify(nextSnapshot, void 0, 4)}
86
- `, "utf8");
87
- options.logger.success(`wrote ${migrationFile}`);
88
- if (diff.unsupported.length > 0) {
89
- options.logger.warn(`${String(diff.unsupported.length)} unsupported diff(s) — see the comment block in ${filename} and write the SQL manually`);
90
- }
91
- return { code: 0, empty: false, migrationFile };
92
- };
93
- const DATA_MIGRATIONS_FILENAME = "migrations.ts";
94
- const IDENTIFIER_PATTERN = /^[A-Za-z_]\w*$/u;
95
- const RESERVED_WORDS = /* @__PURE__ */ new Set([
96
- "await",
97
- "break",
98
- "case",
99
- "catch",
100
- "class",
101
- "const",
102
- "continue",
103
- "debugger",
104
- "default",
105
- "delete",
106
- "do",
107
- "else",
108
- "enum",
109
- "export",
110
- "extends",
111
- "false",
112
- "finally",
113
- "for",
114
- "function",
115
- "if",
116
- "implements",
117
- "import",
118
- "in",
119
- "instanceof",
120
- "interface",
121
- "let",
122
- "new",
123
- "null",
124
- "package",
125
- "private",
126
- "protected",
127
- "public",
128
- "return",
129
- "static",
130
- "super",
131
- "switch",
132
- "this",
133
- "throw",
134
- "true",
135
- "try",
136
- "typeof",
137
- "var",
138
- "void",
139
- "while",
140
- "with",
141
- "yield"
142
- ]);
143
- const DEFINE_MIGRATION_IMPORT = `import { defineMigration } from "@lunora/server";`;
144
- const RUN_MIGRATION_OP = "__lunora_admin__:runMigration";
145
- const MIGRATION_STATUS_OP = "__lunora_admin__:migrationStatus";
146
- const MIGRATE_ENDPOINT_PATH = "/_lunora/migrate";
147
- const kebabCase = (input) => trimChar(input.trim().toLowerCase().replaceAll(NON_ALPHANUMERIC, "-"), "-");
148
- const camelCase = (slug) => slug.split("-").filter((part) => part.length > 0).map((part, index) => {
149
- if (index === 0) {
150
- return part;
151
- }
152
- return part.charAt(0).toUpperCase() + part.slice(1);
153
- }).join("");
154
- const runMigrateCreateCommand = (options) => {
155
- const cwd = options.cwd ?? process.cwd();
156
- const slug = kebabCase(options.name);
157
- if (slug === "") {
158
- options.logger.error(`invalid migration name: "${options.name}" — must contain at least one alphanumeric character`);
159
- return { code: 1, file: "" };
160
- }
161
- const exportName = camelCase(slug);
162
- if (!IDENTIFIER_PATTERN.test(exportName) || RESERVED_WORDS.has(exportName)) {
163
- options.logger.error(
164
- `invalid migration name: "${options.name}" derives the export \`${exportName}\`, which is not a valid identifier — pick a name that starts with a letter and isn't a reserved word`
165
- );
166
- return { code: 1, file: "" };
167
- }
168
- const table = options.table ?? "TODO_table";
169
- if (!IDENTIFIER_PATTERN.test(table)) {
170
- options.logger.error(`invalid --table: "${table}" — must be a valid identifier ([A-Za-z_][A-Za-z0-9_]*)`);
171
- return { code: 1, file: "" };
172
- }
173
- const lunoraDirectory = join(cwd, "lunora");
174
- const file = join(lunoraDirectory, DATA_MIGRATIONS_FILENAME);
175
- let content = existsSync(file) ? readFileSync(file, "utf8") : "";
176
- if (content.includes(`id: "${slug}"`) || new RegExp(String.raw`\bexport const ${exportName}\b`, "u").test(content)) {
177
- options.logger.error(`a migration with id "${slug}" (export \`${exportName}\`) already exists in ${file}`);
178
- return { code: 1, file: "" };
179
- }
180
- if (content.trim() === "") {
181
- content = `${DEFINE_MIGRATION_IMPORT}
182
- `;
183
- } else if (!content.includes(DEFINE_MIGRATION_IMPORT)) {
184
- content = `${DEFINE_MIGRATION_IMPORT}
185
- ${content}`;
186
- }
187
- const block = `export const ${exportName} = defineMigration({
188
- id: "${slug}",
189
- table: "${table}",
1
+ import{existsSync as m,mkdirSync as T,writeFileSync as h,mkdtempSync as N,rmSync as M,readFileSync as I}from"node:fs";import{tmpdir as R}from"node:os";import{discoverSchema as _,readPackageDependencies as U,discoverMigrations as x}from"@lunora/codegen";import{isInteractive as C,promptSelect as O,promptText as F}from"@lunora/config";import{LunoraError as y}from"@lunora/errors";import{join as c}from"@visulima/path";import{Project as b}from"ts-morph";import{r as P}from"../packem_shared/admin-url-Cil3Or6N.mjs";import{d as D}from"../packem_shared/command-DwC11Cwe.mjs";import{diffSnapshots as z,renderMigrationFile as L}from"../packem_shared/diffSnapshots-CIOFQN_a.mjs";import{r as j}from"../packem_shared/resolve-target-BRvw8Pf7.mjs";import q from"../packem_shared/schemaIrToSnapshot-qpRoV7HY.mjs";import{readAndLogBody as H}from"./runRpcCommand.mjs";import{runExportCommand as G}from"../packem_shared/runExportCommand-DmXKEWSq.mjs";import{r as B}from"../packem_shared/import-CrVGrOt3.mjs";const u="__lunora_reproject__",W=e=>{if(!e.startsWith(u))return;const r=e.slice(u.length);return r===""?void 0:r},J=".snapshot.json",k=/[^\da-z]+/gu,A=(e,r)=>{let n=0,t=e.length;for(;n<t&&e[n]===r;)n+=1;for(;t>n&&e[t-1]===r;)t-=1;return e.slice(n,t)},K=e=>{const r=A(e.toLowerCase().replaceAll(k,"_"),"_");return r===""?"auto":r},V=e=>{const r=(n,t=2)=>n.toString().padStart(t,"0");return`${String(e.getUTCFullYear())}${r(e.getUTCMonth()+1)}${r(e.getUTCDate())}${r(e.getUTCHours())}${r(e.getUTCMinutes())}${r(e.getUTCSeconds())}`},Z=e=>{if(m(e))try{const r=I(e,"utf8"),n=JSON.parse(r);if(n.version!==1)throw new y("INTERNAL",`unsupported snapshot version: ${n.version}`);return n}catch(r){const n=r instanceof Error?r.message:String(r);throw new y("INTERNAL",`failed to read ${e}: ${n}`,{cause:r})}},X=e=>{const r=e.cwd??process.cwd(),n=c(r,"lunora","schema.ts");if(!m(n))return e.logger.error(`schema not found: ${n} — run \`vis generate lunora-table --name=<name>\` to create one`),{code:1,empty:!0,migrationFile:""};const t=new b({skipAddingFilesFromTsConfig:!0}),a=_(t,n),s=q(a),o=c(r,"lunora","migrations"),i=c(o,J);let d;try{d=Z(i)}catch(g){return e.logger.error(g instanceof Error?g.message:String(g)),{code:1,empty:!0,migrationFile:""}}const l=z(d,s);if(l.empty)return e.logger.info("no schema changes detected — snapshot is already up to date"),{code:0,empty:!0,migrationFile:""};const v=(e.now??(()=>new Date))(),p=K(e.name??"auto"),w=`${V(v)}_${p}.sql`,f=c(o,w);T(o,{recursive:!0});const E=L(p,l,v.toISOString());return h(f,E,"utf8"),h(i,`${JSON.stringify(s,void 0,4)}
2
+ `,"utf8"),e.logger.success(`wrote ${f}`),l.unsupported.length>0&&e.logger.warn(`${String(l.unsupported.length)} unsupported diff(s) — see the comment block in ${w} and write the SQL manually`),{code:0,empty:!1,migrationFile:f}},Q="migrations.ts",$=/^[A-Za-z_]\w*$/u,Y=new Set(["await","break","case","catch","class","const","continue","debugger","default","delete","do","else","enum","export","extends","false","finally","for","function","if","implements","import","in","instanceof","interface","let","new","null","package","private","protected","public","return","static","super","switch","this","throw","true","try","typeof","var","void","while","with","yield"]),S=/^import\s*\{\s*defineMigration\s*\}\s*from\s*["'](?:@lunora\/server|lunorash\/server)["'][^\n]*$/mu,ee=e=>`import { defineMigration } from "${U(e)?.has("lunorash")??!1?"lunorash/server":"@lunora/server"}";`,re="__lunora_admin__:runMigration",te="__lunora_admin__:migrationStatus",ne="/_lunora/migrate",ae=e=>A(e.trim().toLowerCase().replaceAll(k,"-"),"-"),oe=e=>e.split("-").filter(r=>r.length>0).map((r,n)=>n===0?r:r.charAt(0).toUpperCase()+r.slice(1)).join(""),ie=e=>{const r=c(e,"lunora","schema.ts");if(!m(r))return[];try{const n=new b({skipAddingFilesFromTsConfig:!0});return _(n,r).tables.map(t=>t.name)}catch{return[]}},se=async e=>e.length>0?O("Which table does this migration iterate?",e.map(r=>({label:r,value:r}))):F("Target table for the migration: "),ce=async(e,r)=>{if(r.table!==void 0)return r.table;const n=r.promptTable??(C()?se:void 0);if(n===void 0){r.logger.error("migrate create requires a target table when not running interactively — re-run with --table <table>");return}const a=(await n(ie(e)))?.trim();if(a===void 0||a===""){r.logger.error("no table selected — re-run with --table <table>");return}return a},de=async e=>{const r=e.cwd??process.cwd(),n=ae(e.name);if(n==="")return e.logger.error(`invalid migration name: "${e.name}" — must contain at least one alphanumeric character`),{code:1,file:""};const t=oe(n);if(!$.test(t)||Y.has(t))return e.logger.error(`invalid migration name: "${e.name}" derives the export \`${t}\`, which is not a valid identifier — pick a name that starts with a letter and isn't a reserved word`),{code:1,file:""};const a=await ce(r,e);if(a===void 0)return{code:1,file:""};if(!$.test(a))return e.logger.error(`invalid table: "${a}" — must be a valid identifier ([A-Za-z_][A-Za-z0-9_]*)`),{code:1,file:""};const s=c(r,"lunora"),o=c(s,Q);let i=m(o)?I(o,"utf8"):"";if(i.includes(`id: "${n}"`)||new RegExp(String.raw`\bexport const ${t}\b`,"u").test(i))return e.logger.error(`a migration with id "${n}" (export \`${t}\`) already exists in ${o}`),{code:1,file:""};const d=ee(r);i.trim()===""?i=`${d}
3
+ `:S.test(i)?i=i.replace(S,d):i=`${d}
4
+ ${i}`;const l=`export const ${t} = defineMigration({
5
+ id: "${n}",
6
+ table: "${a}",
190
7
  up: (document) => document,
191
- });`;
192
- mkdirSync(lunoraDirectory, { recursive: true });
193
- writeFileSync(file, `${content.trimEnd()}
194
-
195
- ${block}
196
- `, "utf8");
197
- options.logger.success(`scaffolded migration "${slug}" in ${file}`);
198
- if (options.table === void 0) {
199
- options.logger.warn(`set the \`table\` field on "${slug}" — it defaults to "${table}"`);
200
- }
201
- return { code: 0, file };
202
- };
203
- const resolveMigrationTable = (cwd, id) => {
204
- const project = new Project({ skipAddingFilesFromTsConfig: true });
205
- const migrations = discoverMigrations(project, join(cwd, "lunora"));
206
- return migrations.find((migration) => migration.id === id)?.table;
207
- };
208
- const resolveValidatedTable = (cwd, options) => {
209
- let table;
210
- try {
211
- table = resolveMigrationTable(cwd, options.id);
212
- } catch (error) {
213
- options.logger.error(error instanceof Error ? error.message : String(error));
214
- return void 0;
215
- }
216
- if (table === void 0) {
217
- options.logger.error(`migration "${options.id}" not found under lunora/ — declare it with defineMigration({ id: "${options.id}", ... })`);
218
- return void 0;
219
- }
220
- if (table === "") {
221
- options.logger.error(`migration "${options.id}" must declare \`table\` as a static string literal`);
222
- return void 0;
223
- }
224
- return table;
225
- };
226
- const resolveMigrateDataRequest = (options) => {
227
- const cwd = options.cwd ?? process.cwd();
228
- if (options.prod && options.url === void 0) {
229
- options.logger.error("--prod requires an explicit --url (refusing to migrate the implicit localhost worker)");
230
- return void 0;
231
- }
232
- if (options.prod && (options.subcommand === "up" || options.subcommand === "down") && !options.yes) {
233
- options.logger.error(`migrate ${options.subcommand} --prod runs the migration against production. Re-run with --yes to confirm.`);
234
- return void 0;
235
- }
236
- const token = options.token ?? process.env.LUNORA_ADMIN_TOKEN;
237
- if (!token) {
238
- options.logger.error("admin token required — pass --token or set LUNORA_ADMIN_TOKEN");
239
- return void 0;
240
- }
241
- const table = resolveValidatedTable(cwd, options);
242
- if (table === void 0) {
243
- return void 0;
244
- }
245
- const baseUrl = resolveAdminBaseUrl(options.url, options.logger);
246
- if (baseUrl === void 0) {
247
- return void 0;
248
- }
249
- const fetchImpl = options.fetchImpl ?? globalThis.fetch;
250
- if (typeof fetchImpl !== "function") {
251
- throw new TypeError("no fetch implementation available — pass fetchImpl or run on Node >= 18");
252
- }
253
- return { fetchImpl, requestUrl: `${baseUrl}${MIGRATE_ENDPOINT_PATH}`, table, token };
254
- };
255
- const buildMigrateArgs = (options) => {
256
- const args = { id: options.id };
257
- if (options.subcommand === "status") {
258
- return args;
259
- }
260
- args.direction = options.subcommand;
261
- if (options.dryRun) {
262
- args.dryRun = true;
263
- }
264
- if (options.batchSize !== void 0) {
265
- args.batchSize = options.batchSize;
266
- }
267
- if (options.maxBatches !== void 0) {
268
- args.maxBatches = options.maxBatches;
269
- }
270
- return args;
271
- };
272
- const runMigrateDataCommand = async (options) => {
273
- const request = resolveMigrateDataRequest(options);
274
- if (request === void 0) {
275
- return { body: void 0, code: 1, requestUrl: "" };
276
- }
277
- const { fetchImpl, requestUrl, table, token } = request;
278
- const functionPath = options.subcommand === "status" ? MIGRATION_STATUS_OP : RUN_MIGRATION_OP;
279
- const args = buildMigrateArgs(options);
280
- options.logger.info(`POST ${requestUrl} -> ${options.subcommand} ${options.id} (table "${table}")`);
281
- const response = await fetchImpl(requestUrl, {
282
- body: JSON.stringify({ args, functionPath, table }),
283
- headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
284
- method: "POST"
285
- });
286
- const text = await response.text();
287
- let body;
288
- try {
289
- body = JSON.parse(text);
290
- } catch {
291
- body = text;
292
- }
293
- options.logger.info(JSON.stringify(body, void 0, 2));
294
- return { body, code: response.ok ? 0 : 1, requestUrl };
295
- };
296
- const runMigrateToHyperdriveCommand = async (options) => {
297
- const { logger } = options;
298
- const fromUrl = options.fromUrl ?? options.toUrl;
299
- const toUrl = options.toUrl ?? options.fromUrl;
300
- if (fromUrl !== void 0 && fromUrl === toUrl) {
301
- logger.error(
302
- "source and target are the same deployment — pass distinct --from-url and --to-url so the D1 export and Hyperdrive import don't run against one database"
303
- );
304
- return { code: 1 };
305
- }
306
- const temporaryDirectory = options.out === void 0 ? mkdtempSync(join(tmpdir(), "lunora-d1ps-")) : void 0;
307
- const dumpPath = options.out ?? join(temporaryDirectory, "dump.ndjson");
308
- logger.info(`Exporting .global() data from the D1 source (${fromUrl ?? "http://localhost:8787"}) …`);
309
- const exportResult = await runExportCommand({
310
- fetchImpl: options.fetchImpl,
311
- logger,
312
- out: dumpPath,
313
- prod: options.prod,
314
- tables: options.tables,
315
- token: options.fromToken,
316
- url: fromUrl
317
- });
318
- if (exportResult.code !== 0) {
319
- return { code: exportResult.code };
320
- }
321
- logger.info(`Exported ${String(exportResult.rows)} row(s) (${String(exportResult.bytes)} bytes).`);
322
- logger.info(`Importing into the Hyperdrive target (${toUrl ?? "http://localhost:8787"}) …`);
323
- const importResult = await runImportCommand({
324
- batchSize: options.batchSize,
325
- fetchImpl: options.fetchImpl,
326
- file: dumpPath,
327
- logger,
328
- prod: options.prod,
329
- token: options.toToken,
330
- url: toUrl
331
- });
332
- if (temporaryDirectory !== void 0) {
333
- rmSync(temporaryDirectory, { force: true, recursive: true });
334
- }
335
- if (importResult.code !== 0) {
336
- return { code: importResult.code };
337
- }
338
- if (importResult.inserted === exportResult.rows) {
339
- logger.info(`✓ Migrated ${String(exportResult.rows)} row(s) — counts match. Verify your app reads from Hyperdrive, then decommission the D1 binding.`);
340
- } else {
341
- logger.warn(
342
- `Imported ${String(importResult.inserted)} of ${String(exportResult.rows)} exported row(s) — the remainder likely already existed in the target (see conflicts above). Re-run after resolving, or inspect the dump with --out.`
343
- );
344
- }
345
- return { code: 0 };
346
- };
347
- const execute = defineHandler(({ argument, cwd, logger, options }) => {
348
- const sub = argument[0];
349
- if (sub === "generate") {
350
- return runMigrateGenerateCommand({ cwd, logger, name: argument[1] ?? options.name });
351
- }
352
- if (sub === "d1-to-hyperdrive") {
353
- return runMigrateToHyperdriveCommand({
354
- batchSize: options.batchSize,
355
- fromToken: options.fromToken ?? options.token,
356
- fromUrl: options.fromUrl ?? options.url,
357
- logger,
358
- out: options.out,
359
- prod: options.prod === true,
360
- tables: options.tables,
361
- toToken: options.toToken ?? options.token,
362
- toUrl: options.toUrl ?? options.url
363
- });
364
- }
365
- if (sub === "create") {
366
- const name = argument[1] ?? options.name;
367
- if (!name) {
368
- logger.error("migrate create requires a name. Usage: lunora migrate create <name> [--table <table>]");
369
- return { code: 1 };
370
- }
371
- return runMigrateCreateCommand({ cwd, logger, name, table: options.table });
372
- }
373
- if (sub === "up" || sub === "down" || sub === "status") {
374
- const id = argument[1] ?? options.name;
375
- if (!id) {
376
- logger.error(`migrate ${sub} requires a migration id. Usage: lunora migrate ${sub} <id>`);
377
- return { code: 1 };
378
- }
379
- return runMigrateDataCommand({
380
- batchSize: options.batchSize,
381
- cwd,
382
- dryRun: options.dryRun === true,
383
- id,
384
- logger,
385
- maxBatches: options.steps,
386
- prod: options.prod === true,
387
- subcommand: sub,
388
- token: options.token,
389
- url: resolveProductionWorkerUrl({ cwd, prod: options.prod === true, url: options.url }),
390
- yes: options.yes === true
391
- });
392
- }
393
- logger.error(`unknown migrate subcommand: "${sub ?? ""}" — expected generate | create | up | down | status`);
394
- return { code: 1 };
395
- });
8
+ });`;return T(s,{recursive:!0}),h(o,`${i.trimEnd()}
396
9
 
397
- export { execute, runMigrateCreateCommand, runMigrateDataCommand, runMigrateGenerateCommand, runMigrateToHyperdriveCommand };
10
+ ${l}
11
+ `,"utf8"),e.logger.success(`scaffolded migration "${n}" in ${o}`),{code:0,file:o}},le=(e,r)=>{const n=new b({skipAddingFilesFromTsConfig:!0});return x(n,c(e,"lunora")).find(a=>a.id===r)?.table},ue=(e,r)=>{const n=W(r.id);if(n!==void 0)return n;if(r.id.startsWith(u)){r.logger.error(`"${r.id}" names no table — use ${u}<table>`);return}let t;try{t=le(e,r.id)}catch(a){r.logger.error(a instanceof Error?a.message:String(a));return}if(t===void 0){r.logger.error(`migration "${r.id}" not found under lunora/ — declare it with defineMigration({ id: "${r.id}", ... })`);return}if(t===""){r.logger.error(`migration "${r.id}" must declare \`table\` as a static string literal`);return}return t},me=e=>{const r=e.cwd??process.cwd();if(e.prod&&e.url===void 0){e.logger.error("--prod requires an explicit --url (refusing to migrate the implicit localhost worker)");return}if(e.prod&&(e.subcommand==="up"||e.subcommand==="down")&&!e.yes){e.logger.error(`migrate ${e.subcommand} --prod runs the migration against production. Re-run with --yes to confirm.`);return}const n=e.token??process.env.LUNORA_ADMIN_TOKEN;if(!n){e.logger.error("admin token required — pass --token or set LUNORA_ADMIN_TOKEN");return}const t=ue(r,e);if(t===void 0)return;const a=P(e.url,e.logger,e.cwd);if(a===void 0)return;const s=e.fetchImpl??globalThis.fetch;if(typeof s!="function")throw new TypeError("no fetch implementation available — pass fetchImpl or run on Node >= 18");return{fetchImpl:s,requestUrl:`${a}${ne}`,table:t,token:n}},fe=e=>{const r={id:e.id};return e.subcommand==="status"||(r.direction=e.subcommand,e.dryRun&&(r.dryRun=!0),e.batchSize!==void 0&&(r.batchSize=e.batchSize),e.maxBatches!==void 0&&(r.maxBatches=e.maxBatches)),r},ge=async e=>{const r=me(e);if(r===void 0)return{body:void 0,code:1,requestUrl:""};const{fetchImpl:n,requestUrl:t,table:a,token:s}=r,o=e.subcommand==="status"?te:re,i=fe(e);e.logger.info(`POST ${t} -> ${e.subcommand} ${e.id} (table "${a}")`);const d=await n(t,{body:JSON.stringify({args:i,functionPath:o,table:a}),headers:{authorization:`Bearer ${s}`,"content-type":"application/json"},method:"POST"});return{body:await H(d,e.logger),code:d.ok?0:1,requestUrl:t}},he=async e=>{const{logger:r}=e,n=e.fromUrl??e.toUrl,t=e.toUrl??e.fromUrl;if(n!==void 0&&n===t)return r.error("source and target are the same deployment — pass distinct --from-url and --to-url so the D1 export and Hyperdrive import don't run against one database"),{code:1};const a=e.out===void 0?N(c(R(),"lunora-d1ps-")):void 0,s=e.out??c(a,"dump.ndjson");try{r.info(`Exporting .global() data from the D1 source (${n??"http://localhost:8787"}) …`);const o=await G({fetchImpl:e.fetchImpl,logger:r,out:s,prod:e.prod,tables:e.tables,token:e.fromToken,url:n});if(o.code!==0)return{code:o.code};r.info(`Exported ${String(o.rows)} row(s) (${String(o.bytes)} bytes).`),r.info(`Importing into the Hyperdrive target (${t??"http://localhost:8787"}) …`);const i=await B({batchSize:e.batchSize,fetchImpl:e.fetchImpl,file:s,logger:r,prod:e.prod,token:e.toToken,url:t});return i.code!==0?{code:i.code}:(i.inserted===o.rows?r.info(`✓ Migrated ${String(o.rows)} row(s) — counts match. Verify your app reads from Hyperdrive, then decommission the D1 binding.`):r.warn(`Imported ${String(i.inserted)} of ${String(o.rows)} exported row(s) — the remainder likely already existed in the target (see conflicts above). Re-run after resolving, or inspect the dump with --out.`),{code:0})}finally{a!==void 0&&M(a,{force:!0,recursive:!0})}},xe=D(({argument:e,cwd:r,logger:n,options:t})=>{const a=e[0];if(a==="generate")return X({cwd:r,logger:n,name:e[1]??t.name});if(a==="d1-to-hyperdrive")return he({batchSize:t.batchSize,fromToken:t.fromToken??t.token,fromUrl:t.fromUrl??t.url,logger:n,out:t.out,prod:t.prod===!0,tables:t.tables,toToken:t.toToken??t.token,toUrl:t.toUrl??t.url});if(a==="create"){const s=e[1]??t.name;return s?de({cwd:r,logger:n,name:s,table:t.table}):(n.error("migrate create requires a name. Usage: lunora migrate create <name> [--table <table>]"),{code:1})}if(a==="up"||a==="down"||a==="status"){const s=e[1]??t.name;return s?ge({batchSize:t.batchSize,cwd:r,dryRun:t.dryRun===!0,id:s,logger:n,maxBatches:t.steps,prod:t.prod===!0,subcommand:a,token:t.token,url:j({cwd:r,prod:t.prod===!0,url:t.url}),yes:t.yes===!0}):(n.error(`migrate ${a} requires a migration id. Usage: lunora migrate ${a} <id>`),{code:1})}return n.error(`unknown migrate subcommand: "${a??""}" — expected generate | create | up | down | status`),{code:1}});export{xe as execute,de as runMigrateCreateCommand,ge as runMigrateDataCommand,X as runMigrateGenerateCommand,he as runMigrateToHyperdriveCommand};
@@ -1,41 +1 @@
1
- import { existsSync, rmSync } from 'node:fs';
2
- import { join } from '@visulima/path';
3
- import { d as defineHandler } from '../packem_shared/command-BC30oSBW.mjs';
4
- import { b as tuiConfirm } from '../packem_shared/tui-prompts-M6OWsuyw.mjs';
5
-
6
- const runResetCommand = async (options) => {
7
- const cwd = options.cwd ?? process.cwd();
8
- const targets = [join(cwd, ".wrangler", "state")];
9
- if (options.all) {
10
- targets.push(join(cwd, ".lunora-cache"));
11
- }
12
- if (!options.yes) {
13
- const isTty = process.stdin.isTTY;
14
- if (!isTty && options.confirm === void 0) {
15
- options.logger.error("reset: stdin is not a TTY — re-run with --yes to confirm deleting .wrangler/state");
16
- return { code: 1, removed: [] };
17
- }
18
- const confirmer = options.confirm ?? tuiConfirm;
19
- const confirmed = await confirmer("This will delete .wrangler/state. Continue?");
20
- if (!confirmed) {
21
- options.logger.info("reset: aborted");
22
- return { code: 1, removed: [] };
23
- }
24
- }
25
- const removed = [];
26
- for (const target of targets) {
27
- if (existsSync(target)) {
28
- rmSync(target, { force: true, recursive: true });
29
- removed.push(target);
30
- options.logger.success(`removed ${target}`);
31
- } else {
32
- options.logger.info(`skipped (not present): ${target}`);
33
- }
34
- }
35
- return { code: 0, removed };
36
- };
37
- const execute = defineHandler(
38
- ({ cwd, logger, options }) => runResetCommand({ all: options.all === true, cwd, logger, yes: options.yes === true })
39
- );
40
-
41
- export { execute, runResetCommand };
1
+ import{existsSync as n,rmSync as i}from"node:fs";import{join as c}from"@visulima/path";import{d}from"../packem_shared/command-DwC11Cwe.mjs";import{b as f}from"../packem_shared/tui-prompts-Dd0pDuNr.mjs";const m=async e=>{const o=e.cwd??process.cwd(),t=[c(o,".wrangler","state")];if(e.all&&t.push(c(o,".lunora-cache")),!e.yes){if(!process.stdin.isTTY&&e.confirm===void 0)return e.logger.error("reset: stdin is not a TTY — re-run with --yes to confirm deleting .wrangler/state"),{code:1,removed:[]};if(!await(e.confirm??f)("This will delete .wrangler/state. Continue?"))return e.logger.info("reset: aborted"),{code:1,removed:[]}}const s=[];for(const r of t)n(r)?(i(r,{force:!0,recursive:!0}),s.push(r),e.logger.success(`removed ${r}`)):e.logger.info(`skipped (not present): ${r}`);return{code:0,removed:s}},T=d(({cwd:e,logger:o,options:t})=>m({all:t.all===!0,cwd:e,logger:o,yes:t.yes===!0}));export{T as execute,m as runResetCommand};
@@ -1,68 +1 @@
1
- import { d as defineHandler } from '../packem_shared/command-BC30oSBW.mjs';
2
- import { r as resolveWorkerUrl } from '../packem_shared/resolve-target-qbsJ_5sF.mjs';
3
-
4
- const parseArgsJson = (raw) => {
5
- if (raw === void 0 || raw.length === 0) {
6
- return {};
7
- }
8
- try {
9
- return JSON.parse(raw);
10
- } catch (error) {
11
- const message = error instanceof Error ? error.message : String(error);
12
- throw new Error(`failed to parse --args as JSON: ${message}`, { cause: error });
13
- }
14
- };
15
- const TRAILING_SLASH = /\/$/u;
16
- const runRpcCommand = async (options) => {
17
- const resolvedUrl = resolveWorkerUrl({ cwd: options.cwd ?? process.cwd(), url: options.url });
18
- const baseUrl = (resolvedUrl ?? "http://localhost:8787").replace(TRAILING_SLASH, "");
19
- const requestUrl = `${baseUrl}/_lunora/rpc`;
20
- const fetchImpl = options.fetchImpl ?? globalThis.fetch;
21
- if (typeof fetchImpl !== "function") {
22
- throw new TypeError("no fetch implementation available — pass --fetch via dependency injection or run on Node >= 18");
23
- }
24
- let parsedArgs;
25
- try {
26
- parsedArgs = parseArgsJson(options.args);
27
- } catch (error) {
28
- const message = error instanceof Error ? error.message : String(error);
29
- options.logger.error(message);
30
- return { body: void 0, code: 1, requestUrl };
31
- }
32
- const payload = {
33
- args: parsedArgs,
34
- functionPath: options.functionPath
35
- };
36
- if (options.shard !== void 0) {
37
- payload.shardKey = options.shard;
38
- }
39
- options.logger.info(`POST ${requestUrl} -> ${options.functionPath}`);
40
- const response = await fetchImpl(requestUrl, {
41
- body: JSON.stringify(payload),
42
- headers: { "content-type": "application/json" },
43
- method: "POST"
44
- });
45
- const text = await response.text();
46
- let body;
47
- try {
48
- body = JSON.parse(text);
49
- } catch {
50
- body = text;
51
- }
52
- options.logger.info(JSON.stringify(body, void 0, 2));
53
- return {
54
- body,
55
- code: response.ok ? 0 : 1,
56
- requestUrl
57
- };
58
- };
59
- const execute = defineHandler(({ argument, cwd, logger, options }) => {
60
- const functionPath = argument[0];
61
- if (!functionPath) {
62
- logger.error("missing function path. Usage: lunora run <functionPath> [--args <json>]");
63
- return { code: 1 };
64
- }
65
- return runRpcCommand({ args: options.args, cwd, functionPath, logger, shard: options.shard, url: options.url });
66
- });
67
-
68
- export { execute, runRpcCommand };
1
+ import{LunoraError as v}from"@lunora/errors";import{r as A,d as _}from"../packem_shared/admin-token-rxXZbVMZ.mjs";import{r as N,a as S}from"../packem_shared/admin-url-Cil3Or6N.mjs";import{d as b}from"../packem_shared/command-DwC11Cwe.mjs";import{a as P}from"../packem_shared/resolve-target-BRvw8Pf7.mjs";const h=(r,t="--args")=>{if(r===void 0||r.length===0)return{};try{return JSON.parse(r)}catch(e){const a=e instanceof Error?e.message:String(e);throw new v("INTERNAL",`failed to parse ${t} as JSON: ${a}`,{cause:e})}},I=/\/$/u,O="__lunora_admin__:runAs",k="__lunora_admin__:",T=async(r,t)=>{const e=await r.text();let a;try{a=JSON.parse(e)}catch{a=e}return t.info(JSON.stringify(a,void 0,2)),a},$=(r,t)=>{const e=t.body?.error?.code;t.runAs||t.status!==403||e!=="FORBIDDEN_SHARD"||r.info("this app authorizes per shard, so an anonymous call is denied — retry with --as <userId> to run as an authenticated user")},E=({args:r,claims:t,options:e,runAs:a})=>{const n=a?{args:{args:r,functionPath:e.functionPath,identity:t,userId:e.as},functionPath:O}:{args:r,functionPath:e.functionPath};return e.shard!==void 0&&(n.shardKey=e.shard),n},R=({cwd:r,logger:t,needsBearer:e,url:a})=>e?N(a,t,r):(P({cwd:r,url:a})??S(r)).replace(I,""),U=async r=>{const t=r.cwd??process.cwd(),e=r.as!==void 0&&r.as!=="",a=e||r.functionPath.startsWith(k),n=R({cwd:t,logger:r.logger,needsBearer:a,url:r.url});if(n===void 0)return{body:void 0,code:1,requestUrl:r.url??""};const s=`${n}/_lunora/rpc`,i=r.fetchImpl??globalThis.fetch;if(typeof i!="function")throw new TypeError("no fetch implementation available — pass --fetch via dependency injection or run on Node >= 18");let u,l;try{u=h(r.args),l=r.claims===void 0?void 0:h(r.claims,"--claims")}catch(d){return r.logger.error(d instanceof Error?d.message:String(d)),{body:void 0,code:1,requestUrl:s}}const{source:g,token:o}=a?A({cwd:t,token:r.token,url:n}):{};if(a&&o===void 0)return r.logger.error("admin token required — pass --token, set LUNORA_ADMIN_TOKEN, or add it to .dev.vars (local targets only)"),{body:void 0,code:1,requestUrl:s};o!==void 0&&r.logger.debug?.(`admin bearer from ${_(g)}`);const m={"content-type":"application/json",...o===void 0?{}:{authorization:`Bearer ${o}`}},y=E({args:u,claims:l,options:r,runAs:e});r.logger.info(`POST ${s} -> ${r.functionPath}${e?` (as ${r.as??""})`:""}`);const c=await i(s,{body:JSON.stringify(y),headers:m,method:"POST"}),f=await T(c,r.logger);return $(r.logger,{body:f,runAs:e,status:c.status}),{body:f,code:c.ok?0:1,requestUrl:s}},L=b(({argument:r,cwd:t,logger:e,options:a})=>{const n=r[0];return n?U({args:a.args,as:a.as,claims:a.claims,cwd:t,functionPath:n,logger:e,shard:a.shard,token:a.token,url:a.url}):(e.error("missing function path. Usage: lunora run <functionPath> [--args <json>]"),{code:1})});export{L as execute,T as readAndLogBody,U as runRpcCommand};
@@ -0,0 +1 @@
1
+ import{C as a,R as s,V as C,r as N}from"./cli-CrC0a7dH.mjs";import"./createLogger-hGafwf-3.mjs";export{a as COMMANDS,s as REGISTERED_COMMAND_NAMES,C as VERSION,N as runCli};
@@ -0,0 +1 @@
1
+ import"./admin-token-rxXZbVMZ.mjs";import"./admin-url-Cil3Or6N.mjs";import{D as a,r as i}from"./import-CrVGrOt3.mjs";import"./shared-D-zCOmgY.mjs";export{a as DEFAULT_IMPORT_BATCH_SIZE,i as runImportCommand};
@@ -0,0 +1 @@
1
+ import{readFileSync as a}from"node:fs";import{join as c}from"node:path";import{DEV_VARS_FILE as s,parseDevVariableEntries as v}from"@lunora/config";const o="LUNORA_ADMIN_TOKEN",u=new Set(["127.0.0.1","::1","[::1]","localhost"]),f=e=>{if(e===void 0||e==="")return!0;try{return u.has(new URL(e).hostname)}catch{return!1}},d=e=>{let r;try{r=a(c(e,s),"utf8")}catch{return}const t=v(r).find(n=>n.key===o);return t?.value===""?void 0:t?.value},A=({cwd:e,token:r,url:t})=>{if(r!==void 0&&r!=="")return{source:"flag",token:r};const n=process.env[o];if(n!==void 0&&n!=="")return{source:"env",token:n};if(!f(t))return{};const i=d(e);return i===void 0?{}:{source:"dev-vars",token:i}},E=e=>e==="flag"?"--token":e==="env"?o:s;export{E as d,f as i,A as r};
@@ -0,0 +1 @@
1
+ import{readLiveDevServerState as a}from"@lunora/config";const l=new Set(["127.0.0.1","::1","[::1]","localhost"]),c=/\/$/u,n="http://localhost:8787",i=t=>t===void 0?n:a(t)?.url??n,h=(t,o,s)=>{const e=t??i(s);let r;try{r=new URL(e)}catch{o.error(`invalid --url: ${e}`);return}if(!l.has(r.hostname)&&r.protocol!=="https:"){o.error(`refusing to send the admin bearer over ${r.protocol}// to ${r.hostname} — use https for non-localhost targets`);return}return e.replace(c,"")};export{i as a,h as r};
@@ -0,0 +1 @@
1
+ import{errorAdvisoryNames as t}from"@lunora/codegen";const v=e=>e.strictAdvisories??(process.env.CI!==void 0&&process.env.CI!==""),c=(e,s)=>{const r=e.filter(o=>o.level==="ERROR");return{errorAdvisories:r,names:t(e),shouldBlock:r.length>0&&s}};export{c as e,v as r};
@@ -0,0 +1 @@
1
+ import{LunoraError as r}from"@lunora/errors";const n=["both","none","openapi","openrpc"],p=n.join(" | "),t=o=>{if(!(typeof o!="string"||o.length===0)){if(n.includes(o))return o;throw new r("INTERNAL",`invalid --api-spec "${o}" — expected one of: ${p}`)}};export{p as A,t as p};
@@ -0,0 +1,2 @@
1
+ import{mkdirSync as a,writeFileSync as g}from"node:fs";import{findWranglerFile as f,readWranglerJsonc as l,buildBindingManifest as m}from"@lunora/config/cloudflare";import{isAbsolute as c,resolve as h,dirname as u}from"@visulima/path";const v=r=>{const n=f(r),e=n===void 0?void 0:l(n).parsed;return e===void 0?{error:`no readable wrangler config in ${r}. The binding manifest is derived from it, and an empty one would tell a deployer this Worker needs nothing.`}:{manifest:m(e)}},y=r=>{const{destination:n,dev:e,logger:s,projectRoot:d}=r,t=v(d);if(t.manifest===void 0)return{error:t.error};const i={...t.manifest,...e===void 0?{}:{dev:e}},o=c(n)?n:h(d,n);return a(u(o),{recursive:!0}),g(o,`${JSON.stringify(i,void 0,2)}
2
+ `,"utf8"),s.success(`binding manifest written to ${o} (${i.bindings.length.toString()} bindings, ${i.crons.length.toString()} crons)`),i.unknown.length>0&&s.warn(`binding manifest does not model these wrangler sections: ${i.unknown.join(", ")}. Anything they bind must be provisioned by hand — please report them so the manifest can cover them.`),{}};export{v as d,y as w};
@@ -0,0 +1 @@
1
+ import{existsSync as c,readFileSync as o,readdirSync as p,statSync as m}from"node:fs";import{join as s}from"@visulima/path";import d from"./parseManifest-CwPTKdtS.mjs";const l=/[\u0000-\u001F\u007F-\u009F]/gu,n=i=>i===void 0?void 0:i.replaceAll(l,""),a=i=>p(i).filter(r=>{const e=s(i,r);return m(e).isDirectory()&&c(s(e,"registry.json"))}),S=i=>{const r=s(i,"index.json");if(c(r)){const e=JSON.parse(o(r,"utf8"));if(Array.isArray(e.items))return e.items.filter(t=>typeof t=="object"&&t!==null&&typeof t.name=="string").map(t=>({description:n(t.description),name:n(t.name)??t.name}))}return a(i).map(e=>{const t=JSON.parse(o(s(i,e,"registry.json"),"utf8"));return{description:n(t.description),name:e}})},g=i=>({items:a(i).map(e=>{const t=d(JSON.parse(o(s(i,e,"registry.json"),"utf8")),e);return{...t.description===void 0?{}:{description:t.description},name:t.name,...t.title===void 0?{}:{title:t.title}}}).toSorted((e,t)=>e.name.localeCompare(t.name))});export{g as buildRegistryIndex,S as collectCatalog,a as listItemDirectories};