vela 0.10.13 → 0.10.14

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.
package/dist/bin.js CHANGED
@@ -12,8 +12,8 @@ function normalizeArgv(argv) {
12
12
 
13
13
  // src/program.ts
14
14
  import process35 from "node:process";
15
- import * as p54 from "@clack/prompts";
16
- import { Command as Command100 } from "commander";
15
+ import * as p59 from "@clack/prompts";
16
+ import { Command as Command103 } from "commander";
17
17
  import nodePath from "node:path";
18
18
  import dotenv2 from "dotenv";
19
19
  import pc36 from "picocolors";
@@ -21,7 +21,7 @@ import pc36 from "picocolors";
21
21
  // package.json
22
22
  var package_default = {
23
23
  name: "vela",
24
- version: "0.10.13",
24
+ version: "0.10.14",
25
25
  type: "module",
26
26
  description: "A CLI for creating and updating SvelteKit projects",
27
27
  license: "MIT",
@@ -55,7 +55,7 @@ var package_default = {
55
55
  dependencies: {
56
56
  "@clack/prompts": "^1.7.0",
57
57
  "@faker-js/faker": "^10.6.0",
58
- "@velastack/patterns": "^0.1.9",
58
+ "@velastack/patterns": "^0.2.2",
59
59
  "@velastack/pocketbase-codegen": "^0.1.0",
60
60
  "annotate-json-schema": "^0.1.0",
61
61
  commander: "^13.1.0",
@@ -379,8 +379,8 @@ function detectFeatures(root, { isAppMode, isPaymentsMode }) {
379
379
  }
380
380
 
381
381
  // src/commands/bless.ts
382
- import fs11 from "node:fs";
383
- import path10 from "node:path";
382
+ import fs13 from "node:fs";
383
+ import path11 from "node:path";
384
384
  import process5 from "node:process";
385
385
  import * as v2 from "valibot";
386
386
  import { Command as Command2 } from "commander";
@@ -866,13 +866,75 @@ function quoteEnvValue(value) {
866
866
  return `"${escaped}"`;
867
867
  }
868
868
 
869
- // src/lib/config-merge.ts
869
+ // src/lib/app-css.ts
870
+ import fs7 from "node:fs";
871
+ var SHADCN_TAILWIND_CSS = "shadcn-svelte/tailwind.css";
872
+ var SHADCN_TAILWIND_IMPORT = `@import '${SHADCN_TAILWIND_CSS}';`;
873
+ function hasShadcnImport(css) {
874
+ return css.includes(SHADCN_TAILWIND_CSS);
875
+ }
876
+ function insertShadcnImport(css) {
877
+ const lines = css.split("\n");
878
+ let lastImport = -1;
879
+ for (const [index, line] of lines.entries()) {
880
+ const trimmed = line.trim();
881
+ if (trimmed.startsWith("@import")) {
882
+ lastImport = index;
883
+ continue;
884
+ }
885
+ if (trimmed === "" || trimmed.startsWith("/*") || trimmed.startsWith("//")) continue;
886
+ break;
887
+ }
888
+ if (lastImport === -1) {
889
+ return `${SHADCN_TAILWIND_IMPORT}
890
+ ${css}`;
891
+ }
892
+ lines.splice(lastImport + 1, 0, SHADCN_TAILWIND_IMPORT);
893
+ return lines.join("\n");
894
+ }
895
+ function ensureShadcnImport(appCssPath) {
896
+ if (!fs7.existsSync(appCssPath)) return false;
897
+ const css = fs7.readFileSync(appCssPath, "utf8");
898
+ if (hasShadcnImport(css)) return false;
899
+ fs7.writeFileSync(appCssPath, insertShadcnImport(css));
900
+ return true;
901
+ }
902
+
903
+ // src/lib/components-json.ts
870
904
  import fs8 from "node:fs";
871
- import path7 from "node:path";
905
+ import path6 from "node:path";
906
+ function readComponentsJson(root) {
907
+ const file = path6.join(root, "components.json");
908
+ if (!fs8.existsSync(file)) return void 0;
909
+ try {
910
+ const parsed = JSON.parse(fs8.readFileSync(file, "utf8"));
911
+ return parsed && typeof parsed === "object" ? parsed : void 0;
912
+ } catch {
913
+ return void 0;
914
+ }
915
+ }
916
+ function componentsJsonHints(config) {
917
+ const hints = [];
918
+ if (!config.style) {
919
+ hints.push(
920
+ 'components.json has no "style": shadcn-svelte defaults to "nova", while vela ships "vega". Add "style": "vega" so new components match.'
921
+ );
922
+ }
923
+ if (!config.iconLibrary) {
924
+ hints.push(
925
+ `components.json has no "iconLibrary": add "iconLibrary": "lucide", the library vela's components use.`
926
+ );
927
+ }
928
+ return hints;
929
+ }
930
+
931
+ // src/lib/config-merge.ts
932
+ import fs10 from "node:fs";
933
+ import path8 from "node:path";
872
934
 
873
935
  // src/lib/config-target.ts
874
- import fs7 from "node:fs";
875
- import path6 from "node:path";
936
+ import fs9 from "node:fs";
937
+ import path7 from "node:path";
876
938
  import {
877
939
  Project,
878
940
  QuoteKind,
@@ -892,8 +954,8 @@ var SVELTE_CONFIG_CANDIDATES = [
892
954
  ];
893
955
  function probeFirstExisting(root, candidates) {
894
956
  for (const rel of candidates) {
895
- const abs = path6.join(root, rel);
896
- if (fs7.existsSync(abs)) return abs;
957
+ const abs = path7.join(root, rel);
958
+ if (fs9.existsSync(abs)) return abs;
897
959
  }
898
960
  return null;
899
961
  }
@@ -969,7 +1031,7 @@ function mergeSvelteConfig(projectRoot) {
969
1031
  };
970
1032
  }
971
1033
  function mergeRunesIntoViteArg(vite, arg) {
972
- const file = path7.basename(vite.filePath);
1034
+ const file = path8.basename(vite.filePath);
973
1035
  const compilerOptions = getOrCreateObjectLiteralProperty(arg, "compilerOptions", "{}");
974
1036
  if (!compilerOptions) {
975
1037
  return {
@@ -988,8 +1050,8 @@ function mergeRunesIntoViteArg(vite, arg) {
988
1050
  return { applied: true, reason: "added runes compilerOption", file };
989
1051
  }
990
1052
  function mergeRunesIntoSvelteConfig(filePath) {
991
- const file = path7.basename(filePath);
992
- const original = fs8.readFileSync(filePath, "utf8");
1053
+ const file = path8.basename(filePath);
1054
+ const original = fs10.readFileSync(filePath, "utf8");
993
1055
  if (/runes\s*:/m.test(original)) {
994
1056
  return { applied: false, reason: "runes already configured", file };
995
1057
  }
@@ -1012,11 +1074,11 @@ function mergeRunesIntoSvelteConfig(filePath) {
1012
1074
  }
1013
1075
  const insertAt = anchor.index + anchor[0].length;
1014
1076
  const updated = original.slice(0, insertAt) + RUNES_SNIPPET + original.slice(insertAt);
1015
- fs8.writeFileSync(filePath, updated);
1077
+ fs10.writeFileSync(filePath, updated);
1016
1078
  return { applied: true, reason: "added runes compilerOption", file };
1017
1079
  }
1018
1080
  function mergeViteConfig(filePath) {
1019
- if (!fs8.existsSync(filePath)) {
1081
+ if (!fs10.existsSync(filePath)) {
1020
1082
  return {
1021
1083
  applied: false,
1022
1084
  reason: "vite.config.ts not found",
@@ -1024,7 +1086,7 @@ function mergeViteConfig(filePath) {
1024
1086
  // then add tailwindcss() to the plugins array`
1025
1087
  };
1026
1088
  }
1027
- const original = fs8.readFileSync(filePath, "utf8");
1089
+ const original = fs10.readFileSync(filePath, "utf8");
1028
1090
  if (original.includes("@tailwindcss/vite")) {
1029
1091
  return { applied: false, reason: "tailwindcss plugin already present" };
1030
1092
  }
@@ -1043,14 +1105,14 @@ function mergeViteConfig(filePath) {
1043
1105
  const trailing = withImport.slice(insertAt);
1044
1106
  const prefix = /^\s*\]/.test(trailing) ? "tailwindcss()" : "tailwindcss(), ";
1045
1107
  const updated = withImport.slice(0, insertAt) + prefix + withImport.slice(insertAt);
1046
- fs8.writeFileSync(filePath, updated);
1108
+ fs10.writeFileSync(filePath, updated);
1047
1109
  return { applied: true, reason: "added @tailwindcss/vite plugin" };
1048
1110
  }
1049
1111
  function mergeTsconfig(filePath) {
1050
- if (!fs8.existsSync(filePath)) {
1112
+ if (!fs10.existsSync(filePath)) {
1051
1113
  return { applied: false, reason: "tsconfig.json not found" };
1052
1114
  }
1053
- const original = fs8.readFileSync(filePath, "utf8");
1115
+ const original = fs10.readFileSync(filePath, "utf8");
1054
1116
  if (/rewriteRelativeImportExtensions/.test(original)) {
1055
1117
  return { applied: false, reason: "rewriteRelativeImportExtensions already set" };
1056
1118
  }
@@ -1066,7 +1128,7 @@ function mergeTsconfig(filePath) {
1066
1128
  const indent = detectIndent(original, insertAt);
1067
1129
  const updated = original.slice(0, insertAt) + `
1068
1130
  ${indent}"rewriteRelativeImportExtensions": true,` + original.slice(insertAt);
1069
- fs8.writeFileSync(filePath, updated);
1131
+ fs10.writeFileSync(filePath, updated);
1070
1132
  return { applied: true, reason: "added rewriteRelativeImportExtensions" };
1071
1133
  }
1072
1134
  var GITIGNORE_ENTRIES = [
@@ -1078,7 +1140,7 @@ var GITIGNORE_ENTRIES = [
1078
1140
  "vite.config.ts.timestamp-*"
1079
1141
  ];
1080
1142
  function mergeGitignore(filePath) {
1081
- const existing = fs8.existsSync(filePath) ? fs8.readFileSync(filePath, "utf8") : "";
1143
+ const existing = fs10.existsSync(filePath) ? fs10.readFileSync(filePath, "utf8") : "";
1082
1144
  const lines = existing.split("\n").map((l) => l.trim());
1083
1145
  const missing = GITIGNORE_ENTRIES.filter((entry) => !lines.includes(entry));
1084
1146
  if (missing.length === 0) {
@@ -1087,7 +1149,7 @@ function mergeGitignore(filePath) {
1087
1149
  const needsNewline = existing.length > 0 && !existing.endsWith("\n");
1088
1150
  const appended = `${existing}${needsNewline ? "\n" : ""}${missing.join("\n")}
1089
1151
  `;
1090
- fs8.writeFileSync(filePath, appended);
1152
+ fs10.writeFileSync(filePath, appended);
1091
1153
  return { applied: true, reason: `added ${missing.length} gitignore entries` };
1092
1154
  }
1093
1155
  function addImport(source, importLine) {
@@ -1112,14 +1174,14 @@ function detectIndent(source, atOffset) {
1112
1174
  }
1113
1175
 
1114
1176
  // src/lib/scaffold-detect.ts
1115
- import fs9 from "node:fs";
1116
- import path8 from "node:path";
1177
+ import fs11 from "node:fs";
1178
+ import path9 from "node:path";
1117
1179
  var VANILLA_MARKER = "Welcome to SvelteKit";
1118
- var PAGE_REL = path8.join("src", "routes", "+page.svelte");
1180
+ var PAGE_REL = path9.join("src", "routes", "+page.svelte");
1119
1181
  function isVanillaRoutes(cwd) {
1120
- const pagePath = path8.join(cwd, PAGE_REL);
1121
- if (!fs9.existsSync(pagePath)) return false;
1122
- return fs9.readFileSync(pagePath, "utf8").includes(VANILLA_MARKER);
1182
+ const pagePath = path9.join(cwd, PAGE_REL);
1183
+ if (!fs11.existsSync(pagePath)) return false;
1184
+ return fs11.readFileSync(pagePath, "utf8").includes(VANILLA_MARKER);
1123
1185
  }
1124
1186
 
1125
1187
  // src/lib/result-report.ts
@@ -1167,41 +1229,41 @@ ${failure.message}` : headline);
1167
1229
  }
1168
1230
 
1169
1231
  // src/lib/template-files.ts
1170
- import fs10 from "node:fs";
1171
- import path9 from "node:path";
1232
+ import fs12 from "node:fs";
1233
+ import path10 from "node:path";
1172
1234
  var PUBLISH_SAFE_NAMES = {
1173
1235
  ".gitignore": "_gitignore",
1174
1236
  ".npmrc": "_npmrc"
1175
1237
  };
1176
1238
  function templateName(projectRelPath) {
1177
- const safe = PUBLISH_SAFE_NAMES[path9.basename(projectRelPath)];
1239
+ const safe = PUBLISH_SAFE_NAMES[path10.basename(projectRelPath)];
1178
1240
  if (!safe) return projectRelPath;
1179
- const dir = path9.dirname(projectRelPath);
1180
- return dir === "." ? safe : path9.join(dir, safe);
1241
+ const dir = path10.dirname(projectRelPath);
1242
+ return dir === "." ? safe : path10.join(dir, safe);
1181
1243
  }
1182
1244
  function restoreTemplateNames(target) {
1183
1245
  for (const [real, safe] of Object.entries(PUBLISH_SAFE_NAMES)) {
1184
- const from = path9.join(target, safe);
1185
- if (!fs10.existsSync(from)) continue;
1186
- fs10.renameSync(from, path9.join(target, real));
1246
+ const from = path10.join(target, safe);
1247
+ if (!fs12.existsSync(from)) continue;
1248
+ fs12.renameSync(from, path10.join(target, real));
1187
1249
  }
1188
1250
  }
1189
1251
  var TEMPLATE_SOURCE = /\.template\.([^.]+)$/;
1190
1252
  function applyTemplateFiles(target, values) {
1191
1253
  const written = [];
1192
1254
  for (const source of findTemplateSources(target)) {
1193
- const raw = fs10.readFileSync(source, "utf8");
1255
+ const raw = fs12.readFileSync(source, "utf8");
1194
1256
  const dest = source.replace(TEMPLATE_SOURCE, ".$1");
1195
- fs10.writeFileSync(dest, fillTemplatePlaceholders(raw, values));
1196
- fs10.unlinkSync(source);
1197
- written.push(path9.relative(target, dest));
1257
+ fs12.writeFileSync(dest, fillTemplatePlaceholders(raw, values));
1258
+ fs12.unlinkSync(source);
1259
+ written.push(path10.relative(target, dest));
1198
1260
  }
1199
1261
  return written.sort();
1200
1262
  }
1201
1263
  function findTemplateSources(dir) {
1202
1264
  const found = [];
1203
- for (const entry of fs10.readdirSync(dir, { withFileTypes: true })) {
1204
- const full = path9.join(dir, entry.name);
1265
+ for (const entry of fs12.readdirSync(dir, { withFileTypes: true })) {
1266
+ const full = path10.join(dir, entry.name);
1205
1267
  if (entry.isDirectory()) {
1206
1268
  if (entry.name === "node_modules" || entry.name === ".git") continue;
1207
1269
  found.push(...findTemplateSources(full));
@@ -1229,10 +1291,16 @@ var VELA_ONLY_FILES = [
1229
1291
  path: "src/hooks.server.ts",
1230
1292
  adds: "the handlePocketbase hook \u2014 the backend is not wired up without it"
1231
1293
  },
1232
- { path: "src/app.css", adds: "vela's Tailwind imports and theme tokens" },
1294
+ {
1295
+ path: "src/app.css",
1296
+ adds: "vela's Tailwind imports, theme tokens and the shadcn-svelte/tailwind.css import"
1297
+ },
1233
1298
  { path: "src/lib/index.ts", adds: "a $lib placeholder comment" },
1234
1299
  { path: "src/lib/utils.ts", adds: "the cn helper and the component type utilities" },
1235
- { path: "components.json", adds: "the shadcn-svelte config that `vela ui add` reads" },
1300
+ {
1301
+ path: "components.json",
1302
+ adds: "the shadcn-svelte config (vega style, lucide icons) that `vela ui add` reads"
1303
+ },
1236
1304
  { path: ".npmrc", adds: "engine-strict=true" },
1237
1305
  { path: ".ignore", adds: "search ignores for generated files" }
1238
1306
  ];
@@ -1277,6 +1345,8 @@ async function blessProject(cwdArg, options) {
1277
1345
  );
1278
1346
  mergeDependencies(projectPath, templateDir);
1279
1347
  copyVelaOnlyFiles(templateDir, projectPath);
1348
+ ensureShadcnCss(projectPath);
1349
+ hintComponentsJson(projectPath);
1280
1350
  mergeConfigFiles(projectPath);
1281
1351
  mergeAppDts(templateDir, projectPath);
1282
1352
  maybeReplaceRoutes(projectPath, templateDir, options);
@@ -1303,23 +1373,35 @@ async function blessProject(cwdArg, options) {
1303
1373
  p4.log.success("PocketBase initialized");
1304
1374
  printNextSteps(projectPath, packageManager);
1305
1375
  }
1376
+ function ensureShadcnCss(projectPath) {
1377
+ if (ensureShadcnImport(path11.join(projectPath, "src", "app.css"))) {
1378
+ p4.log.info(
1379
+ "src/app.css: added the shadcn-svelte/tailwind.css import its registry components rely on."
1380
+ );
1381
+ }
1382
+ }
1383
+ function hintComponentsJson(projectPath) {
1384
+ const config = readComponentsJson(projectPath);
1385
+ if (!config) return;
1386
+ for (const hint of componentsJsonHints(config)) p4.log.warn(hint);
1387
+ }
1306
1388
  function resolveProjectPath(cwdArg) {
1307
- const projectPath = path10.resolve(cwdArg);
1308
- if (!fs11.existsSync(projectPath)) {
1389
+ const projectPath = path11.resolve(cwdArg);
1390
+ if (!fs13.existsSync(projectPath)) {
1309
1391
  throw new Error(`Path does not exist: ${projectPath}`);
1310
1392
  }
1311
- if (!fs11.existsSync(path10.join(projectPath, "package.json"))) {
1393
+ if (!fs13.existsSync(path11.join(projectPath, "package.json"))) {
1312
1394
  throw new Error(`No package.json found at ${projectPath}`);
1313
1395
  }
1314
- if (!fs11.existsSync(path10.join(projectPath, "src", "routes"))) {
1396
+ if (!fs13.existsSync(path11.join(projectPath, "src", "routes"))) {
1315
1397
  throw new Error(`No src/routes directory found at ${projectPath}`);
1316
1398
  }
1317
1399
  return projectPath;
1318
1400
  }
1319
1401
  function assertNotAlreadyBlessed(projectPath) {
1320
- const hooksPath = path10.join(projectPath, "src", "hooks.server.ts");
1321
- if (!fs11.existsSync(hooksPath)) return;
1322
- const content = fs11.readFileSync(hooksPath, "utf8");
1402
+ const hooksPath = path11.join(projectPath, "src", "hooks.server.ts");
1403
+ if (!fs13.existsSync(hooksPath)) return;
1404
+ const content = fs13.readFileSync(hooksPath, "utf8");
1323
1405
  if (content.includes("@velastack/pocketbase")) {
1324
1406
  throw new Error(
1325
1407
  "This project already looks blessed (src/hooks.server.ts imports @velastack/pocketbase). Run `vela sync` instead."
@@ -1327,8 +1409,8 @@ function assertNotAlreadyBlessed(projectPath) {
1327
1409
  }
1328
1410
  }
1329
1411
  function mergeDependencies(projectPath, templateDir) {
1330
- const userPkgPath = path10.join(projectPath, "package.json");
1331
- const templatePkgPath = path10.join(templateDir, "package.template.json");
1412
+ const userPkgPath = path11.join(projectPath, "package.json");
1413
+ const templatePkgPath = path11.join(templateDir, "package.template.json");
1332
1414
  const userPkg = readPackageJson(userPkgPath);
1333
1415
  const appName = typeof userPkg.name === "string" ? userPkg.name : "sveltekit";
1334
1416
  const templatePkg = readTemplatePackageJson(templatePkgPath, {
@@ -1360,21 +1442,21 @@ ${lines.join("\n")}`);
1360
1442
  function copyVelaOnlyFiles(templateDir, projectPath) {
1361
1443
  const kept = [];
1362
1444
  for (const file of VELA_ONLY_FILES) {
1363
- const src = path10.join(templateDir, templateName(file.path));
1364
- const dest = path10.join(projectPath, file.path);
1365
- if (!fs11.existsSync(src)) continue;
1366
- if (fs11.existsSync(dest)) {
1445
+ const src = path11.join(templateDir, templateName(file.path));
1446
+ const dest = path11.join(projectPath, file.path);
1447
+ if (!fs13.existsSync(src)) continue;
1448
+ if (fs13.existsSync(dest)) {
1367
1449
  kept.push(file);
1368
1450
  continue;
1369
1451
  }
1370
- fs11.mkdirSync(path10.dirname(dest), { recursive: true });
1371
- fs11.copyFileSync(src, dest);
1452
+ fs13.mkdirSync(path11.dirname(dest), { recursive: true });
1453
+ fs13.copyFileSync(src, dest);
1372
1454
  }
1373
1455
  reportKeptFiles(kept);
1374
1456
  for (const rel of VELA_ONLY_DIRS) {
1375
- const src = path10.join(templateDir, rel);
1376
- const dest = path10.join(projectPath, rel);
1377
- if (!fs11.existsSync(src)) continue;
1457
+ const src = path11.join(templateDir, rel);
1458
+ const dest = path11.join(projectPath, rel);
1459
+ if (!fs13.existsSync(src)) continue;
1378
1460
  copyDirShallow(src, dest);
1379
1461
  }
1380
1462
  }
@@ -1388,15 +1470,15 @@ ${lines.join("\n")}`
1388
1470
  );
1389
1471
  }
1390
1472
  function copyDirShallow(src, dest) {
1391
- fs11.mkdirSync(dest, { recursive: true });
1392
- for (const entry of fs11.readdirSync(src, { withFileTypes: true })) {
1473
+ fs13.mkdirSync(dest, { recursive: true });
1474
+ for (const entry of fs13.readdirSync(src, { withFileTypes: true })) {
1393
1475
  if (entry.name === ".DS_Store") continue;
1394
- const srcChild = path10.join(src, entry.name);
1395
- const destChild = path10.join(dest, entry.name);
1476
+ const srcChild = path11.join(src, entry.name);
1477
+ const destChild = path11.join(dest, entry.name);
1396
1478
  if (entry.isDirectory()) {
1397
1479
  copyDirShallow(srcChild, destChild);
1398
- } else if (entry.isFile() && !fs11.existsSync(destChild)) {
1399
- fs11.copyFileSync(srcChild, destChild);
1480
+ } else if (entry.isFile() && !fs13.existsSync(destChild)) {
1481
+ fs13.copyFileSync(srcChild, destChild);
1400
1482
  }
1401
1483
  }
1402
1484
  }
@@ -1404,9 +1486,9 @@ function mergeConfigFiles(projectPath) {
1404
1486
  const runes = mergeSvelteConfig(projectPath);
1405
1487
  const outcomes = [
1406
1488
  [runes.file ?? "svelte.config", runes],
1407
- ["vite.config.ts", mergeViteConfig(path10.join(projectPath, "vite.config.ts"))],
1408
- ["tsconfig.json", mergeTsconfig(path10.join(projectPath, "tsconfig.json"))],
1409
- [".gitignore", mergeGitignore(path10.join(projectPath, ".gitignore"))]
1489
+ ["vite.config.ts", mergeViteConfig(path11.join(projectPath, "vite.config.ts"))],
1490
+ ["tsconfig.json", mergeTsconfig(path11.join(projectPath, "tsconfig.json"))],
1491
+ [".gitignore", mergeGitignore(path11.join(projectPath, ".gitignore"))]
1410
1492
  ];
1411
1493
  for (const [name, outcome] of outcomes) {
1412
1494
  if (outcome.applied) {
@@ -1423,14 +1505,14 @@ ${pc3.cyan(outcome.snippet)}`
1423
1505
  }
1424
1506
  }
1425
1507
  function mergeAppDts(templateDir, projectPath) {
1426
- const dest = path10.join(projectPath, "src", "app.d.ts");
1427
- const templateFile = path10.join(templateDir, "src", "app.d.ts");
1428
- if (!fs11.existsSync(dest)) {
1429
- if (!fs11.existsSync(templateFile)) return;
1430
- fs11.copyFileSync(templateFile, dest);
1508
+ const dest = path11.join(projectPath, "src", "app.d.ts");
1509
+ const templateFile = path11.join(templateDir, "src", "app.d.ts");
1510
+ if (!fs13.existsSync(dest)) {
1511
+ if (!fs13.existsSync(templateFile)) return;
1512
+ fs13.copyFileSync(templateFile, dest);
1431
1513
  return;
1432
1514
  }
1433
- const current = fs11.readFileSync(dest, "utf8");
1515
+ const current = fs13.readFileSync(dest, "utf8");
1434
1516
  if (current.includes("namespace Superforms")) return;
1435
1517
  const block = ` namespace Superforms {
1436
1518
  type Message = {
@@ -1449,7 +1531,7 @@ ${pc3.cyan(block)}`
1449
1531
  }
1450
1532
  const insertAt = match.index + match[0].length;
1451
1533
  const updated = current.slice(0, insertAt) + block + current.slice(insertAt);
1452
- fs11.writeFileSync(dest, updated);
1534
+ fs13.writeFileSync(dest, updated);
1453
1535
  }
1454
1536
  function maybeReplaceRoutes(projectPath, templateDir, options) {
1455
1537
  if (options.skipRoutes) {
@@ -1460,12 +1542,12 @@ function maybeReplaceRoutes(projectPath, templateDir, options) {
1460
1542
  p4.log.info("Leaving src/routes alone (looks customized).");
1461
1543
  return;
1462
1544
  }
1463
- const target = path10.join(projectPath, "src", "routes");
1464
- fs11.rmSync(target, { recursive: true, force: true });
1465
- const src = path10.join(templateDir, "src", "routes");
1466
- fs11.cpSync(src, target, {
1545
+ const target = path11.join(projectPath, "src", "routes");
1546
+ fs13.rmSync(target, { recursive: true, force: true });
1547
+ const src = path11.join(templateDir, "src", "routes");
1548
+ fs13.cpSync(src, target, {
1467
1549
  recursive: true,
1468
- filter: (s) => path10.basename(s) !== ".DS_Store"
1550
+ filter: (s) => path11.basename(s) !== ".DS_Store"
1469
1551
  });
1470
1552
  p4.log.success("Replaced src/routes with the vela template.");
1471
1553
  }
@@ -1474,7 +1556,7 @@ function summarize(names) {
1474
1556
  return `${names.slice(0, 3).join(", ")}, and ${names.length - 3} more`;
1475
1557
  }
1476
1558
  function printNextSteps(projectPath, packageManager) {
1477
- const relative = path10.relative(process5.cwd(), projectPath);
1559
+ const relative = path11.relative(process5.cwd(), projectPath);
1478
1560
  const pm = packageManager ?? getUserAgent() ?? "npm";
1479
1561
  const nextSteps = [];
1480
1562
  if (relative !== "") {
@@ -1498,8 +1580,8 @@ function printNextSteps(projectPath, packageManager) {
1498
1580
  }
1499
1581
 
1500
1582
  // src/commands/create.ts
1501
- import fs12 from "node:fs";
1502
- import path11 from "node:path";
1583
+ import fs14 from "node:fs";
1584
+ import path12 from "node:path";
1503
1585
  import process6 from "node:process";
1504
1586
  import * as v3 from "valibot";
1505
1587
  import { Command as Command3 } from "commander";
@@ -1522,7 +1604,7 @@ var create = new Command3("create").description("scaffold a new velastack projec
1522
1604
  projectPath,
1523
1605
  options
1524
1606
  );
1525
- const relative = path11.relative(process6.cwd(), directory);
1607
+ const relative = path12.relative(process6.cwd(), directory);
1526
1608
  const pm = packageManager ?? (await detect3({ cwd: directory }))?.name ?? getUserAgent() ?? "npm";
1527
1609
  const nextSteps = [];
1528
1610
  if (relative !== "") {
@@ -1571,7 +1653,7 @@ async function createProject(cwdArg, options) {
1571
1653
  }
1572
1654
  let directory;
1573
1655
  if (cwdArg) {
1574
- directory = path11.resolve(cwdArg);
1656
+ directory = path12.resolve(cwdArg);
1575
1657
  } else {
1576
1658
  const answer = await p5.text({
1577
1659
  message: "Where would you like your project to be created?",
@@ -1579,16 +1661,16 @@ async function createProject(cwdArg, options) {
1579
1661
  defaultValue: "./"
1580
1662
  });
1581
1663
  if (p5.isCancel(answer)) onCancel2();
1582
- directory = path11.resolve(answer);
1664
+ directory = path12.resolve(answer);
1583
1665
  }
1584
- if (fs12.existsSync(directory) && fs12.readdirSync(directory).filter((f) => !f.startsWith(".git")).length > 0) {
1666
+ if (fs14.existsSync(directory) && fs14.readdirSync(directory).filter((f) => !f.startsWith(".git")).length > 0) {
1585
1667
  const force = await p5.confirm({
1586
1668
  message: "Directory not empty. Continue?",
1587
1669
  initialValue: false
1588
1670
  });
1589
1671
  if (p5.isCancel(force) || !force) onCancel2();
1590
1672
  }
1591
- const dirName = path11.basename(directory);
1673
+ const dirName = path12.basename(directory);
1592
1674
  const { name } = await p5.group(
1593
1675
  {
1594
1676
  name: () => {
@@ -1606,7 +1688,7 @@ async function createProject(cwdArg, options) {
1606
1688
  const projectPath = directory;
1607
1689
  copyTemplate(template, projectPath);
1608
1690
  applyTemplateFiles(projectPath, { appName: name, cliVersion: package_default.version });
1609
- if (!fs12.existsSync(path11.join(projectPath, "package.json"))) {
1691
+ if (!fs14.existsSync(path12.join(projectPath, "package.json"))) {
1610
1692
  throw new Error(`Template ${template.name} is missing package.template.json`);
1611
1693
  }
1612
1694
  p5.log.success("Project created");
@@ -1668,11 +1750,11 @@ function promptCredentials(options, onCancel2) {
1668
1750
  );
1669
1751
  }
1670
1752
  function copyTemplate(template, target) {
1671
- fs12.mkdirSync(target, { recursive: true });
1672
- fs12.cpSync(template.dir, target, {
1753
+ fs14.mkdirSync(target, { recursive: true });
1754
+ fs14.cpSync(template.dir, target, {
1673
1755
  recursive: true,
1674
1756
  // The manifest describes the template to the CLI; it isn't part of the project.
1675
- filter: (src) => path11.basename(src) !== ".DS_Store" && path11.relative(template.dir, src) !== TEMPLATE_MANIFEST
1757
+ filter: (src) => path12.basename(src) !== ".DS_Store" && path12.relative(template.dir, src) !== TEMPLATE_MANIFEST
1676
1758
  });
1677
1759
  restoreTemplateNames(target);
1678
1760
  }
@@ -1685,11 +1767,11 @@ import { Command as Command4 } from "commander";
1685
1767
  import * as p11 from "@clack/prompts";
1686
1768
 
1687
1769
  // src/lib/pattern-runner.ts
1688
- import path12 from "node:path";
1770
+ import path13 from "node:path";
1689
1771
  import * as p6 from "@clack/prompts";
1690
1772
  import { bySlug } from "@velastack/patterns";
1691
1773
  function toRelative(root, filePath) {
1692
- return path12.isAbsolute(filePath) ? path12.relative(root, filePath) : filePath;
1774
+ return path13.isAbsolute(filePath) ? path13.relative(root, filePath) : filePath;
1693
1775
  }
1694
1776
  var isSuccess = (f) => (f.status ?? "success") === "success";
1695
1777
  async function runPattern(slug2, argv, input, report4) {
@@ -1698,7 +1780,7 @@ async function runPattern(slug2, argv, input, report4) {
1698
1780
  throw new Error(`Unknown pattern: ${slug2}`);
1699
1781
  }
1700
1782
  const { workspaceRootDir, features } = await getWorkspace();
1701
- const log41 = p6.taskLog({ title: report4.task.title });
1783
+ const log43 = p6.taskLog({ title: report4.task.title });
1702
1784
  let result;
1703
1785
  try {
1704
1786
  result = await pattern.generate({
@@ -1718,11 +1800,11 @@ async function runPattern(slug2, argv, input, report4) {
1718
1800
  });
1719
1801
  return collections2;
1720
1802
  },
1721
- logger: { info: (message) => log41.message(message) }
1803
+ logger: { info: (message) => log43.message(message) }
1722
1804
  });
1723
- log41.success(report4.task.success);
1805
+ log43.success(report4.task.success);
1724
1806
  } catch (e) {
1725
- log41.error(report4.task.error);
1807
+ log43.error(report4.task.error);
1726
1808
  throw e;
1727
1809
  }
1728
1810
  const rel = (f) => toRelative(workspaceRootDir, f);
@@ -1756,31 +1838,31 @@ async function runPattern(slug2, argv, input, report4) {
1756
1838
  }
1757
1839
 
1758
1840
  // src/lib/ai-flow.ts
1759
- import fs15 from "node:fs";
1760
- import path15 from "node:path";
1841
+ import fs17 from "node:fs";
1842
+ import path16 from "node:path";
1761
1843
  import * as p10 from "@clack/prompts";
1762
1844
  import pc4 from "picocolors";
1763
1845
 
1764
1846
  // src/lib/config.ts
1765
- import fs13 from "node:fs";
1847
+ import fs15 from "node:fs";
1766
1848
  import os from "node:os";
1767
- import path13 from "node:path";
1768
- var CONFIG_DIR = path13.join(os.homedir(), ".vela");
1769
- var CONFIG_PATH = path13.join(CONFIG_DIR, "config.json");
1849
+ import path14 from "node:path";
1850
+ var CONFIG_DIR = path14.join(os.homedir(), ".vela");
1851
+ var CONFIG_PATH = path14.join(CONFIG_DIR, "config.json");
1770
1852
  function readConfig() {
1771
- if (!fs13.existsSync(CONFIG_PATH)) return null;
1853
+ if (!fs15.existsSync(CONFIG_PATH)) return null;
1772
1854
  try {
1773
- return JSON.parse(fs13.readFileSync(CONFIG_PATH, "utf8"));
1855
+ return JSON.parse(fs15.readFileSync(CONFIG_PATH, "utf8"));
1774
1856
  } catch {
1775
1857
  return null;
1776
1858
  }
1777
1859
  }
1778
1860
  function writeConfig(config) {
1779
- fs13.mkdirSync(CONFIG_DIR, { recursive: true });
1780
- fs13.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
1861
+ fs15.mkdirSync(CONFIG_DIR, { recursive: true });
1862
+ fs15.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
1781
1863
  }
1782
1864
  function clearConfig() {
1783
- if (fs13.existsSync(CONFIG_PATH)) fs13.unlinkSync(CONFIG_PATH);
1865
+ if (fs15.existsSync(CONFIG_PATH)) fs15.unlinkSync(CONFIG_PATH);
1784
1866
  }
1785
1867
  function requireApiKey() {
1786
1868
  const config = readConfig();
@@ -1791,16 +1873,16 @@ function requireApiKey() {
1791
1873
  }
1792
1874
 
1793
1875
  // src/lib/project-config.ts
1794
- import fs14 from "node:fs";
1795
- import path14 from "node:path";
1876
+ import fs16 from "node:fs";
1877
+ import path15 from "node:path";
1796
1878
  function projectConfigPath(workspaceRootDir) {
1797
- return path14.join(workspaceRootDir, ".vela", "project.json");
1879
+ return path15.join(workspaceRootDir, ".vela", "project.json");
1798
1880
  }
1799
1881
  function readProjectConfig(workspaceRootDir) {
1800
1882
  const file = projectConfigPath(workspaceRootDir);
1801
- if (!fs14.existsSync(file)) return null;
1883
+ if (!fs16.existsSync(file)) return null;
1802
1884
  try {
1803
- const parsed = JSON.parse(fs14.readFileSync(file, "utf8"));
1885
+ const parsed = JSON.parse(fs16.readFileSync(file, "utf8"));
1804
1886
  if (typeof parsed.projectId !== "string" || typeof parsed.teamId !== "string" || typeof parsed.projectName !== "string") {
1805
1887
  return null;
1806
1888
  }
@@ -1815,15 +1897,15 @@ function readProjectConfig(workspaceRootDir) {
1815
1897
  }
1816
1898
  function writeProjectConfig(workspaceRootDir, config) {
1817
1899
  const file = projectConfigPath(workspaceRootDir);
1818
- fs14.mkdirSync(path14.dirname(file), { recursive: true });
1900
+ fs16.mkdirSync(path15.dirname(file), { recursive: true });
1819
1901
  let existing = {};
1820
- if (fs14.existsSync(file)) {
1902
+ if (fs16.existsSync(file)) {
1821
1903
  try {
1822
- existing = JSON.parse(fs14.readFileSync(file, "utf8"));
1904
+ existing = JSON.parse(fs16.readFileSync(file, "utf8"));
1823
1905
  } catch {
1824
1906
  }
1825
1907
  }
1826
- fs14.writeFileSync(file, JSON.stringify({ ...existing, ...config }, null, 2) + "\n");
1908
+ fs16.writeFileSync(file, JSON.stringify({ ...existing, ...config }, null, 2) + "\n");
1827
1909
  }
1828
1910
 
1829
1911
  // src/lib/ai-client.ts
@@ -1867,17 +1949,17 @@ async function aiLoop(opts) {
1867
1949
  let attempt = 0;
1868
1950
  while (true) {
1869
1951
  attempt++;
1870
- const spinner5 = p7.spinner();
1871
- spinner5.start(`${opts.stageLabel} (${attempt > 1 ? "iteration " + attempt : "first pass"})\u2026`);
1952
+ const spinner7 = p7.spinner();
1953
+ spinner7.start(`${opts.stageLabel} (${attempt > 1 ? "iteration " + attempt : "first pass"})\u2026`);
1872
1954
  let result;
1873
1955
  let turn;
1874
1956
  try {
1875
1957
  const out = await opts.call({ prompt, history });
1876
1958
  result = out.result;
1877
1959
  turn = out.turn;
1878
- spinner5.stop(`${opts.stageLabel} ready.`);
1960
+ spinner7.stop(`${opts.stageLabel} ready.`);
1879
1961
  } catch (e) {
1880
- spinner5.stop(`${opts.stageLabel} failed.`);
1962
+ spinner7.stop(`${opts.stageLabel} failed.`);
1881
1963
  throw e;
1882
1964
  }
1883
1965
  opts.renderPreview(result);
@@ -2097,11 +2179,11 @@ function specToArgv(spec) {
2097
2179
  return collectionSpecToArgv(spec);
2098
2180
  }
2099
2181
  function writeLayoutSidecar(workspaceRootDir, modelName, layout) {
2100
- const dir = path15.join(workspaceRootDir, "data", "ai-form-layouts");
2101
- fs15.mkdirSync(dir, { recursive: true });
2102
- const file = path15.join(dir, `${modelName}.json`);
2103
- fs15.writeFileSync(file, JSON.stringify(layout, null, 2) + "\n");
2104
- return path15.relative(workspaceRootDir, file);
2182
+ const dir = path16.join(workspaceRootDir, "data", "ai-form-layouts");
2183
+ fs17.mkdirSync(dir, { recursive: true });
2184
+ const file = path16.join(dir, `${modelName}.json`);
2185
+ fs17.writeFileSync(file, JSON.stringify(layout, null, 2) + "\n");
2186
+ return path16.relative(workspaceRootDir, file);
2105
2187
  }
2106
2188
 
2107
2189
  // src/commands/generate/form.ts
@@ -2631,8 +2713,8 @@ import * as p15 from "@clack/prompts";
2631
2713
  import pc5 from "picocolors";
2632
2714
 
2633
2715
  // src/lib/deploy-config.ts
2634
- import fs16 from "node:fs";
2635
- import path16 from "node:path";
2716
+ import fs18 from "node:fs";
2717
+ import path17 from "node:path";
2636
2718
  import crypto from "node:crypto";
2637
2719
  import { pathToFileURL } from "node:url";
2638
2720
  var CONFIG_BASENAMES = [
@@ -2643,8 +2725,8 @@ var CONFIG_BASENAMES = [
2643
2725
  ];
2644
2726
  function findConfigFile(workspaceRootDir) {
2645
2727
  for (const name of CONFIG_BASENAMES) {
2646
- const file = path16.join(workspaceRootDir, name);
2647
- if (fs16.existsSync(file)) return file;
2728
+ const file = path17.join(workspaceRootDir, name);
2729
+ if (fs18.existsSync(file)) return file;
2648
2730
  }
2649
2731
  return null;
2650
2732
  }
@@ -2652,49 +2734,49 @@ async function loadDeployConfig(workspaceRootDir) {
2652
2734
  const file = findConfigFile(workspaceRootDir);
2653
2735
  if (!file) return {};
2654
2736
  if (file.endsWith(".json")) {
2655
- return JSON.parse(fs16.readFileSync(file, "utf8"));
2737
+ return JSON.parse(fs18.readFileSync(file, "utf8"));
2656
2738
  }
2657
2739
  const url = file.endsWith(".ts") ? await transpileToTemp(file) : pathToFileURL(file).href;
2658
2740
  try {
2659
2741
  const mod = await import(url);
2660
2742
  const config = mod.default;
2661
2743
  if (!config || typeof config !== "object") {
2662
- throw new Error(`${path16.basename(file)} must export a config object as its default export.`);
2744
+ throw new Error(`${path17.basename(file)} must export a config object as its default export.`);
2663
2745
  }
2664
2746
  return config;
2665
2747
  } finally {
2666
- if (url !== pathToFileURL(file).href) fs16.rmSync(new URL(url), { force: true });
2748
+ if (url !== pathToFileURL(file).href) fs18.rmSync(new URL(url), { force: true });
2667
2749
  }
2668
2750
  }
2669
2751
  async function transpileToTemp(file) {
2670
2752
  const { ts } = await import("ts-morph");
2671
- const source = fs16.readFileSync(file, "utf8");
2753
+ const source = fs18.readFileSync(file, "utf8");
2672
2754
  const { outputText } = ts.transpileModule(source, {
2673
2755
  compilerOptions: { module: ts.ModuleKind.ESNext, target: ts.ScriptTarget.ES2022 }
2674
2756
  });
2675
- const temp = path16.join(
2676
- path16.dirname(file),
2757
+ const temp = path17.join(
2758
+ path17.dirname(file),
2677
2759
  `.velastack.config.${crypto.randomBytes(4).toString("hex")}.mjs`
2678
2760
  );
2679
- fs16.writeFileSync(temp, outputText);
2761
+ fs18.writeFileSync(temp, outputText);
2680
2762
  return pathToFileURL(temp).href;
2681
2763
  }
2682
2764
  function projectFilePath(workspaceRootDir) {
2683
- return path16.join(workspaceRootDir, ".vela", "project.json");
2765
+ return path17.join(workspaceRootDir, ".vela", "project.json");
2684
2766
  }
2685
2767
  function readProjectFile(workspaceRootDir) {
2686
2768
  const file = projectFilePath(workspaceRootDir);
2687
- if (!fs16.existsSync(file)) return {};
2769
+ if (!fs18.existsSync(file)) return {};
2688
2770
  try {
2689
- return JSON.parse(fs16.readFileSync(file, "utf8"));
2771
+ return JSON.parse(fs18.readFileSync(file, "utf8"));
2690
2772
  } catch {
2691
2773
  return {};
2692
2774
  }
2693
2775
  }
2694
2776
  function writeProjectFile(workspaceRootDir, data) {
2695
2777
  const file = projectFilePath(workspaceRootDir);
2696
- fs16.mkdirSync(path16.dirname(file), { recursive: true });
2697
- fs16.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
2778
+ fs18.mkdirSync(path17.dirname(file), { recursive: true });
2779
+ fs18.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
2698
2780
  }
2699
2781
  function resolveAppIdentity(workspaceRootDir, config = {}) {
2700
2782
  const project = readProjectFile(workspaceRootDir);
@@ -2719,11 +2801,11 @@ function readAppIdentity(workspaceRootDir, config = {}) {
2719
2801
  }
2720
2802
  function defaultProjectName(workspaceRootDir) {
2721
2803
  try {
2722
- const pkg = readPackageJson(path16.join(workspaceRootDir, "package.json"));
2804
+ const pkg = readPackageJson(path17.join(workspaceRootDir, "package.json"));
2723
2805
  if (typeof pkg.name === "string" && pkg.name.trim()) return pkg.name.trim();
2724
2806
  } catch {
2725
2807
  }
2726
- return path16.basename(workspaceRootDir);
2808
+ return path17.basename(workspaceRootDir);
2727
2809
  }
2728
2810
  function slug(value) {
2729
2811
  return value.toLowerCase().replace(/^@/, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 32) || "app";
@@ -2802,9 +2884,9 @@ function sshOptionsFrom(options) {
2802
2884
  }
2803
2885
 
2804
2886
  // src/lib/ssh.ts
2805
- import fs17 from "node:fs";
2887
+ import fs19 from "node:fs";
2806
2888
  import os2 from "node:os";
2807
- import path17 from "node:path";
2889
+ import path18 from "node:path";
2808
2890
  import crypto2 from "node:crypto";
2809
2891
  import process8 from "node:process";
2810
2892
  import { spawn as spawn2 } from "node:child_process";
@@ -2847,9 +2929,9 @@ var SshSession = class {
2847
2929
  }
2848
2930
  async open() {
2849
2931
  if (this.controlPath) return;
2850
- const dir = path17.join(os2.tmpdir(), "vela-ssh");
2851
- fs17.mkdirSync(dir, { recursive: true, mode: 448 });
2852
- const socket = path17.join(dir, `${crypto2.randomBytes(6).toString("hex")}.sock`);
2932
+ const dir = path18.join(os2.tmpdir(), "vela-ssh");
2933
+ fs19.mkdirSync(dir, { recursive: true, mode: 448 });
2934
+ const socket = path18.join(dir, `${crypto2.randomBytes(6).toString("hex")}.sock`);
2853
2935
  this.controlPath = socket;
2854
2936
  const args = [
2855
2937
  ...this.sshArgs(),
@@ -3105,14 +3187,14 @@ function spawnCapture(command, args, opts = {}) {
3105
3187
  }
3106
3188
 
3107
3189
  // src/lib/remote.ts
3108
- import path18 from "node:path";
3190
+ import path19 from "node:path";
3109
3191
  var VELA_ROOT = "/var/lib/vela";
3110
3192
  var VELA_ETC = "/etc/vela";
3111
3193
  var VELA_USER = "vela";
3112
3194
  var SCRIPTS_DIR = `${VELA_ROOT}/scripts`;
3113
3195
  var PROVISIONED_MARKER = `${VELA_ETC}/provisioned`;
3114
3196
  function serverTemplatesDir() {
3115
- return path18.join(templatesDir(), "server");
3197
+ return path19.join(templatesDir(), "server");
3116
3198
  }
3117
3199
  async function syncServerScripts(session) {
3118
3200
  await session.script(`mkdir -p "$1" && chmod 0755 "$1"`, { args: [SCRIPTS_DIR] });
@@ -3180,7 +3262,7 @@ var remotePaths = {
3180
3262
  };
3181
3263
 
3182
3264
  // src/lib/remote-env.ts
3183
- import fs18 from "node:fs";
3265
+ import fs20 from "node:fs";
3184
3266
  import dotenv from "dotenv";
3185
3267
  var KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
3186
3268
  function isValidKey(key) {
@@ -3228,7 +3310,7 @@ function quote(value) {
3228
3310
  return `"${escaped}"`;
3229
3311
  }
3230
3312
  function readLocalEnvFile(file) {
3231
- const parsed = dotenv.parse(fs18.readFileSync(file));
3313
+ const parsed = dotenv.parse(fs20.readFileSync(file));
3232
3314
  const result = {};
3233
3315
  for (const [key, value] of Object.entries(parsed)) {
3234
3316
  if (isValidKey(key)) result[key] = value;
@@ -3518,17 +3600,17 @@ function envFilePath(workspaceRootDir) {
3518
3600
  import pc7 from "picocolors";
3519
3601
 
3520
3602
  // src/lib/local-env.ts
3521
- import fs19 from "node:fs";
3603
+ import fs21 from "node:fs";
3522
3604
  import * as p16 from "@clack/prompts";
3523
3605
  import pc6 from "picocolors";
3524
3606
  function readLocalEnv(envFile) {
3525
- if (!fs19.existsSync(envFile)) return {};
3607
+ if (!fs21.existsSync(envFile)) return {};
3526
3608
  return readLocalEnvFile(envFile);
3527
3609
  }
3528
3610
  function editLocalEnv(envFile, edit) {
3529
- const before = fs19.existsSync(envFile) ? fs19.readFileSync(envFile, "utf8") : "";
3611
+ const before = fs21.existsSync(envFile) ? fs21.readFileSync(envFile, "utf8") : "";
3530
3612
  const after = edit(before);
3531
- if (after !== before) fs19.writeFileSync(envFile, after);
3613
+ if (after !== before) fs21.writeFileSync(envFile, after);
3532
3614
  }
3533
3615
  function setLocalEnv(envFile, key, value) {
3534
3616
  editLocalEnv(envFile, (content) => upsertEnvVar(content, key, value));
@@ -3660,8 +3742,8 @@ Set ${pc7.cyan("POCKETBASE_SUPERUSER_EMAIL")} and ${pc7.cyan("POCKETBASE_SUPERUS
3660
3742
  }
3661
3743
 
3662
3744
  // src/lib/s3-settings.ts
3663
- import fs20 from "node:fs";
3664
- import path19 from "node:path";
3745
+ import fs22 from "node:fs";
3746
+ import path20 from "node:path";
3665
3747
  var VIRTUAL_HOSTED = [/\.amazonaws\.com$/i, /\.r2\.cloudflarestorage\.com$/i];
3666
3748
  function defaultForcePathStyle(endpoint) {
3667
3749
  let host;
@@ -3699,18 +3781,18 @@ async function hasLocalUploads(session, instance, workspaceRootDir) {
3699
3781
  });
3700
3782
  return result.stdout.trim().length > 0;
3701
3783
  }
3702
- return hasFile(path19.join(workspaceRootDir, DATA_DIR, "storage"));
3784
+ return hasFile(path20.join(workspaceRootDir, DATA_DIR, "storage"));
3703
3785
  }
3704
3786
  function hasFile(dir) {
3705
3787
  let entries;
3706
3788
  try {
3707
- entries = fs20.readdirSync(dir, { withFileTypes: true });
3789
+ entries = fs22.readdirSync(dir, { withFileTypes: true });
3708
3790
  } catch {
3709
3791
  return false;
3710
3792
  }
3711
3793
  for (const entry of entries) {
3712
3794
  if (entry.isFile()) return true;
3713
- if (entry.isDirectory() && hasFile(path19.join(dir, entry.name))) return true;
3795
+ if (entry.isDirectory() && hasFile(path20.join(dir, entry.name))) return true;
3714
3796
  }
3715
3797
  return false;
3716
3798
  }
@@ -4430,124 +4512,292 @@ async function confirm7(appName, targetName, envTag, purge) {
4430
4512
  var destroy = new Command40("destroy").description("destroy scaffolding, or a deployment").configureHelp(helpConfig).addCommand(form2).addCommand(schema2).addCommand(resource2).addCommand(scaffold2).addCommand(deployment);
4431
4513
 
4432
4514
  // src/commands/ui.ts
4433
- import { Command as Command43 } from "commander";
4515
+ import { Command as Command46 } from "commander";
4434
4516
 
4435
4517
  // src/commands/ui/add.ts
4436
4518
  import { Command as Command41 } from "commander";
4437
- import { exec as exec2 } from "tinyexec";
4438
- import { detect as detect4, resolveCommand as resolveCommand4 } from "package-manager-detector";
4439
- var add = new Command41("add").description("add ui components").argument("<components...>", "the components to add").configureHelp(helpConfig).action(
4440
- (components) => runCommand(async () => {
4519
+ import * as p24 from "@clack/prompts";
4520
+ import { installComponents } from "@velastack/patterns";
4521
+
4522
+ // src/lib/ui-add.ts
4523
+ var STYLES = ["nova", "vega", "maia", "lyra", "mira", "luma", "sera", "rhea"];
4524
+ var BASE_COLORS = ["neutral", "stone", "zinc", "mauve", "olive", "mist", "taupe"];
4525
+ var THEMES = [
4526
+ ...BASE_COLORS,
4527
+ "amber",
4528
+ "blue",
4529
+ "cyan",
4530
+ "emerald",
4531
+ "fuchsia",
4532
+ "green",
4533
+ "indigo",
4534
+ "lime",
4535
+ "orange",
4536
+ "pink",
4537
+ "purple",
4538
+ "red",
4539
+ "rose",
4540
+ "sky",
4541
+ "teal",
4542
+ "violet",
4543
+ "yellow"
4544
+ ];
4545
+ var NEXT_STEPS = [
4546
+ "Import a component with: import { Button } from '$lib/components/ui/button';",
4547
+ "Tweak styling in src/lib/components/ui/<component>/*.svelte.",
4548
+ `Run \`vela ui base <color>\` to change the palette (${BASE_COLORS.join(", ")}), or \`vela ui list\` to see what else is available.`
4549
+ ];
4550
+ function uiAddReport(requested, outcome) {
4551
+ const { installed, skipped, packages } = outcome;
4552
+ const report4 = {
4553
+ summary: installed.length > 0 ? `Added ${installed.length} UI component(s).` : `All ${new Set(requested).size} requested component(s) are already present.`,
4554
+ componentsAdded: installed,
4555
+ packagesInstalled: packages,
4556
+ nextSteps: [...NEXT_STEPS]
4557
+ };
4558
+ if (skipped.length > 0) {
4559
+ report4.sections = [{ label: "Already present (pass --overwrite to replace)", items: skipped }];
4560
+ report4.nextSteps.push(
4561
+ `Re-add an existing component with: vela ui add --overwrite ${skipped[0]}`
4562
+ );
4563
+ }
4564
+ return report4;
4565
+ }
4566
+
4567
+ // src/commands/ui/add.ts
4568
+ var add = new Command41("add").description("add ui components (shadcn-svelte items and vela components such as data-table)").argument("<components...>", "the components to add").option("--overwrite", "replace components that already exist", false).configureHelp(helpConfig).action(
4569
+ (components, options) => runCommand(async () => {
4441
4570
  const { workspaceRootDir } = await getWorkspace();
4442
- const packageManager = (await detect4({ cwd: workspaceRootDir }))?.name ?? "npm";
4443
- const resolved = resolveCommand4(packageManager, "execute", [
4444
- "shadcn-svelte",
4445
- "add",
4446
- ...components
4447
- ]);
4448
- if (!resolved) {
4449
- throw new Error(`Unable to resolve execute command for ${packageManager}`);
4450
- }
4451
- const args = [...resolved.args];
4452
- if (packageManager === "npm") args.unshift("--yes");
4571
+ const log43 = p24.taskLog({ title: "Adding UI components..." });
4572
+ let outcome;
4453
4573
  try {
4454
- await exec2(resolved.command, args, {
4455
- nodeOptions: { cwd: workspaceRootDir, stdio: "inherit" },
4456
- throwOnError: true
4574
+ outcome = await installComponents({
4575
+ root: workspaceRootDir,
4576
+ components,
4577
+ overwrite: options.overwrite,
4578
+ logger: { info: (message) => log43.message(message) }
4457
4579
  });
4458
- } catch (error) {
4459
- const typed = error;
4460
- throw new Error(
4461
- `Failed to execute '${resolved.command} ${args.join(" ")}': ${typed.message}`,
4462
- { cause: typed.output }
4463
- );
4580
+ log43.success("UI components ready");
4581
+ } catch (e) {
4582
+ log43.error("Could not add UI components");
4583
+ throw e;
4584
+ }
4585
+ reportResult(uiAddReport(components, outcome));
4586
+ }, "Failed to add UI components.")
4587
+ );
4588
+
4589
+ // src/commands/ui/base.ts
4590
+ import { Command as Command42 } from "commander";
4591
+ import * as p25 from "@clack/prompts";
4592
+ import { applyBaseColor } from "@velastack/patterns";
4593
+ var base = new Command42("base").description("change the base (gray) palette").argument("<color>", `base color to use (${BASE_COLORS.join(", ")})`).configureHelp(helpConfig).action(
4594
+ (color) => runCommand(async () => {
4595
+ const { workspaceRootDir } = await getWorkspace();
4596
+ const log43 = p25.taskLog({ title: `Applying the ${color} palette...` });
4597
+ let outcome;
4598
+ try {
4599
+ outcome = await applyBaseColor({ root: workspaceRootDir, color });
4600
+ log43.success("Palette applied");
4601
+ } catch (e) {
4602
+ log43.error("Could not change the base color");
4603
+ throw e;
4464
4604
  }
4465
4605
  reportResult({
4466
- summary: `Added ${components.length} UI component(s).`,
4467
- componentsAdded: components,
4606
+ summary: `Set base color to ${outcome.baseColor}.`,
4607
+ filesModified: outcome.filesModified,
4468
4608
  nextSteps: [
4469
- `Import a component with: import { Button } from '$lib/components/ui/button';`,
4470
- "Tweak styling in src/lib/components/ui/<component>/*.svelte.",
4471
- "Run `vela ui base <color>` to change the palette (slate, gray, zinc, stone, neutral)."
4609
+ "Run your dev server to preview the new palette.",
4610
+ "Run `vela ui theme <accent>` to put an accent color on top of it.",
4611
+ "Tweak individual CSS variables in src/app.css if you want to customize the theme further."
4472
4612
  ]
4473
4613
  });
4474
- }, "Failed to add UI components.")
4614
+ }, "Failed to change base color.")
4475
4615
  );
4476
4616
 
4477
- // src/commands/ui/base.ts
4478
- import fs21 from "node:fs";
4479
- import path20 from "node:path";
4480
- import { Command as Command42, InvalidArgumentError } from "commander";
4481
- var VALID_COLORS = ["slate", "gray", "zinc", "stone", "neutral"];
4482
- function findThemeFile(color) {
4483
- const candidate = path20.join(templatesDir(), "ui", "css", `${color}.css`);
4484
- if (!fs21.existsSync(candidate)) {
4485
- throw new Error(`Theme file not found for color: ${color}`);
4617
+ // src/commands/ui/list.ts
4618
+ import { Command as Command43 } from "commander";
4619
+ import * as p26 from "@clack/prompts";
4620
+ import { listComponents } from "@velastack/patterns";
4621
+
4622
+ // src/lib/ui-list.ts
4623
+ function uiListReport(result) {
4624
+ const installed = new Set(result.installed);
4625
+ const registryUi = result.registry.filter((item) => item.type === "registry:ui").map((item) => item.name).sort();
4626
+ const sections = [
4627
+ { label: `Installed (${result.installed.length})`, items: result.installed },
4628
+ {
4629
+ label: "Vela components",
4630
+ items: result.custom.map((name) => installed.has(name) ? `${name} (installed)` : name)
4631
+ }
4632
+ ];
4633
+ if (!result.registryUnavailable) {
4634
+ sections.push({
4635
+ label: `shadcn-svelte ${result.style} (${registryUi.length})`,
4636
+ items: registryUi
4637
+ });
4486
4638
  }
4487
- return candidate;
4639
+ return {
4640
+ summary: `UI components for the ${result.style} style.`,
4641
+ sections,
4642
+ nextSteps: [
4643
+ "Add one with: vela ui add <component>",
4644
+ "Switch styles with `vela ui style <name>`, or the palette with `vela ui base <color>`."
4645
+ ]
4646
+ };
4488
4647
  }
4489
- function extractSelectors(css) {
4490
- const rootMatch = css.match(/:root\s*{[^}]*}/);
4491
- const darkMatch = css.match(/\.dark\s*{[^}]*}/);
4492
- if (!rootMatch || !darkMatch) {
4493
- throw new Error("Invalid theme file: missing :root or .dark selector");
4648
+
4649
+ // src/commands/ui/list.ts
4650
+ var list = new Command43("list").description("list installed ui components, vela components and the style registry").option("--json", "print the result as JSON", false).configureHelp(helpConfig).action(
4651
+ (options) => runCommand(async () => {
4652
+ const { workspaceRootDir } = await getWorkspace();
4653
+ if (options.json) {
4654
+ const result2 = await listComponents({ root: workspaceRootDir });
4655
+ console.log(JSON.stringify(result2, null, 2));
4656
+ return;
4657
+ }
4658
+ const spinner7 = p26.spinner();
4659
+ spinner7.start("Reading the registry...");
4660
+ let result;
4661
+ try {
4662
+ result = await listComponents({ root: workspaceRootDir });
4663
+ } catch (e) {
4664
+ spinner7.stop("Could not list UI components");
4665
+ throw e;
4666
+ }
4667
+ spinner7.stop(`Read the ${result.style} registry`);
4668
+ reportResult(uiListReport(result));
4669
+ if (result.registryUnavailable) {
4670
+ p26.log.warn(`${result.registryUnavailable}
4671
+ Registry components are not listed.`);
4672
+ }
4673
+ }, "Failed to list UI components.")
4674
+ );
4675
+
4676
+ // src/commands/ui/style.ts
4677
+ import { Command as Command44 } from "commander";
4678
+ import * as p27 from "@clack/prompts";
4679
+ import { switchStyle } from "@velastack/patterns";
4680
+
4681
+ // src/lib/ui-style.ts
4682
+ function uiStyleReport(result) {
4683
+ const nextSteps = ["Run your dev server to see the new style."];
4684
+ if (result.reinstalled.length > 0) {
4685
+ nextSteps.push(
4686
+ "Check `git diff src/lib/components/ui` for local edits the re-added components replaced."
4687
+ );
4494
4688
  }
4495
- return { root: rootMatch[0], dark: darkMatch[0] };
4689
+ nextSteps.push(...result.hints);
4690
+ nextSteps.push(
4691
+ "Run `vela ui base <color>` or `vela ui theme <accent>` to adjust the palette.",
4692
+ "Run `vela ui list` to see what the new style offers."
4693
+ );
4694
+ return {
4695
+ summary: `Switched to the ${result.style} style.`,
4696
+ componentsAdded: result.reinstalled,
4697
+ filesModified: result.filesModified,
4698
+ packagesInstalled: result.packages,
4699
+ nextSteps
4700
+ };
4496
4701
  }
4497
- function applyTheme(appCss, selectors) {
4498
- let out = appCss;
4499
- out = out.match(/:root\s*{[^}]*}/) ? out.replace(/:root\s*{[^}]*}/, selectors.root) : `${selectors.root}
4500
4702
 
4501
- ${out}`;
4502
- out = out.match(/\.dark\s*{[^}]*}/) ? out.replace(/\.dark\s*{[^}]*}/, selectors.dark) : `${out}
4703
+ // src/commands/ui/style.ts
4704
+ var style = new Command44("style").description("switch the shadcn-svelte style, re-adding its components").argument("<style>", `style to switch to (${STYLES.join(", ")})`).option("-y, --yes", "skip the confirmation prompt").option("--no-font", "keep the current font instead of applying the style's").configureHelp(helpConfig).action(
4705
+ (name, options) => runCommand(async () => {
4706
+ const { workspaceRootDir } = await getWorkspace();
4707
+ const spinner7 = p27.spinner();
4708
+ spinner7.start(`Reading the ${name} registry...`);
4709
+ let log43;
4710
+ let outcome;
4711
+ try {
4712
+ outcome = await switchStyle({
4713
+ root: workspaceRootDir,
4714
+ style: name,
4715
+ font: options.font,
4716
+ logger: { info: (message) => log43?.message(message) },
4717
+ confirm: async (components) => {
4718
+ spinner7.stop(`Read the ${name} registry`);
4719
+ if (components.length > 0) {
4720
+ p27.log.info(
4721
+ `Re-adds ${components.length} component(s) from the ${name} registry; local edits to their files are lost:
4722
+ ${components.map((c) => `- ${c}`).join("\n")}`
4723
+ );
4724
+ } else {
4725
+ p27.log.info(
4726
+ `No installed component comes from the registry; only the config changes.`
4727
+ );
4728
+ }
4729
+ if (!options.yes) {
4730
+ const ok = await p27.confirm({ message: `Switch to ${name}?`, initialValue: false });
4731
+ if (p27.isCancel(ok) || !ok) return false;
4732
+ }
4733
+ log43 = p27.taskLog({ title: `Switching to the ${name} style...` });
4734
+ return true;
4735
+ }
4736
+ });
4737
+ } catch (e) {
4738
+ spinner7.stop(`Could not switch to ${name}`);
4739
+ log43?.error("Could not switch style");
4740
+ throw e;
4741
+ }
4742
+ spinner7.stop(`Read the ${name} registry`);
4743
+ if (outcome.status === "unchanged") {
4744
+ p27.log.info(`Already using the ${name} style.`);
4745
+ return;
4746
+ }
4747
+ if (outcome.status === "cancelled") {
4748
+ p27.cancel("Operation cancelled.");
4749
+ return;
4750
+ }
4751
+ log43?.success("Style switched");
4752
+ reportResult(uiStyleReport(outcome));
4753
+ }, "Failed to switch style.")
4754
+ );
4503
4755
 
4504
- ${selectors.dark}`;
4505
- return out;
4506
- }
4507
- var base = new Command42("base").description("change the base color").argument("<color>", "base color to use", (value) => {
4508
- if (!VALID_COLORS.includes(value)) {
4509
- throw new InvalidArgumentError(`Valid colors are: ${VALID_COLORS.join(", ")}`);
4510
- }
4511
- return value;
4512
- }).configureHelp(helpConfig).action(
4513
- (color) => runCommand(async () => {
4756
+ // src/commands/ui/theme.ts
4757
+ import { Command as Command45 } from "commander";
4758
+ import * as p28 from "@clack/prompts";
4759
+ import { applyTheme } from "@velastack/patterns";
4760
+ var theme = new Command45("theme").description("change the accent color, keeping the base palette").argument("<accent>", `accent to use (${THEMES.join(", ")})`).configureHelp(helpConfig).action(
4761
+ (accent) => runCommand(async () => {
4514
4762
  const { workspaceRootDir } = await getWorkspace();
4515
- const appCssPath = path20.join(workspaceRootDir, "src", "app.css");
4516
- if (!fs21.existsSync(appCssPath)) {
4517
- throw new Error(`Could not find ${path20.relative(workspaceRootDir, appCssPath)}`);
4763
+ const log43 = p28.taskLog({ title: `Applying the ${accent} accent...` });
4764
+ let outcome;
4765
+ try {
4766
+ outcome = await applyTheme({ root: workspaceRootDir, theme: accent });
4767
+ log43.success("Accent applied");
4768
+ } catch (e) {
4769
+ log43.error("Could not change the accent");
4770
+ throw e;
4518
4771
  }
4519
- const themeContent = fs21.readFileSync(findThemeFile(color), "utf8");
4520
- const selectors = extractSelectors(themeContent);
4521
- const appCss = fs21.readFileSync(appCssPath, "utf8");
4522
- fs21.writeFileSync(appCssPath, applyTheme(appCss, selectors));
4523
4772
  reportResult({
4524
- summary: `Set base color to ${color}.`,
4525
- filesModified: [path20.relative(workspaceRootDir, appCssPath)],
4773
+ summary: `Set accent to ${outcome.theme} on the ${outcome.baseColor} palette.`,
4774
+ filesModified: outcome.filesModified,
4526
4775
  nextSteps: [
4527
- "Run your dev server to preview the new palette.",
4776
+ "Run your dev server to preview the new accent.",
4777
+ "Run `vela ui base <color>` to change the palette underneath (this resets the accent).",
4528
4778
  "Tweak individual CSS variables in src/app.css if you want to customize the theme further."
4529
4779
  ]
4530
4780
  });
4531
- }, "Failed to change base color.")
4781
+ }, "Failed to change accent.")
4532
4782
  );
4533
4783
 
4534
4784
  // src/commands/ui.ts
4535
- var ui = new Command43("ui").description("generate ui components").configureHelp(helpConfig).addCommand(add).addCommand(base);
4785
+ var ui = new Command46("ui").description("generate ui components").configureHelp(helpConfig).addCommand(add).addCommand(list).addCommand(style).addCommand(base).addCommand(theme);
4536
4786
 
4537
4787
  // src/commands/legal.ts
4538
- import { Command as Command46 } from "commander";
4788
+ import { Command as Command49 } from "commander";
4539
4789
 
4540
4790
  // src/commands/legal/terms.ts
4541
- import fs22 from "node:fs";
4791
+ import fs23 from "node:fs";
4542
4792
  import path21 from "node:path";
4543
- import { Command as Command44 } from "commander";
4544
- import * as p25 from "@clack/prompts";
4793
+ import { Command as Command47 } from "commander";
4794
+ import * as p30 from "@clack/prompts";
4545
4795
 
4546
4796
  // src/commands/legal/shared.ts
4547
4797
  import process16 from "node:process";
4548
- import * as p24 from "@clack/prompts";
4798
+ import * as p29 from "@clack/prompts";
4549
4799
  var sharedFields = {
4550
- websiteUrl: () => p24.text({
4800
+ websiteUrl: () => p29.text({
4551
4801
  message: "What is your website URL?",
4552
4802
  placeholder: "http://www.mysite.com",
4553
4803
  validate: (value) => {
@@ -4556,7 +4806,7 @@ var sharedFields = {
4556
4806
  }
4557
4807
  }
4558
4808
  }),
4559
- websiteName: () => p24.text({
4809
+ websiteName: () => p29.text({
4560
4810
  message: "What is your website name?",
4561
4811
  placeholder: "My Site",
4562
4812
  validate: (value) => {
@@ -4565,7 +4815,7 @@ var sharedFields = {
4565
4815
  }
4566
4816
  }
4567
4817
  }),
4568
- entityType: () => p24.select({
4818
+ entityType: () => p29.select({
4569
4819
  message: "Entity type",
4570
4820
  options: [
4571
4821
  {
@@ -4576,7 +4826,7 @@ var sharedFields = {
4576
4826
  { value: "individual", label: "I'm an Individual" }
4577
4827
  ]
4578
4828
  }),
4579
- businessName: ({ results }) => results?.entityType === "business" ? p24.text({
4829
+ businessName: ({ results }) => results?.entityType === "business" ? p29.text({
4580
4830
  message: "What is the name of the business?",
4581
4831
  placeholder: "My Company LLC",
4582
4832
  validate: (value) => {
@@ -4585,7 +4835,7 @@ var sharedFields = {
4585
4835
  }
4586
4836
  }
4587
4837
  }) : void 0,
4588
- businessAddress: ({ results }) => results?.entityType === "business" ? p24.text({
4838
+ businessAddress: ({ results }) => results?.entityType === "business" ? p29.text({
4589
4839
  message: "What is the address of the business?",
4590
4840
  placeholder: "1 Cupertino, CA 95014",
4591
4841
  validate: (value) => {
@@ -4594,7 +4844,7 @@ var sharedFields = {
4594
4844
  }
4595
4845
  }
4596
4846
  }) : void 0,
4597
- country: () => p24.text({
4847
+ country: () => p29.text({
4598
4848
  message: "Enter the country",
4599
4849
  validate: (value) => {
4600
4850
  if (!value) {
@@ -4602,7 +4852,7 @@ var sharedFields = {
4602
4852
  }
4603
4853
  }
4604
4854
  }),
4605
- state: () => p24.text({
4855
+ state: () => p29.text({
4606
4856
  message: "Enter the state",
4607
4857
  validate: (value) => {
4608
4858
  if (!value) {
@@ -4612,11 +4862,11 @@ var sharedFields = {
4612
4862
  })
4613
4863
  };
4614
4864
  var onCancel = () => {
4615
- p24.cancel("Operation cancelled.");
4865
+ p29.cancel("Operation cancelled.");
4616
4866
  process16.exit(0);
4617
4867
  };
4618
4868
  async function contactMethods(type) {
4619
- const selection = await p24.multiselect({
4869
+ const selection = await p29.multiselect({
4620
4870
  message: `How can users contact you for any questions regarding your ${type === "privacy" ? "Privacy Policy" : "Terms & Conditions"}? Check all that apply`,
4621
4871
  options: [
4622
4872
  { value: "email", label: "By email" },
@@ -4625,11 +4875,11 @@ async function contactMethods(type) {
4625
4875
  { value: "mail", label: "By sending post mail" }
4626
4876
  ]
4627
4877
  });
4628
- if (p24.isCancel(selection)) onCancel();
4878
+ if (p29.isCancel(selection)) onCancel();
4629
4879
  const contact = selection;
4630
4880
  const details = {};
4631
4881
  if (contact.includes("email")) {
4632
- const email3 = await p24.text({
4882
+ const email3 = await p29.text({
4633
4883
  message: "What's the email?",
4634
4884
  placeholder: "office@mycompany.com",
4635
4885
  validate: (value) => {
@@ -4638,11 +4888,11 @@ async function contactMethods(type) {
4638
4888
  }
4639
4889
  }
4640
4890
  });
4641
- if (p24.isCancel(email3)) onCancel();
4891
+ if (p29.isCancel(email3)) onCancel();
4642
4892
  details.email = email3;
4643
4893
  }
4644
4894
  if (contact.includes("page")) {
4645
- const page = await p24.text({
4895
+ const page = await p29.text({
4646
4896
  message: "What's the link?",
4647
4897
  placeholder: "http://www.mycompany.com/contact",
4648
4898
  validate: (value) => {
@@ -4651,11 +4901,11 @@ async function contactMethods(type) {
4651
4901
  }
4652
4902
  }
4653
4903
  });
4654
- if (p24.isCancel(page)) onCancel();
4904
+ if (p29.isCancel(page)) onCancel();
4655
4905
  details.page = page;
4656
4906
  }
4657
4907
  if (contact.includes("phone")) {
4658
- const phone = await p24.text({
4908
+ const phone = await p29.text({
4659
4909
  message: "What's the phone number?",
4660
4910
  placeholder: "408.996.1010",
4661
4911
  validate: (value) => {
@@ -4664,11 +4914,11 @@ async function contactMethods(type) {
4664
4914
  }
4665
4915
  }
4666
4916
  });
4667
- if (p24.isCancel(phone)) onCancel();
4917
+ if (p29.isCancel(phone)) onCancel();
4668
4918
  details.phone = phone;
4669
4919
  }
4670
4920
  if (contact.includes("mail")) {
4671
- const address = await p24.text({
4921
+ const address = await p29.text({
4672
4922
  message: "What's the address?",
4673
4923
  placeholder: "767 Fifth Avenue New York, NY 10153, United States",
4674
4924
  validate: (value) => {
@@ -4677,14 +4927,14 @@ async function contactMethods(type) {
4677
4927
  }
4678
4928
  }
4679
4929
  });
4680
- if (p24.isCancel(address)) onCancel();
4930
+ if (p29.isCancel(address)) onCancel();
4681
4931
  details.address = address;
4682
4932
  }
4683
4933
  return { methods: contact, details };
4684
4934
  }
4685
4935
  var escapeHtml = (value) => String(value ?? "").replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
4686
4936
  var applyTypography = (html) => html.replaceAll("<p>", '<p class="text-base leading-7">').replaceAll("<ul>", '<ul class="list-disc pl-6 space-y-1 text-base leading-7">').replaceAll("<h3>", '<h3 class="text-lg font-semibold">').replaceAll("<h4>", '<h4 class="font-semibold">');
4687
- var list = (items) => items.length ? `<ul class="list-disc pl-6 space-y-1 text-base leading-7">${items.map((i) => `<li>${i}</li>`).join("")}</ul>` : "";
4937
+ var list2 = (items) => items.length ? `<ul class="list-disc pl-6 space-y-1 text-base leading-7">${items.map((i) => `<li>${i}</li>`).join("")}</ul>` : "";
4688
4938
  var titledSection = (title, body) => body ? `<section class="space-y-3"><h2 class="text-xl font-semibold">${escapeHtml(
4689
4939
  title
4690
4940
  )}</h2>${applyTypography(body)}</section>` : "";
@@ -4893,7 +5143,7 @@ var sectionSubscriptions = (a) => {
4893
5143
  const autoRenewalNotice = `<p><strong>Auto-renewal disclosure (California, New York, and other states).</strong> In accordance with the California Automatic Renewal Law (Cal. Bus. &amp; Prof. Code &sect; 17600 et seq.), New York General Business Law &sect; 527-a, and similar laws, you acknowledge that your subscription will continue until cancelled, that we will charge the payment method you provided on a recurring basis at the frequency described at the time of purchase, that your subscription will automatically renew unless you cancel, and that you may cancel at any time using the cancellation methods described above.</p>`;
4894
5144
  return titledSection(
4895
5145
  "Subscriptions and Automatic Renewal",
4896
- `<p>Some parts of the Service may be billed on a subscription basis.</p>${list(bullets)}${autoRenewalNotice}`
5146
+ `<p>Some parts of the Service may be billed on a subscription basis.</p>${list2(bullets)}${autoRenewalNotice}`
4897
5147
  );
4898
5148
  };
4899
5149
  var sectionPromotions = () => titledSection(
@@ -4902,7 +5152,7 @@ var sectionPromotions = () => titledSection(
4902
5152
  );
4903
5153
  var sectionProhibited = () => titledSection(
4904
5154
  "Prohibited Uses",
4905
- `<p>You agree not to use the Service:</p>${list([
5155
+ `<p>You agree not to use the Service:</p>${list2([
4906
5156
  "In any way that violates any applicable national, state, local, or international law or regulation (including, without limitation, any laws regarding the export of data or software to and from the United States or other countries).",
4907
5157
  "For the purpose of exploiting, harming, or attempting to exploit or harm minors in any way by exposing them to inappropriate content, asking for personally identifiable information, or otherwise.",
4908
5158
  'To transmit, or procure the sending of, any advertising or promotional material, including any "junk mail," "chain letter," "spam," or any other similar solicitation, without our prior written consent.',
@@ -5032,7 +5282,7 @@ var sectionContact = (a) => {
5032
5282
  if (a.contact?.methods?.includes("mail") && a.contact.details.address) {
5033
5283
  items.push(`By mail: ${escapeHtml(a.contact.details.address)}`);
5034
5284
  }
5035
- return `<section class="space-y-3"><h2 class="text-xl font-semibold">Contact Us</h2><p class="text-base leading-7">If you have any questions about these Terms, you can contact us:</p>${list(items)}</section>`;
5285
+ return `<section class="space-y-3"><h2 class="text-xl font-semibold">Contact Us</h2><p class="text-base leading-7">If you have any questions about these Terms, you can contact us:</p>${list2(items)}</section>`;
5036
5286
  };
5037
5287
  var generateTermsHtml = (answers) => {
5038
5288
  const c = compute(answers);
@@ -5073,7 +5323,7 @@ var generateTermsHtml = (answers) => {
5073
5323
  };
5074
5324
  async function termsAction() {
5075
5325
  const { workspaceRootDir, publicRoutesDir } = await getWorkspace();
5076
- const core = await p25.group(
5326
+ const core = await p30.group(
5077
5327
  {
5078
5328
  websiteUrl: sharedFields.websiteUrl,
5079
5329
  websiteName: sharedFields.websiteName,
@@ -5085,25 +5335,25 @@ async function termsAction() {
5085
5335
  },
5086
5336
  { onCancel }
5087
5337
  );
5088
- const accounts = await p25.select({
5338
+ const accounts = await p30.select({
5089
5339
  message: "Can users create accounts?",
5090
5340
  options: [
5091
5341
  { value: "yes", label: "Yes, users can create accounts" },
5092
5342
  { value: "no", label: "No" }
5093
5343
  ]
5094
5344
  });
5095
- if (p25.isCancel(accounts)) onCancel();
5096
- const userContent = await p25.select({
5345
+ if (p30.isCancel(accounts)) onCancel();
5346
+ const userContent = await p30.select({
5097
5347
  message: "Can users create and/or upload content (ie. text, images)?",
5098
5348
  options: [
5099
5349
  { value: "yes", label: "Yes, users can create and/or upload content" },
5100
5350
  { value: "no", label: "No" }
5101
5351
  ]
5102
5352
  });
5103
- if (p25.isCancel(userContent)) onCancel();
5353
+ if (p30.isCancel(userContent)) onCancel();
5104
5354
  let infringementEmail;
5105
5355
  if (userContent === "yes") {
5106
- const email3 = await p25.text({
5356
+ const email3 = await p30.text({
5107
5357
  message: "What's the email address where you will receive infringements notices?",
5108
5358
  placeholder: "dmca@website.com",
5109
5359
  validate: (value) => {
@@ -5112,10 +5362,10 @@ async function termsAction() {
5112
5362
  }
5113
5363
  }
5114
5364
  });
5115
- if (p25.isCancel(email3)) onCancel();
5365
+ if (p30.isCancel(email3)) onCancel();
5116
5366
  infringementEmail = email3;
5117
5367
  }
5118
- const canBuyGoods = await p25.select({
5368
+ const canBuyGoods = await p30.select({
5119
5369
  message: "Can users buy goods (products, items)?",
5120
5370
  options: [
5121
5371
  {
@@ -5125,28 +5375,28 @@ async function termsAction() {
5125
5375
  { value: "no", label: "No" }
5126
5376
  ]
5127
5377
  });
5128
- if (p25.isCancel(canBuyGoods)) onCancel();
5129
- const subscriptions2 = await p25.select({
5378
+ if (p30.isCancel(canBuyGoods)) onCancel();
5379
+ const subscriptions2 = await p30.select({
5130
5380
  message: "Do you offer subscription plans?",
5131
5381
  options: [
5132
5382
  { value: "yes", label: "Yes, we offer subscription plans" },
5133
5383
  { value: "no", label: "No" }
5134
5384
  ]
5135
5385
  });
5136
- if (p25.isCancel(subscriptions2)) onCancel();
5386
+ if (p30.isCancel(subscriptions2)) onCancel();
5137
5387
  let freeTrial;
5138
5388
  if (subscriptions2 === "yes") {
5139
- const ft = await p25.select({
5389
+ const ft = await p30.select({
5140
5390
  message: "Do you offer a free trial?",
5141
5391
  options: [
5142
5392
  { value: "yes", label: "Yes" },
5143
5393
  { value: "no", label: "No" }
5144
5394
  ]
5145
5395
  });
5146
- if (p25.isCancel(ft)) onCancel();
5396
+ if (p30.isCancel(ft)) onCancel();
5147
5397
  freeTrial = ft;
5148
5398
  }
5149
- const exclusiveContent = await p25.select({
5399
+ const exclusiveContent = await p30.select({
5150
5400
  message: "Do you want to make it clear that your own content & trademarks are your exclusive property?",
5151
5401
  options: [
5152
5402
  {
@@ -5156,24 +5406,24 @@ async function termsAction() {
5156
5406
  { value: "no", label: "No" }
5157
5407
  ]
5158
5408
  });
5159
- if (p25.isCancel(exclusiveContent)) onCancel();
5160
- const feedbackReuse = await p25.select({
5409
+ if (p30.isCancel(exclusiveContent)) onCancel();
5410
+ const feedbackReuse = await p30.select({
5161
5411
  message: "If users provide you feedback & suggestions, do you want to use this feedback without compensation or credits given?",
5162
5412
  options: [
5163
5413
  { value: "yes", label: "Yes, we may implement any feedback or suggestions we receive" },
5164
5414
  { value: "no", label: "No" }
5165
5415
  ]
5166
5416
  });
5167
- if (p25.isCancel(feedbackReuse)) onCancel();
5168
- const promotions = await p25.select({
5417
+ if (p30.isCancel(feedbackReuse)) onCancel();
5418
+ const promotions = await p30.select({
5169
5419
  message: "Do you plan to offer promotions, contests, sweepstakes?",
5170
5420
  options: [
5171
5421
  { value: "yes", label: "Yes, we may offer promotions, contests, sweepstakes" },
5172
5422
  { value: "no", label: "No" }
5173
5423
  ]
5174
5424
  });
5175
- if (p25.isCancel(promotions)) onCancel();
5176
- const mobileAppRaw = await p25.multiselect({
5425
+ if (p30.isCancel(promotions)) onCancel();
5426
+ const mobileAppRaw = await p30.multiselect({
5177
5427
  message: "Is the Service distributed through any mobile app stores? Check all that apply",
5178
5428
  options: [
5179
5429
  { value: "apple", label: "Apple App Store" },
@@ -5181,7 +5431,7 @@ async function termsAction() {
5181
5431
  ],
5182
5432
  required: false
5183
5433
  });
5184
- if (p25.isCancel(mobileAppRaw)) onCancel();
5434
+ if (p30.isCancel(mobileAppRaw)) onCancel();
5185
5435
  const mobileApp = mobileAppRaw ?? [];
5186
5436
  const contact = await contactMethods("terms");
5187
5437
  const html = generateTermsHtml({
@@ -5206,9 +5456,9 @@ async function termsAction() {
5206
5456
  "+page.svelte"
5207
5457
  );
5208
5458
  const termsPageTs = path21.join(workspaceRootDir, publicRoutesDir, LEGAL_DIR, "terms", "+page.ts");
5209
- fs22.mkdirSync(path21.dirname(termsPage), { recursive: true });
5210
- fs22.writeFileSync(termsPage, html);
5211
- fs22.writeFileSync(
5459
+ fs23.mkdirSync(path21.dirname(termsPage), { recursive: true });
5460
+ fs23.writeFileSync(termsPage, html);
5461
+ fs23.writeFileSync(
5212
5462
  termsPageTs,
5213
5463
  pageMetaTagsLoader("Terms of Service", `Terms of Service for ${core.websiteName}`)
5214
5464
  );
@@ -5224,13 +5474,13 @@ async function termsAction() {
5224
5474
  ]
5225
5475
  });
5226
5476
  }
5227
- var terms = new Command44("terms").description("generate placeholder terms and conditions").configureHelp(helpConfig).action(() => runCommand(termsAction, "Failed to generate terms and conditions."));
5477
+ var terms = new Command47("terms").description("generate placeholder terms and conditions").configureHelp(helpConfig).action(() => runCommand(termsAction, "Failed to generate terms and conditions."));
5228
5478
 
5229
5479
  // src/commands/legal/privacy.ts
5230
- import fs23 from "node:fs";
5480
+ import fs24 from "node:fs";
5231
5481
  import path22 from "node:path";
5232
- import { Command as Command45 } from "commander";
5233
- import * as p26 from "@clack/prompts";
5482
+ import { Command as Command48 } from "commander";
5483
+ import * as p31 from "@clack/prompts";
5234
5484
  var mapLabels = {
5235
5485
  personalInfo: {
5236
5486
  email: "Email address",
@@ -5436,7 +5686,7 @@ var sectionCategoriesCollected = (a, c) => {
5436
5686
  geolocation: pi.includes("address"),
5437
5687
  sensitive: false
5438
5688
  });
5439
- const personal = `<h4 class="font-semibold">Personal Data</h4><p class="text-base leading-7">While using our Service, we may ask you to provide us with certain personally identifiable information that can be used to contact or identify you. Personally identifiable information may include, but is not limited to:</p>${list(
5689
+ const personal = `<h4 class="font-semibold">Personal Data</h4><p class="text-base leading-7">While using our Service, we may ask you to provide us with certain personally identifiable information that can be used to contact or identify you. Personally identifiable information may include, but is not limited to:</p>${list2(
5440
5690
  (c.piLabels.length ? c.piLabels : [
5441
5691
  "Email address",
5442
5692
  "First name and last name",
@@ -5483,12 +5733,12 @@ var sectionUse = (a, c) => {
5483
5733
  "<strong>For security and fraud prevention:</strong> to protect the rights, property, or safety of the Company, our users, or others, including detecting, preventing, and responding to fraud, abuse, security risks, and technical issues.",
5484
5734
  "<strong>To comply with legal obligations:</strong> to comply with applicable laws, lawful requests, court orders, and legal processes."
5485
5735
  );
5486
- let body = `<p class="text-base leading-7">The Company may use Personal Data for the following purposes:</p>${list(useBullets)}`;
5736
+ let body = `<p class="text-base leading-7">The Company may use Personal Data for the following purposes:</p>${list2(useBullets)}`;
5487
5737
  if (a.showAds === "yes") {
5488
- body += `<p class="text-base leading-7">We may display advertising on the Service${c.adsPlatforms.length ? " using the following platforms:" : "."}</p>${c.adsPlatforms.length ? list(c.adsPlatforms.map(escapeHtml)) : ""}`;
5738
+ body += `<p class="text-base leading-7">We may display advertising on the Service${c.adsPlatforms.length ? " using the following platforms:" : "."}</p>${c.adsPlatforms.length ? list2(c.adsPlatforms.map(escapeHtml)) : ""}`;
5489
5739
  }
5490
5740
  if (a.canPay === "yes" && c.paymentProcessors.length) {
5491
- body += `<p class="text-base leading-7">If you make purchases, we may process payments via the following providers, who handle your payment information in accordance with their own privacy policies:</p>${list(
5741
+ body += `<p class="text-base leading-7">If you make purchases, we may process payments via the following providers, who handle your payment information in accordance with their own privacy policies:</p>${list2(
5492
5742
  c.paymentProcessors.map(escapeHtml)
5493
5743
  )}`;
5494
5744
  }
@@ -5506,7 +5756,7 @@ var sectionShare = (a, c) => {
5506
5756
  body += "<li><strong>With your consent:</strong> for any other purpose with your consent.</li>";
5507
5757
  body += "</ul>";
5508
5758
  if (c.providers.length) {
5509
- body += `<p>We currently use the following service providers:</p>${list(c.providers.map(escapeHtml))}`;
5759
+ body += `<p>We currently use the following service providers:</p>${list2(c.providers.map(escapeHtml))}`;
5510
5760
  }
5511
5761
  void a;
5512
5762
  return titledSection("How We Share or Disclose Personal Information", body);
@@ -5517,7 +5767,7 @@ var sectionSaleSharing = (a, c) => {
5517
5767
  let recipients = "";
5518
5768
  if (sells) {
5519
5769
  const partners = [...c.adsPlatforms, ...c.remarketingPlatforms];
5520
- const list_ = partners.length ? `<p>The categories of third parties to which we may disclose personal information for these purposes include advertising networks, analytics providers, and marketing partners, including:</p>${list(
5770
+ const list_ = partners.length ? `<p>The categories of third parties to which we may disclose personal information for these purposes include advertising networks, analytics providers, and marketing partners, including:</p>${list2(
5521
5771
  partners.map(escapeHtml)
5522
5772
  )}` : "<p>The categories of third parties to which we may disclose personal information for these purposes include advertising networks, analytics providers, social media platforms, and marketing partners.</p>";
5523
5773
  recipients = list_;
@@ -5531,20 +5781,20 @@ var sectionSaleSharing = (a, c) => {
5531
5781
  var sectionCookies = (a, c) => {
5532
5782
  let body = `<p>We use Cookies and similar tracking technologies (such as web beacons, pixels, tags, scripts, and software development kits) to track the activity on our Service and hold certain information.</p><p>Cookies can be "Persistent" or "Session" Cookies. Persistent Cookies remain on your personal computer or mobile device when you go offline, while Session Cookies are deleted as soon as you close your web browser.</p><h4>Categories of Cookies We Use</h4><ul><li><strong>Strictly Necessary Cookies.</strong> These are required for the operation of the Service and to provide functionalities you request, such as logging in or accessing secure areas. The Service cannot function properly without them.</li><li><strong>Performance / Analytics Cookies.</strong> These cookies allow us to count visits and traffic sources so we can measure and improve the performance of the Service.</li><li><strong>Functional Cookies.</strong> These cookies enable enhanced functionality and personalization, such as remembering your preferences.</li><li><strong>Targeting / Advertising Cookies.</strong> These cookies may be set through our Service by our advertising partners to build a profile of your interests and show you relevant advertisements on other sites.</li><li><strong>Cookies Policy / Notice Acceptance Cookies.</strong> These cookies identify whether users have accepted the use of cookies on the Service.</li></ul>`;
5533
5783
  if (a.tracking === "yes" && c.trackingTools.length) {
5534
- body += `<p>We currently use the following analytics and tracking tools:</p>${list(c.trackingTools.map(escapeHtml))}`;
5784
+ body += `<p>We currently use the following analytics and tracking tools:</p>${list2(c.trackingTools.map(escapeHtml))}`;
5535
5785
  }
5536
5786
  body += `<h4>Your Choices About Cookies</h4><p>You can instruct your browser to refuse all Cookies or to indicate when a Cookie is being sent. If you do not accept Cookies, you may not be able to use some parts of our Service. You can also manage your cookie preferences through any cookie banner or preference center we provide.</p><h4>Do Not Track and Global Privacy Control</h4><p>Some browsers transmit "Do Not Track" ("DNT") or Global Privacy Control ("GPC") signals. There is currently no industry standard for responding to DNT signals, but we honor GPC signals as an opt-out of the sale or sharing of personal information for the browser or device on which the signal is detected, as required by applicable law.</p>`;
5537
5787
  return titledSection("Tracking Technologies and Cookies", body);
5538
5788
  };
5539
5789
  var sectionEmail = (a, c) => a.sendEmails === "yes" ? titledSection(
5540
5790
  "Email Communications",
5541
- c.emailPlatforms.length ? `<p>We may send transactional, account-related, and (where you have opted in) marketing emails using the following platforms, who process email information on our behalf as service providers:</p>${list(
5791
+ c.emailPlatforms.length ? `<p>We may send transactional, account-related, and (where you have opted in) marketing emails using the following platforms, who process email information on our behalf as service providers:</p>${list2(
5542
5792
  c.emailPlatforms.map(escapeHtml)
5543
5793
  )}<p>You may unsubscribe from marketing emails at any time using the unsubscribe link included in those emails. Even if you unsubscribe from marketing emails, we may still send you transactional or account-related emails (for example, to confirm a purchase or notify you of changes to the Service).</p>` : "<p>We may send you transactional, account-related, and (where you have opted in) marketing emails. You may unsubscribe from marketing emails at any time using the unsubscribe link included in those emails.</p>"
5544
5794
  ) : "";
5545
5795
  var sectionRemarketing = (a, c) => a.remarketing === "yes" ? titledSection(
5546
5796
  "Remarketing and Targeted Advertising",
5547
- c.remarketingPlatforms.length ? `<p>We use remarketing services to advertise to visitors of our Service on third-party websites and applications after they have visited the Service. These services may use cookies and similar technologies to deliver advertisements based on your past visits. The remarketing services we use include:</p>${list(
5797
+ c.remarketingPlatforms.length ? `<p>We use remarketing services to advertise to visitors of our Service on third-party websites and applications after they have visited the Service. These services may use cookies and similar technologies to deliver advertisements based on your past visits. The remarketing services we use include:</p>${list2(
5548
5798
  c.remarketingPlatforms.map(escapeHtml)
5549
5799
  )}<p>You may opt out of personalized advertising by visiting the Network Advertising Initiative opt-out page (<a href="https://www.networkadvertising.org/choices/" rel="external nofollow noopener" target="_blank">https://www.networkadvertising.org/choices/</a>), the Digital Advertising Alliance opt-out page (<a href="https://www.aboutads.info/choices/" rel="external nofollow noopener" target="_blank">https://www.aboutads.info/choices/</a>), or the European Interactive Digital Advertising Alliance (<a href="https://www.youronlinechoices.eu" rel="external nofollow noopener" target="_blank">https://www.youronlinechoices.eu</a>).</p>` : "<p>We use remarketing services to advertise to visitors of our Service on third-party websites and applications after they have visited the Service.</p>"
5550
5800
  ) : "";
@@ -5619,7 +5869,7 @@ var sectionContact2 = (a) => {
5619
5869
  if (a.contact?.methods?.includes("mail") && a.contact.details.address) {
5620
5870
  items.push(`By mail: ${escapeHtml(a.contact.details.address)}`);
5621
5871
  }
5622
- return `<section class="space-y-3"><h2 class="text-xl font-semibold">Contact Us</h2><p class="text-base leading-7">If you have any questions about this Privacy Policy, you can contact us:</p>${list(items)}</section>`;
5872
+ return `<section class="space-y-3"><h2 class="text-xl font-semibold">Contact Us</h2><p class="text-base leading-7">If you have any questions about this Privacy Policy, you can contact us:</p>${list2(items)}</section>`;
5623
5873
  };
5624
5874
  var generatePrivacyHtml = (answers) => {
5625
5875
  const c = compute2(answers);
@@ -5648,12 +5898,12 @@ var generatePrivacyHtml = (answers) => {
5648
5898
  return `<section data-role="content">${sections.join("")}</section>`;
5649
5899
  };
5650
5900
  async function promptWithCustom(message, options, customMessage) {
5651
- const selection = await p26.multiselect({ message, options });
5652
- if (p26.isCancel(selection)) onCancel();
5901
+ const selection = await p31.multiselect({ message, options });
5902
+ if (p31.isCancel(selection)) onCancel();
5653
5903
  const values = selection;
5654
5904
  if (values.includes("custom")) {
5655
- const custom = await p26.text({ message: customMessage });
5656
- if (p26.isCancel(custom)) onCancel();
5905
+ const custom = await p31.text({ message: customMessage });
5906
+ if (p31.isCancel(custom)) onCancel();
5657
5907
  const idx = values.indexOf("custom");
5658
5908
  if (idx !== -1) values.splice(idx, 1);
5659
5909
  if (custom) values.push(String(custom));
@@ -5662,7 +5912,7 @@ async function promptWithCustom(message, options, customMessage) {
5662
5912
  }
5663
5913
  async function privacyAction() {
5664
5914
  const { workspaceRootDir, publicRoutesDir } = await getWorkspace();
5665
- const core = await p26.group(
5915
+ const core = await p31.group(
5666
5916
  {
5667
5917
  websiteUrl: sharedFields.websiteUrl,
5668
5918
  websiteName: sharedFields.websiteName,
@@ -5674,7 +5924,7 @@ async function privacyAction() {
5674
5924
  },
5675
5925
  { onCancel }
5676
5926
  );
5677
- const personalInfo = await p26.multiselect({
5927
+ const personalInfo = await p31.multiselect({
5678
5928
  message: "What kind of personal information do you collect from users? Check all that apply",
5679
5929
  options: [
5680
5930
  { value: "email", label: "Email address" },
@@ -5689,16 +5939,16 @@ async function privacyAction() {
5689
5939
  ],
5690
5940
  required: false
5691
5941
  });
5692
- if (p26.isCancel(personalInfo)) onCancel();
5942
+ if (p31.isCancel(personalInfo)) onCancel();
5693
5943
  const contact = await contactMethods("privacy");
5694
- const tracking = await p26.select({
5944
+ const tracking = await p31.select({
5695
5945
  message: "Do you use tracking and/or analytics tools, such as Google Analytics?",
5696
5946
  options: [
5697
5947
  { value: "yes", label: "Yes, we use Google Analytics or other related tools" },
5698
5948
  { value: "no", label: "No" }
5699
5949
  ]
5700
5950
  });
5701
- if (p26.isCancel(tracking)) onCancel();
5951
+ if (p31.isCancel(tracking)) onCancel();
5702
5952
  let trackingTools;
5703
5953
  if (tracking === "yes") {
5704
5954
  trackingTools = await promptWithCustom(
@@ -5717,7 +5967,7 @@ async function privacyAction() {
5717
5967
  "Enter your custom tracking/analytics tool name"
5718
5968
  );
5719
5969
  }
5720
- const sendEmails = await p26.select({
5970
+ const sendEmails = await p31.select({
5721
5971
  message: "Do you send emails to users?",
5722
5972
  options: [
5723
5973
  {
@@ -5727,7 +5977,7 @@ async function privacyAction() {
5727
5977
  { value: "no", label: "No" }
5728
5978
  ]
5729
5979
  });
5730
- if (p26.isCancel(sendEmails)) onCancel();
5980
+ if (p31.isCancel(sendEmails)) onCancel();
5731
5981
  let emailPlatforms;
5732
5982
  if (sendEmails === "yes") {
5733
5983
  emailPlatforms = await promptWithCustom(
@@ -5742,14 +5992,14 @@ async function privacyAction() {
5742
5992
  "Enter your custom email platform"
5743
5993
  );
5744
5994
  }
5745
- const showAds = await p26.select({
5995
+ const showAds = await p31.select({
5746
5996
  message: "Do you show ads?",
5747
5997
  options: [
5748
5998
  { value: "yes", label: "Yes, we show ads" },
5749
5999
  { value: "no", label: "No" }
5750
6000
  ]
5751
6001
  });
5752
- if (p26.isCancel(showAds)) onCancel();
6002
+ if (p31.isCancel(showAds)) onCancel();
5753
6003
  let adsPlatforms;
5754
6004
  if (showAds === "yes") {
5755
6005
  adsPlatforms = await promptWithCustom(
@@ -5772,7 +6022,7 @@ async function privacyAction() {
5772
6022
  "Enter your custom ads platform"
5773
6023
  );
5774
6024
  }
5775
- const canPay = await p26.select({
6025
+ const canPay = await p31.select({
5776
6026
  message: "Can users pay for products or services?",
5777
6027
  options: [
5778
6028
  { value: "yes", label: "Yes, users can pay for our products/services" },
@@ -5782,7 +6032,7 @@ async function privacyAction() {
5782
6032
  }
5783
6033
  ]
5784
6034
  });
5785
- if (p26.isCancel(canPay)) onCancel();
6035
+ if (p31.isCancel(canPay)) onCancel();
5786
6036
  let paymentProcessors;
5787
6037
  if (canPay === "yes") {
5788
6038
  paymentProcessors = await promptWithCustom(
@@ -5813,14 +6063,14 @@ async function privacyAction() {
5813
6063
  "Enter your custom payment processor/method"
5814
6064
  );
5815
6065
  }
5816
- const remarketing = await p26.select({
6066
+ const remarketing = await p31.select({
5817
6067
  message: "Do you use remarketing services for marketing & advertising purposes?",
5818
6068
  options: [
5819
6069
  { value: "yes", label: "Yes, we use remarketing services to advertise our business" },
5820
6070
  { value: "no", label: "No" }
5821
6071
  ]
5822
6072
  });
5823
- if (p26.isCancel(remarketing)) onCancel();
6073
+ if (p31.isCancel(remarketing)) onCancel();
5824
6074
  let remarketingPlatforms;
5825
6075
  if (remarketing === "yes") {
5826
6076
  remarketingPlatforms = await promptWithCustom(
@@ -5839,7 +6089,7 @@ async function privacyAction() {
5839
6089
  "Enter your custom remarketing platform"
5840
6090
  );
5841
6091
  }
5842
- const providersRaw = await p26.multiselect({
6092
+ const providersRaw = await p31.multiselect({
5843
6093
  message: "Select if you use any of the following providers",
5844
6094
  options: [
5845
6095
  { value: "recaptcha", label: "Invisible reCAPTCHA" },
@@ -5850,16 +6100,16 @@ async function privacyAction() {
5850
6100
  ],
5851
6101
  required: false
5852
6102
  });
5853
- if (p26.isCancel(providersRaw)) onCancel();
6103
+ if (p31.isCancel(providersRaw)) onCancel();
5854
6104
  const providers = providersRaw;
5855
6105
  if (providers.includes("custom")) {
5856
- const custom = await p26.text({ message: "Enter your custom provider" });
5857
- if (p26.isCancel(custom)) onCancel();
6106
+ const custom = await p31.text({ message: "Enter your custom provider" });
6107
+ if (p31.isCancel(custom)) onCancel();
5858
6108
  const idx = providers.indexOf("custom");
5859
6109
  if (idx !== -1) providers.splice(idx, 1);
5860
6110
  if (custom) providers.push(String(custom));
5861
6111
  }
5862
- const usStates = await p26.select({
6112
+ const usStates = await p31.select({
5863
6113
  message: "Include U.S. state privacy rights (CCPA/CPRA, VCDPA, CPA, CTDPA, UCPA, TX, OR, etc.)?",
5864
6114
  options: [
5865
6115
  {
@@ -5870,55 +6120,55 @@ async function privacyAction() {
5870
6120
  ],
5871
6121
  initialValue: "yes"
5872
6122
  });
5873
- if (p26.isCancel(usStates)) onCancel();
5874
- const gdpr = await p26.select({
6123
+ if (p31.isCancel(usStates)) onCancel();
6124
+ const gdpr = await p31.select({
5875
6125
  message: "Do you want your Privacy Policy to include GDPR / UK GDPR wording?",
5876
6126
  options: [
5877
6127
  { value: "yes", label: "Yes. Include GDPR rights for EEA, UK, and Swiss residents" },
5878
6128
  { value: "no", label: "No" }
5879
6129
  ]
5880
6130
  });
5881
- if (p26.isCancel(gdpr)) onCancel();
6131
+ if (p31.isCancel(gdpr)) onCancel();
5882
6132
  let facebookFanPage = "no";
5883
6133
  const facebookDetails = { name: "", url: "" };
5884
6134
  if (gdpr === "yes") {
5885
- const fan = await p26.select({
6135
+ const fan = await p31.select({
5886
6136
  message: "Do you have a Facebook Fan Page?",
5887
6137
  options: [
5888
6138
  { value: "yes", label: "Yes, we have a Facebook Fan Page" },
5889
6139
  { value: "no", label: "No" }
5890
6140
  ]
5891
6141
  });
5892
- if (p26.isCancel(fan)) onCancel();
6142
+ if (p31.isCancel(fan)) onCancel();
5893
6143
  facebookFanPage = fan;
5894
6144
  if (facebookFanPage === "yes") {
5895
- const name = await p26.text({
6145
+ const name = await p31.text({
5896
6146
  message: "What is the name of the Facebook Fan Page?",
5897
6147
  placeholder: "My Facebook Page"
5898
6148
  });
5899
- if (p26.isCancel(name)) onCancel();
6149
+ if (p31.isCancel(name)) onCancel();
5900
6150
  facebookDetails.name = name;
5901
- const url = await p26.text({
6151
+ const url = await p31.text({
5902
6152
  message: "What is the URL of the Facebook Fan Page?",
5903
6153
  placeholder: "https://facebook.com/my-facebook-page"
5904
6154
  });
5905
- if (p26.isCancel(url)) onCancel();
6155
+ if (p31.isCancel(url)) onCancel();
5906
6156
  facebookDetails.url = url;
5907
6157
  }
5908
6158
  }
5909
- const kids = await p26.select({
6159
+ const kids = await p31.select({
5910
6160
  message: "Do you collect information from kids under the age of 13?",
5911
6161
  options: [
5912
6162
  { value: "yes", label: "Yes. We collect information from children under the age of 13" },
5913
6163
  { value: "no", label: "No" }
5914
6164
  ]
5915
6165
  });
5916
- if (p26.isCancel(kids)) onCancel();
5917
- const retention = await p26.text({
6166
+ if (p31.isCancel(kids)) onCancel();
6167
+ const retention = await p31.text({
5918
6168
  message: "How long do you retain personal information? (leave blank for default wording)",
5919
6169
  placeholder: "e.g. 12 months after account closure"
5920
6170
  });
5921
- if (p26.isCancel(retention)) onCancel();
6171
+ if (p31.isCancel(retention)) onCancel();
5922
6172
  const html = generatePrivacyHtml({
5923
6173
  core,
5924
6174
  personalInfo: personalInfo ?? [],
@@ -5955,9 +6205,9 @@ async function privacyAction() {
5955
6205
  "privacy",
5956
6206
  "+page.ts"
5957
6207
  );
5958
- fs23.mkdirSync(path22.dirname(privacyPage), { recursive: true });
5959
- fs23.writeFileSync(privacyPage, html);
5960
- fs23.writeFileSync(
6208
+ fs24.mkdirSync(path22.dirname(privacyPage), { recursive: true });
6209
+ fs24.writeFileSync(privacyPage, html);
6210
+ fs24.writeFileSync(
5961
6211
  privacyPageTs,
5962
6212
  pageMetaTagsLoader("Privacy Policy", `Privacy Policy for ${core.websiteName}`)
5963
6213
  );
@@ -5973,19 +6223,19 @@ async function privacyAction() {
5973
6223
  ]
5974
6224
  });
5975
6225
  }
5976
- var privacy = new Command45("privacy").description("generate placeholder privacy policy").configureHelp(helpConfig).action(() => runCommand(privacyAction, "Failed to generate privacy policy."));
6226
+ var privacy = new Command48("privacy").description("generate placeholder privacy policy").configureHelp(helpConfig).action(() => runCommand(privacyAction, "Failed to generate privacy policy."));
5977
6227
 
5978
6228
  // src/commands/legal.ts
5979
- var legal = new Command46("legal").description("generate placeholder legal documents").configureHelp(helpConfig).addCommand(terms).addCommand(privacy);
6229
+ var legal = new Command49("legal").description("generate placeholder legal documents").configureHelp(helpConfig).addCommand(terms).addCommand(privacy);
5980
6230
 
5981
6231
  // src/commands/fixtures.ts
5982
- import { Command as Command52 } from "commander";
6232
+ import { Command as Command55 } from "commander";
5983
6233
 
5984
6234
  // src/commands/fixtures/load.ts
5985
- import { Command as Command47 } from "commander";
6235
+ import { Command as Command50 } from "commander";
5986
6236
 
5987
6237
  // src/lib/data.ts
5988
- import fs24 from "node:fs";
6238
+ import fs25 from "node:fs";
5989
6239
  import path23 from "node:path";
5990
6240
  import { ClientResponseError } from "pocketbase";
5991
6241
 
@@ -6027,8 +6277,8 @@ function dataDir(cwd, kind) {
6027
6277
  }
6028
6278
  function getDataFiles(cwd, kind) {
6029
6279
  const dir = dataDir(cwd, kind);
6030
- if (!fs24.existsSync(dir)) return [];
6031
- return fs24.readdirSync(dir).filter((file) => file.endsWith(".json")).sort((a, b) => a.localeCompare(b)).map((file) => ({
6280
+ if (!fs25.existsSync(dir)) return [];
6281
+ return fs25.readdirSync(dir).filter((file) => file.endsWith(".json")).sort((a, b) => a.localeCompare(b)).map((file) => ({
6032
6282
  collectionName: file.replace(/\.json$/i, "").replace(/^\d+[-_]?/, ""),
6033
6283
  filePath: path23.join(dir, file)
6034
6284
  }));
@@ -6040,16 +6290,16 @@ function getFixtureFiles(cwd) {
6040
6290
  return getDataFiles(cwd, "fixtures");
6041
6291
  }
6042
6292
  function readRecords(filePath) {
6043
- return JSON.parse(fs24.readFileSync(filePath, "utf8"));
6293
+ return JSON.parse(fs25.readFileSync(filePath, "utf8"));
6044
6294
  }
6045
6295
  function readSeedIds(cwd) {
6046
6296
  const ids = /* @__PURE__ */ new Map();
6047
6297
  for (const { collectionName, filePath } of getSeedFiles(cwd)) {
6048
- const list2 = ids.get(collectionName) ?? [];
6298
+ const list3 = ids.get(collectionName) ?? [];
6049
6299
  for (const record of readRecords(filePath)) {
6050
- if (typeof record.id === "string" && record.id) list2.push(record.id);
6300
+ if (typeof record.id === "string" && record.id) list3.push(record.id);
6051
6301
  }
6052
- ids.set(collectionName, list2);
6302
+ ids.set(collectionName, list3);
6053
6303
  }
6054
6304
  return ids;
6055
6305
  }
@@ -6172,7 +6422,7 @@ async function hasLoadedFixtures(pb) {
6172
6422
  }
6173
6423
 
6174
6424
  // src/commands/fixtures/load.ts
6175
- var load = new Command47("load").description("load fixtures into the database").configureHelp(helpConfig).action(
6425
+ var load = new Command50("load").description("load fixtures into the database").configureHelp(helpConfig).action(
6176
6426
  () => runCommand(async () => {
6177
6427
  const { workspaceRootDir } = await getWorkspace();
6178
6428
  let loaded = [];
@@ -6198,8 +6448,8 @@ var load = new Command47("load").description("load fixtures into the database").
6198
6448
  );
6199
6449
 
6200
6450
  // src/commands/fixtures/clear.ts
6201
- import { Command as Command48 } from "commander";
6202
- var clear = new Command48("clear").description("clear loaded fixtures").configureHelp(helpConfig).action(
6451
+ import { Command as Command51 } from "commander";
6452
+ var clear = new Command51("clear").description("clear loaded fixtures").configureHelp(helpConfig).action(
6203
6453
  () => runCommand(async () => {
6204
6454
  const { workspaceRootDir } = await getWorkspace();
6205
6455
  let cleared = [];
@@ -6228,8 +6478,8 @@ var clear = new Command48("clear").description("clear loaded fixtures").configur
6228
6478
  );
6229
6479
 
6230
6480
  // src/commands/fixtures/reset.ts
6231
- import { Command as Command49 } from "commander";
6232
- var reset = new Command49("reset").description("clear and reload fixtures").configureHelp(helpConfig).action(
6481
+ import { Command as Command52 } from "commander";
6482
+ var reset = new Command52("reset").description("clear and reload fixtures").configureHelp(helpConfig).action(
6233
6483
  () => runCommand(async () => {
6234
6484
  const { workspaceRootDir } = await getWorkspace();
6235
6485
  let cleared = [];
@@ -6259,10 +6509,10 @@ var reset = new Command49("reset").description("clear and reload fixtures").conf
6259
6509
  );
6260
6510
 
6261
6511
  // src/commands/fixtures/generate.ts
6262
- import fs25 from "node:fs";
6512
+ import fs26 from "node:fs";
6263
6513
  import path24 from "node:path";
6264
- import { Command as Command50, InvalidArgumentError as InvalidArgumentError2 } from "commander";
6265
- import * as p27 from "@clack/prompts";
6514
+ import { Command as Command53, InvalidArgumentError } from "commander";
6515
+ import * as p32 from "@clack/prompts";
6266
6516
  import { annotate } from "annotate-json-schema";
6267
6517
  import { createGenerator } from "json-schema-faker";
6268
6518
  import { faker } from "@faker-js/faker";
@@ -6275,20 +6525,20 @@ function padZeros(num, length) {
6275
6525
  function parseCount(value) {
6276
6526
  const n = parseInt(value, 10);
6277
6527
  if (!Number.isFinite(n) || n <= 0 || n > 999) {
6278
- throw new InvalidArgumentError2("count must be between 1 and 999");
6528
+ throw new InvalidArgumentError("count must be between 1 and 999");
6279
6529
  }
6280
6530
  return n;
6281
6531
  }
6282
6532
  function parseSeed(value) {
6283
6533
  const n = parseInt(value, 10);
6284
6534
  if (!Number.isFinite(n)) {
6285
- throw new InvalidArgumentError2("seed must be an integer");
6535
+ throw new InvalidArgumentError("seed must be an integer");
6286
6536
  }
6287
6537
  return n;
6288
6538
  }
6289
6539
  async function loadCollections(pb) {
6290
- const list2 = await pb.collections.getFullList();
6291
- return list2.map((c) => ({
6540
+ const list3 = await pb.collections.getFullList();
6541
+ return list3.map((c) => ({
6292
6542
  id: c.id,
6293
6543
  name: c.name,
6294
6544
  type: c.type,
@@ -6297,9 +6547,9 @@ async function loadCollections(pb) {
6297
6547
  }
6298
6548
  async function generateFixtureFiles(pb, workspaceRootDir, opts) {
6299
6549
  const fixturesDir = dataDir(workspaceRootDir, "fixtures");
6300
- fs25.mkdirSync(fixturesDir, { recursive: true });
6301
- for (const file of fs25.readdirSync(fixturesDir)) {
6302
- if (file.endsWith(".json")) fs25.unlinkSync(path24.join(fixturesDir, file));
6550
+ fs26.mkdirSync(fixturesDir, { recursive: true });
6551
+ for (const file of fs26.readdirSync(fixturesDir)) {
6552
+ if (file.endsWith(".json")) fs26.unlinkSync(path24.join(fixturesDir, file));
6303
6553
  }
6304
6554
  if (opts.seed !== void 0) faker.seed(opts.seed);
6305
6555
  const generator = createGenerator({
@@ -6366,13 +6616,13 @@ async function generateFixtureFiles(pb, workspaceRootDir, opts) {
6366
6616
  items.push(record);
6367
6617
  }
6368
6618
  const filename = `${padZeros(fileIndex, 2)}-${collection.name}.json`;
6369
- fs25.writeFileSync(path24.join(fixturesDir, filename), JSON.stringify(items, null, 2));
6619
+ fs26.writeFileSync(path24.join(fixturesDir, filename), JSON.stringify(items, null, 2));
6370
6620
  writtenFiles.push(`${path24.join(DATA_DIR, "fixtures", filename)} (${items.length} records)`);
6371
6621
  fileIndex++;
6372
6622
  }
6373
6623
  return { writtenFiles, warnings };
6374
6624
  }
6375
- var generate2 = new Command50("generate").description("generate fixture data").option("-c, --count <count>", "number of records per collection", parseCount, 10).option("-s, --seed <seed>", "seed for deterministic output", parseSeed).option("-f, --force", "overwrite existing fixture files and clear loaded fixtures").configureHelp(helpConfig).action(
6625
+ var generate2 = new Command53("generate").description("generate fixture data").option("-c, --count <count>", "number of records per collection", parseCount, 10).option("-s, --seed <seed>", "seed for deterministic output", parseSeed).option("-f, --force", "overwrite existing fixture files and clear loaded fixtures").configureHelp(helpConfig).action(
6376
6626
  (opts) => runCommand(async () => {
6377
6627
  const { workspaceRootDir } = await getWorkspace();
6378
6628
  const existing = getFixtureFiles(workspaceRootDir);
@@ -6401,7 +6651,7 @@ var generate2 = new Command50("generate").description("generate fixture data").o
6401
6651
  seed: opts.seed
6402
6652
  });
6403
6653
  });
6404
- for (const warning of result.warnings) p27.log.warn(warning);
6654
+ for (const warning of result.warnings) p32.log.warn(warning);
6405
6655
  if (result.writtenFiles.length === 0) {
6406
6656
  reportResult({
6407
6657
  summary: "No eligible collections found to generate fixtures for.",
@@ -6425,23 +6675,23 @@ var generate2 = new Command50("generate").description("generate fixture data").o
6425
6675
  );
6426
6676
 
6427
6677
  // src/commands/fixtures/regen.ts
6428
- import { Command as Command51, InvalidArgumentError as InvalidArgumentError3 } from "commander";
6429
- import * as p28 from "@clack/prompts";
6678
+ import { Command as Command54, InvalidArgumentError as InvalidArgumentError2 } from "commander";
6679
+ import * as p33 from "@clack/prompts";
6430
6680
  function parseCount2(value) {
6431
6681
  const n = parseInt(value, 10);
6432
6682
  if (!Number.isFinite(n) || n <= 0 || n > 999) {
6433
- throw new InvalidArgumentError3("count must be between 1 and 999");
6683
+ throw new InvalidArgumentError2("count must be between 1 and 999");
6434
6684
  }
6435
6685
  return n;
6436
6686
  }
6437
6687
  function parseSeed2(value) {
6438
6688
  const n = parseInt(value, 10);
6439
6689
  if (!Number.isFinite(n)) {
6440
- throw new InvalidArgumentError3("seed must be an integer");
6690
+ throw new InvalidArgumentError2("seed must be an integer");
6441
6691
  }
6442
6692
  return n;
6443
6693
  }
6444
- var regen = new Command51("regen").description("clear the database, regenerate fixture files, and reload them").option("-c, --count <count>", "number of records per collection", parseCount2, 10).option("-s, --seed <seed>", "seed for deterministic output", parseSeed2).configureHelp(helpConfig).action(
6694
+ var regen = new Command54("regen").description("clear the database, regenerate fixture files, and reload them").option("-c, --count <count>", "number of records per collection", parseCount2, 10).option("-s, --seed <seed>", "seed for deterministic output", parseSeed2).configureHelp(helpConfig).action(
6445
6695
  (opts) => runCommand(async () => {
6446
6696
  const { workspaceRootDir } = await getWorkspace();
6447
6697
  let cleared = [];
@@ -6455,7 +6705,7 @@ var regen = new Command51("regen").description("clear the database, regenerate f
6455
6705
  });
6456
6706
  loaded = await loadFixtures(pb, workspaceRootDir);
6457
6707
  });
6458
- for (const warning of result.warnings) p28.log.warn(warning);
6708
+ for (const warning of result.warnings) p33.log.warn(warning);
6459
6709
  reportResult({
6460
6710
  summary: `Regenerated fixtures (${loaded.length} collection(s) reloaded).`,
6461
6711
  filesCreated: result.writtenFiles,
@@ -6470,14 +6720,14 @@ var regen = new Command51("regen").description("clear the database, regenerate f
6470
6720
  );
6471
6721
 
6472
6722
  // src/commands/fixtures.ts
6473
- var fixtures = new Command52("fixtures").description("manage fixture data").configureHelp(helpConfig).addCommand(generate2).addCommand(load).addCommand(clear).addCommand(reset).addCommand(regen);
6723
+ var fixtures = new Command55("fixtures").description("manage fixture data").configureHelp(helpConfig).addCommand(generate2).addCommand(load).addCommand(clear).addCommand(reset).addCommand(regen);
6474
6724
 
6475
6725
  // src/commands/seeds.ts
6476
- import { Command as Command56 } from "commander";
6726
+ import { Command as Command59 } from "commander";
6477
6727
 
6478
6728
  // src/commands/seeds/load.ts
6479
- import { Command as Command53 } from "commander";
6480
- var load2 = new Command53("load").description("load seeds into the database").option("-f, --force", "load even if target collections already have records").configureHelp(helpConfig).action(
6729
+ import { Command as Command56 } from "commander";
6730
+ var load2 = new Command56("load").description("load seeds into the database").option("-f, --force", "load even if target collections already have records").configureHelp(helpConfig).action(
6481
6731
  (opts) => runCommand(async () => {
6482
6732
  const { workspaceRootDir } = await getWorkspace();
6483
6733
  const seedFiles = getSeedFiles(workspaceRootDir);
@@ -6514,9 +6764,9 @@ var load2 = new Command53("load").description("load seeds into the database").op
6514
6764
  );
6515
6765
 
6516
6766
  // src/commands/seeds/save.ts
6517
- import fs26 from "node:fs";
6767
+ import fs27 from "node:fs";
6518
6768
  import path25 from "node:path";
6519
- import { Command as Command54 } from "commander";
6769
+ import { Command as Command57 } from "commander";
6520
6770
  var padZeros2 = (num, length) => num.toString().padStart(length, "0");
6521
6771
  function filterSystemFields(record, systemFieldNames) {
6522
6772
  const out = {};
@@ -6527,7 +6777,7 @@ function filterSystemFields(record, systemFieldNames) {
6527
6777
  }
6528
6778
  return out;
6529
6779
  }
6530
- var save = new Command54("save").description("save the current data as seeds").option("-f, --force", "overwrite existing seed files").configureHelp(helpConfig).action(
6780
+ var save = new Command57("save").description("save the current data as seeds").option("-f, --force", "overwrite existing seed files").configureHelp(helpConfig).action(
6531
6781
  (opts) => runCommand(async () => {
6532
6782
  const { workspaceRootDir } = await getWorkspace();
6533
6783
  const seedsPath = dataDir(workspaceRootDir, "seeds");
@@ -6535,10 +6785,10 @@ var save = new Command54("save").description("save the current data as seeds").o
6535
6785
  if (existing.length > 0 && !opts.force) {
6536
6786
  throw new Error("Existing seed files found in data/seeds. Pass --force to overwrite.");
6537
6787
  }
6538
- fs26.mkdirSync(seedsPath, { recursive: true });
6788
+ fs27.mkdirSync(seedsPath, { recursive: true });
6539
6789
  if (opts.force) {
6540
- for (const file of fs26.readdirSync(seedsPath)) {
6541
- if (file.endsWith(".json")) fs26.unlinkSync(path25.join(seedsPath, file));
6790
+ for (const file of fs27.readdirSync(seedsPath)) {
6791
+ if (file.endsWith(".json")) fs27.unlinkSync(path25.join(seedsPath, file));
6542
6792
  }
6543
6793
  }
6544
6794
  const saved = [];
@@ -6573,7 +6823,7 @@ var save = new Command54("save").description("save the current data as seeds").o
6573
6823
  `${padZeros2(count, 2)}-${collectionName}.json`
6574
6824
  );
6575
6825
  const seedPath = path25.join(workspaceRootDir, relativeSeedPath);
6576
- fs26.writeFileSync(seedPath, JSON.stringify(filtered, null, 2));
6826
+ fs27.writeFileSync(seedPath, JSON.stringify(filtered, null, 2));
6577
6827
  saved.push(`${relativeSeedPath} (${filtered.length} records)`);
6578
6828
  count++;
6579
6829
  }
@@ -6599,8 +6849,8 @@ var save = new Command54("save").description("save the current data as seeds").o
6599
6849
  );
6600
6850
 
6601
6851
  // src/commands/seeds/clear.ts
6602
- import { Command as Command55 } from "commander";
6603
- var clear2 = new Command55("clear").description("clear seeded records").configureHelp(helpConfig).action(
6852
+ import { Command as Command58 } from "commander";
6853
+ var clear2 = new Command58("clear").description("clear seeded records").configureHelp(helpConfig).action(
6604
6854
  () => runCommand(async () => {
6605
6855
  const { workspaceRootDir } = await getWorkspace();
6606
6856
  const seedFiles = getSeedFiles(workspaceRootDir);
@@ -6631,23 +6881,23 @@ var clear2 = new Command55("clear").description("clear seeded records").configur
6631
6881
  );
6632
6882
 
6633
6883
  // src/commands/seeds.ts
6634
- var seeds = new Command56("seeds").description("manage seed data").configureHelp(helpConfig).addCommand(load2).addCommand(save).addCommand(clear2);
6884
+ var seeds = new Command59("seeds").description("manage seed data").configureHelp(helpConfig).addCommand(load2).addCommand(save).addCommand(clear2);
6635
6885
 
6636
6886
  // src/commands/signup.ts
6637
- import { Command as Command58 } from "commander";
6638
- import * as p30 from "@clack/prompts";
6887
+ import { Command as Command61 } from "commander";
6888
+ import * as p35 from "@clack/prompts";
6639
6889
  import makeFetchCookie2 from "fetch-cookie";
6640
6890
 
6641
6891
  // src/commands/login.ts
6642
6892
  import os3 from "node:os";
6643
- import { Command as Command57 } from "commander";
6644
- import * as p29 from "@clack/prompts";
6893
+ import { Command as Command60 } from "commander";
6894
+ import * as p34 from "@clack/prompts";
6645
6895
  import makeFetchCookie from "fetch-cookie";
6646
- var login = new Command57("login").description("login to velastack.dev").configureHelp(helpConfig).action(
6896
+ var login = new Command60("login").description("login to velastack.dev").configureHelp(helpConfig).action(
6647
6897
  () => runCommand(async () => {
6648
- const { email: email3, password: password11 } = await p29.group({
6649
- email: () => p29.text({ message: "Email" }),
6650
- password: () => p29.password({ message: "Password" })
6898
+ const { email: email3, password: password11 } = await p34.group({
6899
+ email: () => p34.text({ message: "Email" }),
6900
+ password: () => p34.password({ message: "Password" })
6651
6901
  });
6652
6902
  const fetchCookie = makeFetchCookie(fetch);
6653
6903
  const loginRes = await fetchCookie(`${API_URL}/login`, {
@@ -6669,7 +6919,7 @@ var login = new Command57("login").description("login to velastack.dev").configu
6669
6919
  }
6670
6920
  const apiKey = await issueApiKey(fetchCookie);
6671
6921
  writeConfig({ apiKey });
6672
- p29.log.success("Logged in to velastack.dev");
6922
+ p34.log.success("Logged in to velastack.dev");
6673
6923
  }, "Failed to login.")
6674
6924
  );
6675
6925
  async function issueApiKey(fetchCookie) {
@@ -6710,12 +6960,12 @@ function extractApiKey(cookie) {
6710
6960
  }
6711
6961
 
6712
6962
  // src/commands/signup.ts
6713
- var signup = new Command58("signup").description("signup to velastack.dev").configureHelp(helpConfig).action(
6963
+ var signup = new Command61("signup").description("signup to velastack.dev").configureHelp(helpConfig).action(
6714
6964
  () => runCommand(async () => {
6715
- const { email: email3, password: password11, passwordConfirm } = await p30.group({
6716
- email: () => p30.text({ message: "Email" }),
6717
- password: () => p30.password({ message: "Password" }),
6718
- passwordConfirm: () => p30.password({ message: "Confirm password" })
6965
+ const { email: email3, password: password11, passwordConfirm } = await p35.group({
6966
+ email: () => p35.text({ message: "Email" }),
6967
+ password: () => p35.password({ message: "Password" }),
6968
+ passwordConfirm: () => p35.password({ message: "Confirm password" })
6719
6969
  });
6720
6970
  if (password11 !== passwordConfirm) {
6721
6971
  throw new Error("Passwords do not match.");
@@ -6739,33 +6989,33 @@ var signup = new Command58("signup").description("signup to velastack.dev").conf
6739
6989
  }
6740
6990
  const apiKey = await issueApiKey(fetchCookie);
6741
6991
  writeConfig({ apiKey });
6742
- p30.log.success("Signed up to velastack.dev");
6743
- p30.log.info("Check your email for a confirmation link.");
6992
+ p35.log.success("Signed up to velastack.dev");
6993
+ p35.log.info("Check your email for a confirmation link.");
6744
6994
  }, "Failed to signup.")
6745
6995
  );
6746
6996
 
6747
6997
  // src/commands/logout.ts
6748
- import { Command as Command59 } from "commander";
6749
- import * as p31 from "@clack/prompts";
6750
- var logout = new Command59("logout").alias("signout").description("logout from velastack.dev").configureHelp(helpConfig).action(
6998
+ import { Command as Command62 } from "commander";
6999
+ import * as p36 from "@clack/prompts";
7000
+ var logout = new Command62("logout").alias("signout").description("logout from velastack.dev").configureHelp(helpConfig).action(
6751
7001
  () => runCommand(() => {
6752
7002
  if (!readConfig()) {
6753
- p31.log.info("Not logged in");
7003
+ p36.log.info("Not logged in");
6754
7004
  return;
6755
7005
  }
6756
7006
  clearConfig();
6757
- p31.log.success("Logged out of velastack.dev");
7007
+ p36.log.success("Logged out of velastack.dev");
6758
7008
  })
6759
7009
  );
6760
7010
 
6761
7011
  // src/commands/whoami.ts
6762
- import { Command as Command60 } from "commander";
6763
- import * as p32 from "@clack/prompts";
6764
- var whoami = new Command60("whoami").description("show the current user").configureHelp(helpConfig).action(
7012
+ import { Command as Command63 } from "commander";
7013
+ import * as p37 from "@clack/prompts";
7014
+ var whoami = new Command63("whoami").description("show the current user").configureHelp(helpConfig).action(
6765
7015
  () => runCommand(async () => {
6766
7016
  const apiKey = readConfig()?.apiKey;
6767
7017
  if (!apiKey) {
6768
- p32.log.info("Not logged in. Run `vela login` to login.");
7018
+ p37.log.info("Not logged in. Run `vela login` to login.");
6769
7019
  return;
6770
7020
  }
6771
7021
  const res = await fetch(`${API_URL}/api/collections/users/records`, {
@@ -6773,15 +7023,15 @@ var whoami = new Command60("whoami").description("show the current user").config
6773
7023
  });
6774
7024
  const data = await res.json();
6775
7025
  if (!data.items.length) throw new Error("No user found. Run `vela login` to login.");
6776
- p32.log.success(`Logged in as ${data.items[0].email}`);
7026
+ p37.log.success(`Logged in as ${data.items[0].email}`);
6777
7027
  })
6778
7028
  );
6779
7029
 
6780
7030
  // src/commands/migrate.ts
6781
- import { Command as Command66 } from "commander";
7031
+ import { Command as Command69 } from "commander";
6782
7032
 
6783
7033
  // src/commands/migrate/up.ts
6784
- import { Command as Command61 } from "commander";
7034
+ import { Command as Command64 } from "commander";
6785
7035
 
6786
7036
  // src/lib/migrate.ts
6787
7037
  import path26 from "node:path";
@@ -6820,18 +7070,18 @@ async function runMigrateUp() {
6820
7070
  ]
6821
7071
  });
6822
7072
  }
6823
- var up = new Command61("up").description("apply all pending migrations").configureHelp(helpConfig).action(() => runCommand(runMigrateUp, "Failed to run migrations."));
7073
+ var up = new Command64("up").description("apply all pending migrations").configureHelp(helpConfig).action(() => runCommand(runMigrateUp, "Failed to run migrations."));
6824
7074
 
6825
7075
  // src/commands/migrate/down.ts
6826
- import { Command as Command62, InvalidArgumentError as InvalidArgumentError4 } from "commander";
7076
+ import { Command as Command65, InvalidArgumentError as InvalidArgumentError3 } from "commander";
6827
7077
  function parseSteps(value) {
6828
7078
  const n = parseInt(value, 10);
6829
7079
  if (!Number.isFinite(n) || n <= 0) {
6830
- throw new InvalidArgumentError4("number must be a positive integer");
7080
+ throw new InvalidArgumentError3("number must be a positive integer");
6831
7081
  }
6832
7082
  return n;
6833
7083
  }
6834
- var down = new Command62("down").alias("rollback").description("revert the last N applied migrations").argument("[number]", "how many migrations to revert", parseSteps, 1).configureHelp(helpConfig).action(
7084
+ var down = new Command65("down").alias("rollback").description("revert the last N applied migrations").argument("[number]", "how many migrations to revert", parseSteps, 1).configureHelp(helpConfig).action(
6835
7085
  (n) => runCommand(async () => {
6836
7086
  await runPocketbaseMigrate(["down", String(n)]);
6837
7087
  reportResult({
@@ -6845,11 +7095,11 @@ var down = new Command62("down").alias("rollback").description("revert the last
6845
7095
  );
6846
7096
 
6847
7097
  // src/commands/migrate/create.ts
6848
- import fs27 from "node:fs";
7098
+ import fs28 from "node:fs";
6849
7099
  import path27 from "node:path";
6850
7100
  import process18 from "node:process";
6851
- import { Command as Command63 } from "commander";
6852
- var create2 = new Command63("create").alias("new").description("create a new blank migration").argument("<name>", "migration name (snake_case)").configureHelp(helpConfig).action(
7101
+ import { Command as Command66 } from "commander";
7102
+ var create2 = new Command66("create").alias("new").description("create a new blank migration").argument("<name>", "migration name (snake_case)").configureHelp(helpConfig).action(
6853
7103
  (name) => runCommand(async () => {
6854
7104
  const cwd = process18.cwd();
6855
7105
  const before = listMigrationFiles(cwd);
@@ -6868,16 +7118,16 @@ var create2 = new Command63("create").alias("new").description("create a new bla
6868
7118
  );
6869
7119
  function listMigrationFiles(cwd) {
6870
7120
  const dir = path27.join(cwd, MIGRATIONS_DIR);
6871
- if (!fs27.existsSync(dir)) return /* @__PURE__ */ new Set();
6872
- return new Set(fs27.readdirSync(dir).filter((f) => /\.[jt]s$/.test(f)));
7121
+ if (!fs28.existsSync(dir)) return /* @__PURE__ */ new Set();
7122
+ return new Set(fs28.readdirSync(dir).filter((f) => /\.[jt]s$/.test(f)));
6873
7123
  }
6874
7124
 
6875
7125
  // src/commands/migrate/collections.ts
6876
- import fs28 from "node:fs";
7126
+ import fs29 from "node:fs";
6877
7127
  import path28 from "node:path";
6878
7128
  import process19 from "node:process";
6879
- import { Command as Command64 } from "commander";
6880
- var collections = new Command64("collections").alias("snapshot").description("snapshot local collections into a new migration").configureHelp(helpConfig).action(
7129
+ import { Command as Command67 } from "commander";
7130
+ var collections = new Command67("collections").alias("snapshot").description("snapshot local collections into a new migration").configureHelp(helpConfig).action(
6881
7131
  () => runCommand(async () => {
6882
7132
  const cwd = process19.cwd();
6883
7133
  const before = listMigrationFiles2(cwd);
@@ -6903,13 +7153,13 @@ var collections = new Command64("collections").alias("snapshot").description("sn
6903
7153
  );
6904
7154
  function listMigrationFiles2(cwd) {
6905
7155
  const dir = path28.join(cwd, MIGRATIONS_DIR);
6906
- if (!fs28.existsSync(dir)) return /* @__PURE__ */ new Set();
6907
- return new Set(fs28.readdirSync(dir).filter((f) => /\.[jt]s$/.test(f)));
7156
+ if (!fs29.existsSync(dir)) return /* @__PURE__ */ new Set();
7157
+ return new Set(fs29.readdirSync(dir).filter((f) => /\.[jt]s$/.test(f)));
6908
7158
  }
6909
7159
 
6910
7160
  // src/commands/migrate/history-sync.ts
6911
- import { Command as Command65 } from "commander";
6912
- var historySync = new Command65("history-sync").description("drop _migrations rows whose files no longer exist").configureHelp(helpConfig).action(
7161
+ import { Command as Command68 } from "commander";
7162
+ var historySync = new Command68("history-sync").description("drop _migrations rows whose files no longer exist").configureHelp(helpConfig).action(
6913
7163
  () => runCommand(async () => {
6914
7164
  await runPocketbaseMigrate(["history-sync"]);
6915
7165
  reportResult({
@@ -6920,14 +7170,14 @@ var historySync = new Command65("history-sync").description("drop _migrations ro
6920
7170
  );
6921
7171
 
6922
7172
  // src/commands/migrate.ts
6923
- var migrate = new Command66("migrate").description("manage database migrations").configureHelp(helpConfig).action(() => runCommand(runMigrateUp, "Failed to run migrations.")).addCommand(up).addCommand(down).addCommand(create2).addCommand(collections).addCommand(historySync);
7173
+ var migrate = new Command69("migrate").description("manage database migrations").configureHelp(helpConfig).action(() => runCommand(runMigrateUp, "Failed to run migrations.")).addCommand(up).addCommand(down).addCommand(create2).addCommand(collections).addCommand(historySync);
6924
7174
 
6925
7175
  // src/commands/dev.ts
6926
- import fs29 from "node:fs";
7176
+ import fs30 from "node:fs";
6927
7177
  import path30 from "node:path";
6928
7178
  import process21 from "node:process";
6929
7179
  import { performance } from "node:perf_hooks";
6930
- import { Command as Command67, InvalidArgumentError as InvalidArgumentError5 } from "commander";
7180
+ import { Command as Command70, InvalidArgumentError as InvalidArgumentError4 } from "commander";
6931
7181
  import pc13 from "picocolors";
6932
7182
  import PocketBase4 from "pocketbase";
6933
7183
 
@@ -6972,11 +7222,11 @@ async function loadVite(cwd = process20.cwd()) {
6972
7222
  function parsePort(value) {
6973
7223
  const port = Number(value);
6974
7224
  if (!Number.isInteger(port) || port < 1 || port > 65535) {
6975
- throw new InvalidArgumentError5("must be a whole number between 1 and 65535.");
7225
+ throw new InvalidArgumentError4("must be a whole number between 1 and 65535.");
6976
7226
  }
6977
7227
  return port;
6978
7228
  }
6979
- var dev = new Command67("dev").description("start the development server").option("--open [path]", "open the app in a browser once the server is ready").option("--host [host]", "expose the server on the network").option("--port <port>", "port to listen on", parsePort).option("--strictPort", "exit if the port is already in use instead of taking the next one").option("--cors", "enable CORS").option("--force", "re-bundle dependencies, ignoring the optimizer cache").configureHelp(helpConfig).action(async (options) => {
7229
+ var dev = new Command70("dev").description("start the development server").option("--open [path]", "open the app in a browser once the server is ready").option("--host [host]", "expose the server on the network").option("--port <port>", "port to listen on", parsePort).option("--strictPort", "exit if the port is already in use instead of taking the next one").option("--cors", "enable CORS").option("--force", "re-bundle dependencies, ignoring the optimizer cache").configureHelp(helpConfig).action(async (options) => {
6980
7230
  const cwd = process21.cwd();
6981
7231
  process21.env.VELA_DATA_DIR ??= localDataDir(cwd);
6982
7232
  const startTime = performance.now();
@@ -6988,7 +7238,7 @@ var dev = new Command67("dev").description("start the development server").optio
6988
7238
  const needsStart = backend3 && !process21.env.POCKETBASE_URL;
6989
7239
  const cleanup = () => {
6990
7240
  if (pbProc?.pid) pbProc.kill();
6991
- if (fs29.existsSync(viteMetadataFile)) fs29.rmSync(viteMetadataFile);
7241
+ if (fs30.existsSync(viteMetadataFile)) fs30.rmSync(viteMetadataFile);
6992
7242
  };
6993
7243
  if (needsStart) {
6994
7244
  const dataDir2 = path30.join(cwd, DATA_DIR);
@@ -7026,8 +7276,8 @@ var dev = new Command67("dev").description("start the development server").optio
7026
7276
  if (!backend3) return;
7027
7277
  const { address, port: vitePort } = server.httpServer.address();
7028
7278
  const viteHost = address === "::1" ? "localhost" : address;
7029
- await fs29.promises.mkdir(viteMetadataDir, { recursive: true });
7030
- await fs29.promises.writeFile(
7279
+ await fs30.promises.mkdir(viteMetadataDir, { recursive: true });
7280
+ await fs30.promises.writeFile(
7031
7281
  viteMetadataFile,
7032
7282
  JSON.stringify({
7033
7283
  pocketbaseUrl: process21.env.POCKETBASE_URL,
@@ -7068,9 +7318,9 @@ async function startWatchingTypes(cwd, pb) {
7068
7318
  void (async () => {
7069
7319
  for (; ; ) {
7070
7320
  try {
7071
- await fs29.promises.mkdir(pocketbaseDir, { recursive: true });
7072
- for await (const event of fs29.promises.watch(pocketbaseDir)) {
7073
- if (event.eventType === "rename" && event.filename === "$types.d.ts" && !fs29.existsSync(pocketbaseTypes)) {
7321
+ await fs30.promises.mkdir(pocketbaseDir, { recursive: true });
7322
+ for await (const event of fs30.promises.watch(pocketbaseDir)) {
7323
+ if (event.eventType === "rename" && event.filename === "$types.d.ts" && !fs30.existsSync(pocketbaseTypes)) {
7074
7324
  setTimeout(regenerate, 100);
7075
7325
  }
7076
7326
  }
@@ -7082,15 +7332,15 @@ async function startWatchingTypes(cwd, pb) {
7082
7332
  }
7083
7333
 
7084
7334
  // src/commands/build.ts
7085
- import fs30 from "node:fs";
7335
+ import fs31 from "node:fs";
7086
7336
  import path31 from "node:path";
7087
7337
  import process23 from "node:process";
7088
- import { Command as Command68 } from "commander";
7089
- import * as p33 from "@clack/prompts";
7338
+ import { Command as Command71 } from "commander";
7339
+ import * as p38 from "@clack/prompts";
7090
7340
  import pc14 from "picocolors";
7091
7341
  import { x as x3 } from "tinyexec";
7092
- import { detect as detect5 } from "package-manager-detector";
7093
- import { resolveCommand as resolveCommand5 } from "package-manager-detector/commands";
7342
+ import { detect as detect4 } from "package-manager-detector";
7343
+ import { resolveCommand as resolveCommand4 } from "package-manager-detector/commands";
7094
7344
 
7095
7345
  // src/lib/build-env.ts
7096
7346
  function applyBuildEnv(cwd, env2 = process.env) {
@@ -7119,7 +7369,7 @@ function normalizeOrigin(value) {
7119
7369
 
7120
7370
  // src/commands/build.ts
7121
7371
  var PRERENDERED_DIR = path31.join(".svelte-kit", "output", "prerendered");
7122
- var build = new Command68("build").description("build the app").configureHelp(helpConfig).option("-t, --target <target>", "which copy of the app to build for", PRODUCTION_TARGET).action(async (options) => {
7372
+ var build = new Command71("build").description("build the app").configureHelp(helpConfig).option("-t, --target <target>", "which copy of the app to build for", PRODUCTION_TARGET).action(async (options) => {
7123
7373
  const cwd = process23.cwd();
7124
7374
  applyBuildEnv(cwd);
7125
7375
  const origin = await originForBuild(cwd, options.target);
@@ -7147,8 +7397,8 @@ var build = new Command68("build").description("build the app").configureHelp(he
7147
7397
  });
7148
7398
  }
7149
7399
  try {
7150
- const pm = (await detect5({ cwd }))?.name ?? "npm";
7151
- const resolved = resolveCommand5(pm, "execute", ["vite", "build"]);
7400
+ const pm = (await detect4({ cwd }))?.name ?? "npm";
7401
+ const resolved = resolveCommand4(pm, "execute", ["vite", "build"]);
7152
7402
  const args = resolved.args.slice();
7153
7403
  if (pm === "npm") args.unshift("--yes");
7154
7404
  await x3(resolved.command, args, {
@@ -7174,8 +7424,8 @@ async function originForBuild(cwd, target) {
7174
7424
  }
7175
7425
  function warnIfPrerendered(cwd) {
7176
7426
  const dir = path31.join(cwd, PRERENDERED_DIR);
7177
- if (!fs30.existsSync(dir) || fs30.readdirSync(dir).length === 0) return;
7178
- p33.log.warn(
7427
+ if (!fs31.existsSync(dir) || fs31.readdirSync(dir).length === 0) return;
7428
+ p38.log.warn(
7179
7429
  `Prerendered pages were built with no domain configured, so their canonical
7180
7430
  links point at SvelteKit's placeholder host rather than at this site.
7181
7431
 
@@ -7186,11 +7436,11 @@ Set one with ${pc14.cyan("vela deploy --domain example.com")}, or pass ${pc14.cy
7186
7436
  // src/commands/preview.ts
7187
7437
  import path32 from "node:path";
7188
7438
  import process24 from "node:process";
7189
- import { Command as Command69 } from "commander";
7439
+ import { Command as Command72 } from "commander";
7190
7440
  import { x as x4 } from "tinyexec";
7191
- import { detect as detect6 } from "package-manager-detector";
7192
- import { resolveCommand as resolveCommand6 } from "package-manager-detector/commands";
7193
- var preview = new Command69("preview").description("preview the built app").configureHelp(helpConfig).action(async () => {
7441
+ import { detect as detect5 } from "package-manager-detector";
7442
+ import { resolveCommand as resolveCommand5 } from "package-manager-detector/commands";
7443
+ var preview = new Command72("preview").description("preview the built app").configureHelp(helpConfig).action(async () => {
7194
7444
  const cwd = process24.cwd();
7195
7445
  process24.env.VELA_DATA_DIR ??= localDataDir(cwd);
7196
7446
  let pbProc;
@@ -7215,8 +7465,8 @@ var preview = new Command69("preview").description("preview the built app").conf
7215
7465
  });
7216
7466
  }
7217
7467
  try {
7218
- const pm = (await detect6({ cwd }))?.name ?? "npm";
7219
- const resolved = resolveCommand6(pm, "execute", ["vite", "preview"]);
7468
+ const pm = (await detect5({ cwd }))?.name ?? "npm";
7469
+ const resolved = resolveCommand5(pm, "execute", ["vite", "preview"]);
7220
7470
  const args = resolved.args.slice();
7221
7471
  if (pm === "npm") args.unshift("--yes");
7222
7472
  await x4(resolved.command, args, {
@@ -7230,8 +7480,8 @@ var preview = new Command69("preview").description("preview the built app").conf
7230
7480
 
7231
7481
  // src/commands/sync.ts
7232
7482
  import path33 from "node:path";
7233
- import { Command as Command70 } from "commander";
7234
- var sync = new Command70("sync").description("sync types from the database").configureHelp(helpConfig).action(
7483
+ import { Command as Command73 } from "commander";
7484
+ var sync = new Command73("sync").description("sync types from the database").configureHelp(helpConfig).action(
7235
7485
  () => runCommand(async () => {
7236
7486
  const { workspaceRootDir } = await getWorkspace();
7237
7487
  const typesDir = path33.join(workspaceRootDir, ".svelte-kit", "types");
@@ -7244,8 +7494,8 @@ var sync = new Command70("sync").description("sync types from the database").con
7244
7494
  );
7245
7495
 
7246
7496
  // src/commands/provision.ts
7247
- import { Command as Command71 } from "commander";
7248
- import * as p34 from "@clack/prompts";
7497
+ import { Command as Command74 } from "commander";
7498
+ import * as p39 from "@clack/prompts";
7249
7499
  import pc15 from "picocolors";
7250
7500
  import * as v6 from "valibot";
7251
7501
  var OptionsSchema2 = v6.object({
@@ -7254,24 +7504,24 @@ var OptionsSchema2 = v6.object({
7254
7504
  nodeMajor: v6.optional(v6.string())
7255
7505
  });
7256
7506
  var provision = addSshOptions(
7257
- new Command71("provision").description("prepare a server to host vela apps").argument("<target>", "SSH target \u2014 an alias from ~/.ssh/config, or user@host").configureHelp(helpConfig)
7507
+ new Command74("provision").description("prepare a server to host vela apps").argument("<target>", "SSH target \u2014 an alias from ~/.ssh/config, or user@host").configureHelp(helpConfig)
7258
7508
  ).option("--pb-version <version>", "PocketBase version to install").option("--node-major <version>", "Node.js major version to install", "22").action(
7259
7509
  (target, raw) => runCommand(async () => {
7260
7510
  const options = parseOptions(OptionsSchema2, raw);
7261
7511
  const pbVersion = options.pbVersion ?? pocketbaseVersion();
7262
- p34.intro(pc15.bgCyan(pc15.black(" vela provision ")));
7263
- p34.log.info(`Target ${pc15.cyan(target)}`);
7512
+ p39.intro(pc15.bgCyan(pc15.black(" vela provision ")));
7513
+ p39.log.info(`Target ${pc15.cyan(target)}`);
7264
7514
  await withSsh(target, sshOptionsFrom(options), async (session) => {
7265
7515
  await session.detectElevation();
7266
7516
  const existing = await readServerInfo(session);
7267
7517
  if (existing) {
7268
- p34.log.info(
7518
+ p39.log.info(
7269
7519
  `Already provisioned by vela ${existing.cliVersion} on ${existing.provisionedAt}. Bringing it up to date.`
7270
7520
  );
7271
7521
  }
7272
- p34.log.step("Uploading server scripts");
7522
+ p39.log.step("Uploading server scripts");
7273
7523
  await syncServerScripts(session);
7274
- p34.log.step("Running provision");
7524
+ p39.log.step("Running provision");
7275
7525
  const result = await runServerScript(session, "provision.sh", {
7276
7526
  args: [
7277
7527
  "--pb-version",
@@ -7283,7 +7533,7 @@ var provision = addSshOptions(
7283
7533
  ],
7284
7534
  stream: true
7285
7535
  });
7286
- p34.log.success(
7536
+ p39.log.success(
7287
7537
  `${target} is ready.
7288
7538
 
7289
7539
  Node ${result?.node ?? "installed"}
@@ -7291,27 +7541,27 @@ var provision = addSshOptions(
7291
7541
  PocketBase ${result?.pocketbase ?? pbVersion}`
7292
7542
  );
7293
7543
  });
7294
- p34.outro(`Deploy with ${pc15.cyan(`vela deploy --server ${target}`)}`);
7544
+ p39.outro(`Deploy with ${pc15.cyan(`vela deploy --server ${target}`)}`);
7295
7545
  }, "Failed to provision.")
7296
7546
  );
7297
7547
 
7298
7548
  // src/commands/deploy.ts
7299
7549
  import path36 from "node:path";
7300
- import fs33 from "node:fs";
7301
- import { Command as Command72, Option as Option2 } from "commander";
7302
- import * as p35 from "@clack/prompts";
7550
+ import fs34 from "node:fs";
7551
+ import { Command as Command75, Option as Option2 } from "commander";
7552
+ import * as p40 from "@clack/prompts";
7303
7553
  import pc16 from "picocolors";
7304
7554
  import * as v7 from "valibot";
7305
7555
 
7306
7556
  // src/lib/pocketbase-settings.ts
7307
- import fs31 from "node:fs";
7557
+ import fs32 from "node:fs";
7308
7558
  import path34 from "node:path";
7309
7559
  import process25 from "node:process";
7310
7560
  import PocketBase5 from "pocketbase";
7311
7561
  var COPIED_KEYS = ["appName", "senderName", "senderAddress"];
7312
7562
  async function readLocalMeta(cwd) {
7313
7563
  const dataDir2 = path34.join(cwd, DATA_DIR);
7314
- if (!fs31.existsSync(dataDir2)) return null;
7564
+ if (!fs32.existsSync(dataDir2)) return null;
7315
7565
  const email3 = process25.env.POCKETBASE_SUPERUSER_EMAIL;
7316
7566
  const password11 = process25.env.POCKETBASE_SUPERUSER_PASSWORD;
7317
7567
  if (!email3 || !password11) return null;
@@ -7362,10 +7612,10 @@ async function seedRemoteMeta(session, instance, local, appURL) {
7362
7612
  }
7363
7613
 
7364
7614
  // src/lib/artifact.ts
7365
- import fs32 from "node:fs";
7615
+ import fs33 from "node:fs";
7366
7616
  import path35 from "node:path";
7367
- import { detect as detect7 } from "package-manager-detector";
7368
- import { resolveCommand as resolveCommand7 } from "package-manager-detector/commands";
7617
+ import { detect as detect6 } from "package-manager-detector";
7618
+ import { resolveCommand as resolveCommand6 } from "package-manager-detector/commands";
7369
7619
  var DEFAULT_OUTPUT_DIR = "build";
7370
7620
  var BuildError = class extends Error {
7371
7621
  };
@@ -7381,8 +7631,8 @@ async function runBuild(cwd, buildCommand, env2) {
7381
7631
  throw new BuildError(`\`${buildCommand}\` exited ${result2.exitCode}.`);
7382
7632
  return;
7383
7633
  }
7384
- const pm = (await detect7({ cwd }))?.name ?? "npm";
7385
- const resolved = resolveCommand7(pm, "run", ["build"]);
7634
+ const pm = (await detect6({ cwd }))?.name ?? "npm";
7635
+ const resolved = resolveCommand6(pm, "run", ["build"]);
7386
7636
  if (!resolved) throw new BuildError(`Could not work out how to run a build with ${pm}.`);
7387
7637
  const result = await spawnCapture(resolved.command, resolved.args, {
7388
7638
  cwd,
@@ -7401,10 +7651,10 @@ function collectArtifact(cwd, config = {}) {
7401
7651
  const entries = [];
7402
7652
  const add2 = (rel, remoteDir = "") => {
7403
7653
  const localPath = path35.join(cwd, rel);
7404
- if (fs32.existsSync(localPath)) entries.push({ localPath, remoteDir });
7654
+ if (fs33.existsSync(localPath)) entries.push({ localPath, remoteDir });
7405
7655
  };
7406
7656
  const buildPath = path35.join(cwd, outputDir);
7407
- if (!fs32.existsSync(path35.join(buildPath, "index.js"))) {
7657
+ if (!fs33.existsSync(path35.join(buildPath, "index.js"))) {
7408
7658
  throw new BuildError(
7409
7659
  `No ${outputDir}/index.js after the build.
7410
7660
 
@@ -7418,7 +7668,7 @@ the adapter in your Vite or Svelte config, then build again.`
7418
7668
  add2(".npmrc");
7419
7669
  add2(MIGRATIONS_DIR);
7420
7670
  const hooks = path35.join(cwd, DATA_DIR, "hooks");
7421
- if (fs32.existsSync(hooks)) entries.push({ localPath: hooks, remoteDir: "hooks" });
7671
+ if (fs33.existsSync(hooks)) entries.push({ localPath: hooks, remoteDir: "hooks" });
7422
7672
  for (const extra of config.include ?? []) add2(extra);
7423
7673
  return entries;
7424
7674
  }
@@ -7440,7 +7690,7 @@ var OptionsSchema3 = v7.object({
7440
7690
  build: v7.optional(v7.boolean())
7441
7691
  });
7442
7692
  var deploy = addTargetOptions(
7443
- new Command72("deploy").description("deploy the app").configureHelp(helpConfig),
7693
+ new Command75("deploy").description("deploy the app").configureHelp(helpConfig),
7444
7694
  "production"
7445
7695
  ).option("--project <name>", "override the project name").option("--domain <hosts>", "hostname(s) to serve on, comma separated").option("--health-path <path>", "path the health check requests").option("--keep <count>", "how many old releases to keep on the server").option("--pb-version <version>", "PocketBase version to run").option("--no-build", "deploy the existing build output without rebuilding").addOption(
7446
7696
  new Option2(
@@ -7456,13 +7706,13 @@ var deploy = addTargetOptions(
7456
7706
  const options = parseOptions(OptionsSchema3, raw);
7457
7707
  const backend3 = hasBackend();
7458
7708
  const release = releaseId();
7459
- p35.intro(pc16.bgCyan(pc16.black(" vela deploy ")));
7709
+ p40.intro(pc16.bgCyan(pc16.black(" vela deploy ")));
7460
7710
  await withTarget(
7461
7711
  raw,
7462
7712
  {
7463
7713
  remote: async (ctx) => {
7464
7714
  const { session, instance, workspaceRootDir, config } = ctx;
7465
- p35.log.info(
7715
+ p40.log.info(
7466
7716
  `${pc16.cyan(ctx.appName)} ${pc16.dim("\u2192")} ${pc16.cyan(ctx.targetName)} ${pc16.dim(`(${ctx.server})`)}`
7467
7717
  );
7468
7718
  const [existing] = await readInstanceStates(session, instance);
@@ -7478,7 +7728,7 @@ var deploy = addTargetOptions(
7478
7728
  tunnel = await openDatabaseTunnel(session, instance, existing);
7479
7729
  } catch (err) {
7480
7730
  if (askedForRemoteDb) throw err;
7481
- p35.log.warn(
7731
+ p40.log.warn(
7482
7732
  `Could not build against the ${pc16.cyan(ctx.targetName)} database, using a local one instead.
7483
7733
  ${pc16.dim(String(err))}`
7484
7734
  );
@@ -7486,13 +7736,13 @@ ${pc16.dim(String(err))}`
7486
7736
  }
7487
7737
  if (tunnel) {
7488
7738
  buildEnv = { ...buildEnv, ...tunnel.env };
7489
- p35.log.info(
7739
+ p40.log.info(
7490
7740
  `Building against the ${pc16.cyan(ctx.targetName)} database on ${ctx.server} ${pc16.dim(`(port ${tunnel.pbPort})`)}`
7491
7741
  );
7492
7742
  } else if (backend3) {
7493
7743
  await ensureSuperuser(workspaceRootDir);
7494
7744
  }
7495
- p35.log.step("Building");
7745
+ p40.log.step("Building");
7496
7746
  try {
7497
7747
  await runBuild(workspaceRootDir, config.deploy?.buildCommand, buildEnv);
7498
7748
  } finally {
@@ -7501,9 +7751,9 @@ ${pc16.dim(String(err))}`
7501
7751
  }
7502
7752
  const entries = collectArtifact(workspaceRootDir, config.deploy ?? {});
7503
7753
  const sha = await gitSha(workspaceRootDir);
7504
- p35.log.step(`Uploading release ${pc16.dim(release)}`);
7754
+ p40.log.step(`Uploading release ${pc16.dim(release)}`);
7505
7755
  await uploadRelease(session, instance, release, entries);
7506
- p35.log.step("Activating");
7756
+ p40.log.step("Activating");
7507
7757
  const result = await runServerScript(session, "apply.sh", {
7508
7758
  args: [
7509
7759
  instance,
@@ -7535,7 +7785,7 @@ ${pc16.dim(String(err))}`
7535
7785
  });
7536
7786
  if (!existing) await reportEmptyEnvironment(session, instance, workspaceRootDir);
7537
7787
  const url = result?.url ?? "";
7538
- p35.log.success(
7788
+ p40.log.success(
7539
7789
  `Deployed ${pc16.cyan(ctx.appName)} ${pc16.dim(release)}
7540
7790
 
7541
7791
  URL ${url}
@@ -7548,7 +7798,7 @@ ${pc16.dim(String(err))}`
7548
7798
  workspaceRootDir,
7549
7799
  domain ? result?.url ?? "" : ""
7550
7800
  );
7551
- p35.log.info(
7801
+ p40.log.info(
7552
7802
  `Created the PocketBase superuser this app authenticates as.
7553
7803
 
7554
7804
  Its credentials are stored in the environment on the server. To use
@@ -7559,7 +7809,7 @@ and deploy again.`
7559
7809
  await reportAppURLDrift(session, instance, domain);
7560
7810
  }
7561
7811
  if (!domain) {
7562
- p35.log.warn(
7812
+ p40.log.warn(
7563
7813
  `No domain configured, so nothing is proxied to this app yet.
7564
7814
  Redeploy with ${pc16.cyan("--domain example.com")} once DNS points at ${ctx.server}.`
7565
7815
  );
@@ -7568,7 +7818,7 @@ Redeploy with ${pc16.cyan("--domain example.com")} once DNS points at ${ctx.serv
7568
7818
  },
7569
7819
  { project: options.project, askDomain: true, label: "deploy" }
7570
7820
  );
7571
- p35.outro(`${pc16.cyan("vela status")} to see what is running`);
7821
+ p40.outro(`${pc16.cyan("vela status")} to see what is running`);
7572
7822
  }, "Failed to deploy.")
7573
7823
  );
7574
7824
  async function reportAppURLDrift(session, instance, domain) {
@@ -7576,7 +7826,7 @@ async function reportAppURLDrift(session, instance, domain) {
7576
7826
  if (!expected) return;
7577
7827
  const current = await readRemoteAppURL(session, instance);
7578
7828
  if (!current || normalizeOrigin(current) === expected) return;
7579
- p35.log.warn(
7829
+ p40.log.warn(
7580
7830
  `This app's PocketBase ${pc16.cyan("appURL")} is ${pc16.dim(current)}, but it is served on ${pc16.dim(expected)}.
7581
7831
 
7582
7832
  Emails and anything else PocketBase links to will use the former. Update it in
@@ -7591,15 +7841,15 @@ async function copyLocalBranding(session, instance, workspaceRootDir, appURL) {
7591
7841
  if (copied.length === 0) return;
7592
7842
  const outcome = await restartInstance(session, instance);
7593
7843
  if (outcome.deployed && !outcome.restarted) {
7594
- p35.log.warn(
7844
+ p40.log.warn(
7595
7845
  `Copied ${copied.join(", ")}, but the app did not restart to pick them up.
7596
7846
  ${pc16.dim(outcome.error ?? "")}`
7597
7847
  );
7598
7848
  return;
7599
7849
  }
7600
- p35.log.success(`Copied ${copied.join(", ")} from this project's database`);
7850
+ p40.log.success(`Copied ${copied.join(", ")} from this project's database`);
7601
7851
  } catch (err) {
7602
- p35.log.warn(
7852
+ p40.log.warn(
7603
7853
  `Could not copy this project's PocketBase settings across.
7604
7854
  Set them in the admin panel instead. ${pc16.dim(String(err))}`
7605
7855
  );
@@ -7683,7 +7933,7 @@ async function uploadRelease(session, instance, release, entries) {
7683
7933
  }
7684
7934
  function isDirectory(target) {
7685
7935
  try {
7686
- return fs33.statSync(target).isDirectory();
7936
+ return fs34.statSync(target).isDirectory();
7687
7937
  } catch {
7688
7938
  return false;
7689
7939
  }
@@ -7691,8 +7941,8 @@ function isDirectory(target) {
7691
7941
  async function reportEmptyEnvironment(session, instance, workspaceRootDir) {
7692
7942
  const remote = await readRemoteEnv(session, instance);
7693
7943
  if (Object.keys(remote).length > 0) return;
7694
- if (!fs33.existsSync(path36.join(workspaceRootDir, ".env"))) return;
7695
- p35.log.warn(
7944
+ if (!fs34.existsSync(path36.join(workspaceRootDir, ".env"))) return;
7945
+ p40.log.warn(
7696
7946
  `This app has no production environment variables yet.
7697
7947
 
7698
7948
  Local ${pc16.cyan(".env")} values are not uploaded by a deploy. Set them with
@@ -7703,8 +7953,8 @@ ${pc16.cyan("vela env set KEY")}, or copy a file across with ${pc16.cyan("vela e
7703
7953
  // src/commands/link.ts
7704
7954
  import path37 from "node:path";
7705
7955
  import process26 from "node:process";
7706
- import { Command as Command73 } from "commander";
7707
- import * as p36 from "@clack/prompts";
7956
+ import { Command as Command76 } from "commander";
7957
+ import * as p41 from "@clack/prompts";
7708
7958
 
7709
7959
  // src/lib/velastack-api.ts
7710
7960
  async function apiFetch(apiKey, pathAndQuery, init) {
@@ -7755,12 +8005,12 @@ async function createProject2(apiKey, args) {
7755
8005
 
7756
8006
  // src/commands/link.ts
7757
8007
  var CREATE_NEW = "__new__";
7758
- var link = new Command73("link").description("link this project to a velastack.dev project").configureHelp(helpConfig).action(() => runCommand(linkProject, "Failed to link the project."));
8008
+ var link = new Command76("link").description("link this project to a velastack.dev project").configureHelp(helpConfig).action(() => runCommand(linkProject, "Failed to link the project."));
7759
8009
  async function linkProject() {
7760
8010
  const { workspaceRootDir } = await getWorkspace();
7761
8011
  const existing = readProjectConfig(workspaceRootDir);
7762
8012
  if (existing) {
7763
- p36.log.success(`Linked to ${existing.projectName}.`);
8013
+ p41.log.success(`Linked to ${existing.projectName}.`);
7764
8014
  return;
7765
8015
  }
7766
8016
  const apiKey = requireApiKey();
@@ -7787,10 +8037,10 @@ async function linkProject() {
7787
8037
  projectName = created.name;
7788
8038
  }
7789
8039
  writeProjectConfig(workspaceRootDir, { projectId, teamId, projectName });
7790
- p36.log.success(`Linked to ${projectName}.`);
8040
+ p41.log.success(`Linked to ${projectName}.`);
7791
8041
  }
7792
8042
  async function pickExistingProject(projects) {
7793
- const choice = await p36.select({
8043
+ const choice = await p41.select({
7794
8044
  message: "Select a project",
7795
8045
  options: [
7796
8046
  ...projects.map((pr) => ({
@@ -7800,38 +8050,38 @@ async function pickExistingProject(projects) {
7800
8050
  { value: CREATE_NEW, label: "Create a new project" }
7801
8051
  ]
7802
8052
  });
7803
- if (p36.isCancel(choice)) {
7804
- p36.cancel("Operation cancelled.");
8053
+ if (p41.isCancel(choice)) {
8054
+ p41.cancel("Operation cancelled.");
7805
8055
  process26.exit(0);
7806
8056
  }
7807
8057
  return choice;
7808
8058
  }
7809
8059
  async function pickTeam(teams3) {
7810
8060
  if (teams3.length === 1) return teams3[0];
7811
- const choice = await p36.select({
8061
+ const choice = await p41.select({
7812
8062
  message: "Select a team",
7813
8063
  options: teams3.map((team) => ({
7814
8064
  value: team.id,
7815
8065
  label: team.is_personal ? `${team.name} (personal)` : team.name
7816
8066
  }))
7817
8067
  });
7818
- if (p36.isCancel(choice)) {
7819
- p36.cancel("Operation cancelled.");
8068
+ if (p41.isCancel(choice)) {
8069
+ p41.cancel("Operation cancelled.");
7820
8070
  process26.exit(0);
7821
8071
  }
7822
8072
  return teams3.find((team) => team.id === choice);
7823
8073
  }
7824
8074
  async function promptProjectName(workspaceRootDir) {
7825
8075
  const defaultValue = defaultProjectName2(workspaceRootDir);
7826
- const value = await p36.text({
8076
+ const value = await p41.text({
7827
8077
  message: "Project name",
7828
8078
  defaultValue,
7829
8079
  initialValue: defaultValue,
7830
8080
  placeholder: defaultValue,
7831
8081
  validate: (v9) => !v9?.trim() ? "Required" : void 0
7832
8082
  });
7833
- if (p36.isCancel(value)) {
7834
- p36.cancel("Operation cancelled.");
8083
+ if (p41.isCancel(value)) {
8084
+ p41.cancel("Operation cancelled.");
7835
8085
  process26.exit(0);
7836
8086
  }
7837
8087
  return value.trim();
@@ -7847,14 +8097,14 @@ function defaultProjectName2(workspaceRootDir) {
7847
8097
  }
7848
8098
 
7849
8099
  // src/commands/env.ts
7850
- import { Command as Command78 } from "commander";
8100
+ import { Command as Command81 } from "commander";
7851
8101
 
7852
8102
  // src/commands/env/list.ts
7853
- import { Command as Command74 } from "commander";
7854
- import * as p37 from "@clack/prompts";
8103
+ import { Command as Command77 } from "commander";
8104
+ import * as p42 from "@clack/prompts";
7855
8105
  import pc17 from "picocolors";
7856
8106
  var envList = addTargetOptions(
7857
- new Command74("list").description("list environment variable names").configureHelp(helpConfig),
8107
+ new Command77("list").description("list environment variable names").configureHelp(helpConfig),
7858
8108
  "local"
7859
8109
  ).action(
7860
8110
  (raw) => runCommand(
@@ -7876,10 +8126,10 @@ var envList = addTargetOptions(
7876
8126
  );
7877
8127
  function report(keys, where) {
7878
8128
  if (keys.length === 0) {
7879
- p37.log.info(`No environment variables configured ${pc17.dim(`(${where})`)}.`);
8129
+ p42.log.info(`No environment variables configured ${pc17.dim(`(${where})`)}.`);
7880
8130
  return;
7881
8131
  }
7882
- p37.log.info(
8132
+ p42.log.info(
7883
8133
  `Environment ${pc17.dim(`(${where})`)}
7884
8134
 
7885
8135
  ` + keys.sort().map((key) => ` ${key}`).join("\n")
@@ -7888,11 +8138,11 @@ function report(keys, where) {
7888
8138
 
7889
8139
  // src/commands/env/set.ts
7890
8140
  import process27 from "node:process";
7891
- import { Command as Command75 } from "commander";
7892
- import * as p38 from "@clack/prompts";
8141
+ import { Command as Command78 } from "commander";
8142
+ import * as p43 from "@clack/prompts";
7893
8143
  import pc18 from "picocolors";
7894
8144
  var envSet = addTargetOptions(
7895
- new Command75("set").description("set an environment variable").argument("<key>", "variable name").argument("[value]", "value \u2014 prompted for, without echo, when omitted").configureHelp(helpConfig),
8145
+ new Command78("set").description("set an environment variable").argument("<key>", "variable name").argument("[value]", "value \u2014 prompted for, without echo, when omitted").configureHelp(helpConfig),
7896
8146
  "local"
7897
8147
  ).action(
7898
8148
  (key, value, raw) => runCommand(
@@ -7902,14 +8152,14 @@ var envSet = addTargetOptions(
7902
8152
  local: async (ctx) => {
7903
8153
  const resolved = await resolveValue(key, value);
7904
8154
  setLocalEnv(ctx.envFile, key, resolved);
7905
- p38.log.success(`${key} updated ${pc18.dim("(local)")}`);
8155
+ p43.log.success(`${key} updated ${pc18.dim("(local)")}`);
7906
8156
  await applyLocalEnvChange(ctx, [key]);
7907
8157
  },
7908
8158
  remote: async (ctx) => {
7909
8159
  const resolved = await resolveValue(key, value);
7910
8160
  const env2 = await readRemoteEnv(ctx.session, ctx.instance);
7911
8161
  await writeRemoteEnv(ctx.session, ctx.instance, { ...env2, [key]: resolved });
7912
- p38.log.success(`${key} updated ${pc18.dim(`(${ctx.targetName})`)}`);
8162
+ p43.log.success(`${key} updated ${pc18.dim(`(${ctx.targetName})`)}`);
7913
8163
  await applyEnvRestart(ctx, [key]);
7914
8164
  }
7915
8165
  },
@@ -7923,23 +8173,23 @@ async function resolveValue(key, value) {
7923
8173
  return value ?? await promptValue(key);
7924
8174
  }
7925
8175
  async function promptValue(key) {
7926
- const value = await p38.password({
8176
+ const value = await p43.password({
7927
8177
  message: `Value for ${pc18.cyan(key)}`,
7928
8178
  validate: (input) => !input?.length ? "Required" : void 0
7929
8179
  });
7930
- if (p38.isCancel(value)) {
7931
- p38.cancel("Operation cancelled.");
8180
+ if (p43.isCancel(value)) {
8181
+ p43.cancel("Operation cancelled.");
7932
8182
  process27.exit(0);
7933
8183
  }
7934
8184
  return value;
7935
8185
  }
7936
8186
 
7937
8187
  // src/commands/env/unset.ts
7938
- import { Command as Command76 } from "commander";
7939
- import * as p39 from "@clack/prompts";
8188
+ import { Command as Command79 } from "commander";
8189
+ import * as p44 from "@clack/prompts";
7940
8190
  import pc19 from "picocolors";
7941
8191
  var envUnset = addTargetOptions(
7942
- new Command76("unset").description("remove an environment variable").argument("<key>", "variable name").configureHelp(helpConfig),
8192
+ new Command79("unset").description("remove an environment variable").argument("<key>", "variable name").configureHelp(helpConfig),
7943
8193
  "local"
7944
8194
  ).action(
7945
8195
  (key, raw) => runCommand(
@@ -7948,22 +8198,22 @@ var envUnset = addTargetOptions(
7948
8198
  {
7949
8199
  local: async (ctx) => {
7950
8200
  if (!(key in readLocalEnv(ctx.envFile))) {
7951
- p39.log.info(`${key} is not set \u2014 nothing to remove.`);
8201
+ p44.log.info(`${key} is not set \u2014 nothing to remove.`);
7952
8202
  return;
7953
8203
  }
7954
8204
  unsetLocalEnv(ctx.envFile, key);
7955
- p39.log.success(`${key} removed ${pc19.dim("(local)")}`);
8205
+ p44.log.success(`${key} removed ${pc19.dim("(local)")}`);
7956
8206
  await applyLocalEnvChange(ctx, [key]);
7957
8207
  },
7958
8208
  remote: async (ctx) => {
7959
8209
  const env2 = await readRemoteEnv(ctx.session, ctx.instance);
7960
8210
  if (!(key in env2)) {
7961
- p39.log.info(`${key} is not set \u2014 nothing to remove.`);
8211
+ p44.log.info(`${key} is not set \u2014 nothing to remove.`);
7962
8212
  return;
7963
8213
  }
7964
8214
  delete env2[key];
7965
8215
  await writeRemoteEnv(ctx.session, ctx.instance, env2);
7966
- p39.log.success(`${key} removed ${pc19.dim(`(${ctx.targetName})`)}`);
8216
+ p44.log.success(`${key} removed ${pc19.dim(`(${ctx.targetName})`)}`);
7967
8217
  await applyEnvRestart(ctx, [key]);
7968
8218
  }
7969
8219
  },
@@ -7974,14 +8224,14 @@ var envUnset = addTargetOptions(
7974
8224
  );
7975
8225
 
7976
8226
  // src/commands/env/import.ts
7977
- import fs34 from "node:fs";
8227
+ import fs35 from "node:fs";
7978
8228
  import path38 from "node:path";
7979
8229
  import process28 from "node:process";
7980
- import { Command as Command77 } from "commander";
7981
- import * as p40 from "@clack/prompts";
8230
+ import { Command as Command80 } from "commander";
8231
+ import * as p45 from "@clack/prompts";
7982
8232
  import pc20 from "picocolors";
7983
8233
  var envImport = addTargetOptions(
7984
- new Command77("import").description("merge a dotenv file into the environment").argument("<file>", "dotenv file to read").configureHelp(helpConfig),
8234
+ new Command80("import").description("merge a dotenv file into the environment").argument("<file>", "dotenv file to read").configureHelp(helpConfig),
7985
8235
  "local"
7986
8236
  ).action(
7987
8237
  (file, raw) => runCommand(
@@ -7996,22 +8246,22 @@ var envImport = addTargetOptions(
7996
8246
  const incoming = read(source, file);
7997
8247
  const keys = Object.keys(incoming);
7998
8248
  if (keys.length === 0) return;
7999
- p40.log.step(`Importing ${keys.length} variable(s) from ${pc20.cyan(file)}`);
8249
+ p45.log.step(`Importing ${keys.length} variable(s) from ${pc20.cyan(file)}`);
8000
8250
  editLocalEnv(
8001
8251
  ctx.envFile,
8002
8252
  (content) => keys.reduce((acc, key) => upsertEnvVar(acc, key, incoming[key]), content)
8003
8253
  );
8004
- p40.log.success(`${keys.length} variable(s) updated ${pc20.dim("(local)")}`);
8254
+ p45.log.success(`${keys.length} variable(s) updated ${pc20.dim("(local)")}`);
8005
8255
  await applyLocalEnvChange(ctx, keys);
8006
8256
  },
8007
8257
  remote: async (ctx) => {
8008
8258
  const incoming = read(resolve(file), file);
8009
8259
  const keys = Object.keys(incoming);
8010
8260
  if (keys.length === 0) return;
8011
- p40.log.step(`Importing ${keys.length} variable(s) from ${pc20.cyan(file)}`);
8261
+ p45.log.step(`Importing ${keys.length} variable(s) from ${pc20.cyan(file)}`);
8012
8262
  const existing = await readRemoteEnv(ctx.session, ctx.instance);
8013
8263
  await writeRemoteEnv(ctx.session, ctx.instance, { ...existing, ...incoming });
8014
- p40.log.success(`${keys.length} variable(s) updated ${pc20.dim(`(${ctx.targetName})`)}`);
8264
+ p45.log.success(`${keys.length} variable(s) updated ${pc20.dim(`(${ctx.targetName})`)}`);
8015
8265
  await applyEnvRestart(ctx, keys);
8016
8266
  }
8017
8267
  },
@@ -8024,21 +8274,21 @@ function resolve(file) {
8024
8274
  return path38.resolve(process28.cwd(), file);
8025
8275
  }
8026
8276
  function read(resolved, shown) {
8027
- if (!fs34.existsSync(resolved)) throw new Error(`${shown} does not exist.`);
8277
+ if (!fs35.existsSync(resolved)) throw new Error(`${shown} does not exist.`);
8028
8278
  const incoming = readLocalEnvFile(resolved);
8029
- if (Object.keys(incoming).length === 0) p40.log.info(`${shown} has no variables to import.`);
8279
+ if (Object.keys(incoming).length === 0) p45.log.info(`${shown} has no variables to import.`);
8030
8280
  return incoming;
8031
8281
  }
8032
8282
 
8033
8283
  // src/commands/env.ts
8034
- var env = new Command78("env").description("manage environment variables, locally or on a target").configureHelp(helpConfig).addCommand(envList).addCommand(envSet).addCommand(envUnset).addCommand(envImport);
8284
+ var env = new Command81("env").description("manage environment variables, locally or on a target").configureHelp(helpConfig).addCommand(envList).addCommand(envSet).addCommand(envUnset).addCommand(envImport);
8035
8285
 
8036
8286
  // src/commands/status.ts
8037
- import { Command as Command79 } from "commander";
8038
- import * as p41 from "@clack/prompts";
8287
+ import { Command as Command82 } from "commander";
8288
+ import * as p46 from "@clack/prompts";
8039
8289
  import pc21 from "picocolors";
8040
8290
  var status = addTargetOptions(
8041
- new Command79("status").description("show what is deployed").configureHelp(helpConfig),
8291
+ new Command82("status").description("show what is deployed").configureHelp(helpConfig),
8042
8292
  "production"
8043
8293
  ).option("--all", "show every app on the server, not just this project").option("--json", "print raw JSON").action(
8044
8294
  (raw) => runCommand(async () => {
@@ -8069,11 +8319,11 @@ function report2(states, json) {
8069
8319
  return;
8070
8320
  }
8071
8321
  if (states.length === 0) {
8072
- p41.log.info("Nothing is deployed here yet.");
8322
+ p46.log.info("Nothing is deployed here yet.");
8073
8323
  return;
8074
8324
  }
8075
8325
  for (const state of states) {
8076
- p41.log.info(describe(state));
8326
+ p46.log.info(describe(state));
8077
8327
  }
8078
8328
  }
8079
8329
  function describe(state) {
@@ -8096,11 +8346,11 @@ function describe(state) {
8096
8346
  }
8097
8347
 
8098
8348
  // src/commands/rollback.ts
8099
- import { Command as Command80 } from "commander";
8100
- import * as p42 from "@clack/prompts";
8349
+ import { Command as Command83 } from "commander";
8350
+ import * as p47 from "@clack/prompts";
8101
8351
  import pc22 from "picocolors";
8102
8352
  var rollback = addTargetOptions(
8103
- new Command80("rollback").description("put the previous release back").configureHelp(helpConfig),
8353
+ new Command83("rollback").description("put the previous release back").configureHelp(helpConfig),
8104
8354
  "production"
8105
8355
  ).option("--to <release>", "roll back to a specific release instead of the previous one").action(
8106
8356
  (raw) => runCommand(async () => {
@@ -8109,7 +8359,7 @@ var rollback = addTargetOptions(
8109
8359
  raw,
8110
8360
  {
8111
8361
  remote: async (ctx) => {
8112
- p42.log.step(
8362
+ p47.log.step(
8113
8363
  `Rolling back ${pc22.cyan(ctx.appName)} ${pc22.dim(`(${ctx.targetName})`)} on ${ctx.server}`
8114
8364
  );
8115
8365
  const result = await runServerScript(
@@ -8120,7 +8370,7 @@ var rollback = addTargetOptions(
8120
8370
  stream: true
8121
8371
  }
8122
8372
  );
8123
- p42.log.success(
8373
+ p47.log.success(
8124
8374
  `Rolled back to ${pc22.cyan(result?.release ?? "the previous release")}` + (result?.from ? ` ${pc22.dim(`(was ${result.from})`)}` : "")
8125
8375
  );
8126
8376
  }
@@ -8134,9 +8384,9 @@ var rollback = addTargetOptions(
8134
8384
  );
8135
8385
 
8136
8386
  // src/commands/logs.ts
8137
- import { Command as Command81 } from "commander";
8387
+ import { Command as Command84 } from "commander";
8138
8388
  var logs = addTargetOptions(
8139
- new Command81("logs").description("tail the logs of a deployed app").configureHelp(helpConfig),
8389
+ new Command84("logs").description("tail the logs of a deployed app").configureHelp(helpConfig),
8140
8390
  "production"
8141
8391
  ).option("-f, --follow", "keep streaming new output").option("-n, --lines <count>", "how many lines of history to show", "100").option("--pocketbase", "show the PocketBase service instead of the app").action(
8142
8392
  (raw) => runCommand(async () => {
@@ -8170,16 +8420,16 @@ var logs = addTargetOptions(
8170
8420
  );
8171
8421
 
8172
8422
  // src/commands/admin.ts
8173
- import { Command as Command83 } from "commander";
8423
+ import { Command as Command86 } from "commander";
8174
8424
 
8175
8425
  // src/commands/admin/create.ts
8176
8426
  import process29 from "node:process";
8177
- import { Command as Command82 } from "commander";
8178
- import * as p43 from "@clack/prompts";
8427
+ import { Command as Command85 } from "commander";
8428
+ import * as p48 from "@clack/prompts";
8179
8429
  import pc23 from "picocolors";
8180
8430
  var MIN_PASSWORD = 10;
8181
8431
  var adminCreate = addTargetOptions(
8182
- new Command82("create").description("create a login for the admin panel").argument("[email]", "email to sign in with \u2014 prompted for when omitted").configureHelp(helpConfig),
8432
+ new Command85("create").description("create a login for the admin panel").argument("[email]", "email to sign in with \u2014 prompted for when omitted").configureHelp(helpConfig),
8183
8433
  "local"
8184
8434
  ).action(
8185
8435
  (email3, raw) => runCommand(
@@ -8207,7 +8457,7 @@ var adminCreate = addTargetOptions(
8207
8457
  const metadata = getPocketbaseMetadata(ctx.workspaceRootDir);
8208
8458
  if (metadata) signIn = `http://${metadata.viteHost}:${metadata.vitePort}`;
8209
8459
  }
8210
- p43.log.info(
8460
+ p48.log.info(
8211
8461
  signIn ? `Sign in at ${pc23.cyan(`${signIn}/admin`)}` : `Sign in at ${pc23.cyan("/admin")} once ${pc23.cyan("vela dev")} is running.`
8212
8462
  );
8213
8463
  },
@@ -8221,7 +8471,7 @@ var adminCreate = addTargetOptions(
8221
8471
  (pb) => upsertSuperuser(pb, address, password11)
8222
8472
  );
8223
8473
  const base2 = state?.domain ? `https://${state.domain.split(",")[0].trim()}` : "";
8224
- p43.log.info(
8474
+ p48.log.info(
8225
8475
  base2 ? `Sign in at ${pc23.cyan(`${base2}/admin`)}` : `Sign in at ${pc23.cyan("/admin")} once a domain is configured for this target.`
8226
8476
  );
8227
8477
  }
@@ -8234,20 +8484,20 @@ var adminCreate = addTargetOptions(
8234
8484
  async function upsertSuperuser(pb, email3, password11) {
8235
8485
  const existing = await findSuperuser(pb, email3);
8236
8486
  if (existing) {
8237
- const confirmed = await p43.confirm({
8487
+ const confirmed = await p48.confirm({
8238
8488
  message: `${email3} already has an account, update its password?`,
8239
8489
  initialValue: false
8240
8490
  });
8241
- if (p43.isCancel(confirmed) || !confirmed) {
8242
- p43.cancel("Operation cancelled.");
8491
+ if (p48.isCancel(confirmed) || !confirmed) {
8492
+ p48.cancel("Operation cancelled.");
8243
8493
  process29.exit(0);
8244
8494
  }
8245
8495
  await pb.collection("_superusers").update(existing, { password: password11, passwordConfirm: password11 });
8246
- p43.log.success(`Password updated for ${pc23.cyan(email3)}, you can sign in now`);
8496
+ p48.log.success(`Password updated for ${pc23.cyan(email3)}, you can sign in now`);
8247
8497
  return;
8248
8498
  }
8249
8499
  await pb.collection("_superusers").create({ email: email3, password: password11, passwordConfirm: password11 });
8250
- p43.log.success(`${pc23.cyan(email3)} can now sign in`);
8500
+ p48.log.success(`${pc23.cyan(email3)} can now sign in`);
8251
8501
  }
8252
8502
  async function findSuperuser(pb, email3) {
8253
8503
  try {
@@ -8258,47 +8508,47 @@ async function findSuperuser(pb, email3) {
8258
8508
  }
8259
8509
  }
8260
8510
  async function promptEmail() {
8261
- const value = await p43.text({
8511
+ const value = await p48.text({
8262
8512
  message: "Email to sign in with",
8263
8513
  validate: (input) => input?.includes("@") ? void 0 : "An email address is required"
8264
8514
  });
8265
- if (p43.isCancel(value)) {
8266
- p43.cancel("Operation cancelled.");
8515
+ if (p48.isCancel(value)) {
8516
+ p48.cancel("Operation cancelled.");
8267
8517
  process29.exit(0);
8268
8518
  }
8269
8519
  return value.trim();
8270
8520
  }
8271
8521
  async function promptPassword2() {
8272
- const value = await p43.password({
8522
+ const value = await p48.password({
8273
8523
  message: "Password",
8274
8524
  validate: (input) => (input?.length ?? 0) >= MIN_PASSWORD ? void 0 : `At least ${MIN_PASSWORD} characters is required`
8275
8525
  });
8276
- if (p43.isCancel(value)) {
8277
- p43.cancel("Operation cancelled.");
8526
+ if (p48.isCancel(value)) {
8527
+ p48.cancel("Operation cancelled.");
8278
8528
  process29.exit(0);
8279
8529
  }
8280
- const again = await p43.password({
8530
+ const again = await p48.password({
8281
8531
  message: "Password again",
8282
8532
  validate: (input) => input === value ? void 0 : "The two do not match"
8283
8533
  });
8284
- if (p43.isCancel(again)) {
8285
- p43.cancel("Operation cancelled.");
8534
+ if (p48.isCancel(again)) {
8535
+ p48.cancel("Operation cancelled.");
8286
8536
  process29.exit(0);
8287
8537
  }
8288
8538
  return value;
8289
8539
  }
8290
8540
 
8291
8541
  // src/commands/admin.ts
8292
- var admin = new Command83("admin").description("manage admin panel logins").configureHelp(helpConfig).addCommand(adminCreate);
8542
+ var admin = new Command86("admin").description("manage admin panel logins").configureHelp(helpConfig).addCommand(adminCreate);
8293
8543
 
8294
8544
  // src/commands/backup.ts
8295
- import { Command as Command89 } from "commander";
8545
+ import { Command as Command92 } from "commander";
8296
8546
 
8297
8547
  // src/commands/backup/create.ts
8298
- import fs35 from "node:fs";
8548
+ import fs36 from "node:fs";
8299
8549
  import path39 from "node:path";
8300
- import { Command as Command84 } from "commander";
8301
- import * as p44 from "@clack/prompts";
8550
+ import { Command as Command87 } from "commander";
8551
+ import * as p49 from "@clack/prompts";
8302
8552
  import pc24 from "picocolors";
8303
8553
 
8304
8554
  // src/lib/backups.ts
@@ -8320,8 +8570,8 @@ async function readStorageSettings(pb) {
8320
8570
  };
8321
8571
  }
8322
8572
  async function listBackups(pb) {
8323
- const list2 = await pb.backups.getFullList();
8324
- return [...list2].sort((a, b) => b.modified.localeCompare(a.modified));
8573
+ const list3 = await pb.backups.getFullList();
8574
+ return [...list3].sort((a, b) => b.modified.localeCompare(a.modified));
8325
8575
  }
8326
8576
  function isClientTimeout(error) {
8327
8577
  for (let e = error, depth = 0; e && depth < 5; depth++) {
@@ -8386,7 +8636,7 @@ async function writeSchedule(pb, cron, maxKeep) {
8386
8636
  // src/commands/backup/create.ts
8387
8637
  var DEFAULT_BACKUP_DIR = "backups";
8388
8638
  var backupCreate = addTargetOptions(
8389
- new Command84("create").description("take a backup of the database and uploads").argument("[name]", "name for the archive \u2014 generated when omitted").option("-o, --output <dir>", "where to save the archive", DEFAULT_BACKUP_DIR).option("--no-download", "leave the archive on the server").configureHelp(helpConfig),
8639
+ new Command87("create").description("take a backup of the database and uploads").argument("[name]", "name for the archive \u2014 generated when omitted").option("-o, --output <dir>", "where to save the archive", DEFAULT_BACKUP_DIR).option("--no-download", "leave the archive on the server").configureHelp(helpConfig),
8390
8640
  "production"
8391
8641
  ).action(
8392
8642
  (name, raw) => runCommand(() => {
@@ -8402,7 +8652,7 @@ Backup names are lowercase letters, digits, ${pc24.cyan("-")} and ${pc24.cyan("_
8402
8652
  }
8403
8653
  const storage = await readStorageSettings(ctx.pb);
8404
8654
  if (storage.s3Enabled) {
8405
- p44.log.warn(
8655
+ p49.log.warn(
8406
8656
  `Uploads are stored in S3, so this archive holds the database only.
8407
8657
 
8408
8658
  PocketBase leaves ${pc24.cyan("storage/")} out of a backup whenever S3 is on.
@@ -8410,16 +8660,16 @@ Your bucket's own versioning is what protects the uploaded files.`
8410
8660
  );
8411
8661
  }
8412
8662
  if (ctx.session) await checkpointAppDatabases(ctx.session, ctx.instance);
8413
- const spinner5 = p44.spinner();
8414
- spinner5.start(`Backing up ${ctx.targetName}`);
8663
+ const spinner7 = p49.spinner();
8664
+ spinner7.start(`Backing up ${ctx.targetName}`);
8415
8665
  try {
8416
8666
  await createBackup(ctx.pb, key);
8417
8667
  } catch (error) {
8418
- spinner5.stop(`Backup of ${ctx.targetName} failed.`);
8668
+ spinner7.stop(`Backup of ${ctx.targetName} failed.`);
8419
8669
  throw error;
8420
8670
  }
8421
8671
  const size = (await listBackups(ctx.pb)).find((b) => b.key === key)?.size ?? 0;
8422
- spinner5.stop(`Backed up ${ctx.targetName} \u2014 ${key} (${formatBytes(size)})`);
8672
+ spinner7.stop(`Backed up ${ctx.targetName} \u2014 ${key} (${formatBytes(size)})`);
8423
8673
  if (storage.backupsS3Enabled) {
8424
8674
  reportResult({
8425
8675
  summary: `Backed up ${ctx.targetName} to your backups bucket.`,
@@ -8451,37 +8701,37 @@ Your bucket's own versioning is what protects the uploaded files.`
8451
8701
  );
8452
8702
  async function download(ctx, key, outputDir) {
8453
8703
  const dir = path39.resolve(ctx.workspaceRootDir, outputDir);
8454
- fs35.mkdirSync(dir, { recursive: true });
8704
+ fs36.mkdirSync(dir, { recursive: true });
8455
8705
  const destination = path39.join(dir, key);
8456
8706
  if (!ctx.session) {
8457
- fs35.copyFileSync(path39.join(ctx.workspaceRootDir, "data", "backups", key), destination);
8707
+ fs36.copyFileSync(path39.join(ctx.workspaceRootDir, "data", "backups", key), destination);
8458
8708
  return path39.relative(ctx.workspaceRootDir, destination);
8459
8709
  }
8460
- const spinner5 = p44.spinner();
8461
- spinner5.start(`Downloading ${key}`);
8710
+ const spinner7 = p49.spinner();
8711
+ spinner7.start(`Downloading ${key}`);
8462
8712
  try {
8463
8713
  await ctx.session.download(remotePaths.backup(ctx.instance, key), destination);
8464
8714
  } catch (error) {
8465
- spinner5.stop(`Could not download ${key}.`);
8715
+ spinner7.stop(`Could not download ${key}.`);
8466
8716
  throw error;
8467
8717
  }
8468
- spinner5.stop(`Downloaded ${key}`);
8718
+ spinner7.stop(`Downloaded ${key}`);
8469
8719
  return path39.relative(ctx.workspaceRootDir, destination);
8470
8720
  }
8471
8721
 
8472
8722
  // src/commands/backup/list.ts
8473
- import { Command as Command85 } from "commander";
8474
- import * as p45 from "@clack/prompts";
8723
+ import { Command as Command88 } from "commander";
8724
+ import * as p50 from "@clack/prompts";
8475
8725
  import pc25 from "picocolors";
8476
8726
  var backupList = addTargetOptions(
8477
- new Command85("list").description("list the backups on a target").configureHelp(helpConfig),
8727
+ new Command88("list").description("list the backups on a target").configureHelp(helpConfig),
8478
8728
  "production"
8479
8729
  ).action(
8480
8730
  (raw) => runCommand(
8481
8731
  () => withBackupTarget(raw, "backup list", async (ctx) => {
8482
8732
  const backups = await listBackups(ctx.pb);
8483
8733
  if (backups.length === 0) {
8484
- p45.log.info(
8734
+ p50.log.info(
8485
8735
  `${pc25.cyan(ctx.targetName)} has no backups yet.
8486
8736
 
8487
8737
  Take one with ${pc25.cyan("vela backup create")}.`
@@ -8489,7 +8739,7 @@ Take one with ${pc25.cyan("vela backup create")}.`
8489
8739
  return;
8490
8740
  }
8491
8741
  const width = Math.max(...backups.map((b) => b.key.length));
8492
- p45.log.message(
8742
+ p50.log.message(
8493
8743
  backups.map(
8494
8744
  (b) => `${b.key.padEnd(width)} ${pc25.dim(formatBytes(b.size).padStart(8))} ${pc25.dim(b.modified)}`
8495
8745
  ).join("\n")
@@ -8500,13 +8750,13 @@ Take one with ${pc25.cyan("vela backup create")}.`
8500
8750
  );
8501
8751
 
8502
8752
  // src/commands/backup/download.ts
8503
- import fs36 from "node:fs";
8753
+ import fs37 from "node:fs";
8504
8754
  import path40 from "node:path";
8505
- import { Command as Command86 } from "commander";
8506
- import * as p46 from "@clack/prompts";
8755
+ import { Command as Command89 } from "commander";
8756
+ import * as p51 from "@clack/prompts";
8507
8757
  import pc26 from "picocolors";
8508
8758
  var backupDownload = addTargetOptions(
8509
- new Command86("download").description("save a backup off the server").argument("<key>", "archive to download, as shown by `vela backup list`").option("-o, --output <dir>", "where to save the archive", DEFAULT_BACKUP_DIR).configureHelp(helpConfig),
8759
+ new Command89("download").description("save a backup off the server").argument("<key>", "archive to download, as shown by `vela backup list`").option("-o, --output <dir>", "where to save the archive", DEFAULT_BACKUP_DIR).configureHelp(helpConfig),
8510
8760
  "production"
8511
8761
  ).action(
8512
8762
  (key, raw) => runCommand(() => {
@@ -8529,20 +8779,20 @@ Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
8529
8779
  );
8530
8780
  }
8531
8781
  const dir = path40.resolve(ctx.workspaceRootDir, options.output);
8532
- fs36.mkdirSync(dir, { recursive: true });
8782
+ fs37.mkdirSync(dir, { recursive: true });
8533
8783
  const destination = path40.join(dir, key);
8534
8784
  if (!ctx.session) {
8535
- fs36.copyFileSync(path40.join(ctx.workspaceRootDir, "data", "backups", key), destination);
8785
+ fs37.copyFileSync(path40.join(ctx.workspaceRootDir, "data", "backups", key), destination);
8536
8786
  } else {
8537
- const spinner5 = p46.spinner();
8538
- spinner5.start(`Downloading ${key} (${formatBytes(found.size)})`);
8787
+ const spinner7 = p51.spinner();
8788
+ spinner7.start(`Downloading ${key} (${formatBytes(found.size)})`);
8539
8789
  try {
8540
8790
  await ctx.session.download(remotePaths.backup(ctx.instance, key), destination);
8541
8791
  } catch (error) {
8542
- spinner5.stop(`Could not download ${key}.`);
8792
+ spinner7.stop(`Could not download ${key}.`);
8543
8793
  throw error;
8544
8794
  }
8545
- spinner5.stop(`Downloaded ${key}`);
8795
+ spinner7.stop(`Downloaded ${key}`);
8546
8796
  }
8547
8797
  reportResult({
8548
8798
  summary: `Saved ${key} from ${ctx.targetName}.`,
@@ -8554,11 +8804,11 @@ Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
8554
8804
 
8555
8805
  // src/commands/backup/delete.ts
8556
8806
  import process30 from "node:process";
8557
- import { Command as Command87 } from "commander";
8558
- import * as p47 from "@clack/prompts";
8807
+ import { Command as Command90 } from "commander";
8808
+ import * as p52 from "@clack/prompts";
8559
8809
  import pc27 from "picocolors";
8560
8810
  var backupDelete = addTargetOptions(
8561
- new Command87("delete").description("remove a backup from a target").argument("<key>", "archive to delete, as shown by `vela backup list`").option("-y, --yes", "skip the confirmation").configureHelp(helpConfig),
8811
+ new Command90("delete").description("remove a backup from a target").argument("<key>", "archive to delete, as shown by `vela backup list`").option("-y, --yes", "skip the confirmation").configureHelp(helpConfig),
8562
8812
  "production"
8563
8813
  ).action(
8564
8814
  (key, raw) => runCommand(() => {
@@ -8573,12 +8823,12 @@ Run ${pc27.cyan("vela backup list")} to see what it does have.`
8573
8823
  );
8574
8824
  }
8575
8825
  if (!options.yes) {
8576
- const confirmed = await p47.confirm({
8826
+ const confirmed = await p52.confirm({
8577
8827
  message: `Delete ${key} (${formatBytes(found.size)}) from ${ctx.targetName}?`,
8578
8828
  initialValue: false
8579
8829
  });
8580
- if (p47.isCancel(confirmed) || !confirmed) {
8581
- p47.cancel("Operation cancelled.");
8830
+ if (p52.isCancel(confirmed) || !confirmed) {
8831
+ p52.cancel("Operation cancelled.");
8582
8832
  process30.exit(0);
8583
8833
  }
8584
8834
  }
@@ -8589,12 +8839,12 @@ Run ${pc27.cyan("vela backup list")} to see what it does have.`
8589
8839
  );
8590
8840
 
8591
8841
  // src/commands/backup/schedule.ts
8592
- import { Command as Command88 } from "commander";
8593
- import * as p48 from "@clack/prompts";
8842
+ import { Command as Command91 } from "commander";
8843
+ import * as p53 from "@clack/prompts";
8594
8844
  import pc28 from "picocolors";
8595
8845
  var DEFAULT_KEEP = 7;
8596
8846
  var backupSchedule = addTargetOptions(
8597
- new Command88("schedule").description("back up automatically on a schedule").argument("[cron]", "when to run, as a cron expression \u2014 shows the current one when omitted").option("--keep <n>", "how many scheduled archives to keep", String(DEFAULT_KEEP)).option("--off", "stop backing up automatically").configureHelp(helpConfig),
8847
+ new Command91("schedule").description("back up automatically on a schedule").argument("[cron]", "when to run, as a cron expression \u2014 shows the current one when omitted").option("--keep <n>", "how many scheduled archives to keep", String(DEFAULT_KEEP)).option("--off", "stop backing up automatically").configureHelp(helpConfig),
8598
8848
  "production"
8599
8849
  ).action(
8600
8850
  (cron, raw) => runCommand(() => {
@@ -8607,7 +8857,7 @@ var backupSchedule = addTargetOptions(
8607
8857
  }
8608
8858
  if (!cron) {
8609
8859
  const current = await readSchedule(ctx.pb);
8610
- p48.log.info(
8860
+ p53.log.info(
8611
8861
  current.cron ? `${ctx.targetName} backs up on ${pc28.cyan(current.cron)}, keeping ${current.maxKeep}.` : `${ctx.targetName} has no backup schedule.
8612
8862
 
8613
8863
  Set one with ${pc28.cyan('vela backup schedule "0 3 * * *"')}.`
@@ -8638,17 +8888,17 @@ Set one with ${pc28.cyan('vela backup schedule "0 3 * * *"')}.`
8638
8888
  );
8639
8889
 
8640
8890
  // src/commands/backup.ts
8641
- var backup = new Command89("backup").description("back up the database and uploads, locally or on a target").configureHelp(helpConfig).addCommand(backupCreate).addCommand(backupList).addCommand(backupDownload).addCommand(backupDelete).addCommand(backupSchedule);
8891
+ var backup = new Command92("backup").description("back up the database and uploads, locally or on a target").configureHelp(helpConfig).addCommand(backupCreate).addCommand(backupList).addCommand(backupDownload).addCommand(backupDelete).addCommand(backupSchedule);
8642
8892
 
8643
8893
  // src/commands/restore.ts
8644
- import fs37 from "node:fs";
8894
+ import fs38 from "node:fs";
8645
8895
  import path41 from "node:path";
8646
8896
  import process31 from "node:process";
8647
- import { Command as Command90 } from "commander";
8648
- import * as p49 from "@clack/prompts";
8897
+ import { Command as Command93 } from "commander";
8898
+ import * as p54 from "@clack/prompts";
8649
8899
  import pc29 from "picocolors";
8650
8900
  var restore = addTargetOptions(
8651
- new Command90("restore").description("replace a deployment\u2019s database and uploads from a backup").argument("[source]", "a backup key on the target, or a path to a local archive").configureHelp(helpConfig),
8901
+ new Command93("restore").description("replace a deployment\u2019s database and uploads from a backup").argument("[source]", "a backup key on the target, or a path to a local archive").configureHelp(helpConfig),
8652
8902
  "production"
8653
8903
  ).option("-y, --yes", "skip the confirmation prompt").option("--no-migrate", "do not run migrations against the restored database").option("--keep-previous <n>", "how many replaced databases to keep", "1").action(
8654
8904
  (source, raw) => runCommand(async () => {
@@ -8663,10 +8913,10 @@ var restore = addTargetOptions(
8663
8913
  `${ctx.targetName} was deployed without a database, so there is nothing to restore.`
8664
8914
  );
8665
8915
  }
8666
- const local = source && fs37.existsSync(source) ? source : void 0;
8916
+ const local = source && fs38.existsSync(source) ? source : void 0;
8667
8917
  const key = local ? void 0 : await resolveKey(ctx, source);
8668
8918
  if (!options.yes) {
8669
- await confirm11(ctx.appName, ctx.targetName, ctx.envTag, local ?? key);
8919
+ await confirm12(ctx.appName, ctx.targetName, ctx.envTag, local ?? key);
8670
8920
  }
8671
8921
  const archive = local ? await stage(ctx, local) : remotePaths.backup(ctx.instance, key);
8672
8922
  const result = await runServerScript(ctx.session, "restore.sh", {
@@ -8683,18 +8933,18 @@ var restore = addTargetOptions(
8683
8933
  ],
8684
8934
  stream: true
8685
8935
  });
8686
- p49.log.success(
8936
+ p54.log.success(
8687
8937
  `Restored ${pc29.cyan(`${ctx.appName} (${ctx.targetName})`)} from ${pc29.cyan(
8688
8938
  local ? path41.basename(local) : key
8689
8939
  )}.`
8690
8940
  );
8691
8941
  if (result?.storageCarriedOver) {
8692
- p49.log.info(
8942
+ p54.log.info(
8693
8943
  "The archive held no uploads, so the files already on the server were kept."
8694
8944
  );
8695
8945
  }
8696
8946
  if (result?.previousDataDir) {
8697
- p49.log.info(
8947
+ p54.log.info(
8698
8948
  `The database this replaced is at ${pc29.cyan(result.previousDataDir)}.
8699
8949
 
8700
8950
  It is the only way back. Remove it once you are satisfied with the restore.`
@@ -8735,7 +8985,7 @@ Run ${pc29.cyan("vela backup list")} to see what it does have.`
8735
8985
  Take one with ${pc29.cyan("vela backup create")}, or pass the path to an archive on this machine.`
8736
8986
  );
8737
8987
  }
8738
- const chosen = await p49.select({
8988
+ const chosen = await p54.select({
8739
8989
  message: `Which backup should ${ctx.targetName} be restored from?`,
8740
8990
  options: backups.map((b) => ({
8741
8991
  value: b.key,
@@ -8743,8 +8993,8 @@ Take one with ${pc29.cyan("vela backup create")}, or pass the path to an archive
8743
8993
  hint: `${formatBytes(b.size)}, ${b.modified}`
8744
8994
  }))
8745
8995
  });
8746
- if (p49.isCancel(chosen)) {
8747
- p49.cancel("Operation cancelled.");
8996
+ if (p54.isCancel(chosen)) {
8997
+ p54.cancel("Operation cancelled.");
8748
8998
  process31.exit(0);
8749
8999
  }
8750
9000
  return chosen;
@@ -8752,44 +9002,44 @@ Take one with ${pc29.cyan("vela backup create")}, or pass the path to an archive
8752
9002
  async function stage(ctx, file) {
8753
9003
  const dir = remotePaths.restoreStage(ctx.instance);
8754
9004
  const remote = `${dir}/${path41.basename(file)}`;
8755
- const spinner5 = p49.spinner();
8756
- spinner5.start(`Uploading ${path41.basename(file)}`);
9005
+ const spinner7 = p54.spinner();
9006
+ spinner7.start(`Uploading ${path41.basename(file)}`);
8757
9007
  try {
8758
9008
  await ctx.session.script(`mkdir -p "$1"`, { args: [dir] });
8759
9009
  await ctx.session.upload([file], dir);
8760
9010
  } catch (error) {
8761
- spinner5.stop(`Could not upload ${path41.basename(file)}.`);
9011
+ spinner7.stop(`Could not upload ${path41.basename(file)}.`);
8762
9012
  throw error;
8763
9013
  }
8764
- spinner5.stop(`Uploaded ${path41.basename(file)}`);
9014
+ spinner7.stop(`Uploaded ${path41.basename(file)}`);
8765
9015
  return remote;
8766
9016
  }
8767
- async function confirm11(appName, targetName, envTag, from) {
9017
+ async function confirm12(appName, targetName, envTag, from) {
8768
9018
  const what = `${pc29.cyan(`${appName} (${targetName})`)} from ${pc29.cyan(path41.basename(from))}`;
8769
9019
  if (isProd(envTag)) {
8770
- const answer = await p49.text({
9020
+ const answer = await p54.text({
8771
9021
  message: `This replaces the database and uploads of ${what}. Type the app name to confirm`,
8772
9022
  validate: (value) => value === appName ? void 0 : `Type ${appName} to confirm`
8773
9023
  });
8774
- if (p49.isCancel(answer)) {
8775
- p49.cancel("Operation cancelled.");
9024
+ if (p54.isCancel(answer)) {
9025
+ p54.cancel("Operation cancelled.");
8776
9026
  process31.exit(0);
8777
9027
  }
8778
9028
  return;
8779
9029
  }
8780
- const ok = await p49.confirm({
9030
+ const ok = await p54.confirm({
8781
9031
  message: `Replace the database and uploads of ${what}?`,
8782
9032
  initialValue: false
8783
9033
  });
8784
- if (p49.isCancel(ok) || !ok) {
8785
- p49.cancel("Operation cancelled.");
9034
+ if (p54.isCancel(ok) || !ok) {
9035
+ p54.cancel("Operation cancelled.");
8786
9036
  process31.exit(0);
8787
9037
  }
8788
9038
  }
8789
9039
 
8790
9040
  // src/commands/targets.ts
8791
- import { Command as Command91 } from "commander";
8792
- import * as p50 from "@clack/prompts";
9041
+ import { Command as Command94 } from "commander";
9042
+ import * as p55 from "@clack/prompts";
8793
9043
  import pc30 from "picocolors";
8794
9044
  import * as v8 from "valibot";
8795
9045
  var OptionsSchema4 = v8.object({
@@ -8798,7 +9048,7 @@ var OptionsSchema4 = v8.object({
8798
9048
  offline: v8.optional(v8.boolean())
8799
9049
  });
8800
9050
  var targets = addSshOptions(
8801
- new Command91("targets").description("list the targets this project can deploy to").configureHelp(helpConfig)
9051
+ new Command94("targets").description("list the targets this project can deploy to").configureHelp(helpConfig)
8802
9052
  ).option("--json", "print raw JSON").option("--offline", "skip connecting to servers").action(
8803
9053
  (raw) => runCommand(async () => {
8804
9054
  const options = parseOptions(OptionsSchema4, raw);
@@ -8864,11 +9114,11 @@ function report3(rows, offline) {
8864
9114
  const lines = rows.map(
8865
9115
  (row) => `${row.kind === "local" ? pc30.dim(row.target.padEnd(target)) : pc30.cyan(row.target.padEnd(target))} ${row.server.padEnd(server)} ${row.domain.padEnd(domain)} ${row.release}`
8866
9116
  );
8867
- p50.log.info(`${pc30.dim(header)}
9117
+ p55.log.info(`${pc30.dim(header)}
8868
9118
  ${lines.join("\n")}`);
8869
9119
  const unreachable = rows.filter((row) => row.kind === "remote" && !row.reachable);
8870
9120
  if (!offline && unreachable.length > 0) {
8871
- p50.log.warn(
9121
+ p55.log.warn(
8872
9122
  `Could not reach ${unreachable.map((row) => row.server).join(", ")}.
8873
9123
  Release and domain are shown from what this project recorded.`
8874
9124
  );
@@ -8878,19 +9128,19 @@ Release and domain are shown from what this project recorded.`
8878
9128
  // src/commands/test.ts
8879
9129
  import path42 from "node:path";
8880
9130
  import process32 from "node:process";
8881
- import { Command as Command92 } from "commander";
9131
+ import { Command as Command95 } from "commander";
8882
9132
  import PocketBase6 from "pocketbase";
8883
9133
  import pc31 from "picocolors";
8884
9134
  import { x as x5 } from "tinyexec";
8885
- import { detect as detect8 } from "package-manager-detector";
8886
- import { resolveCommand as resolveCommand8 } from "package-manager-detector/commands";
8887
- import fs38 from "node:fs";
8888
- var testServer = new Command92("test:server").description("run server tests").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(async (_opts, cmd) => {
9135
+ import { detect as detect7 } from "package-manager-detector";
9136
+ import { resolveCommand as resolveCommand7 } from "package-manager-detector/commands";
9137
+ import fs39 from "node:fs";
9138
+ var testServer = new Command95("test:server").description("run server tests").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(async (_opts, cmd) => {
8889
9139
  const cwd = process32.cwd();
8890
9140
  const email3 = `test-${Math.random().toString(36).slice(2)}@example.com`;
8891
9141
  const password11 = "password";
8892
9142
  const testDataDir = path42.join(cwd, "test-data");
8893
- fs38.rmSync(testDataDir, { recursive: true, force: true });
9143
+ fs39.rmSync(testDataDir, { recursive: true, force: true });
8894
9144
  const { stop, url } = await launchPocketbase(cwd, {
8895
9145
  dir: testDataDir,
8896
9146
  migrationsDir: path42.join(cwd, MIGRATIONS_DIR),
@@ -8913,7 +9163,7 @@ var testServer = new Command92("test:server").description("run server tests").al
8913
9163
  if (cleanedUp) return;
8914
9164
  cleanedUp = true;
8915
9165
  stop();
8916
- fs38.rmSync(testDataDir, { recursive: true, force: true });
9166
+ fs39.rmSync(testDataDir, { recursive: true, force: true });
8917
9167
  };
8918
9168
  const cleanup = async () => {
8919
9169
  if (cleanedUp) return;
@@ -8965,8 +9215,8 @@ var testServer = new Command92("test:server").description("run server tests").al
8965
9215
  const passthrough = filter ? extraArgs.filter((a) => a !== filter) : extraArgs;
8966
9216
  if (!filter) filter = "server";
8967
9217
  try {
8968
- const pm = (await detect8({ cwd }))?.name ?? "npm";
8969
- const resolved = resolveCommand8(pm, "execute", [
9218
+ const pm = (await detect7({ cwd }))?.name ?? "npm";
9219
+ const resolved = resolveCommand7(pm, "execute", [
8970
9220
  "vitest",
8971
9221
  "run",
8972
9222
  filter,
@@ -9012,9 +9262,9 @@ function stubPagesPlugin() {
9012
9262
  }
9013
9263
 
9014
9264
  // src/commands/routes.ts
9015
- import fs39 from "node:fs";
9265
+ import fs40 from "node:fs";
9016
9266
  import path43 from "node:path";
9017
- import { Command as Command93 } from "commander";
9267
+ import { Command as Command96 } from "commander";
9018
9268
  var HTTP_METHODS = /* @__PURE__ */ new Set([
9019
9269
  "GET",
9020
9270
  "POST",
@@ -9025,7 +9275,7 @@ var HTTP_METHODS = /* @__PURE__ */ new Set([
9025
9275
  "HEAD",
9026
9276
  "fallback"
9027
9277
  ]);
9028
- var routes = new Command93("routes").description("list routes").configureHelp(helpConfig).action(async () => {
9278
+ var routes = new Command96("routes").description("list routes").configureHelp(helpConfig).action(async () => {
9029
9279
  const { workspaceRootDir, routesDir } = await getWorkspace();
9030
9280
  const routesRoot = path43.join(workspaceRootDir, routesDir);
9031
9281
  const found = walk(routesRoot, routesRoot).filter((r) => r.methods.length > 0);
@@ -9033,7 +9283,7 @@ var routes = new Command93("routes").description("list routes").configureHelp(he
9033
9283
  printTable(found);
9034
9284
  });
9035
9285
  function walk(root, dir) {
9036
- const entries = fs39.readdirSync(dir, { withFileTypes: true });
9286
+ const entries = fs40.readdirSync(dir, { withFileTypes: true });
9037
9287
  const routes2 = [];
9038
9288
  const hasLeaf = entries.some((e) => e.isFile() && isRouteFile(e.name));
9039
9289
  if (hasLeaf) {
@@ -9059,7 +9309,7 @@ function isRouteFile(name) {
9059
9309
  }
9060
9310
  function extractMethods(file) {
9061
9311
  try {
9062
- const content = fs39.readFileSync(file, "utf8");
9312
+ const content = fs40.readFileSync(file, "utf8");
9063
9313
  const methods = [];
9064
9314
  const exportRegex = /export\s+(?:const|async\s+function|function)\s+(\w+)/g;
9065
9315
  let match;
@@ -9101,14 +9351,14 @@ function printTable(routes2) {
9101
9351
 
9102
9352
  // src/commands/i18n.ts
9103
9353
  import process33 from "node:process";
9104
- import { Command as Command94 } from "commander";
9354
+ import { Command as Command97 } from "commander";
9105
9355
  import { x as x6 } from "tinyexec";
9106
- import { detect as detect9 } from "package-manager-detector";
9107
- import { resolveCommand as resolveCommand9 } from "package-manager-detector/commands";
9356
+ import { detect as detect8 } from "package-manager-detector";
9357
+ import { resolveCommand as resolveCommand8 } from "package-manager-detector/commands";
9108
9358
  async function runWuchale(extraArgs) {
9109
9359
  const cwd = process33.cwd();
9110
- const pm = (await detect9({ cwd }))?.name ?? "npm";
9111
- const resolved = resolveCommand9(pm, "execute", ["wuchale", ...extraArgs]);
9360
+ const pm = (await detect8({ cwd }))?.name ?? "npm";
9361
+ const resolved = resolveCommand8(pm, "execute", ["wuchale", ...extraArgs]);
9112
9362
  const args = resolved.args.slice();
9113
9363
  if (pm === "npm") args.unshift("--yes");
9114
9364
  await x6(resolved.command, args, {
@@ -9116,11 +9366,11 @@ async function runWuchale(extraArgs) {
9116
9366
  throwOnError: true
9117
9367
  });
9118
9368
  }
9119
- var extract = new Command94("extract").description("extract translatable strings").configureHelp(helpConfig).action(() => runWuchale([]));
9120
- var watch = new Command94("watch").description("watch and extract translatable strings").configureHelp(helpConfig).action(() => runWuchale(["--watch"]));
9121
- var status2 = new Command94("status").description("show i18n status").configureHelp(helpConfig).action(() => runWuchale(["status"]));
9122
- var clean = new Command94("clean").description("clean unused translatable strings").configureHelp(helpConfig).action(() => runWuchale(["--clean"]));
9123
- var i18n3 = new Command94("i18n").description("i18n utilities").configureHelp(helpConfig).addCommand(extract, { isDefault: true }).addCommand(watch).addCommand(status2).addCommand(clean);
9369
+ var extract = new Command97("extract").description("extract translatable strings").configureHelp(helpConfig).action(() => runWuchale([]));
9370
+ var watch = new Command97("watch").description("watch and extract translatable strings").configureHelp(helpConfig).action(() => runWuchale(["--watch"]));
9371
+ var status2 = new Command97("status").description("show i18n status").configureHelp(helpConfig).action(() => runWuchale(["status"]));
9372
+ var clean = new Command97("clean").description("clean unused translatable strings").configureHelp(helpConfig).action(() => runWuchale(["--clean"]));
9373
+ var i18n3 = new Command97("i18n").description("i18n utilities").configureHelp(helpConfig).addCommand(extract, { isDefault: true }).addCommand(watch).addCommand(status2).addCommand(clean);
9124
9374
 
9125
9375
  // src/commands/oauth.ts
9126
9376
  var oauth = stubCommand("oauth", "configure OAuth providers");
@@ -9129,15 +9379,15 @@ var oauth = stubCommand("oauth", "configure OAuth providers");
9129
9379
  var schemas = stubCommand("schemas", "manage database schemas");
9130
9380
 
9131
9381
  // src/commands/cms.ts
9132
- import { Command as Command99 } from "commander";
9382
+ import { Command as Command102 } from "commander";
9133
9383
 
9134
9384
  // src/commands/cms/editor.ts
9135
- import { Command as Command98 } from "commander";
9385
+ import { Command as Command101 } from "commander";
9136
9386
 
9137
9387
  // src/commands/cms/editor/add.ts
9138
9388
  import { randomBytes } from "node:crypto";
9139
- import { Command as Command95 } from "commander";
9140
- import * as p51 from "@clack/prompts";
9389
+ import { Command as Command98 } from "commander";
9390
+ import * as p56 from "@clack/prompts";
9141
9391
  import pc33 from "picocolors";
9142
9392
 
9143
9393
  // src/lib/cms-backend.ts
@@ -9179,7 +9429,7 @@ async function withCmsBackend(fn, cwd = process34.cwd()) {
9179
9429
  }
9180
9430
 
9181
9431
  // src/commands/cms/editor/add.ts
9182
- var editorAdd = new Command95("add").description("create an editor who can sign in to the admin bar").argument("<email>", "email the editor signs in with").option("--password <password>", "password to set \u2014 generated and shown once when omitted").option("--project <id>", "project the editor may edit", DEFAULT_PROJECT).configureHelp(helpConfig).action(
9432
+ var editorAdd = new Command98("add").description("create an editor who can sign in to the admin bar").argument("<email>", "email the editor signs in with").option("--password <password>", "password to set \u2014 generated and shown once when omitted").option("--project <id>", "project the editor may edit", DEFAULT_PROJECT).configureHelp(helpConfig).action(
9183
9433
  (email3, options) => runCommand(async () => {
9184
9434
  const generated = options.password === void 0;
9185
9435
  const password11 = options.password ?? randomBytes(12).toString("base64url");
@@ -9190,31 +9440,31 @@ var editorAdd = new Command95("add").description("create an editor who can sign
9190
9440
  if (generated) {
9191
9441
  lines.push("", `Password: ${pc33.bold(password11)}`, "", "It is shown once; copy it now.");
9192
9442
  }
9193
- p51.log.success(lines.join("\n"));
9194
- p51.log.info(
9443
+ p56.log.success(lines.join("\n"));
9444
+ p56.log.info(
9195
9445
  `Run ${pc33.cyan("vela dev")}, open any page with ${pc33.cyan("?edit")} on the URL (or press ${pc33.cyan("Ctrl+E")}), and sign in.`
9196
9446
  );
9197
9447
  }, "Failed to add the editor.")
9198
9448
  );
9199
9449
 
9200
9450
  // src/commands/cms/editor/password.ts
9201
- import { Command as Command96 } from "commander";
9202
- import * as p52 from "@clack/prompts";
9451
+ import { Command as Command99 } from "commander";
9452
+ import * as p57 from "@clack/prompts";
9203
9453
  import pc34 from "picocolors";
9204
- var editorPassword = new Command96("password").description("set an editor's password").argument("<email>", "email of the editor").argument("<password>", "new password").configureHelp(helpConfig).action(
9454
+ var editorPassword = new Command99("password").description("set an editor's password").argument("<email>", "email of the editor").argument("<password>", "new password").configureHelp(helpConfig).action(
9205
9455
  (email3, password11) => runCommand(async () => {
9206
9456
  await withCmsBackend((cms3) => cms3.editors.setPassword(email3, password11));
9207
- p52.log.success(
9457
+ p57.log.success(
9208
9458
  `Updated the password for ${pc34.cyan(email3)}. Existing sessions were signed out.`
9209
9459
  );
9210
9460
  }, "Failed to set the password.")
9211
9461
  );
9212
9462
 
9213
9463
  // src/commands/cms/editor/list.ts
9214
- import { Command as Command97 } from "commander";
9215
- import * as p53 from "@clack/prompts";
9464
+ import { Command as Command100 } from "commander";
9465
+ import * as p58 from "@clack/prompts";
9216
9466
  import pc35 from "picocolors";
9217
- var editorList = new Command97("list").description("list editors and the projects they may edit").configureHelp(helpConfig).action(
9467
+ var editorList = new Command100("list").description("list editors and the projects they may edit").configureHelp(helpConfig).action(
9218
9468
  () => runCommand(async () => {
9219
9469
  const rows = await withCmsBackend(
9220
9470
  async (cms3) => cms3.editors.list().map((editor2) => ({
@@ -9223,11 +9473,11 @@ var editorList = new Command97("list").description("list editors and the project
9223
9473
  }))
9224
9474
  );
9225
9475
  if (rows.length === 0) {
9226
- p53.log.info(`No editors yet. Add one with ${pc35.cyan("vela cms editor add <email>")}.`);
9476
+ p58.log.info(`No editors yet. Add one with ${pc35.cyan("vela cms editor add <email>")}.`);
9227
9477
  return;
9228
9478
  }
9229
9479
  const width = Math.max(...rows.map((row) => row.email.length));
9230
- p53.log.info(
9480
+ p58.log.info(
9231
9481
  `Editors
9232
9482
 
9233
9483
  ` + rows.map(
@@ -9238,10 +9488,10 @@ var editorList = new Command97("list").description("list editors and the project
9238
9488
  );
9239
9489
 
9240
9490
  // src/commands/cms/editor.ts
9241
- var editor = new Command98("editor").description("manage who can sign in to the admin bar").configureHelp(helpConfig).addCommand(editorAdd).addCommand(editorPassword).addCommand(editorList);
9491
+ var editor = new Command101("editor").description("manage who can sign in to the admin bar").configureHelp(helpConfig).addCommand(editorAdd).addCommand(editorPassword).addCommand(editorList);
9242
9492
 
9243
9493
  // src/commands/cms.ts
9244
- var cms2 = new Command99("cms").description("manage the CMS").configureHelp(helpConfig).addCommand(editor);
9494
+ var cms2 = new Command102("cms").description("manage the CMS").configureHelp(helpConfig).addCommand(editor);
9245
9495
 
9246
9496
  // src/program.ts
9247
9497
  var NO_BACKEND_COMMMANDS = /* @__PURE__ */ new Set([
@@ -9276,7 +9526,7 @@ var NO_BACKEND_COMMMANDS = /* @__PURE__ */ new Set([
9276
9526
  ]);
9277
9527
  var BACKEND_OPTIONAL_COMMANDS = /* @__PURE__ */ new Set(["dev", "build", "preview", "deploy"]);
9278
9528
  var SELF_CREDENTIALED_COMMANDS = /* @__PURE__ */ new Set(["test:server"]);
9279
- var program = new Command100().name(package_default.name).description(package_default.description).version(package_default.version, "-v, --version").configureHelp(helpConfig);
9529
+ var program = new Command103().name(package_default.name).description(package_default.description).version(package_default.version, "-v, --version").configureHelp(helpConfig);
9280
9530
  program.hook("preAction", (_thisCommand, actionCommand) => {
9281
9531
  if (isStub(actionCommand)) return;
9282
9532
  const envRoot = findWorkspaceRoot() ?? process35.cwd();
@@ -9287,20 +9537,20 @@ program.hook("preAction", (_thisCommand, actionCommand) => {
9287
9537
  if (NO_BACKEND_COMMMANDS.has(top)) return;
9288
9538
  if (!hasBackend()) {
9289
9539
  if (BACKEND_OPTIONAL_COMMANDS.has(top)) return;
9290
- p54.log.error(
9540
+ p59.log.error(
9291
9541
  `${pc36.cyan(`vela ${path45}`)} needs a backend, and this project does not have one.
9292
9542
 
9293
9543
  Static projects have no database to talk to.
9294
9544
 
9295
9545
  To add a backend to this project, run ${pc36.cyan("vela bless")}.`
9296
9546
  );
9297
- p54.log.message();
9298
- p54.cancel("Operation failed.");
9547
+ p59.log.message();
9548
+ p59.cancel("Operation failed.");
9299
9549
  process35.exit(1);
9300
9550
  }
9301
9551
  if (SELF_CREDENTIALED_COMMANDS.has(path45)) return;
9302
9552
  if (!process35.env.POCKETBASE_SUPERUSER_EMAIL || !process35.env.POCKETBASE_SUPERUSER_PASSWORD) {
9303
- p54.log.error(
9553
+ p59.log.error(
9304
9554
  `PocketBase superuser credentials are required.
9305
9555
 
9306
9556
  Set ${pc36.cyan("POCKETBASE_SUPERUSER_EMAIL")} and ${pc36.cyan("POCKETBASE_SUPERUSER_PASSWORD")} in your .env file.
@@ -9308,8 +9558,8 @@ Set ${pc36.cyan("POCKETBASE_SUPERUSER_EMAIL")} and ${pc36.cyan("POCKETBASE_SUPER
9308
9558
  To set up a new project, run ${pc36.cyan("vela create")}.
9309
9559
  To set up an existing project, run ${pc36.cyan("vela bless")}.`
9310
9560
  );
9311
- p54.log.message();
9312
- p54.cancel("Operation failed.");
9561
+ p59.log.message();
9562
+ p59.cancel("Operation failed.");
9313
9563
  process35.exit(1);
9314
9564
  }
9315
9565
  });