vela 0.16.0 → 0.18.0

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
@@ -13,14 +13,14 @@ function normalizeArgv(argv) {
13
13
  // src/program.ts
14
14
  import process54 from "node:process";
15
15
  import * as p74 from "@clack/prompts";
16
- import { Command as Command118 } from "commander";
16
+ import { Command as Command120 } from "commander";
17
17
  import nodePath from "node:path";
18
18
  import dotenv2 from "dotenv";
19
19
 
20
20
  // package.json
21
21
  var package_default = {
22
22
  name: "vela",
23
- version: "0.16.0",
23
+ version: "0.18.0",
24
24
  type: "module",
25
25
  description: "A CLI for creating and updating SvelteKit projects",
26
26
  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.5.0",
60
+ "@velastack/patterns": "^0.7.0",
61
61
  "@velastack/pocketbase-codegen": "^0.1.0",
62
62
  "@velastack/schema": "^0.3.0",
63
63
  "@velastack/schema-ui": "^0.3.1",
@@ -72,7 +72,7 @@ var package_default = {
72
72
  "package-manager-detector": "^1.8.0",
73
73
  picocolors: "^1.1.1",
74
74
  pocketbase: "^0.28.0",
75
- "pocketbase-server": "^0.40.6-beta.4",
75
+ "pocketbase-server": "^0.40.6-beta.5",
76
76
  stripe: "^22.6.2",
77
77
  sv: "~1.1.1",
78
78
  svelte: "^5.56.10",
@@ -300,8 +300,8 @@ function dropTemplateAdapters(user, template) {
300
300
  }
301
301
  return copy;
302
302
  }
303
- function readPackageJson(path66) {
304
- return JSON.parse(fs2.readFileSync(path66, "utf8"));
303
+ function readPackageJson(path68) {
304
+ return JSON.parse(fs2.readFileSync(path68, "utf8"));
305
305
  }
306
306
  var PACKAGE_NAME_PLACEHOLDER = /~TODO~/g;
307
307
  var APP_NAME_PLACEHOLDER = /~APP_NAME~/g;
@@ -330,12 +330,12 @@ function jsString(value) {
330
330
  const quote2 = count("'") > count('"') ? '"' : "'";
331
331
  return `${quote2}${escapeFor(quote2, value)}${quote2}`;
332
332
  }
333
- function readTemplatePackageJson(path66, values) {
334
- const raw = fillTemplatePlaceholders(fs2.readFileSync(path66, "utf8"), values);
333
+ function readTemplatePackageJson(path68, values) {
334
+ const raw = fillTemplatePlaceholders(fs2.readFileSync(path68, "utf8"), values);
335
335
  return JSON.parse(raw);
336
336
  }
337
- function writePackageJson(path66, pkg) {
338
- fs2.writeFileSync(path66, JSON.stringify(pkg, null, " ") + "\n");
337
+ function writePackageJson(path68, pkg) {
338
+ fs2.writeFileSync(path68, JSON.stringify(pkg, null, " ") + "\n");
339
339
  }
340
340
  function toValidPackageName(name) {
341
341
  return name.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._]/, "").replace(/[^a-z0-9~.-]+/g, "-");
@@ -406,9 +406,9 @@ function minOfComparatorSet(set) {
406
406
  if (upperOnly) return { major: 0, minor: 0, patch: 0, prerelease: [] };
407
407
  return floor;
408
408
  }
409
- function parseVersionPart(text19) {
410
- if (text19 === "" || text19 === "*" || text19 === "x" || text19 === "X") return null;
411
- const match = text19.match(VERSION_PART);
409
+ function parseVersionPart(text18) {
410
+ if (text18 === "" || text18 === "*" || text18 === "x" || text18 === "X") return null;
411
+ const match = text18.match(VERSION_PART);
412
412
  if (!match) return null;
413
413
  const nums = [match[1], match[2], match[3]];
414
414
  const firstWild = nums.findIndex((n) => n === void 0 || /^[xX*]$/.test(n));
@@ -594,6 +594,8 @@ function detectFeatures(root, { isAppMode }) {
594
594
  // The code page, not src/lib/server/whatsapp.ts, which goes once the
595
595
  // PocketBase SDK has WhatsApp.
596
596
  whatsapp: has("src/routes/(public)/(auth)/whatsapp"),
597
+ // The cart store every provider's ecommerce files share a path for.
598
+ ecommerce: has("src/lib/cart.svelte.ts"),
597
599
  ui: detectUi(root)
598
600
  };
599
601
  }
@@ -899,10 +901,10 @@ function writeCachedIndex(cached2) {
899
901
  fs6.mkdirSync(cacheRoot(), { recursive: true });
900
902
  fs6.writeFileSync(indexCachePath(), JSON.stringify(cached2, null, 2));
901
903
  }
902
- function parseTemplateIndex(text19, url) {
904
+ function parseTemplateIndex(text18, url) {
903
905
  let parsed;
904
906
  try {
905
- parsed = JSON.parse(text19);
907
+ parsed = JSON.parse(text18);
906
908
  } catch (e) {
907
909
  throw new Error(`Template index at ${url} is not valid JSON: ${e.message}`);
908
910
  }
@@ -1852,8 +1854,8 @@ async function readSite(root) {
1852
1854
  if (!property || !Node6.isPropertyAssignment(property)) continue;
1853
1855
  const value = property.getInitializer();
1854
1856
  if (Node6.isStringLiteral(value) || Node6.isNoSubstitutionTemplateLiteral(value)) {
1855
- const text19 = value.getLiteralValue().trim();
1856
- if (text19) info[key] = text19;
1857
+ const text18 = value.getLiteralValue().trim();
1858
+ if (text18) info[key] = text18;
1857
1859
  }
1858
1860
  }
1859
1861
  return info;
@@ -2192,11 +2194,11 @@ function mergeOriginConfig(root, options = {}) {
2192
2194
  if (target) setOriginComment(target);
2193
2195
  }
2194
2196
  if (orphaned.length > 0) {
2195
- let text19 = vite.sourceFile.getFullText();
2197
+ let text18 = vite.sourceFile.getFullText();
2196
2198
  for (const comment of orphaned) {
2197
- text19 = text19.replace(new RegExp(String.raw`\n[\t ]*${escapeRegExp2(comment)}[\t ]*(?=\n)`), "");
2199
+ text18 = text18.replace(new RegExp(String.raw`\n[\t ]*${escapeRegExp2(comment)}[\t ]*(?=\n)`), "");
2198
2200
  }
2199
- vite.sourceFile.replaceWithText(text19);
2201
+ vite.sourceFile.replaceWithText(text18);
2200
2202
  }
2201
2203
  vite.sourceFile.saveSync();
2202
2204
  const moved = hasPathsOrigin ? "removed prerender.origin, which SvelteKit 3 no longer accepts; kept the existing paths.origin" : "moved prerender.origin to paths.origin";
@@ -2228,8 +2230,8 @@ var ORIGIN_COMMENT = [
2228
2230
  "baked in at build time. It is left unset for a deploy that serves more",
2229
2231
  "than one host, where each request's own origin is used instead."
2230
2232
  ];
2231
- function escapeRegExp2(text19) {
2232
- return text19.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2233
+ function escapeRegExp2(text18) {
2234
+ return text18.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2233
2235
  }
2234
2236
  function mentionsPrerender(node) {
2235
2237
  return node.getLeadingCommentRanges().some((c) => /prerender/i.test(c.getText()));
@@ -2526,7 +2528,7 @@ function detectJsonIndent(source) {
2526
2528
  var PRINT_WIDTH = 100;
2527
2529
  function stringifyJson(value, indent, level = 0, prefix = 0) {
2528
2530
  const pad2 = (n) => indent.repeat(n);
2529
- const width = (text19) => text19.replaceAll(" ", " ").length;
2531
+ const width = (text18) => text18.replaceAll(" ", " ").length;
2530
2532
  if (Array.isArray(value)) {
2531
2533
  if (value.length === 0) return "[]";
2532
2534
  const scalars = value.every((v14) => v14 === null || typeof v14 !== "object");
@@ -3750,6 +3752,12 @@ async function seedSite(apiKey, projectId, input) {
3750
3752
  body: JSON.stringify(input)
3751
3753
  });
3752
3754
  }
3755
+ async function createProjectForms(apiKey, projectId, forms) {
3756
+ return apiFetch(apiKey, `/v1/projects/${projectId}/forms`, {
3757
+ method: "POST",
3758
+ body: JSON.stringify({ forms })
3759
+ });
3760
+ }
3753
3761
  async function destroyEnvironment(apiKey, projectId, envTag) {
3754
3762
  return apiFetch(apiKey, `/v1/projects/${projectId}/environments/${encodeURIComponent(envTag)}`, {
3755
3763
  method: "DELETE"
@@ -4374,10 +4382,10 @@ var npmViewLookup = (name, range, cwd) => new Promise((resolve2, reject) => {
4374
4382
  (error, stdout, stderr) => {
4375
4383
  if (error && /\bE404\b/.test(`${stderr}${error.message}`)) return resolve2(null);
4376
4384
  if (error) return reject(error);
4377
- const text19 = stdout.trim();
4378
- if (!text19) return resolve2(null);
4385
+ const text18 = stdout.trim();
4386
+ if (!text18) return resolve2(null);
4379
4387
  try {
4380
- resolve2(newest(JSON.parse(text19)));
4388
+ resolve2(newest(JSON.parse(text18)));
4381
4389
  } catch (e) {
4382
4390
  reject(e);
4383
4391
  }
@@ -4834,14 +4842,14 @@ function skipString(source, start) {
4834
4842
  }
4835
4843
  return -1;
4836
4844
  }
4837
- function splitTopLevel(text19) {
4845
+ function splitTopLevel(text18) {
4838
4846
  const parts = [];
4839
4847
  let depth = 0;
4840
4848
  let partStart = 0;
4841
- for (let i = 0; i < text19.length; i++) {
4842
- const c = text19[i];
4849
+ for (let i = 0; i < text18.length; i++) {
4850
+ const c = text18[i];
4843
4851
  if (c === '"' || c === "'" || c === "`") {
4844
- const end = skipString(text19, i);
4852
+ const end = skipString(text18, i);
4845
4853
  if (end === -1) break;
4846
4854
  i = end;
4847
4855
  continue;
@@ -4849,12 +4857,12 @@ function splitTopLevel(text19) {
4849
4857
  if (c === "(" || c === "{" || c === "[") depth++;
4850
4858
  else if (c === ")" || c === "}" || c === "]") depth--;
4851
4859
  else if (c === "," && depth === 0) {
4852
- parts.push({ start: partStart, end: i, text: text19.slice(partStart, i) });
4860
+ parts.push({ start: partStart, end: i, text: text18.slice(partStart, i) });
4853
4861
  partStart = i + 1;
4854
4862
  }
4855
4863
  }
4856
- if (text19.slice(partStart).trim()) {
4857
- parts.push({ start: partStart, end: text19.length, text: text19.slice(partStart) });
4864
+ if (text18.slice(partStart).trim()) {
4865
+ parts.push({ start: partStart, end: text18.length, text: text18.slice(partStart) });
4858
4866
  }
4859
4867
  return parts;
4860
4868
  }
@@ -4971,8 +4979,8 @@ function rewriteGotoOptions(inner) {
4971
4979
  if (!joined.startsWith(lead)) joined = lead + joined.trimStart();
4972
4980
  return { inner: joined + tail, summary: summary.join("; ") };
4973
4981
  }
4974
- function escapeRegExp3(text19) {
4975
- return text19.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4982
+ function escapeRegExp3(text18) {
4983
+ return text18.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4976
4984
  }
4977
4985
  function rewriteInvalidateAll(source) {
4978
4986
  const outcome = { edits: [], changes: [], tasks: [] };
@@ -5057,9 +5065,9 @@ function addTaskComments(source, file, tasks) {
5057
5065
  const lineStart2 = code2.lastIndexOf("\n", index - 1) + 1;
5058
5066
  const lineEnd = code2.indexOf("\n", index);
5059
5067
  const excerpt = code2.slice(lineStart2, lineEnd === -1 ? void 0 : lineEnd).trim().replace(/--/g, "- -").slice(0, 80);
5060
- const text19 = `${MIGRATION_TASK_MARKER} \`${excerpt}\`: ${message}`;
5061
- if (code2.includes(text19)) continue;
5062
- code2 = `<!-- ${text19} -->
5068
+ const text18 = `${MIGRATION_TASK_MARKER} \`${excerpt}\`: ${message}`;
5069
+ if (code2.includes(text18)) continue;
5070
+ code2 = `<!-- ${text18} -->
5063
5071
  ${code2}`;
5064
5072
  added.push(`line ${line}: ${message}`);
5065
5073
  continue;
@@ -5453,8 +5461,8 @@ function svArgs(root, tasks, exclude) {
5453
5461
  }
5454
5462
  var ANSI = /\u001b\[[0-9;?]*[A-Za-z]/g;
5455
5463
  function parseSvFailure(output) {
5456
- const text19 = output.replace(ANSI, "");
5457
- const match = text19.match(/Task '([^']+)' failed: ([^\n]*)/);
5464
+ const text18 = output.replace(ANSI, "");
5465
+ const match = text18.match(/Task '([^']+)' failed: ([^\n]*)/);
5458
5466
  if (!match) return null;
5459
5467
  const message = match[2].trim();
5460
5468
  const file = message.match(/Unable to process '([^']+)'/)?.[1];
@@ -5544,9 +5552,9 @@ function originFixup(root, capture, sv) {
5544
5552
  ${outcome.snippet}`);
5545
5553
  }
5546
5554
  const lost = Boolean(carry && !outcome.applied && outcome.snippet);
5547
- for (const text19 of capture?.spreads ?? []) {
5548
- if (carry && !lost && carry.text.endsWith(text19)) continue;
5549
- sv.dropped.push({ file: capture.file, text: text19 });
5555
+ for (const text18 of capture?.spreads ?? []) {
5556
+ if (carry && !lost && carry.text.endsWith(text18)) continue;
5557
+ sv.dropped.push({ file: capture.file, text: text18 });
5550
5558
  }
5551
5559
  return f;
5552
5560
  }
@@ -5857,10 +5865,10 @@ function belowFloor(project, key, entry) {
5857
5865
  return Boolean(floor && locked && compareVersions(locked, floor) < 0);
5858
5866
  }
5859
5867
  function readJson(file) {
5860
- const text19 = fs29.readFileSync(file, "utf8");
5868
+ const text18 = fs29.readFileSync(file, "utf8");
5861
5869
  return {
5862
- data: JSON.parse(text19),
5863
- indent: text19.match(/^[{[]\s*\n([\t ]+)/)?.[1] ?? " "
5870
+ data: JSON.parse(text18),
5871
+ indent: text18.match(/^[{[]\s*\n([\t ]+)/)?.[1] ?? " "
5864
5872
  };
5865
5873
  }
5866
5874
  function writeJson(file, data, indent) {
@@ -5967,13 +5975,13 @@ function previousFollowUps(root, pattern) {
5967
5975
  const end = content.indexOf("\n## ", start + FOLLOW_UPS_HEADING.length);
5968
5976
  return content.slice(start, end === -1 ? void 0 : end).split("\n").filter((line) => line.startsWith("- [") && pattern.test(line)).map((line) => line.replace(/^- \[[ x]\] /, ""));
5969
5977
  }
5970
- function code(text19) {
5971
- const fence = text19.includes("`") ? "``" : "`";
5972
- const pad2 = text19.startsWith("`") || text19.endsWith("`") ? " " : "";
5973
- return `${fence}${pad2}${text19}${pad2}${fence}`;
5978
+ function code(text18) {
5979
+ const fence = text18.includes("`") ? "``" : "`";
5980
+ const pad2 = text18.startsWith("`") || text18.endsWith("`") ? " " : "";
5981
+ return `${fence}${pad2}${text18}${pad2}${fence}`;
5974
5982
  }
5975
- function escape(text19) {
5976
- return text19.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5983
+ function escape(text18) {
5984
+ return text18.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5977
5985
  }
5978
5986
  function writeFollowUps(root, items, generic) {
5979
5987
  const file = path28.join(root, MIGRATION_TASKS_FILE);
@@ -6115,8 +6123,8 @@ function findRepeaterImport(dir) {
6115
6123
  for (const entry of entries) {
6116
6124
  if (!entry.isFile() || !SOURCE_FILE.test(entry.name)) continue;
6117
6125
  const file = path29.join(entry.parentPath, entry.name);
6118
- const text19 = fs30.readFileSync(file, "utf8");
6119
- if (text19.includes("CmsRepeater") && REPEATER_IMPORT.test(text19)) {
6126
+ const text18 = fs30.readFileSync(file, "utf8");
6127
+ if (text18.includes("CmsRepeater") && REPEATER_IMPORT.test(text18)) {
6120
6128
  return path29.relative(dir, file);
6121
6129
  }
6122
6130
  }
@@ -6506,7 +6514,7 @@ function hasScript(directory, name) {
6506
6514
  }
6507
6515
 
6508
6516
  // src/commands/generate.ts
6509
- import { Command as Command10 } from "commander";
6517
+ import { Command as Command11 } from "commander";
6510
6518
 
6511
6519
  // src/commands/generate/form.ts
6512
6520
  import { Command as Command4 } from "commander";
@@ -6533,6 +6541,7 @@ Then run this again.`
6533
6541
 
6534
6542
  // src/lib/require-features.ts
6535
6543
  import {
6544
+ blockingFeatures,
6536
6545
  bySlug as bySlug2,
6537
6546
  unmetRequirements
6538
6547
  } from "@velastack/patterns";
@@ -6547,7 +6556,21 @@ var ENABLE_COMMAND = {
6547
6556
  blog: "vela enable blog",
6548
6557
  contentNegotiation: "vela enable content-negotiation",
6549
6558
  cms: "vela enable cms",
6550
- workflows: "vela enable workflows"
6559
+ workflows: "vela enable workflows",
6560
+ ecommerce: "vela enable ecommerce"
6561
+ };
6562
+ var DISABLE_COMMAND = {
6563
+ auth: "vela disable auth",
6564
+ api: "vela disable api",
6565
+ apiKeys: "vela disable api-keys",
6566
+ backend: "vela disable backend",
6567
+ i18n: "vela disable i18n",
6568
+ teams: "vela disable teams",
6569
+ payments: "vela disable payments",
6570
+ blog: "vela disable blog",
6571
+ contentNegotiation: "vela disable content-negotiation",
6572
+ cms: "vela disable cms",
6573
+ ecommerce: "vela disable ecommerce"
6551
6574
  };
6552
6575
  var FEATURE_NAME = {
6553
6576
  apiKeys: "API keys",
@@ -6602,9 +6625,23 @@ function unmetMessage(command, unmet) {
6602
6625
  ...notes.length > 0 ? ["", ...notes] : []
6603
6626
  ].join("\n");
6604
6627
  }
6628
+ function blockedMessage(command, blocking) {
6629
+ const names = blocking.map((feature) => FEATURE_NAME[feature] ?? feature);
6630
+ const steps = blocking.flatMap((feature) => DISABLE_COMMAND[feature] ?? []);
6631
+ const they = blocking.length > 1 ? "they depend" : "it depends";
6632
+ return [
6633
+ `\`${command}\` can't run while this project has ${names.join(", ")}: ${they} on what it removes.`,
6634
+ "",
6635
+ "Nothing was changed. To take it out first:",
6636
+ ...steps.map((step, i) => ` ${i + 1}. ${step}`),
6637
+ "Then run this again."
6638
+ ].join("\n");
6639
+ }
6605
6640
  function assertRequires(command, pattern, context) {
6606
6641
  const unmet = unmetRequirements(pattern, context);
6607
6642
  if (unmet.length > 0) throw new Error(unmetMessage(command, unmet));
6643
+ const blocking = blockingFeatures(pattern, context.features);
6644
+ if (blocking.length > 0) throw new Error(blockedMessage(command, blocking));
6608
6645
  }
6609
6646
  async function assertPatternRequires(slug2, provider) {
6610
6647
  const pattern = bySlug2[slug2];
@@ -7290,15 +7327,55 @@ var workflow = new Command9("workflow").description("generate a background workf
7290
7327
  )
7291
7328
  );
7292
7329
 
7330
+ // src/commands/generate/shop.ts
7331
+ import { Command as Command10 } from "commander";
7332
+ var shop = new Command10("shop").description("generate a product listing and product pages for the project's cart").option("--provider <provider>", "must match the payments provider: stripe, shopify or whatsapp").allowExcessArguments(true).configureHelp(helpConfig).action(
7333
+ (opts, cmd) => runCommand(async () => {
7334
+ const { detected } = await detectWorkspace();
7335
+ const provider = await resolveProvider("generate-shop", opts.provider, detected.providers);
7336
+ await assertPatternRequires("generate-shop", provider.id);
7337
+ if (provider.id === "stripe") assertBackendReady("vela generate shop");
7338
+ await runPattern(
7339
+ "generate-shop",
7340
+ cmd.args,
7341
+ { provider: provider.id },
7342
+ {
7343
+ summary: `Generated a ${provider.label} shop.`,
7344
+ nextSteps: [
7345
+ "Run `vela dev` and visit /shop.",
7346
+ ...NEXT_STEPS[provider.id],
7347
+ "The pages are yours to edit; `vela destroy shop` removes them."
7348
+ ],
7349
+ task: {
7350
+ title: "Generating the shop",
7351
+ success: "Generated the shop",
7352
+ error: "Failed to generate the shop"
7353
+ }
7354
+ }
7355
+ );
7356
+ }, "Failed to generate the shop.")
7357
+ );
7358
+ var NEXT_STEPS = {
7359
+ stripe: [
7360
+ "Products and prices come from your Stripe dashboard; the catalog syncs every ten minutes. Set `metadata.slug` on a product for a readable URL."
7361
+ ],
7362
+ shopify: [
7363
+ "Products live in Shopify admin; publish them to the Headless channel the Storefront token belongs to."
7364
+ ],
7365
+ whatsapp: [
7366
+ "Edit the products in src/lib/catalog.ts; prices are in `site.currency` (src/lib/site.ts). With the CMS, open /shop with `?edit` instead."
7367
+ ]
7368
+ };
7369
+
7293
7370
  // src/commands/generate.ts
7294
- var generate = new Command10("generate").description("generate scaffolding for database models and forms").configureHelp(helpConfig).addCommand(form).addCommand(schema).addCommand(resource).addCommand(scaffold).addCommand(migration).addCommand(workflow);
7371
+ var generate = new Command11("generate").description("generate scaffolding for database models and forms").configureHelp(helpConfig).addCommand(form).addCommand(schema).addCommand(resource).addCommand(scaffold).addCommand(shop).addCommand(migration).addCommand(workflow);
7295
7372
 
7296
7373
  // src/commands/enable.ts
7297
- import { Command as Command28 } from "commander";
7374
+ import { Command as Command29 } from "commander";
7298
7375
 
7299
7376
  // src/commands/enable/ai.ts
7300
- import { Command as Command11 } from "commander";
7301
- var ai = new Command11("ai").description("enable AI chat with the Vercel AI SDK (Vercel AI Gateway, OpenAI or Anthropic)").option("--provider <provider>", "AI provider: gateway, openai or anthropic").allowExcessArguments(true).configureHelp(helpConfig).action(
7377
+ import { Command as Command12 } from "commander";
7378
+ var ai = new Command12("ai").description("enable AI chat with the Vercel AI SDK (Vercel AI Gateway, OpenAI or Anthropic)").option("--provider <provider>", "AI provider: gateway, openai or anthropic").allowExcessArguments(true).configureHelp(helpConfig).action(
7302
7379
  (opts, cmd) => runCommand(async () => {
7303
7380
  const provider = await resolveProvider("enable-ai", opts.provider);
7304
7381
  const providerEnv = await collectProviderEnv(provider);
@@ -7330,8 +7407,8 @@ var ai = new Command11("ai").description("enable AI chat with the Vercel AI SDK
7330
7407
  );
7331
7408
 
7332
7409
  // src/commands/enable/analytics.ts
7333
- import { Command as Command12 } from "commander";
7334
- var analytics = new Command12("analytics").description("enable web analytics (Plausible, Google Analytics or PostHog)").option("--provider <provider>", "analytics provider: plausible, google or posthog").allowExcessArguments(true).configureHelp(helpConfig).action(
7410
+ import { Command as Command13 } from "commander";
7411
+ var analytics = new Command13("analytics").description("enable web analytics (Plausible, Google Analytics or PostHog)").option("--provider <provider>", "analytics provider: plausible, google or posthog").allowExcessArguments(true).configureHelp(helpConfig).action(
7335
7412
  (opts, cmd) => runCommand(async () => {
7336
7413
  const provider = await resolveProvider("enable-analytics", opts.provider);
7337
7414
  const providerEnv = await collectProviderEnv(provider);
@@ -7361,8 +7438,8 @@ var analytics = new Command12("analytics").description("enable web analytics (Pl
7361
7438
  );
7362
7439
 
7363
7440
  // src/commands/enable/auth.ts
7364
- import { Command as Command13 } from "commander";
7365
- var auth = new Command13("auth").description("enable authentication (email/password + OAuth scaffold)").option(
7441
+ import { Command as Command14 } from "commander";
7442
+ var auth = new Command14("auth").description("enable authentication (email/password + OAuth scaffold)").option(
7366
7443
  "--remote",
7367
7444
  "generate the auth forms with SvelteKit remote functions instead of form actions and superforms"
7368
7445
  ).allowExcessArguments(true).configureHelp(helpConfig).action(
@@ -7394,8 +7471,8 @@ var auth = new Command13("auth").description("enable authentication (email/passw
7394
7471
  );
7395
7472
 
7396
7473
  // src/commands/enable/api.ts
7397
- import { Command as Command14 } from "commander";
7398
- var api = new Command14("api").description("enable the PocketBase REST API").allowExcessArguments(true).configureHelp(helpConfig).action(
7474
+ import { Command as Command15 } from "commander";
7475
+ var api = new Command15("api").description("enable the PocketBase REST API").allowExcessArguments(true).configureHelp(helpConfig).action(
7399
7476
  (_opts, cmd) => runCommand(
7400
7477
  () => runPattern(
7401
7478
  "enable-api",
@@ -7420,8 +7497,8 @@ var api = new Command14("api").description("enable the PocketBase REST API").all
7420
7497
  );
7421
7498
 
7422
7499
  // src/commands/enable/api-keys.ts
7423
- import { Command as Command15 } from "commander";
7424
- var apiKeys = new Command15("api-keys").description("enable API key management").allowExcessArguments(true).configureHelp(helpConfig).action(
7500
+ import { Command as Command16 } from "commander";
7501
+ var apiKeys = new Command16("api-keys").description("enable API key management").allowExcessArguments(true).configureHelp(helpConfig).action(
7425
7502
  (_opts, cmd) => runCommand(
7426
7503
  () => runPattern(
7427
7504
  "enable-api-keys",
@@ -7448,14 +7525,14 @@ var apiKeys = new Command15("api-keys").description("enable API key management")
7448
7525
  // src/commands/enable/backend.ts
7449
7526
  import process18 from "node:process";
7450
7527
  import * as v6 from "valibot";
7451
- import { Command as Command16 } from "commander";
7528
+ import { Command as Command17 } from "commander";
7452
7529
  import * as p20 from "@clack/prompts";
7453
7530
  import pc7 from "picocolors";
7454
7531
  var optionsSchema3 = v6.strictObject({
7455
7532
  email: emailFlag,
7456
7533
  password: passwordFlag
7457
7534
  });
7458
- var backend = new Command16("backend").description("enable the PocketBase backend").option("--email <email>", "email of the admin user").option("--password <password>", "password of the admin user").allowExcessArguments(true).configureHelp(helpConfig).action(
7535
+ var backend = new Command17("backend").description("enable the PocketBase backend").option("--email <email>", "email of the admin user").option("--password <password>", "password of the admin user").allowExcessArguments(true).configureHelp(helpConfig).action(
7459
7536
  (rawOpts, cmd) => runCommand(async () => {
7460
7537
  const options = parseOptions(optionsSchema3, rawOpts);
7461
7538
  const { workspaceRootDir, features } = await getWorkspace();
@@ -7526,8 +7603,8 @@ async function resolveCredentials(options) {
7526
7603
  }
7527
7604
 
7528
7605
  // src/commands/enable/i18n.ts
7529
- import { Command as Command17 } from "commander";
7530
- var i18n = new Command17("i18n").description("enable internationalization").allowExcessArguments(true).configureHelp(helpConfig).action(
7606
+ import { Command as Command18 } from "commander";
7607
+ var i18n = new Command18("i18n").description("enable internationalization").allowExcessArguments(true).configureHelp(helpConfig).action(
7531
7608
  (_opts, cmd) => runCommand(
7532
7609
  () => runPattern(
7533
7610
  "enable-i18n",
@@ -7552,8 +7629,8 @@ var i18n = new Command17("i18n").description("enable internationalization").allo
7552
7629
  );
7553
7630
 
7554
7631
  // src/commands/enable/teams.ts
7555
- import { Command as Command18 } from "commander";
7556
- var teams = new Command18("teams").description("enable team / multi-tenant support").allowExcessArguments(true).configureHelp(helpConfig).action(
7632
+ import { Command as Command19 } from "commander";
7633
+ var teams = new Command19("teams").description("enable team / multi-tenant support").allowExcessArguments(true).configureHelp(helpConfig).action(
7557
7634
  (_opts, cmd) => runCommand(
7558
7635
  () => runPattern(
7559
7636
  "enable-teams",
@@ -7578,27 +7655,95 @@ var teams = new Command18("teams").description("enable team / multi-tenant suppo
7578
7655
  );
7579
7656
 
7580
7657
  // src/commands/enable/payments.ts
7658
+ import fs35 from "node:fs";
7659
+ import path35 from "node:path";
7581
7660
  import process19 from "node:process";
7582
- import { Command as Command19 } from "commander";
7661
+ import { Command as Command20 } from "commander";
7583
7662
  import * as p21 from "@clack/prompts";
7584
- var payments = new Command19("payments").description("enable payments (Stripe or Shopify)").option("--provider <provider>", "payment provider: stripe or shopify").allowExcessArguments(true).configureHelp(helpConfig).action(
7663
+
7664
+ // src/lib/order-form.ts
7665
+ import fs34 from "node:fs";
7666
+ import path34 from "node:path";
7667
+ var ORDER_FORM_KEY = "order";
7668
+ var ORDER_FORM_NAME = "Orders";
7669
+ var HOSTED_CMS = /^(https?:\/\/[^/]+)\/v1\/projects\/([^/?#]+)\/cms\/?$/;
7670
+ function hostedCmsProject(root) {
7671
+ let source;
7672
+ try {
7673
+ source = fs34.readFileSync(path34.join(root, "src", "lib", "cms.ts"), "utf8");
7674
+ } catch {
7675
+ return null;
7676
+ }
7677
+ const endpoint = /\bendpoint:\s*['"]([^'"]+)['"]/.exec(source)?.[1];
7678
+ const match = endpoint ? HOSTED_CMS.exec(endpoint) : null;
7679
+ return match ? { origin: match[1], projectId: match[2] } : null;
7680
+ }
7681
+ function orderFormUrl(origin, projectId) {
7682
+ return `${origin}/v1/projects/${projectId}/forms/${ORDER_FORM_KEY}`;
7683
+ }
7684
+ async function ensureOrderForm(root, deps = { readApiKey, createForms: createProjectForms }) {
7685
+ const linked = readProjectConfig(root);
7686
+ const project = linked ? { origin: API_URL, projectId: linked.projectId } : hostedCmsProject(root);
7687
+ if (!project) {
7688
+ return {
7689
+ kind: "skipped",
7690
+ note: "Orders are not recorded until PUBLIC_WHATSAPP_ORDER_FORM is set: link the project to velastack.dev (`vela link`), then run `vela enable payments --provider whatsapp` again."
7691
+ };
7692
+ }
7693
+ const apiKey = deps.readApiKey();
7694
+ if (!apiKey) {
7695
+ return {
7696
+ kind: "skipped",
7697
+ note: "Orders are not recorded until PUBLIC_WHATSAPP_ORDER_FORM is set: run `vela login`, then `vela enable payments --provider whatsapp` again."
7698
+ };
7699
+ }
7700
+ let origins;
7701
+ try {
7702
+ ({ origins = [] } = await deps.createForms(apiKey, project.projectId, [
7703
+ { key: ORDER_FORM_KEY, name: ORDER_FORM_NAME }
7704
+ ]));
7705
+ } catch (error) {
7706
+ const reason = error instanceof ApiError ? `velastack.dev answered ${error.status}` : String(error);
7707
+ return {
7708
+ kind: "skipped",
7709
+ note: `Could not create the hosted order form (${reason}). Add a form keyed "${ORDER_FORM_KEY}" to the project on velastack.dev, then set PUBLIC_WHATSAPP_ORDER_FORM=${orderFormUrl(project.origin, project.projectId)}.`
7710
+ };
7711
+ }
7712
+ const url = orderFormUrl(project.origin, project.projectId);
7713
+ return origins.length > 0 ? {
7714
+ kind: "created",
7715
+ url,
7716
+ note: `The project's forms accept posts only from ${origins.join(", ")} (and localhost). If the site is served from another domain, add it on velastack.dev, or its orders are refused.`
7717
+ } : { kind: "created", url };
7718
+ }
7719
+
7720
+ // src/commands/enable/payments.ts
7721
+ var payments = new Command20("payments").description("enable payments (Stripe, Shopify or WhatsApp)").option("--provider <provider>", "payment provider: stripe, shopify or whatsapp").option(
7722
+ "--currency <code>",
7723
+ "WhatsApp: the business's currency, an ISO 4217 code such as MXN (kept in src/lib/site.ts)"
7724
+ ).allowExcessArguments(true).configureHelp(helpConfig).action(
7585
7725
  (opts, cmd) => runCommand(async () => {
7586
7726
  const provider = await resolveProvider("enable-payments", opts.provider);
7587
7727
  await assertPatternRequires("enable-payments", provider.id);
7588
7728
  if (provider.id === "stripe") assertBackendReady("vela enable payments");
7589
7729
  if (provider.id === "stripe") noteWebhookSecret();
7730
+ const currency = provider.id === "whatsapp" ? await askCurrency(opts.currency) : void 0;
7731
+ const orderForm = provider.id === "whatsapp" ? await prepareOrderForm() : [];
7590
7732
  const providerEnv = await collectProviderEnv(provider);
7591
- const demoId = await askDemoId(provider);
7592
- const blank = missingEnvKeys(provider, providerEnv);
7733
+ const demoId = provider.id === "whatsapp" ? "" : await askDemoId(provider);
7734
+ const blank = missingEnvKeys(provider, providerEnv).filter(
7735
+ (key) => !(key === "PUBLIC_WHATSAPP_ORDER_FORM" && orderForm.length > 0)
7736
+ );
7593
7737
  await runPattern(
7594
7738
  "enable-payments",
7595
7739
  cmd.args,
7596
- { provider: provider.id, providerEnv, demoId },
7740
+ { provider: provider.id, providerEnv, demoId, currency },
7597
7741
  {
7598
7742
  summary: `Enabled ${provider.label} payments.`,
7599
7743
  nextSteps: [
7600
7744
  ...blank.map((key) => `Set ${key} in .env.`),
7601
- ...NEXT_STEPS[provider.id],
7745
+ ...orderForm,
7746
+ ...NEXT_STEPS2[provider.id],
7602
7747
  "Set the same variables on each deploy target with `vela env set`."
7603
7748
  ],
7604
7749
  task: {
@@ -7610,7 +7755,7 @@ var payments = new Command19("payments").description("enable payments (Stripe or
7610
7755
  );
7611
7756
  }, "Failed to enable payments.")
7612
7757
  );
7613
- var NEXT_STEPS = {
7758
+ var NEXT_STEPS2 = {
7614
7759
  stripe: [
7615
7760
  "Forward Stripe webhooks locally with `stripe listen --forward-to localhost:5173/webhooks/stripe`.",
7616
7761
  "Run `vela dev` and visit /payment to run through the checkout flow.",
@@ -7619,8 +7764,46 @@ var NEXT_STEPS = {
7619
7764
  shopify: [
7620
7765
  "Run `vela dev` and visit /payment to try the Buy button (it is there when you gave a variant).",
7621
7766
  "Products, prices and checkout settings live in Shopify admin."
7767
+ ],
7768
+ whatsapp: [
7769
+ 'Put `<OrderButton name="..." price={...} />` (src/lib/components/payments/order-button.svelte) on the pages that sell things; prices are in `site.currency` (src/lib/site.ts).',
7770
+ "Edit the message the business receives in src/lib/order.ts.",
7771
+ "Orders recorded to the hosted form are on velastack.dev, under the project's forms."
7622
7772
  ]
7623
7773
  };
7774
+ function isCurrency(code2) {
7775
+ return Intl.supportedValuesOf("currency").includes(code2.trim().toUpperCase());
7776
+ }
7777
+ async function askCurrency(flag) {
7778
+ if (flag) return flag.trim().toUpperCase();
7779
+ const root = findWorkspaceRoot();
7780
+ const site = root ? path35.join(root, "src", "lib", "site.ts") : null;
7781
+ if (site && fs35.existsSync(site) && /^\s*currency\s*:/m.test(fs35.readFileSync(site, "utf8"))) {
7782
+ return void 0;
7783
+ }
7784
+ if (!isInteractive()) return void 0;
7785
+ const value = await p21.text({
7786
+ message: "The business's currency, which every price is in (ISO 4217)",
7787
+ placeholder: "MXN, EUR, USD...",
7788
+ validate: (value2) => value2 && isCurrency(value2) ? void 0 : "An ISO 4217 code, such as MXN or EUR"
7789
+ });
7790
+ if (p21.isCancel(value)) {
7791
+ p21.cancel("Operation cancelled.");
7792
+ process19.exit(0);
7793
+ }
7794
+ return value.trim().toUpperCase();
7795
+ }
7796
+ async function prepareOrderForm() {
7797
+ if (process19.env.PUBLIC_WHATSAPP_ORDER_FORM) return [];
7798
+ const root = findWorkspaceRoot();
7799
+ if (!root) return [];
7800
+ const outcome = await ensureOrderForm(root);
7801
+ if (outcome.kind === "created") {
7802
+ process19.env.PUBLIC_WHATSAPP_ORDER_FORM = outcome.url;
7803
+ return outcome.note ? [outcome.note] : [];
7804
+ }
7805
+ return [outcome.note];
7806
+ }
7624
7807
  function noteWebhookSecret() {
7625
7808
  if (process19.env.STRIPE_WEBHOOK_SECRET || !isInteractive()) return;
7626
7809
  p21.note(
@@ -7650,25 +7833,29 @@ async function askDemoId(provider) {
7650
7833
  }
7651
7834
 
7652
7835
  // src/commands/enable/ecommerce.ts
7653
- import process20 from "node:process";
7654
- import { Command as Command20 } from "commander";
7655
- import * as p22 from "@clack/prompts";
7656
- var ecommerce = new Command20("ecommerce").description("enable a cart and checkout on the project's payments provider").option("--provider <provider>", "must match the payments provider: stripe or shopify").allowExcessArguments(true).configureHelp(helpConfig).action(
7836
+ import { Command as Command21 } from "commander";
7837
+ var ecommerce = new Command21("ecommerce").description("enable a cart and checkout on the project's payments provider").option("--provider <provider>", "must match the payments provider: stripe, shopify or whatsapp").allowExcessArguments(true).configureHelp(helpConfig).action(
7657
7838
  (opts, cmd) => runCommand(async () => {
7658
- const { detected } = await detectWorkspace();
7839
+ const { detected, features } = await detectWorkspace();
7840
+ if (features.ecommerce) {
7841
+ throw new Error(
7842
+ [
7843
+ "This project already has a cart (src/lib/cart.svelte.ts). Nothing was changed.",
7844
+ "To start over, run `vela disable ecommerce` first, then this again."
7845
+ ].join("\n")
7846
+ );
7847
+ }
7659
7848
  const provider = await resolveProvider("enable-ecommerce", opts.provider, detected.providers);
7660
7849
  await assertPatternRequires("enable-ecommerce", provider.id);
7661
- const demoId = await askDemoId2(provider);
7662
7850
  await runPattern(
7663
7851
  "enable-ecommerce",
7664
7852
  cmd.args,
7665
- { provider: provider.id, demoId },
7853
+ { provider: provider.id },
7666
7854
  {
7667
7855
  summary: `Enabled a ${provider.label} cart.`,
7668
7856
  nextSteps: [
7669
- ...demoId ? ["Run `vela dev` and visit /shop to add the demo item to the cart."] : [],
7670
- "Put `<AddToCart>` (src/lib/components/cart/add-to-cart.svelte) on the pages that sell things.",
7671
- ...NEXT_STEPS2[provider.id]
7857
+ "Run `vela generate shop` for a product listing and product pages, or put `<AddToCart>` (src/lib/components/cart/add-to-cart.svelte) on your own pages.",
7858
+ ...NEXT_STEPS3[provider.id]
7672
7859
  ],
7673
7860
  task: {
7674
7861
  title: "Enabling ecommerce",
@@ -7679,28 +7866,20 @@ var ecommerce = new Command20("ecommerce").description("enable a cart and checko
7679
7866
  );
7680
7867
  }, "Failed to enable ecommerce.")
7681
7868
  );
7682
- var NEXT_STEPS2 = {
7869
+ var NEXT_STEPS3 = {
7683
7870
  stripe: [
7684
7871
  "Checkout is Stripe Checkout: payment methods, tax and shipping are set in the Stripe dashboard."
7685
7872
  ],
7686
- shopify: ["Checkout is Shopify's: payment, tax and shipping settings live in Shopify admin."]
7873
+ shopify: ["Checkout is Shopify's: payment, tax and shipping settings live in Shopify admin."],
7874
+ whatsapp: [
7875
+ 'Give each item an id, a name and, optionally, a price in `site.currency`: `<AddToCart id="concha" name="Concha" price={12} />`.',
7876
+ "Checkout opens WhatsApp with the order; the business confirms it and takes payment in the chat."
7877
+ ]
7687
7878
  };
7688
- async function askDemoId2(provider) {
7689
- if (!isInteractive()) return "";
7690
- const value = await p22.text({
7691
- message: provider.id === "stripe" ? "Stripe price_id for a demo /shop page (price_...)" : "Shopify product variant for a demo /shop page (gid://shopify/ProductVariant/...)",
7692
- placeholder: "leave blank to skip the demo page"
7693
- });
7694
- if (p22.isCancel(value)) {
7695
- p22.cancel("Operation cancelled.");
7696
- process20.exit(0);
7697
- }
7698
- return (value ?? "").trim();
7699
- }
7700
7879
 
7701
7880
  // src/commands/enable/subscriptions.ts
7702
- import { Command as Command21 } from "commander";
7703
- var subscriptions = new Command21("subscriptions").description("enable Stripe subscriptions (requires auth and Stripe payments)").allowExcessArguments(true).configureHelp(helpConfig).action(
7881
+ import { Command as Command22 } from "commander";
7882
+ var subscriptions = new Command22("subscriptions").description("enable Stripe subscriptions (requires auth and Stripe payments)").allowExcessArguments(true).configureHelp(helpConfig).action(
7704
7883
  (_opts, cmd) => runCommand(
7705
7884
  () => runPattern(
7706
7885
  "enable-subscriptions",
@@ -7725,8 +7904,8 @@ var subscriptions = new Command21("subscriptions").description("enable Stripe su
7725
7904
  );
7726
7905
 
7727
7906
  // src/commands/enable/notifications.ts
7728
- import { Command as Command22 } from "commander";
7729
- var notifications = new Command22("notifications").description("enable in-app notifications with a bell dropdown (requires auth)").allowExcessArguments(true).configureHelp(helpConfig).action(
7907
+ import { Command as Command23 } from "commander";
7908
+ var notifications = new Command23("notifications").description("enable in-app notifications with a bell dropdown (requires auth)").allowExcessArguments(true).configureHelp(helpConfig).action(
7730
7909
  (_opts, cmd) => runCommand(
7731
7910
  () => runPattern(
7732
7911
  "enable-notifications",
@@ -7751,9 +7930,9 @@ var notifications = new Command22("notifications").description("enable in-app no
7751
7930
  );
7752
7931
 
7753
7932
  // src/commands/enable/cms.ts
7754
- import process21 from "node:process";
7755
- import { Command as Command23 } from "commander";
7756
- import * as p23 from "@clack/prompts";
7933
+ import process20 from "node:process";
7934
+ import { Command as Command24 } from "commander";
7935
+ import * as p22 from "@clack/prompts";
7757
7936
  import pc8 from "picocolors";
7758
7937
  function resolveCmsBackend(facts) {
7759
7938
  if (facts.endpoint) return { kind: "hosted", endpoint: facts.endpoint, from: "flag" };
@@ -7770,12 +7949,12 @@ function adapterOf(root) {
7770
7949
  return "none";
7771
7950
  }
7772
7951
  }
7773
- var cms = new Command23("cms").description("enable an inline-editing CMS with an admin bar").option(
7952
+ var cms = new Command24("cms").description("enable an inline-editing CMS with an admin bar").option(
7774
7953
  "--endpoint <url>",
7775
7954
  "read from a hosted CMS at this URL instead of installing the backend in this app"
7776
7955
  ).allowExcessArguments(true).configureHelp(helpConfig).action(
7777
7956
  (opts, cmd) => runCommand(async () => {
7778
- const root = findWorkspaceRoot() ?? process21.cwd();
7957
+ const root = findWorkspaceRoot() ?? process20.cwd();
7779
7958
  assertKit3(root, "vela enable cms");
7780
7959
  const backend3 = resolveCmsBackend({
7781
7960
  endpoint: opts.endpoint,
@@ -7784,7 +7963,7 @@ var cms = new Command23("cms").description("enable an inline-editing CMS with an
7784
7963
  projectId: readProjectConfig(root)?.projectId
7785
7964
  });
7786
7965
  if (backend3.kind === "none") {
7787
- p23.log.error(
7966
+ p22.log.error(
7788
7967
  `${pc8.cyan("vela enable cms")} needs somewhere to run the CMS backend, and this project has no Node server.
7789
7968
 
7790
7969
  Any one of these gives it one:
@@ -7792,14 +7971,14 @@ Any one of these gives it one:
7792
7971
  - ${pc8.cyan("vela enable cms --endpoint <url>")} to point at a hosted CMS yourself.
7793
7972
  - ${pc8.cyan("vela enable backend")}, or switching to @sveltejs/adapter-node, to host it in this app.`
7794
7973
  );
7795
- p23.log.message();
7796
- p23.cancel("Operation failed.");
7797
- process21.exitCode = 1;
7974
+ p22.log.message();
7975
+ p22.cancel("Operation failed.");
7976
+ process20.exitCode = 1;
7798
7977
  return;
7799
7978
  }
7800
7979
  const hosted = backend3.kind === "hosted";
7801
7980
  if (hosted && backend3.from === "link") {
7802
- p23.log.info(`Using the hosted CMS of the linked project (${pc8.cyan(backend3.endpoint)}).`);
7981
+ p22.log.info(`Using the hosted CMS of the linked project (${pc8.cyan(backend3.endpoint)}).`);
7803
7982
  }
7804
7983
  const input = hosted ? { endpoint: backend3.endpoint } : { server: true };
7805
7984
  await runPattern("enable-cms", cmd.args, input, {
@@ -7819,8 +7998,8 @@ Any one of these gives it one:
7819
7998
  );
7820
7999
 
7821
8000
  // src/commands/enable/blog.ts
7822
- import { Command as Command24 } from "commander";
7823
- var blog = new Command24("blog").description("enable an mdsvex blog with posts, tags, and RSS").allowExcessArguments(true).configureHelp(helpConfig).action(
8001
+ import { Command as Command25 } from "commander";
8002
+ var blog = new Command25("blog").description("enable an mdsvex blog with posts, tags, and RSS").allowExcessArguments(true).configureHelp(helpConfig).action(
7824
8003
  (_opts, cmd) => runCommand(
7825
8004
  () => runPattern(
7826
8005
  "enable-blog",
@@ -7845,16 +8024,16 @@ var blog = new Command24("blog").description("enable an mdsvex blog with posts,
7845
8024
  );
7846
8025
 
7847
8026
  // src/commands/enable/content-negotiation.ts
7848
- import process22 from "node:process";
7849
- import { Command as Command25 } from "commander";
7850
- var contentNegotiation = new Command25("content-negotiation").description("enable content negotiation (sveltekit-negotiate)").allowExcessArguments(true).configureHelp(helpConfig).action(
8027
+ import process21 from "node:process";
8028
+ import { Command as Command26 } from "commander";
8029
+ var contentNegotiation = new Command26("content-negotiation").description("enable content negotiation (sveltekit-negotiate)").allowExcessArguments(true).configureHelp(helpConfig).action(
7851
8030
  (_opts, cmd) => runCommand(
7852
8031
  () => runPattern(
7853
8032
  "enable-content-negotiation",
7854
8033
  cmd.args,
7855
8034
  // The demo page's loader imports `svelte-meta-tags`, which vela's
7856
8035
  // templates carry and a project vela did not create may not.
7857
- { metaTags: hasDependency(findWorkspaceRoot() ?? process22.cwd(), "svelte-meta-tags") },
8036
+ { metaTags: hasDependency(findWorkspaceRoot() ?? process21.cwd(), "svelte-meta-tags") },
7858
8037
  {
7859
8038
  summary: "Enabled content negotiation.",
7860
8039
  nextSteps: [
@@ -7873,8 +8052,8 @@ var contentNegotiation = new Command25("content-negotiation").description("enabl
7873
8052
  );
7874
8053
 
7875
8054
  // src/commands/enable/workflows.ts
7876
- import { Command as Command26 } from "commander";
7877
- var workflows = new Command26("workflows").description("add background workflows to a project created before they were built in").allowExcessArguments(true).configureHelp(helpConfig).action(
8055
+ import { Command as Command27 } from "commander";
8056
+ var workflows = new Command27("workflows").description("add background workflows to a project created before they were built in").allowExcessArguments(true).configureHelp(helpConfig).action(
7878
8057
  (_opts, cmd) => runCommand(
7879
8058
  () => runPattern(
7880
8059
  "enable-workflows",
@@ -7899,8 +8078,8 @@ var workflows = new Command26("workflows").description("add background workflows
7899
8078
  );
7900
8079
 
7901
8080
  // src/commands/enable/whatsapp.ts
7902
- import { Command as Command27 } from "commander";
7903
- var whatsapp = new Command27("whatsapp").description("enable WhatsApp sign-in on the login and signup pages (requires auth)").allowExcessArguments(true).configureHelp(helpConfig).action(
8081
+ import { Command as Command28 } from "commander";
8082
+ var whatsapp = new Command28("whatsapp").description("enable WhatsApp sign-in on the login and signup pages (requires auth)").allowExcessArguments(true).configureHelp(helpConfig).action(
7904
8083
  (_opts, cmd) => runCommand(
7905
8084
  () => runPattern(
7906
8085
  "enable-whatsapp",
@@ -7925,33 +8104,33 @@ var whatsapp = new Command27("whatsapp").description("enable WhatsApp sign-in on
7925
8104
  );
7926
8105
 
7927
8106
  // src/commands/enable.ts
7928
- var enable = new Command28("enable").description("enable features").configureHelp(helpConfig).addCommand(ai).addCommand(analytics).addCommand(auth).addCommand(api).addCommand(apiKeys).addCommand(backend).addCommand(contentNegotiation).addCommand(i18n).addCommand(teams).addCommand(payments).addCommand(ecommerce).addCommand(subscriptions).addCommand(notifications).addCommand(cms).addCommand(blog).addCommand(workflows).addCommand(whatsapp);
8107
+ var enable = new Command29("enable").description("enable features").configureHelp(helpConfig).addCommand(ai).addCommand(analytics).addCommand(auth).addCommand(api).addCommand(apiKeys).addCommand(backend).addCommand(contentNegotiation).addCommand(i18n).addCommand(teams).addCommand(payments).addCommand(ecommerce).addCommand(subscriptions).addCommand(notifications).addCommand(cms).addCommand(blog).addCommand(workflows).addCommand(whatsapp);
7929
8108
 
7930
8109
  // src/commands/disable.ts
7931
- import { Command as Command43 } from "commander";
8110
+ import { Command as Command44 } from "commander";
7932
8111
 
7933
8112
  // src/commands/disable/ai.ts
7934
- import { Command as Command29 } from "commander";
8113
+ import { Command as Command30 } from "commander";
7935
8114
 
7936
8115
  // src/commands/disable/_shared.ts
7937
- import process23 from "node:process";
7938
- import * as p24 from "@clack/prompts";
8116
+ import process22 from "node:process";
8117
+ import * as p23 from "@clack/prompts";
7939
8118
  async function runDisable(opts, flags, cmdArgs) {
7940
8119
  if (!flags.yes) {
7941
- const ok = await p24.confirm({
8120
+ const ok = await p23.confirm({
7942
8121
  message: opts.confirmMessage,
7943
8122
  initialValue: false
7944
8123
  });
7945
- if (p24.isCancel(ok) || !ok) {
7946
- p24.cancel("Operation cancelled.");
7947
- process23.exit(0);
8124
+ if (p23.isCancel(ok) || !ok) {
8125
+ p23.cancel("Operation cancelled.");
8126
+ process22.exit(0);
7948
8127
  }
7949
8128
  }
7950
8129
  await runPattern(opts.slug, cmdArgs, { destructive: true }, opts.report);
7951
8130
  }
7952
8131
 
7953
8132
  // src/commands/disable/ai.ts
7954
- var ai2 = new Command29("ai").description("disable AI chat").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8133
+ var ai2 = new Command30("ai").description("disable AI chat").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
7955
8134
  (opts, cmd) => runCommand(
7956
8135
  () => runDisable(
7957
8136
  {
@@ -7977,8 +8156,8 @@ var ai2 = new Command29("ai").description("disable AI chat").option("-y, --yes",
7977
8156
  );
7978
8157
 
7979
8158
  // src/commands/disable/analytics.ts
7980
- import { Command as Command30 } from "commander";
7981
- var analytics2 = new Command30("analytics").description("disable web analytics").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8159
+ import { Command as Command31 } from "commander";
8160
+ var analytics2 = new Command31("analytics").description("disable web analytics").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
7982
8161
  (opts, cmd) => runCommand(
7983
8162
  () => runDisable(
7984
8163
  {
@@ -8004,8 +8183,8 @@ var analytics2 = new Command30("analytics").description("disable web analytics")
8004
8183
  );
8005
8184
 
8006
8185
  // src/commands/disable/auth.ts
8007
- import { Command as Command31 } from "commander";
8008
- var auth2 = new Command31("auth").description("disable authentication").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8186
+ import { Command as Command32 } from "commander";
8187
+ var auth2 = new Command32("auth").description("disable authentication").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8009
8188
  (opts, cmd) => runCommand(
8010
8189
  () => runDisable(
8011
8190
  {
@@ -8031,8 +8210,8 @@ var auth2 = new Command31("auth").description("disable authentication").option("
8031
8210
  );
8032
8211
 
8033
8212
  // src/commands/disable/api.ts
8034
- import { Command as Command32 } from "commander";
8035
- var api2 = new Command32("api").description("disable the REST API").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8213
+ import { Command as Command33 } from "commander";
8214
+ var api2 = new Command33("api").description("disable the REST API").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8036
8215
  (opts, cmd) => runCommand(
8037
8216
  () => runDisable(
8038
8217
  {
@@ -8055,8 +8234,8 @@ var api2 = new Command32("api").description("disable the REST API").option("-y,
8055
8234
  );
8056
8235
 
8057
8236
  // src/commands/disable/api-keys.ts
8058
- import { Command as Command33 } from "commander";
8059
- var apiKeys2 = new Command33("api-keys").description("disable API key management").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8237
+ import { Command as Command34 } from "commander";
8238
+ var apiKeys2 = new Command34("api-keys").description("disable API key management").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8060
8239
  (opts, cmd) => runCommand(
8061
8240
  () => runDisable(
8062
8241
  {
@@ -8079,8 +8258,8 @@ var apiKeys2 = new Command33("api-keys").description("disable API key management
8079
8258
  );
8080
8259
 
8081
8260
  // src/commands/disable/backend.ts
8082
- import { Command as Command34 } from "commander";
8083
- var backend2 = new Command34("backend").description("disable the PocketBase backend").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8261
+ import { Command as Command35 } from "commander";
8262
+ var backend2 = new Command35("backend").description("disable the PocketBase backend").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8084
8263
  (opts, cmd) => runCommand(
8085
8264
  () => runDisable(
8086
8265
  {
@@ -8103,8 +8282,8 @@ var backend2 = new Command34("backend").description("disable the PocketBase back
8103
8282
  );
8104
8283
 
8105
8284
  // src/commands/disable/content-negotiation.ts
8106
- import { Command as Command35 } from "commander";
8107
- var contentNegotiation2 = new Command35("content-negotiation").description("disable content negotiation").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8285
+ import { Command as Command36 } from "commander";
8286
+ var contentNegotiation2 = new Command36("content-negotiation").description("disable content negotiation").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8108
8287
  (opts, cmd) => runCommand(
8109
8288
  () => runDisable(
8110
8289
  {
@@ -8127,8 +8306,8 @@ var contentNegotiation2 = new Command35("content-negotiation").description("disa
8127
8306
  );
8128
8307
 
8129
8308
  // src/commands/disable/i18n.ts
8130
- import { Command as Command36 } from "commander";
8131
- var i18n2 = new Command36("i18n").description("disable internationalization").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8309
+ import { Command as Command37 } from "commander";
8310
+ var i18n2 = new Command37("i18n").description("disable internationalization").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8132
8311
  (opts, cmd) => runCommand(
8133
8312
  () => runDisable(
8134
8313
  {
@@ -8152,8 +8331,8 @@ var i18n2 = new Command36("i18n").description("disable internationalization").op
8152
8331
  );
8153
8332
 
8154
8333
  // src/commands/disable/notifications.ts
8155
- import { Command as Command37 } from "commander";
8156
- var notifications2 = new Command37("notifications").description("disable in-app notifications").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8334
+ import { Command as Command38 } from "commander";
8335
+ var notifications2 = new Command38("notifications").description("disable in-app notifications").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8157
8336
  (opts, cmd) => runCommand(
8158
8337
  () => runDisable(
8159
8338
  {
@@ -8179,8 +8358,8 @@ var notifications2 = new Command37("notifications").description("disable in-app
8179
8358
  );
8180
8359
 
8181
8360
  // src/commands/disable/teams.ts
8182
- import { Command as Command38 } from "commander";
8183
- var teams2 = new Command38("teams").description("disable teams").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8361
+ import { Command as Command39 } from "commander";
8362
+ var teams2 = new Command39("teams").description("disable teams").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8184
8363
  (opts, cmd) => runCommand(
8185
8364
  () => runDisable(
8186
8365
  {
@@ -8203,7 +8382,7 @@ var teams2 = new Command38("teams").description("disable teams").option("-y, --y
8203
8382
  );
8204
8383
 
8205
8384
  // src/commands/disable/payments.ts
8206
- import { Command as Command39 } from "commander";
8385
+ import { Command as Command40 } from "commander";
8207
8386
  var STRIPE = {
8208
8387
  confirmMessage: "Disable payments? Drops Stripe collections, strips Stripe env credentials, reverts nav/signup edits, and removes generated payment files. Stripe dashboard products/prices and the stripe packages are untouched.",
8209
8388
  nextSteps: [
@@ -8217,14 +8396,22 @@ var SHOPIFY = {
8217
8396
  "The @shopify/storefront-api-client package remains installed. Uninstall it manually if desired."
8218
8397
  ]
8219
8398
  };
8220
- var payments2 = new Command39("payments").description("disable payments").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8399
+ var WHATSAPP = {
8400
+ confirmMessage: "Disable payments? Removes the Order on WhatsApp button, src/lib/order.ts and the WhatsApp env variables. Orders recorded on velastack.dev are untouched.",
8401
+ nextSteps: [
8402
+ "The hosted order form and the orders in it stay on velastack.dev.",
8403
+ "The @velastack/whatsapp package remains installed. Uninstall it manually if desired."
8404
+ ]
8405
+ };
8406
+ var COPY = { shopify: SHOPIFY, whatsapp: WHATSAPP };
8407
+ var payments2 = new Command40("payments").description("disable payments").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8221
8408
  (opts, cmd) => runCommand(async () => {
8222
8409
  const { detected } = await detectWorkspace();
8223
8410
  const provider = detected.providers.payments;
8224
8411
  if (provider === "stripe" || provider === void 0 && hasBackend()) {
8225
8412
  assertBackendReady("vela disable payments");
8226
8413
  }
8227
- const copy = provider === "shopify" ? SHOPIFY : STRIPE;
8414
+ const copy = (provider ? COPY[provider] : void 0) ?? STRIPE;
8228
8415
  await runDisable(
8229
8416
  {
8230
8417
  slug: "disable-payments",
@@ -8246,8 +8433,8 @@ var payments2 = new Command39("payments").description("disable payments").option
8246
8433
  );
8247
8434
 
8248
8435
  // src/commands/disable/ecommerce.ts
8249
- import { Command as Command40 } from "commander";
8250
- var ecommerce2 = new Command40("ecommerce").description("disable ecommerce").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8436
+ import { Command as Command41 } from "commander";
8437
+ var ecommerce2 = new Command41("ecommerce").description("disable ecommerce").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8251
8438
  (opts, cmd) => runCommand(
8252
8439
  () => runDisable(
8253
8440
  {
@@ -8274,8 +8461,8 @@ var ecommerce2 = new Command40("ecommerce").description("disable ecommerce").opt
8274
8461
  );
8275
8462
 
8276
8463
  // src/commands/disable/subscriptions.ts
8277
- import { Command as Command41 } from "commander";
8278
- var subscriptions2 = new Command41("subscriptions").description("disable Stripe subscriptions").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8464
+ import { Command as Command42 } from "commander";
8465
+ var subscriptions2 = new Command42("subscriptions").description("disable Stripe subscriptions").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8279
8466
  (opts, cmd) => runCommand(
8280
8467
  () => runDisable(
8281
8468
  {
@@ -8302,8 +8489,8 @@ var subscriptions2 = new Command41("subscriptions").description("disable Stripe
8302
8489
  );
8303
8490
 
8304
8491
  // src/commands/disable/whatsapp.ts
8305
- import { Command as Command42 } from "commander";
8306
- var whatsapp2 = new Command42("whatsapp").description("disable WhatsApp sign-in").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8492
+ import { Command as Command43 } from "commander";
8493
+ var whatsapp2 = new Command43("whatsapp").description("disable WhatsApp sign-in").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8307
8494
  (opts, cmd) => runCommand(
8308
8495
  () => runDisable(
8309
8496
  {
@@ -8331,30 +8518,30 @@ var whatsapp2 = new Command42("whatsapp").description("disable WhatsApp sign-in"
8331
8518
  );
8332
8519
 
8333
8520
  // src/commands/disable.ts
8334
- var disable = new Command43("disable").description("disable features").configureHelp(helpConfig).addCommand(ai2).addCommand(analytics2).addCommand(auth2).addCommand(api2).addCommand(apiKeys2).addCommand(backend2).addCommand(contentNegotiation2).addCommand(i18n2).addCommand(notifications2).addCommand(teams2).addCommand(payments2).addCommand(ecommerce2).addCommand(subscriptions2).addCommand(whatsapp2);
8521
+ var disable = new Command44("disable").description("disable features").configureHelp(helpConfig).addCommand(ai2).addCommand(analytics2).addCommand(auth2).addCommand(api2).addCommand(apiKeys2).addCommand(backend2).addCommand(contentNegotiation2).addCommand(i18n2).addCommand(notifications2).addCommand(teams2).addCommand(payments2).addCommand(ecommerce2).addCommand(subscriptions2).addCommand(whatsapp2);
8335
8522
 
8336
8523
  // src/commands/destroy.ts
8337
- import { Command as Command49 } from "commander";
8524
+ import { Command as Command51 } from "commander";
8338
8525
 
8339
8526
  // src/commands/destroy/form.ts
8340
- import { Command as Command44 } from "commander";
8527
+ import { Command as Command45 } from "commander";
8341
8528
 
8342
8529
  // src/commands/destroy/_shared.ts
8343
- import process24 from "node:process";
8344
- import * as p25 from "@clack/prompts";
8530
+ import process23 from "node:process";
8531
+ import * as p24 from "@clack/prompts";
8345
8532
  async function runDestroy(slug2, model, confirmMessage, report5, flags) {
8346
8533
  if (!flags.yes) {
8347
- const ok = await p25.confirm({ message: confirmMessage, initialValue: false });
8348
- if (p25.isCancel(ok) || !ok) {
8349
- p25.cancel("Operation cancelled.");
8350
- process24.exit(0);
8534
+ const ok = await p24.confirm({ message: confirmMessage, initialValue: false });
8535
+ if (p24.isCancel(ok) || !ok) {
8536
+ p24.cancel("Operation cancelled.");
8537
+ process23.exit(0);
8351
8538
  }
8352
8539
  }
8353
8540
  await runPattern(slug2, [model], { destructive: true, route: flags.route }, report5);
8354
8541
  }
8355
8542
 
8356
8543
  // src/commands/destroy/form.ts
8357
- var form2 = new Command44("form").description("destroy a form generated by `vela generate form`").argument("<model>", "model name used when the form was generated (e.g., contact, login)").option("-y, --yes", "skip confirmation prompt").option(
8544
+ var form2 = new Command45("form").description("destroy a form generated by `vela generate form`").argument("<model>", "model name used when the form was generated (e.g., contact, login)").option("-y, --yes", "skip confirmation prompt").option(
8358
8545
  "--route <route>",
8359
8546
  "custom route the form was generated at (must match the --route used at generation)"
8360
8547
  ).allowExcessArguments(true).configureHelp(helpConfig).action(
@@ -8378,8 +8565,8 @@ var form2 = new Command44("form").description("destroy a form generated by `vela
8378
8565
  );
8379
8566
 
8380
8567
  // src/commands/destroy/schema.ts
8381
- import { Command as Command45 } from "commander";
8382
- var schema2 = new Command45("schema").description("destroy a zod schema generated by `vela generate schema`").argument("<model>", "schema model name (e.g., contact, login)").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8568
+ import { Command as Command46 } from "commander";
8569
+ var schema2 = new Command46("schema").description("destroy a zod schema generated by `vela generate schema`").argument("<model>", "schema model name (e.g., contact, login)").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8383
8570
  (model, opts) => runCommand(
8384
8571
  () => runDestroy(
8385
8572
  "destroy-schema",
@@ -8400,8 +8587,8 @@ var schema2 = new Command45("schema").description("destroy a zod schema generate
8400
8587
  );
8401
8588
 
8402
8589
  // src/commands/destroy/resource.ts
8403
- import { Command as Command46 } from "commander";
8404
- var resource2 = new Command46("resource").description("destroy a resource generated by `vela generate resource`").argument("<model>", "model path used when the resource was generated (e.g., contacts, articles)").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8590
+ import { Command as Command47 } from "commander";
8591
+ var resource2 = new Command47("resource").description("destroy a resource generated by `vela generate resource`").argument("<model>", "model path used when the resource was generated (e.g., contacts, articles)").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
8405
8592
  (model, opts) => runCommand(
8406
8593
  () => runDestroy(
8407
8594
  "destroy-resource",
@@ -8422,8 +8609,8 @@ var resource2 = new Command46("resource").description("destroy a resource genera
8422
8609
  );
8423
8610
 
8424
8611
  // src/commands/destroy/scaffold.ts
8425
- import { Command as Command47 } from "commander";
8426
- var scaffold2 = new Command47("scaffold").description("destroy a scaffold generated by `vela generate scaffold`").argument("<model>", "model name used when the scaffold was generated (e.g., contact, todo)").option("-y, --yes", "skip confirmation prompt").option(
8612
+ import { Command as Command48 } from "commander";
8613
+ var scaffold2 = new Command48("scaffold").description("destroy a scaffold generated by `vela generate scaffold`").argument("<model>", "model name used when the scaffold was generated (e.g., contact, todo)").option("-y, --yes", "skip confirmation prompt").option(
8427
8614
  "--route <route>",
8428
8615
  "custom route the scaffold was generated at (must match the --route used at generation)"
8429
8616
  ).allowExcessArguments(true).configureHelp(helpConfig).action(
@@ -8450,37 +8637,37 @@ var scaffold2 = new Command47("scaffold").description("destroy a scaffold genera
8450
8637
  );
8451
8638
 
8452
8639
  // src/commands/destroy/deployment.ts
8453
- import process28 from "node:process";
8454
- import { Command as Command48 } from "commander";
8455
- import * as p29 from "@clack/prompts";
8640
+ import process27 from "node:process";
8641
+ import { Command as Command49 } from "commander";
8642
+ import * as p28 from "@clack/prompts";
8456
8643
  import pc12 from "picocolors";
8457
8644
 
8458
8645
  // src/lib/server-command.ts
8459
- import process27 from "node:process";
8646
+ import process26 from "node:process";
8460
8647
  import * as v8 from "valibot";
8461
- import * as p26 from "@clack/prompts";
8648
+ import * as p25 from "@clack/prompts";
8462
8649
  import pc9 from "picocolors";
8463
8650
 
8464
8651
  // src/lib/deploy-config.ts
8465
- import fs34 from "node:fs";
8466
- import path34 from "node:path";
8652
+ import fs36 from "node:fs";
8653
+ import path36 from "node:path";
8467
8654
  import crypto2 from "node:crypto";
8468
8655
  function projectFilePath(workspaceRootDir) {
8469
- return path34.join(workspaceRootDir, ".vela", "project.json");
8656
+ return path36.join(workspaceRootDir, ".vela", "project.json");
8470
8657
  }
8471
8658
  function readProjectFile(workspaceRootDir) {
8472
8659
  const file = projectFilePath(workspaceRootDir);
8473
- if (!fs34.existsSync(file)) return {};
8660
+ if (!fs36.existsSync(file)) return {};
8474
8661
  try {
8475
- return JSON.parse(fs34.readFileSync(file, "utf8"));
8662
+ return JSON.parse(fs36.readFileSync(file, "utf8"));
8476
8663
  } catch {
8477
8664
  return {};
8478
8665
  }
8479
8666
  }
8480
8667
  function writeProjectFile(workspaceRootDir, data) {
8481
8668
  const file = projectFilePath(workspaceRootDir);
8482
- fs34.mkdirSync(path34.dirname(file), { recursive: true });
8483
- fs34.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
8669
+ fs36.mkdirSync(path36.dirname(file), { recursive: true });
8670
+ fs36.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
8484
8671
  }
8485
8672
  function resolveAppIdentity(workspaceRootDir, projectName) {
8486
8673
  const project = readProjectFile(workspaceRootDir);
@@ -8505,11 +8692,11 @@ function readAppIdentity(workspaceRootDir, projectName) {
8505
8692
  }
8506
8693
  function defaultProjectName(workspaceRootDir) {
8507
8694
  try {
8508
- const pkg = readPackageJson(path34.join(workspaceRootDir, "package.json"));
8695
+ const pkg = readPackageJson(path36.join(workspaceRootDir, "package.json"));
8509
8696
  if (typeof pkg.name === "string" && pkg.name.trim()) return pkg.name.trim();
8510
8697
  } catch {
8511
8698
  }
8512
- return path34.basename(workspaceRootDir);
8699
+ return path36.basename(workspaceRootDir);
8513
8700
  }
8514
8701
  function slug(value) {
8515
8702
  return value.toLowerCase().replace(/^@/, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 32) || "app";
@@ -8580,17 +8767,17 @@ function randomSuffix() {
8580
8767
  }
8581
8768
 
8582
8769
  // src/lib/artifact.ts
8583
- import fs36 from "node:fs";
8584
- import path36 from "node:path";
8770
+ import fs38 from "node:fs";
8771
+ import path38 from "node:path";
8585
8772
  import { detect as detect6 } from "package-manager-detector";
8586
8773
  import { resolveCommand as resolveCommand4 } from "package-manager-detector/commands";
8587
8774
 
8588
8775
  // src/lib/ssh.ts
8589
- import fs35 from "node:fs";
8776
+ import fs37 from "node:fs";
8590
8777
  import os5 from "node:os";
8591
- import path35 from "node:path";
8778
+ import path37 from "node:path";
8592
8779
  import crypto4 from "node:crypto";
8593
- import process25 from "node:process";
8780
+ import process24 from "node:process";
8594
8781
  import { spawn as spawn4 } from "node:child_process";
8595
8782
  var RemoteCommandError = class extends Error {
8596
8783
  exitCode;
@@ -8631,9 +8818,9 @@ var SshSession = class {
8631
8818
  }
8632
8819
  async open() {
8633
8820
  if (this.controlPath) return;
8634
- const dir = path35.join(os5.tmpdir(), "vela-ssh");
8635
- fs35.mkdirSync(dir, { recursive: true, mode: 448 });
8636
- const socket = path35.join(dir, `${crypto4.randomBytes(6).toString("hex")}.sock`);
8821
+ const dir = path37.join(os5.tmpdir(), "vela-ssh");
8822
+ fs37.mkdirSync(dir, { recursive: true, mode: 448 });
8823
+ const socket = path37.join(dir, `${crypto4.randomBytes(6).toString("hex")}.sock`);
8637
8824
  this.controlPath = socket;
8638
8825
  const args = [
8639
8826
  ...this.sshArgs(),
@@ -8868,17 +9055,17 @@ function spawnCapture(command, args, opts = {}) {
8868
9055
  const child = spawn4(command, args, {
8869
9056
  stdio,
8870
9057
  cwd: opts.cwd,
8871
- env: opts.env ? { ...process25.env, ...opts.env } : void 0
9058
+ env: opts.env ? { ...process24.env, ...opts.env } : void 0
8872
9059
  });
8873
9060
  let stdout = "";
8874
9061
  let stderr = "";
8875
9062
  child.stdout?.on("data", (chunk) => {
8876
9063
  stdout += chunk;
8877
- if (opts.streamStdout) process25.stdout.write(chunk);
9064
+ if (opts.streamStdout) process24.stdout.write(chunk);
8878
9065
  });
8879
9066
  child.stderr?.on("data", (chunk) => {
8880
9067
  stderr += chunk;
8881
- if (opts.stream) process25.stderr.write(chunk);
9068
+ if (opts.stream) process24.stderr.write(chunk);
8882
9069
  });
8883
9070
  child.on("error", reject);
8884
9071
  child.on("close", (code2) => resolve2({ stdout, stderr, exitCode: code2 ?? 1 }));
@@ -8923,11 +9110,11 @@ function collectArtifact(cwd) {
8923
9110
  const outputDir = DEFAULT_OUTPUT_DIR;
8924
9111
  const entries = [];
8925
9112
  const add2 = (rel, remoteDir = "") => {
8926
- const localPath = path36.join(cwd, rel);
8927
- if (fs36.existsSync(localPath)) entries.push({ localPath, remoteDir });
9113
+ const localPath = path38.join(cwd, rel);
9114
+ if (fs38.existsSync(localPath)) entries.push({ localPath, remoteDir });
8928
9115
  };
8929
- const buildPath = path36.join(cwd, outputDir);
8930
- if (!fs36.existsSync(path36.join(buildPath, "index.js"))) {
9116
+ const buildPath = path38.join(cwd, outputDir);
9117
+ if (!fs38.existsSync(path38.join(buildPath, "index.js"))) {
8931
9118
  throw new BuildError(
8932
9119
  `No ${outputDir}/index.js to deploy.
8933
9120
 
@@ -8940,18 +9127,18 @@ build ran with it as the adapter, then deploy again.`
8940
9127
  for (const lockfile of [NPM_LOCKFILE, ...FOREIGN_LOCKFILES]) add2(lockfile);
8941
9128
  add2(".npmrc");
8942
9129
  add2(MIGRATIONS_DIR);
8943
- const hooks = path36.join(cwd, DATA_DIR, "hooks");
8944
- if (fs36.existsSync(hooks)) entries.push({ localPath: hooks, remoteDir: "hooks" });
9130
+ const hooks = path38.join(cwd, DATA_DIR, "hooks");
9131
+ if (fs38.existsSync(hooks)) entries.push({ localPath: hooks, remoteDir: "hooks" });
8945
9132
  return entries;
8946
9133
  }
8947
9134
  var NPM_LOCKFILE = "package-lock.json";
8948
9135
  var FOREIGN_LOCKFILES = ["pnpm-lock.yaml", "yarn.lock", "bun.lock", "bun.lockb"];
8949
9136
  function hasLockfile(cwd) {
8950
- return fs36.existsSync(path36.join(cwd, NPM_LOCKFILE));
9137
+ return fs38.existsSync(path38.join(cwd, NPM_LOCKFILE));
8951
9138
  }
8952
9139
  function foreignLockfile(cwd) {
8953
9140
  if (hasLockfile(cwd)) return void 0;
8954
- return FOREIGN_LOCKFILES.find((name) => fs36.existsSync(path36.join(cwd, name)));
9141
+ return FOREIGN_LOCKFILES.find((name) => fs38.existsSync(path38.join(cwd, name)));
8955
9142
  }
8956
9143
  async function gitSha(cwd) {
8957
9144
  const result = await spawnCapture("git", ["rev-parse", "HEAD"], { cwd });
@@ -8990,9 +9177,9 @@ function sshOptionsFrom(options) {
8990
9177
 
8991
9178
  // src/lib/remote.ts
8992
9179
  import crypto5 from "node:crypto";
8993
- import fs37 from "node:fs";
8994
- import path37 from "node:path";
8995
- import process26 from "node:process";
9180
+ import fs39 from "node:fs";
9181
+ import path39 from "node:path";
9182
+ import process25 from "node:process";
8996
9183
  var VELA_ROOT = "/var/lib/vela";
8997
9184
  var VELA_ETC = "/etc/vela";
8998
9185
  var VELA_USER = "vela";
@@ -9004,19 +9191,19 @@ function instanceHasBackend(state) {
9004
9191
  return state.backend ?? Boolean(state.pbPort);
9005
9192
  }
9006
9193
  function serverTemplatesDir() {
9007
- return path37.join(templatesDir(), "server");
9194
+ return path39.join(templatesDir(), "server");
9008
9195
  }
9009
9196
  var DIGEST_LENGTH = 12;
9010
9197
  function serverScriptsDigest(dir = serverTemplatesDir()) {
9011
9198
  const hash = crypto5.createHash("sha256");
9012
9199
  for (const file of listFiles(dir).sort()) {
9013
- hash.update(file).update("\0").update(fs37.readFileSync(path37.join(dir, file))).update("\0");
9200
+ hash.update(file).update("\0").update(fs39.readFileSync(path39.join(dir, file))).update("\0");
9014
9201
  }
9015
9202
  return hash.digest("hex").slice(0, DIGEST_LENGTH);
9016
9203
  }
9017
9204
  function listFiles(root, prefix = "") {
9018
9205
  const files = [];
9019
- for (const entry of fs37.readdirSync(path37.join(root, prefix), { withFileTypes: true })) {
9206
+ for (const entry of fs39.readdirSync(path39.join(root, prefix), { withFileTypes: true })) {
9020
9207
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
9021
9208
  if (entry.isDirectory()) files.push(...listFiles(root, rel));
9022
9209
  else if (entry.isFile()) files.push(rel);
@@ -9029,7 +9216,7 @@ async function syncServerScripts(session) {
9029
9216
  const dir = `${SCRIPT_VERSIONS_DIR}/${digest}`;
9030
9217
  const present = await session.script(`[ -d "$1" ] && echo yes || echo no`, { args: [dir] });
9031
9218
  if (present.stdout.trim() !== "yes") {
9032
- const incoming = `${SCRIPT_VERSIONS_DIR}/.incoming.${digest}.${process26.pid}.${Date.now()}`;
9219
+ const incoming = `${SCRIPT_VERSIONS_DIR}/.incoming.${digest}.${process25.pid}.${Date.now()}`;
9033
9220
  await session.script(`mkdir -p "$1" && chmod 0755 "$(dirname "$1")" "$1"`, {
9034
9221
  args: [incoming]
9035
9222
  });
@@ -9143,7 +9330,7 @@ var remotePaths = {
9143
9330
  };
9144
9331
 
9145
9332
  // src/lib/remote-env.ts
9146
- import fs38 from "node:fs";
9333
+ import fs40 from "node:fs";
9147
9334
  import dotenv from "dotenv";
9148
9335
  var KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
9149
9336
  function isValidKey(key) {
@@ -9191,7 +9378,7 @@ function quote(value) {
9191
9378
  return `"${escaped}"`;
9192
9379
  }
9193
9380
  function readLocalEnvFile(file) {
9194
- const parsed = dotenv.parse(fs38.readFileSync(file));
9381
+ const parsed = dotenv.parse(fs40.readFileSync(file));
9195
9382
  const result = {};
9196
9383
  for (const [key, value] of Object.entries(parsed)) {
9197
9384
  if (isValidKey(key)) result[key] = value;
@@ -9298,8 +9485,8 @@ function describeTarget(target) {
9298
9485
  return target.name;
9299
9486
  }
9300
9487
  }
9301
- function bold(text19) {
9302
- return `\`${text19}\``;
9488
+ function bold(text18) {
9489
+ return `\`${text18}\``;
9303
9490
  }
9304
9491
 
9305
9492
  // src/lib/server-command.ts
@@ -9396,7 +9583,7 @@ async function ensureBinding(workspaceRootDir, target, request = {}) {
9396
9583
  writeBinding(workspaceRootDir, key, binding);
9397
9584
  }
9398
9585
  if (moving) {
9399
- p26.log.warn(
9586
+ p25.log.warn(
9400
9587
  `${pc9.cyan(bindingName(target))} now points at ${pc9.cyan(server)}.
9401
9588
 
9402
9589
  Whatever is running on ${existing.server} is left there, and this project can no
@@ -9407,7 +9594,7 @@ longer reach it. Remove it there first if that was not intended.`
9407
9594
  }
9408
9595
  async function confirmMove(target, from, to) {
9409
9596
  const name = bindingName(target);
9410
- if (!process27.stdout.isTTY || process27.env.CI) {
9597
+ if (!process26.stdout.isTTY || process26.env.CI) {
9411
9598
  throw new Error(
9412
9599
  `${pc9.cyan(`--server ${to}`)} does not match the server recorded for ${pc9.cyan(name)}, ${pc9.cyan(from)}.
9413
9600
 
@@ -9415,13 +9602,13 @@ Drop ${pc9.cyan("--server")} to use the recorded one, or move the binding on pur
9415
9602
  this command once from a terminal (or editing .vela/project.json).`
9416
9603
  );
9417
9604
  }
9418
- const ok = await p26.confirm({
9605
+ const ok = await p25.confirm({
9419
9606
  message: `${name} ${target.kind === "preview" ? "run" : "runs"} on ${from}. Point ${name} at ${to} instead?`,
9420
9607
  initialValue: false
9421
9608
  });
9422
- if (p26.isCancel(ok) || !ok) {
9423
- p26.cancel("Operation cancelled.");
9424
- process27.exit(0);
9609
+ if (p25.isCancel(ok) || !ok) {
9610
+ p25.cancel("Operation cancelled.");
9611
+ process26.exit(0);
9425
9612
  }
9426
9613
  }
9427
9614
  function bindingName(target) {
@@ -9429,7 +9616,7 @@ function bindingName(target) {
9429
9616
  }
9430
9617
  async function promptServer(target) {
9431
9618
  const name = bindingName(target);
9432
- if (!process27.stdout.isTTY || process27.env.CI) {
9619
+ if (!process26.stdout.isTTY || process26.env.CI) {
9433
9620
  throw new Error(
9434
9621
  `${name} ${target.kind === "preview" ? "are" : "is"} not bound to a server yet, and there is no terminal to ask on.
9435
9622
 
@@ -9437,29 +9624,29 @@ Pass ${pc9.cyan("--server user@host")}, or run the command once from your own ma
9437
9624
  and commit ${pc9.cyan(".vela/project.json")}.`
9438
9625
  );
9439
9626
  }
9440
- p26.log.info(
9627
+ p25.log.info(
9441
9628
  `${pc9.cyan(name)} ${target.kind === "preview" ? "are" : "is"} not bound to a server yet.`
9442
9629
  );
9443
- const value = await p26.text({
9630
+ const value = await p25.text({
9444
9631
  message: `Which server should ${name} run on?`,
9445
9632
  placeholder: "root@203.0.113.10",
9446
9633
  validate: (input) => input?.trim() ? void 0 : "An ssh_config alias, or user@host"
9447
9634
  });
9448
- if (p26.isCancel(value)) {
9449
- p26.cancel("Operation cancelled.");
9450
- process27.exit(0);
9635
+ if (p25.isCancel(value)) {
9636
+ p25.cancel("Operation cancelled.");
9637
+ process26.exit(0);
9451
9638
  }
9452
9639
  return value.trim();
9453
9640
  }
9454
9641
  async function promptDomain(target) {
9455
- if (!process27.stdout.isTTY || process27.env.CI) return void 0;
9456
- const value = await p26.text({
9642
+ if (!process26.stdout.isTTY || process26.env.CI) return void 0;
9643
+ const value = await p25.text({
9457
9644
  message: `Which hostname should ${target.name} be served on?`,
9458
9645
  placeholder: "example.com \u2014 leave blank to decide later"
9459
9646
  });
9460
- if (p26.isCancel(value)) {
9461
- p26.cancel("Operation cancelled.");
9462
- process27.exit(0);
9647
+ if (p25.isCancel(value)) {
9648
+ p25.cancel("Operation cancelled.");
9649
+ process26.exit(0);
9463
9650
  }
9464
9651
  return value.trim() || void 0;
9465
9652
  }
@@ -9467,10 +9654,10 @@ async function applyRestart(ctx) {
9467
9654
  const outcome = await restartInstance(ctx.session, ctx.instance);
9468
9655
  if (!outcome.deployed) return;
9469
9656
  if (outcome.restarted) {
9470
- p26.log.success("App restarted");
9657
+ p25.log.success("App restarted");
9471
9658
  return;
9472
9659
  }
9473
- p26.log.error(
9660
+ p25.log.error(
9474
9661
  `App restart failed.
9475
9662
 
9476
9663
  The new value is stored and will be used the next time the app starts.
@@ -9479,7 +9666,7 @@ ${pc9.dim(outcome.error ?? "")}`
9479
9666
  }
9480
9667
  async function applyEnvRestart(ctx, changed) {
9481
9668
  if (touchesSuperuser(changed)) {
9482
- p26.log.warn(
9669
+ p25.log.warn(
9483
9670
  `PocketBase superuser credentials changed.
9484
9671
 
9485
9672
  The database still holds the old ones, so the app has not been restarted.
@@ -9516,14 +9703,14 @@ function isPreview(envTag) {
9516
9703
  return envTag.startsWith("preview--");
9517
9704
  }
9518
9705
  function destroyDecision(request) {
9519
- const { appName, purge, yes, confirm: confirm14, interactive } = request;
9706
+ const { appName, purge, yes, confirm: confirm15, interactive } = request;
9520
9707
  const dangerous = isProd(request.envTag) || purge && !isPreview(request.envTag);
9521
9708
  const what = describe(request);
9522
- if (confirm14 !== void 0) {
9523
- if (confirm14 === appName) return { kind: "proceed" };
9709
+ if (confirm15 !== void 0) {
9710
+ if (confirm15 === appName) return { kind: "proceed" };
9524
9711
  return {
9525
9712
  kind: "refuse",
9526
- message: `\`--confirm ${confirm14}\` does not name this app. Removing ${what} takes \`--confirm ${appName}\`.`
9713
+ message: `\`--confirm ${confirm15}\` does not name this app. Removing ${what} takes \`--confirm ${appName}\`.`
9527
9714
  };
9528
9715
  }
9529
9716
  if (dangerous) {
@@ -9556,11 +9743,11 @@ function describe({ appName, envTag, purge }) {
9556
9743
  }
9557
9744
 
9558
9745
  // src/lib/deploy-report.ts
9559
- import * as p28 from "@clack/prompts";
9746
+ import * as p27 from "@clack/prompts";
9560
9747
  import pc11 from "picocolors";
9561
9748
 
9562
9749
  // src/lib/server-identity.ts
9563
- import * as p27 from "@clack/prompts";
9750
+ import * as p26 from "@clack/prompts";
9564
9751
  import pc10 from "picocolors";
9565
9752
  var IPV4 = /^\d{1,3}(?:\.\d{1,3}){3}$/;
9566
9753
  async function ensureServerIdentity(session, apiKey) {
@@ -9574,7 +9761,7 @@ async function ensureServerIdentity(session, apiKey) {
9574
9761
  if (!existing || existing.serverId !== registered.serverId || existing.originHost !== registered.originHost || existing.token !== registered.token) {
9575
9762
  await writeServerIdentity(session, registered);
9576
9763
  if (existing) {
9577
- p27.log.info(`${pc10.cyan(session.target)} was re-registered with velastack.dev.`);
9764
+ p26.log.info(`${pc10.cyan(session.target)} was re-registered with velastack.dev.`);
9578
9765
  }
9579
9766
  }
9580
9767
  await runServerScript(session, "origin.sh");
@@ -9614,7 +9801,7 @@ function createDeployReporter(workspaceRootDir) {
9614
9801
  const link2 = readProjectConfig(workspaceRootDir);
9615
9802
  const apiKey = link2 ? readApiKey() : null;
9616
9803
  if (link2 && !apiKey) {
9617
- p28.log.warn(
9804
+ p27.log.warn(
9618
9805
  `This project is linked to ${pc11.cyan(link2.projectName)} on velastack.dev, but there is no
9619
9806
  API key here, so this deploy will not be recorded. Run ${pc11.cyan("vela login")}, or set
9620
9807
  ${pc11.cyan("VELA_API_KEY")}.`
@@ -9665,7 +9852,7 @@ async function reportEnvironmentDestroyed(workspaceRootDir, envTag, { missingOk
9665
9852
  }
9666
9853
  }
9667
9854
  function warn(what, err) {
9668
- p28.log.warn(
9855
+ p27.log.warn(
9669
9856
  `velastack.dev could not ${what}.
9670
9857
  ${pc11.dim(err instanceof Error ? err.message : String(err))}`
9671
9858
  );
@@ -9674,7 +9861,7 @@ ${pc11.dim(err instanceof Error ? err.message : String(err))}`
9674
9861
  // src/commands/destroy/deployment.ts
9675
9862
  var deployment = addLockWaitOption(
9676
9863
  addTargetOptions(
9677
- new Command48("deployment").description("remove a deployed environment from its server").configureHelp(helpConfig),
9864
+ new Command49("deployment").description("remove a deployed environment from its server").configureHelp(helpConfig),
9678
9865
  "production"
9679
9866
  )
9680
9867
  ).option("--purge", "also delete the database and uploaded files").option("-y, --yes", "skip the confirmation prompt").option(
@@ -9693,7 +9880,7 @@ var deployment = addLockWaitOption(
9693
9880
  purge: options.purge === true,
9694
9881
  yes: options.yes === true,
9695
9882
  confirm: options.confirm,
9696
- interactive: Boolean(process28.stdin.isTTY && process28.stdout.isTTY)
9883
+ interactive: Boolean(process27.stdin.isTTY && process27.stdout.isTTY)
9697
9884
  });
9698
9885
  if (decision.kind === "refuse") throw new Error(decision.message);
9699
9886
  if (decision.kind === "prompt") {
@@ -9713,13 +9900,13 @@ var deployment = addLockWaitOption(
9713
9900
  missingOk: true
9714
9901
  });
9715
9902
  }
9716
- p29.log.info(
9903
+ p28.log.info(
9717
9904
  `Nothing named ${pc12.cyan(`${ctx.appName} (${ctx.targetName})`)} on ${ctx.server}; nothing to remove.`
9718
9905
  );
9719
9906
  return;
9720
9907
  }
9721
9908
  await reportEnvironmentDestroyed(ctx.workspaceRootDir, ctx.envTag);
9722
- p29.log.success(
9909
+ p28.log.success(
9723
9910
  `Removed ${pc12.cyan(`${ctx.appName} (${ctx.targetName})`)} from ${ctx.server}.` + (result?.purged ? result.trash ? `
9724
9911
 
9725
9912
  A snapshot of its data is at ${pc12.cyan(result.trash)} on the server for two weeks.` : "" : `
@@ -9737,34 +9924,66 @@ The database and uploads are still in the instance's shared directory. Pass ${pc
9737
9924
  );
9738
9925
  async function confirm6(appName, targetName, byName) {
9739
9926
  if (byName) {
9740
- const answer = await p29.text({
9927
+ const answer = await p28.text({
9741
9928
  message: `This removes ${pc12.cyan(`${appName} (${targetName})`)}. Type the app name to confirm`,
9742
9929
  validate: (value) => value === appName ? void 0 : `Type ${appName} to confirm`
9743
9930
  });
9744
- if (p29.isCancel(answer)) {
9745
- p29.cancel("Operation cancelled.");
9746
- process28.exit(0);
9931
+ if (p28.isCancel(answer)) {
9932
+ p28.cancel("Operation cancelled.");
9933
+ process27.exit(0);
9747
9934
  }
9748
9935
  return;
9749
9936
  }
9750
- const ok = await p29.confirm({
9937
+ const ok = await p28.confirm({
9751
9938
  message: `Remove ${appName} (${targetName})?`,
9752
9939
  initialValue: false
9753
9940
  });
9754
- if (p29.isCancel(ok) || !ok) {
9755
- p29.cancel("Operation cancelled.");
9756
- process28.exit(0);
9941
+ if (p28.isCancel(ok) || !ok) {
9942
+ p28.cancel("Operation cancelled.");
9943
+ process27.exit(0);
9757
9944
  }
9758
9945
  }
9759
9946
 
9947
+ // src/commands/destroy/shop.ts
9948
+ import process28 from "node:process";
9949
+ import { Command as Command50 } from "commander";
9950
+ import * as p29 from "@clack/prompts";
9951
+ var shop2 = new Command50("shop").description("destroy the shop pages generated by `vela generate shop`").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
9952
+ (opts, cmd) => runCommand(async () => {
9953
+ if (!opts.yes) {
9954
+ const ok = await p29.confirm({
9955
+ message: "Destroy the shop? Removes the listing and product pages (and src/lib/catalog.ts on WhatsApp). The cart and payments stay.",
9956
+ initialValue: false
9957
+ });
9958
+ if (p29.isCancel(ok) || !ok) {
9959
+ p29.cancel("Operation cancelled.");
9960
+ process28.exit(0);
9961
+ }
9962
+ }
9963
+ await runPattern(
9964
+ "destroy-shop",
9965
+ cmd.args,
9966
+ { destructive: true },
9967
+ {
9968
+ summary: "Destroyed the shop.",
9969
+ task: {
9970
+ title: "Destroying the shop",
9971
+ success: "Destroyed the shop",
9972
+ error: "Failed to destroy the shop"
9973
+ }
9974
+ }
9975
+ );
9976
+ }, "Failed to destroy the shop.")
9977
+ );
9978
+
9760
9979
  // src/commands/destroy.ts
9761
- var destroy = new Command49("destroy").description("destroy scaffolding, or a deployment").configureHelp(helpConfig).addCommand(form2).addCommand(schema2).addCommand(resource2).addCommand(scaffold2).addCommand(deployment);
9980
+ var destroy = new Command51("destroy").description("destroy scaffolding, or a deployment").configureHelp(helpConfig).addCommand(form2).addCommand(schema2).addCommand(resource2).addCommand(scaffold2).addCommand(shop2).addCommand(deployment);
9762
9981
 
9763
9982
  // src/commands/ui.ts
9764
- import { Command as Command55 } from "commander";
9983
+ import { Command as Command57 } from "commander";
9765
9984
 
9766
9985
  // src/commands/ui/add.ts
9767
- import { Command as Command50 } from "commander";
9986
+ import { Command as Command52 } from "commander";
9768
9987
  import * as p30 from "@clack/prompts";
9769
9988
  import { installComponents } from "@velastack/patterns";
9770
9989
 
@@ -9791,7 +10010,7 @@ var THEMES = [
9791
10010
  "violet",
9792
10011
  "yellow"
9793
10012
  ];
9794
- var NEXT_STEPS3 = [
10013
+ var NEXT_STEPS4 = [
9795
10014
  "Import a component with: import { Button } from '#lib/components/ui/button/index.js';",
9796
10015
  "Tweak styling in src/lib/components/ui/<component>/*.svelte.",
9797
10016
  `Run \`vela ui base <color>\` to change the palette (${BASE_COLORS.join(", ")}), or \`vela ui list\` to see what else is available.`
@@ -9802,7 +10021,7 @@ function uiAddReport(requested, outcome) {
9802
10021
  summary: installed2.length > 0 ? `Added ${installed2.length} UI component(s).` : `All ${new Set(requested).size} requested component(s) are already present.`,
9803
10022
  componentsAdded: installed2,
9804
10023
  packagesInstalled: packages,
9805
- nextSteps: [...NEXT_STEPS3]
10024
+ nextSteps: [...NEXT_STEPS4]
9806
10025
  };
9807
10026
  if (skipped.length > 0) {
9808
10027
  report5.sections = [{ label: "Already present (pass --overwrite to replace)", items: skipped }];
@@ -9814,7 +10033,7 @@ function uiAddReport(requested, outcome) {
9814
10033
  }
9815
10034
 
9816
10035
  // src/commands/ui/add.ts
9817
- var add = new Command50("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(
10036
+ var add = new Command52("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(
9818
10037
  (components, options) => runCommand(async () => {
9819
10038
  const { workspaceRootDir } = await getWorkspace();
9820
10039
  assertShadcn("vela ui add", workspaceRootDir);
@@ -9837,10 +10056,10 @@ var add = new Command50("add").description("add ui components (shadcn-svelte ite
9837
10056
  );
9838
10057
 
9839
10058
  // src/commands/ui/base.ts
9840
- import { Command as Command51 } from "commander";
10059
+ import { Command as Command53 } from "commander";
9841
10060
  import * as p31 from "@clack/prompts";
9842
10061
  import { applyBaseColor } from "@velastack/patterns";
9843
- var base = new Command51("base").description("change the base (gray) palette").argument("<color>", `base color to use (${BASE_COLORS.join(", ")})`).configureHelp(helpConfig).action(
10062
+ var base = new Command53("base").description("change the base (gray) palette").argument("<color>", `base color to use (${BASE_COLORS.join(", ")})`).configureHelp(helpConfig).action(
9844
10063
  (color) => runCommand(async () => {
9845
10064
  const { workspaceRootDir } = await getWorkspace();
9846
10065
  assertShadcn("vela ui base", workspaceRootDir);
@@ -9866,7 +10085,7 @@ var base = new Command51("base").description("change the base (gray) palette").a
9866
10085
  );
9867
10086
 
9868
10087
  // src/commands/ui/list.ts
9869
- import { Command as Command52 } from "commander";
10088
+ import { Command as Command54 } from "commander";
9870
10089
  import * as p32 from "@clack/prompts";
9871
10090
  import { listComponents } from "@velastack/patterns";
9872
10091
 
@@ -9898,7 +10117,7 @@ function uiListReport(result) {
9898
10117
  }
9899
10118
 
9900
10119
  // src/commands/ui/list.ts
9901
- var list = new Command52("list").description("list installed ui components, vela components and the style registry").option("--json", "print the result as JSON", false).configureHelp(helpConfig).action(
10120
+ var list = new Command54("list").description("list installed ui components, vela components and the style registry").option("--json", "print the result as JSON", false).configureHelp(helpConfig).action(
9902
10121
  (options) => runCommand(async () => {
9903
10122
  const { workspaceRootDir } = await getWorkspace();
9904
10123
  assertShadcn("vela ui list", workspaceRootDir);
@@ -9926,7 +10145,7 @@ Registry components are not listed.`);
9926
10145
  );
9927
10146
 
9928
10147
  // src/commands/ui/style.ts
9929
- import { Command as Command53 } from "commander";
10148
+ import { Command as Command55 } from "commander";
9930
10149
  import * as p33 from "@clack/prompts";
9931
10150
  import { switchStyle } from "@velastack/patterns";
9932
10151
 
@@ -9953,7 +10172,7 @@ function uiStyleReport(result) {
9953
10172
  }
9954
10173
 
9955
10174
  // src/commands/ui/style.ts
9956
- var style = new Command53("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(
10175
+ var style = new Command55("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(
9957
10176
  (name, options) => runCommand(async () => {
9958
10177
  const { workspaceRootDir } = await getWorkspace();
9959
10178
  assertShadcn("vela ui style", workspaceRootDir);
@@ -10007,10 +10226,10 @@ ${components.map((c) => `- ${c}`).join("\n")}`
10007
10226
  );
10008
10227
 
10009
10228
  // src/commands/ui/theme.ts
10010
- import { Command as Command54 } from "commander";
10229
+ import { Command as Command56 } from "commander";
10011
10230
  import * as p34 from "@clack/prompts";
10012
10231
  import { applyTheme } from "@velastack/patterns";
10013
- var theme = new Command54("theme").description("change the accent color, keeping the base palette").argument("<accent>", `accent to use (${THEMES.join(", ")})`).configureHelp(helpConfig).action(
10232
+ var theme = new Command56("theme").description("change the accent color, keeping the base palette").argument("<accent>", `accent to use (${THEMES.join(", ")})`).configureHelp(helpConfig).action(
10014
10233
  (accent) => runCommand(async () => {
10015
10234
  const { workspaceRootDir } = await getWorkspace();
10016
10235
  assertShadcn("vela ui theme", workspaceRootDir);
@@ -10036,20 +10255,20 @@ var theme = new Command54("theme").description("change the accent color, keeping
10036
10255
  );
10037
10256
 
10038
10257
  // src/commands/ui.ts
10039
- var ui = new Command55("ui").description("generate ui components").configureHelp(helpConfig).addCommand(add).addCommand(list).addCommand(style).addCommand(base).addCommand(theme);
10258
+ var ui = new Command57("ui").description("generate ui components").configureHelp(helpConfig).addCommand(add).addCommand(list).addCommand(style).addCommand(base).addCommand(theme);
10040
10259
 
10041
10260
  // src/commands/legal.ts
10042
- import { Command as Command58 } from "commander";
10261
+ import { Command as Command60 } from "commander";
10043
10262
 
10044
10263
  // src/commands/legal/terms.ts
10045
- import path39 from "node:path";
10046
- import { Command as Command56 } from "commander";
10264
+ import path41 from "node:path";
10265
+ import { Command as Command58 } from "commander";
10047
10266
  import * as p36 from "@clack/prompts";
10048
10267
 
10049
10268
  // src/commands/legal/shared.ts
10050
10269
  import process29 from "node:process";
10051
- import fs39 from "node:fs";
10052
- import path38 from "node:path";
10270
+ import fs41 from "node:fs";
10271
+ import path40 from "node:path";
10053
10272
  import * as p35 from "@clack/prompts";
10054
10273
  function siteFields(site) {
10055
10274
  const url = site?.url && !isLocalUrl(site.url) ? site.url : void 0;
@@ -10331,16 +10550,16 @@ function writeLegalPage(root, dir, page) {
10331
10550
 
10332
10551
  ${html}`;
10333
10552
  }
10334
- const pagePath = path38.join(root, dir, "+page.svelte");
10335
- fs39.mkdirSync(path38.dirname(pagePath), { recursive: true });
10336
- fs39.writeFileSync(pagePath, html);
10553
+ const pagePath = path40.join(root, dir, "+page.svelte");
10554
+ fs41.mkdirSync(path40.dirname(pagePath), { recursive: true });
10555
+ fs41.writeFileSync(pagePath, html);
10337
10556
  const written = [pagePath];
10338
10557
  if (metaTags) {
10339
- const loaderPath = path38.join(root, dir, "+page.ts");
10340
- fs39.writeFileSync(loaderPath, pageMetaTagsLoader(page.title, page.description));
10558
+ const loaderPath = path40.join(root, dir, "+page.ts");
10559
+ fs41.writeFileSync(loaderPath, pageMetaTagsLoader(page.title, page.description));
10341
10560
  written.push(loaderPath);
10342
10561
  }
10343
- return written.map((file) => path38.relative(root, file));
10562
+ return written.map((file) => path40.relative(root, file));
10344
10563
  }
10345
10564
 
10346
10565
  // src/commands/legal/terms.ts
@@ -10737,7 +10956,7 @@ async function termsAction() {
10737
10956
  });
10738
10957
  const [relativeTermsPage, ...rest] = writeLegalPage(
10739
10958
  workspaceRootDir,
10740
- path39.join(publicRoutesDir, LEGAL_DIR, "terms"),
10959
+ path41.join(publicRoutesDir, LEGAL_DIR, "terms"),
10741
10960
  {
10742
10961
  html,
10743
10962
  title: "Terms of Service",
@@ -10754,11 +10973,11 @@ async function termsAction() {
10754
10973
  ]
10755
10974
  });
10756
10975
  }
10757
- var terms = new Command56("terms").description("generate placeholder terms and conditions").configureHelp(helpConfig).action(() => runCommand(termsAction, "Failed to generate terms and conditions."));
10976
+ var terms = new Command58("terms").description("generate placeholder terms and conditions").configureHelp(helpConfig).action(() => runCommand(termsAction, "Failed to generate terms and conditions."));
10758
10977
 
10759
10978
  // src/commands/legal/privacy.ts
10760
- import path40 from "node:path";
10761
- import { Command as Command57 } from "commander";
10979
+ import path42 from "node:path";
10980
+ import { Command as Command59 } from "commander";
10762
10981
  import * as p37 from "@clack/prompts";
10763
10982
  var mapLabels = {
10764
10983
  personalInfo: {
@@ -11473,7 +11692,7 @@ async function privacyAction() {
11473
11692
  });
11474
11693
  const [relativePrivacyPage, ...rest] = writeLegalPage(
11475
11694
  workspaceRootDir,
11476
- path40.join(publicRoutesDir, LEGAL_DIR, "privacy"),
11695
+ path42.join(publicRoutesDir, LEGAL_DIR, "privacy"),
11477
11696
  {
11478
11697
  html,
11479
11698
  title: "Privacy Policy",
@@ -11490,20 +11709,20 @@ async function privacyAction() {
11490
11709
  ]
11491
11710
  });
11492
11711
  }
11493
- var privacy = new Command57("privacy").description("generate placeholder privacy policy").configureHelp(helpConfig).action(() => runCommand(privacyAction, "Failed to generate privacy policy."));
11712
+ var privacy = new Command59("privacy").description("generate placeholder privacy policy").configureHelp(helpConfig).action(() => runCommand(privacyAction, "Failed to generate privacy policy."));
11494
11713
 
11495
11714
  // src/commands/legal.ts
11496
- var legal = new Command58("legal").description("generate placeholder legal documents").configureHelp(helpConfig).addCommand(terms).addCommand(privacy);
11715
+ var legal = new Command60("legal").description("generate placeholder legal documents").configureHelp(helpConfig).addCommand(terms).addCommand(privacy);
11497
11716
 
11498
11717
  // src/commands/fixtures.ts
11499
- import { Command as Command64 } from "commander";
11718
+ import { Command as Command66 } from "commander";
11500
11719
 
11501
11720
  // src/commands/fixtures/load.ts
11502
- import { Command as Command59 } from "commander";
11721
+ import { Command as Command61 } from "commander";
11503
11722
 
11504
11723
  // src/lib/data.ts
11505
- import fs40 from "node:fs";
11506
- import path41 from "node:path";
11724
+ import fs42 from "node:fs";
11725
+ import path43 from "node:path";
11507
11726
  import { ClientResponseError } from "pocketbase";
11508
11727
 
11509
11728
  // src/lib/collections.ts
@@ -11540,14 +11759,14 @@ function dependencyOrder(collections2, startingCollectionId) {
11540
11759
 
11541
11760
  // src/lib/data.ts
11542
11761
  function dataDir(cwd, kind) {
11543
- return path41.join(cwd, DATA_DIR, kind);
11762
+ return path43.join(cwd, DATA_DIR, kind);
11544
11763
  }
11545
11764
  function getDataFiles(cwd, kind) {
11546
11765
  const dir = dataDir(cwd, kind);
11547
- if (!fs40.existsSync(dir)) return [];
11548
- return fs40.readdirSync(dir).filter((file) => file.endsWith(".json")).sort((a, b) => a.localeCompare(b)).map((file) => ({
11766
+ if (!fs42.existsSync(dir)) return [];
11767
+ return fs42.readdirSync(dir).filter((file) => file.endsWith(".json")).sort((a, b) => a.localeCompare(b)).map((file) => ({
11549
11768
  collectionName: file.replace(/\.json$/i, "").replace(/^\d+[-_]?/, ""),
11550
- filePath: path41.join(dir, file)
11769
+ filePath: path43.join(dir, file)
11551
11770
  }));
11552
11771
  }
11553
11772
  function getSeedFiles(cwd) {
@@ -11557,7 +11776,7 @@ function getFixtureFiles(cwd) {
11557
11776
  return getDataFiles(cwd, "fixtures");
11558
11777
  }
11559
11778
  function readRecords(filePath) {
11560
- return JSON.parse(fs40.readFileSync(filePath, "utf8"));
11779
+ return JSON.parse(fs42.readFileSync(filePath, "utf8"));
11561
11780
  }
11562
11781
  function readSeedIds(cwd) {
11563
11782
  const ids = /* @__PURE__ */ new Map();
@@ -11594,7 +11813,7 @@ function describeError(e) {
11594
11813
  return e instanceof Error ? e.message : String(e);
11595
11814
  }
11596
11815
  function label(cwd, filePath, count) {
11597
- return `${path41.relative(cwd, filePath)} (${count} records)`;
11816
+ return `${path43.relative(cwd, filePath)} (${count} records)`;
11598
11817
  }
11599
11818
  async function createRecords(pb, kind, cwd, { collectionName, filePath }) {
11600
11819
  const records = readRecords(filePath);
@@ -11602,7 +11821,7 @@ async function createRecords(pb, kind, cwd, { collectionName, filePath }) {
11602
11821
  try {
11603
11822
  await pb.collection(collectionName).create(record);
11604
11823
  } catch (e) {
11605
- throw new DataLoadError(kind, path41.relative(cwd, filePath), index, e);
11824
+ throw new DataLoadError(kind, path43.relative(cwd, filePath), index, e);
11606
11825
  }
11607
11826
  }
11608
11827
  return records.length;
@@ -11689,7 +11908,7 @@ async function hasLoadedFixtures(pb) {
11689
11908
  }
11690
11909
 
11691
11910
  // src/commands/fixtures/load.ts
11692
- var load = new Command59("load").description("load fixtures into the database").configureHelp(helpConfig).action(
11911
+ var load = new Command61("load").description("load fixtures into the database").configureHelp(helpConfig).action(
11693
11912
  () => runCommand(async () => {
11694
11913
  const { workspaceRootDir } = await getWorkspace();
11695
11914
  let loaded = [];
@@ -11715,8 +11934,8 @@ var load = new Command59("load").description("load fixtures into the database").
11715
11934
  );
11716
11935
 
11717
11936
  // src/commands/fixtures/clear.ts
11718
- import { Command as Command60 } from "commander";
11719
- var clear = new Command60("clear").description("clear loaded fixtures").configureHelp(helpConfig).action(
11937
+ import { Command as Command62 } from "commander";
11938
+ var clear = new Command62("clear").description("clear loaded fixtures").configureHelp(helpConfig).action(
11720
11939
  () => runCommand(async () => {
11721
11940
  const { workspaceRootDir } = await getWorkspace();
11722
11941
  let cleared = [];
@@ -11745,8 +11964,8 @@ var clear = new Command60("clear").description("clear loaded fixtures").configur
11745
11964
  );
11746
11965
 
11747
11966
  // src/commands/fixtures/reset.ts
11748
- import { Command as Command61 } from "commander";
11749
- var reset = new Command61("reset").description("clear and reload fixtures").configureHelp(helpConfig).action(
11967
+ import { Command as Command63 } from "commander";
11968
+ var reset = new Command63("reset").description("clear and reload fixtures").configureHelp(helpConfig).action(
11750
11969
  () => runCommand(async () => {
11751
11970
  const { workspaceRootDir } = await getWorkspace();
11752
11971
  let cleared = [];
@@ -11776,9 +11995,9 @@ var reset = new Command61("reset").description("clear and reload fixtures").conf
11776
11995
  );
11777
11996
 
11778
11997
  // src/commands/fixtures/generate.ts
11779
- import fs41 from "node:fs";
11780
- import path42 from "node:path";
11781
- import { Command as Command62, InvalidArgumentError } from "commander";
11998
+ import fs43 from "node:fs";
11999
+ import path44 from "node:path";
12000
+ import { Command as Command64, InvalidArgumentError } from "commander";
11782
12001
  import * as p38 from "@clack/prompts";
11783
12002
  import { annotate } from "annotate-json-schema";
11784
12003
  import { createGenerator } from "json-schema-faker";
@@ -11814,9 +12033,9 @@ async function loadCollections(pb) {
11814
12033
  }
11815
12034
  async function generateFixtureFiles(pb, workspaceRootDir, opts) {
11816
12035
  const fixturesDir = dataDir(workspaceRootDir, "fixtures");
11817
- fs41.mkdirSync(fixturesDir, { recursive: true });
11818
- for (const file of fs41.readdirSync(fixturesDir)) {
11819
- if (file.endsWith(".json")) fs41.unlinkSync(path42.join(fixturesDir, file));
12036
+ fs43.mkdirSync(fixturesDir, { recursive: true });
12037
+ for (const file of fs43.readdirSync(fixturesDir)) {
12038
+ if (file.endsWith(".json")) fs43.unlinkSync(path44.join(fixturesDir, file));
11820
12039
  }
11821
12040
  if (opts.seed !== void 0) faker.seed(opts.seed);
11822
12041
  const generator = createGenerator({
@@ -11883,13 +12102,13 @@ async function generateFixtureFiles(pb, workspaceRootDir, opts) {
11883
12102
  items.push(record);
11884
12103
  }
11885
12104
  const filename = `${padZeros(fileIndex, 2)}-${collection.name}.json`;
11886
- fs41.writeFileSync(path42.join(fixturesDir, filename), JSON.stringify(items, null, 2));
11887
- writtenFiles.push(`${path42.join(DATA_DIR, "fixtures", filename)} (${items.length} records)`);
12105
+ fs43.writeFileSync(path44.join(fixturesDir, filename), JSON.stringify(items, null, 2));
12106
+ writtenFiles.push(`${path44.join(DATA_DIR, "fixtures", filename)} (${items.length} records)`);
11888
12107
  fileIndex++;
11889
12108
  }
11890
12109
  return { writtenFiles, warnings };
11891
12110
  }
11892
- var generate2 = new Command62("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(
12111
+ var generate2 = new Command64("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(
11893
12112
  (opts) => runCommand(async () => {
11894
12113
  const { workspaceRootDir } = await getWorkspace();
11895
12114
  const existing = getFixtureFiles(workspaceRootDir);
@@ -11942,7 +12161,7 @@ var generate2 = new Command62("generate").description("generate fixture data").o
11942
12161
  );
11943
12162
 
11944
12163
  // src/commands/fixtures/regen.ts
11945
- import { Command as Command63, InvalidArgumentError as InvalidArgumentError2 } from "commander";
12164
+ import { Command as Command65, InvalidArgumentError as InvalidArgumentError2 } from "commander";
11946
12165
  import * as p39 from "@clack/prompts";
11947
12166
  function parseCount2(value) {
11948
12167
  const n = parseInt(value, 10);
@@ -11958,7 +12177,7 @@ function parseSeed2(value) {
11958
12177
  }
11959
12178
  return n;
11960
12179
  }
11961
- var regen = new Command63("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(
12180
+ var regen = new Command65("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(
11962
12181
  (opts) => runCommand(async () => {
11963
12182
  const { workspaceRootDir } = await getWorkspace();
11964
12183
  let cleared = [];
@@ -11987,14 +12206,14 @@ var regen = new Command63("regen").description("clear the database, regenerate f
11987
12206
  );
11988
12207
 
11989
12208
  // src/commands/fixtures.ts
11990
- var fixtures = new Command64("fixtures").description("manage fixture data").configureHelp(helpConfig).addCommand(generate2).addCommand(load).addCommand(clear).addCommand(reset).addCommand(regen);
12209
+ var fixtures = new Command66("fixtures").description("manage fixture data").configureHelp(helpConfig).addCommand(generate2).addCommand(load).addCommand(clear).addCommand(reset).addCommand(regen);
11991
12210
 
11992
12211
  // src/commands/seeds.ts
11993
- import { Command as Command68 } from "commander";
12212
+ import { Command as Command70 } from "commander";
11994
12213
 
11995
12214
  // src/commands/seeds/load.ts
11996
- import { Command as Command65 } from "commander";
11997
- var load2 = new Command65("load").description("load seeds into the database").option("-f, --force", "load even if target collections already have records").configureHelp(helpConfig).action(
12215
+ import { Command as Command67 } from "commander";
12216
+ var load2 = new Command67("load").description("load seeds into the database").option("-f, --force", "load even if target collections already have records").configureHelp(helpConfig).action(
11998
12217
  (opts) => runCommand(async () => {
11999
12218
  const { workspaceRootDir } = await getWorkspace();
12000
12219
  const seedFiles = getSeedFiles(workspaceRootDir);
@@ -12031,9 +12250,9 @@ var load2 = new Command65("load").description("load seeds into the database").op
12031
12250
  );
12032
12251
 
12033
12252
  // src/commands/seeds/save.ts
12034
- import fs42 from "node:fs";
12035
- import path43 from "node:path";
12036
- import { Command as Command66 } from "commander";
12253
+ import fs44 from "node:fs";
12254
+ import path45 from "node:path";
12255
+ import { Command as Command68 } from "commander";
12037
12256
  var padZeros2 = (num, length) => num.toString().padStart(length, "0");
12038
12257
  function filterSystemFields(record, systemFieldNames) {
12039
12258
  const out = {};
@@ -12044,7 +12263,7 @@ function filterSystemFields(record, systemFieldNames) {
12044
12263
  }
12045
12264
  return out;
12046
12265
  }
12047
- var save = new Command66("save").description("save the current data as seeds").option("-f, --force", "overwrite existing seed files").configureHelp(helpConfig).action(
12266
+ var save = new Command68("save").description("save the current data as seeds").option("-f, --force", "overwrite existing seed files").configureHelp(helpConfig).action(
12048
12267
  (opts) => runCommand(async () => {
12049
12268
  const { workspaceRootDir } = await getWorkspace();
12050
12269
  const seedsPath = dataDir(workspaceRootDir, "seeds");
@@ -12052,10 +12271,10 @@ var save = new Command66("save").description("save the current data as seeds").o
12052
12271
  if (existing.length > 0 && !opts.force) {
12053
12272
  throw new Error("Existing seed files found in data/seeds. Pass --force to overwrite.");
12054
12273
  }
12055
- fs42.mkdirSync(seedsPath, { recursive: true });
12274
+ fs44.mkdirSync(seedsPath, { recursive: true });
12056
12275
  if (opts.force) {
12057
- for (const file of fs42.readdirSync(seedsPath)) {
12058
- if (file.endsWith(".json")) fs42.unlinkSync(path43.join(seedsPath, file));
12276
+ for (const file of fs44.readdirSync(seedsPath)) {
12277
+ if (file.endsWith(".json")) fs44.unlinkSync(path45.join(seedsPath, file));
12059
12278
  }
12060
12279
  }
12061
12280
  const saved = [];
@@ -12084,13 +12303,13 @@ var save = new Command66("save").description("save the current data as seeds").o
12084
12303
  const filtered = records.map(
12085
12304
  (r) => filterSystemFields(r, systemFieldNames)
12086
12305
  );
12087
- const relativeSeedPath = path43.join(
12306
+ const relativeSeedPath = path45.join(
12088
12307
  DATA_DIR,
12089
12308
  "seeds",
12090
12309
  `${padZeros2(count, 2)}-${collectionName}.json`
12091
12310
  );
12092
- const seedPath = path43.join(workspaceRootDir, relativeSeedPath);
12093
- fs42.writeFileSync(seedPath, JSON.stringify(filtered, null, 2));
12311
+ const seedPath = path45.join(workspaceRootDir, relativeSeedPath);
12312
+ fs44.writeFileSync(seedPath, JSON.stringify(filtered, null, 2));
12094
12313
  saved.push(`${relativeSeedPath} (${filtered.length} records)`);
12095
12314
  count++;
12096
12315
  }
@@ -12116,8 +12335,8 @@ var save = new Command66("save").description("save the current data as seeds").o
12116
12335
  );
12117
12336
 
12118
12337
  // src/commands/seeds/clear.ts
12119
- import { Command as Command67 } from "commander";
12120
- var clear2 = new Command67("clear").description("clear seeded records").configureHelp(helpConfig).action(
12338
+ import { Command as Command69 } from "commander";
12339
+ var clear2 = new Command69("clear").description("clear seeded records").configureHelp(helpConfig).action(
12121
12340
  () => runCommand(async () => {
12122
12341
  const { workspaceRootDir } = await getWorkspace();
12123
12342
  const seedFiles = getSeedFiles(workspaceRootDir);
@@ -12148,13 +12367,13 @@ var clear2 = new Command67("clear").description("clear seeded records").configur
12148
12367
  );
12149
12368
 
12150
12369
  // src/commands/seeds.ts
12151
- var seeds = new Command68("seeds").description("manage seed data").configureHelp(helpConfig).addCommand(load2).addCommand(save).addCommand(clear2);
12370
+ var seeds = new Command70("seeds").description("manage seed data").configureHelp(helpConfig).addCommand(load2).addCommand(save).addCommand(clear2);
12152
12371
 
12153
12372
  // src/commands/signup.ts
12154
- import { Command as Command69 } from "commander";
12373
+ import { Command as Command71 } from "commander";
12155
12374
  import * as p40 from "@clack/prompts";
12156
12375
  import makeFetchCookie2 from "fetch-cookie";
12157
- var signup = new Command69("signup").description("signup to velastack.dev").configureHelp(helpConfig).action(
12376
+ var signup = new Command71("signup").description("signup to velastack.dev").configureHelp(helpConfig).action(
12158
12377
  () => runCommand(async () => {
12159
12378
  const { email: email2, password: password8, passwordConfirm } = await p40.group({
12160
12379
  email: () => p40.text({ message: "Email" }),
@@ -12189,9 +12408,9 @@ var signup = new Command69("signup").description("signup to velastack.dev").conf
12189
12408
  );
12190
12409
 
12191
12410
  // src/commands/logout.ts
12192
- import { Command as Command70 } from "commander";
12411
+ import { Command as Command72 } from "commander";
12193
12412
  import * as p41 from "@clack/prompts";
12194
- var logout = new Command70("logout").alias("signout").description("logout from velastack.dev").configureHelp(helpConfig).action(
12413
+ var logout = new Command72("logout").alias("signout").description("logout from velastack.dev").configureHelp(helpConfig).action(
12195
12414
  () => runCommand(() => {
12196
12415
  if (!readConfig()) {
12197
12416
  p41.log.info("Not logged in");
@@ -12203,9 +12422,9 @@ var logout = new Command70("logout").alias("signout").description("logout from v
12203
12422
  );
12204
12423
 
12205
12424
  // src/commands/whoami.ts
12206
- import { Command as Command71 } from "commander";
12425
+ import { Command as Command73 } from "commander";
12207
12426
  import * as p42 from "@clack/prompts";
12208
- var whoami = new Command71("whoami").description("show the current user").configureHelp(helpConfig).action(
12427
+ var whoami = new Command73("whoami").description("show the current user").configureHelp(helpConfig).action(
12209
12428
  () => runCommand(async () => {
12210
12429
  const apiKey = readConfig()?.apiKey;
12211
12430
  if (!apiKey) {
@@ -12222,13 +12441,13 @@ var whoami = new Command71("whoami").description("show the current user").config
12222
12441
  );
12223
12442
 
12224
12443
  // src/commands/migrate.ts
12225
- import { Command as Command78 } from "commander";
12444
+ import { Command as Command80 } from "commander";
12226
12445
 
12227
12446
  // src/commands/migrate/up.ts
12228
- import { Command as Command72 } from "commander";
12447
+ import { Command as Command74 } from "commander";
12229
12448
 
12230
12449
  // src/lib/migrate.ts
12231
- import path44 from "node:path";
12450
+ import path46 from "node:path";
12232
12451
  import process30 from "node:process";
12233
12452
  import { x as x3 } from "tinyexec";
12234
12453
  function migrateRoot() {
@@ -12242,9 +12461,9 @@ async function runPocketbaseMigrate(args) {
12242
12461
  binaryPath,
12243
12462
  [
12244
12463
  "--dir",
12245
- path44.join(cwd, DATA_DIR),
12464
+ path46.join(cwd, DATA_DIR),
12246
12465
  "--migrationsDir",
12247
- path44.join(cwd, MIGRATIONS_DIR),
12466
+ path46.join(cwd, MIGRATIONS_DIR),
12248
12467
  "migrate",
12249
12468
  ...args
12250
12469
  ],
@@ -12267,10 +12486,10 @@ async function runMigrateUp() {
12267
12486
  ]
12268
12487
  });
12269
12488
  }
12270
- var up = new Command72("up").description("apply all pending migrations").configureHelp(helpConfig).action(() => runCommand(runMigrateUp, "Failed to run migrations."));
12489
+ var up = new Command74("up").description("apply all pending migrations").configureHelp(helpConfig).action(() => runCommand(runMigrateUp, "Failed to run migrations."));
12271
12490
 
12272
12491
  // src/commands/migrate/down.ts
12273
- import { Command as Command73, InvalidArgumentError as InvalidArgumentError3 } from "commander";
12492
+ import { Command as Command75, InvalidArgumentError as InvalidArgumentError3 } from "commander";
12274
12493
  function parseSteps(value) {
12275
12494
  const n = parseInt(value, 10);
12276
12495
  if (!Number.isFinite(n) || n <= 0) {
@@ -12278,7 +12497,7 @@ function parseSteps(value) {
12278
12497
  }
12279
12498
  return n;
12280
12499
  }
12281
- var down = new Command73("down").alias("rollback").description("revert the last N applied migrations").argument("[number]", "how many migrations to revert", parseSteps, 1).configureHelp(helpConfig).action(
12500
+ var down = new Command75("down").alias("rollback").description("revert the last N applied migrations").argument("[number]", "how many migrations to revert", parseSteps, 1).configureHelp(helpConfig).action(
12282
12501
  (n) => runCommand(async () => {
12283
12502
  await runPocketbaseMigrate(["down", String(n)]);
12284
12503
  reportResult({
@@ -12292,10 +12511,10 @@ var down = new Command73("down").alias("rollback").description("revert the last
12292
12511
  );
12293
12512
 
12294
12513
  // src/commands/migrate/create.ts
12295
- import fs43 from "node:fs";
12296
- import path45 from "node:path";
12297
- import { Command as Command74 } from "commander";
12298
- var create2 = new Command74("create").alias("new").description("create a new blank migration").argument("<name>", "migration name (snake_case)").configureHelp(helpConfig).action(
12514
+ import fs45 from "node:fs";
12515
+ import path47 from "node:path";
12516
+ import { Command as Command76 } from "commander";
12517
+ var create2 = new Command76("create").alias("new").description("create a new blank migration").argument("<name>", "migration name (snake_case)").configureHelp(helpConfig).action(
12299
12518
  (name) => runCommand(async () => {
12300
12519
  const cwd = migrateRoot();
12301
12520
  const before = listMigrationFiles(cwd);
@@ -12304,7 +12523,7 @@ var create2 = new Command74("create").alias("new").description("create a new bla
12304
12523
  const added = [...after].filter((f) => !before.has(f));
12305
12524
  reportResult({
12306
12525
  summary: `Created blank migration ${name}.`,
12307
- filesCreated: added.map((f) => path45.join(MIGRATIONS_DIR, f)),
12526
+ filesCreated: added.map((f) => path47.join(MIGRATIONS_DIR, f)),
12308
12527
  nextSteps: [
12309
12528
  `Open the new file in ${MIGRATIONS_DIR}/ and fill in the up/down handlers.`,
12310
12529
  "Run `vela migrate up` to apply the migration once the handlers are written."
@@ -12313,16 +12532,16 @@ var create2 = new Command74("create").alias("new").description("create a new bla
12313
12532
  }, "Failed to create migration.")
12314
12533
  );
12315
12534
  function listMigrationFiles(cwd) {
12316
- const dir = path45.join(cwd, MIGRATIONS_DIR);
12317
- if (!fs43.existsSync(dir)) return /* @__PURE__ */ new Set();
12318
- return new Set(fs43.readdirSync(dir).filter((f) => /\.[jt]s$/.test(f)));
12535
+ const dir = path47.join(cwd, MIGRATIONS_DIR);
12536
+ if (!fs45.existsSync(dir)) return /* @__PURE__ */ new Set();
12537
+ return new Set(fs45.readdirSync(dir).filter((f) => /\.[jt]s$/.test(f)));
12319
12538
  }
12320
12539
 
12321
12540
  // src/commands/migrate/collections.ts
12322
- import fs44 from "node:fs";
12323
- import path46 from "node:path";
12324
- import { Command as Command75 } from "commander";
12325
- var collections = new Command75("collections").alias("snapshot").description("snapshot local collections into a new migration").configureHelp(helpConfig).action(
12541
+ import fs46 from "node:fs";
12542
+ import path48 from "node:path";
12543
+ import { Command as Command77 } from "commander";
12544
+ var collections = new Command77("collections").alias("snapshot").description("snapshot local collections into a new migration").configureHelp(helpConfig).action(
12326
12545
  () => runCommand(async () => {
12327
12546
  const cwd = migrateRoot();
12328
12547
  const before = listMigrationFiles2(cwd);
@@ -12337,7 +12556,7 @@ var collections = new Command75("collections").alias("snapshot").description("sn
12337
12556
  }
12338
12557
  reportResult({
12339
12558
  summary: "Snapshotted local collections into a new migration.",
12340
- filesCreated: added.map((f) => path46.join(MIGRATIONS_DIR, f)),
12559
+ filesCreated: added.map((f) => path48.join(MIGRATIONS_DIR, f)),
12341
12560
  nextSteps: [
12342
12561
  `Review the generated snapshot in ${MIGRATIONS_DIR}/.`,
12343
12562
  "Commit the snapshot so teammates pick up the new schema.",
@@ -12347,14 +12566,14 @@ var collections = new Command75("collections").alias("snapshot").description("sn
12347
12566
  }, "Failed to snapshot collections.")
12348
12567
  );
12349
12568
  function listMigrationFiles2(cwd) {
12350
- const dir = path46.join(cwd, MIGRATIONS_DIR);
12351
- if (!fs44.existsSync(dir)) return /* @__PURE__ */ new Set();
12352
- return new Set(fs44.readdirSync(dir).filter((f) => /\.[jt]s$/.test(f)));
12569
+ const dir = path48.join(cwd, MIGRATIONS_DIR);
12570
+ if (!fs46.existsSync(dir)) return /* @__PURE__ */ new Set();
12571
+ return new Set(fs46.readdirSync(dir).filter((f) => /\.[jt]s$/.test(f)));
12353
12572
  }
12354
12573
 
12355
12574
  // src/commands/migrate/history-sync.ts
12356
- import { Command as Command76 } from "commander";
12357
- var historySync = new Command76("history-sync").description("drop _migrations rows whose files no longer exist").configureHelp(helpConfig).action(
12575
+ import { Command as Command78 } from "commander";
12576
+ var historySync = new Command78("history-sync").description("drop _migrations rows whose files no longer exist").configureHelp(helpConfig).action(
12358
12577
  () => runCommand(async () => {
12359
12578
  await runPocketbaseMigrate(["history-sync"]);
12360
12579
  reportResult({
@@ -12365,14 +12584,14 @@ var historySync = new Command76("history-sync").description("drop _migrations ro
12365
12584
  );
12366
12585
 
12367
12586
  // src/commands/migrate/sveltekit-3.ts
12368
- import path47 from "node:path";
12587
+ import path49 from "node:path";
12369
12588
  import process31 from "node:process";
12370
- import { Command as Command77 } from "commander";
12589
+ import { Command as Command79 } from "commander";
12371
12590
  import * as p43 from "@clack/prompts";
12372
12591
  import pc13 from "picocolors";
12373
- var sveltekit3 = new Command77("sveltekit-3").description("upgrade a SvelteKit 2 project to SvelteKit 3 (sv migrate, then the vela steps)").option("--cwd <path>", "the project to migrate (default: the current project)").option("--no-install", "skip installing dependencies").option("--force", "run even when the git working tree has uncommitted changes").option("--skip-sv", "only run the vela steps (sv has already been run)").configureHelp(helpConfig).action(
12592
+ var sveltekit3 = new Command79("sveltekit-3").description("upgrade a SvelteKit 2 project to SvelteKit 3 (sv migrate, then the vela steps)").option("--cwd <path>", "the project to migrate (default: the current project)").option("--no-install", "skip installing dependencies").option("--force", "run even when the git working tree has uncommitted changes").option("--skip-sv", "only run the vela steps (sv has already been run)").configureHelp(helpConfig).action(
12374
12593
  (options) => runCommand(async () => {
12375
- const root = options.cwd ? path47.resolve(options.cwd) : findWorkspaceRoot() ?? process31.cwd();
12594
+ const root = options.cwd ? path49.resolve(options.cwd) : findWorkspaceRoot() ?? process31.cwd();
12376
12595
  p43.intro(pc13.bgCyan(pc13.black(" vela migrate sveltekit-3 ")));
12377
12596
  const result = await runKit3Migration(root, {
12378
12597
  install: options.install,
@@ -12389,7 +12608,7 @@ function printReport(root, result) {
12389
12608
  sections.push({ label: "Build output removed first", items: result.sv.cleared });
12390
12609
  }
12391
12610
  for (const fixup2 of changed) sections.push({ label: fixup2.name, items: fixup2.details });
12392
- const summary = result.mode === "repair" ? changed.length > 0 ? "Already on SvelteKit 3; brought the vela setup up to date." : "Already on SvelteKit 3; nothing left to change." : `Migrated ${path47.basename(root)} to SvelteKit 3.`;
12611
+ const summary = result.mode === "repair" ? changed.length > 0 ? "Already on SvelteKit 3; brought the vela setup up to date." : "Already on SvelteKit 3; nothing left to change." : `Migrated ${path49.basename(root)} to SvelteKit 3.`;
12393
12612
  reportResult({ summary, sections });
12394
12613
  const tasks = result.tasks;
12395
12614
  if (tasks && (tasks.sections.length > 0 || tasks.markerComments > 0)) {
@@ -12444,14 +12663,14 @@ function nextStepsFor(result) {
12444
12663
  }
12445
12664
 
12446
12665
  // src/commands/migrate.ts
12447
- var migrate = new Command78("migrate").description("manage database migrations (and `migrate sveltekit-3` to upgrade SvelteKit)").configureHelp(helpConfig).action(() => runCommand(runMigrateUp, "Failed to run migrations.")).addCommand(up).addCommand(down).addCommand(create2).addCommand(collections).addCommand(historySync).addCommand(sveltekit3);
12666
+ var migrate = new Command80("migrate").description("manage database migrations (and `migrate sveltekit-3` to upgrade SvelteKit)").configureHelp(helpConfig).action(() => runCommand(runMigrateUp, "Failed to run migrations.")).addCommand(up).addCommand(down).addCommand(create2).addCommand(collections).addCommand(historySync).addCommand(sveltekit3);
12448
12667
 
12449
12668
  // src/commands/dev.ts
12450
- import fs45 from "node:fs";
12451
- import path49 from "node:path";
12669
+ import fs47 from "node:fs";
12670
+ import path51 from "node:path";
12452
12671
  import process33 from "node:process";
12453
12672
  import { performance } from "node:perf_hooks";
12454
- import { Command as Command79, InvalidArgumentError as InvalidArgumentError4 } from "commander";
12673
+ import { Command as Command81, InvalidArgumentError as InvalidArgumentError4 } from "commander";
12455
12674
  import pc15 from "picocolors";
12456
12675
  import PocketBase5 from "pocketbase";
12457
12676
 
@@ -12480,7 +12699,7 @@ function createPocketbaseLogFilter() {
12480
12699
  }
12481
12700
 
12482
12701
  // src/lib/vite.ts
12483
- import path48 from "node:path";
12702
+ import path50 from "node:path";
12484
12703
  import process32 from "node:process";
12485
12704
  import { createRequire as createRequire4 } from "node:module";
12486
12705
  import { pathToFileURL } from "node:url";
@@ -12500,7 +12719,7 @@ function viteVersionError(version) {
12500
12719
  }
12501
12720
  function resolveProjectVite(cwd) {
12502
12721
  try {
12503
- return createRequire4(path48.join(cwd, "package.json")).resolve("vite");
12722
+ return createRequire4(path50.join(cwd, "package.json")).resolve("vite");
12504
12723
  } catch {
12505
12724
  return null;
12506
12725
  }
@@ -12524,14 +12743,14 @@ function parsePort(value) {
12524
12743
  }
12525
12744
  return port;
12526
12745
  }
12527
- var dev = new Command79("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").option("--all-sql", "also print the auth lookup PocketBase runs on every request").configureHelp(helpConfig).action(async (options) => {
12746
+ var dev = new Command81("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").option("--all-sql", "also print the auth lookup PocketBase runs on every request").configureHelp(helpConfig).action(async (options) => {
12528
12747
  const cwd = process33.cwd();
12529
12748
  warnIfKit2(findWorkspaceRoot(cwd) ?? cwd, (m) => console.warn(pc15.yellow(`\u25B2 ${m}`)));
12530
12749
  process33.env.VELA_DATA_DIR ??= localDataDir(cwd);
12531
12750
  const startTime = performance.now();
12532
12751
  const { createServer, resolveConfig, version } = await loadVite(cwd);
12533
- const viteMetadataDir = path49.join(cwd, "node_modules", ".vite");
12534
- const viteMetadataFile = path49.join(viteMetadataDir, "_pocketbase_metadata.json");
12752
+ const viteMetadataDir = path51.join(cwd, "node_modules", ".vite");
12753
+ const viteMetadataFile = path51.join(viteMetadataDir, "_pocketbase_metadata.json");
12535
12754
  const serverOptions = {};
12536
12755
  if (options.open !== void 0) serverOptions.open = options.open;
12537
12756
  if (options.host !== void 0) serverOptions.host = options.host;
@@ -12547,7 +12766,7 @@ var dev = new Command79("dev").description("start the development server").optio
12547
12766
  const needsStart = backend3 && !process33.env.POCKETBASE_URL;
12548
12767
  const cleanup = () => {
12549
12768
  if (pbProc?.pid) pbProc.kill();
12550
- if (fs45.existsSync(viteMetadataFile)) fs45.rmSync(viteMetadataFile);
12769
+ if (fs47.existsSync(viteMetadataFile)) fs47.rmSync(viteMetadataFile);
12551
12770
  };
12552
12771
  if (needsStart) {
12553
12772
  const resolved = await resolveConfig(inlineConfig, "serve");
@@ -12565,11 +12784,11 @@ var dev = new Command79("dev").description("start the development server").optio
12565
12784
  )
12566
12785
  );
12567
12786
  }
12568
- const dataDir2 = path49.join(cwd, DATA_DIR);
12787
+ const dataDir2 = path51.join(cwd, DATA_DIR);
12569
12788
  const started = await startPocketbaseServe({
12570
12789
  dataDir: dataDir2,
12571
12790
  migrationsDir: MIGRATIONS_DIR,
12572
- hooksDir: path49.join(dataDir2, "hooks"),
12791
+ hooksDir: path51.join(dataDir2, "hooks"),
12573
12792
  dev: true,
12574
12793
  stdio: "pipe",
12575
12794
  env: {
@@ -12591,8 +12810,8 @@ var dev = new Command79("dev").description("start the development server").optio
12591
12810
  if (!backend3) return;
12592
12811
  const { address, port: vitePort } = server.httpServer.address();
12593
12812
  const viteHost = address === "::1" ? "localhost" : address;
12594
- await fs45.promises.mkdir(viteMetadataDir, { recursive: true });
12595
- await fs45.promises.writeFile(
12813
+ await fs47.promises.mkdir(viteMetadataDir, { recursive: true });
12814
+ await fs47.promises.writeFile(
12596
12815
  viteMetadataFile,
12597
12816
  JSON.stringify({
12598
12817
  pocketbaseUrl: process33.env.POCKETBASE_URL,
@@ -12623,18 +12842,18 @@ var dev = new Command79("dev").description("start the development server").optio
12623
12842
  });
12624
12843
  async function startWatchingTypes(cwd, pb) {
12625
12844
  const { processTypes } = await import("@velastack/pocketbase-codegen");
12626
- const typesDir = path49.resolve(cwd, ".svelte-kit", "types");
12627
- const pocketbaseDir = path49.join(typesDir, "pocketbase");
12628
- const pocketbaseTypes = path49.join(pocketbaseDir, "$types.d.ts");
12845
+ const typesDir = path51.resolve(cwd, ".svelte-kit", "types");
12846
+ const pocketbaseDir = path51.join(typesDir, "pocketbase");
12847
+ const pocketbaseTypes = path51.join(pocketbaseDir, "$types.d.ts");
12629
12848
  const regenerate = () => processTypes(pb, typesDir).catch(() => {
12630
12849
  });
12631
12850
  await regenerate();
12632
12851
  void (async () => {
12633
12852
  for (; ; ) {
12634
12853
  try {
12635
- await fs45.promises.mkdir(pocketbaseDir, { recursive: true });
12636
- for await (const event of fs45.promises.watch(pocketbaseDir)) {
12637
- if (event.eventType === "rename" && event.filename === "$types.d.ts" && !fs45.existsSync(pocketbaseTypes)) {
12854
+ await fs47.promises.mkdir(pocketbaseDir, { recursive: true });
12855
+ for await (const event of fs47.promises.watch(pocketbaseDir)) {
12856
+ if (event.eventType === "rename" && event.filename === "$types.d.ts" && !fs47.existsSync(pocketbaseTypes)) {
12638
12857
  setTimeout(regenerate, 100);
12639
12858
  }
12640
12859
  }
@@ -12646,10 +12865,10 @@ async function startWatchingTypes(cwd, pb) {
12646
12865
  }
12647
12866
 
12648
12867
  // src/commands/build.ts
12649
- import fs46 from "node:fs";
12650
- import path50 from "node:path";
12868
+ import fs48 from "node:fs";
12869
+ import path52 from "node:path";
12651
12870
  import process35 from "node:process";
12652
- import { Command as Command80 } from "commander";
12871
+ import { Command as Command82 } from "commander";
12653
12872
  import * as p44 from "@clack/prompts";
12654
12873
  import pc16 from "picocolors";
12655
12874
  import { x as x4 } from "tinyexec";
@@ -12689,8 +12908,8 @@ function splitHosts(value) {
12689
12908
  }
12690
12909
 
12691
12910
  // src/commands/build.ts
12692
- var PRERENDERED_DIR = path50.join(".svelte-kit", "output", "prerendered");
12693
- var build = new Command80("build").description("build the app").configureHelp(helpConfig).option("-t, --target <target>", "which copy of the app to build for", PRODUCTION_TARGET).action(async (options) => {
12911
+ var PRERENDERED_DIR = path52.join(".svelte-kit", "output", "prerendered");
12912
+ var build = new Command82("build").description("build the app").configureHelp(helpConfig).option("-t, --target <target>", "which copy of the app to build for", PRODUCTION_TARGET).action(async (options) => {
12694
12913
  const cwd = process35.cwd();
12695
12914
  warnIfKit2(findWorkspaceRoot(cwd) ?? cwd, (m) => p44.log.warn(m));
12696
12915
  warnIfSsrExternalMissing(findWorkspaceRoot(cwd) ?? cwd);
@@ -12707,11 +12926,11 @@ var build = new Command80("build").description("build the app").configureHelp(he
12707
12926
  onTerminate(cleanup);
12708
12927
  if (needsStart) {
12709
12928
  await ensureSuperuser(cwd);
12710
- const dataDir2 = path50.join(cwd, DATA_DIR);
12929
+ const dataDir2 = path52.join(cwd, DATA_DIR);
12711
12930
  const started = await startPocketbaseServe({
12712
12931
  dataDir: dataDir2,
12713
12932
  migrationsDir: MIGRATIONS_DIR,
12714
- hooksDir: path50.join(dataDir2, "hooks"),
12933
+ hooksDir: path52.join(dataDir2, "hooks"),
12715
12934
  dev: true
12716
12935
  });
12717
12936
  pbProc = started.proc;
@@ -12758,8 +12977,8 @@ async function originForBuild(cwd, target) {
12758
12977
  }
12759
12978
  }
12760
12979
  function warnIfPrerendered(cwd) {
12761
- const dir = path50.join(cwd, PRERENDERED_DIR);
12762
- if (!fs46.existsSync(dir) || fs46.readdirSync(dir).length === 0) return;
12980
+ const dir = path52.join(cwd, PRERENDERED_DIR);
12981
+ if (!fs48.existsSync(dir) || fs48.readdirSync(dir).length === 0) return;
12763
12982
  if (process35.env.VELA_ORIGIN === "") {
12764
12983
  p44.log.warn(
12765
12984
  `Prerendered pages were built with no origin, on purpose: this app is served on
@@ -12782,17 +13001,17 @@ Set one with ${pc16.cyan("vela deploy --domain example.com")}, or pass ${pc16.cy
12782
13001
  }
12783
13002
 
12784
13003
  // src/commands/preview.ts
12785
- import fs47 from "node:fs";
12786
- import path51 from "node:path";
13004
+ import fs49 from "node:fs";
13005
+ import path53 from "node:path";
12787
13006
  import process36 from "node:process";
12788
- import { Command as Command81 } from "commander";
13007
+ import { Command as Command83 } from "commander";
12789
13008
  import * as p45 from "@clack/prompts";
12790
13009
  import pc17 from "picocolors";
12791
13010
  import { x as x5 } from "tinyexec";
12792
13011
  import { detect as detect8 } from "package-manager-detector";
12793
13012
  import { resolveCommand as resolveCommand6 } from "package-manager-detector/commands";
12794
- var ADAPTER_NODE_MODULE = path51.join("build", "adapter-node.js");
12795
- var preview = new Command81("preview").description("preview the built app").configureHelp(helpConfig).action(async () => {
13013
+ var ADAPTER_NODE_MODULE = path53.join("build", "adapter-node.js");
13014
+ var preview = new Command83("preview").description("preview the built app").configureHelp(helpConfig).action(async () => {
12796
13015
  const cwd = process36.cwd();
12797
13016
  process36.env.VELA_DATA_DIR ??= localDataDir(cwd);
12798
13017
  warnIfKit2(findWorkspaceRoot(cwd) ?? cwd, (m) => p45.log.warn(m));
@@ -12806,11 +13025,11 @@ var preview = new Command81("preview").description("preview the built app").conf
12806
13025
  };
12807
13026
  onTerminate(cleanup);
12808
13027
  if (needsStart) {
12809
- const dataDir2 = path51.join(cwd, DATA_DIR);
13028
+ const dataDir2 = path53.join(cwd, DATA_DIR);
12810
13029
  const started = await startPocketbaseServe({
12811
13030
  dataDir: dataDir2,
12812
13031
  migrationsDir: MIGRATIONS_DIR,
12813
- hooksDir: path51.join(dataDir2, "hooks"),
13032
+ hooksDir: path53.join(dataDir2, "hooks"),
12814
13033
  dev: true
12815
13034
  });
12816
13035
  pbProc = started.proc;
@@ -12844,7 +13063,7 @@ function bakedOrigin(source) {
12844
13063
  function warnIfOriginBaked(cwd) {
12845
13064
  let source;
12846
13065
  try {
12847
- source = fs47.readFileSync(path51.join(cwd, ADAPTER_NODE_MODULE), "utf8");
13066
+ source = fs49.readFileSync(path53.join(cwd, ADAPTER_NODE_MODULE), "utf8");
12848
13067
  } catch {
12849
13068
  return;
12850
13069
  }
@@ -12860,12 +13079,12 @@ set empty so no domain is baked in.`
12860
13079
  }
12861
13080
 
12862
13081
  // src/commands/sync.ts
12863
- import path52 from "node:path";
12864
- import { Command as Command82 } from "commander";
12865
- var sync = new Command82("sync").description("sync types from the database").configureHelp(helpConfig).action(
13082
+ import path54 from "node:path";
13083
+ import { Command as Command84 } from "commander";
13084
+ var sync = new Command84("sync").description("sync types from the database").configureHelp(helpConfig).action(
12866
13085
  () => runCommand(async () => {
12867
13086
  const { workspaceRootDir } = await getWorkspace();
12868
- const typesDir = path52.join(workspaceRootDir, ".svelte-kit", "types");
13087
+ const typesDir = path54.join(workspaceRootDir, ".svelte-kit", "types");
12869
13088
  const { processTypes } = await import("@velastack/pocketbase-codegen");
12870
13089
  await withPocketbase(workspaceRootDir, async (pb) => {
12871
13090
  await processTypes(pb, typesDir);
@@ -12875,7 +13094,7 @@ var sync = new Command82("sync").description("sync types from the database").con
12875
13094
  );
12876
13095
 
12877
13096
  // src/commands/provision.ts
12878
- import { Command as Command83 } from "commander";
13097
+ import { Command as Command85 } from "commander";
12879
13098
  import * as p46 from "@clack/prompts";
12880
13099
  import pc18 from "picocolors";
12881
13100
  import * as v9 from "valibot";
@@ -12890,7 +13109,7 @@ var OptionsSchema2 = v9.object({
12890
13109
  )
12891
13110
  });
12892
13111
  var provision = addSshOptions(
12893
- new Command83("provision").description("prepare a server to host vela apps").argument("<target>", "SSH target \u2014 an alias from ~/.ssh/config, or user@host").configureHelp(helpConfig)
13112
+ new Command85("provision").description("prepare a server to host vela apps").argument("<target>", "SSH target \u2014 an alias from ~/.ssh/config, or user@host").configureHelp(helpConfig)
12894
13113
  ).option("--pb-version <version>", "PocketBase version to install").option(
12895
13114
  "--node-major <version>",
12896
13115
  "Node.js major version to bring the server up to (match the one you build with)",
@@ -12936,10 +13155,10 @@ var provision = addSshOptions(
12936
13155
  );
12937
13156
 
12938
13157
  // src/commands/deploy.ts
12939
- import path56 from "node:path";
12940
- import fs51 from "node:fs";
13158
+ import path58 from "node:path";
13159
+ import fs53 from "node:fs";
12941
13160
  import process38 from "node:process";
12942
- import { Command as Command84, Option as Option2 } from "commander";
13161
+ import { Command as Command86, Option as Option2 } from "commander";
12943
13162
  import * as p48 from "@clack/prompts";
12944
13163
  import pc20 from "picocolors";
12945
13164
  import * as v10 from "valibot";
@@ -13055,12 +13274,12 @@ function reachedInstances(states, appId, layer) {
13055
13274
  }
13056
13275
 
13057
13276
  // src/lib/build-stack.ts
13058
- import fs49 from "node:fs";
13059
- import path54 from "node:path";
13277
+ import fs51 from "node:fs";
13278
+ import path56 from "node:path";
13060
13279
 
13061
13280
  // src/lib/static-env.ts
13062
- import fs48 from "node:fs";
13063
- import path53 from "node:path";
13281
+ import fs50 from "node:fs";
13282
+ import path55 from "node:path";
13064
13283
  import { ENV_DECL_CANDIDATES } from "@velastack/patterns";
13065
13284
  import { Node as Node5, Project as Project5, QuoteKind as QuoteKind3 } from "ts-morph";
13066
13285
  function staticEnv(root) {
@@ -13074,7 +13293,7 @@ function staticEnv(root) {
13074
13293
  };
13075
13294
  }
13076
13295
  const file = findEnvDecl(root);
13077
- const rel = file ? path53.relative(root, file).split(path53.sep).join("/") : ENV_DECL_CANDIDATES[0];
13296
+ const rel = file ? path55.relative(root, file).split(path55.sep).join("/") : ENV_DECL_CANDIDATES[0];
13078
13297
  return {
13079
13298
  names: file ? staticEnvDeclarations(file) : /* @__PURE__ */ new Set(),
13080
13299
  rule: "declarations",
@@ -13084,8 +13303,8 @@ function staticEnv(root) {
13084
13303
  }
13085
13304
  function findEnvDecl(root) {
13086
13305
  for (const rel of ENV_DECL_CANDIDATES) {
13087
- const abs = path53.join(root, rel);
13088
- if (fs48.existsSync(abs)) return abs;
13306
+ const abs = path55.join(root, rel);
13307
+ if (fs50.existsSync(abs)) return abs;
13089
13308
  }
13090
13309
  return null;
13091
13310
  }
@@ -13157,10 +13376,10 @@ var SOURCE_EXTENSIONS2 = /* @__PURE__ */ new Set([".ts", ".js", ".mts", ".mjs",
13157
13376
  var STATIC_IMPORT = /import\s*(?:type\s*)?\{([^}]*)\}\s*from\s*['"]\$env\/static\/(?:private|public)['"]/g;
13158
13377
  function staticEnvImports(root) {
13159
13378
  const names = /* @__PURE__ */ new Set();
13160
- const src = path53.join(root, "src");
13161
- if (!fs48.existsSync(src)) return names;
13379
+ const src = path55.join(root, "src");
13380
+ if (!fs50.existsSync(src)) return names;
13162
13381
  for (const file of sourceFiles2(src)) {
13163
- const content = fs48.readFileSync(file, "utf8");
13382
+ const content = fs50.readFileSync(file, "utf8");
13164
13383
  if (!content.includes("$env/static/")) continue;
13165
13384
  for (const match of content.matchAll(STATIC_IMPORT)) {
13166
13385
  for (const spec of match[1].split(",")) {
@@ -13172,11 +13391,11 @@ function staticEnvImports(root) {
13172
13391
  return names;
13173
13392
  }
13174
13393
  function* sourceFiles2(dir) {
13175
- for (const entry of fs48.readdirSync(dir, { withFileTypes: true })) {
13394
+ for (const entry of fs50.readdirSync(dir, { withFileTypes: true })) {
13176
13395
  if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
13177
- const full = path53.join(dir, entry.name);
13396
+ const full = path55.join(dir, entry.name);
13178
13397
  if (entry.isDirectory()) yield* sourceFiles2(full);
13179
- else if (SOURCE_EXTENSIONS2.has(path53.extname(entry.name))) yield full;
13398
+ else if (SOURCE_EXTENSIONS2.has(path55.extname(entry.name))) yield full;
13180
13399
  }
13181
13400
  }
13182
13401
 
@@ -13187,8 +13406,8 @@ var DevOnlyEnvError = class extends Error {
13187
13406
  function buildStack(root, input) {
13188
13407
  const env2 = { ...input.stack, ...input.derived };
13189
13408
  const blanked = [];
13190
- const file = path54.join(root, ".env");
13191
- const local = fs49.existsSync(file) ? readLocalEnvFile(file) : {};
13409
+ const file = path56.join(root, ".env");
13410
+ const local = fs51.existsSync(file) ? readLocalEnvFile(file) : {};
13192
13411
  for (const key of Object.keys(local)) {
13193
13412
  if (key in env2) continue;
13194
13413
  if (!input.tunnel && LOCAL_BUILD_KEYS.test(key)) continue;
@@ -13209,16 +13428,16 @@ The build would bake in your development value. Set ${baked.length === 1 ? "it"
13209
13428
  }
13210
13429
 
13211
13430
  // src/lib/env-nudge.ts
13212
- import fs50 from "node:fs";
13213
- import path55 from "node:path";
13431
+ import fs52 from "node:fs";
13432
+ import path57 from "node:path";
13214
13433
  import process37 from "node:process";
13215
13434
  import * as p47 from "@clack/prompts";
13216
13435
  import pc19 from "picocolors";
13217
13436
  var ENV_EXAMPLE = ".env.example";
13218
13437
  var SUPPLIED = /^(NODE_ENV|HOST|PORT|ORIGIN|PROTOCOL_HEADER|HOST_HEADER|ADDRESS_HEADER|XFF_DEPTH|PB_PORT|POCKETBASE_URL|POCKETBASE_SUPERUSER_EMAIL|POCKETBASE_SUPERUSER_PASSWORD|APP_NAME|VELA_)/;
13219
13438
  function missingFromExample(root, present) {
13220
- const file = path55.join(root, ENV_EXAMPLE);
13221
- if (!fs50.existsSync(file)) return [];
13439
+ const file = path57.join(root, ENV_EXAMPLE);
13440
+ if (!fs52.existsSync(file)) return [];
13222
13441
  const have = new Set(present);
13223
13442
  return Object.keys(readLocalEnvFile(file)).filter((key) => !have.has(key) && !SUPPLIED.test(key)).sort();
13224
13443
  }
@@ -13305,7 +13524,7 @@ var OptionsSchema3 = v10.object({
13305
13524
  });
13306
13525
  var deploy = addLockWaitOption(
13307
13526
  addTargetOptions(
13308
- new Command84("deploy").description("deploy the app").configureHelp(helpConfig),
13527
+ new Command86("deploy").description("deploy the app").configureHelp(helpConfig),
13309
13528
  "production"
13310
13529
  )
13311
13530
  ).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(
@@ -13567,12 +13786,12 @@ ${pc20.cyan(err.snippet)}` : err.message);
13567
13786
  current = detectAdapter(workspaceRootDir);
13568
13787
  } catch {
13569
13788
  }
13570
- const editable = current !== void 0 && !/^svelte\.config\./.test(path56.basename(current.file));
13789
+ const editable = current !== void 0 && !/^svelte\.config\./.test(path58.basename(current.file));
13571
13790
  if (current && editable && (current.kind === "auto" || current.kind === "none") && isInteractive()) {
13572
13791
  const has = current.kind === "auto" ? `is on ${ADAPTER_AUTO}` : "has no SvelteKit adapter configured";
13573
13792
  const confirmed = await p48.confirm({
13574
13793
  message: `This project ${has}, and vela deploy runs the app as a Node server.
13575
- Switch it to ${ADAPTER_NODE}? This edits ${path56.basename(current.file)} and package.json.`
13794
+ Switch it to ${ADAPTER_NODE}? This edits ${path58.basename(current.file)} and package.json.`
13576
13795
  });
13577
13796
  if (p48.isCancel(confirmed) || !confirmed) {
13578
13797
  p48.cancel("Nothing was changed, and nothing was deployed.");
@@ -13696,7 +13915,7 @@ async function uploadRelease(session, instance, release, entries) {
13696
13915
  }
13697
13916
  function isDirectory(target) {
13698
13917
  try {
13699
- return fs51.statSync(target).isDirectory();
13918
+ return fs53.statSync(target).isDirectory();
13700
13919
  } catch {
13701
13920
  return false;
13702
13921
  }
@@ -13737,12 +13956,12 @@ async function serverTimeOrLocal(session) {
13737
13956
  }
13738
13957
 
13739
13958
  // src/commands/link.ts
13740
- import path57 from "node:path";
13959
+ import path59 from "node:path";
13741
13960
  import process39 from "node:process";
13742
- import { Command as Command85 } from "commander";
13961
+ import { Command as Command87 } from "commander";
13743
13962
  import * as p49 from "@clack/prompts";
13744
13963
  var CREATE_NEW = "__new__";
13745
- var link = new Command85("link").description("link this project to a velastack.dev project").configureHelp(helpConfig).action(() => runCommand(linkProject, "Failed to link the project."));
13964
+ var link = new Command87("link").description("link this project to a velastack.dev project").configureHelp(helpConfig).action(() => runCommand(linkProject, "Failed to link the project."));
13746
13965
  async function linkProject() {
13747
13966
  const { workspaceRootDir } = await getWorkspace();
13748
13967
  const existing = readProjectConfig(workspaceRootDir);
@@ -13800,35 +14019,35 @@ async function promptProjectName(workspaceRootDir) {
13800
14019
  }
13801
14020
  function defaultProjectName2(workspaceRootDir) {
13802
14021
  try {
13803
- const pkg = readPackageJson(path57.join(workspaceRootDir, "package.json"));
14022
+ const pkg = readPackageJson(path59.join(workspaceRootDir, "package.json"));
13804
14023
  const name = pkg.name;
13805
14024
  if (typeof name === "string" && name.trim()) return name.trim();
13806
14025
  } catch {
13807
14026
  }
13808
- return path57.basename(workspaceRootDir);
14027
+ return path59.basename(workspaceRootDir);
13809
14028
  }
13810
14029
 
13811
14030
  // src/commands/env.ts
13812
- import { Command as Command91 } from "commander";
14031
+ import { Command as Command93 } from "commander";
13813
14032
 
13814
14033
  // src/commands/env/list.ts
13815
- import { Command as Command86 } from "commander";
14034
+ import { Command as Command88 } from "commander";
13816
14035
  import * as v12 from "valibot";
13817
14036
  import * as p52 from "@clack/prompts";
13818
14037
  import pc23 from "picocolors";
13819
14038
 
13820
14039
  // src/lib/local-env.ts
13821
- import fs52 from "node:fs";
14040
+ import fs54 from "node:fs";
13822
14041
  import * as p50 from "@clack/prompts";
13823
14042
  import pc21 from "picocolors";
13824
14043
  function readLocalEnv(envFile) {
13825
- if (!fs52.existsSync(envFile)) return {};
14044
+ if (!fs54.existsSync(envFile)) return {};
13826
14045
  return readLocalEnvFile(envFile);
13827
14046
  }
13828
14047
  function editLocalEnv(envFile, edit) {
13829
- const before = fs52.existsSync(envFile) ? fs52.readFileSync(envFile, "utf8") : "";
14048
+ const before = fs54.existsSync(envFile) ? fs54.readFileSync(envFile, "utf8") : "";
13830
14049
  const after = edit(before);
13831
- if (after !== before) fs52.writeFileSync(envFile, after);
14050
+ if (after !== before) fs54.writeFileSync(envFile, after);
13832
14051
  }
13833
14052
  function setLocalEnv(envFile, key, value) {
13834
14053
  editLocalEnv(envFile, (content) => upsertEnvVar(content, key, value));
@@ -14084,7 +14303,7 @@ var OptionsSchema5 = v12.object({
14084
14303
  var HIDDEN = "\u2022\u2022\u2022\u2022";
14085
14304
  var MAX_VALUE = 32;
14086
14305
  var envList = addEnvTargetOptions(
14087
- new Command86("list").description("list environment variables \u2014 every scope at once without -t").configureHelp(helpConfig)
14306
+ new Command88("list").description("list environment variables \u2014 every scope at once without -t").configureHelp(helpConfig)
14088
14307
  ).action(
14089
14308
  (raw) => runCommand(async () => {
14090
14309
  const options = parseOptions(OptionsSchema5, raw);
@@ -14244,17 +14463,17 @@ function matrixCell(key, columns, index, states) {
14244
14463
  return pc23.dim("\u2014");
14245
14464
  }
14246
14465
  var ANSI3 = /\u001b\[[0-9;]*m/g;
14247
- function plain(text19) {
14248
- return text19.replace(ANSI3, "");
14466
+ function plain(text18) {
14467
+ return text18.replace(ANSI3, "");
14249
14468
  }
14250
14469
 
14251
14470
  // src/commands/env/set.ts
14252
14471
  import process41 from "node:process";
14253
- import { Command as Command87 } from "commander";
14472
+ import { Command as Command89 } from "commander";
14254
14473
  import * as p53 from "@clack/prompts";
14255
14474
  import pc24 from "picocolors";
14256
14475
  var envSet = addEnvTargetOptions(
14257
- new Command87("set").description("set an environment variable \u2014 the value is prompted for, never an argument").argument("<key>", "variable name").option(
14476
+ new Command89("set").description("set an environment variable \u2014 the value is prompted for, never an argument").argument("<key>", "variable name").option(
14258
14477
  "--public",
14259
14478
  "readable back with `vela env list` and `vela env get`; PUBLIC_* keys are public regardless"
14260
14479
  ).configureHelp(helpConfig)
@@ -14312,11 +14531,11 @@ async function promptValue2(key, visibility) {
14312
14531
  }
14313
14532
 
14314
14533
  // src/commands/env/unset.ts
14315
- import { Command as Command88 } from "commander";
14534
+ import { Command as Command90 } from "commander";
14316
14535
  import * as p54 from "@clack/prompts";
14317
14536
  import pc25 from "picocolors";
14318
14537
  var envUnset = addEnvTargetOptions(
14319
- new Command88("unset").description("remove an environment variable").argument("<key>", "variable name").configureHelp(helpConfig)
14538
+ new Command90("unset").description("remove an environment variable").argument("<key>", "variable name").configureHelp(helpConfig)
14320
14539
  ).action(
14321
14540
  (key, raw) => runCommand(
14322
14541
  () => withEnvScope(
@@ -14357,14 +14576,14 @@ var envUnset = addEnvTargetOptions(
14357
14576
  );
14358
14577
 
14359
14578
  // src/commands/env/import.ts
14360
- import fs53 from "node:fs";
14361
- import path58 from "node:path";
14579
+ import fs55 from "node:fs";
14580
+ import path60 from "node:path";
14362
14581
  import process42 from "node:process";
14363
- import { Command as Command89 } from "commander";
14582
+ import { Command as Command91 } from "commander";
14364
14583
  import * as p55 from "@clack/prompts";
14365
14584
  import pc26 from "picocolors";
14366
14585
  var envImport = addEnvTargetOptions(
14367
- new Command89("import").description("merge a dotenv file into the environment").argument("<file>", "dotenv file to read").option("--public", "import as readable values; PUBLIC_* keys are public regardless").configureHelp(helpConfig)
14586
+ new Command91("import").description("merge a dotenv file into the environment").argument("<file>", "dotenv file to read").option("--public", "import as readable values; PUBLIC_* keys are public regardless").configureHelp(helpConfig)
14368
14587
  ).action(
14369
14588
  (file, raw) => runCommand(
14370
14589
  () => withEnvScope(
@@ -14429,10 +14648,10 @@ function report2(outcome, where) {
14429
14648
  p55.log.success(`${parts.join(", ")} variable(s) updated ${pc26.dim(`(${where})`)}`);
14430
14649
  }
14431
14650
  function resolve(file) {
14432
- return path58.resolve(process42.cwd(), file);
14651
+ return path60.resolve(process42.cwd(), file);
14433
14652
  }
14434
14653
  function read(resolved, shown) {
14435
- if (!fs53.existsSync(resolved)) throw new Error(`${shown} does not exist.`);
14654
+ if (!fs55.existsSync(resolved)) throw new Error(`${shown} does not exist.`);
14436
14655
  const incoming = readLocalEnvFile(resolved);
14437
14656
  if (Object.keys(incoming).length === 0) p55.log.info(`${shown} has no variables to import.`);
14438
14657
  return incoming;
@@ -14440,11 +14659,11 @@ function read(resolved, shown) {
14440
14659
 
14441
14660
  // src/commands/env/get.ts
14442
14661
  import process43 from "node:process";
14443
- import { Command as Command90 } from "commander";
14662
+ import { Command as Command92 } from "commander";
14444
14663
  import * as p56 from "@clack/prompts";
14445
14664
  import pc27 from "picocolors";
14446
14665
  var envGet = addEnvTargetOptions(
14447
- new Command90("get").description("print a public environment variable").argument("<key>", "variable name").configureHelp(helpConfig)
14666
+ new Command92("get").description("print a public environment variable").argument("<key>", "variable name").configureHelp(helpConfig)
14448
14667
  ).action(
14449
14668
  (key, raw) => runCommand(
14450
14669
  () => withEnvScope(
@@ -14492,14 +14711,14 @@ Set it again to change it: ${pc27.cyan(`vela env set ${key}`)}`
14492
14711
  }
14493
14712
 
14494
14713
  // src/commands/env.ts
14495
- var env = new Command91("env").description("manage environment variables, locally or on a target").configureHelp(helpConfig).addCommand(envList).addCommand(envGet).addCommand(envSet).addCommand(envUnset).addCommand(envImport);
14714
+ var env = new Command93("env").description("manage environment variables, locally or on a target").configureHelp(helpConfig).addCommand(envList).addCommand(envGet).addCommand(envSet).addCommand(envUnset).addCommand(envImport);
14496
14715
 
14497
14716
  // src/commands/status.ts
14498
- import { Command as Command92 } from "commander";
14717
+ import { Command as Command94 } from "commander";
14499
14718
  import * as p57 from "@clack/prompts";
14500
14719
  import pc28 from "picocolors";
14501
14720
  var status = addTargetOptions(
14502
- new Command92("status").description("show what is deployed").configureHelp(helpConfig),
14721
+ new Command94("status").description("show what is deployed").configureHelp(helpConfig),
14503
14722
  "production"
14504
14723
  ).option("--all", "show every app on the server, not just this project").option("--json", "print raw JSON").action(
14505
14724
  (raw) => runCommand(async () => {
@@ -14558,12 +14777,12 @@ function describe2(state) {
14558
14777
  }
14559
14778
 
14560
14779
  // src/commands/rollback.ts
14561
- import { Command as Command93 } from "commander";
14780
+ import { Command as Command95 } from "commander";
14562
14781
  import * as p58 from "@clack/prompts";
14563
14782
  import pc29 from "picocolors";
14564
14783
  var rollback = addLockWaitOption(
14565
14784
  addTargetOptions(
14566
- new Command93("rollback").description("put the previous release back").configureHelp(helpConfig),
14785
+ new Command95("rollback").description("put the previous release back").configureHelp(helpConfig),
14567
14786
  "production"
14568
14787
  )
14569
14788
  ).option("--to <release>", "roll back to a specific release instead of the previous one").action(
@@ -14602,7 +14821,7 @@ var rollback = addLockWaitOption(
14602
14821
  );
14603
14822
 
14604
14823
  // src/commands/logs.ts
14605
- import { Command as Command94 } from "commander";
14824
+ import { Command as Command96 } from "commander";
14606
14825
 
14607
14826
  // src/lib/remote-pocketbase.ts
14608
14827
  import PocketBase6 from "pocketbase";
@@ -14653,7 +14872,7 @@ async function withRemotePocketbase(session, instance, fn) {
14653
14872
 
14654
14873
  // src/commands/logs.ts
14655
14874
  var logs = addTargetOptions(
14656
- new Command94("logs").description("tail the logs of a deployed app").configureHelp(helpConfig),
14875
+ new Command96("logs").description("tail the logs of a deployed app").configureHelp(helpConfig),
14657
14876
  "production"
14658
14877
  ).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(
14659
14878
  (raw) => runCommand(async () => {
@@ -14688,16 +14907,16 @@ var logs = addTargetOptions(
14688
14907
  );
14689
14908
 
14690
14909
  // src/commands/admin.ts
14691
- import { Command as Command96 } from "commander";
14910
+ import { Command as Command98 } from "commander";
14692
14911
 
14693
14912
  // src/commands/admin/create.ts
14694
14913
  import process44 from "node:process";
14695
- import { Command as Command95 } from "commander";
14914
+ import { Command as Command97 } from "commander";
14696
14915
  import * as p59 from "@clack/prompts";
14697
14916
  import pc30 from "picocolors";
14698
14917
  var MIN_PASSWORD = 10;
14699
14918
  var adminCreate = addTargetOptions(
14700
- new Command95("create").description("create a login for the admin panel").argument("[email]", "email to sign in with \u2014 prompted for when omitted").configureHelp(helpConfig),
14919
+ new Command97("create").description("create a login for the admin panel").argument("[email]", "email to sign in with \u2014 prompted for when omitted").configureHelp(helpConfig),
14701
14920
  "local"
14702
14921
  ).action(
14703
14922
  (email2, raw) => runCommand(
@@ -14815,15 +15034,15 @@ async function promptPassword() {
14815
15034
  }
14816
15035
 
14817
15036
  // src/commands/admin.ts
14818
- var admin = new Command96("admin").description("manage admin panel logins").configureHelp(helpConfig).addCommand(adminCreate);
15037
+ var admin = new Command98("admin").description("manage admin panel logins").configureHelp(helpConfig).addCommand(adminCreate);
14819
15038
 
14820
15039
  // src/commands/backup.ts
14821
- import { Command as Command102 } from "commander";
15040
+ import { Command as Command104 } from "commander";
14822
15041
 
14823
15042
  // src/commands/backup/create.ts
14824
- import fs54 from "node:fs";
14825
- import path59 from "node:path";
14826
- import { Command as Command97 } from "commander";
15043
+ import fs56 from "node:fs";
15044
+ import path61 from "node:path";
15045
+ import { Command as Command99 } from "commander";
14827
15046
  import * as p60 from "@clack/prompts";
14828
15047
  import pc32 from "picocolors";
14829
15048
 
@@ -14972,7 +15191,7 @@ async function writeSchedule(pb, cron, maxKeep) {
14972
15191
  // src/commands/backup/create.ts
14973
15192
  var DEFAULT_BACKUP_DIR = "backups";
14974
15193
  var backupCreate = addTargetOptions(
14975
- new Command97("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),
15194
+ new Command99("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),
14976
15195
  "production"
14977
15196
  ).action(
14978
15197
  (name, raw) => runCommand(() => {
@@ -15036,12 +15255,12 @@ Your bucket's own versioning is what protects the uploaded files.`
15036
15255
  }, "Failed to create the backup.")
15037
15256
  );
15038
15257
  async function download(ctx, key, outputDir) {
15039
- const dir = path59.resolve(ctx.workspaceRootDir, outputDir);
15040
- fs54.mkdirSync(dir, { recursive: true });
15041
- const destination = path59.join(dir, key);
15258
+ const dir = path61.resolve(ctx.workspaceRootDir, outputDir);
15259
+ fs56.mkdirSync(dir, { recursive: true });
15260
+ const destination = path61.join(dir, key);
15042
15261
  if (!ctx.session) {
15043
- fs54.copyFileSync(path59.join(ctx.workspaceRootDir, "data", "backups", key), destination);
15044
- return path59.relative(ctx.workspaceRootDir, destination);
15262
+ fs56.copyFileSync(path61.join(ctx.workspaceRootDir, "data", "backups", key), destination);
15263
+ return path61.relative(ctx.workspaceRootDir, destination);
15045
15264
  }
15046
15265
  const spinner9 = p60.spinner();
15047
15266
  spinner9.start(`Downloading ${key}`);
@@ -15052,15 +15271,15 @@ async function download(ctx, key, outputDir) {
15052
15271
  throw error;
15053
15272
  }
15054
15273
  spinner9.stop(`Downloaded ${key}`);
15055
- return path59.relative(ctx.workspaceRootDir, destination);
15274
+ return path61.relative(ctx.workspaceRootDir, destination);
15056
15275
  }
15057
15276
 
15058
15277
  // src/commands/backup/list.ts
15059
- import { Command as Command98 } from "commander";
15278
+ import { Command as Command100 } from "commander";
15060
15279
  import * as p61 from "@clack/prompts";
15061
15280
  import pc33 from "picocolors";
15062
15281
  var backupList = addTargetOptions(
15063
- new Command98("list").description("list the backups on a target").configureHelp(helpConfig),
15282
+ new Command100("list").description("list the backups on a target").configureHelp(helpConfig),
15064
15283
  "production"
15065
15284
  ).action(
15066
15285
  (raw) => runCommand(
@@ -15086,13 +15305,13 @@ Take one with ${pc33.cyan("vela backup create")}.`
15086
15305
  );
15087
15306
 
15088
15307
  // src/commands/backup/download.ts
15089
- import fs55 from "node:fs";
15090
- import path60 from "node:path";
15091
- import { Command as Command99 } from "commander";
15308
+ import fs57 from "node:fs";
15309
+ import path62 from "node:path";
15310
+ import { Command as Command101 } from "commander";
15092
15311
  import * as p62 from "@clack/prompts";
15093
15312
  import pc34 from "picocolors";
15094
15313
  var backupDownload = addTargetOptions(
15095
- new Command99("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),
15314
+ new Command101("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),
15096
15315
  "production"
15097
15316
  ).action(
15098
15317
  (key, raw) => runCommand(() => {
@@ -15114,11 +15333,11 @@ Run ${pc34.cyan("vela backup list")} to see what it does have.`
15114
15333
  Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
15115
15334
  );
15116
15335
  }
15117
- const dir = path60.resolve(ctx.workspaceRootDir, options.output);
15118
- fs55.mkdirSync(dir, { recursive: true });
15119
- const destination = path60.join(dir, key);
15336
+ const dir = path62.resolve(ctx.workspaceRootDir, options.output);
15337
+ fs57.mkdirSync(dir, { recursive: true });
15338
+ const destination = path62.join(dir, key);
15120
15339
  if (!ctx.session) {
15121
- fs55.copyFileSync(path60.join(ctx.workspaceRootDir, "data", "backups", key), destination);
15340
+ fs57.copyFileSync(path62.join(ctx.workspaceRootDir, "data", "backups", key), destination);
15122
15341
  } else {
15123
15342
  const spinner9 = p62.spinner();
15124
15343
  spinner9.start(`Downloading ${key} (${formatBytes(found.size)})`);
@@ -15132,7 +15351,7 @@ Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
15132
15351
  }
15133
15352
  reportResult({
15134
15353
  summary: `Saved ${key} from ${ctx.targetName}.`,
15135
- filesCreated: [path60.relative(ctx.workspaceRootDir, destination)]
15354
+ filesCreated: [path62.relative(ctx.workspaceRootDir, destination)]
15136
15355
  });
15137
15356
  });
15138
15357
  }, "Failed to download the backup.")
@@ -15140,11 +15359,11 @@ Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
15140
15359
 
15141
15360
  // src/commands/backup/delete.ts
15142
15361
  import process45 from "node:process";
15143
- import { Command as Command100 } from "commander";
15362
+ import { Command as Command102 } from "commander";
15144
15363
  import * as p63 from "@clack/prompts";
15145
15364
  import pc35 from "picocolors";
15146
15365
  var backupDelete = addTargetOptions(
15147
- new Command100("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),
15366
+ new Command102("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),
15148
15367
  "production"
15149
15368
  ).action(
15150
15369
  (key, raw) => runCommand(() => {
@@ -15175,12 +15394,12 @@ Run ${pc35.cyan("vela backup list")} to see what it does have.`
15175
15394
  );
15176
15395
 
15177
15396
  // src/commands/backup/schedule.ts
15178
- import { Command as Command101 } from "commander";
15397
+ import { Command as Command103 } from "commander";
15179
15398
  import * as p64 from "@clack/prompts";
15180
15399
  import pc36 from "picocolors";
15181
15400
  var DEFAULT_KEEP = 7;
15182
15401
  var backupSchedule = addTargetOptions(
15183
- new Command101("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),
15402
+ new Command103("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),
15184
15403
  "production"
15185
15404
  ).action(
15186
15405
  (cron, raw) => runCommand(() => {
@@ -15224,18 +15443,18 @@ Set one with ${pc36.cyan('vela backup schedule "0 3 * * *"')}.`
15224
15443
  );
15225
15444
 
15226
15445
  // src/commands/backup.ts
15227
- var backup = new Command102("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);
15446
+ var backup = new Command104("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);
15228
15447
 
15229
15448
  // src/commands/restore.ts
15230
- import fs56 from "node:fs";
15231
- import path61 from "node:path";
15449
+ import fs58 from "node:fs";
15450
+ import path63 from "node:path";
15232
15451
  import process46 from "node:process";
15233
- import { Command as Command103 } from "commander";
15452
+ import { Command as Command105 } from "commander";
15234
15453
  import * as p65 from "@clack/prompts";
15235
15454
  import pc37 from "picocolors";
15236
15455
  var restore = addLockWaitOption(
15237
15456
  addTargetOptions(
15238
- new Command103("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),
15457
+ new Command105("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),
15239
15458
  "production"
15240
15459
  )
15241
15460
  ).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(
@@ -15258,10 +15477,10 @@ Run \`vela deploy\` first, then restore.`
15258
15477
  `${ctx.targetName} was deployed without a database, so there is nothing to restore.`
15259
15478
  );
15260
15479
  }
15261
- const local = source && fs56.existsSync(source) ? source : void 0;
15480
+ const local = source && fs58.existsSync(source) ? source : void 0;
15262
15481
  const key = local ? void 0 : await resolveKey(ctx, source);
15263
15482
  if (!options.yes) {
15264
- await confirm13(ctx.appName, ctx.targetName, ctx.envTag, local ?? key);
15483
+ await confirm14(ctx.appName, ctx.targetName, ctx.envTag, local ?? key);
15265
15484
  }
15266
15485
  const archive = local ? await stage(ctx, local) : remotePaths.backup(ctx.instance, key);
15267
15486
  const result = await runServerScript(ctx.session, "restore.sh", {
@@ -15281,7 +15500,7 @@ Run \`vela deploy\` first, then restore.`
15281
15500
  });
15282
15501
  p65.log.success(
15283
15502
  `Restored ${pc37.cyan(`${ctx.appName} (${ctx.targetName})`)} from ${pc37.cyan(
15284
- local ? path61.basename(local) : key
15503
+ local ? path63.basename(local) : key
15285
15504
  )}.`
15286
15505
  );
15287
15506
  if (result?.storageCarriedOver) {
@@ -15347,21 +15566,21 @@ Take one with ${pc37.cyan("vela backup create")}, or pass the path to an archive
15347
15566
  }
15348
15567
  async function stage(ctx, file) {
15349
15568
  const dir = remotePaths.restoreStage(ctx.instance);
15350
- const remote = `${dir}/${path61.basename(file)}`;
15569
+ const remote = `${dir}/${path63.basename(file)}`;
15351
15570
  const spinner9 = p65.spinner();
15352
- spinner9.start(`Uploading ${path61.basename(file)}`);
15571
+ spinner9.start(`Uploading ${path63.basename(file)}`);
15353
15572
  try {
15354
15573
  await ctx.session.script(`mkdir -p "$1"`, { args: [dir] });
15355
15574
  await ctx.session.upload([file], dir);
15356
15575
  } catch (error) {
15357
- spinner9.stop(`Could not upload ${path61.basename(file)}.`);
15576
+ spinner9.stop(`Could not upload ${path63.basename(file)}.`);
15358
15577
  throw error;
15359
15578
  }
15360
- spinner9.stop(`Uploaded ${path61.basename(file)}`);
15579
+ spinner9.stop(`Uploaded ${path63.basename(file)}`);
15361
15580
  return remote;
15362
15581
  }
15363
- async function confirm13(appName, targetName, envTag, from) {
15364
- const what = `${pc37.cyan(`${appName} (${targetName})`)} from ${pc37.cyan(path61.basename(from))}`;
15582
+ async function confirm14(appName, targetName, envTag, from) {
15583
+ const what = `${pc37.cyan(`${appName} (${targetName})`)} from ${pc37.cyan(path63.basename(from))}`;
15365
15584
  if (isProd(envTag)) {
15366
15585
  const answer = await p65.text({
15367
15586
  message: `This replaces the database and uploads of ${what}. Type the app name to confirm`,
@@ -15384,7 +15603,7 @@ async function confirm13(appName, targetName, envTag, from) {
15384
15603
  }
15385
15604
 
15386
15605
  // src/commands/targets.ts
15387
- import { Command as Command104 } from "commander";
15606
+ import { Command as Command106 } from "commander";
15388
15607
  import * as p66 from "@clack/prompts";
15389
15608
  import pc38 from "picocolors";
15390
15609
  import * as v13 from "valibot";
@@ -15394,7 +15613,7 @@ var OptionsSchema6 = v13.object({
15394
15613
  offline: v13.optional(v13.boolean())
15395
15614
  });
15396
15615
  var targets = addSshOptions(
15397
- new Command104("targets").description("list the targets this project can deploy to").configureHelp(helpConfig)
15616
+ new Command106("targets").description("list the targets this project can deploy to").configureHelp(helpConfig)
15398
15617
  ).option("--json", "print raw JSON").option("--offline", "skip connecting to servers").action(
15399
15618
  (raw) => runCommand(async () => {
15400
15619
  const options = parseOptions(OptionsSchema6, raw);
@@ -15471,29 +15690,29 @@ Release and domain are shown from what this project recorded.`
15471
15690
  }
15472
15691
 
15473
15692
  // src/commands/test.ts
15474
- import path62 from "node:path";
15693
+ import path64 from "node:path";
15475
15694
  import process47 from "node:process";
15476
- import { Command as Command105 } from "commander";
15695
+ import { Command as Command107 } from "commander";
15477
15696
  import PocketBase7 from "pocketbase";
15478
15697
  import pc39 from "picocolors";
15479
15698
  import { x as x6 } from "tinyexec";
15480
15699
  import { detect as detect9 } from "package-manager-detector";
15481
15700
  import { resolveCommand as resolveCommand7 } from "package-manager-detector/commands";
15482
- import fs57 from "node:fs";
15483
- var testServer = new Command105("test:server").description("run server tests").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(async (_opts, cmd) => {
15701
+ import fs59 from "node:fs";
15702
+ var testServer = new Command107("test:server").description("run server tests").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(async (_opts, cmd) => {
15484
15703
  const cwd = process47.cwd();
15485
15704
  warnIfKit2(cwd, (m) => console.warn(pc39.yellow(`\u25B2 ${m}`)));
15486
15705
  const email2 = `test-${Math.random().toString(36).slice(2)}@example.com`;
15487
15706
  const password8 = "password";
15488
- const testDataDir = path62.join(cwd, "test-data");
15489
- fs57.rmSync(testDataDir, { recursive: true, force: true });
15707
+ const testDataDir = path64.join(cwd, "test-data");
15708
+ fs59.rmSync(testDataDir, { recursive: true, force: true });
15490
15709
  const { stop, url } = await launchPocketbase(cwd, {
15491
15710
  dir: testDataDir,
15492
- migrationsDir: path62.join(cwd, MIGRATIONS_DIR),
15711
+ migrationsDir: path64.join(cwd, MIGRATIONS_DIR),
15493
15712
  // The app's PocketBase hooks (slug generation, personal teams, …) are part
15494
15713
  // of its behaviour; the suite runs against the same server dev and build
15495
15714
  // start, so it loads them from the same place.
15496
- hooksDir: path62.join(cwd, DATA_DIR, "hooks"),
15715
+ hooksDir: path64.join(cwd, DATA_DIR, "hooks"),
15497
15716
  email: email2,
15498
15717
  password: password8
15499
15718
  });
@@ -15509,7 +15728,7 @@ var testServer = new Command105("test:server").description("run server tests").a
15509
15728
  if (cleanedUp) return;
15510
15729
  cleanedUp = true;
15511
15730
  stop();
15512
- fs57.rmSync(testDataDir, { recursive: true, force: true });
15731
+ fs59.rmSync(testDataDir, { recursive: true, force: true });
15513
15732
  };
15514
15733
  const cleanup = async () => {
15515
15734
  if (cleanedUp) return;
@@ -15622,9 +15841,9 @@ function stubPagesPlugin() {
15622
15841
  }
15623
15842
 
15624
15843
  // src/commands/routes.ts
15625
- import fs58 from "node:fs";
15626
- import path63 from "node:path";
15627
- import { Command as Command106 } from "commander";
15844
+ import fs60 from "node:fs";
15845
+ import path65 from "node:path";
15846
+ import { Command as Command108 } from "commander";
15628
15847
  var HTTP_METHODS = /* @__PURE__ */ new Set([
15629
15848
  "GET",
15630
15849
  "POST",
@@ -15635,32 +15854,32 @@ var HTTP_METHODS = /* @__PURE__ */ new Set([
15635
15854
  "HEAD",
15636
15855
  "fallback"
15637
15856
  ]);
15638
- var routes = new Command106("routes").description("list routes").configureHelp(helpConfig).action(async () => {
15857
+ var routes = new Command108("routes").description("list routes").configureHelp(helpConfig).action(async () => {
15639
15858
  const { workspaceRootDir, routesDir } = await getWorkspace();
15640
- const routesRoot = path63.join(workspaceRootDir, routesDir);
15859
+ const routesRoot = path65.join(workspaceRootDir, routesDir);
15641
15860
  const found = walk(routesRoot, routesRoot).filter((r) => r.methods.length > 0);
15642
15861
  found.sort((a, b) => a.urlPattern.localeCompare(b.urlPattern));
15643
15862
  printTable(found);
15644
15863
  });
15645
15864
  function walk(root, dir) {
15646
- const entries = fs58.readdirSync(dir, { withFileTypes: true });
15865
+ const entries = fs60.readdirSync(dir, { withFileTypes: true });
15647
15866
  const routes2 = [];
15648
15867
  const hasLeaf = entries.some((e) => e.isFile() && isRouteFile(e.name));
15649
15868
  if (hasLeaf) {
15650
- const id = "/" + path63.relative(root, dir).split(path63.sep).filter(Boolean).join("/");
15869
+ const id = "/" + path65.relative(root, dir).split(path65.sep).filter(Boolean).join("/");
15651
15870
  const urlPattern = id.replace(/\([^)]+\)\/?/g, "").replace(/\/$/, "") || "/";
15652
15871
  const methods = /* @__PURE__ */ new Set();
15653
15872
  for (const entry of entries) {
15654
15873
  if (!entry.isFile()) continue;
15655
15874
  if (entry.name.endsWith("+page.svelte")) methods.add("GET");
15656
15875
  if (entry.name.endsWith("+server.ts") || entry.name.endsWith("+server.js") || entry.name.endsWith("+page.server.ts") || entry.name.endsWith("+page.server.js")) {
15657
- extractMethods(path63.join(dir, entry.name)).forEach((m) => methods.add(m));
15876
+ extractMethods(path65.join(dir, entry.name)).forEach((m) => methods.add(m));
15658
15877
  }
15659
15878
  }
15660
15879
  routes2.push({ id: id || "/", urlPattern, methods: [...methods] });
15661
15880
  }
15662
15881
  for (const entry of entries) {
15663
- if (entry.isDirectory()) routes2.push(...walk(root, path63.join(dir, entry.name)));
15882
+ if (entry.isDirectory()) routes2.push(...walk(root, path65.join(dir, entry.name)));
15664
15883
  }
15665
15884
  return routes2;
15666
15885
  }
@@ -15669,7 +15888,7 @@ function isRouteFile(name) {
15669
15888
  }
15670
15889
  function extractMethods(file) {
15671
15890
  try {
15672
- const content = fs58.readFileSync(file, "utf8");
15891
+ const content = fs60.readFileSync(file, "utf8");
15673
15892
  const methods = [];
15674
15893
  const exportRegex = /export\s+(?:const|async\s+function|function)\s+(\w+)/g;
15675
15894
  let match;
@@ -15710,17 +15929,17 @@ function printTable(routes2) {
15710
15929
  }
15711
15930
 
15712
15931
  // src/commands/i18n.ts
15713
- import fs59 from "node:fs";
15714
- import path64 from "node:path";
15932
+ import fs61 from "node:fs";
15933
+ import path66 from "node:path";
15715
15934
  import process48 from "node:process";
15716
- import { Command as Command107 } from "commander";
15935
+ import { Command as Command109 } from "commander";
15717
15936
  import { x as x7 } from "tinyexec";
15718
15937
  import { detect as detect10 } from "package-manager-detector";
15719
15938
  import { resolveCommand as resolveCommand8 } from "package-manager-detector/commands";
15720
15939
  var WUCHALE_CONFIG_NAMES = ["js", "mjs", "ts", "mts"].map((ext) => `wuchale.config.${ext}`);
15721
15940
  async function runWuchale(extraArgs) {
15722
15941
  const cwd = findWorkspaceRoot() ?? process48.cwd();
15723
- if (!WUCHALE_CONFIG_NAMES.some((name) => fs59.existsSync(path64.join(cwd, name)))) {
15942
+ if (!WUCHALE_CONFIG_NAMES.some((name) => fs61.existsSync(path66.join(cwd, name)))) {
15724
15943
  throw new Error("No wuchale config found. Run `vela enable i18n` to set up i18n.");
15725
15944
  }
15726
15945
  const pm = (await detect10({ cwd }))?.name ?? "npm";
@@ -15732,24 +15951,24 @@ async function runWuchale(extraArgs) {
15732
15951
  throwOnError: true
15733
15952
  });
15734
15953
  }
15735
- var extract2 = new Command107("extract").description("extract translatable strings").configureHelp(helpConfig).action(() => runCommand(() => runWuchale([])));
15736
- var watch = new Command107("watch").description("watch and extract translatable strings").configureHelp(helpConfig).action(() => runCommand(() => runWuchale(["--watch"])));
15737
- var status2 = new Command107("status").description("show i18n status").configureHelp(helpConfig).action(() => runCommand(() => runWuchale(["status"])));
15738
- var clean = new Command107("clean").description("clean unused translatable strings").configureHelp(helpConfig).action(() => runCommand(() => runWuchale(["--clean"])));
15739
- var i18n3 = new Command107("i18n").description("i18n utilities").configureHelp(helpConfig).addCommand(extract2, { isDefault: true }).addCommand(watch).addCommand(status2).addCommand(clean);
15954
+ var extract2 = new Command109("extract").description("extract translatable strings").configureHelp(helpConfig).action(() => runCommand(() => runWuchale([])));
15955
+ var watch = new Command109("watch").description("watch and extract translatable strings").configureHelp(helpConfig).action(() => runCommand(() => runWuchale(["--watch"])));
15956
+ var status2 = new Command109("status").description("show i18n status").configureHelp(helpConfig).action(() => runCommand(() => runWuchale(["status"])));
15957
+ var clean = new Command109("clean").description("clean unused translatable strings").configureHelp(helpConfig).action(() => runCommand(() => runWuchale(["--clean"])));
15958
+ var i18n3 = new Command109("i18n").description("i18n utilities").configureHelp(helpConfig).addCommand(extract2, { isDefault: true }).addCommand(watch).addCommand(status2).addCommand(clean);
15740
15959
 
15741
15960
  // src/commands/cms.ts
15742
- import { Command as Command113 } from "commander";
15961
+ import { Command as Command115 } from "commander";
15743
15962
 
15744
15963
  // src/commands/cms/deploy.ts
15745
15964
  import process49 from "node:process";
15746
- import { Command as Command108 } from "commander";
15965
+ import { Command as Command110 } from "commander";
15747
15966
  import * as p67 from "@clack/prompts";
15748
15967
  import pc40 from "picocolors";
15749
15968
  var POLL_INTERVAL2 = 5e3;
15750
15969
  var POLL_TIMEOUT = 30 * 6e4;
15751
15970
  var inFlight = (run) => run?.status === "pending" || run?.status === "building";
15752
- var deploy2 = new Command108("deploy").description("rebuild the hosted site with the latest published content").option(
15971
+ var deploy2 = new Command110("deploy").description("rebuild the hosted site with the latest published content").option(
15753
15972
  "--project <id>",
15754
15973
  "velastack.dev project whose site to rebuild, instead of the linked one"
15755
15974
  ).option("--no-wait", "return once the build has started instead of waiting for it").configureHelp(helpConfig).action(
@@ -15838,17 +16057,17 @@ async function waitForRun(apiKey, projectId, runId) {
15838
16057
  }
15839
16058
 
15840
16059
  // src/commands/cms/editor.ts
15841
- import { Command as Command112 } from "commander";
16060
+ import { Command as Command114 } from "commander";
15842
16061
 
15843
16062
  // src/commands/cms/editor/add.ts
15844
16063
  import { randomBytes } from "node:crypto";
15845
- import { Command as Command109 } from "commander";
16064
+ import { Command as Command111 } from "commander";
15846
16065
  import * as p68 from "@clack/prompts";
15847
16066
  import pc42 from "picocolors";
15848
16067
 
15849
16068
  // src/lib/cms-backend.ts
15850
16069
  import { createRequire as createRequire5 } from "node:module";
15851
- import path65 from "node:path";
16070
+ import path67 from "node:path";
15852
16071
  import process50 from "node:process";
15853
16072
  import { pathToFileURL as pathToFileURL2 } from "node:url";
15854
16073
  import pc41 from "picocolors";
@@ -15856,7 +16075,7 @@ var DEFAULT_PROJECT = "default";
15856
16075
  async function loadBackendModule(root) {
15857
16076
  let entry;
15858
16077
  try {
15859
- entry = createRequire5(path65.join(root, "package.json")).resolve("@velastack/cms/backend");
16078
+ entry = createRequire5(path67.join(root, "package.json")).resolve("@velastack/cms/backend");
15860
16079
  } catch {
15861
16080
  throw new Error(
15862
16081
  `@velastack/cms is not installed in this project.
@@ -15874,8 +16093,8 @@ async function withCmsBackend(fn, cwd = process50.cwd()) {
15874
16093
  const { createCmsBackend } = await loadBackendModule(root);
15875
16094
  const dataDir2 = localDataDir(root);
15876
16095
  const backend3 = createCmsBackend({
15877
- dbPath: path65.join(dataDir2, "cms.sqlite"),
15878
- uploadDir: path65.join(dataDir2, "uploads")
16096
+ dbPath: path67.join(dataDir2, "cms.sqlite"),
16097
+ uploadDir: path67.join(dataDir2, "uploads")
15879
16098
  });
15880
16099
  try {
15881
16100
  return await fn(backend3);
@@ -15885,7 +16104,7 @@ async function withCmsBackend(fn, cwd = process50.cwd()) {
15885
16104
  }
15886
16105
 
15887
16106
  // src/commands/cms/editor/add.ts
15888
- var editorAdd = new Command109("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(
16107
+ var editorAdd = new Command111("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(
15889
16108
  (email2, options) => runCommand(async () => {
15890
16109
  const generated = options.password === void 0;
15891
16110
  const password8 = options.password ?? randomBytes(12).toString("base64url");
@@ -15904,10 +16123,10 @@ var editorAdd = new Command109("add").description("create an editor who can sign
15904
16123
  );
15905
16124
 
15906
16125
  // src/commands/cms/editor/password.ts
15907
- import { Command as Command110 } from "commander";
16126
+ import { Command as Command112 } from "commander";
15908
16127
  import * as p69 from "@clack/prompts";
15909
16128
  import pc43 from "picocolors";
15910
- var editorPassword = new Command110("password").description("set an editor's password").argument("<email>", "email of the editor").argument("<password>", "new password").configureHelp(helpConfig).action(
16129
+ var editorPassword = new Command112("password").description("set an editor's password").argument("<email>", "email of the editor").argument("<password>", "new password").configureHelp(helpConfig).action(
15911
16130
  (email2, password8) => runCommand(async () => {
15912
16131
  await withCmsBackend((cms3) => cms3.editors.setPassword(email2, password8));
15913
16132
  p69.log.success(
@@ -15917,10 +16136,10 @@ var editorPassword = new Command110("password").description("set an editor's pas
15917
16136
  );
15918
16137
 
15919
16138
  // src/commands/cms/editor/list.ts
15920
- import { Command as Command111 } from "commander";
16139
+ import { Command as Command113 } from "commander";
15921
16140
  import * as p70 from "@clack/prompts";
15922
16141
  import pc44 from "picocolors";
15923
- var editorList = new Command111("list").description("list editors and the projects they may edit").configureHelp(helpConfig).action(
16142
+ var editorList = new Command113("list").description("list editors and the projects they may edit").configureHelp(helpConfig).action(
15924
16143
  () => runCommand(async () => {
15925
16144
  const rows = await withCmsBackend(
15926
16145
  async (cms3) => cms3.editors.list().map((editor2) => ({
@@ -15944,17 +16163,17 @@ var editorList = new Command111("list").description("list editors and the projec
15944
16163
  );
15945
16164
 
15946
16165
  // src/commands/cms/editor.ts
15947
- var editor = new Command112("editor").description("manage who can sign in to the admin bar").configureHelp(helpConfig).addCommand(editorAdd).addCommand(editorPassword).addCommand(editorList);
16166
+ var editor = new Command114("editor").description("manage who can sign in to the admin bar").configureHelp(helpConfig).addCommand(editorAdd).addCommand(editorPassword).addCommand(editorList);
15948
16167
 
15949
16168
  // src/commands/cms.ts
15950
- var cms2 = new Command113("cms").description("manage the CMS").configureHelp(helpConfig).addCommand(editor).addCommand(deploy2);
16169
+ var cms2 = new Command115("cms").description("manage the CMS").configureHelp(helpConfig).addCommand(editor).addCommand(deploy2);
15951
16170
 
15952
16171
  // src/commands/workflows.ts
15953
- import { Command as Command117 } from "commander";
16172
+ import { Command as Command119 } from "commander";
15954
16173
 
15955
16174
  // src/commands/workflows/list.ts
15956
16175
  import process51 from "node:process";
15957
- import { Command as Command114, InvalidArgumentError as InvalidArgumentError5 } from "commander";
16176
+ import { Command as Command116, InvalidArgumentError as InvalidArgumentError5 } from "commander";
15958
16177
  import * as p71 from "@clack/prompts";
15959
16178
  import pc45 from "picocolors";
15960
16179
 
@@ -16029,7 +16248,7 @@ function formatRun(run, nameWidth) {
16029
16248
  const error = run.status === "failed" && run.error?.message ? pc45.red(` ${run.error.message}`) : "";
16030
16249
  return `${run.id} ${run.workflowName.padEnd(nameWidth)} ${status3}${attempts} ${when}${error}`;
16031
16250
  }
16032
- var workflowsList = new Command114("list").description("list recent workflow runs").option("--status <status>", `only runs in this state (${STATUSES.join(", ")})`, parseStatus).option("--name <workflow>", "only runs of this workflow").option("--limit <n>", "how many to show", parseLimit, 50).configureHelp(helpConfig).action(
16251
+ var workflowsList = new Command116("list").description("list recent workflow runs").option("--status <status>", `only runs in this state (${STATUSES.join(", ")})`, parseStatus).option("--name <workflow>", "only runs of this workflow").option("--limit <n>", "how many to show", parseLimit, 50).configureHelp(helpConfig).action(
16033
16252
  (options) => runCommand(async () => {
16034
16253
  await withPocketbase(process51.cwd(), async (pb) => {
16035
16254
  const runs = await listRuns(pb, {
@@ -16053,7 +16272,7 @@ Start one from server code with ${pc45.cyan("<workflow>.run(input)")}, or with $
16053
16272
 
16054
16273
  // src/commands/workflows/run.ts
16055
16274
  import process52 from "node:process";
16056
- import { Command as Command115, InvalidArgumentError as InvalidArgumentError6 } from "commander";
16275
+ import { Command as Command117, InvalidArgumentError as InvalidArgumentError6 } from "commander";
16057
16276
  import * as p72 from "@clack/prompts";
16058
16277
  import pc46 from "picocolors";
16059
16278
  function parseInput(value) {
@@ -16063,7 +16282,7 @@ function parseInput(value) {
16063
16282
  throw new InvalidArgumentError6(`must be JSON, e.g. '{"userId":"abc"}'.`);
16064
16283
  }
16065
16284
  }
16066
- var workflowsRun = new Command115("run").description("start a run of a workflow; the running app picks it up").argument("<name>", "the workflow name, as in its defineWorkflow spec").argument("[input]", "the run input as JSON", parseInput).configureHelp(helpConfig).action(
16285
+ var workflowsRun = new Command117("run").description("start a run of a workflow; the running app picks it up").argument("<name>", "the workflow name, as in its defineWorkflow spec").argument("[input]", "the run input as JSON", parseInput).configureHelp(helpConfig).action(
16067
16286
  (name, input) => runCommand(async () => {
16068
16287
  await withPocketbase(process52.cwd(), async (pb) => {
16069
16288
  const run = await createRun(pb, name, input);
@@ -16078,10 +16297,10 @@ It runs once the app is up (${pc46.cyan("vela dev")}); ${pc46.cyan("vela workflo
16078
16297
 
16079
16298
  // src/commands/workflows/cancel.ts
16080
16299
  import process53 from "node:process";
16081
- import { Command as Command116 } from "commander";
16300
+ import { Command as Command118 } from "commander";
16082
16301
  import * as p73 from "@clack/prompts";
16083
16302
  import pc47 from "picocolors";
16084
- var workflowsCancel = new Command116("cancel").description("cancel a pending or running workflow run").argument("<run-id>", "the run id from `vela workflows list`").configureHelp(helpConfig).action(
16303
+ var workflowsCancel = new Command118("cancel").description("cancel a pending or running workflow run").argument("<run-id>", "the run id from `vela workflows list`").configureHelp(helpConfig).action(
16085
16304
  (id) => runCommand(async () => {
16086
16305
  await withPocketbase(process53.cwd(), async (pb) => {
16087
16306
  const run = await cancelRun(pb, id);
@@ -16091,7 +16310,7 @@ var workflowsCancel = new Command116("cancel").description("cancel a pending or
16091
16310
  );
16092
16311
 
16093
16312
  // src/commands/workflows.ts
16094
- var workflows2 = new Command117("workflows").description("list, start and cancel background workflow runs").configureHelp(helpConfig).addCommand(workflowsList).addCommand(workflowsRun).addCommand(workflowsCancel);
16313
+ var workflows2 = new Command119("workflows").description("list, start and cancel background workflow runs").configureHelp(helpConfig).addCommand(workflowsList).addCommand(workflowsRun).addCommand(workflowsCancel);
16095
16314
 
16096
16315
  // src/program.ts
16097
16316
  var NO_BACKEND_COMMMANDS = /* @__PURE__ */ new Set([
@@ -16155,27 +16374,33 @@ var NO_BACKEND_COMMMANDS = /* @__PURE__ */ new Set([
16155
16374
  // drop collections and stay gated.
16156
16375
  "destroy deployment"
16157
16376
  ]);
16158
- var PROVIDER_GATED_COMMANDS = /* @__PURE__ */ new Set(["enable payments", "disable payments"]);
16377
+ var PROVIDER_GATED_COMMANDS = /* @__PURE__ */ new Set([
16378
+ "enable payments",
16379
+ "disable payments",
16380
+ // Stripe's shop reads PocketBase; Shopify's and WhatsApp's run on a static site.
16381
+ "generate shop",
16382
+ "destroy shop"
16383
+ ]);
16159
16384
  var BACKEND_OPTIONAL_COMMANDS = /* @__PURE__ */ new Set(["dev", "build", "preview", "deploy"]);
16160
16385
  var SELF_CREDENTIALED_COMMANDS = /* @__PURE__ */ new Set(["test:server"]);
16161
- var program = new Command118().name(package_default.name).description(package_default.description).version(package_default.version, "-v, --version").configureHelp(helpConfig);
16386
+ var program = new Command120().name(package_default.name).description(package_default.description).version(package_default.version, "-v, --version").configureHelp(helpConfig);
16162
16387
  program.hook("preAction", (_thisCommand, actionCommand) => {
16163
16388
  const envRoot = findWorkspaceRoot() ?? process54.cwd();
16164
16389
  dotenv2.config({ path: nodePath.join(envRoot, ".env"), quiet: true });
16165
- const path66 = getCommandPath(actionCommand);
16166
- if (NO_BACKEND_COMMMANDS.has(path66)) return;
16167
- if (PROVIDER_GATED_COMMANDS.has(path66)) return;
16168
- const top = path66.split(" ", 1)[0];
16390
+ const path68 = getCommandPath(actionCommand);
16391
+ if (NO_BACKEND_COMMMANDS.has(path68)) return;
16392
+ if (PROVIDER_GATED_COMMANDS.has(path68)) return;
16393
+ const top = path68.split(" ", 1)[0];
16169
16394
  if (NO_BACKEND_COMMMANDS.has(top)) return;
16170
16395
  if (!hasBackend()) {
16171
16396
  if (BACKEND_OPTIONAL_COMMANDS.has(top)) return;
16172
- p74.log.error(missingBackendMessage(`vela ${path66}`));
16397
+ p74.log.error(missingBackendMessage(`vela ${path68}`));
16173
16398
  p74.log.message();
16174
16399
  p74.cancel("Operation failed.");
16175
16400
  process54.exit(1);
16176
16401
  }
16177
- if (SELF_CREDENTIALED_COMMANDS.has(path66)) return;
16178
- if (path66 === "generate migration" && actionCommand.opts().ai) return;
16402
+ if (SELF_CREDENTIALED_COMMANDS.has(path68)) return;
16403
+ if (path68 === "generate migration" && actionCommand.opts().ai) return;
16179
16404
  if (!hasSuperuserCredentials()) {
16180
16405
  p74.log.error(missingCredentialsMessage());
16181
16406
  p74.log.message();