vela 0.13.2 → 0.13.4

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
@@ -21,7 +21,7 @@ import pc42 from "picocolors";
21
21
  // package.json
22
22
  var package_default = {
23
23
  name: "vela",
24
- version: "0.13.2",
24
+ version: "0.13.4",
25
25
  type: "module",
26
26
  description: "A CLI for creating and updating SvelteKit projects",
27
27
  license: "MIT",
@@ -57,7 +57,7 @@ var package_default = {
57
57
  dependencies: {
58
58
  "@clack/prompts": "^1.7.0",
59
59
  "@faker-js/faker": "^10.6.0",
60
- "@velastack/patterns": "^0.2.8",
60
+ "@velastack/patterns": "^0.2.11",
61
61
  "@velastack/pocketbase-codegen": "^0.1.0",
62
62
  "annotate-json-schema": "^0.1.0",
63
63
  commander: "^13.1.0",
@@ -80,11 +80,11 @@ var package_default = {
80
80
  },
81
81
  devDependencies: {
82
82
  "@types/cross-spawn": "^6.0.6",
83
- "@types/node": "^22.0.0",
83
+ "@types/node": "^26.5.1",
84
84
  esbuild: "^0.28.2",
85
85
  prettier: "^3.9.6",
86
86
  shellcheck: "^4.1.0",
87
- typescript: "^5.6.0",
87
+ typescript: "^7.0.2",
88
88
  vite: "^8.2.2",
89
89
  vitest: "^5.0.1"
90
90
  },
@@ -236,8 +236,8 @@ function stubCommand(name, description, fullName) {
236
236
  }
237
237
 
238
238
  // src/lib/workspace.ts
239
- import fs2 from "node:fs";
240
- import path from "node:path";
239
+ import fs3 from "node:fs";
240
+ import path2 from "node:path";
241
241
  import process3 from "node:process";
242
242
 
243
243
  // src/lib/constants.ts
@@ -254,8 +254,36 @@ var API_URL = (process2.env.VELA_API_URL?.trim() || "https://velastack.dev").rep
254
254
  var FIXTURE_PREFIX = "vela";
255
255
  var TEMPLATE_INDEX_URL = process2.env.VELA_TEMPLATE_INDEX_URL?.trim() || "https://templates.velastack.app/index.json";
256
256
 
257
- // src/lib/package-json.ts
257
+ // src/lib/components-json.ts
258
258
  import fs from "node:fs";
259
+ import path from "node:path";
260
+ function readComponentsJson(root) {
261
+ const file = path.join(root, "components.json");
262
+ if (!fs.existsSync(file)) return void 0;
263
+ try {
264
+ const parsed = JSON.parse(fs.readFileSync(file, "utf8"));
265
+ return parsed && typeof parsed === "object" ? parsed : void 0;
266
+ } catch {
267
+ return void 0;
268
+ }
269
+ }
270
+ function componentsJsonHints(config) {
271
+ const hints = [];
272
+ if (!config.style) {
273
+ hints.push(
274
+ 'components.json has no "style": shadcn-svelte defaults to "nova", while vela ships "vega". Add "style": "vega" so new components match.'
275
+ );
276
+ }
277
+ if (!config.iconLibrary) {
278
+ hints.push(
279
+ `components.json has no "iconLibrary": add "iconLibrary": "lucide", the library vela's components use.`
280
+ );
281
+ }
282
+ return hints;
283
+ }
284
+
285
+ // src/lib/package-json.ts
286
+ import fs2 from "node:fs";
259
287
  var DEP_KINDS = ["dependencies", "devDependencies"];
260
288
  function mergePackageJson(user, template) {
261
289
  const merged = structuredClone(user);
@@ -315,8 +343,8 @@ function dropTemplateAdapters(user, template) {
315
343
  }
316
344
  return copy;
317
345
  }
318
- function readPackageJson(path47) {
319
- return JSON.parse(fs.readFileSync(path47, "utf8"));
346
+ function readPackageJson(path48) {
347
+ return JSON.parse(fs2.readFileSync(path48, "utf8"));
320
348
  }
321
349
  var PACKAGE_NAME_PLACEHOLDER = /~TODO~/g;
322
350
  var APP_NAME_PLACEHOLDER = /~APP_NAME~/g;
@@ -334,12 +362,12 @@ function fillTemplatePlaceholders(raw, values) {
334
362
  function escapeSingleQuoted(value) {
335
363
  return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
336
364
  }
337
- function readTemplatePackageJson(path47, values) {
338
- const raw = fillTemplatePlaceholders(fs.readFileSync(path47, "utf8"), values);
365
+ function readTemplatePackageJson(path48, values) {
366
+ const raw = fillTemplatePlaceholders(fs2.readFileSync(path48, "utf8"), values);
339
367
  return JSON.parse(raw);
340
368
  }
341
- function writePackageJson(path47, pkg) {
342
- fs.writeFileSync(path47, JSON.stringify(pkg, null, " ") + "\n");
369
+ function writePackageJson(path48, pkg) {
370
+ fs2.writeFileSync(path48, JSON.stringify(pkg, null, " ") + "\n");
343
371
  }
344
372
  function toValidPackageName(name) {
345
373
  return name.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._]/, "").replace(/[^a-z0-9~.-]+/g, "-");
@@ -353,44 +381,40 @@ function sortKeys(obj) {
353
381
  // src/lib/workspace.ts
354
382
  function findWorkspaceRoot(from = process3.cwd()) {
355
383
  let currentDir = from;
356
- while (currentDir !== path.parse(currentDir).root) {
357
- if (fs2.existsSync(path.join(currentDir, "package.json"))) return currentDir;
358
- currentDir = path.dirname(currentDir);
384
+ while (currentDir !== path2.parse(currentDir).root) {
385
+ if (fs3.existsSync(path2.join(currentDir, "package.json"))) return currentDir;
386
+ currentDir = path2.dirname(currentDir);
359
387
  }
360
388
  return null;
361
389
  }
362
390
  function hasBackend(from = process3.cwd()) {
363
391
  const root = findWorkspaceRoot(from);
364
- return root !== null && fs2.existsSync(path.join(root, DATA_DIR));
392
+ return root !== null && fs3.existsSync(path2.join(root, DATA_DIR));
365
393
  }
366
394
  function hasApiRoutes(root) {
367
- const dir = path.join(root, "src", "routes", "api");
368
- if (!fs2.existsSync(dir)) return false;
369
- return fs2.readdirSync(dir).some((entry) => entry !== "README.md");
395
+ const dir = path2.join(root, "src", "routes", "api");
396
+ if (!fs3.existsSync(dir)) return false;
397
+ return fs3.readdirSync(dir).some((entry) => entry !== "README.md");
370
398
  }
371
399
  function localDataDir(from = process3.cwd()) {
372
- return path.join(findWorkspaceRoot(from) ?? from, DATA_DIR);
400
+ return path2.join(findWorkspaceRoot(from) ?? from, DATA_DIR);
373
401
  }
374
402
  async function getWorkspace() {
375
403
  const workspaceRootDir = findWorkspaceRoot();
376
404
  if (!workspaceRootDir) {
377
405
  throw new Error("Could not find workspace root (no package.json found)");
378
406
  }
379
- const routesDir = path.join("src", "routes");
380
- const fullRoutesPath = path.join(workspaceRootDir, routesDir);
381
- if (!fs2.existsSync(fullRoutesPath)) {
407
+ const routesDir = path2.join("src", "routes");
408
+ const fullRoutesPath = path2.join(workspaceRootDir, routesDir);
409
+ if (!fs3.existsSync(fullRoutesPath)) {
382
410
  throw new Error("Could not find src/routes directory");
383
411
  }
384
- let publicRoutesDir = path.join(routesDir, PUBLIC_DIR);
385
- if (!fs2.existsSync(path.join(workspaceRootDir, publicRoutesDir))) {
386
- publicRoutesDir = routesDir;
387
- }
388
- let appRoutesDir;
389
- const appRoutesPath = path.join(fullRoutesPath, APP_DIR);
390
- const isAppMode = fs2.existsSync(appRoutesPath);
391
- if (isAppMode) appRoutesDir = path.join(routesDir, APP_DIR);
392
- const isPaymentsMode = fs2.existsSync(
393
- path.join(workspaceRootDir, routesDir, "webhooks", "stripe")
412
+ const routeGroups = detectRouteGroups(workspaceRootDir);
413
+ const publicRoutesDir = path2.join(routesDir, routeGroups.public ?? "");
414
+ const isAppMode = routeGroups.app !== null;
415
+ const appRoutesDir = routeGroups.app ? path2.join(routesDir, routeGroups.app) : void 0;
416
+ const isPaymentsMode = fs3.existsSync(
417
+ path2.join(workspaceRootDir, routesDir, "webhooks", "stripe")
394
418
  );
395
419
  const features = detectFeatures(workspaceRootDir, { isAppMode, isPaymentsMode });
396
420
  return {
@@ -398,14 +422,25 @@ async function getWorkspace() {
398
422
  routesDir,
399
423
  publicRoutesDir,
400
424
  appRoutesDir,
425
+ routeGroups,
401
426
  isAppMode,
402
427
  isPaymentsMode,
403
428
  features
404
429
  };
405
430
  }
431
+ function detectRouteGroups(root) {
432
+ const group8 = (name) => fs3.existsSync(path2.join(root, "src", "routes", name)) ? name : null;
433
+ return { public: group8(PUBLIC_DIR), app: group8(APP_DIR) };
434
+ }
435
+ function detectUi(root) {
436
+ const pkg = readPackageJson(path2.join(root, "package.json"));
437
+ const hasDep = (name) => Boolean(pkg.dependencies?.[name] || pkg.devDependencies?.[name]);
438
+ const shadcn = readComponentsJson(root) !== void 0 && (hasDep("shadcn-svelte") || hasDep("bits-ui"));
439
+ return shadcn ? "shadcn" : "plain";
440
+ }
406
441
  function detectFeatures(root, { isAppMode, isPaymentsMode }) {
407
- const has = (rel) => fs2.existsSync(path.join(root, rel));
408
- const pkg = readPackageJson(path.join(root, "package.json"));
442
+ const has = (rel) => fs3.existsSync(path2.join(root, rel));
443
+ const pkg = readPackageJson(path2.join(root, "package.json"));
409
444
  const hasDep = (name) => Boolean(pkg.dependencies?.[name] || pkg.devDependencies?.[name]);
410
445
  return {
411
446
  auth: isAppMode,
@@ -418,7 +453,8 @@ function detectFeatures(root, { isAppMode, isPaymentsMode }) {
418
453
  blog: hasDep("mdsvex"),
419
454
  contentNegotiation: hasDep("sveltekit-negotiate"),
420
455
  cms: hasDep("@velastack/cms"),
421
- workflows: has("src/lib/server/workflows.ts")
456
+ workflows: has("src/lib/server/workflows.ts"),
457
+ ui: detectUi(root)
422
458
  };
423
459
  }
424
460
 
@@ -460,46 +496,46 @@ function toFlag(key) {
460
496
  }
461
497
 
462
498
  // src/lib/templates.ts
463
- import fs6 from "node:fs";
464
- import path5 from "node:path";
499
+ import fs7 from "node:fs";
500
+ import path6 from "node:path";
465
501
  import { fileURLToPath as fileURLToPath2 } from "node:url";
466
502
 
467
503
  // src/lib/template-files.ts
468
- import fs3 from "node:fs";
469
- import path2 from "node:path";
504
+ import fs4 from "node:fs";
505
+ import path3 from "node:path";
470
506
  var PUBLISH_SAFE_NAMES = {
471
507
  ".gitignore": "_gitignore",
472
508
  ".npmrc": "_npmrc"
473
509
  };
474
510
  function templateName(projectRelPath) {
475
- const safe = PUBLISH_SAFE_NAMES[path2.basename(projectRelPath)];
511
+ const safe = PUBLISH_SAFE_NAMES[path3.basename(projectRelPath)];
476
512
  if (!safe) return projectRelPath;
477
- const dir = path2.dirname(projectRelPath);
478
- return dir === "." ? safe : path2.join(dir, safe);
513
+ const dir = path3.dirname(projectRelPath);
514
+ return dir === "." ? safe : path3.join(dir, safe);
479
515
  }
480
516
  function restoreTemplateNames(target) {
481
517
  for (const [real, safe] of Object.entries(PUBLISH_SAFE_NAMES)) {
482
- const from = path2.join(target, safe);
483
- if (!fs3.existsSync(from)) continue;
484
- fs3.renameSync(from, path2.join(target, real));
518
+ const from = path3.join(target, safe);
519
+ if (!fs4.existsSync(from)) continue;
520
+ fs4.renameSync(from, path3.join(target, real));
485
521
  }
486
522
  }
487
523
  var TEMPLATE_SOURCE = /\.template\.([^.]+)$/;
488
524
  function applyTemplateFiles(target, values) {
489
525
  const written = [];
490
526
  for (const source of findTemplateSources(target)) {
491
- const raw = fs3.readFileSync(source, "utf8");
527
+ const raw = fs4.readFileSync(source, "utf8");
492
528
  const dest = source.replace(TEMPLATE_SOURCE, ".$1");
493
- fs3.writeFileSync(dest, fillTemplatePlaceholders(raw, values));
494
- fs3.unlinkSync(source);
495
- written.push(path2.relative(target, dest));
529
+ fs4.writeFileSync(dest, fillTemplatePlaceholders(raw, values));
530
+ fs4.unlinkSync(source);
531
+ written.push(path3.relative(target, dest));
496
532
  }
497
533
  return written.sort();
498
534
  }
499
535
  function findTemplateSources(dir) {
500
536
  const found = [];
501
- for (const entry of fs3.readdirSync(dir, { withFileTypes: true })) {
502
- const full = path2.join(dir, entry.name);
537
+ for (const entry of fs4.readdirSync(dir, { withFileTypes: true })) {
538
+ const full = path3.join(dir, entry.name);
503
539
  if (entry.isDirectory()) {
504
540
  if (entry.name === "node_modules" || entry.name === ".git") continue;
505
541
  found.push(...findTemplateSources(full));
@@ -511,38 +547,38 @@ function findTemplateSources(dir) {
511
547
  }
512
548
 
513
549
  // src/lib/template-registry.ts
514
- import fs5 from "node:fs";
550
+ import fs6 from "node:fs";
515
551
  import os2 from "node:os";
516
- import path4 from "node:path";
552
+ import path5 from "node:path";
517
553
  import { createHash } from "node:crypto";
518
554
  import { fileURLToPath } from "node:url";
519
555
  import * as v2 from "valibot";
520
556
  import * as tar from "tar";
521
557
 
522
558
  // src/lib/config.ts
523
- import fs4 from "node:fs";
559
+ import fs5 from "node:fs";
524
560
  import os from "node:os";
525
- import path3 from "node:path";
561
+ import path4 from "node:path";
526
562
  import process4 from "node:process";
527
563
  function configDir() {
528
- return path3.join(os.homedir(), ".vela");
564
+ return path4.join(os.homedir(), ".vela");
529
565
  }
530
566
  var CONFIG_DIR = configDir();
531
- var CONFIG_PATH = path3.join(CONFIG_DIR, "config.json");
567
+ var CONFIG_PATH = path4.join(CONFIG_DIR, "config.json");
532
568
  function readConfig() {
533
- if (!fs4.existsSync(CONFIG_PATH)) return null;
569
+ if (!fs5.existsSync(CONFIG_PATH)) return null;
534
570
  try {
535
- return JSON.parse(fs4.readFileSync(CONFIG_PATH, "utf8"));
571
+ return JSON.parse(fs5.readFileSync(CONFIG_PATH, "utf8"));
536
572
  } catch {
537
573
  return null;
538
574
  }
539
575
  }
540
576
  function writeConfig(config) {
541
- fs4.mkdirSync(CONFIG_DIR, { recursive: true });
542
- fs4.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
577
+ fs5.mkdirSync(CONFIG_DIR, { recursive: true });
578
+ fs5.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
543
579
  }
544
580
  function clearConfig() {
545
- if (fs4.existsSync(CONFIG_PATH)) fs4.unlinkSync(CONFIG_PATH);
581
+ if (fs5.existsSync(CONFIG_PATH)) fs5.unlinkSync(CONFIG_PATH);
546
582
  }
547
583
  function readApiKey() {
548
584
  const fromEnv = process4.env.VELA_API_KEY?.trim();
@@ -588,16 +624,16 @@ var indexSchema = v2.object({
588
624
  templates: v2.array(v2.unknown())
589
625
  });
590
626
  function cacheRoot() {
591
- return path4.join(configDir(), CACHE_DIR_NAME);
627
+ return path5.join(configDir(), CACHE_DIR_NAME);
592
628
  }
593
629
  function indexCachePath() {
594
- return path4.join(cacheRoot(), INDEX_CACHE_FILE);
630
+ return path5.join(cacheRoot(), INDEX_CACHE_FILE);
595
631
  }
596
632
  function readCachedIndex(url) {
597
633
  const file = indexCachePath();
598
- if (!fs5.existsSync(file)) return null;
634
+ if (!fs6.existsSync(file)) return null;
599
635
  try {
600
- const cached2 = JSON.parse(fs5.readFileSync(file, "utf8"));
636
+ const cached2 = JSON.parse(fs6.readFileSync(file, "utf8"));
601
637
  if (cached2.url !== url) return null;
602
638
  return cached2;
603
639
  } catch {
@@ -605,8 +641,8 @@ function readCachedIndex(url) {
605
641
  }
606
642
  }
607
643
  function writeCachedIndex(cached2) {
608
- fs5.mkdirSync(cacheRoot(), { recursive: true });
609
- fs5.writeFileSync(indexCachePath(), JSON.stringify(cached2, null, 2));
644
+ fs6.mkdirSync(cacheRoot(), { recursive: true });
645
+ fs6.writeFileSync(indexCachePath(), JSON.stringify(cached2, null, 2));
610
646
  }
611
647
  function parseTemplateIndex(text19, url) {
612
648
  let parsed;
@@ -633,7 +669,7 @@ function isFileUrl(url) {
633
669
  }
634
670
  async function readBytes(url, options) {
635
671
  if (isFileUrl(url)) {
636
- return new Uint8Array(fs5.readFileSync(fileURLToPath(url)));
672
+ return new Uint8Array(fs6.readFileSync(fileURLToPath(url)));
637
673
  }
638
674
  const res = await fetch(url, {
639
675
  headers: options.headers,
@@ -671,7 +707,7 @@ function sha256(bytes) {
671
707
  return createHash("sha256").update(bytes).digest("hex");
672
708
  }
673
709
  function tarballCachePath(entry) {
674
- return path4.join(
710
+ return path5.join(
675
711
  cacheRoot(),
676
712
  TARBALL_CACHE_DIR,
677
713
  `${entry.name}-${entry.sha256.slice(0, 12)}.tgz`
@@ -681,8 +717,8 @@ async function downloadTemplate(entry, indexUrl, options = {}) {
681
717
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS * 6;
682
718
  const cacheFile = tarballCachePath(entry);
683
719
  let haveTarball = false;
684
- if (fs5.existsSync(cacheFile)) {
685
- const cached2 = new Uint8Array(fs5.readFileSync(cacheFile));
720
+ if (fs6.existsSync(cacheFile)) {
721
+ const cached2 = new Uint8Array(fs6.readFileSync(cacheFile));
686
722
  haveTarball = sha256(cached2) === entry.sha256;
687
723
  }
688
724
  if (!haveTarball) {
@@ -699,14 +735,14 @@ async function downloadTemplate(entry, indexUrl, options = {}) {
699
735
  `Downloaded template ${entry.name} did not match its checksum (expected ${entry.sha256}, got ${digest}). Try again, or set VELA_TEMPLATE_INDEX_URL to a registry you trust.`
700
736
  );
701
737
  }
702
- fs5.mkdirSync(path4.dirname(cacheFile), { recursive: true });
703
- fs5.writeFileSync(cacheFile, fetched);
738
+ fs6.mkdirSync(path5.dirname(cacheFile), { recursive: true });
739
+ fs6.writeFileSync(cacheFile, fetched);
704
740
  }
705
- const dir = fs5.mkdtempSync(path4.join(os2.tmpdir(), `vela-template-${entry.name}-`));
741
+ const dir = fs6.mkdtempSync(path5.join(os2.tmpdir(), `vela-template-${entry.name}-`));
706
742
  try {
707
743
  await tar.extract({ file: cacheFile, cwd: dir, strip: 1 });
708
744
  } catch (e) {
709
- fs5.rmSync(dir, { recursive: true, force: true });
745
+ fs6.rmSync(dir, { recursive: true, force: true });
710
746
  throw new Error(`Could not unpack template ${entry.name}: ${e.message}`);
711
747
  }
712
748
  return dir;
@@ -718,25 +754,25 @@ var DEFAULT_TEMPLATE = "minimal";
718
754
  var DEFAULT_CATEGORY = "starter";
719
755
  var cached;
720
756
  function templatesDir() {
721
- let dir = path5.dirname(fileURLToPath2(import.meta.url));
722
- const { root } = path5.parse(dir);
757
+ let dir = path6.dirname(fileURLToPath2(import.meta.url));
758
+ const { root } = path6.parse(dir);
723
759
  while (dir !== root) {
724
- const candidate = path5.join(dir, "templates");
760
+ const candidate = path6.join(dir, "templates");
725
761
  if (holdsManifest(candidate)) return candidate;
726
- dir = path5.dirname(dir);
762
+ dir = path6.dirname(dir);
727
763
  }
728
764
  throw new Error("Could not locate the templates directory");
729
765
  }
730
766
  function holdsManifest(dir) {
731
- if (!fs6.existsSync(dir)) return false;
732
- return fs6.readdirSync(dir, { withFileTypes: true }).some(
733
- (entry) => entry.isDirectory() && fs6.existsSync(path5.join(dir, entry.name, TEMPLATE_MANIFEST))
767
+ if (!fs7.existsSync(dir)) return false;
768
+ return fs7.readdirSync(dir, { withFileTypes: true }).some(
769
+ (entry) => entry.isDirectory() && fs7.existsSync(path6.join(dir, entry.name, TEMPLATE_MANIFEST))
734
770
  );
735
771
  }
736
772
  function listProjectTemplates() {
737
773
  if (cached) return cached;
738
774
  const root = templatesDir();
739
- cached = fs6.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => readManifest(root, entry.name)).filter((template) => template !== void 0).sort((a, b) => a.name.localeCompare(b.name));
775
+ cached = fs7.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => readManifest(root, entry.name)).filter((template) => template !== void 0).sort((a, b) => a.name.localeCompare(b.name));
740
776
  return cached;
741
777
  }
742
778
  function projectTemplateNames(options = {}) {
@@ -809,25 +845,25 @@ async function resolveTemplate(template) {
809
845
  ...info,
810
846
  dir,
811
847
  cleanup() {
812
- fs6.rmSync(dir, { recursive: true, force: true });
848
+ fs7.rmSync(dir, { recursive: true, force: true });
813
849
  }
814
850
  };
815
851
  }
816
852
  function copyTemplate(template, target) {
817
- fs6.mkdirSync(target, { recursive: true });
818
- fs6.cpSync(template.dir, target, {
853
+ fs7.mkdirSync(target, { recursive: true });
854
+ fs7.cpSync(template.dir, target, {
819
855
  recursive: true,
820
856
  // The manifest describes the template to the CLI; it isn't part of the project.
821
- filter: (src) => path5.basename(src) !== ".DS_Store" && path5.relative(template.dir, src) !== TEMPLATE_MANIFEST
857
+ filter: (src) => path6.basename(src) !== ".DS_Store" && path6.relative(template.dir, src) !== TEMPLATE_MANIFEST
822
858
  });
823
859
  restoreTemplateNames(target);
824
860
  }
825
861
  function readManifest(root, name) {
826
- const manifestPath = path5.join(root, name, TEMPLATE_MANIFEST);
827
- if (!fs6.existsSync(manifestPath)) return void 0;
862
+ const manifestPath = path6.join(root, name, TEMPLATE_MANIFEST);
863
+ if (!fs7.existsSync(manifestPath)) return void 0;
828
864
  let parsed;
829
865
  try {
830
- parsed = JSON.parse(fs6.readFileSync(manifestPath, "utf8"));
866
+ parsed = JSON.parse(fs7.readFileSync(manifestPath, "utf8"));
831
867
  } catch (e) {
832
868
  throw new Error(
833
869
  `Template ${name} has an unreadable ${TEMPLATE_MANIFEST}: ${e.message}`
@@ -850,7 +886,7 @@ function readManifest(root, name) {
850
886
  price: typeof manifest.price === "number" ? manifest.price : void 0,
851
887
  nextSteps: optionalStringArray(manifest.nextSteps),
852
888
  cms: typeof manifest.cms === "boolean" ? manifest.cms : void 0,
853
- dir: path5.join(root, name)
889
+ dir: path6.join(root, name)
854
890
  };
855
891
  }
856
892
  function optionalString(value) {
@@ -863,8 +899,8 @@ function optionalStringArray(value) {
863
899
  }
864
900
 
865
901
  // src/lib/package-manager.ts
866
- import fs7 from "node:fs";
867
- import path6 from "node:path";
902
+ import fs8 from "node:fs";
903
+ import path7 from "node:path";
868
904
  import process5 from "node:process";
869
905
  import { exec } from "tinyexec";
870
906
  import { Option } from "commander";
@@ -934,9 +970,9 @@ async function installDependencies(agent, cwd, { exitOnFailure = true } = {}) {
934
970
  }
935
971
  function addPnpmBuildDependencies(cwd, packageManager2, allowedPackages) {
936
972
  if (!packageManager2 || packageManager2 !== "pnpm") return;
937
- const pkgPath = path6.join(cwd, "package.json");
938
- if (!fs7.existsSync(pkgPath)) return;
939
- const pkg = JSON.parse(fs7.readFileSync(pkgPath, "utf-8"));
973
+ const pkgPath = path7.join(cwd, "package.json");
974
+ if (!fs8.existsSync(pkgPath)) return;
975
+ const pkg = JSON.parse(fs8.readFileSync(pkgPath, "utf-8"));
940
976
  pkg.pnpm ??= {};
941
977
  pkg.pnpm.onlyBuiltDependencies ??= [];
942
978
  for (const name of allowedPackages) {
@@ -944,13 +980,13 @@ function addPnpmBuildDependencies(cwd, packageManager2, allowedPackages) {
944
980
  pkg.pnpm.onlyBuiltDependencies.push(name);
945
981
  }
946
982
  }
947
- fs7.writeFileSync(pkgPath, JSON.stringify(pkg, null, " ") + "\n");
983
+ fs8.writeFileSync(pkgPath, JSON.stringify(pkg, null, " ") + "\n");
948
984
  }
949
985
 
950
986
  // src/lib/pocketbase.ts
951
- import fs8 from "node:fs";
987
+ import fs9 from "node:fs";
952
988
  import net from "node:net";
953
- import path7 from "node:path";
989
+ import path8 from "node:path";
954
990
  import process6 from "node:process";
955
991
  import { createRequire } from "node:module";
956
992
  import { spawn } from "node:child_process";
@@ -1063,9 +1099,9 @@ async function authWithRetries(pb, email3, password11, attempts = 3) {
1063
1099
  }
1064
1100
  }
1065
1101
  function getPocketbaseMetadata(cwd) {
1066
- const metadataPath = path7.join(cwd, "node_modules", ".vite", "_pocketbase_metadata.json");
1067
- if (fs8.existsSync(metadataPath)) {
1068
- return JSON.parse(fs8.readFileSync(metadataPath, "utf8"));
1102
+ const metadataPath = path8.join(cwd, "node_modules", ".vite", "_pocketbase_metadata.json");
1103
+ if (fs9.existsSync(metadataPath)) {
1104
+ return JSON.parse(fs9.readFileSync(metadataPath, "utf8"));
1069
1105
  }
1070
1106
  return null;
1071
1107
  }
@@ -1078,12 +1114,12 @@ async function execPackageBin(cwd, args, stdio = "pipe") {
1078
1114
  return x(command, resolvedArgs, { nodeOptions: { cwd, stdio }, throwOnError: true });
1079
1115
  }
1080
1116
  async function withPocketbase(cwd, fn, creds) {
1081
- const dir = path7.join(cwd, DATA_DIR);
1082
- const migrationsDir = path7.join(cwd, MIGRATIONS_DIR);
1117
+ const dir = path8.join(cwd, DATA_DIR);
1118
+ const migrationsDir = path8.join(cwd, MIGRATIONS_DIR);
1083
1119
  const host = "localhost";
1084
1120
  const email3 = creds?.email ?? process6.env.POCKETBASE_SUPERUSER_EMAIL;
1085
1121
  const password11 = creds?.password ?? process6.env.POCKETBASE_SUPERUSER_PASSWORD;
1086
- if (!fs8.existsSync(dir)) {
1122
+ if (!fs9.existsSync(dir)) {
1087
1123
  throw new Error("PocketBase data directory does not exist");
1088
1124
  }
1089
1125
  const metadata = getPocketbaseMetadata(cwd);
@@ -1108,10 +1144,10 @@ async function withPocketbase(cwd, fn, creds) {
1108
1144
  }
1109
1145
  }
1110
1146
  async function createSuperuser(cwd, email3, password11) {
1111
- const dir = path7.join(cwd, DATA_DIR);
1112
- const migrationsDir = path7.join(cwd, MIGRATIONS_DIR);
1113
- fs8.mkdirSync(dir, { recursive: true });
1114
- fs8.mkdirSync(migrationsDir, { recursive: true });
1147
+ const dir = path8.join(cwd, DATA_DIR);
1148
+ const migrationsDir = path8.join(cwd, MIGRATIONS_DIR);
1149
+ fs9.mkdirSync(dir, { recursive: true });
1150
+ fs9.mkdirSync(migrationsDir, { recursive: true });
1115
1151
  await execPackageBin(
1116
1152
  cwd,
1117
1153
  [
@@ -1136,8 +1172,8 @@ async function launchPocketbase(cwd, {
1136
1172
  password: password11
1137
1173
  }) {
1138
1174
  const host = "localhost";
1139
- fs8.mkdirSync(dir, { recursive: true });
1140
- fs8.mkdirSync(migrationsDir, { recursive: true });
1175
+ fs9.mkdirSync(dir, { recursive: true });
1176
+ fs9.mkdirSync(migrationsDir, { recursive: true });
1141
1177
  await execPackageBin(
1142
1178
  cwd,
1143
1179
  [
@@ -1179,8 +1215,8 @@ async function ensureSuperuser(cwd) {
1179
1215
  const email3 = process6.env.POCKETBASE_SUPERUSER_EMAIL;
1180
1216
  const password11 = process6.env.POCKETBASE_SUPERUSER_PASSWORD;
1181
1217
  if (!email3 || !password11) return;
1182
- const dir = path7.join(cwd, DATA_DIR);
1183
- if (!fs8.existsSync(dir)) return;
1218
+ const dir = path8.join(cwd, DATA_DIR);
1219
+ if (!fs9.existsSync(dir)) return;
1184
1220
  const { getBinaryPath } = await import("pocketbase-server");
1185
1221
  await x(
1186
1222
  getBinaryPath(),
@@ -1188,7 +1224,7 @@ async function ensureSuperuser(cwd) {
1188
1224
  "--dir",
1189
1225
  dir,
1190
1226
  "--migrationsDir",
1191
- path7.join(cwd, MIGRATIONS_DIR),
1227
+ path8.join(cwd, MIGRATIONS_DIR),
1192
1228
  "superuser",
1193
1229
  "upsert",
1194
1230
  email3,
@@ -1199,8 +1235,8 @@ async function ensureSuperuser(cwd) {
1199
1235
  }
1200
1236
 
1201
1237
  // src/lib/env.ts
1202
- import fs9 from "node:fs";
1203
- import path8 from "node:path";
1238
+ import fs10 from "node:fs";
1239
+ import path9 from "node:path";
1204
1240
  function addEnvVar(content, key, value) {
1205
1241
  if (content.includes(`${key}=`)) return content;
1206
1242
  return appendLine(content, `${key}=${value}`);
@@ -1215,11 +1251,11 @@ function appendLine(existing, line) {
1215
1251
  return withNewline + line + "\n";
1216
1252
  }
1217
1253
  function writeEnvFile(cwd, vars, comments = []) {
1218
- const envPath = path8.join(cwd, ".env");
1219
- let content = fs9.existsSync(envPath) ? fs9.readFileSync(envPath, "utf8") : "";
1254
+ const envPath = path9.join(cwd, ".env");
1255
+ let content = fs10.existsSync(envPath) ? fs10.readFileSync(envPath, "utf8") : "";
1220
1256
  for (const comment of comments) content = addEnvComment(content, comment);
1221
1257
  for (const [key, value] of Object.entries(vars)) content = addEnvVar(content, key, value);
1222
- fs9.writeFileSync(envPath, content);
1258
+ fs10.writeFileSync(envPath, content);
1223
1259
  }
1224
1260
  function upsertEnvVar(content, key, value) {
1225
1261
  const line = `${key}=${quoteEnvValue(value)}`;
@@ -1252,7 +1288,7 @@ function quoteEnvValue(value) {
1252
1288
  }
1253
1289
 
1254
1290
  // src/lib/app-css.ts
1255
- import fs10 from "node:fs";
1291
+ import fs11 from "node:fs";
1256
1292
  var SHADCN_TAILWIND_CSS = "shadcn-svelte/tailwind.css";
1257
1293
  var SHADCN_TAILWIND_IMPORT = `@import '${SHADCN_TAILWIND_CSS}';`;
1258
1294
  function hasShadcnImport(css) {
@@ -1278,41 +1314,13 @@ ${css}`;
1278
1314
  return lines.join("\n");
1279
1315
  }
1280
1316
  function ensureShadcnImport(appCssPath) {
1281
- if (!fs10.existsSync(appCssPath)) return false;
1282
- const css = fs10.readFileSync(appCssPath, "utf8");
1317
+ if (!fs11.existsSync(appCssPath)) return false;
1318
+ const css = fs11.readFileSync(appCssPath, "utf8");
1283
1319
  if (hasShadcnImport(css)) return false;
1284
- fs10.writeFileSync(appCssPath, insertShadcnImport(css));
1320
+ fs11.writeFileSync(appCssPath, insertShadcnImport(css));
1285
1321
  return true;
1286
1322
  }
1287
1323
 
1288
- // src/lib/components-json.ts
1289
- import fs11 from "node:fs";
1290
- import path9 from "node:path";
1291
- function readComponentsJson(root) {
1292
- const file = path9.join(root, "components.json");
1293
- if (!fs11.existsSync(file)) return void 0;
1294
- try {
1295
- const parsed = JSON.parse(fs11.readFileSync(file, "utf8"));
1296
- return parsed && typeof parsed === "object" ? parsed : void 0;
1297
- } catch {
1298
- return void 0;
1299
- }
1300
- }
1301
- function componentsJsonHints(config) {
1302
- const hints = [];
1303
- if (!config.style) {
1304
- hints.push(
1305
- 'components.json has no "style": shadcn-svelte defaults to "nova", while vela ships "vega". Add "style": "vega" so new components match.'
1306
- );
1307
- }
1308
- if (!config.iconLibrary) {
1309
- hints.push(
1310
- `components.json has no "iconLibrary": add "iconLibrary": "lucide", the library vela's components use.`
1311
- );
1312
- }
1313
- return hints;
1314
- }
1315
-
1316
1324
  // src/lib/config-merge.ts
1317
1325
  import fs13 from "node:fs";
1318
1326
  import path11 from "node:path";
@@ -2691,8 +2699,8 @@ async function runPattern(slug2, argv, input, report4) {
2691
2699
  throw new Error(`Unknown pattern: ${slug2}`);
2692
2700
  }
2693
2701
  checkProviderInput(pattern, argv, input);
2694
- const { workspaceRootDir, features } = await getWorkspace();
2695
- const log49 = p9.taskLog({ title: report4.task.title });
2702
+ const { workspaceRootDir, features, routeGroups } = await getWorkspace();
2703
+ const log50 = p9.taskLog({ title: report4.task.title });
2696
2704
  let result;
2697
2705
  try {
2698
2706
  result = await pattern.generate({
@@ -2700,6 +2708,7 @@ async function runPattern(slug2, argv, input, report4) {
2700
2708
  env: "runtime",
2701
2709
  root: workspaceRootDir,
2702
2710
  features,
2711
+ routeGroups,
2703
2712
  input,
2704
2713
  // Patterns no longer read the schema themselves: @velastack/pocketbase-codegen
2705
2714
  // takes an injected client, and only the CLI knows how to reach (or spawn)
@@ -2712,11 +2721,11 @@ async function runPattern(slug2, argv, input, report4) {
2712
2721
  });
2713
2722
  return collections2;
2714
2723
  },
2715
- logger: { info: (message) => log49.message(message) }
2724
+ logger: { info: (message) => log50.message(message) }
2716
2725
  });
2717
- log49.success(report4.task.success);
2726
+ log50.success(report4.task.success);
2718
2727
  } catch (e) {
2719
- log49.error(report4.task.error);
2728
+ log50.error(report4.task.error);
2720
2729
  throw e;
2721
2730
  }
2722
2731
  const rel = (f) => toRelative(workspaceRootDir, f);
@@ -2749,9 +2758,34 @@ async function runPattern(slug2, argv, input, report4) {
2749
2758
  });
2750
2759
  }
2751
2760
 
2761
+ // src/lib/form-ui.ts
2762
+ import path17 from "node:path";
2763
+ var UIS = ["shadcn", "plain"];
2764
+ function detectFormInput(root) {
2765
+ const pkg = readPackageJson(path17.join(root, "package.json"));
2766
+ const hasDep = (name) => Boolean(pkg.dependencies?.[name] || pkg.devDependencies?.[name]);
2767
+ return {
2768
+ flash: hasDep("sveltekit-flash-message"),
2769
+ serverTests: hasDep("supertest")
2770
+ };
2771
+ }
2772
+ function resolveFormInput(root, detectedUi, requested) {
2773
+ const detected = detectFormInput(root);
2774
+ if (requested === void 0) return detected;
2775
+ if (!UIS.includes(requested)) {
2776
+ throw new Error(`Unknown --ui "${requested}". Expected one of: ${UIS.join(", ")}.`);
2777
+ }
2778
+ if (requested === "shadcn" && detectedUi !== "shadcn") {
2779
+ throw new Error(
2780
+ "--ui shadcn needs a shadcn-svelte project (a components.json and the shadcn-svelte package). Run `vela bless` to set one up, or use --ui plain."
2781
+ );
2782
+ }
2783
+ return { ...detected, ui: requested };
2784
+ }
2785
+
2752
2786
  // src/lib/ai-flow.ts
2753
2787
  import fs18 from "node:fs";
2754
- import path17 from "node:path";
2788
+ import path18 from "node:path";
2755
2789
  import * as p13 from "@clack/prompts";
2756
2790
  import pc4 from "picocolors";
2757
2791
 
@@ -3026,17 +3060,20 @@ function specToArgv(spec) {
3026
3060
  return collectionSpecToArgv(spec);
3027
3061
  }
3028
3062
  function writeLayoutSidecar(workspaceRootDir, modelName, layout) {
3029
- const dir = path17.join(workspaceRootDir, "data", "ai-form-layouts");
3063
+ const dir = path18.join(workspaceRootDir, "data", "ai-form-layouts");
3030
3064
  fs18.mkdirSync(dir, { recursive: true });
3031
- const file = path17.join(dir, `${modelName}.json`);
3065
+ const file = path18.join(dir, `${modelName}.json`);
3032
3066
  fs18.writeFileSync(file, JSON.stringify(layout, null, 2) + "\n");
3033
- return path17.relative(workspaceRootDir, file);
3067
+ return path18.relative(workspaceRootDir, file);
3034
3068
  }
3035
3069
 
3036
3070
  // src/commands/generate/form.ts
3037
3071
  var form = new Command5("form").description("generate a form from a model").argument("[model]", 'model name (e.g. "contact")').argument("[fields...]", 'field definitions (e.g. "name:text", "email:email")').option("--remote", "generate a form backed by a remote PocketBase collection").option(
3038
3072
  "--route <route>",
3039
- 'place the form at a custom route (e.g. "(app)/[team_id]/projects/new"). Defaults to the model name under (app)/(public).'
3073
+ 'place the form at a custom route (e.g. "(app)/[team_id]/projects/new"). Defaults to the model name under the (app) or (public) group, or src/routes when it has neither.'
3074
+ ).option(
3075
+ "--ui <ui>",
3076
+ 'markup to generate: "shadcn" components or "plain" HTML. Defaults to shadcn when the project has shadcn-svelte, plain otherwise.'
3040
3077
  ).option(
3041
3078
  "--ai <description>",
3042
3079
  "design the form with AI from a natural-language description (two stages: schema \u2192 layout)"
@@ -3069,6 +3106,11 @@ var form = new Command5("form").description("generate a form from a model").argu
3069
3106
  argv = [model, ...fields];
3070
3107
  modelName = model;
3071
3108
  }
3109
+ const { workspaceRootDir, features } = await getWorkspace();
3110
+ const formInput = resolveFormInput(workspaceRootDir, features.ui, options.ui);
3111
+ if (features.ui === "plain" && !options.ui) {
3112
+ p14.log.info("shadcn-svelte not detected: generating a plain HTML form.");
3113
+ }
3072
3114
  const slug2 = options.remote ? "generate-form-remote" : "generate-form";
3073
3115
  const nextSteps = [
3074
3116
  "Edit the form fields and validation in the generated +page.svelte.",
@@ -3082,7 +3124,7 @@ var form = new Command5("form").description("generate a form from a model").argu
3082
3124
  await runPattern(
3083
3125
  slug2,
3084
3126
  argv,
3085
- { route: options.route },
3127
+ { route: options.route, ...formInput },
3086
3128
  {
3087
3129
  summary: `Created ${modelName} form.`,
3088
3130
  nextSteps,
@@ -3172,7 +3214,7 @@ import { Command as Command8 } from "commander";
3172
3214
  import * as p16 from "@clack/prompts";
3173
3215
  var scaffold = new Command8("scaffold").description("generate a full CRUD scaffold (model, forms, list, detail)").argument("[model]", "model name").argument("[fields...]", "field definitions").option("--remote", "generate a scaffold backed by a remote PocketBase collection").option(
3174
3216
  "--route <route>",
3175
- 'place the scaffold at a custom route (e.g. "(app)/[team_id]/projects"). Defaults to the pluralized model name under (app)/(public).'
3217
+ 'place the scaffold at a custom route (e.g. "(app)/[team_id]/projects"). Defaults to the pluralized model name under the (app) or (public) group, or src/routes when it has neither.'
3176
3218
  ).option(
3177
3219
  "--ai <description>",
3178
3220
  "design the scaffold with AI from a natural-language description (two stages: schema \u2192 layout)"
@@ -3644,7 +3686,7 @@ import pc5 from "picocolors";
3644
3686
 
3645
3687
  // src/lib/deploy-config.ts
3646
3688
  import fs19 from "node:fs";
3647
- import path18 from "node:path";
3689
+ import path19 from "node:path";
3648
3690
  import crypto from "node:crypto";
3649
3691
  import { pathToFileURL } from "node:url";
3650
3692
  var CONFIG_BASENAMES = [
@@ -3655,7 +3697,7 @@ var CONFIG_BASENAMES = [
3655
3697
  ];
3656
3698
  function findConfigFile(workspaceRootDir) {
3657
3699
  for (const name of CONFIG_BASENAMES) {
3658
- const file = path18.join(workspaceRootDir, name);
3700
+ const file = path19.join(workspaceRootDir, name);
3659
3701
  if (fs19.existsSync(file)) return file;
3660
3702
  }
3661
3703
  return null;
@@ -3671,7 +3713,7 @@ async function loadDeployConfig(workspaceRootDir) {
3671
3713
  const mod = await import(url);
3672
3714
  const config = mod.default;
3673
3715
  if (!config || typeof config !== "object") {
3674
- throw new Error(`${path18.basename(file)} must export a config object as its default export.`);
3716
+ throw new Error(`${path19.basename(file)} must export a config object as its default export.`);
3675
3717
  }
3676
3718
  return config;
3677
3719
  } finally {
@@ -3684,15 +3726,15 @@ async function transpileToTemp(file) {
3684
3726
  const { outputText } = ts.transpileModule(source, {
3685
3727
  compilerOptions: { module: ts.ModuleKind.ESNext, target: ts.ScriptTarget.ES2022 }
3686
3728
  });
3687
- const temp = path18.join(
3688
- path18.dirname(file),
3729
+ const temp = path19.join(
3730
+ path19.dirname(file),
3689
3731
  `.velastack.config.${crypto.randomBytes(4).toString("hex")}.mjs`
3690
3732
  );
3691
3733
  fs19.writeFileSync(temp, outputText);
3692
3734
  return pathToFileURL(temp).href;
3693
3735
  }
3694
3736
  function projectFilePath(workspaceRootDir) {
3695
- return path18.join(workspaceRootDir, ".vela", "project.json");
3737
+ return path19.join(workspaceRootDir, ".vela", "project.json");
3696
3738
  }
3697
3739
  function readProjectFile(workspaceRootDir) {
3698
3740
  const file = projectFilePath(workspaceRootDir);
@@ -3705,7 +3747,7 @@ function readProjectFile(workspaceRootDir) {
3705
3747
  }
3706
3748
  function writeProjectFile(workspaceRootDir, data) {
3707
3749
  const file = projectFilePath(workspaceRootDir);
3708
- fs19.mkdirSync(path18.dirname(file), { recursive: true });
3750
+ fs19.mkdirSync(path19.dirname(file), { recursive: true });
3709
3751
  fs19.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
3710
3752
  }
3711
3753
  function resolveAppIdentity(workspaceRootDir, config = {}) {
@@ -3731,11 +3773,11 @@ function readAppIdentity(workspaceRootDir, config = {}) {
3731
3773
  }
3732
3774
  function defaultProjectName(workspaceRootDir) {
3733
3775
  try {
3734
- const pkg = readPackageJson(path18.join(workspaceRootDir, "package.json"));
3776
+ const pkg = readPackageJson(path19.join(workspaceRootDir, "package.json"));
3735
3777
  if (typeof pkg.name === "string" && pkg.name.trim()) return pkg.name.trim();
3736
3778
  } catch {
3737
3779
  }
3738
- return path18.basename(workspaceRootDir);
3780
+ return path19.basename(workspaceRootDir);
3739
3781
  }
3740
3782
  function slug(value) {
3741
3783
  return value.toLowerCase().replace(/^@/, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 32) || "app";
@@ -3807,14 +3849,14 @@ function randomSuffix() {
3807
3849
 
3808
3850
  // src/lib/artifact.ts
3809
3851
  import fs21 from "node:fs";
3810
- import path20 from "node:path";
3852
+ import path21 from "node:path";
3811
3853
  import { detect as detect4 } from "package-manager-detector";
3812
3854
  import { resolveCommand as resolveCommand4 } from "package-manager-detector/commands";
3813
3855
 
3814
3856
  // src/lib/ssh.ts
3815
3857
  import fs20 from "node:fs";
3816
3858
  import os4 from "node:os";
3817
- import path19 from "node:path";
3859
+ import path20 from "node:path";
3818
3860
  import crypto3 from "node:crypto";
3819
3861
  import process13 from "node:process";
3820
3862
  import { spawn as spawn2 } from "node:child_process";
@@ -3857,9 +3899,9 @@ var SshSession = class {
3857
3899
  }
3858
3900
  async open() {
3859
3901
  if (this.controlPath) return;
3860
- const dir = path19.join(os4.tmpdir(), "vela-ssh");
3902
+ const dir = path20.join(os4.tmpdir(), "vela-ssh");
3861
3903
  fs20.mkdirSync(dir, { recursive: true, mode: 448 });
3862
- const socket = path19.join(dir, `${crypto3.randomBytes(6).toString("hex")}.sock`);
3904
+ const socket = path20.join(dir, `${crypto3.randomBytes(6).toString("hex")}.sock`);
3863
3905
  this.controlPath = socket;
3864
3906
  const args = [
3865
3907
  ...this.sshArgs(),
@@ -4149,11 +4191,11 @@ function collectArtifact(cwd, config = {}) {
4149
4191
  const outputDir = config.outputDir ?? DEFAULT_OUTPUT_DIR;
4150
4192
  const entries = [];
4151
4193
  const add2 = (rel, remoteDir = "") => {
4152
- const localPath = path20.join(cwd, rel);
4194
+ const localPath = path21.join(cwd, rel);
4153
4195
  if (fs21.existsSync(localPath)) entries.push({ localPath, remoteDir });
4154
4196
  };
4155
- const buildPath = path20.join(cwd, outputDir);
4156
- if (!fs21.existsSync(path20.join(buildPath, "index.js"))) {
4197
+ const buildPath = path21.join(cwd, outputDir);
4198
+ if (!fs21.existsSync(path21.join(buildPath, "index.js"))) {
4157
4199
  throw new BuildError(
4158
4200
  `No ${outputDir}/index.js to deploy.
4159
4201
 
@@ -4167,7 +4209,7 @@ matches where it writes), then deploy again.`
4167
4209
  add2("package-lock.json");
4168
4210
  add2(".npmrc");
4169
4211
  add2(MIGRATIONS_DIR);
4170
- const hooks = path20.join(cwd, DATA_DIR, "hooks");
4212
+ const hooks = path21.join(cwd, DATA_DIR, "hooks");
4171
4213
  if (fs21.existsSync(hooks)) entries.push({ localPath: hooks, remoteDir: "hooks" });
4172
4214
  for (const extra of config.include ?? []) add2(extra);
4173
4215
  return entries;
@@ -4210,7 +4252,7 @@ function sshOptionsFrom(options) {
4210
4252
  // src/lib/remote.ts
4211
4253
  import crypto4 from "node:crypto";
4212
4254
  import fs22 from "node:fs";
4213
- import path21 from "node:path";
4255
+ import path22 from "node:path";
4214
4256
  import process14 from "node:process";
4215
4257
  var VELA_ROOT = "/var/lib/vela";
4216
4258
  var VELA_ETC = "/etc/vela";
@@ -4223,19 +4265,19 @@ function instanceHasBackend(state) {
4223
4265
  return state.backend ?? Boolean(state.pbPort);
4224
4266
  }
4225
4267
  function serverTemplatesDir() {
4226
- return path21.join(templatesDir(), "server");
4268
+ return path22.join(templatesDir(), "server");
4227
4269
  }
4228
4270
  var DIGEST_LENGTH = 12;
4229
4271
  function serverScriptsDigest(dir = serverTemplatesDir()) {
4230
4272
  const hash = crypto4.createHash("sha256");
4231
4273
  for (const file of listFiles(dir).sort()) {
4232
- hash.update(file).update("\0").update(fs22.readFileSync(path21.join(dir, file))).update("\0");
4274
+ hash.update(file).update("\0").update(fs22.readFileSync(path22.join(dir, file))).update("\0");
4233
4275
  }
4234
4276
  return hash.digest("hex").slice(0, DIGEST_LENGTH);
4235
4277
  }
4236
4278
  function listFiles(root, prefix = "") {
4237
4279
  const files = [];
4238
- for (const entry of fs22.readdirSync(path21.join(root, prefix), { withFileTypes: true })) {
4280
+ for (const entry of fs22.readdirSync(path22.join(root, prefix), { withFileTypes: true })) {
4239
4281
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
4240
4282
  if (entry.isDirectory()) files.push(...listFiles(root, rel));
4241
4283
  else if (entry.isFile()) files.push(rel);
@@ -4875,7 +4917,7 @@ Set ${pc7.cyan("POCKETBASE_SUPERUSER_EMAIL")} and ${pc7.cyan("POCKETBASE_SUPERUS
4875
4917
 
4876
4918
  // src/lib/s3-settings.ts
4877
4919
  import fs25 from "node:fs";
4878
- import path22 from "node:path";
4920
+ import path23 from "node:path";
4879
4921
  var VIRTUAL_HOSTED = [/\.amazonaws\.com$/i, /\.r2\.cloudflarestorage\.com$/i];
4880
4922
  function defaultForcePathStyle(endpoint) {
4881
4923
  let host;
@@ -4913,7 +4955,7 @@ async function hasLocalUploads(session, instance, workspaceRootDir) {
4913
4955
  });
4914
4956
  return result.stdout.trim().length > 0;
4915
4957
  }
4916
- return hasFile(path22.join(workspaceRootDir, DATA_DIR, "storage"));
4958
+ return hasFile(path23.join(workspaceRootDir, DATA_DIR, "storage"));
4917
4959
  }
4918
4960
  function hasFile(dir) {
4919
4961
  let entries;
@@ -4924,7 +4966,7 @@ function hasFile(dir) {
4924
4966
  }
4925
4967
  for (const entry of entries) {
4926
4968
  if (entry.isFile()) return true;
4927
- if (entry.isDirectory() && hasFile(path22.join(dir, entry.name))) return true;
4969
+ if (entry.isDirectory() && hasFile(path23.join(dir, entry.name))) return true;
4928
4970
  }
4929
4971
  return false;
4930
4972
  }
@@ -5964,18 +6006,18 @@ function uiAddReport(requested, outcome) {
5964
6006
  var add = new Command48("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(
5965
6007
  (components, options) => runCommand(async () => {
5966
6008
  const { workspaceRootDir } = await getWorkspace();
5967
- const log49 = p29.taskLog({ title: "Adding UI components..." });
6009
+ const log50 = p29.taskLog({ title: "Adding UI components..." });
5968
6010
  let outcome;
5969
6011
  try {
5970
6012
  outcome = await installComponents({
5971
6013
  root: workspaceRootDir,
5972
6014
  components,
5973
6015
  overwrite: options.overwrite,
5974
- logger: { info: (message) => log49.message(message) }
6016
+ logger: { info: (message) => log50.message(message) }
5975
6017
  });
5976
- log49.success("UI components ready");
6018
+ log50.success("UI components ready");
5977
6019
  } catch (e) {
5978
- log49.error("Could not add UI components");
6020
+ log50.error("Could not add UI components");
5979
6021
  throw e;
5980
6022
  }
5981
6023
  reportResult(uiAddReport(components, outcome));
@@ -5989,13 +6031,13 @@ import { applyBaseColor } from "@velastack/patterns";
5989
6031
  var base = new Command49("base").description("change the base (gray) palette").argument("<color>", `base color to use (${BASE_COLORS.join(", ")})`).configureHelp(helpConfig).action(
5990
6032
  (color) => runCommand(async () => {
5991
6033
  const { workspaceRootDir } = await getWorkspace();
5992
- const log49 = p30.taskLog({ title: `Applying the ${color} palette...` });
6034
+ const log50 = p30.taskLog({ title: `Applying the ${color} palette...` });
5993
6035
  let outcome;
5994
6036
  try {
5995
6037
  outcome = await applyBaseColor({ root: workspaceRootDir, color });
5996
- log49.success("Palette applied");
6038
+ log50.success("Palette applied");
5997
6039
  } catch (e) {
5998
- log49.error("Could not change the base color");
6040
+ log50.error("Could not change the base color");
5999
6041
  throw e;
6000
6042
  }
6001
6043
  reportResult({
@@ -6102,14 +6144,14 @@ var style = new Command51("style").description("switch the shadcn-svelte style,
6102
6144
  const { workspaceRootDir } = await getWorkspace();
6103
6145
  const spinner8 = p32.spinner();
6104
6146
  spinner8.start(`Reading the ${name} registry...`);
6105
- let log49;
6147
+ let log50;
6106
6148
  let outcome;
6107
6149
  try {
6108
6150
  outcome = await switchStyle({
6109
6151
  root: workspaceRootDir,
6110
6152
  style: name,
6111
6153
  font: options.font,
6112
- logger: { info: (message) => log49?.message(message) },
6154
+ logger: { info: (message) => log50?.message(message) },
6113
6155
  confirm: async (components) => {
6114
6156
  spinner8.stop(`Read the ${name} registry`);
6115
6157
  if (components.length > 0) {
@@ -6126,13 +6168,13 @@ ${components.map((c) => `- ${c}`).join("\n")}`
6126
6168
  const ok = await p32.confirm({ message: `Switch to ${name}?`, initialValue: false });
6127
6169
  if (p32.isCancel(ok) || !ok) return false;
6128
6170
  }
6129
- log49 = p32.taskLog({ title: `Switching to the ${name} style...` });
6171
+ log50 = p32.taskLog({ title: `Switching to the ${name} style...` });
6130
6172
  return true;
6131
6173
  }
6132
6174
  });
6133
6175
  } catch (e) {
6134
6176
  spinner8.stop(`Could not switch to ${name}`);
6135
- log49?.error("Could not switch style");
6177
+ log50?.error("Could not switch style");
6136
6178
  throw e;
6137
6179
  }
6138
6180
  spinner8.stop(`Read the ${name} registry`);
@@ -6144,7 +6186,7 @@ ${components.map((c) => `- ${c}`).join("\n")}`
6144
6186
  p32.cancel("Operation cancelled.");
6145
6187
  return;
6146
6188
  }
6147
- log49?.success("Style switched");
6189
+ log50?.success("Style switched");
6148
6190
  reportResult(uiStyleReport(outcome));
6149
6191
  }, "Failed to switch style.")
6150
6192
  );
@@ -6156,13 +6198,13 @@ import { applyTheme } from "@velastack/patterns";
6156
6198
  var theme = new Command52("theme").description("change the accent color, keeping the base palette").argument("<accent>", `accent to use (${THEMES.join(", ")})`).configureHelp(helpConfig).action(
6157
6199
  (accent) => runCommand(async () => {
6158
6200
  const { workspaceRootDir } = await getWorkspace();
6159
- const log49 = p33.taskLog({ title: `Applying the ${accent} accent...` });
6201
+ const log50 = p33.taskLog({ title: `Applying the ${accent} accent...` });
6160
6202
  let outcome;
6161
6203
  try {
6162
6204
  outcome = await applyTheme({ root: workspaceRootDir, theme: accent });
6163
- log49.success("Accent applied");
6205
+ log50.success("Accent applied");
6164
6206
  } catch (e) {
6165
- log49.error("Could not change the accent");
6207
+ log50.error("Could not change the accent");
6166
6208
  throw e;
6167
6209
  }
6168
6210
  reportResult({
@@ -6185,7 +6227,7 @@ import { Command as Command56 } from "commander";
6185
6227
 
6186
6228
  // src/commands/legal/terms.ts
6187
6229
  import fs26 from "node:fs";
6188
- import path23 from "node:path";
6230
+ import path24 from "node:path";
6189
6231
  import { Command as Command54 } from "commander";
6190
6232
  import * as p35 from "@clack/prompts";
6191
6233
 
@@ -6844,22 +6886,22 @@ async function termsAction() {
6844
6886
  mobileApp,
6845
6887
  contact
6846
6888
  });
6847
- const termsPage = path23.join(
6889
+ const termsPage = path24.join(
6848
6890
  workspaceRootDir,
6849
6891
  publicRoutesDir,
6850
6892
  LEGAL_DIR,
6851
6893
  "terms",
6852
6894
  "+page.svelte"
6853
6895
  );
6854
- const termsPageTs = path23.join(workspaceRootDir, publicRoutesDir, LEGAL_DIR, "terms", "+page.ts");
6855
- fs26.mkdirSync(path23.dirname(termsPage), { recursive: true });
6896
+ const termsPageTs = path24.join(workspaceRootDir, publicRoutesDir, LEGAL_DIR, "terms", "+page.ts");
6897
+ fs26.mkdirSync(path24.dirname(termsPage), { recursive: true });
6856
6898
  fs26.writeFileSync(termsPage, html);
6857
6899
  fs26.writeFileSync(
6858
6900
  termsPageTs,
6859
6901
  pageMetaTagsLoader("Terms of Service", `Terms of Service for ${core.websiteName}`)
6860
6902
  );
6861
- const relativeTermsPage = path23.relative(workspaceRootDir, termsPage);
6862
- const relativeTermsPageTs = path23.relative(workspaceRootDir, termsPageTs);
6903
+ const relativeTermsPage = path24.relative(workspaceRootDir, termsPage);
6904
+ const relativeTermsPageTs = path24.relative(workspaceRootDir, termsPageTs);
6863
6905
  reportResult({
6864
6906
  summary: "Generated placeholder terms and conditions.",
6865
6907
  filesCreated: [relativeTermsPage, relativeTermsPageTs],
@@ -6874,7 +6916,7 @@ var terms = new Command54("terms").description("generate placeholder terms and c
6874
6916
 
6875
6917
  // src/commands/legal/privacy.ts
6876
6918
  import fs27 from "node:fs";
6877
- import path24 from "node:path";
6919
+ import path25 from "node:path";
6878
6920
  import { Command as Command55 } from "commander";
6879
6921
  import * as p36 from "@clack/prompts";
6880
6922
  var mapLabels = {
@@ -7587,28 +7629,28 @@ async function privacyAction() {
7587
7629
  kids,
7588
7630
  retention
7589
7631
  });
7590
- const privacyPage = path24.join(
7632
+ const privacyPage = path25.join(
7591
7633
  workspaceRootDir,
7592
7634
  publicRoutesDir,
7593
7635
  LEGAL_DIR,
7594
7636
  "privacy",
7595
7637
  "+page.svelte"
7596
7638
  );
7597
- const privacyPageTs = path24.join(
7639
+ const privacyPageTs = path25.join(
7598
7640
  workspaceRootDir,
7599
7641
  publicRoutesDir,
7600
7642
  LEGAL_DIR,
7601
7643
  "privacy",
7602
7644
  "+page.ts"
7603
7645
  );
7604
- fs27.mkdirSync(path24.dirname(privacyPage), { recursive: true });
7646
+ fs27.mkdirSync(path25.dirname(privacyPage), { recursive: true });
7605
7647
  fs27.writeFileSync(privacyPage, html);
7606
7648
  fs27.writeFileSync(
7607
7649
  privacyPageTs,
7608
7650
  pageMetaTagsLoader("Privacy Policy", `Privacy Policy for ${core.websiteName}`)
7609
7651
  );
7610
- const relativePrivacyPage = path24.relative(workspaceRootDir, privacyPage);
7611
- const relativePrivacyPageTs = path24.relative(workspaceRootDir, privacyPageTs);
7652
+ const relativePrivacyPage = path25.relative(workspaceRootDir, privacyPage);
7653
+ const relativePrivacyPageTs = path25.relative(workspaceRootDir, privacyPageTs);
7612
7654
  reportResult({
7613
7655
  summary: "Generated placeholder privacy policy.",
7614
7656
  filesCreated: [relativePrivacyPage, relativePrivacyPageTs],
@@ -7632,7 +7674,7 @@ import { Command as Command57 } from "commander";
7632
7674
 
7633
7675
  // src/lib/data.ts
7634
7676
  import fs28 from "node:fs";
7635
- import path25 from "node:path";
7677
+ import path26 from "node:path";
7636
7678
  import { ClientResponseError } from "pocketbase";
7637
7679
 
7638
7680
  // src/lib/collections.ts
@@ -7669,14 +7711,14 @@ function dependencyOrder(collections2, startingCollectionId) {
7669
7711
 
7670
7712
  // src/lib/data.ts
7671
7713
  function dataDir(cwd, kind) {
7672
- return path25.join(cwd, DATA_DIR, kind);
7714
+ return path26.join(cwd, DATA_DIR, kind);
7673
7715
  }
7674
7716
  function getDataFiles(cwd, kind) {
7675
7717
  const dir = dataDir(cwd, kind);
7676
7718
  if (!fs28.existsSync(dir)) return [];
7677
7719
  return fs28.readdirSync(dir).filter((file) => file.endsWith(".json")).sort((a, b) => a.localeCompare(b)).map((file) => ({
7678
7720
  collectionName: file.replace(/\.json$/i, "").replace(/^\d+[-_]?/, ""),
7679
- filePath: path25.join(dir, file)
7721
+ filePath: path26.join(dir, file)
7680
7722
  }));
7681
7723
  }
7682
7724
  function getSeedFiles(cwd) {
@@ -7723,7 +7765,7 @@ function describeError(e) {
7723
7765
  return e instanceof Error ? e.message : String(e);
7724
7766
  }
7725
7767
  function label3(cwd, filePath, count) {
7726
- return `${path25.relative(cwd, filePath)} (${count} records)`;
7768
+ return `${path26.relative(cwd, filePath)} (${count} records)`;
7727
7769
  }
7728
7770
  async function createRecords(pb, kind, cwd, { collectionName, filePath }) {
7729
7771
  const records = readRecords(filePath);
@@ -7731,7 +7773,7 @@ async function createRecords(pb, kind, cwd, { collectionName, filePath }) {
7731
7773
  try {
7732
7774
  await pb.collection(collectionName).create(record);
7733
7775
  } catch (e) {
7734
- throw new DataLoadError(kind, path25.relative(cwd, filePath), index, e);
7776
+ throw new DataLoadError(kind, path26.relative(cwd, filePath), index, e);
7735
7777
  }
7736
7778
  }
7737
7779
  return records.length;
@@ -7906,7 +7948,7 @@ var reset = new Command59("reset").description("clear and reload fixtures").conf
7906
7948
 
7907
7949
  // src/commands/fixtures/generate.ts
7908
7950
  import fs29 from "node:fs";
7909
- import path26 from "node:path";
7951
+ import path27 from "node:path";
7910
7952
  import { Command as Command60, InvalidArgumentError } from "commander";
7911
7953
  import * as p37 from "@clack/prompts";
7912
7954
  import { annotate } from "annotate-json-schema";
@@ -7945,7 +7987,7 @@ async function generateFixtureFiles(pb, workspaceRootDir, opts) {
7945
7987
  const fixturesDir = dataDir(workspaceRootDir, "fixtures");
7946
7988
  fs29.mkdirSync(fixturesDir, { recursive: true });
7947
7989
  for (const file of fs29.readdirSync(fixturesDir)) {
7948
- if (file.endsWith(".json")) fs29.unlinkSync(path26.join(fixturesDir, file));
7990
+ if (file.endsWith(".json")) fs29.unlinkSync(path27.join(fixturesDir, file));
7949
7991
  }
7950
7992
  if (opts.seed !== void 0) faker.seed(opts.seed);
7951
7993
  const generator = createGenerator({
@@ -8012,8 +8054,8 @@ async function generateFixtureFiles(pb, workspaceRootDir, opts) {
8012
8054
  items.push(record);
8013
8055
  }
8014
8056
  const filename = `${padZeros(fileIndex, 2)}-${collection.name}.json`;
8015
- fs29.writeFileSync(path26.join(fixturesDir, filename), JSON.stringify(items, null, 2));
8016
- writtenFiles.push(`${path26.join(DATA_DIR, "fixtures", filename)} (${items.length} records)`);
8057
+ fs29.writeFileSync(path27.join(fixturesDir, filename), JSON.stringify(items, null, 2));
8058
+ writtenFiles.push(`${path27.join(DATA_DIR, "fixtures", filename)} (${items.length} records)`);
8017
8059
  fileIndex++;
8018
8060
  }
8019
8061
  return { writtenFiles, warnings };
@@ -8161,7 +8203,7 @@ var load2 = new Command63("load").description("load seeds into the database").op
8161
8203
 
8162
8204
  // src/commands/seeds/save.ts
8163
8205
  import fs30 from "node:fs";
8164
- import path27 from "node:path";
8206
+ import path28 from "node:path";
8165
8207
  import { Command as Command64 } from "commander";
8166
8208
  var padZeros2 = (num, length) => num.toString().padStart(length, "0");
8167
8209
  function filterSystemFields(record, systemFieldNames) {
@@ -8184,7 +8226,7 @@ var save = new Command64("save").description("save the current data as seeds").o
8184
8226
  fs30.mkdirSync(seedsPath, { recursive: true });
8185
8227
  if (opts.force) {
8186
8228
  for (const file of fs30.readdirSync(seedsPath)) {
8187
- if (file.endsWith(".json")) fs30.unlinkSync(path27.join(seedsPath, file));
8229
+ if (file.endsWith(".json")) fs30.unlinkSync(path28.join(seedsPath, file));
8188
8230
  }
8189
8231
  }
8190
8232
  const saved = [];
@@ -8213,12 +8255,12 @@ var save = new Command64("save").description("save the current data as seeds").o
8213
8255
  const filtered = records.map(
8214
8256
  (r) => filterSystemFields(r, systemFieldNames)
8215
8257
  );
8216
- const relativeSeedPath = path27.join(
8258
+ const relativeSeedPath = path28.join(
8217
8259
  DATA_DIR,
8218
8260
  "seeds",
8219
8261
  `${padZeros2(count, 2)}-${collectionName}.json`
8220
8262
  );
8221
- const seedPath = path27.join(workspaceRootDir, relativeSeedPath);
8263
+ const seedPath = path28.join(workspaceRootDir, relativeSeedPath);
8222
8264
  fs30.writeFileSync(seedPath, JSON.stringify(filtered, null, 2));
8223
8265
  saved.push(`${relativeSeedPath} (${filtered.length} records)`);
8224
8266
  count++;
@@ -8357,7 +8399,7 @@ import { Command as Command75 } from "commander";
8357
8399
  import { Command as Command70 } from "commander";
8358
8400
 
8359
8401
  // src/lib/migrate.ts
8360
- import path28 from "node:path";
8402
+ import path29 from "node:path";
8361
8403
  import process23 from "node:process";
8362
8404
  import { x as x2 } from "tinyexec";
8363
8405
  async function runPocketbaseMigrate(args) {
@@ -8368,9 +8410,9 @@ async function runPocketbaseMigrate(args) {
8368
8410
  binaryPath,
8369
8411
  [
8370
8412
  "--dir",
8371
- path28.join(cwd, DATA_DIR),
8413
+ path29.join(cwd, DATA_DIR),
8372
8414
  "--migrationsDir",
8373
- path28.join(cwd, MIGRATIONS_DIR),
8415
+ path29.join(cwd, MIGRATIONS_DIR),
8374
8416
  "migrate",
8375
8417
  ...args
8376
8418
  ],
@@ -8419,7 +8461,7 @@ var down = new Command71("down").alias("rollback").description("revert the last
8419
8461
 
8420
8462
  // src/commands/migrate/create.ts
8421
8463
  import fs31 from "node:fs";
8422
- import path29 from "node:path";
8464
+ import path30 from "node:path";
8423
8465
  import process24 from "node:process";
8424
8466
  import { Command as Command72 } from "commander";
8425
8467
  var create2 = new Command72("create").alias("new").description("create a new blank migration").argument("<name>", "migration name (snake_case)").configureHelp(helpConfig).action(
@@ -8431,7 +8473,7 @@ var create2 = new Command72("create").alias("new").description("create a new bla
8431
8473
  const added = [...after].filter((f) => !before.has(f));
8432
8474
  reportResult({
8433
8475
  summary: `Created blank migration ${name}.`,
8434
- filesCreated: added.map((f) => path29.join(MIGRATIONS_DIR, f)),
8476
+ filesCreated: added.map((f) => path30.join(MIGRATIONS_DIR, f)),
8435
8477
  nextSteps: [
8436
8478
  `Open the new file in ${MIGRATIONS_DIR}/ and fill in the up/down handlers.`,
8437
8479
  "Run `vela migrate up` to apply the migration once the handlers are written."
@@ -8440,14 +8482,14 @@ var create2 = new Command72("create").alias("new").description("create a new bla
8440
8482
  }, "Failed to create migration.")
8441
8483
  );
8442
8484
  function listMigrationFiles(cwd) {
8443
- const dir = path29.join(cwd, MIGRATIONS_DIR);
8485
+ const dir = path30.join(cwd, MIGRATIONS_DIR);
8444
8486
  if (!fs31.existsSync(dir)) return /* @__PURE__ */ new Set();
8445
8487
  return new Set(fs31.readdirSync(dir).filter((f) => /\.[jt]s$/.test(f)));
8446
8488
  }
8447
8489
 
8448
8490
  // src/commands/migrate/collections.ts
8449
8491
  import fs32 from "node:fs";
8450
- import path30 from "node:path";
8492
+ import path31 from "node:path";
8451
8493
  import process25 from "node:process";
8452
8494
  import { Command as Command73 } from "commander";
8453
8495
  var collections = new Command73("collections").alias("snapshot").description("snapshot local collections into a new migration").configureHelp(helpConfig).action(
@@ -8465,7 +8507,7 @@ var collections = new Command73("collections").alias("snapshot").description("sn
8465
8507
  }
8466
8508
  reportResult({
8467
8509
  summary: "Snapshotted local collections into a new migration.",
8468
- filesCreated: added.map((f) => path30.join(MIGRATIONS_DIR, f)),
8510
+ filesCreated: added.map((f) => path31.join(MIGRATIONS_DIR, f)),
8469
8511
  nextSteps: [
8470
8512
  `Review the generated snapshot in ${MIGRATIONS_DIR}/.`,
8471
8513
  "Commit the snapshot so teammates pick up the new schema.",
@@ -8475,7 +8517,7 @@ var collections = new Command73("collections").alias("snapshot").description("sn
8475
8517
  }, "Failed to snapshot collections.")
8476
8518
  );
8477
8519
  function listMigrationFiles2(cwd) {
8478
- const dir = path30.join(cwd, MIGRATIONS_DIR);
8520
+ const dir = path31.join(cwd, MIGRATIONS_DIR);
8479
8521
  if (!fs32.existsSync(dir)) return /* @__PURE__ */ new Set();
8480
8522
  return new Set(fs32.readdirSync(dir).filter((f) => /\.[jt]s$/.test(f)));
8481
8523
  }
@@ -8497,7 +8539,7 @@ var migrate = new Command75("migrate").description("manage database migrations")
8497
8539
 
8498
8540
  // src/commands/dev.ts
8499
8541
  import fs33 from "node:fs";
8500
- import path32 from "node:path";
8542
+ import path33 from "node:path";
8501
8543
  import process27 from "node:process";
8502
8544
  import { performance } from "node:perf_hooks";
8503
8545
  import { Command as Command76, InvalidArgumentError as InvalidArgumentError4 } from "commander";
@@ -8529,7 +8571,7 @@ function createPocketbaseLogFilter() {
8529
8571
  }
8530
8572
 
8531
8573
  // src/lib/vite.ts
8532
- import path31 from "node:path";
8574
+ import path32 from "node:path";
8533
8575
  import process26 from "node:process";
8534
8576
  import { createRequire as createRequire2 } from "node:module";
8535
8577
  import { pathToFileURL as pathToFileURL2 } from "node:url";
@@ -8549,7 +8591,7 @@ function viteVersionError(version) {
8549
8591
  }
8550
8592
  function resolveProjectVite(cwd) {
8551
8593
  try {
8552
- return createRequire2(path31.join(cwd, "package.json")).resolve("vite");
8594
+ return createRequire2(path32.join(cwd, "package.json")).resolve("vite");
8553
8595
  } catch {
8554
8596
  return null;
8555
8597
  }
@@ -8578,8 +8620,8 @@ var dev = new Command76("dev").description("start the development server").optio
8578
8620
  process27.env.VELA_DATA_DIR ??= localDataDir(cwd);
8579
8621
  const startTime = performance.now();
8580
8622
  const { createServer, version } = await loadVite(cwd);
8581
- const viteMetadataDir = path32.join(cwd, "node_modules", ".vite");
8582
- const viteMetadataFile = path32.join(viteMetadataDir, "_pocketbase_metadata.json");
8623
+ const viteMetadataDir = path33.join(cwd, "node_modules", ".vite");
8624
+ const viteMetadataFile = path33.join(viteMetadataDir, "_pocketbase_metadata.json");
8583
8625
  let pbProc;
8584
8626
  const backend3 = hasBackend(cwd);
8585
8627
  const needsStart = backend3 && !process27.env.POCKETBASE_URL;
@@ -8588,11 +8630,11 @@ var dev = new Command76("dev").description("start the development server").optio
8588
8630
  if (fs33.existsSync(viteMetadataFile)) fs33.rmSync(viteMetadataFile);
8589
8631
  };
8590
8632
  if (needsStart) {
8591
- const dataDir2 = path32.join(cwd, DATA_DIR);
8633
+ const dataDir2 = path33.join(cwd, DATA_DIR);
8592
8634
  const started = await startPocketbaseServe({
8593
8635
  dataDir: dataDir2,
8594
8636
  migrationsDir: MIGRATIONS_DIR,
8595
- hooksDir: path32.join(dataDir2, "hooks"),
8637
+ hooksDir: path33.join(dataDir2, "hooks"),
8596
8638
  dev: true,
8597
8639
  stdio: "pipe"
8598
8640
  });
@@ -8657,9 +8699,9 @@ var dev = new Command76("dev").description("start the development server").optio
8657
8699
  });
8658
8700
  async function startWatchingTypes(cwd, pb) {
8659
8701
  const { processTypes } = await import("@velastack/pocketbase-codegen");
8660
- const typesDir = path32.resolve(cwd, ".svelte-kit", "types");
8661
- const pocketbaseDir = path32.join(typesDir, "pocketbase");
8662
- const pocketbaseTypes = path32.join(pocketbaseDir, "$types.d.ts");
8702
+ const typesDir = path33.resolve(cwd, ".svelte-kit", "types");
8703
+ const pocketbaseDir = path33.join(typesDir, "pocketbase");
8704
+ const pocketbaseTypes = path33.join(pocketbaseDir, "$types.d.ts");
8663
8705
  const regenerate = () => processTypes(pb, typesDir).catch(() => {
8664
8706
  });
8665
8707
  await regenerate();
@@ -8681,7 +8723,7 @@ async function startWatchingTypes(cwd, pb) {
8681
8723
 
8682
8724
  // src/commands/build.ts
8683
8725
  import fs34 from "node:fs";
8684
- import path33 from "node:path";
8726
+ import path34 from "node:path";
8685
8727
  import process29 from "node:process";
8686
8728
  import { Command as Command77 } from "commander";
8687
8729
  import * as p42 from "@clack/prompts";
@@ -8719,7 +8761,7 @@ function splitHosts(value) {
8719
8761
  }
8720
8762
 
8721
8763
  // src/commands/build.ts
8722
- var PRERENDERED_DIR = path33.join(".svelte-kit", "output", "prerendered");
8764
+ var PRERENDERED_DIR = path34.join(".svelte-kit", "output", "prerendered");
8723
8765
  var build = new Command77("build").description("build the app").configureHelp(helpConfig).option("-t, --target <target>", "which copy of the app to build for", PRODUCTION_TARGET).action(async (options) => {
8724
8766
  const cwd = process29.cwd();
8725
8767
  applyBuildEnv(cwd);
@@ -8732,11 +8774,11 @@ var build = new Command77("build").description("build the app").configureHelp(he
8732
8774
  };
8733
8775
  if (needsStart) {
8734
8776
  await ensureSuperuser(cwd);
8735
- const dataDir2 = path33.join(cwd, DATA_DIR);
8777
+ const dataDir2 = path34.join(cwd, DATA_DIR);
8736
8778
  const started = await startPocketbaseServe({
8737
8779
  dataDir: dataDir2,
8738
8780
  migrationsDir: MIGRATIONS_DIR,
8739
- hooksDir: path33.join(dataDir2, "hooks"),
8781
+ hooksDir: path34.join(dataDir2, "hooks"),
8740
8782
  dev: true
8741
8783
  });
8742
8784
  pbProc = started.proc;
@@ -8775,7 +8817,7 @@ async function originForBuild(cwd, target) {
8775
8817
  }
8776
8818
  }
8777
8819
  function warnIfPrerendered(cwd) {
8778
- const dir = path33.join(cwd, PRERENDERED_DIR);
8820
+ const dir = path34.join(cwd, PRERENDERED_DIR);
8779
8821
  if (!fs34.existsSync(dir) || fs34.readdirSync(dir).length === 0) return;
8780
8822
  p42.log.warn(
8781
8823
  `Prerendered pages were built with no domain configured, so their canonical
@@ -8786,7 +8828,7 @@ Set one with ${pc16.cyan("vela deploy --domain example.com")}, or pass ${pc16.cy
8786
8828
  }
8787
8829
 
8788
8830
  // src/commands/preview.ts
8789
- import path34 from "node:path";
8831
+ import path35 from "node:path";
8790
8832
  import process30 from "node:process";
8791
8833
  import { Command as Command78 } from "commander";
8792
8834
  import { x as x4 } from "tinyexec";
@@ -8801,11 +8843,11 @@ var preview = new Command78("preview").description("preview the built app").conf
8801
8843
  if (pbProc?.pid) pbProc.kill();
8802
8844
  };
8803
8845
  if (needsStart) {
8804
- const dataDir2 = path34.join(cwd, DATA_DIR);
8846
+ const dataDir2 = path35.join(cwd, DATA_DIR);
8805
8847
  const started = await startPocketbaseServe({
8806
8848
  dataDir: dataDir2,
8807
8849
  migrationsDir: MIGRATIONS_DIR,
8808
- hooksDir: path34.join(dataDir2, "hooks"),
8850
+ hooksDir: path35.join(dataDir2, "hooks"),
8809
8851
  dev: true
8810
8852
  });
8811
8853
  pbProc = started.proc;
@@ -8831,12 +8873,12 @@ var preview = new Command78("preview").description("preview the built app").conf
8831
8873
  });
8832
8874
 
8833
8875
  // src/commands/sync.ts
8834
- import path35 from "node:path";
8876
+ import path36 from "node:path";
8835
8877
  import { Command as Command79 } from "commander";
8836
8878
  var sync = new Command79("sync").description("sync types from the database").configureHelp(helpConfig).action(
8837
8879
  () => runCommand(async () => {
8838
8880
  const { workspaceRootDir } = await getWorkspace();
8839
- const typesDir = path35.join(workspaceRootDir, ".svelte-kit", "types");
8881
+ const typesDir = path36.join(workspaceRootDir, ".svelte-kit", "types");
8840
8882
  const { processTypes } = await import("@velastack/pocketbase-codegen");
8841
8883
  await withPocketbase(workspaceRootDir, async (pb) => {
8842
8884
  await processTypes(pb, typesDir);
@@ -8898,7 +8940,7 @@ var provision = addSshOptions(
8898
8940
  );
8899
8941
 
8900
8942
  // src/commands/deploy.ts
8901
- import path38 from "node:path";
8943
+ import path39 from "node:path";
8902
8944
  import fs37 from "node:fs";
8903
8945
  import { Command as Command81, Option as Option2 } from "commander";
8904
8946
  import * as p44 from "@clack/prompts";
@@ -8907,12 +8949,12 @@ import * as v8 from "valibot";
8907
8949
 
8908
8950
  // src/lib/pocketbase-settings.ts
8909
8951
  import fs35 from "node:fs";
8910
- import path36 from "node:path";
8952
+ import path37 from "node:path";
8911
8953
  import process31 from "node:process";
8912
8954
  import PocketBase5 from "pocketbase";
8913
8955
  var COPIED_KEYS = ["appName", "senderName", "senderAddress"];
8914
8956
  async function readLocalMeta(cwd) {
8915
- const dataDir2 = path36.join(cwd, DATA_DIR);
8957
+ const dataDir2 = path37.join(cwd, DATA_DIR);
8916
8958
  if (!fs35.existsSync(dataDir2)) return null;
8917
8959
  const email3 = process31.env.POCKETBASE_SUPERUSER_EMAIL;
8918
8960
  const password11 = process31.env.POCKETBASE_SUPERUSER_PASSWORD;
@@ -8922,7 +8964,7 @@ async function readLocalMeta(cwd) {
8922
8964
  const started = await startPocketbaseServe({
8923
8965
  dataDir: dataDir2,
8924
8966
  migrationsDir: MIGRATIONS_DIR,
8925
- hooksDir: path36.join(dataDir2, "hooks")
8967
+ hooksDir: path37.join(dataDir2, "hooks")
8926
8968
  });
8927
8969
  proc = started.proc;
8928
8970
  const pb = new PocketBase5(started.url);
@@ -8965,7 +9007,7 @@ async function seedRemoteMeta(session, instance, local, appURL) {
8965
9007
 
8966
9008
  // src/lib/adapter.ts
8967
9009
  import fs36 from "node:fs";
8968
- import path37 from "node:path";
9010
+ import path38 from "node:path";
8969
9011
  import {
8970
9012
  Project as Project2,
8971
9013
  QuoteKind as QuoteKind2,
@@ -9021,7 +9063,7 @@ function resolveKitTarget(root) {
9021
9063
  }
9022
9064
  const sveltePath = probeFirstExisting(root, SVELTE_CONFIG_CANDIDATES);
9023
9065
  if (sveltePath) {
9024
- const name = path37.basename(sveltePath);
9066
+ const name = path38.basename(sveltePath);
9025
9067
  if (sveltePath.endsWith(".cjs")) {
9026
9068
  throw new AdapterError(`${name} is CommonJS, which vela does not edit.`);
9027
9069
  }
@@ -9041,7 +9083,7 @@ function resolveKitTarget(root) {
9041
9083
  };
9042
9084
  }
9043
9085
  if (vite?.sveltekitCall) {
9044
- const name = path37.basename(vite.filePath);
9086
+ const name = path38.basename(vite.filePath);
9045
9087
  if (vite.nonObjectArg) {
9046
9088
  throw new AdapterError(`${name} passes sveltekit() something other than an object literal.`);
9047
9089
  }
@@ -9094,7 +9136,7 @@ function inspectAdapter(target) {
9094
9136
  async function ensureNodeAdapter(root, { install = true } = {}) {
9095
9137
  const target = resolveKitTarget(root);
9096
9138
  const { info, importDecl } = inspectAdapter(target);
9097
- const name = path37.basename(target.filePath);
9139
+ const name = path38.basename(target.filePath);
9098
9140
  const outcome = {
9099
9141
  previous: info.kind,
9100
9142
  removedDeps: [],
@@ -9127,7 +9169,7 @@ vela deploy runs the app as a Node server, which needs ${ADAPTER_NODE}:`
9127
9169
  break;
9128
9170
  }
9129
9171
  if (outcome.configFile) saveTarget(target);
9130
- const pkgPath = path37.join(root, "package.json");
9172
+ const pkgPath = path38.join(root, "package.json");
9131
9173
  if (fs36.existsSync(pkgPath)) {
9132
9174
  const pkg = readPackageJson(pkgPath);
9133
9175
  const { changed, removed } = adoptNodeAdapter(pkg);
@@ -9180,7 +9222,7 @@ function addAdapter(target) {
9180
9222
  const taken = importOf(target.sourceFile, "adapter") ?? target.sourceFile.getVariableDeclaration("adapter");
9181
9223
  if (taken) {
9182
9224
  throw new AdapterError(
9183
- `${path37.basename(target.filePath)} already binds the name \`adapter\` to something that is not the SvelteKit adapter.`
9225
+ `${path38.basename(target.filePath)} already binds the name \`adapter\` to something that is not the SvelteKit adapter.`
9184
9226
  );
9185
9227
  }
9186
9228
  target.sourceFile.addImportDeclaration({
@@ -9591,7 +9633,7 @@ function isDirectory(target) {
9591
9633
  async function reportEmptyEnvironment(session, instance, workspaceRootDir) {
9592
9634
  const remote = await readRemoteEnv(session, instance);
9593
9635
  if (Object.keys(remote).length > 0) return;
9594
- if (!fs37.existsSync(path38.join(workspaceRootDir, ".env"))) return;
9636
+ if (!fs37.existsSync(path39.join(workspaceRootDir, ".env"))) return;
9595
9637
  p44.log.warn(
9596
9638
  `This app has no production environment variables yet.
9597
9639
 
@@ -9609,7 +9651,7 @@ async function serverTimeOrLocal(session) {
9609
9651
  }
9610
9652
 
9611
9653
  // src/commands/link.ts
9612
- import path39 from "node:path";
9654
+ import path40 from "node:path";
9613
9655
  import process32 from "node:process";
9614
9656
  import { Command as Command82 } from "commander";
9615
9657
  import * as p45 from "@clack/prompts";
@@ -9672,12 +9714,12 @@ async function promptProjectName(workspaceRootDir) {
9672
9714
  }
9673
9715
  function defaultProjectName2(workspaceRootDir) {
9674
9716
  try {
9675
- const pkg = readPackageJson(path39.join(workspaceRootDir, "package.json"));
9717
+ const pkg = readPackageJson(path40.join(workspaceRootDir, "package.json"));
9676
9718
  const name = pkg.name;
9677
9719
  if (typeof name === "string" && name.trim()) return name.trim();
9678
9720
  } catch {
9679
9721
  }
9680
- return path39.basename(workspaceRootDir);
9722
+ return path40.basename(workspaceRootDir);
9681
9723
  }
9682
9724
 
9683
9725
  // src/commands/env.ts
@@ -9809,7 +9851,7 @@ var envUnset = addTargetOptions(
9809
9851
 
9810
9852
  // src/commands/env/import.ts
9811
9853
  import fs38 from "node:fs";
9812
- import path40 from "node:path";
9854
+ import path41 from "node:path";
9813
9855
  import process34 from "node:process";
9814
9856
  import { Command as Command86 } from "commander";
9815
9857
  import * as p49 from "@clack/prompts";
@@ -9855,7 +9897,7 @@ var envImport = addTargetOptions(
9855
9897
  )
9856
9898
  );
9857
9899
  function resolve(file) {
9858
- return path40.resolve(process34.cwd(), file);
9900
+ return path41.resolve(process34.cwd(), file);
9859
9901
  }
9860
9902
  function read(resolved, shown) {
9861
9903
  if (!fs38.existsSync(resolved)) throw new Error(`${shown} does not exist.`);
@@ -10137,7 +10179,7 @@ import { Command as Command98 } from "commander";
10137
10179
 
10138
10180
  // src/commands/backup/create.ts
10139
10181
  import fs39 from "node:fs";
10140
- import path41 from "node:path";
10182
+ import path42 from "node:path";
10141
10183
  import { Command as Command93 } from "commander";
10142
10184
  import * as p53 from "@clack/prompts";
10143
10185
  import pc26 from "picocolors";
@@ -10291,12 +10333,12 @@ Your bucket's own versioning is what protects the uploaded files.`
10291
10333
  }, "Failed to create the backup.")
10292
10334
  );
10293
10335
  async function download(ctx, key, outputDir) {
10294
- const dir = path41.resolve(ctx.workspaceRootDir, outputDir);
10336
+ const dir = path42.resolve(ctx.workspaceRootDir, outputDir);
10295
10337
  fs39.mkdirSync(dir, { recursive: true });
10296
- const destination = path41.join(dir, key);
10338
+ const destination = path42.join(dir, key);
10297
10339
  if (!ctx.session) {
10298
- fs39.copyFileSync(path41.join(ctx.workspaceRootDir, "data", "backups", key), destination);
10299
- return path41.relative(ctx.workspaceRootDir, destination);
10340
+ fs39.copyFileSync(path42.join(ctx.workspaceRootDir, "data", "backups", key), destination);
10341
+ return path42.relative(ctx.workspaceRootDir, destination);
10300
10342
  }
10301
10343
  const spinner8 = p53.spinner();
10302
10344
  spinner8.start(`Downloading ${key}`);
@@ -10307,7 +10349,7 @@ async function download(ctx, key, outputDir) {
10307
10349
  throw error;
10308
10350
  }
10309
10351
  spinner8.stop(`Downloaded ${key}`);
10310
- return path41.relative(ctx.workspaceRootDir, destination);
10352
+ return path42.relative(ctx.workspaceRootDir, destination);
10311
10353
  }
10312
10354
 
10313
10355
  // src/commands/backup/list.ts
@@ -10342,7 +10384,7 @@ Take one with ${pc27.cyan("vela backup create")}.`
10342
10384
 
10343
10385
  // src/commands/backup/download.ts
10344
10386
  import fs40 from "node:fs";
10345
- import path42 from "node:path";
10387
+ import path43 from "node:path";
10346
10388
  import { Command as Command95 } from "commander";
10347
10389
  import * as p55 from "@clack/prompts";
10348
10390
  import pc28 from "picocolors";
@@ -10369,11 +10411,11 @@ Run ${pc28.cyan("vela backup list")} to see what it does have.`
10369
10411
  Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
10370
10412
  );
10371
10413
  }
10372
- const dir = path42.resolve(ctx.workspaceRootDir, options.output);
10414
+ const dir = path43.resolve(ctx.workspaceRootDir, options.output);
10373
10415
  fs40.mkdirSync(dir, { recursive: true });
10374
- const destination = path42.join(dir, key);
10416
+ const destination = path43.join(dir, key);
10375
10417
  if (!ctx.session) {
10376
- fs40.copyFileSync(path42.join(ctx.workspaceRootDir, "data", "backups", key), destination);
10418
+ fs40.copyFileSync(path43.join(ctx.workspaceRootDir, "data", "backups", key), destination);
10377
10419
  } else {
10378
10420
  const spinner8 = p55.spinner();
10379
10421
  spinner8.start(`Downloading ${key} (${formatBytes(found.size)})`);
@@ -10387,7 +10429,7 @@ Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
10387
10429
  }
10388
10430
  reportResult({
10389
10431
  summary: `Saved ${key} from ${ctx.targetName}.`,
10390
- filesCreated: [path42.relative(ctx.workspaceRootDir, destination)]
10432
+ filesCreated: [path43.relative(ctx.workspaceRootDir, destination)]
10391
10433
  });
10392
10434
  });
10393
10435
  }, "Failed to download the backup.")
@@ -10483,7 +10525,7 @@ var backup = new Command98("backup").description("back up the database and uploa
10483
10525
 
10484
10526
  // src/commands/restore.ts
10485
10527
  import fs41 from "node:fs";
10486
- import path43 from "node:path";
10528
+ import path44 from "node:path";
10487
10529
  import process37 from "node:process";
10488
10530
  import { Command as Command99 } from "commander";
10489
10531
  import * as p58 from "@clack/prompts";
@@ -10529,7 +10571,7 @@ var restore = addLockWaitOption(
10529
10571
  });
10530
10572
  p58.log.success(
10531
10573
  `Restored ${pc31.cyan(`${ctx.appName} (${ctx.targetName})`)} from ${pc31.cyan(
10532
- local ? path43.basename(local) : key
10574
+ local ? path44.basename(local) : key
10533
10575
  )}.`
10534
10576
  );
10535
10577
  if (result?.storageCarriedOver) {
@@ -10595,21 +10637,21 @@ Take one with ${pc31.cyan("vela backup create")}, or pass the path to an archive
10595
10637
  }
10596
10638
  async function stage(ctx, file) {
10597
10639
  const dir = remotePaths.restoreStage(ctx.instance);
10598
- const remote = `${dir}/${path43.basename(file)}`;
10640
+ const remote = `${dir}/${path44.basename(file)}`;
10599
10641
  const spinner8 = p58.spinner();
10600
- spinner8.start(`Uploading ${path43.basename(file)}`);
10642
+ spinner8.start(`Uploading ${path44.basename(file)}`);
10601
10643
  try {
10602
10644
  await ctx.session.script(`mkdir -p "$1"`, { args: [dir] });
10603
10645
  await ctx.session.upload([file], dir);
10604
10646
  } catch (error) {
10605
- spinner8.stop(`Could not upload ${path43.basename(file)}.`);
10647
+ spinner8.stop(`Could not upload ${path44.basename(file)}.`);
10606
10648
  throw error;
10607
10649
  }
10608
- spinner8.stop(`Uploaded ${path43.basename(file)}`);
10650
+ spinner8.stop(`Uploaded ${path44.basename(file)}`);
10609
10651
  return remote;
10610
10652
  }
10611
10653
  async function confirm13(appName, targetName, envTag, from) {
10612
- const what = `${pc31.cyan(`${appName} (${targetName})`)} from ${pc31.cyan(path43.basename(from))}`;
10654
+ const what = `${pc31.cyan(`${appName} (${targetName})`)} from ${pc31.cyan(path44.basename(from))}`;
10613
10655
  if (isProd(envTag)) {
10614
10656
  const answer = await p58.text({
10615
10657
  message: `This replaces the database and uploads of ${what}. Type the app name to confirm`,
@@ -10720,7 +10762,7 @@ Release and domain are shown from what this project recorded.`
10720
10762
  }
10721
10763
 
10722
10764
  // src/commands/test.ts
10723
- import path44 from "node:path";
10765
+ import path45 from "node:path";
10724
10766
  import process38 from "node:process";
10725
10767
  import { Command as Command101 } from "commander";
10726
10768
  import PocketBase6 from "pocketbase";
@@ -10733,15 +10775,15 @@ var testServer = new Command101("test:server").description("run server tests").a
10733
10775
  const cwd = process38.cwd();
10734
10776
  const email3 = `test-${Math.random().toString(36).slice(2)}@example.com`;
10735
10777
  const password11 = "password";
10736
- const testDataDir = path44.join(cwd, "test-data");
10778
+ const testDataDir = path45.join(cwd, "test-data");
10737
10779
  fs42.rmSync(testDataDir, { recursive: true, force: true });
10738
10780
  const { stop, url } = await launchPocketbase(cwd, {
10739
10781
  dir: testDataDir,
10740
- migrationsDir: path44.join(cwd, MIGRATIONS_DIR),
10782
+ migrationsDir: path45.join(cwd, MIGRATIONS_DIR),
10741
10783
  // The app's PocketBase hooks (slug generation, personal teams, …) are part
10742
10784
  // of its behaviour; the suite runs against the same server dev and build
10743
10785
  // start, so it loads them from the same place.
10744
- hooksDir: path44.join(cwd, DATA_DIR, "hooks"),
10786
+ hooksDir: path45.join(cwd, DATA_DIR, "hooks"),
10745
10787
  email: email3,
10746
10788
  password: password11
10747
10789
  });
@@ -10859,7 +10901,7 @@ function stubPagesPlugin() {
10859
10901
 
10860
10902
  // src/commands/routes.ts
10861
10903
  import fs43 from "node:fs";
10862
- import path45 from "node:path";
10904
+ import path46 from "node:path";
10863
10905
  import { Command as Command102 } from "commander";
10864
10906
  var HTTP_METHODS = /* @__PURE__ */ new Set([
10865
10907
  "GET",
@@ -10873,7 +10915,7 @@ var HTTP_METHODS = /* @__PURE__ */ new Set([
10873
10915
  ]);
10874
10916
  var routes = new Command102("routes").description("list routes").configureHelp(helpConfig).action(async () => {
10875
10917
  const { workspaceRootDir, routesDir } = await getWorkspace();
10876
- const routesRoot = path45.join(workspaceRootDir, routesDir);
10918
+ const routesRoot = path46.join(workspaceRootDir, routesDir);
10877
10919
  const found = walk(routesRoot, routesRoot).filter((r) => r.methods.length > 0);
10878
10920
  found.sort((a, b) => a.urlPattern.localeCompare(b.urlPattern));
10879
10921
  printTable(found);
@@ -10883,20 +10925,20 @@ function walk(root, dir) {
10883
10925
  const routes2 = [];
10884
10926
  const hasLeaf = entries.some((e) => e.isFile() && isRouteFile(e.name));
10885
10927
  if (hasLeaf) {
10886
- const id = "/" + path45.relative(root, dir).split(path45.sep).filter(Boolean).join("/");
10928
+ const id = "/" + path46.relative(root, dir).split(path46.sep).filter(Boolean).join("/");
10887
10929
  const urlPattern = id.replace(/\([^)]+\)\/?/g, "").replace(/\/$/, "") || "/";
10888
10930
  const methods = /* @__PURE__ */ new Set();
10889
10931
  for (const entry of entries) {
10890
10932
  if (!entry.isFile()) continue;
10891
10933
  if (entry.name.endsWith("+page.svelte")) methods.add("GET");
10892
10934
  if (entry.name.endsWith("+server.ts") || entry.name.endsWith("+server.js") || entry.name.endsWith("+page.server.ts") || entry.name.endsWith("+page.server.js")) {
10893
- extractMethods(path45.join(dir, entry.name)).forEach((m) => methods.add(m));
10935
+ extractMethods(path46.join(dir, entry.name)).forEach((m) => methods.add(m));
10894
10936
  }
10895
10937
  }
10896
10938
  routes2.push({ id: id || "/", urlPattern, methods: [...methods] });
10897
10939
  }
10898
10940
  for (const entry of entries) {
10899
- if (entry.isDirectory()) routes2.push(...walk(root, path45.join(dir, entry.name)));
10941
+ if (entry.isDirectory()) routes2.push(...walk(root, path46.join(dir, entry.name)));
10900
10942
  }
10901
10943
  return routes2;
10902
10944
  }
@@ -11084,7 +11126,7 @@ import pc36 from "picocolors";
11084
11126
 
11085
11127
  // src/lib/cms-backend.ts
11086
11128
  import { createRequire as createRequire3 } from "node:module";
11087
- import path46 from "node:path";
11129
+ import path47 from "node:path";
11088
11130
  import process41 from "node:process";
11089
11131
  import { pathToFileURL as pathToFileURL3 } from "node:url";
11090
11132
  import pc35 from "picocolors";
@@ -11092,7 +11134,7 @@ var DEFAULT_PROJECT = "default";
11092
11134
  async function loadBackendModule(root) {
11093
11135
  let entry;
11094
11136
  try {
11095
- entry = createRequire3(path46.join(root, "package.json")).resolve("@velastack/cms/backend");
11137
+ entry = createRequire3(path47.join(root, "package.json")).resolve("@velastack/cms/backend");
11096
11138
  } catch {
11097
11139
  throw new Error(
11098
11140
  `@velastack/cms is not installed in this project.
@@ -11110,8 +11152,8 @@ async function withCmsBackend(fn, cwd = process41.cwd()) {
11110
11152
  const { createCmsBackend } = await loadBackendModule(root);
11111
11153
  const dataDir2 = localDataDir(root);
11112
11154
  const backend3 = createCmsBackend({
11113
- dbPath: path46.join(dataDir2, "cms.sqlite"),
11114
- uploadDir: path46.join(dataDir2, "uploads")
11155
+ dbPath: path47.join(dataDir2, "cms.sqlite"),
11156
+ uploadDir: path47.join(dataDir2, "uploads")
11115
11157
  });
11116
11158
  try {
11117
11159
  return await fn(backend3);
@@ -11372,14 +11414,14 @@ program.hook("preAction", (_thisCommand, actionCommand) => {
11372
11414
  if (isStub(actionCommand)) return;
11373
11415
  const envRoot = findWorkspaceRoot() ?? process45.cwd();
11374
11416
  dotenv2.config({ path: nodePath.join(envRoot, ".env"), quiet: true });
11375
- const path47 = getCommandPath(actionCommand);
11376
- if (NO_BACKEND_COMMMANDS.has(path47)) return;
11377
- const top = path47.split(" ", 1)[0];
11417
+ const path48 = getCommandPath(actionCommand);
11418
+ if (NO_BACKEND_COMMMANDS.has(path48)) return;
11419
+ const top = path48.split(" ", 1)[0];
11378
11420
  if (NO_BACKEND_COMMMANDS.has(top)) return;
11379
11421
  if (!hasBackend()) {
11380
11422
  if (BACKEND_OPTIONAL_COMMANDS.has(top)) return;
11381
11423
  p67.log.error(
11382
- `${pc42.cyan(`vela ${path47}`)} needs a backend, and this project does not have one.
11424
+ `${pc42.cyan(`vela ${path48}`)} needs a backend, and this project does not have one.
11383
11425
 
11384
11426
  Static projects have no database to talk to.
11385
11427
 
@@ -11389,7 +11431,7 @@ To add a backend to this project, run ${pc42.cyan("vela bless")}.`
11389
11431
  p67.cancel("Operation failed.");
11390
11432
  process45.exit(1);
11391
11433
  }
11392
- if (SELF_CREDENTIALED_COMMANDS.has(path47)) return;
11434
+ if (SELF_CREDENTIALED_COMMANDS.has(path48)) return;
11393
11435
  if (!process45.env.POCKETBASE_SUPERUSER_EMAIL || !process45.env.POCKETBASE_SUPERUSER_PASSWORD) {
11394
11436
  p67.log.error(
11395
11437
  `PocketBase superuser credentials are required.