vela 0.13.4 → 0.14.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/README.md +1 -0
- package/dist/bin.js +893 -666
- package/dist/bin.js.map +4 -4
- package/package.json +3 -3
- package/templates/minimal/package.template.json +1 -1
- package/templates/minimal/src/lib/site.template.ts +12 -0
- package/templates/minimal/src/routes/(public)/+page.svelte +3 -4
- package/templates/minimal/src/routes/(public)/root-layout.svelte +6 -2
- package/templates/minimal/src/routes/+layout.server.ts +9 -6
- package/templates/minimal/src/routes/+layout.svelte +2 -1
- package/templates/static/src/lib/site.template.ts +5 -4
- package/templates/static/src/routes/(public)/+page.svelte +3 -4
- package/templates/static/src/routes/(public)/root-layout.svelte +6 -2
- package/templates/static/src/routes/+layout.svelte +2 -1
- package/templates/static/src/routes/+layout.ts +0 -1
package/dist/bin.js
CHANGED
|
@@ -13,7 +13,7 @@ function normalizeArgv(argv) {
|
|
|
13
13
|
// src/program.ts
|
|
14
14
|
import process45 from "node:process";
|
|
15
15
|
import * as p67 from "@clack/prompts";
|
|
16
|
-
import { Command as
|
|
16
|
+
import { Command as Command117 } from "commander";
|
|
17
17
|
import nodePath from "node:path";
|
|
18
18
|
import dotenv2 from "dotenv";
|
|
19
19
|
import pc42 from "picocolors";
|
|
@@ -21,7 +21,7 @@ import pc42 from "picocolors";
|
|
|
21
21
|
// package.json
|
|
22
22
|
var package_default = {
|
|
23
23
|
name: "vela",
|
|
24
|
-
version: "0.
|
|
24
|
+
version: "0.14.0",
|
|
25
25
|
type: "module",
|
|
26
26
|
description: "A CLI for creating and updating SvelteKit projects",
|
|
27
27
|
license: "MIT",
|
|
@@ -57,7 +57,7 @@ var package_default = {
|
|
|
57
57
|
dependencies: {
|
|
58
58
|
"@clack/prompts": "^1.7.0",
|
|
59
59
|
"@faker-js/faker": "^10.6.0",
|
|
60
|
-
"@velastack/patterns": "^0.
|
|
60
|
+
"@velastack/patterns": "^0.3.0",
|
|
61
61
|
"@velastack/pocketbase-codegen": "^0.1.0",
|
|
62
62
|
"annotate-json-schema": "^0.1.0",
|
|
63
63
|
commander: "^13.1.0",
|
|
@@ -70,7 +70,7 @@ var package_default = {
|
|
|
70
70
|
"package-manager-detector": "^1.8.0",
|
|
71
71
|
picocolors: "^1.1.1",
|
|
72
72
|
pocketbase: "^0.28.0",
|
|
73
|
-
"pocketbase-server": "^0.40.5-beta.
|
|
73
|
+
"pocketbase-server": "^0.40.5-beta.2",
|
|
74
74
|
stripe: "^19.3.0",
|
|
75
75
|
svelte: "^5.56.10",
|
|
76
76
|
tar: "^7.5.22",
|
|
@@ -343,8 +343,8 @@ function dropTemplateAdapters(user, template) {
|
|
|
343
343
|
}
|
|
344
344
|
return copy;
|
|
345
345
|
}
|
|
346
|
-
function readPackageJson(
|
|
347
|
-
return JSON.parse(fs2.readFileSync(
|
|
346
|
+
function readPackageJson(path50) {
|
|
347
|
+
return JSON.parse(fs2.readFileSync(path50, "utf8"));
|
|
348
348
|
}
|
|
349
349
|
var PACKAGE_NAME_PLACEHOLDER = /~TODO~/g;
|
|
350
350
|
var APP_NAME_PLACEHOLDER = /~APP_NAME~/g;
|
|
@@ -362,12 +362,12 @@ function fillTemplatePlaceholders(raw, values) {
|
|
|
362
362
|
function escapeSingleQuoted(value) {
|
|
363
363
|
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
364
364
|
}
|
|
365
|
-
function readTemplatePackageJson(
|
|
366
|
-
const raw = fillTemplatePlaceholders(fs2.readFileSync(
|
|
365
|
+
function readTemplatePackageJson(path50, values) {
|
|
366
|
+
const raw = fillTemplatePlaceholders(fs2.readFileSync(path50, "utf8"), values);
|
|
367
367
|
return JSON.parse(raw);
|
|
368
368
|
}
|
|
369
|
-
function writePackageJson(
|
|
370
|
-
fs2.writeFileSync(
|
|
369
|
+
function writePackageJson(path50, pkg) {
|
|
370
|
+
fs2.writeFileSync(path50, JSON.stringify(pkg, null, " ") + "\n");
|
|
371
371
|
}
|
|
372
372
|
function toValidPackageName(name) {
|
|
373
373
|
return name.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._]/, "").replace(/[^a-z0-9~.-]+/g, "-");
|
|
@@ -459,8 +459,8 @@ function detectFeatures(root, { isAppMode, isPaymentsMode }) {
|
|
|
459
459
|
}
|
|
460
460
|
|
|
461
461
|
// src/commands/bless.ts
|
|
462
|
-
import
|
|
463
|
-
import
|
|
462
|
+
import fs16 from "node:fs";
|
|
463
|
+
import path14 from "node:path";
|
|
464
464
|
import process7 from "node:process";
|
|
465
465
|
import * as v3 from "valibot";
|
|
466
466
|
import { Command as Command2 } from "commander";
|
|
@@ -1083,10 +1083,10 @@ async function startPocketbaseServe(opts) {
|
|
|
1083
1083
|
}
|
|
1084
1084
|
throw lastErr instanceof Error ? lastErr : new Error("Failed to start PocketBase");
|
|
1085
1085
|
}
|
|
1086
|
-
async function authWithRetries(pb, email3,
|
|
1086
|
+
async function authWithRetries(pb, email3, password12, attempts = 3) {
|
|
1087
1087
|
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
1088
1088
|
try {
|
|
1089
|
-
await pb.collection("_superusers").authWithPassword(email3,
|
|
1089
|
+
await pb.collection("_superusers").authWithPassword(email3, password12);
|
|
1090
1090
|
return;
|
|
1091
1091
|
} catch (e) {
|
|
1092
1092
|
if (attempt === attempts) {
|
|
@@ -1118,14 +1118,14 @@ async function withPocketbase(cwd, fn, creds) {
|
|
|
1118
1118
|
const migrationsDir = path8.join(cwd, MIGRATIONS_DIR);
|
|
1119
1119
|
const host = "localhost";
|
|
1120
1120
|
const email3 = creds?.email ?? process6.env.POCKETBASE_SUPERUSER_EMAIL;
|
|
1121
|
-
const
|
|
1121
|
+
const password12 = creds?.password ?? process6.env.POCKETBASE_SUPERUSER_PASSWORD;
|
|
1122
1122
|
if (!fs9.existsSync(dir)) {
|
|
1123
1123
|
throw new Error("PocketBase data directory does not exist");
|
|
1124
1124
|
}
|
|
1125
1125
|
const metadata = getPocketbaseMetadata(cwd);
|
|
1126
1126
|
if (metadata?.pocketbaseUrl) {
|
|
1127
1127
|
const pb = new PocketBase(metadata.pocketbaseUrl);
|
|
1128
|
-
await authWithRetries(pb, email3,
|
|
1128
|
+
await authWithRetries(pb, email3, password12);
|
|
1129
1129
|
await fn(pb);
|
|
1130
1130
|
return;
|
|
1131
1131
|
}
|
|
@@ -1137,13 +1137,13 @@ async function withPocketbase(cwd, fn, creds) {
|
|
|
1137
1137
|
});
|
|
1138
1138
|
try {
|
|
1139
1139
|
const pb = new PocketBase(url);
|
|
1140
|
-
await authWithRetries(pb, email3,
|
|
1140
|
+
await authWithRetries(pb, email3, password12);
|
|
1141
1141
|
await fn(pb);
|
|
1142
1142
|
} finally {
|
|
1143
1143
|
proc.kill();
|
|
1144
1144
|
}
|
|
1145
1145
|
}
|
|
1146
|
-
async function createSuperuser(cwd, email3,
|
|
1146
|
+
async function createSuperuser(cwd, email3, password12) {
|
|
1147
1147
|
const dir = path8.join(cwd, DATA_DIR);
|
|
1148
1148
|
const migrationsDir = path8.join(cwd, MIGRATIONS_DIR);
|
|
1149
1149
|
fs9.mkdirSync(dir, { recursive: true });
|
|
@@ -1159,7 +1159,7 @@ async function createSuperuser(cwd, email3, password11) {
|
|
|
1159
1159
|
"superuser",
|
|
1160
1160
|
"create",
|
|
1161
1161
|
email3,
|
|
1162
|
-
|
|
1162
|
+
password12
|
|
1163
1163
|
],
|
|
1164
1164
|
"pipe"
|
|
1165
1165
|
);
|
|
@@ -1169,7 +1169,7 @@ async function launchPocketbase(cwd, {
|
|
|
1169
1169
|
migrationsDir,
|
|
1170
1170
|
hooksDir,
|
|
1171
1171
|
email: email3,
|
|
1172
|
-
password:
|
|
1172
|
+
password: password12
|
|
1173
1173
|
}) {
|
|
1174
1174
|
const host = "localhost";
|
|
1175
1175
|
fs9.mkdirSync(dir, { recursive: true });
|
|
@@ -1185,7 +1185,7 @@ async function launchPocketbase(cwd, {
|
|
|
1185
1185
|
"superuser",
|
|
1186
1186
|
"create",
|
|
1187
1187
|
email3,
|
|
1188
|
-
|
|
1188
|
+
password12
|
|
1189
1189
|
],
|
|
1190
1190
|
"pipe"
|
|
1191
1191
|
);
|
|
@@ -1213,8 +1213,8 @@ function pocketbaseVersion() {
|
|
|
1213
1213
|
}
|
|
1214
1214
|
async function ensureSuperuser(cwd) {
|
|
1215
1215
|
const email3 = process6.env.POCKETBASE_SUPERUSER_EMAIL;
|
|
1216
|
-
const
|
|
1217
|
-
if (!email3 || !
|
|
1216
|
+
const password12 = process6.env.POCKETBASE_SUPERUSER_PASSWORD;
|
|
1217
|
+
if (!email3 || !password12) return;
|
|
1218
1218
|
const dir = path8.join(cwd, DATA_DIR);
|
|
1219
1219
|
if (!fs9.existsSync(dir)) return;
|
|
1220
1220
|
const { getBinaryPath } = await import("pocketbase-server");
|
|
@@ -1228,7 +1228,7 @@ async function ensureSuperuser(cwd) {
|
|
|
1228
1228
|
"superuser",
|
|
1229
1229
|
"upsert",
|
|
1230
1230
|
email3,
|
|
1231
|
-
|
|
1231
|
+
password12
|
|
1232
1232
|
],
|
|
1233
1233
|
{ nodeOptions: { cwd, stdio: "ignore" } }
|
|
1234
1234
|
);
|
|
@@ -1321,13 +1321,49 @@ function ensureShadcnImport(appCssPath) {
|
|
|
1321
1321
|
return true;
|
|
1322
1322
|
}
|
|
1323
1323
|
|
|
1324
|
+
// src/lib/site.ts
|
|
1325
|
+
import fs12 from "node:fs";
|
|
1326
|
+
import path10 from "node:path";
|
|
1327
|
+
var SITE_FILE = path10.join("src", "lib", "site.ts");
|
|
1328
|
+
async function readSite(root) {
|
|
1329
|
+
const file = path10.join(root, SITE_FILE);
|
|
1330
|
+
if (!fs12.existsSync(file)) return null;
|
|
1331
|
+
const { Project: Project3, Node } = await import("ts-morph");
|
|
1332
|
+
const project = new Project3({ useInMemoryFileSystem: true });
|
|
1333
|
+
const source = project.createSourceFile("site.ts", fs12.readFileSync(file, "utf8"));
|
|
1334
|
+
let object6 = source.getVariableDeclaration("site")?.getInitializer();
|
|
1335
|
+
while (object6 && (Node.isAsExpression(object6) || Node.isSatisfiesExpression(object6))) {
|
|
1336
|
+
object6 = object6.getExpression();
|
|
1337
|
+
}
|
|
1338
|
+
if (!object6 || !Node.isObjectLiteralExpression(object6)) return null;
|
|
1339
|
+
const info = {};
|
|
1340
|
+
for (const key of ["name", "url"]) {
|
|
1341
|
+
const property = object6.getProperty(key);
|
|
1342
|
+
if (!property || !Node.isPropertyAssignment(property)) continue;
|
|
1343
|
+
const value = property.getInitializer();
|
|
1344
|
+
if (Node.isStringLiteral(value) || Node.isNoSubstitutionTemplateLiteral(value)) {
|
|
1345
|
+
const text19 = value.getLiteralValue().trim();
|
|
1346
|
+
if (text19) info[key] = text19;
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
return info;
|
|
1350
|
+
}
|
|
1351
|
+
function isLocalUrl(url) {
|
|
1352
|
+
try {
|
|
1353
|
+
const { hostname } = new URL(url);
|
|
1354
|
+
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]";
|
|
1355
|
+
} catch {
|
|
1356
|
+
return false;
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1324
1360
|
// src/lib/config-merge.ts
|
|
1325
|
-
import
|
|
1326
|
-
import
|
|
1361
|
+
import fs14 from "node:fs";
|
|
1362
|
+
import path12 from "node:path";
|
|
1327
1363
|
|
|
1328
1364
|
// src/lib/config-target.ts
|
|
1329
|
-
import
|
|
1330
|
-
import
|
|
1365
|
+
import fs13 from "node:fs";
|
|
1366
|
+
import path11 from "node:path";
|
|
1331
1367
|
import {
|
|
1332
1368
|
Project,
|
|
1333
1369
|
QuoteKind,
|
|
@@ -1347,8 +1383,8 @@ var SVELTE_CONFIG_CANDIDATES = [
|
|
|
1347
1383
|
];
|
|
1348
1384
|
function probeFirstExisting(root, candidates) {
|
|
1349
1385
|
for (const rel of candidates) {
|
|
1350
|
-
const abs =
|
|
1351
|
-
if (
|
|
1386
|
+
const abs = path11.join(root, rel);
|
|
1387
|
+
if (fs13.existsSync(abs)) return abs;
|
|
1352
1388
|
}
|
|
1353
1389
|
return null;
|
|
1354
1390
|
}
|
|
@@ -1424,7 +1460,7 @@ function mergeSvelteConfig(projectRoot) {
|
|
|
1424
1460
|
};
|
|
1425
1461
|
}
|
|
1426
1462
|
function mergeRunesIntoViteArg(vite, arg) {
|
|
1427
|
-
const file =
|
|
1463
|
+
const file = path12.basename(vite.filePath);
|
|
1428
1464
|
const compilerOptions = getOrCreateObjectLiteralProperty(arg, "compilerOptions", "{}");
|
|
1429
1465
|
if (!compilerOptions) {
|
|
1430
1466
|
return {
|
|
@@ -1443,8 +1479,8 @@ function mergeRunesIntoViteArg(vite, arg) {
|
|
|
1443
1479
|
return { applied: true, reason: "added runes compilerOption", file };
|
|
1444
1480
|
}
|
|
1445
1481
|
function mergeRunesIntoSvelteConfig(filePath) {
|
|
1446
|
-
const file =
|
|
1447
|
-
const original =
|
|
1482
|
+
const file = path12.basename(filePath);
|
|
1483
|
+
const original = fs14.readFileSync(filePath, "utf8");
|
|
1448
1484
|
if (/runes\s*:/m.test(original)) {
|
|
1449
1485
|
return { applied: false, reason: "runes already configured", file };
|
|
1450
1486
|
}
|
|
@@ -1467,11 +1503,11 @@ function mergeRunesIntoSvelteConfig(filePath) {
|
|
|
1467
1503
|
}
|
|
1468
1504
|
const insertAt = anchor.index + anchor[0].length;
|
|
1469
1505
|
const updated = original.slice(0, insertAt) + RUNES_SNIPPET + original.slice(insertAt);
|
|
1470
|
-
|
|
1506
|
+
fs14.writeFileSync(filePath, updated);
|
|
1471
1507
|
return { applied: true, reason: "added runes compilerOption", file };
|
|
1472
1508
|
}
|
|
1473
1509
|
function mergeViteConfig(filePath) {
|
|
1474
|
-
if (!
|
|
1510
|
+
if (!fs14.existsSync(filePath)) {
|
|
1475
1511
|
return {
|
|
1476
1512
|
applied: false,
|
|
1477
1513
|
reason: "vite.config.ts not found",
|
|
@@ -1479,7 +1515,7 @@ function mergeViteConfig(filePath) {
|
|
|
1479
1515
|
// then add tailwindcss() to the plugins array`
|
|
1480
1516
|
};
|
|
1481
1517
|
}
|
|
1482
|
-
const original =
|
|
1518
|
+
const original = fs14.readFileSync(filePath, "utf8");
|
|
1483
1519
|
if (original.includes("@tailwindcss/vite")) {
|
|
1484
1520
|
return { applied: false, reason: "tailwindcss plugin already present" };
|
|
1485
1521
|
}
|
|
@@ -1498,14 +1534,14 @@ function mergeViteConfig(filePath) {
|
|
|
1498
1534
|
const trailing = withImport.slice(insertAt);
|
|
1499
1535
|
const prefix = /^\s*\]/.test(trailing) ? "tailwindcss()" : "tailwindcss(), ";
|
|
1500
1536
|
const updated = withImport.slice(0, insertAt) + prefix + withImport.slice(insertAt);
|
|
1501
|
-
|
|
1537
|
+
fs14.writeFileSync(filePath, updated);
|
|
1502
1538
|
return { applied: true, reason: "added @tailwindcss/vite plugin" };
|
|
1503
1539
|
}
|
|
1504
1540
|
function mergeTsconfig(filePath) {
|
|
1505
|
-
if (!
|
|
1541
|
+
if (!fs14.existsSync(filePath)) {
|
|
1506
1542
|
return { applied: false, reason: "tsconfig.json not found" };
|
|
1507
1543
|
}
|
|
1508
|
-
const original =
|
|
1544
|
+
const original = fs14.readFileSync(filePath, "utf8");
|
|
1509
1545
|
if (/rewriteRelativeImportExtensions/.test(original)) {
|
|
1510
1546
|
return { applied: false, reason: "rewriteRelativeImportExtensions already set" };
|
|
1511
1547
|
}
|
|
@@ -1521,7 +1557,7 @@ function mergeTsconfig(filePath) {
|
|
|
1521
1557
|
const indent = detectIndent(original, insertAt);
|
|
1522
1558
|
const updated = original.slice(0, insertAt) + `
|
|
1523
1559
|
${indent}"rewriteRelativeImportExtensions": true,` + original.slice(insertAt);
|
|
1524
|
-
|
|
1560
|
+
fs14.writeFileSync(filePath, updated);
|
|
1525
1561
|
return { applied: true, reason: "added rewriteRelativeImportExtensions" };
|
|
1526
1562
|
}
|
|
1527
1563
|
var GITIGNORE_ENTRIES = [
|
|
@@ -1540,7 +1576,7 @@ var GITIGNORE_ENTRIES = [
|
|
|
1540
1576
|
"/backups"
|
|
1541
1577
|
];
|
|
1542
1578
|
function mergeGitignore(filePath) {
|
|
1543
|
-
const existing =
|
|
1579
|
+
const existing = fs14.existsSync(filePath) ? fs14.readFileSync(filePath, "utf8") : "";
|
|
1544
1580
|
const lines = existing.split("\n").map((l) => l.trim());
|
|
1545
1581
|
const missing = GITIGNORE_ENTRIES.filter((entry) => !lines.includes(entry));
|
|
1546
1582
|
if (missing.length === 0) {
|
|
@@ -1549,7 +1585,7 @@ function mergeGitignore(filePath) {
|
|
|
1549
1585
|
const needsNewline = existing.length > 0 && !existing.endsWith("\n");
|
|
1550
1586
|
const appended = `${existing}${needsNewline ? "\n" : ""}${missing.join("\n")}
|
|
1551
1587
|
`;
|
|
1552
|
-
|
|
1588
|
+
fs14.writeFileSync(filePath, appended);
|
|
1553
1589
|
return { applied: true, reason: `added ${missing.length} gitignore entries` };
|
|
1554
1590
|
}
|
|
1555
1591
|
function addImport(source, importLine) {
|
|
@@ -1574,14 +1610,14 @@ function detectIndent(source, atOffset) {
|
|
|
1574
1610
|
}
|
|
1575
1611
|
|
|
1576
1612
|
// src/lib/scaffold-detect.ts
|
|
1577
|
-
import
|
|
1578
|
-
import
|
|
1613
|
+
import fs15 from "node:fs";
|
|
1614
|
+
import path13 from "node:path";
|
|
1579
1615
|
var VANILLA_MARKER = "Welcome to SvelteKit";
|
|
1580
|
-
var PAGE_REL =
|
|
1616
|
+
var PAGE_REL = path13.join("src", "routes", "+page.svelte");
|
|
1581
1617
|
function isVanillaRoutes(cwd) {
|
|
1582
|
-
const pagePath =
|
|
1583
|
-
if (!
|
|
1584
|
-
return
|
|
1618
|
+
const pagePath = path13.join(cwd, PAGE_REL);
|
|
1619
|
+
if (!fs15.existsSync(pagePath)) return false;
|
|
1620
|
+
return fs15.readFileSync(pagePath, "utf8").includes(VANILLA_MARKER);
|
|
1585
1621
|
}
|
|
1586
1622
|
|
|
1587
1623
|
// src/lib/result-report.ts
|
|
@@ -1676,7 +1712,7 @@ async function blessProject(cwdArg, options) {
|
|
|
1676
1712
|
const projectPath = cwdArg ? resolveProjectPath(cwdArg) : (await getWorkspace()).workspaceRootDir;
|
|
1677
1713
|
assertNotAlreadyBlessed(projectPath);
|
|
1678
1714
|
const templateDir = findProjectTemplate(options.template ?? DEFAULT_TEMPLATE).dir;
|
|
1679
|
-
const { email: email3, password:
|
|
1715
|
+
const { email: email3, password: password12 } = await p4.group(
|
|
1680
1716
|
{
|
|
1681
1717
|
email: () => {
|
|
1682
1718
|
if (options.email) return Promise.resolve(options.email);
|
|
@@ -1703,6 +1739,7 @@ async function blessProject(cwdArg, options) {
|
|
|
1703
1739
|
);
|
|
1704
1740
|
mergeDependencies(projectPath, templateDir);
|
|
1705
1741
|
copyVelaOnlyFiles(templateDir, projectPath);
|
|
1742
|
+
writeSiteFile(templateDir, projectPath);
|
|
1706
1743
|
ensureShadcnCss(projectPath);
|
|
1707
1744
|
hintComponentsJson(projectPath);
|
|
1708
1745
|
mergeConfigFiles(projectPath);
|
|
@@ -1719,12 +1756,12 @@ async function blessProject(cwdArg, options) {
|
|
|
1719
1756
|
}
|
|
1720
1757
|
}
|
|
1721
1758
|
p4.log.step("Initializing PocketBase...");
|
|
1722
|
-
await createSuperuser(projectPath, email3,
|
|
1759
|
+
await createSuperuser(projectPath, email3, password12);
|
|
1723
1760
|
writeEnvFile(
|
|
1724
1761
|
projectPath,
|
|
1725
1762
|
{
|
|
1726
1763
|
POCKETBASE_SUPERUSER_EMAIL: email3,
|
|
1727
|
-
POCKETBASE_SUPERUSER_PASSWORD:
|
|
1764
|
+
POCKETBASE_SUPERUSER_PASSWORD: password12
|
|
1728
1765
|
},
|
|
1729
1766
|
["PocketBase superuser credentials \u2014 used by `vela` commands"]
|
|
1730
1767
|
);
|
|
@@ -1732,7 +1769,7 @@ async function blessProject(cwdArg, options) {
|
|
|
1732
1769
|
printNextSteps(projectPath, packageManager2);
|
|
1733
1770
|
}
|
|
1734
1771
|
function ensureShadcnCss(projectPath) {
|
|
1735
|
-
if (ensureShadcnImport(
|
|
1772
|
+
if (ensureShadcnImport(path14.join(projectPath, "src", "app.css"))) {
|
|
1736
1773
|
p4.log.info(
|
|
1737
1774
|
"src/app.css: added the shadcn-svelte/tailwind.css import its registry components rely on."
|
|
1738
1775
|
);
|
|
@@ -1744,22 +1781,22 @@ function hintComponentsJson(projectPath) {
|
|
|
1744
1781
|
for (const hint of componentsJsonHints(config)) p4.log.warn(hint);
|
|
1745
1782
|
}
|
|
1746
1783
|
function resolveProjectPath(cwdArg) {
|
|
1747
|
-
const projectPath =
|
|
1748
|
-
if (!
|
|
1784
|
+
const projectPath = path14.resolve(cwdArg);
|
|
1785
|
+
if (!fs16.existsSync(projectPath)) {
|
|
1749
1786
|
throw new Error(`Path does not exist: ${projectPath}`);
|
|
1750
1787
|
}
|
|
1751
|
-
if (!
|
|
1788
|
+
if (!fs16.existsSync(path14.join(projectPath, "package.json"))) {
|
|
1752
1789
|
throw new Error(`No package.json found at ${projectPath}`);
|
|
1753
1790
|
}
|
|
1754
|
-
if (!
|
|
1791
|
+
if (!fs16.existsSync(path14.join(projectPath, "src", "routes"))) {
|
|
1755
1792
|
throw new Error(`No src/routes directory found at ${projectPath}`);
|
|
1756
1793
|
}
|
|
1757
1794
|
return projectPath;
|
|
1758
1795
|
}
|
|
1759
1796
|
function assertNotAlreadyBlessed(projectPath) {
|
|
1760
|
-
const hooksPath =
|
|
1761
|
-
if (!
|
|
1762
|
-
const content =
|
|
1797
|
+
const hooksPath = path14.join(projectPath, "src", "hooks.server.ts");
|
|
1798
|
+
if (!fs16.existsSync(hooksPath)) return;
|
|
1799
|
+
const content = fs16.readFileSync(hooksPath, "utf8");
|
|
1763
1800
|
if (content.includes("@velastack/pocketbase")) {
|
|
1764
1801
|
throw new Error(
|
|
1765
1802
|
"This project already looks blessed (src/hooks.server.ts imports @velastack/pocketbase). Run `vela sync` instead."
|
|
@@ -1767,8 +1804,8 @@ function assertNotAlreadyBlessed(projectPath) {
|
|
|
1767
1804
|
}
|
|
1768
1805
|
}
|
|
1769
1806
|
function mergeDependencies(projectPath, templateDir) {
|
|
1770
|
-
const userPkgPath =
|
|
1771
|
-
const templatePkgPath =
|
|
1807
|
+
const userPkgPath = path14.join(projectPath, "package.json");
|
|
1808
|
+
const templatePkgPath = path14.join(templateDir, "package.template.json");
|
|
1772
1809
|
const userPkg = readPackageJson(userPkgPath);
|
|
1773
1810
|
const appName = typeof userPkg.name === "string" ? userPkg.name : "sveltekit";
|
|
1774
1811
|
const templatePkg = readTemplatePackageJson(templatePkgPath, {
|
|
@@ -1803,24 +1840,46 @@ ${lines.join("\n")}`);
|
|
|
1803
1840
|
function copyVelaOnlyFiles(templateDir, projectPath) {
|
|
1804
1841
|
const kept = [];
|
|
1805
1842
|
for (const file of VELA_ONLY_FILES) {
|
|
1806
|
-
const src =
|
|
1807
|
-
const dest =
|
|
1808
|
-
if (!
|
|
1809
|
-
if (
|
|
1843
|
+
const src = path14.join(templateDir, templateName(file.path));
|
|
1844
|
+
const dest = path14.join(projectPath, file.path);
|
|
1845
|
+
if (!fs16.existsSync(src)) continue;
|
|
1846
|
+
if (fs16.existsSync(dest)) {
|
|
1810
1847
|
kept.push(file);
|
|
1811
1848
|
continue;
|
|
1812
1849
|
}
|
|
1813
|
-
|
|
1814
|
-
|
|
1850
|
+
fs16.mkdirSync(path14.dirname(dest), { recursive: true });
|
|
1851
|
+
fs16.copyFileSync(src, dest);
|
|
1815
1852
|
}
|
|
1816
1853
|
reportKeptFiles(kept);
|
|
1817
1854
|
for (const rel of VELA_ONLY_DIRS) {
|
|
1818
|
-
const src =
|
|
1819
|
-
const dest =
|
|
1820
|
-
if (!
|
|
1855
|
+
const src = path14.join(templateDir, rel);
|
|
1856
|
+
const dest = path14.join(projectPath, rel);
|
|
1857
|
+
if (!fs16.existsSync(src)) continue;
|
|
1821
1858
|
copyDirShallow(src, dest);
|
|
1822
1859
|
}
|
|
1823
1860
|
}
|
|
1861
|
+
function writeSiteFile(templateDir, projectPath) {
|
|
1862
|
+
const source = path14.join(templateDir, SITE_FILE.replace(/\.ts$/, ".template.ts"));
|
|
1863
|
+
const dest = path14.join(projectPath, SITE_FILE);
|
|
1864
|
+
if (!fs16.existsSync(source)) return;
|
|
1865
|
+
if (fs16.existsSync(dest)) {
|
|
1866
|
+
p4.log.info(
|
|
1867
|
+
`Kept your ${pc3.bold(SITE_FILE)}. Vela's layouts read ${pc3.cyan("name")} and ${pc3.cyan("url")} from its ${pc3.cyan("site")} export.`
|
|
1868
|
+
);
|
|
1869
|
+
return;
|
|
1870
|
+
}
|
|
1871
|
+
const userPkg = readPackageJson(path14.join(projectPath, "package.json"));
|
|
1872
|
+
const appName = typeof userPkg.name === "string" && userPkg.name ? userPkg.name : "SvelteKit";
|
|
1873
|
+
fs16.mkdirSync(path14.dirname(dest), { recursive: true });
|
|
1874
|
+
fs16.writeFileSync(
|
|
1875
|
+
dest,
|
|
1876
|
+
fillTemplatePlaceholders(fs16.readFileSync(source, "utf8"), {
|
|
1877
|
+
appName,
|
|
1878
|
+
cliVersion: package_default.version
|
|
1879
|
+
})
|
|
1880
|
+
);
|
|
1881
|
+
p4.log.info(`Wrote ${pc3.bold(SITE_FILE)}, naming the app ${pc3.cyan(appName)}. Edit it to rename.`);
|
|
1882
|
+
}
|
|
1824
1883
|
function reportKeptFiles(kept) {
|
|
1825
1884
|
if (kept.length === 0) return;
|
|
1826
1885
|
const padding = Math.max(...kept.map((f) => f.path.length));
|
|
@@ -1831,15 +1890,15 @@ ${lines.join("\n")}`
|
|
|
1831
1890
|
);
|
|
1832
1891
|
}
|
|
1833
1892
|
function copyDirShallow(src, dest) {
|
|
1834
|
-
|
|
1835
|
-
for (const entry of
|
|
1893
|
+
fs16.mkdirSync(dest, { recursive: true });
|
|
1894
|
+
for (const entry of fs16.readdirSync(src, { withFileTypes: true })) {
|
|
1836
1895
|
if (entry.name === ".DS_Store") continue;
|
|
1837
|
-
const srcChild =
|
|
1838
|
-
const destChild =
|
|
1896
|
+
const srcChild = path14.join(src, entry.name);
|
|
1897
|
+
const destChild = path14.join(dest, entry.name);
|
|
1839
1898
|
if (entry.isDirectory()) {
|
|
1840
1899
|
copyDirShallow(srcChild, destChild);
|
|
1841
|
-
} else if (entry.isFile() && !
|
|
1842
|
-
|
|
1900
|
+
} else if (entry.isFile() && !fs16.existsSync(destChild)) {
|
|
1901
|
+
fs16.copyFileSync(srcChild, destChild);
|
|
1843
1902
|
}
|
|
1844
1903
|
}
|
|
1845
1904
|
}
|
|
@@ -1847,9 +1906,9 @@ function mergeConfigFiles(projectPath) {
|
|
|
1847
1906
|
const runes = mergeSvelteConfig(projectPath);
|
|
1848
1907
|
const outcomes = [
|
|
1849
1908
|
[runes.file ?? "svelte.config", runes],
|
|
1850
|
-
["vite.config.ts", mergeViteConfig(
|
|
1851
|
-
["tsconfig.json", mergeTsconfig(
|
|
1852
|
-
[".gitignore", mergeGitignore(
|
|
1909
|
+
["vite.config.ts", mergeViteConfig(path14.join(projectPath, "vite.config.ts"))],
|
|
1910
|
+
["tsconfig.json", mergeTsconfig(path14.join(projectPath, "tsconfig.json"))],
|
|
1911
|
+
[".gitignore", mergeGitignore(path14.join(projectPath, ".gitignore"))]
|
|
1853
1912
|
];
|
|
1854
1913
|
for (const [name, outcome] of outcomes) {
|
|
1855
1914
|
if (outcome.applied) {
|
|
@@ -1866,14 +1925,14 @@ ${pc3.cyan(outcome.snippet)}`
|
|
|
1866
1925
|
}
|
|
1867
1926
|
}
|
|
1868
1927
|
function mergeAppDts(templateDir, projectPath) {
|
|
1869
|
-
const dest =
|
|
1870
|
-
const templateFile =
|
|
1871
|
-
if (!
|
|
1872
|
-
if (!
|
|
1873
|
-
|
|
1928
|
+
const dest = path14.join(projectPath, "src", "app.d.ts");
|
|
1929
|
+
const templateFile = path14.join(templateDir, "src", "app.d.ts");
|
|
1930
|
+
if (!fs16.existsSync(dest)) {
|
|
1931
|
+
if (!fs16.existsSync(templateFile)) return;
|
|
1932
|
+
fs16.copyFileSync(templateFile, dest);
|
|
1874
1933
|
return;
|
|
1875
1934
|
}
|
|
1876
|
-
const current =
|
|
1935
|
+
const current = fs16.readFileSync(dest, "utf8");
|
|
1877
1936
|
if (current.includes("namespace Superforms")) return;
|
|
1878
1937
|
const block = ` namespace Superforms {
|
|
1879
1938
|
type Message = {
|
|
@@ -1892,7 +1951,7 @@ ${pc3.cyan(block)}`
|
|
|
1892
1951
|
}
|
|
1893
1952
|
const insertAt = match.index + match[0].length;
|
|
1894
1953
|
const updated = current.slice(0, insertAt) + block + current.slice(insertAt);
|
|
1895
|
-
|
|
1954
|
+
fs16.writeFileSync(dest, updated);
|
|
1896
1955
|
}
|
|
1897
1956
|
function maybeReplaceRoutes(projectPath, templateDir, options) {
|
|
1898
1957
|
if (options.skipRoutes) {
|
|
@@ -1903,12 +1962,12 @@ function maybeReplaceRoutes(projectPath, templateDir, options) {
|
|
|
1903
1962
|
p4.log.info("Leaving src/routes alone (looks customized).");
|
|
1904
1963
|
return;
|
|
1905
1964
|
}
|
|
1906
|
-
const target =
|
|
1907
|
-
|
|
1908
|
-
const src =
|
|
1909
|
-
|
|
1965
|
+
const target = path14.join(projectPath, "src", "routes");
|
|
1966
|
+
fs16.rmSync(target, { recursive: true, force: true });
|
|
1967
|
+
const src = path14.join(templateDir, "src", "routes");
|
|
1968
|
+
fs16.cpSync(src, target, {
|
|
1910
1969
|
recursive: true,
|
|
1911
|
-
filter: (s) =>
|
|
1970
|
+
filter: (s) => path14.basename(s) !== ".DS_Store"
|
|
1912
1971
|
});
|
|
1913
1972
|
p4.log.success("Replaced src/routes with the vela template.");
|
|
1914
1973
|
}
|
|
@@ -1917,7 +1976,7 @@ function summarize(names) {
|
|
|
1917
1976
|
return `${names.slice(0, 3).join(", ")}, and ${names.length - 3} more`;
|
|
1918
1977
|
}
|
|
1919
1978
|
function printNextSteps(projectPath, packageManager2) {
|
|
1920
|
-
const relative =
|
|
1979
|
+
const relative = path14.relative(process7.cwd(), projectPath);
|
|
1921
1980
|
const pm = packageManager2 ?? getUserAgent() ?? "npm";
|
|
1922
1981
|
const nextSteps = [];
|
|
1923
1982
|
if (relative !== "") {
|
|
@@ -1941,8 +2000,8 @@ function printNextSteps(projectPath, packageManager2) {
|
|
|
1941
2000
|
}
|
|
1942
2001
|
|
|
1943
2002
|
// src/commands/create.ts
|
|
1944
|
-
import
|
|
1945
|
-
import
|
|
2003
|
+
import fs18 from "node:fs";
|
|
2004
|
+
import path16 from "node:path";
|
|
1946
2005
|
import process11 from "node:process";
|
|
1947
2006
|
import * as v4 from "valibot";
|
|
1948
2007
|
import { Command as Command4 } from "commander";
|
|
@@ -2041,7 +2100,9 @@ async function collectProviderEnv(provider) {
|
|
|
2041
2100
|
values[variable.key] = variable.default ?? "";
|
|
2042
2101
|
continue;
|
|
2043
2102
|
}
|
|
2044
|
-
const value = await p5.
|
|
2103
|
+
const value = variable.secret ? await p5.password({
|
|
2104
|
+
message: variable.placeholder ? `${variable.label} (${variable.placeholder})` : variable.label
|
|
2105
|
+
}) : await p5.text({
|
|
2045
2106
|
message: variable.label,
|
|
2046
2107
|
placeholder: variable.placeholder,
|
|
2047
2108
|
initialValue: variable.default
|
|
@@ -2262,16 +2323,16 @@ function toLinked(project, team) {
|
|
|
2262
2323
|
}
|
|
2263
2324
|
|
|
2264
2325
|
// src/lib/project-config.ts
|
|
2265
|
-
import
|
|
2266
|
-
import
|
|
2326
|
+
import fs17 from "node:fs";
|
|
2327
|
+
import path15 from "node:path";
|
|
2267
2328
|
function projectConfigPath(workspaceRootDir) {
|
|
2268
|
-
return
|
|
2329
|
+
return path15.join(workspaceRootDir, ".vela", "project.json");
|
|
2269
2330
|
}
|
|
2270
2331
|
function readProjectConfig(workspaceRootDir) {
|
|
2271
2332
|
const file = projectConfigPath(workspaceRootDir);
|
|
2272
|
-
if (!
|
|
2333
|
+
if (!fs17.existsSync(file)) return null;
|
|
2273
2334
|
try {
|
|
2274
|
-
const parsed = JSON.parse(
|
|
2335
|
+
const parsed = JSON.parse(fs17.readFileSync(file, "utf8"));
|
|
2275
2336
|
if (typeof parsed.projectId !== "string" || typeof parsed.teamId !== "string" || typeof parsed.projectName !== "string") {
|
|
2276
2337
|
return null;
|
|
2277
2338
|
}
|
|
@@ -2286,15 +2347,15 @@ function readProjectConfig(workspaceRootDir) {
|
|
|
2286
2347
|
}
|
|
2287
2348
|
function writeProjectConfig(workspaceRootDir, config) {
|
|
2288
2349
|
const file = projectConfigPath(workspaceRootDir);
|
|
2289
|
-
|
|
2350
|
+
fs17.mkdirSync(path15.dirname(file), { recursive: true });
|
|
2290
2351
|
let existing = {};
|
|
2291
|
-
if (
|
|
2352
|
+
if (fs17.existsSync(file)) {
|
|
2292
2353
|
try {
|
|
2293
|
-
existing = JSON.parse(
|
|
2354
|
+
existing = JSON.parse(fs17.readFileSync(file, "utf8"));
|
|
2294
2355
|
} catch {
|
|
2295
2356
|
}
|
|
2296
2357
|
}
|
|
2297
|
-
|
|
2358
|
+
fs17.writeFileSync(file, JSON.stringify({ ...existing, ...config }, null, 2) + "\n");
|
|
2298
2359
|
}
|
|
2299
2360
|
|
|
2300
2361
|
// src/commands/login.ts
|
|
@@ -2310,7 +2371,7 @@ var login = new Command3("login").description("login to velastack.dev").configur
|
|
|
2310
2371
|
}, "Failed to login.")
|
|
2311
2372
|
);
|
|
2312
2373
|
async function loginInteractively() {
|
|
2313
|
-
const { email: email3, password:
|
|
2374
|
+
const { email: email3, password: password12 } = await p7.group(
|
|
2314
2375
|
{
|
|
2315
2376
|
email: () => p7.text({ message: "Email" }),
|
|
2316
2377
|
password: () => p7.password({ message: "Password" })
|
|
@@ -2329,7 +2390,7 @@ async function loginInteractively() {
|
|
|
2329
2390
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
2330
2391
|
Origin: API_URL
|
|
2331
2392
|
},
|
|
2332
|
-
body: new URLSearchParams({ type: "password", email: email3, password:
|
|
2393
|
+
body: new URLSearchParams({ type: "password", email: email3, password: password12 }).toString()
|
|
2333
2394
|
});
|
|
2334
2395
|
if (!loginRes.headers.get("Set-Cookie")) {
|
|
2335
2396
|
throw new Error(
|
|
@@ -2420,7 +2481,7 @@ function checkFlagsForTemplate(template, options) {
|
|
|
2420
2481
|
throw new Error("--team only applies together with --link new.");
|
|
2421
2482
|
}
|
|
2422
2483
|
}
|
|
2423
|
-
var create = new Command4("create").description("scaffold a new velastack project").argument("[path]", "where the project will be created").option("--template <type>", "template to scaffold (built-in or from the registry)", "minimal").option("--no-install", "skip installing dependencies").option("--name <name>", "app name
|
|
2484
|
+
var create = new Command4("create").description("scaffold a new velastack project").argument("[path]", "where the project will be created").option("--template <type>", "template to scaffold (built-in or from the registry)", "minimal").option("--no-install", "skip installing dependencies").option("--name <name>", "app name, written to src/lib/site.ts").option("--email <email>", "email of the admin user").option("--password <password>", "password of the admin user").option(
|
|
2424
2485
|
"--link <new|none|project-id>",
|
|
2425
2486
|
"link to a velastack.dev project: create one, skip, or use an existing project id (default: create when logged in at a terminal)"
|
|
2426
2487
|
).option("--team <id>", "velastack.dev team for `--link new` (default: your personal team)").option(
|
|
@@ -2435,7 +2496,7 @@ var create = new Command4("create").description("scaffold a new velastack projec
|
|
|
2435
2496
|
options,
|
|
2436
2497
|
listing
|
|
2437
2498
|
);
|
|
2438
|
-
const relative =
|
|
2499
|
+
const relative = path16.relative(process11.cwd(), directory);
|
|
2439
2500
|
const pm = packageManager2 ?? (await detect3({ cwd: directory }))?.name ?? getUserAgent() ?? "npm";
|
|
2440
2501
|
const nextSteps = [];
|
|
2441
2502
|
if (relative !== "") {
|
|
@@ -2460,6 +2521,7 @@ var create = new Command4("create").description("scaffold a new velastack projec
|
|
|
2460
2521
|
nextSteps.push(...template.nextSteps);
|
|
2461
2522
|
} else if (template.backend) {
|
|
2462
2523
|
nextSteps.push("Run `vela generate scaffold <model>` to generate your first CRUD pages.");
|
|
2524
|
+
nextSteps.push("Set your deployed URL in `src/lib/site.ts` before deploying.");
|
|
2463
2525
|
} else {
|
|
2464
2526
|
nextSteps.push(
|
|
2465
2527
|
"Set your deployed URL in `src/lib/site.ts` before building for production."
|
|
@@ -2483,7 +2545,7 @@ async function createProject2(cwdArg, options, listing) {
|
|
|
2483
2545
|
checkFlagsForTemplate(template, options);
|
|
2484
2546
|
let directory;
|
|
2485
2547
|
if (cwdArg) {
|
|
2486
|
-
directory =
|
|
2548
|
+
directory = path16.resolve(cwdArg);
|
|
2487
2549
|
} else {
|
|
2488
2550
|
const answer = await p8.text({
|
|
2489
2551
|
message: "Where would you like your project to be created?",
|
|
@@ -2491,22 +2553,22 @@ async function createProject2(cwdArg, options, listing) {
|
|
|
2491
2553
|
defaultValue: "./"
|
|
2492
2554
|
});
|
|
2493
2555
|
if (p8.isCancel(answer)) onCancel2();
|
|
2494
|
-
directory =
|
|
2556
|
+
directory = path16.resolve(answer);
|
|
2495
2557
|
}
|
|
2496
|
-
if (
|
|
2558
|
+
if (fs18.existsSync(directory) && fs18.readdirSync(directory).filter((f) => !f.startsWith(".git")).length > 0) {
|
|
2497
2559
|
const force = await p8.confirm({
|
|
2498
2560
|
message: "Directory not empty. Continue?",
|
|
2499
2561
|
initialValue: false
|
|
2500
2562
|
});
|
|
2501
2563
|
if (p8.isCancel(force) || !force) onCancel2();
|
|
2502
2564
|
}
|
|
2503
|
-
const dirName =
|
|
2565
|
+
const dirName = path16.basename(directory);
|
|
2504
2566
|
const { name } = await p8.group(
|
|
2505
2567
|
{
|
|
2506
2568
|
name: () => {
|
|
2507
2569
|
if (options.name) return Promise.resolve(options.name);
|
|
2508
2570
|
return p8.text({
|
|
2509
|
-
message: "App name (
|
|
2571
|
+
message: "App name (written to src/lib/site.ts)",
|
|
2510
2572
|
initialValue: dirName || "SvelteKit",
|
|
2511
2573
|
validate: (value) => value?.trim() ? void 0 : "App name is required"
|
|
2512
2574
|
});
|
|
@@ -2529,7 +2591,7 @@ async function createProject2(cwdArg, options, listing) {
|
|
|
2529
2591
|
} finally {
|
|
2530
2592
|
resolved.cleanup();
|
|
2531
2593
|
}
|
|
2532
|
-
if (!
|
|
2594
|
+
if (!fs18.existsSync(path16.join(projectPath, "package.json"))) {
|
|
2533
2595
|
throw new Error(`Template ${template.name} is missing package.template.json`);
|
|
2534
2596
|
}
|
|
2535
2597
|
if (link2.linked) {
|
|
@@ -2548,9 +2610,9 @@ async function createProject2(cwdArg, options, listing) {
|
|
|
2548
2610
|
}
|
|
2549
2611
|
}
|
|
2550
2612
|
if (credentials) {
|
|
2551
|
-
const { email: email3, password:
|
|
2613
|
+
const { email: email3, password: password12 } = credentials;
|
|
2552
2614
|
p8.log.step("Initializing PocketBase...");
|
|
2553
|
-
await createSuperuser(projectPath, email3,
|
|
2615
|
+
await createSuperuser(projectPath, email3, password12);
|
|
2554
2616
|
await withPocketbase(
|
|
2555
2617
|
projectPath,
|
|
2556
2618
|
async (pb) => {
|
|
@@ -2558,13 +2620,13 @@ async function createProject2(cwdArg, options, listing) {
|
|
|
2558
2620
|
meta: { appName: name, appURL: "http://localhost:5173" }
|
|
2559
2621
|
});
|
|
2560
2622
|
},
|
|
2561
|
-
{ email: email3, password:
|
|
2623
|
+
{ email: email3, password: password12 }
|
|
2562
2624
|
);
|
|
2563
2625
|
writeEnvFile(
|
|
2564
2626
|
projectPath,
|
|
2565
2627
|
{
|
|
2566
2628
|
POCKETBASE_SUPERUSER_EMAIL: email3,
|
|
2567
|
-
POCKETBASE_SUPERUSER_PASSWORD:
|
|
2629
|
+
POCKETBASE_SUPERUSER_PASSWORD: password12
|
|
2568
2630
|
},
|
|
2569
2631
|
["PocketBase superuser credentials \u2014 used by `vela` commands"]
|
|
2570
2632
|
);
|
|
@@ -2686,11 +2748,11 @@ import { Command as Command5 } from "commander";
|
|
|
2686
2748
|
import * as p14 from "@clack/prompts";
|
|
2687
2749
|
|
|
2688
2750
|
// src/lib/pattern-runner.ts
|
|
2689
|
-
import
|
|
2751
|
+
import path17 from "node:path";
|
|
2690
2752
|
import * as p9 from "@clack/prompts";
|
|
2691
2753
|
import { bySlug as bySlug2 } from "@velastack/patterns";
|
|
2692
2754
|
function toRelative(root, filePath) {
|
|
2693
|
-
return
|
|
2755
|
+
return path17.isAbsolute(filePath) ? path17.relative(root, filePath) : filePath;
|
|
2694
2756
|
}
|
|
2695
2757
|
var isSuccess = (f) => (f.status ?? "success") === "success";
|
|
2696
2758
|
async function runPattern(slug2, argv, input, report4) {
|
|
@@ -2759,10 +2821,10 @@ async function runPattern(slug2, argv, input, report4) {
|
|
|
2759
2821
|
}
|
|
2760
2822
|
|
|
2761
2823
|
// src/lib/form-ui.ts
|
|
2762
|
-
import
|
|
2824
|
+
import path18 from "node:path";
|
|
2763
2825
|
var UIS = ["shadcn", "plain"];
|
|
2764
2826
|
function detectFormInput(root) {
|
|
2765
|
-
const pkg = readPackageJson(
|
|
2827
|
+
const pkg = readPackageJson(path18.join(root, "package.json"));
|
|
2766
2828
|
const hasDep = (name) => Boolean(pkg.dependencies?.[name] || pkg.devDependencies?.[name]);
|
|
2767
2829
|
return {
|
|
2768
2830
|
flash: hasDep("sveltekit-flash-message"),
|
|
@@ -2784,8 +2846,8 @@ function resolveFormInput(root, detectedUi, requested) {
|
|
|
2784
2846
|
}
|
|
2785
2847
|
|
|
2786
2848
|
// src/lib/ai-flow.ts
|
|
2787
|
-
import
|
|
2788
|
-
import
|
|
2849
|
+
import fs19 from "node:fs";
|
|
2850
|
+
import path19 from "node:path";
|
|
2789
2851
|
import * as p13 from "@clack/prompts";
|
|
2790
2852
|
import pc4 from "picocolors";
|
|
2791
2853
|
|
|
@@ -3060,15 +3122,15 @@ function specToArgv(spec) {
|
|
|
3060
3122
|
return collectionSpecToArgv(spec);
|
|
3061
3123
|
}
|
|
3062
3124
|
function writeLayoutSidecar(workspaceRootDir, modelName, layout) {
|
|
3063
|
-
const dir =
|
|
3064
|
-
|
|
3065
|
-
const file =
|
|
3066
|
-
|
|
3067
|
-
return
|
|
3125
|
+
const dir = path19.join(workspaceRootDir, "data", "ai-form-layouts");
|
|
3126
|
+
fs19.mkdirSync(dir, { recursive: true });
|
|
3127
|
+
const file = path19.join(dir, `${modelName}.json`);
|
|
3128
|
+
fs19.writeFileSync(file, JSON.stringify(layout, null, 2) + "\n");
|
|
3129
|
+
return path19.relative(workspaceRootDir, file);
|
|
3068
3130
|
}
|
|
3069
3131
|
|
|
3070
3132
|
// src/commands/generate/form.ts
|
|
3071
|
-
var form = new Command5("form").description("generate a form from a model").argument("[model]", 'model name (e.g. "contact")').argument("[fields...]", 'field definitions (e.g. "name:text", "email:email")').option("--remote", "generate
|
|
3133
|
+
var form = new Command5("form").description("generate a form from a model").argument("[model]", 'model name (e.g. "contact")').argument("[fields...]", 'field definitions (e.g. "name:text", "email:email")').option("--remote", "generate the form with SvelteKit remote functions instead of superforms").option(
|
|
3072
3134
|
"--route <route>",
|
|
3073
3135
|
'place the form at a custom route (e.g. "(app)/[team_id]/projects/new"). Defaults to the model name under the (app) or (public) group, or src/routes when it has neither.'
|
|
3074
3136
|
).option(
|
|
@@ -3212,7 +3274,7 @@ var resource = new Command7("resource").description("generate a resource (model
|
|
|
3212
3274
|
// src/commands/generate/scaffold.ts
|
|
3213
3275
|
import { Command as Command8 } from "commander";
|
|
3214
3276
|
import * as p16 from "@clack/prompts";
|
|
3215
|
-
var scaffold = new Command8("scaffold").description("generate a full CRUD scaffold (model, forms, list, detail)").argument("[model]", "model name").argument("[fields...]", "field definitions").option("--remote", "generate
|
|
3277
|
+
var scaffold = new Command8("scaffold").description("generate a full CRUD scaffold (model, forms, list, detail)").argument("[model]", "model name").argument("[fields...]", "field definitions").option("--remote", "generate create/update forms with SvelteKit remote functions").option(
|
|
3216
3278
|
"--route <route>",
|
|
3217
3279
|
'place the scaffold at a custom route (e.g. "(app)/[team_id]/projects"). Defaults to the pluralized model name under the (app) or (public) group, or src/routes when it has neither.'
|
|
3218
3280
|
).option(
|
|
@@ -3330,11 +3392,44 @@ var workflow = new Command10("workflow").description("generate a background work
|
|
|
3330
3392
|
var generate = new Command11("generate").description("generate scaffolding for database models and forms").configureHelp(helpConfig).addCommand(form).addCommand(schema).addCommand(resource).addCommand(scaffold).addCommand(migration).addCommand(workflow);
|
|
3331
3393
|
|
|
3332
3394
|
// src/commands/enable.ts
|
|
3333
|
-
import { Command as
|
|
3395
|
+
import { Command as Command29 } from "commander";
|
|
3334
3396
|
|
|
3335
|
-
// src/commands/enable/
|
|
3397
|
+
// src/commands/enable/ai.ts
|
|
3336
3398
|
import { Command as Command12 } from "commander";
|
|
3337
|
-
var
|
|
3399
|
+
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").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
3400
|
+
(opts, cmd) => runCommand(async () => {
|
|
3401
|
+
const provider = await resolveProvider("enable-ai", opts.provider);
|
|
3402
|
+
const providerEnv = await collectProviderEnv(provider);
|
|
3403
|
+
const blank = missingEnvKeys(provider, providerEnv);
|
|
3404
|
+
const keys = (provider.env ?? []).map((variable) => variable.key);
|
|
3405
|
+
const { workspaceRootDir, features } = await getWorkspace();
|
|
3406
|
+
const { serverTests } = detectFormInput(workspaceRootDir);
|
|
3407
|
+
await runPattern(
|
|
3408
|
+
"enable-ai",
|
|
3409
|
+
cmd.args,
|
|
3410
|
+
{ provider: provider.id, providerEnv, serverTests },
|
|
3411
|
+
{
|
|
3412
|
+
summary: `Enabled AI with ${provider.label}.`,
|
|
3413
|
+
nextSteps: [
|
|
3414
|
+
...blank.map((key) => `Set ${key} in .env; /api/chat answers 503 until it is set.`),
|
|
3415
|
+
"Run `vela dev` and open /ai to chat.",
|
|
3416
|
+
features.auth ? "Only signed-in users can call /api/chat, and the /ai page sits behind sign-in." : "/api/chat is open to anyone who can reach the site, and every reply is billed to your key: put it behind sign-in or a rate limit before you deploy.",
|
|
3417
|
+
`Set ${keys.join(" and ")} on each deploy target with \`vela env set\`.`,
|
|
3418
|
+
"Pick the model in src/lib/server/ai.ts and the instructions in src/routes/api/chat/+server.ts."
|
|
3419
|
+
],
|
|
3420
|
+
task: {
|
|
3421
|
+
title: "Enabling AI",
|
|
3422
|
+
success: `Enabled AI with ${provider.label}`,
|
|
3423
|
+
error: "Failed to enable AI"
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3426
|
+
);
|
|
3427
|
+
}, "Failed to enable AI.")
|
|
3428
|
+
);
|
|
3429
|
+
|
|
3430
|
+
// src/commands/enable/analytics.ts
|
|
3431
|
+
import { Command as Command13 } from "commander";
|
|
3432
|
+
var analytics = new Command13("analytics").description("enable web analytics (Plausible, Google Analytics or PostHog)").option("--provider <provider>", "analytics provider: plausible, google or posthog").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
3338
3433
|
(opts, cmd) => runCommand(async () => {
|
|
3339
3434
|
const provider = await resolveProvider("enable-analytics", opts.provider);
|
|
3340
3435
|
const providerEnv = await collectProviderEnv(provider);
|
|
@@ -3364,8 +3459,8 @@ var analytics = new Command12("analytics").description("enable web analytics (Pl
|
|
|
3364
3459
|
);
|
|
3365
3460
|
|
|
3366
3461
|
// src/commands/enable/auth.ts
|
|
3367
|
-
import { Command as
|
|
3368
|
-
var auth = new
|
|
3462
|
+
import { Command as Command14 } from "commander";
|
|
3463
|
+
var auth = new Command14("auth").description("enable authentication (email/password + OAuth scaffold)").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
3369
3464
|
(_opts, cmd) => runCommand(
|
|
3370
3465
|
() => runPattern(
|
|
3371
3466
|
"enable-auth",
|
|
@@ -3390,8 +3485,8 @@ var auth = new Command13("auth").description("enable authentication (email/passw
|
|
|
3390
3485
|
);
|
|
3391
3486
|
|
|
3392
3487
|
// src/commands/enable/api.ts
|
|
3393
|
-
import { Command as
|
|
3394
|
-
var api = new
|
|
3488
|
+
import { Command as Command15 } from "commander";
|
|
3489
|
+
var api = new Command15("api").description("enable the PocketBase REST API").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
3395
3490
|
(_opts, cmd) => runCommand(
|
|
3396
3491
|
() => runPattern(
|
|
3397
3492
|
"enable-api",
|
|
@@ -3416,8 +3511,8 @@ var api = new Command14("api").description("enable the PocketBase REST API").all
|
|
|
3416
3511
|
);
|
|
3417
3512
|
|
|
3418
3513
|
// src/commands/enable/api-keys.ts
|
|
3419
|
-
import { Command as
|
|
3420
|
-
var apiKeys = new
|
|
3514
|
+
import { Command as Command16 } from "commander";
|
|
3515
|
+
var apiKeys = new Command16("api-keys").description("enable API key management").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
3421
3516
|
(_opts, cmd) => runCommand(
|
|
3422
3517
|
() => runPattern(
|
|
3423
3518
|
"enable-api-keys",
|
|
@@ -3442,8 +3537,8 @@ var apiKeys = new Command15("api-keys").description("enable API key management")
|
|
|
3442
3537
|
);
|
|
3443
3538
|
|
|
3444
3539
|
// src/commands/enable/backend.ts
|
|
3445
|
-
import { Command as
|
|
3446
|
-
var backend = new
|
|
3540
|
+
import { Command as Command17 } from "commander";
|
|
3541
|
+
var backend = new Command17("backend").description("enable the PocketBase backend").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
3447
3542
|
(_opts, cmd) => runCommand(
|
|
3448
3543
|
() => runPattern(
|
|
3449
3544
|
"enable-backend",
|
|
@@ -3468,8 +3563,8 @@ var backend = new Command16("backend").description("enable the PocketBase backen
|
|
|
3468
3563
|
);
|
|
3469
3564
|
|
|
3470
3565
|
// src/commands/enable/i18n.ts
|
|
3471
|
-
import { Command as
|
|
3472
|
-
var i18n = new
|
|
3566
|
+
import { Command as Command18 } from "commander";
|
|
3567
|
+
var i18n = new Command18("i18n").description("enable internationalization").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
3473
3568
|
(_opts, cmd) => runCommand(
|
|
3474
3569
|
() => runPattern(
|
|
3475
3570
|
"enable-i18n",
|
|
@@ -3480,7 +3575,7 @@ var i18n = new Command17("i18n").description("enable internationalization").allo
|
|
|
3480
3575
|
nextSteps: [
|
|
3481
3576
|
"Add or adjust locales in wuchale.config.js.",
|
|
3482
3577
|
"Run `vela i18n extract` to pull translatable strings from your components.",
|
|
3483
|
-
"Edit the generated .po files under locales/ to add translations."
|
|
3578
|
+
"Edit the generated .po files under src/locales/ to add translations."
|
|
3484
3579
|
],
|
|
3485
3580
|
task: {
|
|
3486
3581
|
title: "Enabling i18n",
|
|
@@ -3494,8 +3589,8 @@ var i18n = new Command17("i18n").description("enable internationalization").allo
|
|
|
3494
3589
|
);
|
|
3495
3590
|
|
|
3496
3591
|
// src/commands/enable/teams.ts
|
|
3497
|
-
import { Command as
|
|
3498
|
-
var teams = new
|
|
3592
|
+
import { Command as Command19 } from "commander";
|
|
3593
|
+
var teams = new Command19("teams").description("enable team / multi-tenant support").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
3499
3594
|
(_opts, cmd) => runCommand(
|
|
3500
3595
|
() => runPattern(
|
|
3501
3596
|
"enable-teams",
|
|
@@ -3521,10 +3616,10 @@ var teams = new Command18("teams").description("enable team / multi-tenant suppo
|
|
|
3521
3616
|
|
|
3522
3617
|
// src/commands/enable/payments.ts
|
|
3523
3618
|
import process12 from "node:process";
|
|
3524
|
-
import { Command as
|
|
3619
|
+
import { Command as Command20 } from "commander";
|
|
3525
3620
|
import * as p17 from "@clack/prompts";
|
|
3526
3621
|
var PROVIDERS = [{ value: "stripe", label: "Stripe" }];
|
|
3527
|
-
var payments = new
|
|
3622
|
+
var payments = new Command20("payments").description("enable payments").option("--provider <provider>", "payment provider", "stripe").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
3528
3623
|
(opts, cmd) => runCommand(async () => {
|
|
3529
3624
|
const provider = await resolveProvider2(opts.provider, cmd.getOptionValueSource("provider"));
|
|
3530
3625
|
const input = {
|
|
@@ -3621,8 +3716,8 @@ async function promptPassword(message) {
|
|
|
3621
3716
|
}
|
|
3622
3717
|
|
|
3623
3718
|
// src/commands/enable/subscriptions.ts
|
|
3624
|
-
import { Command as
|
|
3625
|
-
var subscriptions = new
|
|
3719
|
+
import { Command as Command21 } from "commander";
|
|
3720
|
+
var subscriptions = new Command21("subscriptions").description("enable Stripe subscriptions (requires auth and payments)").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
3626
3721
|
(_opts, cmd) => runCommand(
|
|
3627
3722
|
() => runPattern(
|
|
3628
3723
|
"enable-subscriptions",
|
|
@@ -3647,8 +3742,8 @@ var subscriptions = new Command20("subscriptions").description("enable Stripe su
|
|
|
3647
3742
|
);
|
|
3648
3743
|
|
|
3649
3744
|
// src/commands/enable/notifications.ts
|
|
3650
|
-
import { Command as
|
|
3651
|
-
var notifications = new
|
|
3745
|
+
import { Command as Command22 } from "commander";
|
|
3746
|
+
var notifications = new Command22("notifications").description("enable in-app notifications with a bell dropdown (requires auth)").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
3652
3747
|
(_opts, cmd) => runCommand(
|
|
3653
3748
|
() => runPattern(
|
|
3654
3749
|
"enable-notifications",
|
|
@@ -3674,7 +3769,7 @@ var notifications = new Command21("notifications").description("enable in-app no
|
|
|
3674
3769
|
|
|
3675
3770
|
// src/commands/enable/s3.ts
|
|
3676
3771
|
import process16 from "node:process";
|
|
3677
|
-
import { Command as
|
|
3772
|
+
import { Command as Command23 } from "commander";
|
|
3678
3773
|
import * as p20 from "@clack/prompts";
|
|
3679
3774
|
import pc8 from "picocolors";
|
|
3680
3775
|
|
|
@@ -3685,8 +3780,8 @@ import * as p18 from "@clack/prompts";
|
|
|
3685
3780
|
import pc5 from "picocolors";
|
|
3686
3781
|
|
|
3687
3782
|
// src/lib/deploy-config.ts
|
|
3688
|
-
import
|
|
3689
|
-
import
|
|
3783
|
+
import fs20 from "node:fs";
|
|
3784
|
+
import path20 from "node:path";
|
|
3690
3785
|
import crypto from "node:crypto";
|
|
3691
3786
|
import { pathToFileURL } from "node:url";
|
|
3692
3787
|
var CONFIG_BASENAMES = [
|
|
@@ -3697,8 +3792,8 @@ var CONFIG_BASENAMES = [
|
|
|
3697
3792
|
];
|
|
3698
3793
|
function findConfigFile(workspaceRootDir) {
|
|
3699
3794
|
for (const name of CONFIG_BASENAMES) {
|
|
3700
|
-
const file =
|
|
3701
|
-
if (
|
|
3795
|
+
const file = path20.join(workspaceRootDir, name);
|
|
3796
|
+
if (fs20.existsSync(file)) return file;
|
|
3702
3797
|
}
|
|
3703
3798
|
return null;
|
|
3704
3799
|
}
|
|
@@ -3706,49 +3801,49 @@ async function loadDeployConfig(workspaceRootDir) {
|
|
|
3706
3801
|
const file = findConfigFile(workspaceRootDir);
|
|
3707
3802
|
if (!file) return {};
|
|
3708
3803
|
if (file.endsWith(".json")) {
|
|
3709
|
-
return JSON.parse(
|
|
3804
|
+
return JSON.parse(fs20.readFileSync(file, "utf8"));
|
|
3710
3805
|
}
|
|
3711
3806
|
const url = file.endsWith(".ts") ? await transpileToTemp(file) : pathToFileURL(file).href;
|
|
3712
3807
|
try {
|
|
3713
3808
|
const mod = await import(url);
|
|
3714
3809
|
const config = mod.default;
|
|
3715
3810
|
if (!config || typeof config !== "object") {
|
|
3716
|
-
throw new Error(`${
|
|
3811
|
+
throw new Error(`${path20.basename(file)} must export a config object as its default export.`);
|
|
3717
3812
|
}
|
|
3718
3813
|
return config;
|
|
3719
3814
|
} finally {
|
|
3720
|
-
if (url !== pathToFileURL(file).href)
|
|
3815
|
+
if (url !== pathToFileURL(file).href) fs20.rmSync(new URL(url), { force: true });
|
|
3721
3816
|
}
|
|
3722
3817
|
}
|
|
3723
3818
|
async function transpileToTemp(file) {
|
|
3724
3819
|
const { ts } = await import("ts-morph");
|
|
3725
|
-
const source =
|
|
3820
|
+
const source = fs20.readFileSync(file, "utf8");
|
|
3726
3821
|
const { outputText } = ts.transpileModule(source, {
|
|
3727
3822
|
compilerOptions: { module: ts.ModuleKind.ESNext, target: ts.ScriptTarget.ES2022 }
|
|
3728
3823
|
});
|
|
3729
|
-
const temp =
|
|
3730
|
-
|
|
3824
|
+
const temp = path20.join(
|
|
3825
|
+
path20.dirname(file),
|
|
3731
3826
|
`.velastack.config.${crypto.randomBytes(4).toString("hex")}.mjs`
|
|
3732
3827
|
);
|
|
3733
|
-
|
|
3828
|
+
fs20.writeFileSync(temp, outputText);
|
|
3734
3829
|
return pathToFileURL(temp).href;
|
|
3735
3830
|
}
|
|
3736
3831
|
function projectFilePath(workspaceRootDir) {
|
|
3737
|
-
return
|
|
3832
|
+
return path20.join(workspaceRootDir, ".vela", "project.json");
|
|
3738
3833
|
}
|
|
3739
3834
|
function readProjectFile(workspaceRootDir) {
|
|
3740
3835
|
const file = projectFilePath(workspaceRootDir);
|
|
3741
|
-
if (!
|
|
3836
|
+
if (!fs20.existsSync(file)) return {};
|
|
3742
3837
|
try {
|
|
3743
|
-
return JSON.parse(
|
|
3838
|
+
return JSON.parse(fs20.readFileSync(file, "utf8"));
|
|
3744
3839
|
} catch {
|
|
3745
3840
|
return {};
|
|
3746
3841
|
}
|
|
3747
3842
|
}
|
|
3748
3843
|
function writeProjectFile(workspaceRootDir, data) {
|
|
3749
3844
|
const file = projectFilePath(workspaceRootDir);
|
|
3750
|
-
|
|
3751
|
-
|
|
3845
|
+
fs20.mkdirSync(path20.dirname(file), { recursive: true });
|
|
3846
|
+
fs20.writeFileSync(file, JSON.stringify(data, null, 2) + "\n");
|
|
3752
3847
|
}
|
|
3753
3848
|
function resolveAppIdentity(workspaceRootDir, config = {}) {
|
|
3754
3849
|
const project = readProjectFile(workspaceRootDir);
|
|
@@ -3773,11 +3868,11 @@ function readAppIdentity(workspaceRootDir, config = {}) {
|
|
|
3773
3868
|
}
|
|
3774
3869
|
function defaultProjectName(workspaceRootDir) {
|
|
3775
3870
|
try {
|
|
3776
|
-
const pkg = readPackageJson(
|
|
3871
|
+
const pkg = readPackageJson(path20.join(workspaceRootDir, "package.json"));
|
|
3777
3872
|
if (typeof pkg.name === "string" && pkg.name.trim()) return pkg.name.trim();
|
|
3778
3873
|
} catch {
|
|
3779
3874
|
}
|
|
3780
|
-
return
|
|
3875
|
+
return path20.basename(workspaceRootDir);
|
|
3781
3876
|
}
|
|
3782
3877
|
function slug(value) {
|
|
3783
3878
|
return value.toLowerCase().replace(/^@/, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 32) || "app";
|
|
@@ -3848,15 +3943,15 @@ function randomSuffix() {
|
|
|
3848
3943
|
}
|
|
3849
3944
|
|
|
3850
3945
|
// src/lib/artifact.ts
|
|
3851
|
-
import
|
|
3852
|
-
import
|
|
3946
|
+
import fs22 from "node:fs";
|
|
3947
|
+
import path22 from "node:path";
|
|
3853
3948
|
import { detect as detect4 } from "package-manager-detector";
|
|
3854
3949
|
import { resolveCommand as resolveCommand4 } from "package-manager-detector/commands";
|
|
3855
3950
|
|
|
3856
3951
|
// src/lib/ssh.ts
|
|
3857
|
-
import
|
|
3952
|
+
import fs21 from "node:fs";
|
|
3858
3953
|
import os4 from "node:os";
|
|
3859
|
-
import
|
|
3954
|
+
import path21 from "node:path";
|
|
3860
3955
|
import crypto3 from "node:crypto";
|
|
3861
3956
|
import process13 from "node:process";
|
|
3862
3957
|
import { spawn as spawn2 } from "node:child_process";
|
|
@@ -3899,9 +3994,9 @@ var SshSession = class {
|
|
|
3899
3994
|
}
|
|
3900
3995
|
async open() {
|
|
3901
3996
|
if (this.controlPath) return;
|
|
3902
|
-
const dir =
|
|
3903
|
-
|
|
3904
|
-
const socket =
|
|
3997
|
+
const dir = path21.join(os4.tmpdir(), "vela-ssh");
|
|
3998
|
+
fs21.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
3999
|
+
const socket = path21.join(dir, `${crypto3.randomBytes(6).toString("hex")}.sock`);
|
|
3905
4000
|
this.controlPath = socket;
|
|
3906
4001
|
const args = [
|
|
3907
4002
|
...this.sshArgs(),
|
|
@@ -4191,11 +4286,11 @@ function collectArtifact(cwd, config = {}) {
|
|
|
4191
4286
|
const outputDir = config.outputDir ?? DEFAULT_OUTPUT_DIR;
|
|
4192
4287
|
const entries = [];
|
|
4193
4288
|
const add2 = (rel, remoteDir = "") => {
|
|
4194
|
-
const localPath =
|
|
4195
|
-
if (
|
|
4289
|
+
const localPath = path22.join(cwd, rel);
|
|
4290
|
+
if (fs22.existsSync(localPath)) entries.push({ localPath, remoteDir });
|
|
4196
4291
|
};
|
|
4197
|
-
const buildPath =
|
|
4198
|
-
if (!
|
|
4292
|
+
const buildPath = path22.join(cwd, outputDir);
|
|
4293
|
+
if (!fs22.existsSync(path22.join(buildPath, "index.js"))) {
|
|
4199
4294
|
throw new BuildError(
|
|
4200
4295
|
`No ${outputDir}/index.js to deploy.
|
|
4201
4296
|
|
|
@@ -4209,8 +4304,8 @@ matches where it writes), then deploy again.`
|
|
|
4209
4304
|
add2("package-lock.json");
|
|
4210
4305
|
add2(".npmrc");
|
|
4211
4306
|
add2(MIGRATIONS_DIR);
|
|
4212
|
-
const hooks =
|
|
4213
|
-
if (
|
|
4307
|
+
const hooks = path22.join(cwd, DATA_DIR, "hooks");
|
|
4308
|
+
if (fs22.existsSync(hooks)) entries.push({ localPath: hooks, remoteDir: "hooks" });
|
|
4214
4309
|
for (const extra of config.include ?? []) add2(extra);
|
|
4215
4310
|
return entries;
|
|
4216
4311
|
}
|
|
@@ -4251,8 +4346,8 @@ function sshOptionsFrom(options) {
|
|
|
4251
4346
|
|
|
4252
4347
|
// src/lib/remote.ts
|
|
4253
4348
|
import crypto4 from "node:crypto";
|
|
4254
|
-
import
|
|
4255
|
-
import
|
|
4349
|
+
import fs23 from "node:fs";
|
|
4350
|
+
import path23 from "node:path";
|
|
4256
4351
|
import process14 from "node:process";
|
|
4257
4352
|
var VELA_ROOT = "/var/lib/vela";
|
|
4258
4353
|
var VELA_ETC = "/etc/vela";
|
|
@@ -4265,19 +4360,19 @@ function instanceHasBackend(state) {
|
|
|
4265
4360
|
return state.backend ?? Boolean(state.pbPort);
|
|
4266
4361
|
}
|
|
4267
4362
|
function serverTemplatesDir() {
|
|
4268
|
-
return
|
|
4363
|
+
return path23.join(templatesDir(), "server");
|
|
4269
4364
|
}
|
|
4270
4365
|
var DIGEST_LENGTH = 12;
|
|
4271
4366
|
function serverScriptsDigest(dir = serverTemplatesDir()) {
|
|
4272
4367
|
const hash = crypto4.createHash("sha256");
|
|
4273
4368
|
for (const file of listFiles(dir).sort()) {
|
|
4274
|
-
hash.update(file).update("\0").update(
|
|
4369
|
+
hash.update(file).update("\0").update(fs23.readFileSync(path23.join(dir, file))).update("\0");
|
|
4275
4370
|
}
|
|
4276
4371
|
return hash.digest("hex").slice(0, DIGEST_LENGTH);
|
|
4277
4372
|
}
|
|
4278
4373
|
function listFiles(root, prefix = "") {
|
|
4279
4374
|
const files = [];
|
|
4280
|
-
for (const entry of
|
|
4375
|
+
for (const entry of fs23.readdirSync(path23.join(root, prefix), { withFileTypes: true })) {
|
|
4281
4376
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
4282
4377
|
if (entry.isDirectory()) files.push(...listFiles(root, rel));
|
|
4283
4378
|
else if (entry.isFile()) files.push(rel);
|
|
@@ -4396,7 +4491,7 @@ var remotePaths = {
|
|
|
4396
4491
|
};
|
|
4397
4492
|
|
|
4398
4493
|
// src/lib/remote-env.ts
|
|
4399
|
-
import
|
|
4494
|
+
import fs24 from "node:fs";
|
|
4400
4495
|
import dotenv from "dotenv";
|
|
4401
4496
|
var KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
4402
4497
|
function isValidKey(key) {
|
|
@@ -4444,7 +4539,7 @@ function quote(value) {
|
|
|
4444
4539
|
return `"${escaped}"`;
|
|
4445
4540
|
}
|
|
4446
4541
|
function readLocalEnvFile(file) {
|
|
4447
|
-
const parsed = dotenv.parse(
|
|
4542
|
+
const parsed = dotenv.parse(fs24.readFileSync(file));
|
|
4448
4543
|
const result = {};
|
|
4449
4544
|
for (const [key, value] of Object.entries(parsed)) {
|
|
4450
4545
|
if (isValidKey(key)) result[key] = value;
|
|
@@ -4773,17 +4868,17 @@ function envFilePath(workspaceRootDir) {
|
|
|
4773
4868
|
import pc7 from "picocolors";
|
|
4774
4869
|
|
|
4775
4870
|
// src/lib/local-env.ts
|
|
4776
|
-
import
|
|
4871
|
+
import fs25 from "node:fs";
|
|
4777
4872
|
import * as p19 from "@clack/prompts";
|
|
4778
4873
|
import pc6 from "picocolors";
|
|
4779
4874
|
function readLocalEnv(envFile) {
|
|
4780
|
-
if (!
|
|
4875
|
+
if (!fs25.existsSync(envFile)) return {};
|
|
4781
4876
|
return readLocalEnvFile(envFile);
|
|
4782
4877
|
}
|
|
4783
4878
|
function editLocalEnv(envFile, edit) {
|
|
4784
|
-
const before =
|
|
4879
|
+
const before = fs25.existsSync(envFile) ? fs25.readFileSync(envFile, "utf8") : "";
|
|
4785
4880
|
const after = edit(before);
|
|
4786
|
-
if (after !== before)
|
|
4881
|
+
if (after !== before) fs25.writeFileSync(envFile, after);
|
|
4787
4882
|
}
|
|
4788
4883
|
function setLocalEnv(envFile, key, value) {
|
|
4789
4884
|
editLocalEnv(envFile, (content) => upsertEnvVar(content, key, value));
|
|
@@ -4795,10 +4890,10 @@ async function applyLocalEnvChange(ctx, changed) {
|
|
|
4795
4890
|
if (touchesSuperuser(changed)) {
|
|
4796
4891
|
const env2 = readLocalEnv(ctx.envFile);
|
|
4797
4892
|
const email3 = env2.POCKETBASE_SUPERUSER_EMAIL;
|
|
4798
|
-
const
|
|
4799
|
-
if (email3 &&
|
|
4893
|
+
const password12 = env2.POCKETBASE_SUPERUSER_PASSWORD;
|
|
4894
|
+
if (email3 && password12) {
|
|
4800
4895
|
process.env.POCKETBASE_SUPERUSER_EMAIL = email3;
|
|
4801
|
-
process.env.POCKETBASE_SUPERUSER_PASSWORD =
|
|
4896
|
+
process.env.POCKETBASE_SUPERUSER_PASSWORD = password12;
|
|
4802
4897
|
await ensureSuperuser(ctx.workspaceRootDir);
|
|
4803
4898
|
p19.log.success("Local superuser updated to match");
|
|
4804
4899
|
} else {
|
|
@@ -4828,8 +4923,8 @@ project with a backend (\`vela bless\` adds one).`
|
|
|
4828
4923
|
}
|
|
4829
4924
|
const env2 = await readRemoteEnv(session, instance);
|
|
4830
4925
|
const email3 = env2.POCKETBASE_SUPERUSER_EMAIL;
|
|
4831
|
-
const
|
|
4832
|
-
if (!email3 || !
|
|
4926
|
+
const password12 = env2.POCKETBASE_SUPERUSER_PASSWORD;
|
|
4927
|
+
if (!email3 || !password12) {
|
|
4833
4928
|
throw new Error(
|
|
4834
4929
|
`${instance} has no PocketBase superuser credentials in its environment.
|
|
4835
4930
|
|
|
@@ -4841,7 +4936,7 @@ A deploy creates them. Deploy again to repair this instance.`
|
|
|
4841
4936
|
return {
|
|
4842
4937
|
url: `http://127.0.0.1:${localPort}`,
|
|
4843
4938
|
email: email3,
|
|
4844
|
-
password:
|
|
4939
|
+
password: password12,
|
|
4845
4940
|
close: () => session.cancelForward(localPort, "127.0.0.1", pbPort)
|
|
4846
4941
|
};
|
|
4847
4942
|
}
|
|
@@ -4871,8 +4966,8 @@ Run ${pc7.cyan("vela bless")} to add a backend.`
|
|
|
4871
4966
|
}
|
|
4872
4967
|
const creds = readLocalEnv(ctx.envFile);
|
|
4873
4968
|
const email3 = creds.POCKETBASE_SUPERUSER_EMAIL;
|
|
4874
|
-
const
|
|
4875
|
-
if (!email3 || !
|
|
4969
|
+
const password12 = creds.POCKETBASE_SUPERUSER_PASSWORD;
|
|
4970
|
+
if (!email3 || !password12) {
|
|
4876
4971
|
throw new Error(
|
|
4877
4972
|
`The local database has no superuser credentials to sign in with.
|
|
4878
4973
|
|
|
@@ -4888,7 +4983,7 @@ Set ${pc7.cyan("POCKETBASE_SUPERUSER_EMAIL")} and ${pc7.cyan("POCKETBASE_SUPERUS
|
|
|
4888
4983
|
targetName: "local",
|
|
4889
4984
|
workspaceRootDir: ctx.workspaceRootDir
|
|
4890
4985
|
}),
|
|
4891
|
-
{ email: email3, password:
|
|
4986
|
+
{ email: email3, password: password12 }
|
|
4892
4987
|
);
|
|
4893
4988
|
},
|
|
4894
4989
|
remote: async (ctx) => {
|
|
@@ -4916,8 +5011,8 @@ Set ${pc7.cyan("POCKETBASE_SUPERUSER_EMAIL")} and ${pc7.cyan("POCKETBASE_SUPERUS
|
|
|
4916
5011
|
}
|
|
4917
5012
|
|
|
4918
5013
|
// src/lib/s3-settings.ts
|
|
4919
|
-
import
|
|
4920
|
-
import
|
|
5014
|
+
import fs26 from "node:fs";
|
|
5015
|
+
import path24 from "node:path";
|
|
4921
5016
|
var VIRTUAL_HOSTED = [/\.amazonaws\.com$/i, /\.r2\.cloudflarestorage\.com$/i];
|
|
4922
5017
|
function defaultForcePathStyle(endpoint) {
|
|
4923
5018
|
let host;
|
|
@@ -4955,25 +5050,25 @@ async function hasLocalUploads(session, instance, workspaceRootDir) {
|
|
|
4955
5050
|
});
|
|
4956
5051
|
return result.stdout.trim().length > 0;
|
|
4957
5052
|
}
|
|
4958
|
-
return hasFile(
|
|
5053
|
+
return hasFile(path24.join(workspaceRootDir, DATA_DIR, "storage"));
|
|
4959
5054
|
}
|
|
4960
5055
|
function hasFile(dir) {
|
|
4961
5056
|
let entries;
|
|
4962
5057
|
try {
|
|
4963
|
-
entries =
|
|
5058
|
+
entries = fs26.readdirSync(dir, { withFileTypes: true });
|
|
4964
5059
|
} catch {
|
|
4965
5060
|
return false;
|
|
4966
5061
|
}
|
|
4967
5062
|
for (const entry of entries) {
|
|
4968
5063
|
if (entry.isFile()) return true;
|
|
4969
|
-
if (entry.isDirectory() && hasFile(
|
|
5064
|
+
if (entry.isDirectory() && hasFile(path24.join(dir, entry.name))) return true;
|
|
4970
5065
|
}
|
|
4971
5066
|
return false;
|
|
4972
5067
|
}
|
|
4973
5068
|
|
|
4974
5069
|
// src/commands/enable/s3.ts
|
|
4975
5070
|
var s3 = addTargetOptions(
|
|
4976
|
-
new
|
|
5071
|
+
new Command23("s3").description("enable S3 file storage").option("--backups", "configure where backups are kept, not where uploads go").option("--endpoint <url>", "S3 endpoint URL").option("--bucket <name>", "S3 bucket name").option("--region <region>", "S3 region").option("--access-key <key>", "S3 access key").option("--secret <secret>", "S3 secret key \u2014 prefer VELA_S3_SECRET").option("--force-path-style", "address the bucket in the path (MinIO, Ceph)").option("--no-force-path-style", "address the bucket as a subdomain (AWS, R2)").option("--force", "enable it even though uploads already exist on disk").configureHelp(helpConfig),
|
|
4977
5072
|
"local"
|
|
4978
5073
|
).action(
|
|
4979
5074
|
(raw) => runCommand(() => {
|
|
@@ -5039,7 +5134,7 @@ async function promptConfig(options, existing) {
|
|
|
5039
5134
|
const bucket = options.bucket ?? await text9("S3 bucket name", existing.bucket);
|
|
5040
5135
|
const region = options.region ?? await text9("S3 region", existing.region || "us-east-1");
|
|
5041
5136
|
const accessKey = options.accessKey ?? await text9("S3 access key", existing.accessKey);
|
|
5042
|
-
const secret = options.secret ?? process16.env.VELA_S3_SECRET ?? await
|
|
5137
|
+
const secret = options.secret ?? process16.env.VELA_S3_SECRET ?? await password7("S3 secret key");
|
|
5043
5138
|
const forcePathStyle = options.forcePathStyle ?? await confirm4(
|
|
5044
5139
|
"Address the bucket in the path? (MinIO, Ceph and most self-hosted gateways need this)",
|
|
5045
5140
|
defaultForcePathStyle(endpoint)
|
|
@@ -5058,7 +5153,7 @@ async function text9(message, initialValue = "") {
|
|
|
5058
5153
|
}
|
|
5059
5154
|
return value.trim();
|
|
5060
5155
|
}
|
|
5061
|
-
async function
|
|
5156
|
+
async function password7(message) {
|
|
5062
5157
|
const value = await p20.password({
|
|
5063
5158
|
message,
|
|
5064
5159
|
validate: (input) => input ? void 0 : `${message} is required`
|
|
@@ -5080,9 +5175,9 @@ async function confirm4(message, initialValue) {
|
|
|
5080
5175
|
|
|
5081
5176
|
// src/commands/enable/smtp.ts
|
|
5082
5177
|
import process17 from "node:process";
|
|
5083
|
-
import { Command as
|
|
5178
|
+
import { Command as Command24 } from "commander";
|
|
5084
5179
|
import * as p21 from "@clack/prompts";
|
|
5085
|
-
var smtp = new
|
|
5180
|
+
var smtp = new Command24("smtp").description("configure SMTP for transactional email").configureHelp(helpConfig).action(
|
|
5086
5181
|
() => runCommand(async () => {
|
|
5087
5182
|
const { workspaceRootDir } = await getWorkspace();
|
|
5088
5183
|
const config = await p21.group(
|
|
@@ -5136,10 +5231,10 @@ var smtp = new Command23("smtp").description("configure SMTP for transactional e
|
|
|
5136
5231
|
|
|
5137
5232
|
// src/commands/enable/cms.ts
|
|
5138
5233
|
import process18 from "node:process";
|
|
5139
|
-
import { Command as
|
|
5234
|
+
import { Command as Command25 } from "commander";
|
|
5140
5235
|
import * as p22 from "@clack/prompts";
|
|
5141
5236
|
import pc9 from "picocolors";
|
|
5142
|
-
var cms = new
|
|
5237
|
+
var cms = new Command25("cms").description("enable an inline-editing CMS with an admin bar").option(
|
|
5143
5238
|
"--endpoint <url>",
|
|
5144
5239
|
"read from a hosted CMS at this URL instead of installing the backend in this app"
|
|
5145
5240
|
).allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
@@ -5172,8 +5267,8 @@ Run ${pc9.cyan("vela bless")} to add a backend, or point at a hosted CMS with ${
|
|
|
5172
5267
|
);
|
|
5173
5268
|
|
|
5174
5269
|
// src/commands/enable/blog.ts
|
|
5175
|
-
import { Command as
|
|
5176
|
-
var blog = new
|
|
5270
|
+
import { Command as Command26 } from "commander";
|
|
5271
|
+
var blog = new Command26("blog").description("enable an mdsvex blog with posts, tags, and RSS").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5177
5272
|
(_opts, cmd) => runCommand(
|
|
5178
5273
|
() => runPattern(
|
|
5179
5274
|
"enable-blog",
|
|
@@ -5198,8 +5293,8 @@ var blog = new Command25("blog").description("enable an mdsvex blog with posts,
|
|
|
5198
5293
|
);
|
|
5199
5294
|
|
|
5200
5295
|
// src/commands/enable/content-negotiation.ts
|
|
5201
|
-
import { Command as
|
|
5202
|
-
var contentNegotiation = new
|
|
5296
|
+
import { Command as Command27 } from "commander";
|
|
5297
|
+
var contentNegotiation = new Command27("content-negotiation").description("enable content negotiation (sveltekit-negotiate)").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5203
5298
|
(_opts, cmd) => runCommand(
|
|
5204
5299
|
() => runPattern(
|
|
5205
5300
|
"enable-content-negotiation",
|
|
@@ -5223,8 +5318,8 @@ var contentNegotiation = new Command26("content-negotiation").description("enabl
|
|
|
5223
5318
|
);
|
|
5224
5319
|
|
|
5225
5320
|
// src/commands/enable/workflows.ts
|
|
5226
|
-
import { Command as
|
|
5227
|
-
var workflows = new
|
|
5321
|
+
import { Command as Command28 } from "commander";
|
|
5322
|
+
var workflows = new Command28("workflows").description("add background workflows to a project created before they were built in").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5228
5323
|
(_opts, cmd) => runCommand(
|
|
5229
5324
|
() => runPattern(
|
|
5230
5325
|
"enable-workflows",
|
|
@@ -5249,13 +5344,13 @@ var workflows = new Command27("workflows").description("add background workflows
|
|
|
5249
5344
|
);
|
|
5250
5345
|
|
|
5251
5346
|
// src/commands/enable.ts
|
|
5252
|
-
var enable = new
|
|
5347
|
+
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(subscriptions).addCommand(notifications).addCommand(s3).addCommand(smtp).addCommand(cms).addCommand(blog).addCommand(workflows);
|
|
5253
5348
|
|
|
5254
5349
|
// src/commands/disable.ts
|
|
5255
|
-
import { Command as
|
|
5350
|
+
import { Command as Command44 } from "commander";
|
|
5256
5351
|
|
|
5257
|
-
// src/commands/disable/
|
|
5258
|
-
import { Command as
|
|
5352
|
+
// src/commands/disable/ai.ts
|
|
5353
|
+
import { Command as Command30 } from "commander";
|
|
5259
5354
|
|
|
5260
5355
|
// src/commands/disable/_shared.ts
|
|
5261
5356
|
import process19 from "node:process";
|
|
@@ -5274,8 +5369,62 @@ async function runDisable(opts, flags, cmdArgs) {
|
|
|
5274
5369
|
await runPattern(opts.slug, cmdArgs, { destructive: true }, opts.report);
|
|
5275
5370
|
}
|
|
5276
5371
|
|
|
5372
|
+
// src/commands/disable/ai.ts
|
|
5373
|
+
var ai2 = new Command30("ai").description("disable AI chat").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5374
|
+
(opts, cmd) => runCommand(
|
|
5375
|
+
() => runDisable(
|
|
5376
|
+
{
|
|
5377
|
+
slug: "disable-ai",
|
|
5378
|
+
confirmMessage: "Disable AI? Deletes src/lib/server/ai.ts, the /api/chat endpoint and the /ai demo page, removes the provider's API key from .env and uninstalls the AI SDK packages.",
|
|
5379
|
+
report: {
|
|
5380
|
+
summary: "Disabled AI.",
|
|
5381
|
+
nextSteps: [
|
|
5382
|
+
"Remove the API key from each deploy target with `vela env unset` if you set one there."
|
|
5383
|
+
],
|
|
5384
|
+
task: {
|
|
5385
|
+
title: "Disabling AI",
|
|
5386
|
+
success: "Disabled AI",
|
|
5387
|
+
error: "Failed to disable AI"
|
|
5388
|
+
}
|
|
5389
|
+
}
|
|
5390
|
+
},
|
|
5391
|
+
opts,
|
|
5392
|
+
cmd.args
|
|
5393
|
+
),
|
|
5394
|
+
"Failed to disable AI."
|
|
5395
|
+
)
|
|
5396
|
+
);
|
|
5397
|
+
|
|
5398
|
+
// src/commands/disable/analytics.ts
|
|
5399
|
+
import { Command as Command31 } from "commander";
|
|
5400
|
+
var analytics2 = new Command31("analytics").description("disable web analytics").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5401
|
+
(opts, cmd) => runCommand(
|
|
5402
|
+
() => runDisable(
|
|
5403
|
+
{
|
|
5404
|
+
slug: "disable-analytics",
|
|
5405
|
+
confirmMessage: "Disable analytics? Deletes the analytics component, removes <Analytics /> from the root layout, strips the provider's variables from .env and uninstalls posthog-js.",
|
|
5406
|
+
report: {
|
|
5407
|
+
summary: "Disabled analytics.",
|
|
5408
|
+
nextSteps: [
|
|
5409
|
+
"Remove the PUBLIC_* analytics variables from each deploy target with `vela env unset` if you set them there."
|
|
5410
|
+
],
|
|
5411
|
+
task: {
|
|
5412
|
+
title: "Disabling analytics",
|
|
5413
|
+
success: "Disabled analytics",
|
|
5414
|
+
error: "Failed to disable analytics"
|
|
5415
|
+
}
|
|
5416
|
+
}
|
|
5417
|
+
},
|
|
5418
|
+
opts,
|
|
5419
|
+
cmd.args
|
|
5420
|
+
),
|
|
5421
|
+
"Failed to disable analytics."
|
|
5422
|
+
)
|
|
5423
|
+
);
|
|
5424
|
+
|
|
5277
5425
|
// src/commands/disable/auth.ts
|
|
5278
|
-
|
|
5426
|
+
import { Command as Command32 } from "commander";
|
|
5427
|
+
var auth2 = new Command32("auth").description("disable authentication").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5279
5428
|
(opts, cmd) => runCommand(
|
|
5280
5429
|
() => runDisable(
|
|
5281
5430
|
{
|
|
@@ -5301,8 +5450,8 @@ var auth2 = new Command29("auth").description("disable authentication").option("
|
|
|
5301
5450
|
);
|
|
5302
5451
|
|
|
5303
5452
|
// src/commands/disable/api.ts
|
|
5304
|
-
import { Command as
|
|
5305
|
-
var api2 = new
|
|
5453
|
+
import { Command as Command33 } from "commander";
|
|
5454
|
+
var api2 = new Command33("api").description("disable the REST API").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5306
5455
|
(opts, cmd) => runCommand(
|
|
5307
5456
|
() => runDisable(
|
|
5308
5457
|
{
|
|
@@ -5325,8 +5474,8 @@ var api2 = new Command30("api").description("disable the REST API").option("-y,
|
|
|
5325
5474
|
);
|
|
5326
5475
|
|
|
5327
5476
|
// src/commands/disable/api-keys.ts
|
|
5328
|
-
import { Command as
|
|
5329
|
-
var apiKeys2 = new
|
|
5477
|
+
import { Command as Command34 } from "commander";
|
|
5478
|
+
var apiKeys2 = new Command34("api-keys").description("disable API key management").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5330
5479
|
(opts, cmd) => runCommand(
|
|
5331
5480
|
() => runDisable(
|
|
5332
5481
|
{
|
|
@@ -5349,13 +5498,13 @@ var apiKeys2 = new Command31("api-keys").description("disable API key management
|
|
|
5349
5498
|
);
|
|
5350
5499
|
|
|
5351
5500
|
// src/commands/disable/backend.ts
|
|
5352
|
-
import { Command as
|
|
5353
|
-
var backend2 = new
|
|
5501
|
+
import { Command as Command35 } from "commander";
|
|
5502
|
+
var backend2 = new Command35("backend").description("disable the PocketBase backend").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5354
5503
|
(opts, cmd) => runCommand(
|
|
5355
5504
|
() => runDisable(
|
|
5356
5505
|
{
|
|
5357
5506
|
slug: "disable-backend",
|
|
5358
|
-
confirmMessage: "Disable the PocketBase backend?
|
|
5507
|
+
confirmMessage: "Disable the PocketBase backend? Deletes data/ (the local database, fixtures, hooks and seeds), src/lib/server/workflows.ts, src/lib/workflows/ and every server.test.ts, and uninstalls the workflow packages. Takes the PocketBase handle and workflow worker out of hooks.server.ts (deleting it if nothing else is left) and switches the SvelteKit adapter back to static. The @velastack/pocketbase and pocketbase-sveltekit packages stay installed.",
|
|
5359
5508
|
report: {
|
|
5360
5509
|
summary: "Disabled the PocketBase backend.",
|
|
5361
5510
|
task: {
|
|
@@ -5373,8 +5522,8 @@ var backend2 = new Command32("backend").description("disable the PocketBase back
|
|
|
5373
5522
|
);
|
|
5374
5523
|
|
|
5375
5524
|
// src/commands/disable/content-negotiation.ts
|
|
5376
|
-
import { Command as
|
|
5377
|
-
var contentNegotiation2 = new
|
|
5525
|
+
import { Command as Command36 } from "commander";
|
|
5526
|
+
var contentNegotiation2 = new Command36("content-negotiation").description("disable content negotiation").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5378
5527
|
(opts, cmd) => runCommand(
|
|
5379
5528
|
() => runDisable(
|
|
5380
5529
|
{
|
|
@@ -5397,18 +5546,16 @@ var contentNegotiation2 = new Command33("content-negotiation").description("disa
|
|
|
5397
5546
|
);
|
|
5398
5547
|
|
|
5399
5548
|
// src/commands/disable/i18n.ts
|
|
5400
|
-
import { Command as
|
|
5401
|
-
var i18n2 = new
|
|
5549
|
+
import { Command as Command37 } from "commander";
|
|
5550
|
+
var i18n2 = new Command37("i18n").description("disable internationalization").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5402
5551
|
(opts, cmd) => runCommand(
|
|
5403
5552
|
() => runDisable(
|
|
5404
5553
|
{
|
|
5405
5554
|
slug: "disable-i18n",
|
|
5406
|
-
confirmMessage: "Disable i18n?
|
|
5555
|
+
confirmMessage: "Disable i18n? Deletes the Wuchale config, reroute hook, URL helpers and language select, uninstalls wuchale, and reverts vite.config, svelte.config, hooks.server, app.html, the root +layout.ts and layout, and .gitignore. The translation catalogs in src/locales stay.",
|
|
5407
5556
|
report: {
|
|
5408
|
-
summary: "Disabled i18n
|
|
5409
|
-
nextSteps: [
|
|
5410
|
-
"Manually revert the Wuchale wiring in vite.config, svelte.config, hooks.server, app.html, and +layout.ts."
|
|
5411
|
-
],
|
|
5557
|
+
summary: "Disabled i18n.",
|
|
5558
|
+
nextSteps: ["Delete src/locales if you no longer need the translation catalogs."],
|
|
5412
5559
|
task: {
|
|
5413
5560
|
title: "Disabling i18n",
|
|
5414
5561
|
success: "Disabled i18n",
|
|
@@ -5424,8 +5571,8 @@ var i18n2 = new Command34("i18n").description("disable internationalization").op
|
|
|
5424
5571
|
);
|
|
5425
5572
|
|
|
5426
5573
|
// src/commands/disable/notifications.ts
|
|
5427
|
-
import { Command as
|
|
5428
|
-
var notifications2 = new
|
|
5574
|
+
import { Command as Command38 } from "commander";
|
|
5575
|
+
var notifications2 = new Command38("notifications").description("disable in-app notifications").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5429
5576
|
(opts, cmd) => runCommand(
|
|
5430
5577
|
() => runDisable(
|
|
5431
5578
|
{
|
|
@@ -5451,8 +5598,8 @@ var notifications2 = new Command35("notifications").description("disable in-app
|
|
|
5451
5598
|
);
|
|
5452
5599
|
|
|
5453
5600
|
// src/commands/disable/teams.ts
|
|
5454
|
-
import { Command as
|
|
5455
|
-
var teams2 = new
|
|
5601
|
+
import { Command as Command39 } from "commander";
|
|
5602
|
+
var teams2 = new Command39("teams").description("disable teams").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5456
5603
|
(opts, cmd) => runCommand(
|
|
5457
5604
|
() => runDisable(
|
|
5458
5605
|
{
|
|
@@ -5475,8 +5622,8 @@ var teams2 = new Command36("teams").description("disable teams").option("-y, --y
|
|
|
5475
5622
|
);
|
|
5476
5623
|
|
|
5477
5624
|
// src/commands/disable/payments.ts
|
|
5478
|
-
import { Command as
|
|
5479
|
-
var payments2 = new
|
|
5625
|
+
import { Command as Command40 } from "commander";
|
|
5626
|
+
var payments2 = new Command40("payments").description("disable payments").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5480
5627
|
(opts, cmd) => runCommand(
|
|
5481
5628
|
() => runDisable(
|
|
5482
5629
|
{
|
|
@@ -5503,11 +5650,11 @@ var payments2 = new Command37("payments").description("disable payments").option
|
|
|
5503
5650
|
);
|
|
5504
5651
|
|
|
5505
5652
|
// src/commands/disable/s3.ts
|
|
5506
|
-
import { Command as
|
|
5653
|
+
import { Command as Command41 } from "commander";
|
|
5507
5654
|
import * as p24 from "@clack/prompts";
|
|
5508
5655
|
import pc10 from "picocolors";
|
|
5509
5656
|
var s32 = addTargetOptions(
|
|
5510
|
-
new
|
|
5657
|
+
new Command41("s3").description("disable S3 file storage").option("--backups", "keep backups on the server again, rather than uploads").configureHelp(helpConfig),
|
|
5511
5658
|
"local"
|
|
5512
5659
|
).action(
|
|
5513
5660
|
(raw) => runCommand(() => {
|
|
@@ -5536,8 +5683,8 @@ function label2(filesystem) {
|
|
|
5536
5683
|
}
|
|
5537
5684
|
|
|
5538
5685
|
// src/commands/disable/subscriptions.ts
|
|
5539
|
-
import { Command as
|
|
5540
|
-
var subscriptions2 = new
|
|
5686
|
+
import { Command as Command42 } from "commander";
|
|
5687
|
+
var subscriptions2 = new Command42("subscriptions").description("disable Stripe subscriptions").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5541
5688
|
(opts, cmd) => runCommand(
|
|
5542
5689
|
() => runDisable(
|
|
5543
5690
|
{
|
|
@@ -5564,8 +5711,8 @@ var subscriptions2 = new Command39("subscriptions").description("disable Stripe
|
|
|
5564
5711
|
);
|
|
5565
5712
|
|
|
5566
5713
|
// src/commands/disable/smtp.ts
|
|
5567
|
-
import { Command as
|
|
5568
|
-
var smtp2 = new
|
|
5714
|
+
import { Command as Command43 } from "commander";
|
|
5715
|
+
var smtp2 = new Command43("smtp").description("disable SMTP configuration").configureHelp(helpConfig).action(
|
|
5569
5716
|
() => runCommand(async () => {
|
|
5570
5717
|
const { workspaceRootDir } = await getWorkspace();
|
|
5571
5718
|
await withPocketbase(workspaceRootDir, async (pb) => {
|
|
@@ -5582,13 +5729,13 @@ var smtp2 = new Command40("smtp").description("disable SMTP configuration").conf
|
|
|
5582
5729
|
);
|
|
5583
5730
|
|
|
5584
5731
|
// src/commands/disable.ts
|
|
5585
|
-
var disable = new
|
|
5732
|
+
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(subscriptions2).addCommand(s32).addCommand(smtp2);
|
|
5586
5733
|
|
|
5587
5734
|
// src/commands/destroy.ts
|
|
5588
|
-
import { Command as
|
|
5735
|
+
import { Command as Command50 } from "commander";
|
|
5589
5736
|
|
|
5590
5737
|
// src/commands/destroy/form.ts
|
|
5591
|
-
import { Command as
|
|
5738
|
+
import { Command as Command45 } from "commander";
|
|
5592
5739
|
|
|
5593
5740
|
// src/commands/destroy/_shared.ts
|
|
5594
5741
|
import process20 from "node:process";
|
|
@@ -5605,7 +5752,7 @@ async function runDestroy(slug2, model, confirmMessage, report4, flags) {
|
|
|
5605
5752
|
}
|
|
5606
5753
|
|
|
5607
5754
|
// src/commands/destroy/form.ts
|
|
5608
|
-
var form2 = new
|
|
5755
|
+
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(
|
|
5609
5756
|
"--route <route>",
|
|
5610
5757
|
"custom route the form was generated at (must match the --route used at generation)"
|
|
5611
5758
|
).allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
@@ -5629,8 +5776,8 @@ var form2 = new Command42("form").description("destroy a form generated by `vela
|
|
|
5629
5776
|
);
|
|
5630
5777
|
|
|
5631
5778
|
// src/commands/destroy/schema.ts
|
|
5632
|
-
import { Command as
|
|
5633
|
-
var schema2 = new
|
|
5779
|
+
import { Command as Command46 } from "commander";
|
|
5780
|
+
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").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5634
5781
|
(model, opts) => runCommand(
|
|
5635
5782
|
() => runDestroy(
|
|
5636
5783
|
"destroy-schema",
|
|
@@ -5651,8 +5798,8 @@ var schema2 = new Command43("schema").description("destroy a zod schema generate
|
|
|
5651
5798
|
);
|
|
5652
5799
|
|
|
5653
5800
|
// src/commands/destroy/resource.ts
|
|
5654
|
-
import { Command as
|
|
5655
|
-
var resource2 = new
|
|
5801
|
+
import { Command as Command47 } from "commander";
|
|
5802
|
+
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").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
5656
5803
|
(model, opts) => runCommand(
|
|
5657
5804
|
() => runDestroy(
|
|
5658
5805
|
"destroy-resource",
|
|
@@ -5673,8 +5820,8 @@ var resource2 = new Command44("resource").description("destroy a resource genera
|
|
|
5673
5820
|
);
|
|
5674
5821
|
|
|
5675
5822
|
// src/commands/destroy/scaffold.ts
|
|
5676
|
-
import { Command as
|
|
5677
|
-
var scaffold2 = new
|
|
5823
|
+
import { Command as Command48 } from "commander";
|
|
5824
|
+
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(
|
|
5678
5825
|
"--route <route>",
|
|
5679
5826
|
"custom route the scaffold was generated at (must match the --route used at generation)"
|
|
5680
5827
|
).allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
@@ -5702,7 +5849,7 @@ var scaffold2 = new Command45("scaffold").description("destroy a scaffold genera
|
|
|
5702
5849
|
|
|
5703
5850
|
// src/commands/destroy/deployment.ts
|
|
5704
5851
|
import process21 from "node:process";
|
|
5705
|
-
import { Command as
|
|
5852
|
+
import { Command as Command49 } from "commander";
|
|
5706
5853
|
import * as p28 from "@clack/prompts";
|
|
5707
5854
|
import pc13 from "picocolors";
|
|
5708
5855
|
|
|
@@ -5868,7 +6015,7 @@ ${pc12.dim(err instanceof Error ? err.message : String(err))}`
|
|
|
5868
6015
|
// src/commands/destroy/deployment.ts
|
|
5869
6016
|
var deployment = addLockWaitOption(
|
|
5870
6017
|
addTargetOptions(
|
|
5871
|
-
new
|
|
6018
|
+
new Command49("deployment").description("remove a deployed environment from its server").configureHelp(helpConfig),
|
|
5872
6019
|
"production"
|
|
5873
6020
|
)
|
|
5874
6021
|
).option("--purge", "also delete the database and uploaded files").option("-y, --yes", "skip the confirmation prompt").option(
|
|
@@ -5947,13 +6094,13 @@ async function confirm8(appName, targetName, byName) {
|
|
|
5947
6094
|
}
|
|
5948
6095
|
|
|
5949
6096
|
// src/commands/destroy.ts
|
|
5950
|
-
var destroy = new
|
|
6097
|
+
var destroy = new Command50("destroy").description("destroy scaffolding, or a deployment").configureHelp(helpConfig).addCommand(form2).addCommand(schema2).addCommand(resource2).addCommand(scaffold2).addCommand(deployment);
|
|
5951
6098
|
|
|
5952
6099
|
// src/commands/ui.ts
|
|
5953
|
-
import { Command as
|
|
6100
|
+
import { Command as Command56 } from "commander";
|
|
5954
6101
|
|
|
5955
6102
|
// src/commands/ui/add.ts
|
|
5956
|
-
import { Command as
|
|
6103
|
+
import { Command as Command51 } from "commander";
|
|
5957
6104
|
import * as p29 from "@clack/prompts";
|
|
5958
6105
|
import { installComponents } from "@velastack/patterns";
|
|
5959
6106
|
|
|
@@ -6003,7 +6150,7 @@ function uiAddReport(requested, outcome) {
|
|
|
6003
6150
|
}
|
|
6004
6151
|
|
|
6005
6152
|
// src/commands/ui/add.ts
|
|
6006
|
-
var add = new
|
|
6153
|
+
var add = new Command51("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(
|
|
6007
6154
|
(components, options) => runCommand(async () => {
|
|
6008
6155
|
const { workspaceRootDir } = await getWorkspace();
|
|
6009
6156
|
const log50 = p29.taskLog({ title: "Adding UI components..." });
|
|
@@ -6025,10 +6172,10 @@ var add = new Command48("add").description("add ui components (shadcn-svelte ite
|
|
|
6025
6172
|
);
|
|
6026
6173
|
|
|
6027
6174
|
// src/commands/ui/base.ts
|
|
6028
|
-
import { Command as
|
|
6175
|
+
import { Command as Command52 } from "commander";
|
|
6029
6176
|
import * as p30 from "@clack/prompts";
|
|
6030
6177
|
import { applyBaseColor } from "@velastack/patterns";
|
|
6031
|
-
var base = new
|
|
6178
|
+
var base = new Command52("base").description("change the base (gray) palette").argument("<color>", `base color to use (${BASE_COLORS.join(", ")})`).configureHelp(helpConfig).action(
|
|
6032
6179
|
(color) => runCommand(async () => {
|
|
6033
6180
|
const { workspaceRootDir } = await getWorkspace();
|
|
6034
6181
|
const log50 = p30.taskLog({ title: `Applying the ${color} palette...` });
|
|
@@ -6053,7 +6200,7 @@ var base = new Command49("base").description("change the base (gray) palette").a
|
|
|
6053
6200
|
);
|
|
6054
6201
|
|
|
6055
6202
|
// src/commands/ui/list.ts
|
|
6056
|
-
import { Command as
|
|
6203
|
+
import { Command as Command53 } from "commander";
|
|
6057
6204
|
import * as p31 from "@clack/prompts";
|
|
6058
6205
|
import { listComponents } from "@velastack/patterns";
|
|
6059
6206
|
|
|
@@ -6085,7 +6232,7 @@ function uiListReport(result) {
|
|
|
6085
6232
|
}
|
|
6086
6233
|
|
|
6087
6234
|
// src/commands/ui/list.ts
|
|
6088
|
-
var list = new
|
|
6235
|
+
var list = new Command53("list").description("list installed ui components, vela components and the style registry").option("--json", "print the result as JSON", false).configureHelp(helpConfig).action(
|
|
6089
6236
|
(options) => runCommand(async () => {
|
|
6090
6237
|
const { workspaceRootDir } = await getWorkspace();
|
|
6091
6238
|
if (options.json) {
|
|
@@ -6112,7 +6259,7 @@ Registry components are not listed.`);
|
|
|
6112
6259
|
);
|
|
6113
6260
|
|
|
6114
6261
|
// src/commands/ui/style.ts
|
|
6115
|
-
import { Command as
|
|
6262
|
+
import { Command as Command54 } from "commander";
|
|
6116
6263
|
import * as p32 from "@clack/prompts";
|
|
6117
6264
|
import { switchStyle } from "@velastack/patterns";
|
|
6118
6265
|
|
|
@@ -6139,7 +6286,7 @@ function uiStyleReport(result) {
|
|
|
6139
6286
|
}
|
|
6140
6287
|
|
|
6141
6288
|
// src/commands/ui/style.ts
|
|
6142
|
-
var style = new
|
|
6289
|
+
var style = new Command54("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(
|
|
6143
6290
|
(name, options) => runCommand(async () => {
|
|
6144
6291
|
const { workspaceRootDir } = await getWorkspace();
|
|
6145
6292
|
const spinner8 = p32.spinner();
|
|
@@ -6192,10 +6339,10 @@ ${components.map((c) => `- ${c}`).join("\n")}`
|
|
|
6192
6339
|
);
|
|
6193
6340
|
|
|
6194
6341
|
// src/commands/ui/theme.ts
|
|
6195
|
-
import { Command as
|
|
6342
|
+
import { Command as Command55 } from "commander";
|
|
6196
6343
|
import * as p33 from "@clack/prompts";
|
|
6197
6344
|
import { applyTheme } from "@velastack/patterns";
|
|
6198
|
-
var theme = new
|
|
6345
|
+
var theme = new Command55("theme").description("change the accent color, keeping the base palette").argument("<accent>", `accent to use (${THEMES.join(", ")})`).configureHelp(helpConfig).action(
|
|
6199
6346
|
(accent) => runCommand(async () => {
|
|
6200
6347
|
const { workspaceRootDir } = await getWorkspace();
|
|
6201
6348
|
const log50 = p33.taskLog({ title: `Applying the ${accent} accent...` });
|
|
@@ -6220,39 +6367,46 @@ var theme = new Command52("theme").description("change the accent color, keeping
|
|
|
6220
6367
|
);
|
|
6221
6368
|
|
|
6222
6369
|
// src/commands/ui.ts
|
|
6223
|
-
var ui = new
|
|
6370
|
+
var ui = new Command56("ui").description("generate ui components").configureHelp(helpConfig).addCommand(add).addCommand(list).addCommand(style).addCommand(base).addCommand(theme);
|
|
6224
6371
|
|
|
6225
6372
|
// src/commands/legal.ts
|
|
6226
|
-
import { Command as
|
|
6373
|
+
import { Command as Command59 } from "commander";
|
|
6227
6374
|
|
|
6228
6375
|
// src/commands/legal/terms.ts
|
|
6229
|
-
import
|
|
6230
|
-
import
|
|
6231
|
-
import { Command as
|
|
6376
|
+
import fs27 from "node:fs";
|
|
6377
|
+
import path25 from "node:path";
|
|
6378
|
+
import { Command as Command57 } from "commander";
|
|
6232
6379
|
import * as p35 from "@clack/prompts";
|
|
6233
6380
|
|
|
6234
6381
|
// src/commands/legal/shared.ts
|
|
6235
6382
|
import process22 from "node:process";
|
|
6236
6383
|
import * as p34 from "@clack/prompts";
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6384
|
+
function siteFields(site) {
|
|
6385
|
+
const url = site?.url && !isLocalUrl(site.url) ? site.url : void 0;
|
|
6386
|
+
return {
|
|
6387
|
+
websiteUrl: () => p34.text({
|
|
6388
|
+
message: "What is your website URL?",
|
|
6389
|
+
placeholder: "http://www.mysite.com",
|
|
6390
|
+
initialValue: url,
|
|
6391
|
+
validate: (value) => {
|
|
6392
|
+
if (!value || !value.startsWith("http")) {
|
|
6393
|
+
return "Please enter a valid URL starting with http or https";
|
|
6394
|
+
}
|
|
6244
6395
|
}
|
|
6245
|
-
}
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6396
|
+
}),
|
|
6397
|
+
websiteName: () => p34.text({
|
|
6398
|
+
message: "What is your website name?",
|
|
6399
|
+
placeholder: "My Site",
|
|
6400
|
+
initialValue: site?.name,
|
|
6401
|
+
validate: (value) => {
|
|
6402
|
+
if (!value) {
|
|
6403
|
+
return "Please enter a website name";
|
|
6404
|
+
}
|
|
6253
6405
|
}
|
|
6254
|
-
}
|
|
6255
|
-
}
|
|
6406
|
+
})
|
|
6407
|
+
};
|
|
6408
|
+
}
|
|
6409
|
+
var sharedFields = {
|
|
6256
6410
|
entityType: () => p34.select({
|
|
6257
6411
|
message: "Entity type",
|
|
6258
6412
|
options: [
|
|
@@ -6761,10 +6915,11 @@ var generateTermsHtml = (answers) => {
|
|
|
6761
6915
|
};
|
|
6762
6916
|
async function termsAction() {
|
|
6763
6917
|
const { workspaceRootDir, publicRoutesDir } = await getWorkspace();
|
|
6918
|
+
const site = siteFields(await readSite(workspaceRootDir));
|
|
6764
6919
|
const core = await p35.group(
|
|
6765
6920
|
{
|
|
6766
|
-
websiteUrl:
|
|
6767
|
-
websiteName:
|
|
6921
|
+
websiteUrl: site.websiteUrl,
|
|
6922
|
+
websiteName: site.websiteName,
|
|
6768
6923
|
entityType: sharedFields.entityType,
|
|
6769
6924
|
businessName: sharedFields.businessName,
|
|
6770
6925
|
businessAddress: sharedFields.businessAddress,
|
|
@@ -6886,22 +7041,22 @@ async function termsAction() {
|
|
|
6886
7041
|
mobileApp,
|
|
6887
7042
|
contact
|
|
6888
7043
|
});
|
|
6889
|
-
const termsPage =
|
|
7044
|
+
const termsPage = path25.join(
|
|
6890
7045
|
workspaceRootDir,
|
|
6891
7046
|
publicRoutesDir,
|
|
6892
7047
|
LEGAL_DIR,
|
|
6893
7048
|
"terms",
|
|
6894
7049
|
"+page.svelte"
|
|
6895
7050
|
);
|
|
6896
|
-
const termsPageTs =
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
|
|
7051
|
+
const termsPageTs = path25.join(workspaceRootDir, publicRoutesDir, LEGAL_DIR, "terms", "+page.ts");
|
|
7052
|
+
fs27.mkdirSync(path25.dirname(termsPage), { recursive: true });
|
|
7053
|
+
fs27.writeFileSync(termsPage, html);
|
|
7054
|
+
fs27.writeFileSync(
|
|
6900
7055
|
termsPageTs,
|
|
6901
7056
|
pageMetaTagsLoader("Terms of Service", `Terms of Service for ${core.websiteName}`)
|
|
6902
7057
|
);
|
|
6903
|
-
const relativeTermsPage =
|
|
6904
|
-
const relativeTermsPageTs =
|
|
7058
|
+
const relativeTermsPage = path25.relative(workspaceRootDir, termsPage);
|
|
7059
|
+
const relativeTermsPageTs = path25.relative(workspaceRootDir, termsPageTs);
|
|
6905
7060
|
reportResult({
|
|
6906
7061
|
summary: "Generated placeholder terms and conditions.",
|
|
6907
7062
|
filesCreated: [relativeTermsPage, relativeTermsPageTs],
|
|
@@ -6912,12 +7067,12 @@ async function termsAction() {
|
|
|
6912
7067
|
]
|
|
6913
7068
|
});
|
|
6914
7069
|
}
|
|
6915
|
-
var terms = new
|
|
7070
|
+
var terms = new Command57("terms").description("generate placeholder terms and conditions").configureHelp(helpConfig).action(() => runCommand(termsAction, "Failed to generate terms and conditions."));
|
|
6916
7071
|
|
|
6917
7072
|
// src/commands/legal/privacy.ts
|
|
6918
|
-
import
|
|
6919
|
-
import
|
|
6920
|
-
import { Command as
|
|
7073
|
+
import fs28 from "node:fs";
|
|
7074
|
+
import path26 from "node:path";
|
|
7075
|
+
import { Command as Command58 } from "commander";
|
|
6921
7076
|
import * as p36 from "@clack/prompts";
|
|
6922
7077
|
var mapLabels = {
|
|
6923
7078
|
personalInfo: {
|
|
@@ -7350,10 +7505,11 @@ async function promptWithCustom(message, options, customMessage) {
|
|
|
7350
7505
|
}
|
|
7351
7506
|
async function privacyAction() {
|
|
7352
7507
|
const { workspaceRootDir, publicRoutesDir } = await getWorkspace();
|
|
7508
|
+
const site = siteFields(await readSite(workspaceRootDir));
|
|
7353
7509
|
const core = await p36.group(
|
|
7354
7510
|
{
|
|
7355
|
-
websiteUrl:
|
|
7356
|
-
websiteName:
|
|
7511
|
+
websiteUrl: site.websiteUrl,
|
|
7512
|
+
websiteName: site.websiteName,
|
|
7357
7513
|
entityType: sharedFields.entityType,
|
|
7358
7514
|
businessName: sharedFields.businessName,
|
|
7359
7515
|
businessAddress: sharedFields.businessAddress,
|
|
@@ -7629,28 +7785,28 @@ async function privacyAction() {
|
|
|
7629
7785
|
kids,
|
|
7630
7786
|
retention
|
|
7631
7787
|
});
|
|
7632
|
-
const privacyPage =
|
|
7788
|
+
const privacyPage = path26.join(
|
|
7633
7789
|
workspaceRootDir,
|
|
7634
7790
|
publicRoutesDir,
|
|
7635
7791
|
LEGAL_DIR,
|
|
7636
7792
|
"privacy",
|
|
7637
7793
|
"+page.svelte"
|
|
7638
7794
|
);
|
|
7639
|
-
const privacyPageTs =
|
|
7795
|
+
const privacyPageTs = path26.join(
|
|
7640
7796
|
workspaceRootDir,
|
|
7641
7797
|
publicRoutesDir,
|
|
7642
7798
|
LEGAL_DIR,
|
|
7643
7799
|
"privacy",
|
|
7644
7800
|
"+page.ts"
|
|
7645
7801
|
);
|
|
7646
|
-
|
|
7647
|
-
|
|
7648
|
-
|
|
7802
|
+
fs28.mkdirSync(path26.dirname(privacyPage), { recursive: true });
|
|
7803
|
+
fs28.writeFileSync(privacyPage, html);
|
|
7804
|
+
fs28.writeFileSync(
|
|
7649
7805
|
privacyPageTs,
|
|
7650
7806
|
pageMetaTagsLoader("Privacy Policy", `Privacy Policy for ${core.websiteName}`)
|
|
7651
7807
|
);
|
|
7652
|
-
const relativePrivacyPage =
|
|
7653
|
-
const relativePrivacyPageTs =
|
|
7808
|
+
const relativePrivacyPage = path26.relative(workspaceRootDir, privacyPage);
|
|
7809
|
+
const relativePrivacyPageTs = path26.relative(workspaceRootDir, privacyPageTs);
|
|
7654
7810
|
reportResult({
|
|
7655
7811
|
summary: "Generated placeholder privacy policy.",
|
|
7656
7812
|
filesCreated: [relativePrivacyPage, relativePrivacyPageTs],
|
|
@@ -7661,20 +7817,20 @@ async function privacyAction() {
|
|
|
7661
7817
|
]
|
|
7662
7818
|
});
|
|
7663
7819
|
}
|
|
7664
|
-
var privacy = new
|
|
7820
|
+
var privacy = new Command58("privacy").description("generate placeholder privacy policy").configureHelp(helpConfig).action(() => runCommand(privacyAction, "Failed to generate privacy policy."));
|
|
7665
7821
|
|
|
7666
7822
|
// src/commands/legal.ts
|
|
7667
|
-
var legal = new
|
|
7823
|
+
var legal = new Command59("legal").description("generate placeholder legal documents").configureHelp(helpConfig).addCommand(terms).addCommand(privacy);
|
|
7668
7824
|
|
|
7669
7825
|
// src/commands/fixtures.ts
|
|
7670
|
-
import { Command as
|
|
7826
|
+
import { Command as Command65 } from "commander";
|
|
7671
7827
|
|
|
7672
7828
|
// src/commands/fixtures/load.ts
|
|
7673
|
-
import { Command as
|
|
7829
|
+
import { Command as Command60 } from "commander";
|
|
7674
7830
|
|
|
7675
7831
|
// src/lib/data.ts
|
|
7676
|
-
import
|
|
7677
|
-
import
|
|
7832
|
+
import fs29 from "node:fs";
|
|
7833
|
+
import path27 from "node:path";
|
|
7678
7834
|
import { ClientResponseError } from "pocketbase";
|
|
7679
7835
|
|
|
7680
7836
|
// src/lib/collections.ts
|
|
@@ -7711,14 +7867,14 @@ function dependencyOrder(collections2, startingCollectionId) {
|
|
|
7711
7867
|
|
|
7712
7868
|
// src/lib/data.ts
|
|
7713
7869
|
function dataDir(cwd, kind) {
|
|
7714
|
-
return
|
|
7870
|
+
return path27.join(cwd, DATA_DIR, kind);
|
|
7715
7871
|
}
|
|
7716
7872
|
function getDataFiles(cwd, kind) {
|
|
7717
7873
|
const dir = dataDir(cwd, kind);
|
|
7718
|
-
if (!
|
|
7719
|
-
return
|
|
7874
|
+
if (!fs29.existsSync(dir)) return [];
|
|
7875
|
+
return fs29.readdirSync(dir).filter((file) => file.endsWith(".json")).sort((a, b) => a.localeCompare(b)).map((file) => ({
|
|
7720
7876
|
collectionName: file.replace(/\.json$/i, "").replace(/^\d+[-_]?/, ""),
|
|
7721
|
-
filePath:
|
|
7877
|
+
filePath: path27.join(dir, file)
|
|
7722
7878
|
}));
|
|
7723
7879
|
}
|
|
7724
7880
|
function getSeedFiles(cwd) {
|
|
@@ -7728,7 +7884,7 @@ function getFixtureFiles(cwd) {
|
|
|
7728
7884
|
return getDataFiles(cwd, "fixtures");
|
|
7729
7885
|
}
|
|
7730
7886
|
function readRecords(filePath) {
|
|
7731
|
-
return JSON.parse(
|
|
7887
|
+
return JSON.parse(fs29.readFileSync(filePath, "utf8"));
|
|
7732
7888
|
}
|
|
7733
7889
|
function readSeedIds(cwd) {
|
|
7734
7890
|
const ids = /* @__PURE__ */ new Map();
|
|
@@ -7765,7 +7921,7 @@ function describeError(e) {
|
|
|
7765
7921
|
return e instanceof Error ? e.message : String(e);
|
|
7766
7922
|
}
|
|
7767
7923
|
function label3(cwd, filePath, count) {
|
|
7768
|
-
return `${
|
|
7924
|
+
return `${path27.relative(cwd, filePath)} (${count} records)`;
|
|
7769
7925
|
}
|
|
7770
7926
|
async function createRecords(pb, kind, cwd, { collectionName, filePath }) {
|
|
7771
7927
|
const records = readRecords(filePath);
|
|
@@ -7773,7 +7929,7 @@ async function createRecords(pb, kind, cwd, { collectionName, filePath }) {
|
|
|
7773
7929
|
try {
|
|
7774
7930
|
await pb.collection(collectionName).create(record);
|
|
7775
7931
|
} catch (e) {
|
|
7776
|
-
throw new DataLoadError(kind,
|
|
7932
|
+
throw new DataLoadError(kind, path27.relative(cwd, filePath), index, e);
|
|
7777
7933
|
}
|
|
7778
7934
|
}
|
|
7779
7935
|
return records.length;
|
|
@@ -7860,7 +8016,7 @@ async function hasLoadedFixtures(pb) {
|
|
|
7860
8016
|
}
|
|
7861
8017
|
|
|
7862
8018
|
// src/commands/fixtures/load.ts
|
|
7863
|
-
var load = new
|
|
8019
|
+
var load = new Command60("load").description("load fixtures into the database").configureHelp(helpConfig).action(
|
|
7864
8020
|
() => runCommand(async () => {
|
|
7865
8021
|
const { workspaceRootDir } = await getWorkspace();
|
|
7866
8022
|
let loaded = [];
|
|
@@ -7886,8 +8042,8 @@ var load = new Command57("load").description("load fixtures into the database").
|
|
|
7886
8042
|
);
|
|
7887
8043
|
|
|
7888
8044
|
// src/commands/fixtures/clear.ts
|
|
7889
|
-
import { Command as
|
|
7890
|
-
var clear = new
|
|
8045
|
+
import { Command as Command61 } from "commander";
|
|
8046
|
+
var clear = new Command61("clear").description("clear loaded fixtures").configureHelp(helpConfig).action(
|
|
7891
8047
|
() => runCommand(async () => {
|
|
7892
8048
|
const { workspaceRootDir } = await getWorkspace();
|
|
7893
8049
|
let cleared = [];
|
|
@@ -7916,8 +8072,8 @@ var clear = new Command58("clear").description("clear loaded fixtures").configur
|
|
|
7916
8072
|
);
|
|
7917
8073
|
|
|
7918
8074
|
// src/commands/fixtures/reset.ts
|
|
7919
|
-
import { Command as
|
|
7920
|
-
var reset = new
|
|
8075
|
+
import { Command as Command62 } from "commander";
|
|
8076
|
+
var reset = new Command62("reset").description("clear and reload fixtures").configureHelp(helpConfig).action(
|
|
7921
8077
|
() => runCommand(async () => {
|
|
7922
8078
|
const { workspaceRootDir } = await getWorkspace();
|
|
7923
8079
|
let cleared = [];
|
|
@@ -7947,9 +8103,9 @@ var reset = new Command59("reset").description("clear and reload fixtures").conf
|
|
|
7947
8103
|
);
|
|
7948
8104
|
|
|
7949
8105
|
// src/commands/fixtures/generate.ts
|
|
7950
|
-
import
|
|
7951
|
-
import
|
|
7952
|
-
import { Command as
|
|
8106
|
+
import fs30 from "node:fs";
|
|
8107
|
+
import path28 from "node:path";
|
|
8108
|
+
import { Command as Command63, InvalidArgumentError } from "commander";
|
|
7953
8109
|
import * as p37 from "@clack/prompts";
|
|
7954
8110
|
import { annotate } from "annotate-json-schema";
|
|
7955
8111
|
import { createGenerator } from "json-schema-faker";
|
|
@@ -7985,9 +8141,9 @@ async function loadCollections(pb) {
|
|
|
7985
8141
|
}
|
|
7986
8142
|
async function generateFixtureFiles(pb, workspaceRootDir, opts) {
|
|
7987
8143
|
const fixturesDir = dataDir(workspaceRootDir, "fixtures");
|
|
7988
|
-
|
|
7989
|
-
for (const file of
|
|
7990
|
-
if (file.endsWith(".json"))
|
|
8144
|
+
fs30.mkdirSync(fixturesDir, { recursive: true });
|
|
8145
|
+
for (const file of fs30.readdirSync(fixturesDir)) {
|
|
8146
|
+
if (file.endsWith(".json")) fs30.unlinkSync(path28.join(fixturesDir, file));
|
|
7991
8147
|
}
|
|
7992
8148
|
if (opts.seed !== void 0) faker.seed(opts.seed);
|
|
7993
8149
|
const generator = createGenerator({
|
|
@@ -8054,13 +8210,13 @@ async function generateFixtureFiles(pb, workspaceRootDir, opts) {
|
|
|
8054
8210
|
items.push(record);
|
|
8055
8211
|
}
|
|
8056
8212
|
const filename = `${padZeros(fileIndex, 2)}-${collection.name}.json`;
|
|
8057
|
-
|
|
8058
|
-
writtenFiles.push(`${
|
|
8213
|
+
fs30.writeFileSync(path28.join(fixturesDir, filename), JSON.stringify(items, null, 2));
|
|
8214
|
+
writtenFiles.push(`${path28.join(DATA_DIR, "fixtures", filename)} (${items.length} records)`);
|
|
8059
8215
|
fileIndex++;
|
|
8060
8216
|
}
|
|
8061
8217
|
return { writtenFiles, warnings };
|
|
8062
8218
|
}
|
|
8063
|
-
var generate2 = new
|
|
8219
|
+
var generate2 = new Command63("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(
|
|
8064
8220
|
(opts) => runCommand(async () => {
|
|
8065
8221
|
const { workspaceRootDir } = await getWorkspace();
|
|
8066
8222
|
const existing = getFixtureFiles(workspaceRootDir);
|
|
@@ -8113,7 +8269,7 @@ var generate2 = new Command60("generate").description("generate fixture data").o
|
|
|
8113
8269
|
);
|
|
8114
8270
|
|
|
8115
8271
|
// src/commands/fixtures/regen.ts
|
|
8116
|
-
import { Command as
|
|
8272
|
+
import { Command as Command64, InvalidArgumentError as InvalidArgumentError2 } from "commander";
|
|
8117
8273
|
import * as p38 from "@clack/prompts";
|
|
8118
8274
|
function parseCount2(value) {
|
|
8119
8275
|
const n = parseInt(value, 10);
|
|
@@ -8129,7 +8285,7 @@ function parseSeed2(value) {
|
|
|
8129
8285
|
}
|
|
8130
8286
|
return n;
|
|
8131
8287
|
}
|
|
8132
|
-
var regen = new
|
|
8288
|
+
var regen = new Command64("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(
|
|
8133
8289
|
(opts) => runCommand(async () => {
|
|
8134
8290
|
const { workspaceRootDir } = await getWorkspace();
|
|
8135
8291
|
let cleared = [];
|
|
@@ -8158,14 +8314,14 @@ var regen = new Command61("regen").description("clear the database, regenerate f
|
|
|
8158
8314
|
);
|
|
8159
8315
|
|
|
8160
8316
|
// src/commands/fixtures.ts
|
|
8161
|
-
var fixtures = new
|
|
8317
|
+
var fixtures = new Command65("fixtures").description("manage fixture data").configureHelp(helpConfig).addCommand(generate2).addCommand(load).addCommand(clear).addCommand(reset).addCommand(regen);
|
|
8162
8318
|
|
|
8163
8319
|
// src/commands/seeds.ts
|
|
8164
|
-
import { Command as
|
|
8320
|
+
import { Command as Command69 } from "commander";
|
|
8165
8321
|
|
|
8166
8322
|
// src/commands/seeds/load.ts
|
|
8167
|
-
import { Command as
|
|
8168
|
-
var load2 = new
|
|
8323
|
+
import { Command as Command66 } from "commander";
|
|
8324
|
+
var load2 = new Command66("load").description("load seeds into the database").option("-f, --force", "load even if target collections already have records").configureHelp(helpConfig).action(
|
|
8169
8325
|
(opts) => runCommand(async () => {
|
|
8170
8326
|
const { workspaceRootDir } = await getWorkspace();
|
|
8171
8327
|
const seedFiles = getSeedFiles(workspaceRootDir);
|
|
@@ -8202,9 +8358,9 @@ var load2 = new Command63("load").description("load seeds into the database").op
|
|
|
8202
8358
|
);
|
|
8203
8359
|
|
|
8204
8360
|
// src/commands/seeds/save.ts
|
|
8205
|
-
import
|
|
8206
|
-
import
|
|
8207
|
-
import { Command as
|
|
8361
|
+
import fs31 from "node:fs";
|
|
8362
|
+
import path29 from "node:path";
|
|
8363
|
+
import { Command as Command67 } from "commander";
|
|
8208
8364
|
var padZeros2 = (num, length) => num.toString().padStart(length, "0");
|
|
8209
8365
|
function filterSystemFields(record, systemFieldNames) {
|
|
8210
8366
|
const out = {};
|
|
@@ -8215,7 +8371,7 @@ function filterSystemFields(record, systemFieldNames) {
|
|
|
8215
8371
|
}
|
|
8216
8372
|
return out;
|
|
8217
8373
|
}
|
|
8218
|
-
var save = new
|
|
8374
|
+
var save = new Command67("save").description("save the current data as seeds").option("-f, --force", "overwrite existing seed files").configureHelp(helpConfig).action(
|
|
8219
8375
|
(opts) => runCommand(async () => {
|
|
8220
8376
|
const { workspaceRootDir } = await getWorkspace();
|
|
8221
8377
|
const seedsPath = dataDir(workspaceRootDir, "seeds");
|
|
@@ -8223,10 +8379,10 @@ var save = new Command64("save").description("save the current data as seeds").o
|
|
|
8223
8379
|
if (existing.length > 0 && !opts.force) {
|
|
8224
8380
|
throw new Error("Existing seed files found in data/seeds. Pass --force to overwrite.");
|
|
8225
8381
|
}
|
|
8226
|
-
|
|
8382
|
+
fs31.mkdirSync(seedsPath, { recursive: true });
|
|
8227
8383
|
if (opts.force) {
|
|
8228
|
-
for (const file of
|
|
8229
|
-
if (file.endsWith(".json"))
|
|
8384
|
+
for (const file of fs31.readdirSync(seedsPath)) {
|
|
8385
|
+
if (file.endsWith(".json")) fs31.unlinkSync(path29.join(seedsPath, file));
|
|
8230
8386
|
}
|
|
8231
8387
|
}
|
|
8232
8388
|
const saved = [];
|
|
@@ -8255,13 +8411,13 @@ var save = new Command64("save").description("save the current data as seeds").o
|
|
|
8255
8411
|
const filtered = records.map(
|
|
8256
8412
|
(r) => filterSystemFields(r, systemFieldNames)
|
|
8257
8413
|
);
|
|
8258
|
-
const relativeSeedPath =
|
|
8414
|
+
const relativeSeedPath = path29.join(
|
|
8259
8415
|
DATA_DIR,
|
|
8260
8416
|
"seeds",
|
|
8261
8417
|
`${padZeros2(count, 2)}-${collectionName}.json`
|
|
8262
8418
|
);
|
|
8263
|
-
const seedPath =
|
|
8264
|
-
|
|
8419
|
+
const seedPath = path29.join(workspaceRootDir, relativeSeedPath);
|
|
8420
|
+
fs31.writeFileSync(seedPath, JSON.stringify(filtered, null, 2));
|
|
8265
8421
|
saved.push(`${relativeSeedPath} (${filtered.length} records)`);
|
|
8266
8422
|
count++;
|
|
8267
8423
|
}
|
|
@@ -8287,8 +8443,8 @@ var save = new Command64("save").description("save the current data as seeds").o
|
|
|
8287
8443
|
);
|
|
8288
8444
|
|
|
8289
8445
|
// src/commands/seeds/clear.ts
|
|
8290
|
-
import { Command as
|
|
8291
|
-
var clear2 = new
|
|
8446
|
+
import { Command as Command68 } from "commander";
|
|
8447
|
+
var clear2 = new Command68("clear").description("clear seeded records").configureHelp(helpConfig).action(
|
|
8292
8448
|
() => runCommand(async () => {
|
|
8293
8449
|
const { workspaceRootDir } = await getWorkspace();
|
|
8294
8450
|
const seedFiles = getSeedFiles(workspaceRootDir);
|
|
@@ -8319,20 +8475,20 @@ var clear2 = new Command65("clear").description("clear seeded records").configur
|
|
|
8319
8475
|
);
|
|
8320
8476
|
|
|
8321
8477
|
// src/commands/seeds.ts
|
|
8322
|
-
var seeds = new
|
|
8478
|
+
var seeds = new Command69("seeds").description("manage seed data").configureHelp(helpConfig).addCommand(load2).addCommand(save).addCommand(clear2);
|
|
8323
8479
|
|
|
8324
8480
|
// src/commands/signup.ts
|
|
8325
|
-
import { Command as
|
|
8481
|
+
import { Command as Command70 } from "commander";
|
|
8326
8482
|
import * as p39 from "@clack/prompts";
|
|
8327
8483
|
import makeFetchCookie2 from "fetch-cookie";
|
|
8328
|
-
var signup = new
|
|
8484
|
+
var signup = new Command70("signup").description("signup to velastack.dev").configureHelp(helpConfig).action(
|
|
8329
8485
|
() => runCommand(async () => {
|
|
8330
|
-
const { email: email3, password:
|
|
8486
|
+
const { email: email3, password: password12, passwordConfirm } = await p39.group({
|
|
8331
8487
|
email: () => p39.text({ message: "Email" }),
|
|
8332
8488
|
password: () => p39.password({ message: "Password" }),
|
|
8333
8489
|
passwordConfirm: () => p39.password({ message: "Confirm password" })
|
|
8334
8490
|
});
|
|
8335
|
-
if (
|
|
8491
|
+
if (password12 !== passwordConfirm) {
|
|
8336
8492
|
throw new Error("Passwords do not match.");
|
|
8337
8493
|
}
|
|
8338
8494
|
const fetchCookie = makeFetchCookie2(fetch);
|
|
@@ -8345,7 +8501,7 @@ var signup = new Command67("signup").description("signup to velastack.dev").conf
|
|
|
8345
8501
|
body: new URLSearchParams({
|
|
8346
8502
|
type: "password",
|
|
8347
8503
|
email: email3,
|
|
8348
|
-
password:
|
|
8504
|
+
password: password12,
|
|
8349
8505
|
passwordConfirm
|
|
8350
8506
|
}).toString()
|
|
8351
8507
|
});
|
|
@@ -8360,9 +8516,9 @@ var signup = new Command67("signup").description("signup to velastack.dev").conf
|
|
|
8360
8516
|
);
|
|
8361
8517
|
|
|
8362
8518
|
// src/commands/logout.ts
|
|
8363
|
-
import { Command as
|
|
8519
|
+
import { Command as Command71 } from "commander";
|
|
8364
8520
|
import * as p40 from "@clack/prompts";
|
|
8365
|
-
var logout = new
|
|
8521
|
+
var logout = new Command71("logout").alias("signout").description("logout from velastack.dev").configureHelp(helpConfig).action(
|
|
8366
8522
|
() => runCommand(() => {
|
|
8367
8523
|
if (!readConfig()) {
|
|
8368
8524
|
p40.log.info("Not logged in");
|
|
@@ -8374,9 +8530,9 @@ var logout = new Command68("logout").alias("signout").description("logout from v
|
|
|
8374
8530
|
);
|
|
8375
8531
|
|
|
8376
8532
|
// src/commands/whoami.ts
|
|
8377
|
-
import { Command as
|
|
8533
|
+
import { Command as Command72 } from "commander";
|
|
8378
8534
|
import * as p41 from "@clack/prompts";
|
|
8379
|
-
var whoami = new
|
|
8535
|
+
var whoami = new Command72("whoami").description("show the current user").configureHelp(helpConfig).action(
|
|
8380
8536
|
() => runCommand(async () => {
|
|
8381
8537
|
const apiKey = readConfig()?.apiKey;
|
|
8382
8538
|
if (!apiKey) {
|
|
@@ -8393,13 +8549,13 @@ var whoami = new Command69("whoami").description("show the current user").config
|
|
|
8393
8549
|
);
|
|
8394
8550
|
|
|
8395
8551
|
// src/commands/migrate.ts
|
|
8396
|
-
import { Command as
|
|
8552
|
+
import { Command as Command78 } from "commander";
|
|
8397
8553
|
|
|
8398
8554
|
// src/commands/migrate/up.ts
|
|
8399
|
-
import { Command as
|
|
8555
|
+
import { Command as Command73 } from "commander";
|
|
8400
8556
|
|
|
8401
8557
|
// src/lib/migrate.ts
|
|
8402
|
-
import
|
|
8558
|
+
import path30 from "node:path";
|
|
8403
8559
|
import process23 from "node:process";
|
|
8404
8560
|
import { x as x2 } from "tinyexec";
|
|
8405
8561
|
async function runPocketbaseMigrate(args) {
|
|
@@ -8410,9 +8566,9 @@ async function runPocketbaseMigrate(args) {
|
|
|
8410
8566
|
binaryPath,
|
|
8411
8567
|
[
|
|
8412
8568
|
"--dir",
|
|
8413
|
-
|
|
8569
|
+
path30.join(cwd, DATA_DIR),
|
|
8414
8570
|
"--migrationsDir",
|
|
8415
|
-
|
|
8571
|
+
path30.join(cwd, MIGRATIONS_DIR),
|
|
8416
8572
|
"migrate",
|
|
8417
8573
|
...args
|
|
8418
8574
|
],
|
|
@@ -8435,10 +8591,10 @@ async function runMigrateUp() {
|
|
|
8435
8591
|
]
|
|
8436
8592
|
});
|
|
8437
8593
|
}
|
|
8438
|
-
var up = new
|
|
8594
|
+
var up = new Command73("up").description("apply all pending migrations").configureHelp(helpConfig).action(() => runCommand(runMigrateUp, "Failed to run migrations."));
|
|
8439
8595
|
|
|
8440
8596
|
// src/commands/migrate/down.ts
|
|
8441
|
-
import { Command as
|
|
8597
|
+
import { Command as Command74, InvalidArgumentError as InvalidArgumentError3 } from "commander";
|
|
8442
8598
|
function parseSteps(value) {
|
|
8443
8599
|
const n = parseInt(value, 10);
|
|
8444
8600
|
if (!Number.isFinite(n) || n <= 0) {
|
|
@@ -8446,7 +8602,7 @@ function parseSteps(value) {
|
|
|
8446
8602
|
}
|
|
8447
8603
|
return n;
|
|
8448
8604
|
}
|
|
8449
|
-
var down = new
|
|
8605
|
+
var down = new Command74("down").alias("rollback").description("revert the last N applied migrations").argument("[number]", "how many migrations to revert", parseSteps, 1).configureHelp(helpConfig).action(
|
|
8450
8606
|
(n) => runCommand(async () => {
|
|
8451
8607
|
await runPocketbaseMigrate(["down", String(n)]);
|
|
8452
8608
|
reportResult({
|
|
@@ -8460,11 +8616,11 @@ var down = new Command71("down").alias("rollback").description("revert the last
|
|
|
8460
8616
|
);
|
|
8461
8617
|
|
|
8462
8618
|
// src/commands/migrate/create.ts
|
|
8463
|
-
import
|
|
8464
|
-
import
|
|
8619
|
+
import fs32 from "node:fs";
|
|
8620
|
+
import path31 from "node:path";
|
|
8465
8621
|
import process24 from "node:process";
|
|
8466
|
-
import { Command as
|
|
8467
|
-
var create2 = new
|
|
8622
|
+
import { Command as Command75 } from "commander";
|
|
8623
|
+
var create2 = new Command75("create").alias("new").description("create a new blank migration").argument("<name>", "migration name (snake_case)").configureHelp(helpConfig).action(
|
|
8468
8624
|
(name) => runCommand(async () => {
|
|
8469
8625
|
const cwd = process24.cwd();
|
|
8470
8626
|
const before = listMigrationFiles(cwd);
|
|
@@ -8473,7 +8629,7 @@ var create2 = new Command72("create").alias("new").description("create a new bla
|
|
|
8473
8629
|
const added = [...after].filter((f) => !before.has(f));
|
|
8474
8630
|
reportResult({
|
|
8475
8631
|
summary: `Created blank migration ${name}.`,
|
|
8476
|
-
filesCreated: added.map((f) =>
|
|
8632
|
+
filesCreated: added.map((f) => path31.join(MIGRATIONS_DIR, f)),
|
|
8477
8633
|
nextSteps: [
|
|
8478
8634
|
`Open the new file in ${MIGRATIONS_DIR}/ and fill in the up/down handlers.`,
|
|
8479
8635
|
"Run `vela migrate up` to apply the migration once the handlers are written."
|
|
@@ -8482,17 +8638,17 @@ var create2 = new Command72("create").alias("new").description("create a new bla
|
|
|
8482
8638
|
}, "Failed to create migration.")
|
|
8483
8639
|
);
|
|
8484
8640
|
function listMigrationFiles(cwd) {
|
|
8485
|
-
const dir =
|
|
8486
|
-
if (!
|
|
8487
|
-
return new Set(
|
|
8641
|
+
const dir = path31.join(cwd, MIGRATIONS_DIR);
|
|
8642
|
+
if (!fs32.existsSync(dir)) return /* @__PURE__ */ new Set();
|
|
8643
|
+
return new Set(fs32.readdirSync(dir).filter((f) => /\.[jt]s$/.test(f)));
|
|
8488
8644
|
}
|
|
8489
8645
|
|
|
8490
8646
|
// src/commands/migrate/collections.ts
|
|
8491
|
-
import
|
|
8492
|
-
import
|
|
8647
|
+
import fs33 from "node:fs";
|
|
8648
|
+
import path32 from "node:path";
|
|
8493
8649
|
import process25 from "node:process";
|
|
8494
|
-
import { Command as
|
|
8495
|
-
var collections = new
|
|
8650
|
+
import { Command as Command76 } from "commander";
|
|
8651
|
+
var collections = new Command76("collections").alias("snapshot").description("snapshot local collections into a new migration").configureHelp(helpConfig).action(
|
|
8496
8652
|
() => runCommand(async () => {
|
|
8497
8653
|
const cwd = process25.cwd();
|
|
8498
8654
|
const before = listMigrationFiles2(cwd);
|
|
@@ -8507,7 +8663,7 @@ var collections = new Command73("collections").alias("snapshot").description("sn
|
|
|
8507
8663
|
}
|
|
8508
8664
|
reportResult({
|
|
8509
8665
|
summary: "Snapshotted local collections into a new migration.",
|
|
8510
|
-
filesCreated: added.map((f) =>
|
|
8666
|
+
filesCreated: added.map((f) => path32.join(MIGRATIONS_DIR, f)),
|
|
8511
8667
|
nextSteps: [
|
|
8512
8668
|
`Review the generated snapshot in ${MIGRATIONS_DIR}/.`,
|
|
8513
8669
|
"Commit the snapshot so teammates pick up the new schema.",
|
|
@@ -8517,14 +8673,14 @@ var collections = new Command73("collections").alias("snapshot").description("sn
|
|
|
8517
8673
|
}, "Failed to snapshot collections.")
|
|
8518
8674
|
);
|
|
8519
8675
|
function listMigrationFiles2(cwd) {
|
|
8520
|
-
const dir =
|
|
8521
|
-
if (!
|
|
8522
|
-
return new Set(
|
|
8676
|
+
const dir = path32.join(cwd, MIGRATIONS_DIR);
|
|
8677
|
+
if (!fs33.existsSync(dir)) return /* @__PURE__ */ new Set();
|
|
8678
|
+
return new Set(fs33.readdirSync(dir).filter((f) => /\.[jt]s$/.test(f)));
|
|
8523
8679
|
}
|
|
8524
8680
|
|
|
8525
8681
|
// src/commands/migrate/history-sync.ts
|
|
8526
|
-
import { Command as
|
|
8527
|
-
var historySync = new
|
|
8682
|
+
import { Command as Command77 } from "commander";
|
|
8683
|
+
var historySync = new Command77("history-sync").description("drop _migrations rows whose files no longer exist").configureHelp(helpConfig).action(
|
|
8528
8684
|
() => runCommand(async () => {
|
|
8529
8685
|
await runPocketbaseMigrate(["history-sync"]);
|
|
8530
8686
|
reportResult({
|
|
@@ -8535,14 +8691,14 @@ var historySync = new Command74("history-sync").description("drop _migrations ro
|
|
|
8535
8691
|
);
|
|
8536
8692
|
|
|
8537
8693
|
// src/commands/migrate.ts
|
|
8538
|
-
var migrate = new
|
|
8694
|
+
var migrate = new Command78("migrate").description("manage database migrations").configureHelp(helpConfig).action(() => runCommand(runMigrateUp, "Failed to run migrations.")).addCommand(up).addCommand(down).addCommand(create2).addCommand(collections).addCommand(historySync);
|
|
8539
8695
|
|
|
8540
8696
|
// src/commands/dev.ts
|
|
8541
|
-
import
|
|
8542
|
-
import
|
|
8697
|
+
import fs34 from "node:fs";
|
|
8698
|
+
import path34 from "node:path";
|
|
8543
8699
|
import process27 from "node:process";
|
|
8544
8700
|
import { performance } from "node:perf_hooks";
|
|
8545
|
-
import { Command as
|
|
8701
|
+
import { Command as Command79, InvalidArgumentError as InvalidArgumentError4 } from "commander";
|
|
8546
8702
|
import pc15 from "picocolors";
|
|
8547
8703
|
import PocketBase4 from "pocketbase";
|
|
8548
8704
|
|
|
@@ -8571,7 +8727,7 @@ function createPocketbaseLogFilter() {
|
|
|
8571
8727
|
}
|
|
8572
8728
|
|
|
8573
8729
|
// src/lib/vite.ts
|
|
8574
|
-
import
|
|
8730
|
+
import path33 from "node:path";
|
|
8575
8731
|
import process26 from "node:process";
|
|
8576
8732
|
import { createRequire as createRequire2 } from "node:module";
|
|
8577
8733
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
@@ -8591,7 +8747,7 @@ function viteVersionError(version) {
|
|
|
8591
8747
|
}
|
|
8592
8748
|
function resolveProjectVite(cwd) {
|
|
8593
8749
|
try {
|
|
8594
|
-
return createRequire2(
|
|
8750
|
+
return createRequire2(path33.join(cwd, "package.json")).resolve("vite");
|
|
8595
8751
|
} catch {
|
|
8596
8752
|
return null;
|
|
8597
8753
|
}
|
|
@@ -8615,26 +8771,26 @@ function parsePort(value) {
|
|
|
8615
8771
|
}
|
|
8616
8772
|
return port;
|
|
8617
8773
|
}
|
|
8618
|
-
var dev = new
|
|
8774
|
+
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) => {
|
|
8619
8775
|
const cwd = process27.cwd();
|
|
8620
8776
|
process27.env.VELA_DATA_DIR ??= localDataDir(cwd);
|
|
8621
8777
|
const startTime = performance.now();
|
|
8622
8778
|
const { createServer, version } = await loadVite(cwd);
|
|
8623
|
-
const viteMetadataDir =
|
|
8624
|
-
const viteMetadataFile =
|
|
8779
|
+
const viteMetadataDir = path34.join(cwd, "node_modules", ".vite");
|
|
8780
|
+
const viteMetadataFile = path34.join(viteMetadataDir, "_pocketbase_metadata.json");
|
|
8625
8781
|
let pbProc;
|
|
8626
8782
|
const backend3 = hasBackend(cwd);
|
|
8627
8783
|
const needsStart = backend3 && !process27.env.POCKETBASE_URL;
|
|
8628
8784
|
const cleanup = () => {
|
|
8629
8785
|
if (pbProc?.pid) pbProc.kill();
|
|
8630
|
-
if (
|
|
8786
|
+
if (fs34.existsSync(viteMetadataFile)) fs34.rmSync(viteMetadataFile);
|
|
8631
8787
|
};
|
|
8632
8788
|
if (needsStart) {
|
|
8633
|
-
const dataDir2 =
|
|
8789
|
+
const dataDir2 = path34.join(cwd, DATA_DIR);
|
|
8634
8790
|
const started = await startPocketbaseServe({
|
|
8635
8791
|
dataDir: dataDir2,
|
|
8636
8792
|
migrationsDir: MIGRATIONS_DIR,
|
|
8637
|
-
hooksDir:
|
|
8793
|
+
hooksDir: path34.join(dataDir2, "hooks"),
|
|
8638
8794
|
dev: true,
|
|
8639
8795
|
stdio: "pipe"
|
|
8640
8796
|
});
|
|
@@ -8666,8 +8822,8 @@ var dev = new Command76("dev").description("start the development server").optio
|
|
|
8666
8822
|
if (!backend3) return;
|
|
8667
8823
|
const { address, port: vitePort } = server.httpServer.address();
|
|
8668
8824
|
const viteHost = address === "::1" ? "localhost" : address;
|
|
8669
|
-
await
|
|
8670
|
-
await
|
|
8825
|
+
await fs34.promises.mkdir(viteMetadataDir, { recursive: true });
|
|
8826
|
+
await fs34.promises.writeFile(
|
|
8671
8827
|
viteMetadataFile,
|
|
8672
8828
|
JSON.stringify({
|
|
8673
8829
|
pocketbaseUrl: process27.env.POCKETBASE_URL,
|
|
@@ -8680,7 +8836,20 @@ var dev = new Command76("dev").description("start the development server").optio
|
|
|
8680
8836
|
process27.env.POCKETBASE_SUPERUSER_EMAIL,
|
|
8681
8837
|
process27.env.POCKETBASE_SUPERUSER_PASSWORD
|
|
8682
8838
|
);
|
|
8683
|
-
|
|
8839
|
+
const site = await readSite(cwd);
|
|
8840
|
+
await pb.settings.update({
|
|
8841
|
+
meta: {
|
|
8842
|
+
appURL: `http://${viteHost}:${vitePort}`,
|
|
8843
|
+
...site?.name && { appName: site.name }
|
|
8844
|
+
}
|
|
8845
|
+
});
|
|
8846
|
+
if (!site?.name) {
|
|
8847
|
+
console.log(
|
|
8848
|
+
pc15.dim(
|
|
8849
|
+
`No app name in ${SITE_FILE}, so PocketBase keeps the one it has. Add \`export const site = { name: '\u2026', url: '\u2026' }\` there to set it from code.`
|
|
8850
|
+
)
|
|
8851
|
+
);
|
|
8852
|
+
}
|
|
8684
8853
|
await startWatchingTypes(cwd, pb);
|
|
8685
8854
|
});
|
|
8686
8855
|
await server.listen();
|
|
@@ -8699,18 +8868,18 @@ var dev = new Command76("dev").description("start the development server").optio
|
|
|
8699
8868
|
});
|
|
8700
8869
|
async function startWatchingTypes(cwd, pb) {
|
|
8701
8870
|
const { processTypes } = await import("@velastack/pocketbase-codegen");
|
|
8702
|
-
const typesDir =
|
|
8703
|
-
const pocketbaseDir =
|
|
8704
|
-
const pocketbaseTypes =
|
|
8871
|
+
const typesDir = path34.resolve(cwd, ".svelte-kit", "types");
|
|
8872
|
+
const pocketbaseDir = path34.join(typesDir, "pocketbase");
|
|
8873
|
+
const pocketbaseTypes = path34.join(pocketbaseDir, "$types.d.ts");
|
|
8705
8874
|
const regenerate = () => processTypes(pb, typesDir).catch(() => {
|
|
8706
8875
|
});
|
|
8707
8876
|
await regenerate();
|
|
8708
8877
|
void (async () => {
|
|
8709
8878
|
for (; ; ) {
|
|
8710
8879
|
try {
|
|
8711
|
-
await
|
|
8712
|
-
for await (const event of
|
|
8713
|
-
if (event.eventType === "rename" && event.filename === "$types.d.ts" && !
|
|
8880
|
+
await fs34.promises.mkdir(pocketbaseDir, { recursive: true });
|
|
8881
|
+
for await (const event of fs34.promises.watch(pocketbaseDir)) {
|
|
8882
|
+
if (event.eventType === "rename" && event.filename === "$types.d.ts" && !fs34.existsSync(pocketbaseTypes)) {
|
|
8714
8883
|
setTimeout(regenerate, 100);
|
|
8715
8884
|
}
|
|
8716
8885
|
}
|
|
@@ -8722,10 +8891,10 @@ async function startWatchingTypes(cwd, pb) {
|
|
|
8722
8891
|
}
|
|
8723
8892
|
|
|
8724
8893
|
// src/commands/build.ts
|
|
8725
|
-
import
|
|
8726
|
-
import
|
|
8894
|
+
import fs35 from "node:fs";
|
|
8895
|
+
import path35 from "node:path";
|
|
8727
8896
|
import process29 from "node:process";
|
|
8728
|
-
import { Command as
|
|
8897
|
+
import { Command as Command80 } from "commander";
|
|
8729
8898
|
import * as p42 from "@clack/prompts";
|
|
8730
8899
|
import pc16 from "picocolors";
|
|
8731
8900
|
import { x as x3 } from "tinyexec";
|
|
@@ -8761,8 +8930,8 @@ function splitHosts(value) {
|
|
|
8761
8930
|
}
|
|
8762
8931
|
|
|
8763
8932
|
// src/commands/build.ts
|
|
8764
|
-
var PRERENDERED_DIR =
|
|
8765
|
-
var build = new
|
|
8933
|
+
var PRERENDERED_DIR = path35.join(".svelte-kit", "output", "prerendered");
|
|
8934
|
+
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) => {
|
|
8766
8935
|
const cwd = process29.cwd();
|
|
8767
8936
|
applyBuildEnv(cwd);
|
|
8768
8937
|
const origin = await originForBuild(cwd, options.target);
|
|
@@ -8774,11 +8943,11 @@ var build = new Command77("build").description("build the app").configureHelp(he
|
|
|
8774
8943
|
};
|
|
8775
8944
|
if (needsStart) {
|
|
8776
8945
|
await ensureSuperuser(cwd);
|
|
8777
|
-
const dataDir2 =
|
|
8946
|
+
const dataDir2 = path35.join(cwd, DATA_DIR);
|
|
8778
8947
|
const started = await startPocketbaseServe({
|
|
8779
8948
|
dataDir: dataDir2,
|
|
8780
8949
|
migrationsDir: MIGRATIONS_DIR,
|
|
8781
|
-
hooksDir:
|
|
8950
|
+
hooksDir: path35.join(dataDir2, "hooks"),
|
|
8782
8951
|
dev: true
|
|
8783
8952
|
});
|
|
8784
8953
|
pbProc = started.proc;
|
|
@@ -8817,24 +8986,26 @@ async function originForBuild(cwd, target) {
|
|
|
8817
8986
|
}
|
|
8818
8987
|
}
|
|
8819
8988
|
function warnIfPrerendered(cwd) {
|
|
8820
|
-
const dir =
|
|
8821
|
-
if (!
|
|
8989
|
+
const dir = path35.join(cwd, PRERENDERED_DIR);
|
|
8990
|
+
if (!fs35.existsSync(dir) || fs35.readdirSync(dir).length === 0) return;
|
|
8822
8991
|
p42.log.warn(
|
|
8823
|
-
`Prerendered pages were built with no domain configured, so
|
|
8824
|
-
|
|
8992
|
+
`Prerendered pages were built with no domain configured, so anything they take
|
|
8993
|
+
from the request's origin points at SvelteKit's placeholder host rather than at
|
|
8994
|
+
this site. Links built from ${pc16.cyan("src/lib/site.ts")}, as the templates' canonical
|
|
8995
|
+
links are, don't depend on it.
|
|
8825
8996
|
|
|
8826
8997
|
Set one with ${pc16.cyan("vela deploy --domain example.com")}, or pass ${pc16.cyan("VELA_ORIGIN")}.`
|
|
8827
8998
|
);
|
|
8828
8999
|
}
|
|
8829
9000
|
|
|
8830
9001
|
// src/commands/preview.ts
|
|
8831
|
-
import
|
|
9002
|
+
import path36 from "node:path";
|
|
8832
9003
|
import process30 from "node:process";
|
|
8833
|
-
import { Command as
|
|
9004
|
+
import { Command as Command81 } from "commander";
|
|
8834
9005
|
import { x as x4 } from "tinyexec";
|
|
8835
9006
|
import { detect as detect6 } from "package-manager-detector";
|
|
8836
9007
|
import { resolveCommand as resolveCommand6 } from "package-manager-detector/commands";
|
|
8837
|
-
var preview = new
|
|
9008
|
+
var preview = new Command81("preview").description("preview the built app").configureHelp(helpConfig).action(async () => {
|
|
8838
9009
|
const cwd = process30.cwd();
|
|
8839
9010
|
process30.env.VELA_DATA_DIR ??= localDataDir(cwd);
|
|
8840
9011
|
let pbProc;
|
|
@@ -8843,11 +9014,11 @@ var preview = new Command78("preview").description("preview the built app").conf
|
|
|
8843
9014
|
if (pbProc?.pid) pbProc.kill();
|
|
8844
9015
|
};
|
|
8845
9016
|
if (needsStart) {
|
|
8846
|
-
const dataDir2 =
|
|
9017
|
+
const dataDir2 = path36.join(cwd, DATA_DIR);
|
|
8847
9018
|
const started = await startPocketbaseServe({
|
|
8848
9019
|
dataDir: dataDir2,
|
|
8849
9020
|
migrationsDir: MIGRATIONS_DIR,
|
|
8850
|
-
hooksDir:
|
|
9021
|
+
hooksDir: path36.join(dataDir2, "hooks"),
|
|
8851
9022
|
dev: true
|
|
8852
9023
|
});
|
|
8853
9024
|
pbProc = started.proc;
|
|
@@ -8873,12 +9044,12 @@ var preview = new Command78("preview").description("preview the built app").conf
|
|
|
8873
9044
|
});
|
|
8874
9045
|
|
|
8875
9046
|
// src/commands/sync.ts
|
|
8876
|
-
import
|
|
8877
|
-
import { Command as
|
|
8878
|
-
var sync = new
|
|
9047
|
+
import path37 from "node:path";
|
|
9048
|
+
import { Command as Command82 } from "commander";
|
|
9049
|
+
var sync = new Command82("sync").description("sync types from the database").configureHelp(helpConfig).action(
|
|
8879
9050
|
() => runCommand(async () => {
|
|
8880
9051
|
const { workspaceRootDir } = await getWorkspace();
|
|
8881
|
-
const typesDir =
|
|
9052
|
+
const typesDir = path37.join(workspaceRootDir, ".svelte-kit", "types");
|
|
8882
9053
|
const { processTypes } = await import("@velastack/pocketbase-codegen");
|
|
8883
9054
|
await withPocketbase(workspaceRootDir, async (pb) => {
|
|
8884
9055
|
await processTypes(pb, typesDir);
|
|
@@ -8888,7 +9059,7 @@ var sync = new Command79("sync").description("sync types from the database").con
|
|
|
8888
9059
|
);
|
|
8889
9060
|
|
|
8890
9061
|
// src/commands/provision.ts
|
|
8891
|
-
import { Command as
|
|
9062
|
+
import { Command as Command83 } from "commander";
|
|
8892
9063
|
import * as p43 from "@clack/prompts";
|
|
8893
9064
|
import pc17 from "picocolors";
|
|
8894
9065
|
import * as v7 from "valibot";
|
|
@@ -8898,7 +9069,7 @@ var OptionsSchema2 = v7.object({
|
|
|
8898
9069
|
nodeMajor: v7.optional(v7.string())
|
|
8899
9070
|
});
|
|
8900
9071
|
var provision = addSshOptions(
|
|
8901
|
-
new
|
|
9072
|
+
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)
|
|
8902
9073
|
).option("--pb-version <version>", "PocketBase version to install").option("--node-major <version>", "Node.js major version to install", "22").action(
|
|
8903
9074
|
(target, raw) => runCommand(async () => {
|
|
8904
9075
|
const options = parseOptions(OptionsSchema2, raw);
|
|
@@ -8940,35 +9111,35 @@ var provision = addSshOptions(
|
|
|
8940
9111
|
);
|
|
8941
9112
|
|
|
8942
9113
|
// src/commands/deploy.ts
|
|
8943
|
-
import
|
|
8944
|
-
import
|
|
8945
|
-
import { Command as
|
|
9114
|
+
import path40 from "node:path";
|
|
9115
|
+
import fs38 from "node:fs";
|
|
9116
|
+
import { Command as Command84, Option as Option2 } from "commander";
|
|
8946
9117
|
import * as p44 from "@clack/prompts";
|
|
8947
9118
|
import pc18 from "picocolors";
|
|
8948
9119
|
import * as v8 from "valibot";
|
|
8949
9120
|
|
|
8950
9121
|
// src/lib/pocketbase-settings.ts
|
|
8951
|
-
import
|
|
8952
|
-
import
|
|
9122
|
+
import fs36 from "node:fs";
|
|
9123
|
+
import path38 from "node:path";
|
|
8953
9124
|
import process31 from "node:process";
|
|
8954
9125
|
import PocketBase5 from "pocketbase";
|
|
8955
|
-
var COPIED_KEYS = ["
|
|
9126
|
+
var COPIED_KEYS = ["senderName", "senderAddress"];
|
|
8956
9127
|
async function readLocalMeta(cwd) {
|
|
8957
|
-
const dataDir2 =
|
|
8958
|
-
if (!
|
|
9128
|
+
const dataDir2 = path38.join(cwd, DATA_DIR);
|
|
9129
|
+
if (!fs36.existsSync(dataDir2)) return null;
|
|
8959
9130
|
const email3 = process31.env.POCKETBASE_SUPERUSER_EMAIL;
|
|
8960
|
-
const
|
|
8961
|
-
if (!email3 || !
|
|
9131
|
+
const password12 = process31.env.POCKETBASE_SUPERUSER_PASSWORD;
|
|
9132
|
+
if (!email3 || !password12) return null;
|
|
8962
9133
|
let proc;
|
|
8963
9134
|
try {
|
|
8964
9135
|
const started = await startPocketbaseServe({
|
|
8965
9136
|
dataDir: dataDir2,
|
|
8966
9137
|
migrationsDir: MIGRATIONS_DIR,
|
|
8967
|
-
hooksDir:
|
|
9138
|
+
hooksDir: path38.join(dataDir2, "hooks")
|
|
8968
9139
|
});
|
|
8969
9140
|
proc = started.proc;
|
|
8970
9141
|
const pb = new PocketBase5(started.url);
|
|
8971
|
-
await authWithRetries(pb, email3,
|
|
9142
|
+
await authWithRetries(pb, email3, password12);
|
|
8972
9143
|
const settings = await pb.settings.getAll();
|
|
8973
9144
|
return settings.meta ?? null;
|
|
8974
9145
|
} catch {
|
|
@@ -8977,37 +9148,39 @@ async function readLocalMeta(cwd) {
|
|
|
8977
9148
|
proc?.kill();
|
|
8978
9149
|
}
|
|
8979
9150
|
}
|
|
8980
|
-
|
|
8981
|
-
|
|
8982
|
-
let appURL = null;
|
|
8983
|
-
await withRemotePocketbase(session, instance, async (pb) => {
|
|
8984
|
-
const settings = await pb.settings.getAll();
|
|
8985
|
-
const value = settings.meta?.appURL;
|
|
8986
|
-
appURL = typeof value === "string" && value.trim() ? value : null;
|
|
8987
|
-
});
|
|
8988
|
-
return appURL;
|
|
8989
|
-
} catch {
|
|
8990
|
-
return null;
|
|
8991
|
-
}
|
|
8992
|
-
}
|
|
8993
|
-
async function seedRemoteMeta(session, instance, local, appURL) {
|
|
8994
|
-
const patch = {};
|
|
9151
|
+
function copiedMeta(local) {
|
|
9152
|
+
const copied = {};
|
|
8995
9153
|
for (const key of COPIED_KEYS) {
|
|
8996
|
-
const value = local[key];
|
|
8997
|
-
if (typeof value === "string" && value.trim())
|
|
9154
|
+
const value = local?.[key];
|
|
9155
|
+
if (typeof value === "string" && value.trim()) copied[key] = value;
|
|
8998
9156
|
}
|
|
8999
|
-
|
|
9000
|
-
|
|
9157
|
+
return copied;
|
|
9158
|
+
}
|
|
9159
|
+
async function syncRemoteMeta(session, instance, patch) {
|
|
9160
|
+
const wanted = Object.fromEntries(
|
|
9161
|
+
Object.entries(patch).filter(([, value]) => typeof value === "string" && value.trim())
|
|
9162
|
+
);
|
|
9163
|
+
let written = [];
|
|
9164
|
+
let appURL = null;
|
|
9001
9165
|
await withRemotePocketbase(session, instance, async (pb) => {
|
|
9002
9166
|
const settings = await pb.settings.getAll();
|
|
9003
|
-
|
|
9167
|
+
const meta = settings.meta ?? {};
|
|
9168
|
+
const changed = Object.fromEntries(
|
|
9169
|
+
Object.entries(wanted).filter(([key, value2]) => meta[key] !== value2)
|
|
9170
|
+
);
|
|
9171
|
+
written = Object.keys(changed);
|
|
9172
|
+
if (written.length > 0) {
|
|
9173
|
+
await pb.settings.update({ meta: { ...meta, ...changed } });
|
|
9174
|
+
}
|
|
9175
|
+
const value = { ...meta, ...changed }.appURL;
|
|
9176
|
+
appURL = typeof value === "string" && value.trim() ? value : null;
|
|
9004
9177
|
});
|
|
9005
|
-
return
|
|
9178
|
+
return { written, appURL };
|
|
9006
9179
|
}
|
|
9007
9180
|
|
|
9008
9181
|
// src/lib/adapter.ts
|
|
9009
|
-
import
|
|
9010
|
-
import
|
|
9182
|
+
import fs37 from "node:fs";
|
|
9183
|
+
import path39 from "node:path";
|
|
9011
9184
|
import {
|
|
9012
9185
|
Project as Project2,
|
|
9013
9186
|
QuoteKind as QuoteKind2,
|
|
@@ -9063,7 +9236,7 @@ function resolveKitTarget(root) {
|
|
|
9063
9236
|
}
|
|
9064
9237
|
const sveltePath = probeFirstExisting(root, SVELTE_CONFIG_CANDIDATES);
|
|
9065
9238
|
if (sveltePath) {
|
|
9066
|
-
const name =
|
|
9239
|
+
const name = path39.basename(sveltePath);
|
|
9067
9240
|
if (sveltePath.endsWith(".cjs")) {
|
|
9068
9241
|
throw new AdapterError(`${name} is CommonJS, which vela does not edit.`);
|
|
9069
9242
|
}
|
|
@@ -9083,7 +9256,7 @@ function resolveKitTarget(root) {
|
|
|
9083
9256
|
};
|
|
9084
9257
|
}
|
|
9085
9258
|
if (vite?.sveltekitCall) {
|
|
9086
|
-
const name =
|
|
9259
|
+
const name = path39.basename(vite.filePath);
|
|
9087
9260
|
if (vite.nonObjectArg) {
|
|
9088
9261
|
throw new AdapterError(`${name} passes sveltekit() something other than an object literal.`);
|
|
9089
9262
|
}
|
|
@@ -9136,7 +9309,7 @@ function inspectAdapter(target) {
|
|
|
9136
9309
|
async function ensureNodeAdapter(root, { install = true } = {}) {
|
|
9137
9310
|
const target = resolveKitTarget(root);
|
|
9138
9311
|
const { info, importDecl } = inspectAdapter(target);
|
|
9139
|
-
const name =
|
|
9312
|
+
const name = path39.basename(target.filePath);
|
|
9140
9313
|
const outcome = {
|
|
9141
9314
|
previous: info.kind,
|
|
9142
9315
|
removedDeps: [],
|
|
@@ -9169,8 +9342,8 @@ vela deploy runs the app as a Node server, which needs ${ADAPTER_NODE}:`
|
|
|
9169
9342
|
break;
|
|
9170
9343
|
}
|
|
9171
9344
|
if (outcome.configFile) saveTarget(target);
|
|
9172
|
-
const pkgPath =
|
|
9173
|
-
if (
|
|
9345
|
+
const pkgPath = path39.join(root, "package.json");
|
|
9346
|
+
if (fs37.existsSync(pkgPath)) {
|
|
9174
9347
|
const pkg = readPackageJson(pkgPath);
|
|
9175
9348
|
const { changed, removed } = adoptNodeAdapter(pkg);
|
|
9176
9349
|
if (changed) {
|
|
@@ -9222,7 +9395,7 @@ function addAdapter(target) {
|
|
|
9222
9395
|
const taken = importOf(target.sourceFile, "adapter") ?? target.sourceFile.getVariableDeclaration("adapter");
|
|
9223
9396
|
if (taken) {
|
|
9224
9397
|
throw new AdapterError(
|
|
9225
|
-
`${
|
|
9398
|
+
`${path39.basename(target.filePath)} already binds the name \`adapter\` to something that is not the SvelteKit adapter.`
|
|
9226
9399
|
);
|
|
9227
9400
|
}
|
|
9228
9401
|
target.sourceFile.addImportDeclaration({
|
|
@@ -9286,13 +9459,13 @@ var OptionsSchema3 = v8.object({
|
|
|
9286
9459
|
});
|
|
9287
9460
|
var deploy = addLockWaitOption(
|
|
9288
9461
|
addTargetOptions(
|
|
9289
|
-
new
|
|
9462
|
+
new Command84("deploy").description("deploy the app").configureHelp(helpConfig),
|
|
9290
9463
|
"production"
|
|
9291
9464
|
)
|
|
9292
9465
|
).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(
|
|
9293
9466
|
new Option2(
|
|
9294
9467
|
"--remote-db",
|
|
9295
|
-
"render the build against the database on the server, over an SSH tunnel \u2014 on by default once the target has been deployed to"
|
|
9468
|
+
"render the build against the database on the server, over an SSH tunnel \u2014 on by default once the target has been deployed to with a backend"
|
|
9296
9469
|
).default(void 0)
|
|
9297
9470
|
).addOption(
|
|
9298
9471
|
new Option2("--no-remote-db", "render the build against a throwaway local database").default(
|
|
@@ -9450,12 +9623,14 @@ ${pc18.dim(String(err))}`
|
|
|
9450
9623
|
if (managed && managed !== existing?.managed) {
|
|
9451
9624
|
p44.log.info(`${pc18.cyan(managed)} goes live within a minute.`);
|
|
9452
9625
|
}
|
|
9626
|
+
const site = await readSite(workspaceRootDir);
|
|
9453
9627
|
if (result?.superuserCreated) {
|
|
9454
|
-
await
|
|
9628
|
+
await seedNewDatabase(
|
|
9455
9629
|
session,
|
|
9456
9630
|
instance,
|
|
9457
9631
|
workspaceRootDir,
|
|
9458
|
-
primaryHost ? result?.url ?? "" : ""
|
|
9632
|
+
primaryHost ? result?.url ?? "" : "",
|
|
9633
|
+
site?.name
|
|
9459
9634
|
);
|
|
9460
9635
|
p44.log.info(
|
|
9461
9636
|
`Created the PocketBase superuser this app authenticates as.
|
|
@@ -9464,9 +9639,10 @@ Its credentials are stored in the environment on the server. To use
|
|
|
9464
9639
|
your own instead, ${pc18.cyan("vela env set POCKETBASE_SUPERUSER_PASSWORD")}
|
|
9465
9640
|
and deploy again.`
|
|
9466
9641
|
);
|
|
9467
|
-
} else if (backend3
|
|
9468
|
-
await
|
|
9642
|
+
} else if (backend3) {
|
|
9643
|
+
await syncAppName(session, instance, site?.name, primaryHost);
|
|
9469
9644
|
}
|
|
9645
|
+
reportSiteUrl(site?.url, primaryUrl, isPreview2);
|
|
9470
9646
|
if (!primaryHost) {
|
|
9471
9647
|
p44.log.warn(
|
|
9472
9648
|
`No domain configured, so nothing is proxied to this app yet.
|
|
@@ -9513,39 +9689,64 @@ ${pc18.cyan(err.snippet)}` : err.message);
|
|
|
9513
9689
|
}
|
|
9514
9690
|
p44.log.warn(`Commit ${changed.join(", ")} so every deploy builds the same way.`);
|
|
9515
9691
|
}
|
|
9516
|
-
async function
|
|
9692
|
+
async function syncAppName(session, instance, appName, domain) {
|
|
9693
|
+
if (!appName && !domain) return;
|
|
9694
|
+
let result;
|
|
9695
|
+
try {
|
|
9696
|
+
result = await syncRemoteMeta(session, instance, { appName });
|
|
9697
|
+
} catch (err) {
|
|
9698
|
+
if (appName) {
|
|
9699
|
+
p44.log.warn(
|
|
9700
|
+
`Could not set this app's name in its PocketBase settings, which its emails use.
|
|
9701
|
+
${pc18.dim(String(err))}`
|
|
9702
|
+
);
|
|
9703
|
+
}
|
|
9704
|
+
return;
|
|
9705
|
+
}
|
|
9706
|
+
if (result.written.length > 0) {
|
|
9707
|
+
p44.log.success(`Named the app ${pc18.cyan(appName ?? "")} in PocketBase, from ${SITE_FILE}`);
|
|
9708
|
+
}
|
|
9517
9709
|
const expected = normalizeOrigin(domain);
|
|
9518
|
-
if (!expected) return;
|
|
9519
|
-
const current = await readRemoteAppURL(session, instance);
|
|
9520
|
-
if (!current || normalizeOrigin(current) === expected) return;
|
|
9710
|
+
if (!expected || !result.appURL || normalizeOrigin(result.appURL) === expected) return;
|
|
9521
9711
|
p44.log.warn(
|
|
9522
|
-
`This app's PocketBase ${pc18.cyan("appURL")} is ${pc18.dim(
|
|
9712
|
+
`This app's PocketBase ${pc18.cyan("appURL")} is ${pc18.dim(result.appURL)}, but it is served on ${pc18.dim(expected)}.
|
|
9523
9713
|
|
|
9524
9714
|
Emails and anything else PocketBase links to will use the former. Update it in
|
|
9525
9715
|
the admin panel if that is not deliberate.`
|
|
9526
9716
|
);
|
|
9527
9717
|
}
|
|
9528
|
-
async function
|
|
9718
|
+
async function seedNewDatabase(session, instance, workspaceRootDir, appURL, appName) {
|
|
9529
9719
|
const local = await readLocalMeta(workspaceRootDir);
|
|
9530
|
-
if (!local) return;
|
|
9531
9720
|
try {
|
|
9532
|
-
const
|
|
9533
|
-
|
|
9534
|
-
|
|
9535
|
-
|
|
9536
|
-
|
|
9537
|
-
|
|
9538
|
-
${pc18.dim(outcome.error ?? "")}`
|
|
9539
|
-
);
|
|
9540
|
-
return;
|
|
9541
|
-
}
|
|
9542
|
-
p44.log.success(`Copied ${copied.join(", ")} from this project's database`);
|
|
9721
|
+
const { written } = await syncRemoteMeta(session, instance, {
|
|
9722
|
+
...copiedMeta(local),
|
|
9723
|
+
appURL,
|
|
9724
|
+
appName
|
|
9725
|
+
});
|
|
9726
|
+
if (written.length > 0) p44.log.success(`Set ${written.join(", ")} in the new database`);
|
|
9543
9727
|
} catch (err) {
|
|
9544
9728
|
p44.log.warn(
|
|
9545
|
-
`Could not
|
|
9546
|
-
Set
|
|
9729
|
+
`Could not set up this app's PocketBase settings.
|
|
9730
|
+
Set its name and sender in the admin panel instead. ${pc18.dim(String(err))}`
|
|
9731
|
+
);
|
|
9732
|
+
}
|
|
9733
|
+
}
|
|
9734
|
+
function reportSiteUrl(url, primaryUrl, isPreview2) {
|
|
9735
|
+
const expected = normalizeOrigin(primaryUrl);
|
|
9736
|
+
if (!url || !expected) return;
|
|
9737
|
+
if (isLocalUrl(url)) {
|
|
9738
|
+
p44.log.warn(
|
|
9739
|
+
`${SITE_FILE} still says the site is at ${pc18.dim(url)}. Canonical links, Open Graph
|
|
9740
|
+
images and feeds are built from it; set ${pc18.cyan("url")} to ${pc18.cyan(expected)} and deploy again.`
|
|
9547
9741
|
);
|
|
9742
|
+
return;
|
|
9548
9743
|
}
|
|
9744
|
+
if (isPreview2 || normalizeOrigin(url) === expected) return;
|
|
9745
|
+
p44.log.warn(
|
|
9746
|
+
`${SITE_FILE} says the site is at ${pc18.dim(url)}, but this deploy serves ${pc18.dim(expected)}.
|
|
9747
|
+
Canonical links, Open Graph images and feeds point at the former. Update ${pc18.cyan("url")}
|
|
9748
|
+
if that is not deliberate.`
|
|
9749
|
+
);
|
|
9549
9750
|
}
|
|
9550
9751
|
async function openDatabaseTunnel(session, instance, state) {
|
|
9551
9752
|
const pbPort = instanceHasBackend(state) ? state?.pbPort : void 0;
|
|
@@ -9558,8 +9759,8 @@ Deploy once without it, then turn it on.`
|
|
|
9558
9759
|
}
|
|
9559
9760
|
const remoteEnv = await readRemoteEnv(session, instance);
|
|
9560
9761
|
const email3 = remoteEnv.POCKETBASE_SUPERUSER_EMAIL;
|
|
9561
|
-
const
|
|
9562
|
-
if (!email3 || !
|
|
9762
|
+
const password12 = remoteEnv.POCKETBASE_SUPERUSER_PASSWORD;
|
|
9763
|
+
if (!email3 || !password12) {
|
|
9563
9764
|
throw new Error(
|
|
9564
9765
|
`--remote-db renders the build as the superuser of ${instance}, and that environment has no credentials for one.
|
|
9565
9766
|
|
|
@@ -9568,7 +9769,7 @@ Set them with \`vela env set POCKETBASE_SUPERUSER_EMAIL\` and \`vela env set POC
|
|
|
9568
9769
|
}
|
|
9569
9770
|
const localPort = await findFreePort("127.0.0.1");
|
|
9570
9771
|
await session.forwardLocalPort(localPort, "127.0.0.1", pbPort);
|
|
9571
|
-
if (!await superuserAuthenticates(localPort, email3,
|
|
9772
|
+
if (!await superuserAuthenticates(localPort, email3, password12)) {
|
|
9572
9773
|
await session.cancelForward(localPort, "127.0.0.1", pbPort);
|
|
9573
9774
|
throw new Error(
|
|
9574
9775
|
`${instance} does not accept the superuser credentials in its own environment.
|
|
@@ -9589,19 +9790,19 @@ or build against a throwaway local database instead:
|
|
|
9589
9790
|
env: {
|
|
9590
9791
|
POCKETBASE_URL: `http://127.0.0.1:${localPort}`,
|
|
9591
9792
|
POCKETBASE_SUPERUSER_EMAIL: email3,
|
|
9592
|
-
POCKETBASE_SUPERUSER_PASSWORD:
|
|
9793
|
+
POCKETBASE_SUPERUSER_PASSWORD: password12
|
|
9593
9794
|
},
|
|
9594
9795
|
close: () => session.cancelForward(localPort, "127.0.0.1", pbPort)
|
|
9595
9796
|
};
|
|
9596
9797
|
}
|
|
9597
|
-
async function superuserAuthenticates(port, identity,
|
|
9798
|
+
async function superuserAuthenticates(port, identity, password12) {
|
|
9598
9799
|
try {
|
|
9599
9800
|
const response = await fetch(
|
|
9600
9801
|
`http://127.0.0.1:${port}/api/collections/_superusers/auth-with-password`,
|
|
9601
9802
|
{
|
|
9602
9803
|
method: "POST",
|
|
9603
9804
|
headers: { "content-type": "application/json" },
|
|
9604
|
-
body: JSON.stringify({ identity, password:
|
|
9805
|
+
body: JSON.stringify({ identity, password: password12 })
|
|
9605
9806
|
}
|
|
9606
9807
|
);
|
|
9607
9808
|
return response.ok;
|
|
@@ -9625,7 +9826,7 @@ async function uploadRelease(session, instance, release, entries) {
|
|
|
9625
9826
|
}
|
|
9626
9827
|
function isDirectory(target) {
|
|
9627
9828
|
try {
|
|
9628
|
-
return
|
|
9829
|
+
return fs38.statSync(target).isDirectory();
|
|
9629
9830
|
} catch {
|
|
9630
9831
|
return false;
|
|
9631
9832
|
}
|
|
@@ -9633,7 +9834,7 @@ function isDirectory(target) {
|
|
|
9633
9834
|
async function reportEmptyEnvironment(session, instance, workspaceRootDir) {
|
|
9634
9835
|
const remote = await readRemoteEnv(session, instance);
|
|
9635
9836
|
if (Object.keys(remote).length > 0) return;
|
|
9636
|
-
if (!
|
|
9837
|
+
if (!fs38.existsSync(path40.join(workspaceRootDir, ".env"))) return;
|
|
9637
9838
|
p44.log.warn(
|
|
9638
9839
|
`This app has no production environment variables yet.
|
|
9639
9840
|
|
|
@@ -9651,12 +9852,12 @@ async function serverTimeOrLocal(session) {
|
|
|
9651
9852
|
}
|
|
9652
9853
|
|
|
9653
9854
|
// src/commands/link.ts
|
|
9654
|
-
import
|
|
9855
|
+
import path41 from "node:path";
|
|
9655
9856
|
import process32 from "node:process";
|
|
9656
|
-
import { Command as
|
|
9857
|
+
import { Command as Command85 } from "commander";
|
|
9657
9858
|
import * as p45 from "@clack/prompts";
|
|
9658
9859
|
var CREATE_NEW = "__new__";
|
|
9659
|
-
var link = new
|
|
9860
|
+
var link = new Command85("link").description("link this project to a velastack.dev project").configureHelp(helpConfig).action(() => runCommand(linkProject, "Failed to link the project."));
|
|
9660
9861
|
async function linkProject() {
|
|
9661
9862
|
const { workspaceRootDir } = await getWorkspace();
|
|
9662
9863
|
const existing = readProjectConfig(workspaceRootDir);
|
|
@@ -9714,23 +9915,23 @@ async function promptProjectName(workspaceRootDir) {
|
|
|
9714
9915
|
}
|
|
9715
9916
|
function defaultProjectName2(workspaceRootDir) {
|
|
9716
9917
|
try {
|
|
9717
|
-
const pkg = readPackageJson(
|
|
9918
|
+
const pkg = readPackageJson(path41.join(workspaceRootDir, "package.json"));
|
|
9718
9919
|
const name = pkg.name;
|
|
9719
9920
|
if (typeof name === "string" && name.trim()) return name.trim();
|
|
9720
9921
|
} catch {
|
|
9721
9922
|
}
|
|
9722
|
-
return
|
|
9923
|
+
return path41.basename(workspaceRootDir);
|
|
9723
9924
|
}
|
|
9724
9925
|
|
|
9725
9926
|
// src/commands/env.ts
|
|
9726
|
-
import { Command as
|
|
9927
|
+
import { Command as Command90 } from "commander";
|
|
9727
9928
|
|
|
9728
9929
|
// src/commands/env/list.ts
|
|
9729
|
-
import { Command as
|
|
9930
|
+
import { Command as Command86 } from "commander";
|
|
9730
9931
|
import * as p46 from "@clack/prompts";
|
|
9731
9932
|
import pc19 from "picocolors";
|
|
9732
9933
|
var envList = addTargetOptions(
|
|
9733
|
-
new
|
|
9934
|
+
new Command86("list").description("list environment variable names").configureHelp(helpConfig),
|
|
9734
9935
|
"local"
|
|
9735
9936
|
).action(
|
|
9736
9937
|
(raw) => runCommand(
|
|
@@ -9764,11 +9965,11 @@ function report(keys, where) {
|
|
|
9764
9965
|
|
|
9765
9966
|
// src/commands/env/set.ts
|
|
9766
9967
|
import process33 from "node:process";
|
|
9767
|
-
import { Command as
|
|
9968
|
+
import { Command as Command87 } from "commander";
|
|
9768
9969
|
import * as p47 from "@clack/prompts";
|
|
9769
9970
|
import pc20 from "picocolors";
|
|
9770
9971
|
var envSet = addTargetOptions(
|
|
9771
|
-
new
|
|
9972
|
+
new Command87("set").description("set an environment variable").argument("<key>", "variable name").argument("[value]", "value \u2014 prompted for, without echo, when omitted").configureHelp(helpConfig),
|
|
9772
9973
|
"local"
|
|
9773
9974
|
).action(
|
|
9774
9975
|
(key, value, raw) => runCommand(
|
|
@@ -9811,11 +10012,11 @@ async function promptValue(key) {
|
|
|
9811
10012
|
}
|
|
9812
10013
|
|
|
9813
10014
|
// src/commands/env/unset.ts
|
|
9814
|
-
import { Command as
|
|
10015
|
+
import { Command as Command88 } from "commander";
|
|
9815
10016
|
import * as p48 from "@clack/prompts";
|
|
9816
10017
|
import pc21 from "picocolors";
|
|
9817
10018
|
var envUnset = addTargetOptions(
|
|
9818
|
-
new
|
|
10019
|
+
new Command88("unset").description("remove an environment variable").argument("<key>", "variable name").configureHelp(helpConfig),
|
|
9819
10020
|
"local"
|
|
9820
10021
|
).action(
|
|
9821
10022
|
(key, raw) => runCommand(
|
|
@@ -9850,14 +10051,14 @@ var envUnset = addTargetOptions(
|
|
|
9850
10051
|
);
|
|
9851
10052
|
|
|
9852
10053
|
// src/commands/env/import.ts
|
|
9853
|
-
import
|
|
9854
|
-
import
|
|
10054
|
+
import fs39 from "node:fs";
|
|
10055
|
+
import path42 from "node:path";
|
|
9855
10056
|
import process34 from "node:process";
|
|
9856
|
-
import { Command as
|
|
10057
|
+
import { Command as Command89 } from "commander";
|
|
9857
10058
|
import * as p49 from "@clack/prompts";
|
|
9858
10059
|
import pc22 from "picocolors";
|
|
9859
10060
|
var envImport = addTargetOptions(
|
|
9860
|
-
new
|
|
10061
|
+
new Command89("import").description("merge a dotenv file into the environment").argument("<file>", "dotenv file to read").configureHelp(helpConfig),
|
|
9861
10062
|
"local"
|
|
9862
10063
|
).action(
|
|
9863
10064
|
(file, raw) => runCommand(
|
|
@@ -9897,24 +10098,24 @@ var envImport = addTargetOptions(
|
|
|
9897
10098
|
)
|
|
9898
10099
|
);
|
|
9899
10100
|
function resolve(file) {
|
|
9900
|
-
return
|
|
10101
|
+
return path42.resolve(process34.cwd(), file);
|
|
9901
10102
|
}
|
|
9902
10103
|
function read(resolved, shown) {
|
|
9903
|
-
if (!
|
|
10104
|
+
if (!fs39.existsSync(resolved)) throw new Error(`${shown} does not exist.`);
|
|
9904
10105
|
const incoming = readLocalEnvFile(resolved);
|
|
9905
10106
|
if (Object.keys(incoming).length === 0) p49.log.info(`${shown} has no variables to import.`);
|
|
9906
10107
|
return incoming;
|
|
9907
10108
|
}
|
|
9908
10109
|
|
|
9909
10110
|
// src/commands/env.ts
|
|
9910
|
-
var env = new
|
|
10111
|
+
var env = new Command90("env").description("manage environment variables, locally or on a target").configureHelp(helpConfig).addCommand(envList).addCommand(envSet).addCommand(envUnset).addCommand(envImport);
|
|
9911
10112
|
|
|
9912
10113
|
// src/commands/status.ts
|
|
9913
|
-
import { Command as
|
|
10114
|
+
import { Command as Command91 } from "commander";
|
|
9914
10115
|
import * as p50 from "@clack/prompts";
|
|
9915
10116
|
import pc23 from "picocolors";
|
|
9916
10117
|
var status = addTargetOptions(
|
|
9917
|
-
new
|
|
10118
|
+
new Command91("status").description("show what is deployed").configureHelp(helpConfig),
|
|
9918
10119
|
"production"
|
|
9919
10120
|
).option("--all", "show every app on the server, not just this project").option("--json", "print raw JSON").action(
|
|
9920
10121
|
(raw) => runCommand(async () => {
|
|
@@ -9973,12 +10174,12 @@ function describe2(state) {
|
|
|
9973
10174
|
}
|
|
9974
10175
|
|
|
9975
10176
|
// src/commands/rollback.ts
|
|
9976
|
-
import { Command as
|
|
10177
|
+
import { Command as Command92 } from "commander";
|
|
9977
10178
|
import * as p51 from "@clack/prompts";
|
|
9978
10179
|
import pc24 from "picocolors";
|
|
9979
10180
|
var rollback = addLockWaitOption(
|
|
9980
10181
|
addTargetOptions(
|
|
9981
|
-
new
|
|
10182
|
+
new Command92("rollback").description("put the previous release back").configureHelp(helpConfig),
|
|
9982
10183
|
"production"
|
|
9983
10184
|
)
|
|
9984
10185
|
).option("--to <release>", "roll back to a specific release instead of the previous one").action(
|
|
@@ -10017,9 +10218,9 @@ var rollback = addLockWaitOption(
|
|
|
10017
10218
|
);
|
|
10018
10219
|
|
|
10019
10220
|
// src/commands/logs.ts
|
|
10020
|
-
import { Command as
|
|
10221
|
+
import { Command as Command93 } from "commander";
|
|
10021
10222
|
var logs = addTargetOptions(
|
|
10022
|
-
new
|
|
10223
|
+
new Command93("logs").description("tail the logs of a deployed app").configureHelp(helpConfig),
|
|
10023
10224
|
"production"
|
|
10024
10225
|
).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(
|
|
10025
10226
|
(raw) => runCommand(async () => {
|
|
@@ -10053,16 +10254,16 @@ var logs = addTargetOptions(
|
|
|
10053
10254
|
);
|
|
10054
10255
|
|
|
10055
10256
|
// src/commands/admin.ts
|
|
10056
|
-
import { Command as
|
|
10257
|
+
import { Command as Command95 } from "commander";
|
|
10057
10258
|
|
|
10058
10259
|
// src/commands/admin/create.ts
|
|
10059
10260
|
import process35 from "node:process";
|
|
10060
|
-
import { Command as
|
|
10261
|
+
import { Command as Command94 } from "commander";
|
|
10061
10262
|
import * as p52 from "@clack/prompts";
|
|
10062
10263
|
import pc25 from "picocolors";
|
|
10063
10264
|
var MIN_PASSWORD = 10;
|
|
10064
10265
|
var adminCreate = addTargetOptions(
|
|
10065
|
-
new
|
|
10266
|
+
new Command94("create").description("create a login for the admin panel").argument("[email]", "email to sign in with \u2014 prompted for when omitted").configureHelp(helpConfig),
|
|
10066
10267
|
"local"
|
|
10067
10268
|
).action(
|
|
10068
10269
|
(email3, raw) => runCommand(
|
|
@@ -10072,12 +10273,12 @@ var adminCreate = addTargetOptions(
|
|
|
10072
10273
|
local: async (ctx) => {
|
|
10073
10274
|
const creds = readLocalEnv(ctx.envFile);
|
|
10074
10275
|
const address = email3 ?? await promptEmail();
|
|
10075
|
-
const
|
|
10276
|
+
const password12 = await promptPassword2();
|
|
10076
10277
|
let signIn = "";
|
|
10077
10278
|
await withPocketbase(
|
|
10078
10279
|
ctx.workspaceRootDir,
|
|
10079
10280
|
async (pb) => {
|
|
10080
|
-
await upsertSuperuser(pb, address,
|
|
10281
|
+
await upsertSuperuser(pb, address, password12);
|
|
10081
10282
|
const settings = await pb.settings.getAll();
|
|
10082
10283
|
signIn = settings.meta?.appURL ?? "";
|
|
10083
10284
|
},
|
|
@@ -10096,12 +10297,12 @@ var adminCreate = addTargetOptions(
|
|
|
10096
10297
|
},
|
|
10097
10298
|
remote: async (ctx) => {
|
|
10098
10299
|
const address = email3 ?? await promptEmail();
|
|
10099
|
-
const
|
|
10300
|
+
const password12 = await promptPassword2();
|
|
10100
10301
|
const [state] = await readInstanceStates(ctx.session, ctx.instance);
|
|
10101
10302
|
await withRemotePocketbase(
|
|
10102
10303
|
ctx.session,
|
|
10103
10304
|
ctx.instance,
|
|
10104
|
-
(pb) => upsertSuperuser(pb, address,
|
|
10305
|
+
(pb) => upsertSuperuser(pb, address, password12)
|
|
10105
10306
|
);
|
|
10106
10307
|
const base2 = state?.domain ? `https://${state.domain.split(",")[0].trim()}` : "";
|
|
10107
10308
|
p52.log.info(
|
|
@@ -10114,7 +10315,7 @@ var adminCreate = addTargetOptions(
|
|
|
10114
10315
|
"Failed to create the admin login."
|
|
10115
10316
|
)
|
|
10116
10317
|
);
|
|
10117
|
-
async function upsertSuperuser(pb, email3,
|
|
10318
|
+
async function upsertSuperuser(pb, email3, password12) {
|
|
10118
10319
|
const existing = await findSuperuser(pb, email3);
|
|
10119
10320
|
if (existing) {
|
|
10120
10321
|
const confirmed = await p52.confirm({
|
|
@@ -10125,11 +10326,11 @@ async function upsertSuperuser(pb, email3, password11) {
|
|
|
10125
10326
|
p52.cancel("Operation cancelled.");
|
|
10126
10327
|
process35.exit(0);
|
|
10127
10328
|
}
|
|
10128
|
-
await pb.collection("_superusers").update(existing, { password:
|
|
10329
|
+
await pb.collection("_superusers").update(existing, { password: password12, passwordConfirm: password12 });
|
|
10129
10330
|
p52.log.success(`Password updated for ${pc25.cyan(email3)}, you can sign in now`);
|
|
10130
10331
|
return;
|
|
10131
10332
|
}
|
|
10132
|
-
await pb.collection("_superusers").create({ email: email3, password:
|
|
10333
|
+
await pb.collection("_superusers").create({ email: email3, password: password12, passwordConfirm: password12 });
|
|
10133
10334
|
p52.log.success(`${pc25.cyan(email3)} can now sign in`);
|
|
10134
10335
|
}
|
|
10135
10336
|
async function findSuperuser(pb, email3) {
|
|
@@ -10172,15 +10373,15 @@ async function promptPassword2() {
|
|
|
10172
10373
|
}
|
|
10173
10374
|
|
|
10174
10375
|
// src/commands/admin.ts
|
|
10175
|
-
var admin = new
|
|
10376
|
+
var admin = new Command95("admin").description("manage admin panel logins").configureHelp(helpConfig).addCommand(adminCreate);
|
|
10176
10377
|
|
|
10177
10378
|
// src/commands/backup.ts
|
|
10178
|
-
import { Command as
|
|
10379
|
+
import { Command as Command101 } from "commander";
|
|
10179
10380
|
|
|
10180
10381
|
// src/commands/backup/create.ts
|
|
10181
|
-
import
|
|
10182
|
-
import
|
|
10183
|
-
import { Command as
|
|
10382
|
+
import fs40 from "node:fs";
|
|
10383
|
+
import path43 from "node:path";
|
|
10384
|
+
import { Command as Command96 } from "commander";
|
|
10184
10385
|
import * as p53 from "@clack/prompts";
|
|
10185
10386
|
import pc26 from "picocolors";
|
|
10186
10387
|
|
|
@@ -10269,7 +10470,7 @@ async function writeSchedule(pb, cron, maxKeep) {
|
|
|
10269
10470
|
// src/commands/backup/create.ts
|
|
10270
10471
|
var DEFAULT_BACKUP_DIR = "backups";
|
|
10271
10472
|
var backupCreate = addTargetOptions(
|
|
10272
|
-
new
|
|
10473
|
+
new Command96("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),
|
|
10273
10474
|
"production"
|
|
10274
10475
|
).action(
|
|
10275
10476
|
(name, raw) => runCommand(() => {
|
|
@@ -10333,12 +10534,12 @@ Your bucket's own versioning is what protects the uploaded files.`
|
|
|
10333
10534
|
}, "Failed to create the backup.")
|
|
10334
10535
|
);
|
|
10335
10536
|
async function download(ctx, key, outputDir) {
|
|
10336
|
-
const dir =
|
|
10337
|
-
|
|
10338
|
-
const destination =
|
|
10537
|
+
const dir = path43.resolve(ctx.workspaceRootDir, outputDir);
|
|
10538
|
+
fs40.mkdirSync(dir, { recursive: true });
|
|
10539
|
+
const destination = path43.join(dir, key);
|
|
10339
10540
|
if (!ctx.session) {
|
|
10340
|
-
|
|
10341
|
-
return
|
|
10541
|
+
fs40.copyFileSync(path43.join(ctx.workspaceRootDir, "data", "backups", key), destination);
|
|
10542
|
+
return path43.relative(ctx.workspaceRootDir, destination);
|
|
10342
10543
|
}
|
|
10343
10544
|
const spinner8 = p53.spinner();
|
|
10344
10545
|
spinner8.start(`Downloading ${key}`);
|
|
@@ -10349,15 +10550,15 @@ async function download(ctx, key, outputDir) {
|
|
|
10349
10550
|
throw error;
|
|
10350
10551
|
}
|
|
10351
10552
|
spinner8.stop(`Downloaded ${key}`);
|
|
10352
|
-
return
|
|
10553
|
+
return path43.relative(ctx.workspaceRootDir, destination);
|
|
10353
10554
|
}
|
|
10354
10555
|
|
|
10355
10556
|
// src/commands/backup/list.ts
|
|
10356
|
-
import { Command as
|
|
10557
|
+
import { Command as Command97 } from "commander";
|
|
10357
10558
|
import * as p54 from "@clack/prompts";
|
|
10358
10559
|
import pc27 from "picocolors";
|
|
10359
10560
|
var backupList = addTargetOptions(
|
|
10360
|
-
new
|
|
10561
|
+
new Command97("list").description("list the backups on a target").configureHelp(helpConfig),
|
|
10361
10562
|
"production"
|
|
10362
10563
|
).action(
|
|
10363
10564
|
(raw) => runCommand(
|
|
@@ -10383,13 +10584,13 @@ Take one with ${pc27.cyan("vela backup create")}.`
|
|
|
10383
10584
|
);
|
|
10384
10585
|
|
|
10385
10586
|
// src/commands/backup/download.ts
|
|
10386
|
-
import
|
|
10387
|
-
import
|
|
10388
|
-
import { Command as
|
|
10587
|
+
import fs41 from "node:fs";
|
|
10588
|
+
import path44 from "node:path";
|
|
10589
|
+
import { Command as Command98 } from "commander";
|
|
10389
10590
|
import * as p55 from "@clack/prompts";
|
|
10390
10591
|
import pc28 from "picocolors";
|
|
10391
10592
|
var backupDownload = addTargetOptions(
|
|
10392
|
-
new
|
|
10593
|
+
new Command98("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),
|
|
10393
10594
|
"production"
|
|
10394
10595
|
).action(
|
|
10395
10596
|
(key, raw) => runCommand(() => {
|
|
@@ -10411,11 +10612,11 @@ Run ${pc28.cyan("vela backup list")} to see what it does have.`
|
|
|
10411
10612
|
Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
|
|
10412
10613
|
);
|
|
10413
10614
|
}
|
|
10414
|
-
const dir =
|
|
10415
|
-
|
|
10416
|
-
const destination =
|
|
10615
|
+
const dir = path44.resolve(ctx.workspaceRootDir, options.output);
|
|
10616
|
+
fs41.mkdirSync(dir, { recursive: true });
|
|
10617
|
+
const destination = path44.join(dir, key);
|
|
10417
10618
|
if (!ctx.session) {
|
|
10418
|
-
|
|
10619
|
+
fs41.copyFileSync(path44.join(ctx.workspaceRootDir, "data", "backups", key), destination);
|
|
10419
10620
|
} else {
|
|
10420
10621
|
const spinner8 = p55.spinner();
|
|
10421
10622
|
spinner8.start(`Downloading ${key} (${formatBytes(found.size)})`);
|
|
@@ -10429,7 +10630,7 @@ Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
|
|
|
10429
10630
|
}
|
|
10430
10631
|
reportResult({
|
|
10431
10632
|
summary: `Saved ${key} from ${ctx.targetName}.`,
|
|
10432
|
-
filesCreated: [
|
|
10633
|
+
filesCreated: [path44.relative(ctx.workspaceRootDir, destination)]
|
|
10433
10634
|
});
|
|
10434
10635
|
});
|
|
10435
10636
|
}, "Failed to download the backup.")
|
|
@@ -10437,11 +10638,11 @@ Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
|
|
|
10437
10638
|
|
|
10438
10639
|
// src/commands/backup/delete.ts
|
|
10439
10640
|
import process36 from "node:process";
|
|
10440
|
-
import { Command as
|
|
10641
|
+
import { Command as Command99 } from "commander";
|
|
10441
10642
|
import * as p56 from "@clack/prompts";
|
|
10442
10643
|
import pc29 from "picocolors";
|
|
10443
10644
|
var backupDelete = addTargetOptions(
|
|
10444
|
-
new
|
|
10645
|
+
new Command99("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),
|
|
10445
10646
|
"production"
|
|
10446
10647
|
).action(
|
|
10447
10648
|
(key, raw) => runCommand(() => {
|
|
@@ -10472,12 +10673,12 @@ Run ${pc29.cyan("vela backup list")} to see what it does have.`
|
|
|
10472
10673
|
);
|
|
10473
10674
|
|
|
10474
10675
|
// src/commands/backup/schedule.ts
|
|
10475
|
-
import { Command as
|
|
10676
|
+
import { Command as Command100 } from "commander";
|
|
10476
10677
|
import * as p57 from "@clack/prompts";
|
|
10477
10678
|
import pc30 from "picocolors";
|
|
10478
10679
|
var DEFAULT_KEEP = 7;
|
|
10479
10680
|
var backupSchedule = addTargetOptions(
|
|
10480
|
-
new
|
|
10681
|
+
new Command100("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),
|
|
10481
10682
|
"production"
|
|
10482
10683
|
).action(
|
|
10483
10684
|
(cron, raw) => runCommand(() => {
|
|
@@ -10521,18 +10722,18 @@ Set one with ${pc30.cyan('vela backup schedule "0 3 * * *"')}.`
|
|
|
10521
10722
|
);
|
|
10522
10723
|
|
|
10523
10724
|
// src/commands/backup.ts
|
|
10524
|
-
var backup = new
|
|
10725
|
+
var backup = new Command101("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);
|
|
10525
10726
|
|
|
10526
10727
|
// src/commands/restore.ts
|
|
10527
|
-
import
|
|
10528
|
-
import
|
|
10728
|
+
import fs42 from "node:fs";
|
|
10729
|
+
import path45 from "node:path";
|
|
10529
10730
|
import process37 from "node:process";
|
|
10530
|
-
import { Command as
|
|
10731
|
+
import { Command as Command102 } from "commander";
|
|
10531
10732
|
import * as p58 from "@clack/prompts";
|
|
10532
10733
|
import pc31 from "picocolors";
|
|
10533
10734
|
var restore = addLockWaitOption(
|
|
10534
10735
|
addTargetOptions(
|
|
10535
|
-
new
|
|
10736
|
+
new Command102("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),
|
|
10536
10737
|
"production"
|
|
10537
10738
|
)
|
|
10538
10739
|
).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(
|
|
@@ -10548,7 +10749,7 @@ var restore = addLockWaitOption(
|
|
|
10548
10749
|
`${ctx.targetName} was deployed without a database, so there is nothing to restore.`
|
|
10549
10750
|
);
|
|
10550
10751
|
}
|
|
10551
|
-
const local = source &&
|
|
10752
|
+
const local = source && fs42.existsSync(source) ? source : void 0;
|
|
10552
10753
|
const key = local ? void 0 : await resolveKey(ctx, source);
|
|
10553
10754
|
if (!options.yes) {
|
|
10554
10755
|
await confirm13(ctx.appName, ctx.targetName, ctx.envTag, local ?? key);
|
|
@@ -10571,7 +10772,7 @@ var restore = addLockWaitOption(
|
|
|
10571
10772
|
});
|
|
10572
10773
|
p58.log.success(
|
|
10573
10774
|
`Restored ${pc31.cyan(`${ctx.appName} (${ctx.targetName})`)} from ${pc31.cyan(
|
|
10574
|
-
local ?
|
|
10775
|
+
local ? path45.basename(local) : key
|
|
10575
10776
|
)}.`
|
|
10576
10777
|
);
|
|
10577
10778
|
if (result?.storageCarriedOver) {
|
|
@@ -10637,21 +10838,21 @@ Take one with ${pc31.cyan("vela backup create")}, or pass the path to an archive
|
|
|
10637
10838
|
}
|
|
10638
10839
|
async function stage(ctx, file) {
|
|
10639
10840
|
const dir = remotePaths.restoreStage(ctx.instance);
|
|
10640
|
-
const remote = `${dir}/${
|
|
10841
|
+
const remote = `${dir}/${path45.basename(file)}`;
|
|
10641
10842
|
const spinner8 = p58.spinner();
|
|
10642
|
-
spinner8.start(`Uploading ${
|
|
10843
|
+
spinner8.start(`Uploading ${path45.basename(file)}`);
|
|
10643
10844
|
try {
|
|
10644
10845
|
await ctx.session.script(`mkdir -p "$1"`, { args: [dir] });
|
|
10645
10846
|
await ctx.session.upload([file], dir);
|
|
10646
10847
|
} catch (error) {
|
|
10647
|
-
spinner8.stop(`Could not upload ${
|
|
10848
|
+
spinner8.stop(`Could not upload ${path45.basename(file)}.`);
|
|
10648
10849
|
throw error;
|
|
10649
10850
|
}
|
|
10650
|
-
spinner8.stop(`Uploaded ${
|
|
10851
|
+
spinner8.stop(`Uploaded ${path45.basename(file)}`);
|
|
10651
10852
|
return remote;
|
|
10652
10853
|
}
|
|
10653
10854
|
async function confirm13(appName, targetName, envTag, from) {
|
|
10654
|
-
const what = `${pc31.cyan(`${appName} (${targetName})`)} from ${pc31.cyan(
|
|
10855
|
+
const what = `${pc31.cyan(`${appName} (${targetName})`)} from ${pc31.cyan(path45.basename(from))}`;
|
|
10655
10856
|
if (isProd(envTag)) {
|
|
10656
10857
|
const answer = await p58.text({
|
|
10657
10858
|
message: `This replaces the database and uploads of ${what}. Type the app name to confirm`,
|
|
@@ -10674,7 +10875,7 @@ async function confirm13(appName, targetName, envTag, from) {
|
|
|
10674
10875
|
}
|
|
10675
10876
|
|
|
10676
10877
|
// src/commands/targets.ts
|
|
10677
|
-
import { Command as
|
|
10878
|
+
import { Command as Command103 } from "commander";
|
|
10678
10879
|
import * as p59 from "@clack/prompts";
|
|
10679
10880
|
import pc32 from "picocolors";
|
|
10680
10881
|
import * as v9 from "valibot";
|
|
@@ -10684,7 +10885,7 @@ var OptionsSchema4 = v9.object({
|
|
|
10684
10885
|
offline: v9.optional(v9.boolean())
|
|
10685
10886
|
});
|
|
10686
10887
|
var targets = addSshOptions(
|
|
10687
|
-
new
|
|
10888
|
+
new Command103("targets").description("list the targets this project can deploy to").configureHelp(helpConfig)
|
|
10688
10889
|
).option("--json", "print raw JSON").option("--offline", "skip connecting to servers").action(
|
|
10689
10890
|
(raw) => runCommand(async () => {
|
|
10690
10891
|
const options = parseOptions(OptionsSchema4, raw);
|
|
@@ -10762,34 +10963,34 @@ Release and domain are shown from what this project recorded.`
|
|
|
10762
10963
|
}
|
|
10763
10964
|
|
|
10764
10965
|
// src/commands/test.ts
|
|
10765
|
-
import
|
|
10966
|
+
import path46 from "node:path";
|
|
10766
10967
|
import process38 from "node:process";
|
|
10767
|
-
import { Command as
|
|
10968
|
+
import { Command as Command104 } from "commander";
|
|
10768
10969
|
import PocketBase6 from "pocketbase";
|
|
10769
10970
|
import pc33 from "picocolors";
|
|
10770
10971
|
import { x as x5 } from "tinyexec";
|
|
10771
10972
|
import { detect as detect8 } from "package-manager-detector";
|
|
10772
10973
|
import { resolveCommand as resolveCommand7 } from "package-manager-detector/commands";
|
|
10773
|
-
import
|
|
10774
|
-
var testServer = new
|
|
10974
|
+
import fs43 from "node:fs";
|
|
10975
|
+
var testServer = new Command104("test:server").description("run server tests").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(async (_opts, cmd) => {
|
|
10775
10976
|
const cwd = process38.cwd();
|
|
10776
10977
|
const email3 = `test-${Math.random().toString(36).slice(2)}@example.com`;
|
|
10777
|
-
const
|
|
10778
|
-
const testDataDir =
|
|
10779
|
-
|
|
10978
|
+
const password12 = "password";
|
|
10979
|
+
const testDataDir = path46.join(cwd, "test-data");
|
|
10980
|
+
fs43.rmSync(testDataDir, { recursive: true, force: true });
|
|
10780
10981
|
const { stop, url } = await launchPocketbase(cwd, {
|
|
10781
10982
|
dir: testDataDir,
|
|
10782
|
-
migrationsDir:
|
|
10983
|
+
migrationsDir: path46.join(cwd, MIGRATIONS_DIR),
|
|
10783
10984
|
// The app's PocketBase hooks (slug generation, personal teams, …) are part
|
|
10784
10985
|
// of its behaviour; the suite runs against the same server dev and build
|
|
10785
10986
|
// start, so it loads them from the same place.
|
|
10786
|
-
hooksDir:
|
|
10987
|
+
hooksDir: path46.join(cwd, DATA_DIR, "hooks"),
|
|
10787
10988
|
email: email3,
|
|
10788
|
-
password:
|
|
10989
|
+
password: password12
|
|
10789
10990
|
});
|
|
10790
10991
|
process38.env.POCKETBASE_URL = url;
|
|
10791
10992
|
process38.env.POCKETBASE_SUPERUSER_EMAIL = email3;
|
|
10792
|
-
process38.env.POCKETBASE_SUPERUSER_PASSWORD =
|
|
10993
|
+
process38.env.POCKETBASE_SUPERUSER_PASSWORD = password12;
|
|
10793
10994
|
process38.env.VELA_DATA_DIR = testDataDir;
|
|
10794
10995
|
process38.env.TEST = "true";
|
|
10795
10996
|
console.log(`${pc33.greenBright("\u2713")} Created test database`);
|
|
@@ -10799,7 +11000,7 @@ var testServer = new Command101("test:server").description("run server tests").a
|
|
|
10799
11000
|
if (cleanedUp) return;
|
|
10800
11001
|
cleanedUp = true;
|
|
10801
11002
|
stop();
|
|
10802
|
-
|
|
11003
|
+
fs43.rmSync(testDataDir, { recursive: true, force: true });
|
|
10803
11004
|
};
|
|
10804
11005
|
const cleanup = async () => {
|
|
10805
11006
|
if (cleanedUp) return;
|
|
@@ -10820,7 +11021,7 @@ var testServer = new Command101("test:server").description("run server tests").a
|
|
|
10820
11021
|
});
|
|
10821
11022
|
const pb = new PocketBase6(url);
|
|
10822
11023
|
try {
|
|
10823
|
-
await authWithRetries(pb, email3,
|
|
11024
|
+
await authWithRetries(pb, email3, password12);
|
|
10824
11025
|
} catch (e) {
|
|
10825
11026
|
await fail(`Auth failed: ${e.message}`);
|
|
10826
11027
|
}
|
|
@@ -10900,9 +11101,9 @@ function stubPagesPlugin() {
|
|
|
10900
11101
|
}
|
|
10901
11102
|
|
|
10902
11103
|
// src/commands/routes.ts
|
|
10903
|
-
import
|
|
10904
|
-
import
|
|
10905
|
-
import { Command as
|
|
11104
|
+
import fs44 from "node:fs";
|
|
11105
|
+
import path47 from "node:path";
|
|
11106
|
+
import { Command as Command105 } from "commander";
|
|
10906
11107
|
var HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
10907
11108
|
"GET",
|
|
10908
11109
|
"POST",
|
|
@@ -10913,32 +11114,32 @@ var HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
|
10913
11114
|
"HEAD",
|
|
10914
11115
|
"fallback"
|
|
10915
11116
|
]);
|
|
10916
|
-
var routes = new
|
|
11117
|
+
var routes = new Command105("routes").description("list routes").configureHelp(helpConfig).action(async () => {
|
|
10917
11118
|
const { workspaceRootDir, routesDir } = await getWorkspace();
|
|
10918
|
-
const routesRoot =
|
|
11119
|
+
const routesRoot = path47.join(workspaceRootDir, routesDir);
|
|
10919
11120
|
const found = walk(routesRoot, routesRoot).filter((r) => r.methods.length > 0);
|
|
10920
11121
|
found.sort((a, b) => a.urlPattern.localeCompare(b.urlPattern));
|
|
10921
11122
|
printTable(found);
|
|
10922
11123
|
});
|
|
10923
11124
|
function walk(root, dir) {
|
|
10924
|
-
const entries =
|
|
11125
|
+
const entries = fs44.readdirSync(dir, { withFileTypes: true });
|
|
10925
11126
|
const routes2 = [];
|
|
10926
11127
|
const hasLeaf = entries.some((e) => e.isFile() && isRouteFile(e.name));
|
|
10927
11128
|
if (hasLeaf) {
|
|
10928
|
-
const id = "/" +
|
|
11129
|
+
const id = "/" + path47.relative(root, dir).split(path47.sep).filter(Boolean).join("/");
|
|
10929
11130
|
const urlPattern = id.replace(/\([^)]+\)\/?/g, "").replace(/\/$/, "") || "/";
|
|
10930
11131
|
const methods = /* @__PURE__ */ new Set();
|
|
10931
11132
|
for (const entry of entries) {
|
|
10932
11133
|
if (!entry.isFile()) continue;
|
|
10933
11134
|
if (entry.name.endsWith("+page.svelte")) methods.add("GET");
|
|
10934
11135
|
if (entry.name.endsWith("+server.ts") || entry.name.endsWith("+server.js") || entry.name.endsWith("+page.server.ts") || entry.name.endsWith("+page.server.js")) {
|
|
10935
|
-
extractMethods(
|
|
11136
|
+
extractMethods(path47.join(dir, entry.name)).forEach((m) => methods.add(m));
|
|
10936
11137
|
}
|
|
10937
11138
|
}
|
|
10938
11139
|
routes2.push({ id: id || "/", urlPattern, methods: [...methods] });
|
|
10939
11140
|
}
|
|
10940
11141
|
for (const entry of entries) {
|
|
10941
|
-
if (entry.isDirectory()) routes2.push(...walk(root,
|
|
11142
|
+
if (entry.isDirectory()) routes2.push(...walk(root, path47.join(dir, entry.name)));
|
|
10942
11143
|
}
|
|
10943
11144
|
return routes2;
|
|
10944
11145
|
}
|
|
@@ -10947,7 +11148,7 @@ function isRouteFile(name) {
|
|
|
10947
11148
|
}
|
|
10948
11149
|
function extractMethods(file) {
|
|
10949
11150
|
try {
|
|
10950
|
-
const content =
|
|
11151
|
+
const content = fs44.readFileSync(file, "utf8");
|
|
10951
11152
|
const methods = [];
|
|
10952
11153
|
const exportRegex = /export\s+(?:const|async\s+function|function)\s+(\w+)/g;
|
|
10953
11154
|
let match;
|
|
@@ -10988,13 +11189,19 @@ function printTable(routes2) {
|
|
|
10988
11189
|
}
|
|
10989
11190
|
|
|
10990
11191
|
// src/commands/i18n.ts
|
|
11192
|
+
import fs45 from "node:fs";
|
|
11193
|
+
import path48 from "node:path";
|
|
10991
11194
|
import process39 from "node:process";
|
|
10992
|
-
import { Command as
|
|
11195
|
+
import { Command as Command106 } from "commander";
|
|
10993
11196
|
import { x as x6 } from "tinyexec";
|
|
10994
11197
|
import { detect as detect9 } from "package-manager-detector";
|
|
10995
11198
|
import { resolveCommand as resolveCommand8 } from "package-manager-detector/commands";
|
|
11199
|
+
var WUCHALE_CONFIG_NAMES = ["js", "mjs", "ts", "mts"].map((ext) => `wuchale.config.${ext}`);
|
|
10996
11200
|
async function runWuchale(extraArgs) {
|
|
10997
|
-
const cwd = process39.cwd();
|
|
11201
|
+
const cwd = findWorkspaceRoot() ?? process39.cwd();
|
|
11202
|
+
if (!WUCHALE_CONFIG_NAMES.some((name) => fs45.existsSync(path48.join(cwd, name)))) {
|
|
11203
|
+
throw new Error("No wuchale config found. Run `vela enable i18n` to set up i18n.");
|
|
11204
|
+
}
|
|
10998
11205
|
const pm = (await detect9({ cwd }))?.name ?? "npm";
|
|
10999
11206
|
const resolved = resolveCommand8(pm, "execute", ["wuchale", ...extraArgs]);
|
|
11000
11207
|
const args = resolved.args.slice();
|
|
@@ -11004,11 +11211,11 @@ async function runWuchale(extraArgs) {
|
|
|
11004
11211
|
throwOnError: true
|
|
11005
11212
|
});
|
|
11006
11213
|
}
|
|
11007
|
-
var extract2 = new
|
|
11008
|
-
var watch = new
|
|
11009
|
-
var status2 = new
|
|
11010
|
-
var clean = new
|
|
11011
|
-
var i18n3 = new
|
|
11214
|
+
var extract2 = new Command106("extract").description("extract translatable strings").configureHelp(helpConfig).action(() => runCommand(() => runWuchale([])));
|
|
11215
|
+
var watch = new Command106("watch").description("watch and extract translatable strings").configureHelp(helpConfig).action(() => runCommand(() => runWuchale(["--watch"])));
|
|
11216
|
+
var status2 = new Command106("status").description("show i18n status").configureHelp(helpConfig).action(() => runCommand(() => runWuchale(["status"])));
|
|
11217
|
+
var clean = new Command106("clean").description("clean unused translatable strings").configureHelp(helpConfig).action(() => runCommand(() => runWuchale(["--clean"])));
|
|
11218
|
+
var i18n3 = new Command106("i18n").description("i18n utilities").configureHelp(helpConfig).addCommand(extract2, { isDefault: true }).addCommand(watch).addCommand(status2).addCommand(clean);
|
|
11012
11219
|
|
|
11013
11220
|
// src/commands/oauth.ts
|
|
11014
11221
|
var oauth = stubCommand("oauth", "configure OAuth providers");
|
|
@@ -11017,17 +11224,17 @@ var oauth = stubCommand("oauth", "configure OAuth providers");
|
|
|
11017
11224
|
var schemas = stubCommand("schemas", "manage database schemas");
|
|
11018
11225
|
|
|
11019
11226
|
// src/commands/cms.ts
|
|
11020
|
-
import { Command as
|
|
11227
|
+
import { Command as Command112 } from "commander";
|
|
11021
11228
|
|
|
11022
11229
|
// src/commands/cms/deploy.ts
|
|
11023
11230
|
import process40 from "node:process";
|
|
11024
|
-
import { Command as
|
|
11231
|
+
import { Command as Command107 } from "commander";
|
|
11025
11232
|
import * as p60 from "@clack/prompts";
|
|
11026
11233
|
import pc34 from "picocolors";
|
|
11027
11234
|
var POLL_INTERVAL2 = 5e3;
|
|
11028
11235
|
var POLL_TIMEOUT = 30 * 6e4;
|
|
11029
11236
|
var inFlight = (run) => run?.status === "pending" || run?.status === "building";
|
|
11030
|
-
var deploy2 = new
|
|
11237
|
+
var deploy2 = new Command107("deploy").description("rebuild the hosted site with the latest published content").option(
|
|
11031
11238
|
"--project <id>",
|
|
11032
11239
|
"velastack.dev project whose site to rebuild, instead of the linked one"
|
|
11033
11240
|
).option("--no-wait", "return once the build has started instead of waiting for it").configureHelp(helpConfig).action(
|
|
@@ -11116,17 +11323,17 @@ async function waitForRun(apiKey, projectId, runId) {
|
|
|
11116
11323
|
}
|
|
11117
11324
|
|
|
11118
11325
|
// src/commands/cms/editor.ts
|
|
11119
|
-
import { Command as
|
|
11326
|
+
import { Command as Command111 } from "commander";
|
|
11120
11327
|
|
|
11121
11328
|
// src/commands/cms/editor/add.ts
|
|
11122
11329
|
import { randomBytes } from "node:crypto";
|
|
11123
|
-
import { Command as
|
|
11330
|
+
import { Command as Command108 } from "commander";
|
|
11124
11331
|
import * as p61 from "@clack/prompts";
|
|
11125
11332
|
import pc36 from "picocolors";
|
|
11126
11333
|
|
|
11127
11334
|
// src/lib/cms-backend.ts
|
|
11128
11335
|
import { createRequire as createRequire3 } from "node:module";
|
|
11129
|
-
import
|
|
11336
|
+
import path49 from "node:path";
|
|
11130
11337
|
import process41 from "node:process";
|
|
11131
11338
|
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
11132
11339
|
import pc35 from "picocolors";
|
|
@@ -11134,7 +11341,7 @@ var DEFAULT_PROJECT = "default";
|
|
|
11134
11341
|
async function loadBackendModule(root) {
|
|
11135
11342
|
let entry;
|
|
11136
11343
|
try {
|
|
11137
|
-
entry = createRequire3(
|
|
11344
|
+
entry = createRequire3(path49.join(root, "package.json")).resolve("@velastack/cms/backend");
|
|
11138
11345
|
} catch {
|
|
11139
11346
|
throw new Error(
|
|
11140
11347
|
`@velastack/cms is not installed in this project.
|
|
@@ -11152,8 +11359,8 @@ async function withCmsBackend(fn, cwd = process41.cwd()) {
|
|
|
11152
11359
|
const { createCmsBackend } = await loadBackendModule(root);
|
|
11153
11360
|
const dataDir2 = localDataDir(root);
|
|
11154
11361
|
const backend3 = createCmsBackend({
|
|
11155
|
-
dbPath:
|
|
11156
|
-
uploadDir:
|
|
11362
|
+
dbPath: path49.join(dataDir2, "cms.sqlite"),
|
|
11363
|
+
uploadDir: path49.join(dataDir2, "uploads")
|
|
11157
11364
|
});
|
|
11158
11365
|
try {
|
|
11159
11366
|
return await fn(backend3);
|
|
@@ -11163,16 +11370,16 @@ async function withCmsBackend(fn, cwd = process41.cwd()) {
|
|
|
11163
11370
|
}
|
|
11164
11371
|
|
|
11165
11372
|
// src/commands/cms/editor/add.ts
|
|
11166
|
-
var editorAdd = new
|
|
11373
|
+
var editorAdd = new Command108("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(
|
|
11167
11374
|
(email3, options) => runCommand(async () => {
|
|
11168
11375
|
const generated = options.password === void 0;
|
|
11169
|
-
const
|
|
11376
|
+
const password12 = options.password ?? randomBytes(12).toString("base64url");
|
|
11170
11377
|
const editor2 = await withCmsBackend(
|
|
11171
|
-
(cms3) => cms3.editors.create({ email: email3, password:
|
|
11378
|
+
(cms3) => cms3.editors.create({ email: email3, password: password12, projects: [options.project] })
|
|
11172
11379
|
);
|
|
11173
11380
|
const lines = [`Added ${pc36.cyan(editor2.email)} as an editor of ${pc36.cyan(options.project)}.`];
|
|
11174
11381
|
if (generated) {
|
|
11175
|
-
lines.push("", `Password: ${pc36.bold(
|
|
11382
|
+
lines.push("", `Password: ${pc36.bold(password12)}`, "", "It is shown once; copy it now.");
|
|
11176
11383
|
}
|
|
11177
11384
|
p61.log.success(lines.join("\n"));
|
|
11178
11385
|
p61.log.info(
|
|
@@ -11182,12 +11389,12 @@ var editorAdd = new Command105("add").description("create an editor who can sign
|
|
|
11182
11389
|
);
|
|
11183
11390
|
|
|
11184
11391
|
// src/commands/cms/editor/password.ts
|
|
11185
|
-
import { Command as
|
|
11392
|
+
import { Command as Command109 } from "commander";
|
|
11186
11393
|
import * as p62 from "@clack/prompts";
|
|
11187
11394
|
import pc37 from "picocolors";
|
|
11188
|
-
var editorPassword = new
|
|
11189
|
-
(email3,
|
|
11190
|
-
await withCmsBackend((cms3) => cms3.editors.setPassword(email3,
|
|
11395
|
+
var editorPassword = new Command109("password").description("set an editor's password").argument("<email>", "email of the editor").argument("<password>", "new password").configureHelp(helpConfig).action(
|
|
11396
|
+
(email3, password12) => runCommand(async () => {
|
|
11397
|
+
await withCmsBackend((cms3) => cms3.editors.setPassword(email3, password12));
|
|
11191
11398
|
p62.log.success(
|
|
11192
11399
|
`Updated the password for ${pc37.cyan(email3)}. Existing sessions were signed out.`
|
|
11193
11400
|
);
|
|
@@ -11195,10 +11402,10 @@ var editorPassword = new Command106("password").description("set an editor's pas
|
|
|
11195
11402
|
);
|
|
11196
11403
|
|
|
11197
11404
|
// src/commands/cms/editor/list.ts
|
|
11198
|
-
import { Command as
|
|
11405
|
+
import { Command as Command110 } from "commander";
|
|
11199
11406
|
import * as p63 from "@clack/prompts";
|
|
11200
11407
|
import pc38 from "picocolors";
|
|
11201
|
-
var editorList = new
|
|
11408
|
+
var editorList = new Command110("list").description("list editors and the projects they may edit").configureHelp(helpConfig).action(
|
|
11202
11409
|
() => runCommand(async () => {
|
|
11203
11410
|
const rows = await withCmsBackend(
|
|
11204
11411
|
async (cms3) => cms3.editors.list().map((editor2) => ({
|
|
@@ -11222,17 +11429,17 @@ var editorList = new Command107("list").description("list editors and the projec
|
|
|
11222
11429
|
);
|
|
11223
11430
|
|
|
11224
11431
|
// src/commands/cms/editor.ts
|
|
11225
|
-
var editor = new
|
|
11432
|
+
var editor = new Command111("editor").description("manage who can sign in to the admin bar").configureHelp(helpConfig).addCommand(editorAdd).addCommand(editorPassword).addCommand(editorList);
|
|
11226
11433
|
|
|
11227
11434
|
// src/commands/cms.ts
|
|
11228
|
-
var cms2 = new
|
|
11435
|
+
var cms2 = new Command112("cms").description("manage the CMS").configureHelp(helpConfig).addCommand(editor).addCommand(deploy2);
|
|
11229
11436
|
|
|
11230
11437
|
// src/commands/workflows.ts
|
|
11231
|
-
import { Command as
|
|
11438
|
+
import { Command as Command116 } from "commander";
|
|
11232
11439
|
|
|
11233
11440
|
// src/commands/workflows/list.ts
|
|
11234
11441
|
import process42 from "node:process";
|
|
11235
|
-
import { Command as
|
|
11442
|
+
import { Command as Command113, InvalidArgumentError as InvalidArgumentError5 } from "commander";
|
|
11236
11443
|
import * as p64 from "@clack/prompts";
|
|
11237
11444
|
import pc39 from "picocolors";
|
|
11238
11445
|
|
|
@@ -11307,7 +11514,7 @@ function formatRun(run, nameWidth) {
|
|
|
11307
11514
|
const error = run.status === "failed" && run.error?.message ? pc39.red(` ${run.error.message}`) : "";
|
|
11308
11515
|
return `${run.id} ${run.workflowName.padEnd(nameWidth)} ${status3}${attempts} ${when}${error}`;
|
|
11309
11516
|
}
|
|
11310
|
-
var workflowsList = new
|
|
11517
|
+
var workflowsList = new Command113("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(
|
|
11311
11518
|
(options) => runCommand(async () => {
|
|
11312
11519
|
await withPocketbase(process42.cwd(), async (pb) => {
|
|
11313
11520
|
const runs = await listRuns(pb, {
|
|
@@ -11331,7 +11538,7 @@ Start one from server code with ${pc39.cyan("<workflow>.run(input)")}, or with $
|
|
|
11331
11538
|
|
|
11332
11539
|
// src/commands/workflows/run.ts
|
|
11333
11540
|
import process43 from "node:process";
|
|
11334
|
-
import { Command as
|
|
11541
|
+
import { Command as Command114, InvalidArgumentError as InvalidArgumentError6 } from "commander";
|
|
11335
11542
|
import * as p65 from "@clack/prompts";
|
|
11336
11543
|
import pc40 from "picocolors";
|
|
11337
11544
|
function parseInput(value) {
|
|
@@ -11341,7 +11548,7 @@ function parseInput(value) {
|
|
|
11341
11548
|
throw new InvalidArgumentError6(`must be JSON, e.g. '{"userId":"abc"}'.`);
|
|
11342
11549
|
}
|
|
11343
11550
|
}
|
|
11344
|
-
var workflowsRun = new
|
|
11551
|
+
var workflowsRun = new Command114("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(
|
|
11345
11552
|
(name, input) => runCommand(async () => {
|
|
11346
11553
|
await withPocketbase(process43.cwd(), async (pb) => {
|
|
11347
11554
|
const run = await createRun(pb, name, input);
|
|
@@ -11356,10 +11563,10 @@ It runs once the app is up (${pc40.cyan("vela dev")}); ${pc40.cyan("vela workflo
|
|
|
11356
11563
|
|
|
11357
11564
|
// src/commands/workflows/cancel.ts
|
|
11358
11565
|
import process44 from "node:process";
|
|
11359
|
-
import { Command as
|
|
11566
|
+
import { Command as Command115 } from "commander";
|
|
11360
11567
|
import * as p66 from "@clack/prompts";
|
|
11361
11568
|
import pc41 from "picocolors";
|
|
11362
|
-
var workflowsCancel = new
|
|
11569
|
+
var workflowsCancel = new Command115("cancel").description("cancel a pending or running workflow run").argument("<run-id>", "the run id from `vela workflows list`").configureHelp(helpConfig).action(
|
|
11363
11570
|
(id) => runCommand(async () => {
|
|
11364
11571
|
await withPocketbase(process44.cwd(), async (pb) => {
|
|
11365
11572
|
const run = await cancelRun(pb, id);
|
|
@@ -11369,7 +11576,7 @@ var workflowsCancel = new Command112("cancel").description("cancel a pending or
|
|
|
11369
11576
|
);
|
|
11370
11577
|
|
|
11371
11578
|
// src/commands/workflows.ts
|
|
11372
|
-
var workflows2 = new
|
|
11579
|
+
var workflows2 = new Command116("workflows").description("list, start and cancel background workflow runs").configureHelp(helpConfig).addCommand(workflowsList).addCommand(workflowsRun).addCommand(workflowsCancel);
|
|
11373
11580
|
|
|
11374
11581
|
// src/program.ts
|
|
11375
11582
|
var NO_BACKEND_COMMMANDS = /* @__PURE__ */ new Set([
|
|
@@ -11385,10 +11592,30 @@ var NO_BACKEND_COMMMANDS = /* @__PURE__ */ new Set([
|
|
|
11385
11592
|
"i18n",
|
|
11386
11593
|
"generate schema",
|
|
11387
11594
|
"generate form",
|
|
11595
|
+
// Only delete the files their generators wrote, so they must work wherever
|
|
11596
|
+
// those generators do.
|
|
11597
|
+
"destroy schema",
|
|
11598
|
+
"destroy form",
|
|
11388
11599
|
// The CMS keeps its own SQLite database and editors; PocketBase is never involved.
|
|
11389
11600
|
"enable cms",
|
|
11601
|
+
// Adds PocketBase to a project that has none, so it can never require one.
|
|
11602
|
+
"enable backend",
|
|
11390
11603
|
// Analytics only touches the root layout and .env; it must work on static sites.
|
|
11391
11604
|
"enable analytics",
|
|
11605
|
+
// The model is called from a SvelteKit endpoint; PocketBase is only read for
|
|
11606
|
+
// the signed-in check when auth is on.
|
|
11607
|
+
"enable ai",
|
|
11608
|
+
// Both only delete files and strip .env, so they run wherever enabling did.
|
|
11609
|
+
"disable ai",
|
|
11610
|
+
"disable analytics",
|
|
11611
|
+
// Only wires hooks, reroute and the root layout; no collections involved.
|
|
11612
|
+
"enable content-negotiation",
|
|
11613
|
+
"disable content-negotiation",
|
|
11614
|
+
// Posts are mdsvex files on disk.
|
|
11615
|
+
"enable blog",
|
|
11616
|
+
// Translations live in wuchale catalogs.
|
|
11617
|
+
"enable i18n",
|
|
11618
|
+
"disable i18n",
|
|
11392
11619
|
"cms",
|
|
11393
11620
|
// Server commands talk to a VPS over SSH, never to the local database.
|
|
11394
11621
|
"provision",
|
|
@@ -11403,25 +11630,25 @@ var NO_BACKEND_COMMMANDS = /* @__PURE__ */ new Set([
|
|
|
11403
11630
|
// own credentials rather than requiring them in this process.
|
|
11404
11631
|
"backup",
|
|
11405
11632
|
"restore",
|
|
11406
|
-
// Removes a copy from its server
|
|
11407
|
-
//
|
|
11633
|
+
// Removes a copy from its server. `destroy resource` and `destroy scaffold`
|
|
11634
|
+
// drop collections and stay gated.
|
|
11408
11635
|
"destroy deployment"
|
|
11409
11636
|
]);
|
|
11410
11637
|
var BACKEND_OPTIONAL_COMMANDS = /* @__PURE__ */ new Set(["dev", "build", "preview", "deploy"]);
|
|
11411
11638
|
var SELF_CREDENTIALED_COMMANDS = /* @__PURE__ */ new Set(["test:server"]);
|
|
11412
|
-
var program = new
|
|
11639
|
+
var program = new Command117().name(package_default.name).description(package_default.description).version(package_default.version, "-v, --version").configureHelp(helpConfig);
|
|
11413
11640
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
11414
11641
|
if (isStub(actionCommand)) return;
|
|
11415
11642
|
const envRoot = findWorkspaceRoot() ?? process45.cwd();
|
|
11416
11643
|
dotenv2.config({ path: nodePath.join(envRoot, ".env"), quiet: true });
|
|
11417
|
-
const
|
|
11418
|
-
if (NO_BACKEND_COMMMANDS.has(
|
|
11419
|
-
const top =
|
|
11644
|
+
const path50 = getCommandPath(actionCommand);
|
|
11645
|
+
if (NO_BACKEND_COMMMANDS.has(path50)) return;
|
|
11646
|
+
const top = path50.split(" ", 1)[0];
|
|
11420
11647
|
if (NO_BACKEND_COMMMANDS.has(top)) return;
|
|
11421
11648
|
if (!hasBackend()) {
|
|
11422
11649
|
if (BACKEND_OPTIONAL_COMMANDS.has(top)) return;
|
|
11423
11650
|
p67.log.error(
|
|
11424
|
-
`${pc42.cyan(`vela ${
|
|
11651
|
+
`${pc42.cyan(`vela ${path50}`)} needs a backend, and this project does not have one.
|
|
11425
11652
|
|
|
11426
11653
|
Static projects have no database to talk to.
|
|
11427
11654
|
|
|
@@ -11431,7 +11658,7 @@ To add a backend to this project, run ${pc42.cyan("vela bless")}.`
|
|
|
11431
11658
|
p67.cancel("Operation failed.");
|
|
11432
11659
|
process45.exit(1);
|
|
11433
11660
|
}
|
|
11434
|
-
if (SELF_CREDENTIALED_COMMANDS.has(
|
|
11661
|
+
if (SELF_CREDENTIALED_COMMANDS.has(path50)) return;
|
|
11435
11662
|
if (!process45.env.POCKETBASE_SUPERUSER_EMAIL || !process45.env.POCKETBASE_SUPERUSER_PASSWORD) {
|
|
11436
11663
|
p67.log.error(
|
|
11437
11664
|
`PocketBase superuser credentials are required.
|