vela 0.21.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +742 -583
- package/dist/bin.js.map +4 -4
- package/package.json +4 -3
package/dist/bin.js
CHANGED
|
@@ -12,7 +12,7 @@ function normalizeArgv(argv) {
|
|
|
12
12
|
|
|
13
13
|
// src/program.ts
|
|
14
14
|
import process54 from "node:process";
|
|
15
|
-
import * as
|
|
15
|
+
import * as p75 from "@clack/prompts";
|
|
16
16
|
import { Command as Command122 } from "commander";
|
|
17
17
|
import nodePath from "node:path";
|
|
18
18
|
import dotenv2 from "dotenv";
|
|
@@ -20,7 +20,7 @@ import dotenv2 from "dotenv";
|
|
|
20
20
|
// package.json
|
|
21
21
|
var package_default = {
|
|
22
22
|
name: "vela",
|
|
23
|
-
version: "0.
|
|
23
|
+
version: "0.22.0",
|
|
24
24
|
type: "module",
|
|
25
25
|
description: "A CLI for creating and updating SvelteKit projects",
|
|
26
26
|
license: "MIT",
|
|
@@ -57,7 +57,7 @@ var package_default = {
|
|
|
57
57
|
dependencies: {
|
|
58
58
|
"@clack/prompts": "^1.7.0",
|
|
59
59
|
"@faker-js/faker": "^10.6.0",
|
|
60
|
-
"@velastack/patterns": "^0.10.
|
|
60
|
+
"@velastack/patterns": "^0.10.1",
|
|
61
61
|
"@velastack/pocketbase-codegen": "^0.1.0",
|
|
62
62
|
"@velastack/schema": "^0.3.0",
|
|
63
63
|
"@velastack/schema-ui": "^0.3.1",
|
|
@@ -65,6 +65,7 @@ var package_default = {
|
|
|
65
65
|
commander: "^15.0.0",
|
|
66
66
|
"cross-spawn": "^7.0.6",
|
|
67
67
|
dedent: "^1.7.2",
|
|
68
|
+
devalue: "^5.9.4",
|
|
68
69
|
dotenv: "^18.0.1",
|
|
69
70
|
"fetch-cookie": "^3.2.0",
|
|
70
71
|
"json-schema-faker": "^0.6.3",
|
|
@@ -73,7 +74,7 @@ var package_default = {
|
|
|
73
74
|
picocolors: "^1.1.1",
|
|
74
75
|
pocketbase: "^0.28.0",
|
|
75
76
|
"pocketbase-server": "^0.40.6-beta.5",
|
|
76
|
-
stripe: "^
|
|
77
|
+
stripe: "^23.0.1",
|
|
77
78
|
sv: "~1.1.1",
|
|
78
79
|
svelte: "^5.56.10",
|
|
79
80
|
tar: "^7.5.22",
|
|
@@ -419,9 +420,9 @@ function minOfComparatorSet(set) {
|
|
|
419
420
|
if (upperOnly) return { major: 0, minor: 0, patch: 0, prerelease: [] };
|
|
420
421
|
return floor;
|
|
421
422
|
}
|
|
422
|
-
function parseVersionPart(
|
|
423
|
-
if (
|
|
424
|
-
const match =
|
|
423
|
+
function parseVersionPart(text20) {
|
|
424
|
+
if (text20 === "" || text20 === "*" || text20 === "x" || text20 === "X") return null;
|
|
425
|
+
const match = text20.match(VERSION_PART);
|
|
425
426
|
if (!match) return null;
|
|
426
427
|
const nums = [match[1], match[2], match[3]];
|
|
427
428
|
const firstWild = nums.findIndex((n) => n === void 0 || /^[xX*]$/.test(n));
|
|
@@ -917,10 +918,10 @@ function writeCachedIndex(cached2) {
|
|
|
917
918
|
fs6.mkdirSync(cacheRoot(), { recursive: true });
|
|
918
919
|
fs6.writeFileSync(indexCachePath(), JSON.stringify(cached2, null, 2));
|
|
919
920
|
}
|
|
920
|
-
function parseTemplateIndex(
|
|
921
|
+
function parseTemplateIndex(text20, url) {
|
|
921
922
|
let parsed;
|
|
922
923
|
try {
|
|
923
|
-
parsed = JSON.parse(
|
|
924
|
+
parsed = JSON.parse(text20);
|
|
924
925
|
} catch (e) {
|
|
925
926
|
throw new Error(`Template index at ${url} is not valid JSON: ${e.message}`);
|
|
926
927
|
}
|
|
@@ -1870,8 +1871,8 @@ async function readSite(root) {
|
|
|
1870
1871
|
if (!property || !Node6.isPropertyAssignment(property)) continue;
|
|
1871
1872
|
const value = property.getInitializer();
|
|
1872
1873
|
if (Node6.isStringLiteral(value) || Node6.isNoSubstitutionTemplateLiteral(value)) {
|
|
1873
|
-
const
|
|
1874
|
-
if (
|
|
1874
|
+
const text20 = value.getLiteralValue().trim();
|
|
1875
|
+
if (text20) info[key] = text20;
|
|
1875
1876
|
}
|
|
1876
1877
|
}
|
|
1877
1878
|
return info;
|
|
@@ -2143,8 +2144,8 @@ function mergeOriginConfig(root, options = {}) {
|
|
|
2143
2144
|
const sources = findPrerenderOrigins(arg);
|
|
2144
2145
|
const pathsProp = arg.getProperty("paths");
|
|
2145
2146
|
const paths = pathsProp && Node.isPropertyAssignment(pathsProp) ? pathsProp.getInitializerIfKind(SyntaxKind2.ObjectLiteralExpression) : void 0;
|
|
2146
|
-
const hasPathsOrigin = paths !== void 0 && hasOrigin(paths) || arg.getProperties().some((
|
|
2147
|
-
const spread = conditionalSpreadOf(
|
|
2147
|
+
const hasPathsOrigin = paths !== void 0 && hasOrigin(paths) || arg.getProperties().some((p76) => {
|
|
2148
|
+
const spread = conditionalSpreadOf(p76, "paths");
|
|
2148
2149
|
return spread !== void 0 && hasOrigin(spread.object);
|
|
2149
2150
|
});
|
|
2150
2151
|
if (sources === "unsupported") {
|
|
@@ -2206,15 +2207,15 @@ function mergeOriginConfig(root, options = {}) {
|
|
|
2206
2207
|
}
|
|
2207
2208
|
}
|
|
2208
2209
|
if (staleComment && !hasPathsOrigin && !paths) {
|
|
2209
|
-
const target = arg.getProperties().find((
|
|
2210
|
+
const target = arg.getProperties().find((p76) => isOriginElement(p76));
|
|
2210
2211
|
if (target) setOriginComment(target);
|
|
2211
2212
|
}
|
|
2212
2213
|
if (orphaned.length > 0) {
|
|
2213
|
-
let
|
|
2214
|
+
let text20 = vite.sourceFile.getFullText();
|
|
2214
2215
|
for (const comment of orphaned) {
|
|
2215
|
-
|
|
2216
|
+
text20 = text20.replace(new RegExp(String.raw`\n[\t ]*${escapeRegExp2(comment)}[\t ]*(?=\n)`), "");
|
|
2216
2217
|
}
|
|
2217
|
-
vite.sourceFile.replaceWithText(
|
|
2218
|
+
vite.sourceFile.replaceWithText(text20);
|
|
2218
2219
|
}
|
|
2219
2220
|
vite.sourceFile.saveSync();
|
|
2220
2221
|
const moved = hasPathsOrigin ? "removed prerender.origin, which SvelteKit 3 no longer accepts; kept the existing paths.origin" : "moved prerender.origin to paths.origin";
|
|
@@ -2227,12 +2228,12 @@ function mergeOriginConfig(root, options = {}) {
|
|
|
2227
2228
|
function configSetsOrigin(arg) {
|
|
2228
2229
|
const prerender = findPrerenderOrigins(arg);
|
|
2229
2230
|
if (prerender === "unsupported" || prerender.length > 0) return true;
|
|
2230
|
-
return arg.getProperties().some((
|
|
2231
|
-
if (Node.isPropertyAssignment(
|
|
2232
|
-
const paths =
|
|
2231
|
+
return arg.getProperties().some((p76) => {
|
|
2232
|
+
if (Node.isPropertyAssignment(p76) && p76.getName() === "paths") {
|
|
2233
|
+
const paths = p76.getInitializerIfKind(SyntaxKind2.ObjectLiteralExpression);
|
|
2233
2234
|
return paths !== void 0 && hasOrigin(paths);
|
|
2234
2235
|
}
|
|
2235
|
-
const spread = conditionalSpreadOf(
|
|
2236
|
+
const spread = conditionalSpreadOf(p76, "paths");
|
|
2236
2237
|
return spread !== void 0 && hasOrigin(spread.object);
|
|
2237
2238
|
});
|
|
2238
2239
|
}
|
|
@@ -2246,8 +2247,8 @@ var ORIGIN_COMMENT = [
|
|
|
2246
2247
|
"baked in at build time. It is left unset for a deploy that serves more",
|
|
2247
2248
|
"than one host, where each request's own origin is used instead."
|
|
2248
2249
|
];
|
|
2249
|
-
function escapeRegExp2(
|
|
2250
|
-
return
|
|
2250
|
+
function escapeRegExp2(text20) {
|
|
2251
|
+
return text20.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2251
2252
|
}
|
|
2252
2253
|
function mentionsPrerender(node) {
|
|
2253
2254
|
return node.getLeadingCommentRanges().some((c) => /prerender/i.test(c.getText()));
|
|
@@ -2355,7 +2356,7 @@ function originValue(prop) {
|
|
|
2355
2356
|
}
|
|
2356
2357
|
function hasOrigin(object8) {
|
|
2357
2358
|
return object8.getProperties().some(
|
|
2358
|
-
(
|
|
2359
|
+
(p76) => p76.getKind() !== SyntaxKind2.SpreadAssignment ? p76.getName?.() === "origin" : conditionalSpreadOf(p76, "origin") !== void 0
|
|
2359
2360
|
);
|
|
2360
2361
|
}
|
|
2361
2362
|
function findPrerenderOrigins(arg) {
|
|
@@ -2544,7 +2545,7 @@ function detectJsonIndent(source) {
|
|
|
2544
2545
|
var PRINT_WIDTH = 100;
|
|
2545
2546
|
function stringifyJson(value, indent, level = 0, prefix = 0) {
|
|
2546
2547
|
const pad2 = (n) => indent.repeat(n);
|
|
2547
|
-
const width = (
|
|
2548
|
+
const width = (text20) => text20.replaceAll(" ", " ").length;
|
|
2548
2549
|
if (Array.isArray(value)) {
|
|
2549
2550
|
if (value.length === 0) return "[]";
|
|
2550
2551
|
const scalars = value.every((v14) => v14 === null || typeof v14 !== "object");
|
|
@@ -3138,7 +3139,7 @@ import path30 from "node:path";
|
|
|
3138
3139
|
import process16 from "node:process";
|
|
3139
3140
|
import * as v5 from "valibot";
|
|
3140
3141
|
import { Command as Command3 } from "commander";
|
|
3141
|
-
import * as
|
|
3142
|
+
import * as p12 from "@clack/prompts";
|
|
3142
3143
|
import { detect as detect5, resolveCommand as resolveCommand3 } from "package-manager-detector";
|
|
3143
3144
|
|
|
3144
3145
|
// src/lib/schema-create.ts
|
|
@@ -3856,46 +3857,195 @@ async function seedLinkedProject(apiKey, projectId, template) {
|
|
|
3856
3857
|
|
|
3857
3858
|
// src/commands/login.ts
|
|
3858
3859
|
import os4 from "node:os";
|
|
3859
|
-
import process14 from "node:process";
|
|
3860
3860
|
import { Command as Command2 } from "commander";
|
|
3861
|
-
import * as
|
|
3861
|
+
import * as p10 from "@clack/prompts";
|
|
3862
3862
|
import makeFetchCookie from "fetch-cookie";
|
|
3863
|
+
|
|
3864
|
+
// src/lib/account.ts
|
|
3865
|
+
import process14 from "node:process";
|
|
3866
|
+
import * as p9 from "@clack/prompts";
|
|
3867
|
+
import { parse } from "devalue";
|
|
3868
|
+
var NO_WHATSAPP = { enabled: false, allowSignup: false };
|
|
3869
|
+
async function fetchAuthMethods() {
|
|
3870
|
+
try {
|
|
3871
|
+
const res = await fetch(`${API_URL}/api/collections/users/auth-methods`);
|
|
3872
|
+
if (!res.ok) return { password: true, whatsapp: NO_WHATSAPP };
|
|
3873
|
+
const data = await res.json();
|
|
3874
|
+
return {
|
|
3875
|
+
password: data.password?.enabled !== false,
|
|
3876
|
+
whatsapp: {
|
|
3877
|
+
enabled: data.whatsapp?.enabled === true,
|
|
3878
|
+
allowSignup: data.whatsapp?.allowSignup === true
|
|
3879
|
+
}
|
|
3880
|
+
};
|
|
3881
|
+
} catch {
|
|
3882
|
+
return { password: true, whatsapp: NO_WHATSAPP };
|
|
3883
|
+
}
|
|
3884
|
+
}
|
|
3885
|
+
async function chooseAuthMethod(kind, methods) {
|
|
3886
|
+
const whatsapp3 = methods.whatsapp.enabled && (kind === "login" || methods.whatsapp.allowSignup);
|
|
3887
|
+
if (!whatsapp3) return "password";
|
|
3888
|
+
if (!methods.password) return "whatsapp";
|
|
3889
|
+
const choice = await p9.select({
|
|
3890
|
+
message: kind === "signup" ? "How do you want to sign up?" : "How do you want to log in?",
|
|
3891
|
+
options: [
|
|
3892
|
+
{ value: "password", label: "Email and password" },
|
|
3893
|
+
{ value: "whatsapp", label: "WhatsApp", hint: "a one-time code on your phone" }
|
|
3894
|
+
]
|
|
3895
|
+
});
|
|
3896
|
+
if (p9.isCancel(choice)) cancelled();
|
|
3897
|
+
return choice;
|
|
3898
|
+
}
|
|
3899
|
+
function cancelled() {
|
|
3900
|
+
p9.cancel("Operation cancelled.");
|
|
3901
|
+
process14.exit(0);
|
|
3902
|
+
}
|
|
3903
|
+
async function postForm(fetchCookie, path68, fields) {
|
|
3904
|
+
const res = await fetchCookie(`${API_URL}${path68}`, {
|
|
3905
|
+
method: "POST",
|
|
3906
|
+
headers: {
|
|
3907
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
3908
|
+
Accept: "application/json",
|
|
3909
|
+
"x-sveltekit-action": "true",
|
|
3910
|
+
Origin: API_URL
|
|
3911
|
+
},
|
|
3912
|
+
body: new URLSearchParams(fields).toString()
|
|
3913
|
+
});
|
|
3914
|
+
let result;
|
|
3915
|
+
try {
|
|
3916
|
+
result = await res.json();
|
|
3917
|
+
} catch {
|
|
3918
|
+
return { type: "error", message: `velastack.dev answered ${res.status}` };
|
|
3919
|
+
}
|
|
3920
|
+
switch (result.type) {
|
|
3921
|
+
case "redirect":
|
|
3922
|
+
return { type: "redirect", location: result.location ?? "/" };
|
|
3923
|
+
case "success":
|
|
3924
|
+
return { type: "success" };
|
|
3925
|
+
case "failure":
|
|
3926
|
+
return { type: "failure", status: result.status ?? 400, message: formMessage(result.data) };
|
|
3927
|
+
default:
|
|
3928
|
+
return { type: "error", message: result.error?.message ?? null };
|
|
3929
|
+
}
|
|
3930
|
+
}
|
|
3931
|
+
function formMessage(data) {
|
|
3932
|
+
if (!data) return null;
|
|
3933
|
+
let form3;
|
|
3934
|
+
try {
|
|
3935
|
+
({ form: form3 } = parse(data));
|
|
3936
|
+
} catch {
|
|
3937
|
+
return null;
|
|
3938
|
+
}
|
|
3939
|
+
if (typeof form3?.message === "string") return form3.message;
|
|
3940
|
+
if (form3?.message?.text) return form3.message.text;
|
|
3941
|
+
for (const errors of Object.values(form3?.errors ?? {})) {
|
|
3942
|
+
if (errors?.[0]) return errors[0];
|
|
3943
|
+
}
|
|
3944
|
+
return null;
|
|
3945
|
+
}
|
|
3946
|
+
function redirectedTo(result) {
|
|
3947
|
+
if (result.type !== "redirect") return null;
|
|
3948
|
+
return new URL(result.location, API_URL).pathname;
|
|
3949
|
+
}
|
|
3950
|
+
function validatePhone(value) {
|
|
3951
|
+
const raw = (value ?? "").trim().replace(/^00/, "+");
|
|
3952
|
+
if (!raw.startsWith("+")) return "Enter the number in international format, eg. +16165550123";
|
|
3953
|
+
const rest = raw.slice(1);
|
|
3954
|
+
if (/[^0-9 .()-]/.test(rest)) return "Enter the number in international format, eg. +16165550123";
|
|
3955
|
+
const digits = rest.replace(/[^0-9]/g, "");
|
|
3956
|
+
if (digits.length < 8 || digits.length > 15 || digits.startsWith("0")) {
|
|
3957
|
+
return "Enter the number in international format, eg. +16165550123";
|
|
3958
|
+
}
|
|
3959
|
+
return void 0;
|
|
3960
|
+
}
|
|
3961
|
+
var CODE_ATTEMPTS = 3;
|
|
3962
|
+
async function signInWithWhatsApp(fetchCookie, kind) {
|
|
3963
|
+
const phone = await p9.text({
|
|
3964
|
+
message: "WhatsApp number",
|
|
3965
|
+
placeholder: "+1 616 555 0123",
|
|
3966
|
+
validate: validatePhone
|
|
3967
|
+
});
|
|
3968
|
+
if (p9.isCancel(phone)) cancelled();
|
|
3969
|
+
const sent = await postForm(fetchCookie, `/${kind}`, { type: "whatsapp", phone: phone.trim() });
|
|
3970
|
+
const codePath = redirectedTo(sent);
|
|
3971
|
+
const otpId = codePath?.match(/^\/whatsapp\/([^/]+)$/)?.[1];
|
|
3972
|
+
if (!otpId) {
|
|
3973
|
+
throw new Error(failureText(sent, "Failed to send the WhatsApp code."));
|
|
3974
|
+
}
|
|
3975
|
+
p9.log.info("We sent a code to your WhatsApp.");
|
|
3976
|
+
for (let attempt = 1; ; attempt++) {
|
|
3977
|
+
const code2 = await p9.text({
|
|
3978
|
+
message: "Code",
|
|
3979
|
+
validate: (value) => /^\d{4,8}$/.test((value ?? "").trim()) ? void 0 : "Enter the code"
|
|
3980
|
+
});
|
|
3981
|
+
if (p9.isCancel(code2)) cancelled();
|
|
3982
|
+
const verified = await postForm(fetchCookie, codePath, { otp: code2.trim() });
|
|
3983
|
+
const next = redirectedTo(verified);
|
|
3984
|
+
if (next) {
|
|
3985
|
+
const isNew = next.startsWith("/welcome");
|
|
3986
|
+
if (isNew) await askForName(fetchCookie);
|
|
3987
|
+
return { isNew };
|
|
3988
|
+
}
|
|
3989
|
+
if (verified.type !== "failure") {
|
|
3990
|
+
throw new Error(failureText(verified, "Failed to verify the code."));
|
|
3991
|
+
}
|
|
3992
|
+
if (attempt >= CODE_ATTEMPTS) {
|
|
3993
|
+
throw new Error(
|
|
3994
|
+
`${verified.message ?? "The code is wrong or has expired."} Run \`vela ${kind}\` again.`
|
|
3995
|
+
);
|
|
3996
|
+
}
|
|
3997
|
+
p9.log.warn(`${verified.message ?? "That code is wrong or has expired."} Try again.`);
|
|
3998
|
+
}
|
|
3999
|
+
}
|
|
4000
|
+
function failureText(result, fallback) {
|
|
4001
|
+
const message = result.type === "failure" || result.type === "error" ? result.message : null;
|
|
4002
|
+
return message ?? `${fallback} Try again or contact support.`;
|
|
4003
|
+
}
|
|
4004
|
+
async function askForName(fetchCookie) {
|
|
4005
|
+
const name = await p9.text({
|
|
4006
|
+
message: "Your name",
|
|
4007
|
+
validate: (value) => (value ?? "").trim() ? void 0 : "Enter your name"
|
|
4008
|
+
});
|
|
4009
|
+
if (p9.isCancel(name)) cancelled();
|
|
4010
|
+
const res = await postForm(fetchCookie, "/welcome", { name: name.trim() });
|
|
4011
|
+
if (!redirectedTo(res)) {
|
|
4012
|
+
p9.log.warn("Could not save your name. You can set it at https://velastack.dev/settings");
|
|
4013
|
+
}
|
|
4014
|
+
}
|
|
4015
|
+
|
|
4016
|
+
// src/commands/login.ts
|
|
3863
4017
|
var login = new Command2("login").description("login to velastack.dev").configureHelp(helpConfig).action(
|
|
3864
4018
|
() => runCommand(async () => {
|
|
3865
4019
|
await loginInteractively();
|
|
3866
|
-
|
|
4020
|
+
p10.log.success("Logged in to velastack.dev");
|
|
3867
4021
|
}, "Failed to login.")
|
|
3868
4022
|
);
|
|
3869
4023
|
async function loginInteractively() {
|
|
3870
|
-
const
|
|
4024
|
+
const method = await chooseAuthMethod("login", await fetchAuthMethods());
|
|
4025
|
+
const fetchCookie = makeFetchCookie(fetch);
|
|
4026
|
+
if (method === "whatsapp") {
|
|
4027
|
+
await signInWithWhatsApp(fetchCookie, "login");
|
|
4028
|
+
} else {
|
|
4029
|
+
await loginWithPassword(fetchCookie);
|
|
4030
|
+
}
|
|
4031
|
+
const apiKey = await issueApiKey(fetchCookie);
|
|
4032
|
+
writeConfig({ apiKey });
|
|
4033
|
+
return apiKey;
|
|
4034
|
+
}
|
|
4035
|
+
async function loginWithPassword(fetchCookie) {
|
|
4036
|
+
const { email: email2, password: password8 } = await p10.group(
|
|
3871
4037
|
{
|
|
3872
|
-
email: () =>
|
|
3873
|
-
password: () =>
|
|
4038
|
+
email: () => p10.text({ message: "Email" }),
|
|
4039
|
+
password: () => p10.password({ message: "Password" })
|
|
3874
4040
|
},
|
|
3875
|
-
{
|
|
3876
|
-
onCancel: () => {
|
|
3877
|
-
p9.cancel("Operation cancelled.");
|
|
3878
|
-
process14.exit(0);
|
|
3879
|
-
}
|
|
3880
|
-
}
|
|
4041
|
+
{ onCancel: cancelled }
|
|
3881
4042
|
);
|
|
3882
|
-
const
|
|
3883
|
-
|
|
3884
|
-
method: "POST",
|
|
3885
|
-
headers: {
|
|
3886
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
3887
|
-
Origin: API_URL
|
|
3888
|
-
},
|
|
3889
|
-
body: new URLSearchParams({ type: "password", email: email2, password: password8 }).toString()
|
|
3890
|
-
});
|
|
3891
|
-
if (!loginRes.headers.get("Set-Cookie")) {
|
|
4043
|
+
const result = await postForm(fetchCookie, "/login", { type: "password", email: email2, password: password8 });
|
|
4044
|
+
if (result.type !== "redirect") {
|
|
3892
4045
|
throw new Error(
|
|
3893
|
-
"Run
|
|
4046
|
+
`${failureText(result, "Failed to authenticate.")} Run \`vela signup\` to create an account or reset at https://velastack.dev/reset`
|
|
3894
4047
|
);
|
|
3895
4048
|
}
|
|
3896
|
-
const apiKey = await issueApiKey(fetchCookie);
|
|
3897
|
-
writeConfig({ apiKey });
|
|
3898
|
-
return apiKey;
|
|
3899
4049
|
}
|
|
3900
4050
|
async function issueApiKey(fetchCookie) {
|
|
3901
4051
|
const label2 = `CLI - ${os4.hostname()}`;
|
|
@@ -3940,7 +4090,7 @@ import path28 from "node:path";
|
|
|
3940
4090
|
import process15 from "node:process";
|
|
3941
4091
|
import { execFileSync, spawn as spawn3 } from "node:child_process";
|
|
3942
4092
|
import { createRequire as createRequire3 } from "node:module";
|
|
3943
|
-
import * as
|
|
4093
|
+
import * as p11 from "@clack/prompts";
|
|
3944
4094
|
import { x as x2 } from "tinyexec";
|
|
3945
4095
|
import { detect as detect4 } from "package-manager-detector";
|
|
3946
4096
|
import {
|
|
@@ -4400,10 +4550,10 @@ var npmViewLookup = (name, range, cwd) => new Promise((resolve2, reject) => {
|
|
|
4400
4550
|
(error, stdout, stderr) => {
|
|
4401
4551
|
if (error && /\bE404\b/.test(`${stderr}${error.message}`)) return resolve2(null);
|
|
4402
4552
|
if (error) return reject(error);
|
|
4403
|
-
const
|
|
4404
|
-
if (!
|
|
4553
|
+
const text20 = stdout.trim();
|
|
4554
|
+
if (!text20) return resolve2(null);
|
|
4405
4555
|
try {
|
|
4406
|
-
resolve2(newest(JSON.parse(
|
|
4556
|
+
resolve2(newest(JSON.parse(text20)));
|
|
4407
4557
|
} catch (e) {
|
|
4408
4558
|
reject(e);
|
|
4409
4559
|
}
|
|
@@ -4492,7 +4642,7 @@ function keyName(node) {
|
|
|
4492
4642
|
return node.getNameNode().getText().replace(/^['"`]|['"`]$/g, "");
|
|
4493
4643
|
}
|
|
4494
4644
|
function localesProperty(alias) {
|
|
4495
|
-
return alias.getProperties().find((
|
|
4645
|
+
return alias.getProperties().find((p76) => keyName(p76) === "$locales");
|
|
4496
4646
|
}
|
|
4497
4647
|
function localesSpecifier(root, rest) {
|
|
4498
4648
|
if (/\.(?:js|mjs|cjs|json)$/.test(rest)) return `#locales/${rest}`;
|
|
@@ -4699,8 +4849,8 @@ var KEPT_EXTENSIONS = /\.(svelte|svg|svx|css|json)$/;
|
|
|
4699
4849
|
var MODULE_EXTENSIONS = [".ts", ".js", ".mts", ".mjs"];
|
|
4700
4850
|
function resolveLibPath(root, rel) {
|
|
4701
4851
|
const lib = path26.join(root, "src", "lib");
|
|
4702
|
-
const isFile = (
|
|
4703
|
-
const isDir = (
|
|
4852
|
+
const isFile = (p76) => fs27.existsSync(path26.join(lib, p76)) && fs27.statSync(path26.join(lib, p76)).isFile();
|
|
4853
|
+
const isDir = (p76) => fs27.existsSync(path26.join(lib, p76)) && fs27.statSync(path26.join(lib, p76)).isDirectory();
|
|
4704
4854
|
if (rel === "") return "";
|
|
4705
4855
|
if (KEPT_EXTENSIONS.test(rel)) {
|
|
4706
4856
|
if (isFile(rel)) return rel;
|
|
@@ -4860,14 +5010,14 @@ function skipString(source, start) {
|
|
|
4860
5010
|
}
|
|
4861
5011
|
return -1;
|
|
4862
5012
|
}
|
|
4863
|
-
function splitTopLevel(
|
|
5013
|
+
function splitTopLevel(text20) {
|
|
4864
5014
|
const parts = [];
|
|
4865
5015
|
let depth = 0;
|
|
4866
5016
|
let partStart = 0;
|
|
4867
|
-
for (let i = 0; i <
|
|
4868
|
-
const c =
|
|
5017
|
+
for (let i = 0; i < text20.length; i++) {
|
|
5018
|
+
const c = text20[i];
|
|
4869
5019
|
if (c === '"' || c === "'" || c === "`") {
|
|
4870
|
-
const end = skipString(
|
|
5020
|
+
const end = skipString(text20, i);
|
|
4871
5021
|
if (end === -1) break;
|
|
4872
5022
|
i = end;
|
|
4873
5023
|
continue;
|
|
@@ -4875,12 +5025,12 @@ function splitTopLevel(text19) {
|
|
|
4875
5025
|
if (c === "(" || c === "{" || c === "[") depth++;
|
|
4876
5026
|
else if (c === ")" || c === "}" || c === "]") depth--;
|
|
4877
5027
|
else if (c === "," && depth === 0) {
|
|
4878
|
-
parts.push({ start: partStart, end: i, text:
|
|
5028
|
+
parts.push({ start: partStart, end: i, text: text20.slice(partStart, i) });
|
|
4879
5029
|
partStart = i + 1;
|
|
4880
5030
|
}
|
|
4881
5031
|
}
|
|
4882
|
-
if (
|
|
4883
|
-
parts.push({ start: partStart, end:
|
|
5032
|
+
if (text20.slice(partStart).trim()) {
|
|
5033
|
+
parts.push({ start: partStart, end: text20.length, text: text20.slice(partStart) });
|
|
4884
5034
|
}
|
|
4885
5035
|
return parts;
|
|
4886
5036
|
}
|
|
@@ -4931,21 +5081,21 @@ function rewriteGotoCalls(source, gotoNames) {
|
|
|
4931
5081
|
function rewriteGotoOptions(inner) {
|
|
4932
5082
|
const tail = inner.match(/,?\s*$/)[0];
|
|
4933
5083
|
const core = inner.slice(0, inner.length - tail.length);
|
|
4934
|
-
const keyed = splitTopLevel(core).map((
|
|
4935
|
-
const m =
|
|
5084
|
+
const keyed = splitTopLevel(core).map((p76) => {
|
|
5085
|
+
const m = p76.text.match(/^\s*(['"]?)([A-Za-z_$][\w$]*)\1\s*(?::\s*([\s\S]*?))?\s*$/);
|
|
4936
5086
|
return {
|
|
4937
|
-
...
|
|
5087
|
+
...p76,
|
|
4938
5088
|
key: m?.[2],
|
|
4939
5089
|
value: m ? m[3] ?? m[2] : void 0,
|
|
4940
5090
|
shorthand: m ? m[3] === void 0 : false
|
|
4941
5091
|
};
|
|
4942
5092
|
});
|
|
4943
|
-
const flags = keyed.filter((
|
|
5093
|
+
const flags = keyed.filter((p76) => p76.key === "noScroll" || p76.key === "keepFocus");
|
|
4944
5094
|
const summary = [];
|
|
4945
5095
|
const replaced = /* @__PURE__ */ new Map();
|
|
4946
5096
|
if (flags.length > 0) {
|
|
4947
5097
|
const values = flags.map((f) => f.shorthand ? void 0 : f.value?.trim());
|
|
4948
|
-
if (keyed.some((
|
|
5098
|
+
if (keyed.some((p76) => p76.key === "reset")) {
|
|
4949
5099
|
return {
|
|
4950
5100
|
inner,
|
|
4951
5101
|
summary: "",
|
|
@@ -4976,29 +5126,29 @@ function rewriteGotoOptions(inner) {
|
|
|
4976
5126
|
`${flags.map((f) => `${f.key}: ${f.value.trim()}`).join(", ")} \u2192 reset: ${allTrue ? "false" : "true"}`
|
|
4977
5127
|
);
|
|
4978
5128
|
}
|
|
4979
|
-
const invalidate = keyed.findIndex((
|
|
5129
|
+
const invalidate = keyed.findIndex((p76) => p76.key === "invalidateAll");
|
|
4980
5130
|
if (invalidate !== -1) {
|
|
4981
|
-
const
|
|
5131
|
+
const p76 = keyed[invalidate];
|
|
4982
5132
|
if (keyed.some((q) => q.key === "refreshAll")) {
|
|
4983
5133
|
replaced.set(invalidate, null);
|
|
4984
5134
|
summary.push("dropped invalidateAll (refreshAll already set)");
|
|
4985
|
-
} else if (
|
|
4986
|
-
replaced.set(invalidate,
|
|
5135
|
+
} else if (p76.shorthand) {
|
|
5136
|
+
replaced.set(invalidate, p76.text.replace("invalidateAll", "refreshAll: invalidateAll"));
|
|
4987
5137
|
summary.push("invalidateAll \u2192 refreshAll");
|
|
4988
5138
|
} else {
|
|
4989
|
-
replaced.set(invalidate,
|
|
5139
|
+
replaced.set(invalidate, p76.text.replace("invalidateAll", "refreshAll"));
|
|
4990
5140
|
summary.push("invalidateAll \u2192 refreshAll");
|
|
4991
5141
|
}
|
|
4992
5142
|
}
|
|
4993
5143
|
if (replaced.size === 0) return { inner, summary: "" };
|
|
4994
|
-
const kept = keyed.map((
|
|
5144
|
+
const kept = keyed.map((p76, i) => replaced.has(i) ? replaced.get(i) : p76.text).filter((t) => t !== null);
|
|
4995
5145
|
let joined = kept.join(",");
|
|
4996
5146
|
const lead = core.match(/^\s*/)[0];
|
|
4997
5147
|
if (!joined.startsWith(lead)) joined = lead + joined.trimStart();
|
|
4998
5148
|
return { inner: joined + tail, summary: summary.join("; ") };
|
|
4999
5149
|
}
|
|
5000
|
-
function escapeRegExp3(
|
|
5001
|
-
return
|
|
5150
|
+
function escapeRegExp3(text20) {
|
|
5151
|
+
return text20.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5002
5152
|
}
|
|
5003
5153
|
function rewriteInvalidateAll(source) {
|
|
5004
5154
|
const outcome = { edits: [], changes: [], tasks: [] };
|
|
@@ -5083,9 +5233,9 @@ function addTaskComments(source, file, tasks) {
|
|
|
5083
5233
|
const lineStart2 = code2.lastIndexOf("\n", index - 1) + 1;
|
|
5084
5234
|
const lineEnd = code2.indexOf("\n", index);
|
|
5085
5235
|
const excerpt = code2.slice(lineStart2, lineEnd === -1 ? void 0 : lineEnd).trim().replace(/--/g, "- -").slice(0, 80);
|
|
5086
|
-
const
|
|
5087
|
-
if (code2.includes(
|
|
5088
|
-
code2 = `<!-- ${
|
|
5236
|
+
const text20 = `${MIGRATION_TASK_MARKER} \`${excerpt}\`: ${message}`;
|
|
5237
|
+
if (code2.includes(text20)) continue;
|
|
5238
|
+
code2 = `<!-- ${text20} -->
|
|
5089
5239
|
${code2}`;
|
|
5090
5240
|
added.push(`line ${line}: ${message}`);
|
|
5091
5241
|
continue;
|
|
@@ -5268,15 +5418,15 @@ var Kit3MigrationError = class extends Error {
|
|
|
5268
5418
|
name = "Kit3MigrationError";
|
|
5269
5419
|
};
|
|
5270
5420
|
var clackLog = {
|
|
5271
|
-
step: (m) =>
|
|
5272
|
-
info: (m) =>
|
|
5273
|
-
warn: (m) =>
|
|
5274
|
-
success: (m) =>
|
|
5421
|
+
step: (m) => p11.log.step(m),
|
|
5422
|
+
info: (m) => p11.log.info(m),
|
|
5423
|
+
warn: (m) => p11.log.warn(m),
|
|
5424
|
+
success: (m) => p11.log.success(m)
|
|
5275
5425
|
};
|
|
5276
5426
|
async function runKit3Migration(root, options = {}) {
|
|
5277
5427
|
const quiet = options.quiet ?? false;
|
|
5278
5428
|
const base2 = options.log ?? clackLog;
|
|
5279
|
-
const
|
|
5429
|
+
const log58 = quiet ? { ...base2, step: () => {
|
|
5280
5430
|
}, info: () => {
|
|
5281
5431
|
}, success: () => {
|
|
5282
5432
|
} } : base2;
|
|
@@ -5287,19 +5437,19 @@ async function runKit3Migration(root, options = {}) {
|
|
|
5287
5437
|
let paramTypes = /* @__PURE__ */ new Set();
|
|
5288
5438
|
if (mode === "repair") {
|
|
5289
5439
|
sv.skipped = "SvelteKit 3 already, with no svelte.config: running only the vela steps";
|
|
5290
|
-
|
|
5440
|
+
log58.info("Already on SvelteKit 3: skipping sv and re-checking the vela steps.");
|
|
5291
5441
|
} else if (options.skipSv) {
|
|
5292
5442
|
sv.skipped = "--skip-sv";
|
|
5293
|
-
|
|
5443
|
+
log58.info("Skipping sv (--skip-sv).");
|
|
5294
5444
|
} else {
|
|
5295
|
-
|
|
5296
|
-
sv.cleared = clearOutputDirs(root,
|
|
5445
|
+
log58.step("Running sv migrate sveltekit-3...");
|
|
5446
|
+
sv.cleared = clearOutputDirs(root, log58);
|
|
5297
5447
|
svelteConfig = captureSvelteConfig(root);
|
|
5298
5448
|
paramTypes = captureParamTypeImports(root);
|
|
5299
|
-
await runSv(root, options.runSv ?? defaultSvRunner, quiet, sv,
|
|
5449
|
+
await runSv(root, options.runSv ?? defaultSvRunner, quiet, sv, log58);
|
|
5300
5450
|
sv.ran = true;
|
|
5301
5451
|
}
|
|
5302
|
-
|
|
5452
|
+
log58.step("Applying the vela steps...");
|
|
5303
5453
|
const cliVersion = options.cliVersion ?? package_default.version;
|
|
5304
5454
|
const fixups = [
|
|
5305
5455
|
originFixup(root, svelteConfig, sv),
|
|
@@ -5315,8 +5465,8 @@ async function runKit3Migration(root, options = {}) {
|
|
|
5315
5465
|
lockfileFixup(root)
|
|
5316
5466
|
];
|
|
5317
5467
|
for (const fixup2 of fixups) {
|
|
5318
|
-
if (fixup2.changed)
|
|
5319
|
-
for (const warning of fixup2.warnings)
|
|
5468
|
+
if (fixup2.changed) log58.info(`${fixup2.name}: ${fixup2.details.join("; ")}`);
|
|
5469
|
+
for (const warning of fixup2.warnings) log58.warn(`${fixup2.name}: ${warning}`);
|
|
5320
5470
|
}
|
|
5321
5471
|
let installed2 = null;
|
|
5322
5472
|
let formatted = [];
|
|
@@ -5399,7 +5549,7 @@ function spawnSync(command, args, cwd) {
|
|
|
5399
5549
|
}
|
|
5400
5550
|
var require_ = createRequire3(import.meta.url);
|
|
5401
5551
|
var OUTPUT_DIRS = /* @__PURE__ */ new Set(["dist", "build", ".svelte-kit"]);
|
|
5402
|
-
function clearOutputDirs(root,
|
|
5552
|
+
function clearOutputDirs(root, log58) {
|
|
5403
5553
|
const cleared = [];
|
|
5404
5554
|
const inGit = spawnSync("git", ["rev-parse", "--is-inside-work-tree"], root) !== null;
|
|
5405
5555
|
const walk2 = (dir, depth) => {
|
|
@@ -5413,7 +5563,7 @@ function clearOutputDirs(root, log57) {
|
|
|
5413
5563
|
fs29.rmSync(full, { recursive: true, force: true });
|
|
5414
5564
|
cleared.push(rel);
|
|
5415
5565
|
} else if (entry.name !== ".svelte-kit") {
|
|
5416
|
-
|
|
5566
|
+
log58.warn(
|
|
5417
5567
|
`${rel} is not ignored by git, so it was left in place; sv may fail to parse what is in it.`
|
|
5418
5568
|
);
|
|
5419
5569
|
}
|
|
@@ -5424,7 +5574,7 @@ function clearOutputDirs(root, log57) {
|
|
|
5424
5574
|
}
|
|
5425
5575
|
};
|
|
5426
5576
|
walk2(root, 0);
|
|
5427
|
-
if (cleared.length > 0)
|
|
5577
|
+
if (cleared.length > 0) log58.info(`Removed build output before running sv: ${cleared.join(", ")}`);
|
|
5428
5578
|
return cleared;
|
|
5429
5579
|
}
|
|
5430
5580
|
function svBin() {
|
|
@@ -5479,8 +5629,8 @@ function svArgs(root, tasks, exclude) {
|
|
|
5479
5629
|
}
|
|
5480
5630
|
var ANSI = /\u001b\[[0-9;?]*[A-Za-z]/g;
|
|
5481
5631
|
function parseSvFailure(output) {
|
|
5482
|
-
const
|
|
5483
|
-
const match =
|
|
5632
|
+
const text20 = output.replace(ANSI, "");
|
|
5633
|
+
const match = text20.match(/Task '([^']+)' failed: ([^\n]*)/);
|
|
5484
5634
|
if (!match) return null;
|
|
5485
5635
|
const message = match[2].trim();
|
|
5486
5636
|
const file = message.match(/Unable to process '([^']+)'/)?.[1];
|
|
@@ -5510,7 +5660,7 @@ function excludeGlob(files) {
|
|
|
5510
5660
|
return `{${alternatives.join(",")}}`;
|
|
5511
5661
|
}
|
|
5512
5662
|
var MAX_RETRIES_PER_TASK = 10;
|
|
5513
|
-
async function runSv(root, runner, quiet, summary,
|
|
5663
|
+
async function runSv(root, runner, quiet, summary, log58) {
|
|
5514
5664
|
const first = await runner(svArgs(root, "all", []), { cwd: root, quiet });
|
|
5515
5665
|
if (first.code === 0) return;
|
|
5516
5666
|
const failure = parseSvFailure(first.output);
|
|
@@ -5528,7 +5678,7 @@ async function runSv(root, runner, quiet, summary, log57) {
|
|
|
5528
5678
|
const task = SV_TASKS[i];
|
|
5529
5679
|
if (i === index && !failure.file) continue;
|
|
5530
5680
|
for (let attempt = 0; attempt < MAX_RETRIES_PER_TASK; attempt++) {
|
|
5531
|
-
|
|
5681
|
+
log58.info(
|
|
5532
5682
|
`Re-running sv task ${task}${summary.excluded.length ? `, skipping ${summary.excluded.join(", ")}` : ""}...`
|
|
5533
5683
|
);
|
|
5534
5684
|
const result = await runner(svArgs(root, task, summary.excluded), { cwd: root, quiet });
|
|
@@ -5550,7 +5700,7 @@ async function runSv(root, runner, quiet, summary, log57) {
|
|
|
5550
5700
|
function record(f) {
|
|
5551
5701
|
summary.failures.push(f);
|
|
5552
5702
|
if (f.file && !summary.excluded.includes(f.file)) summary.excluded.push(f.file);
|
|
5553
|
-
|
|
5703
|
+
log58.warn(
|
|
5554
5704
|
f.file ? `sv's ${f.task} task could not process ${f.file}: ${f.message.replace(/^Unable to process '[^']+'\. Reason: /, "")}` : `sv's ${f.task} task failed: ${f.message}`
|
|
5555
5705
|
);
|
|
5556
5706
|
}
|
|
@@ -5570,9 +5720,9 @@ function originFixup(root, capture, sv) {
|
|
|
5570
5720
|
${outcome.snippet}`);
|
|
5571
5721
|
}
|
|
5572
5722
|
const lost = Boolean(carry && !outcome.applied && outcome.snippet);
|
|
5573
|
-
for (const
|
|
5574
|
-
if (carry && !lost && carry.text.endsWith(
|
|
5575
|
-
sv.dropped.push({ file: capture.file, text:
|
|
5723
|
+
for (const text20 of capture?.spreads ?? []) {
|
|
5724
|
+
if (carry && !lost && carry.text.endsWith(text20)) continue;
|
|
5725
|
+
sv.dropped.push({ file: capture.file, text: text20 });
|
|
5576
5726
|
}
|
|
5577
5727
|
return f;
|
|
5578
5728
|
}
|
|
@@ -5872,10 +6022,10 @@ function belowFloor(project, key, entry) {
|
|
|
5872
6022
|
return Boolean(floor && locked && compareVersions(locked, floor) < 0);
|
|
5873
6023
|
}
|
|
5874
6024
|
function readJson(file) {
|
|
5875
|
-
const
|
|
6025
|
+
const text20 = fs29.readFileSync(file, "utf8");
|
|
5876
6026
|
return {
|
|
5877
|
-
data: JSON.parse(
|
|
5878
|
-
indent:
|
|
6027
|
+
data: JSON.parse(text20),
|
|
6028
|
+
indent: text20.match(/^[{[]\s*\n([\t ]+)/)?.[1] ?? " "
|
|
5879
6029
|
};
|
|
5880
6030
|
}
|
|
5881
6031
|
function writeJson(file, data, indent) {
|
|
@@ -5982,13 +6132,13 @@ function previousFollowUps(root, pattern) {
|
|
|
5982
6132
|
const end = content.indexOf("\n## ", start + FOLLOW_UPS_HEADING.length);
|
|
5983
6133
|
return content.slice(start, end === -1 ? void 0 : end).split("\n").filter((line) => line.startsWith("- [") && pattern.test(line)).map((line) => line.replace(/^- \[[ x]\] /, ""));
|
|
5984
6134
|
}
|
|
5985
|
-
function code(
|
|
5986
|
-
const fence =
|
|
5987
|
-
const pad2 =
|
|
5988
|
-
return `${fence}${pad2}${
|
|
6135
|
+
function code(text20) {
|
|
6136
|
+
const fence = text20.includes("`") ? "``" : "`";
|
|
6137
|
+
const pad2 = text20.startsWith("`") || text20.endsWith("`") ? " " : "";
|
|
6138
|
+
return `${fence}${pad2}${text20}${pad2}${fence}`;
|
|
5989
6139
|
}
|
|
5990
|
-
function escape(
|
|
5991
|
-
return
|
|
6140
|
+
function escape(text20) {
|
|
6141
|
+
return text20.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5992
6142
|
}
|
|
5993
6143
|
function writeFollowUps(root, items, generic) {
|
|
5994
6144
|
const file = path28.join(root, MIGRATION_TASKS_FILE);
|
|
@@ -6130,8 +6280,8 @@ function findRepeaterImport(dir) {
|
|
|
6130
6280
|
for (const entry of entries) {
|
|
6131
6281
|
if (!entry.isFile() || !SOURCE_FILE.test(entry.name)) continue;
|
|
6132
6282
|
const file = path29.join(entry.parentPath, entry.name);
|
|
6133
|
-
const
|
|
6134
|
-
if (
|
|
6283
|
+
const text20 = fs30.readFileSync(file, "utf8");
|
|
6284
|
+
if (text20.includes("CmsRepeater") && REPEATER_IMPORT.test(text20)) {
|
|
6135
6285
|
return path29.relative(dir, file);
|
|
6136
6286
|
}
|
|
6137
6287
|
}
|
|
@@ -6260,7 +6410,7 @@ async function createProject2(cwdArg, options, listing) {
|
|
|
6260
6410
|
const resolved = await resolveCreatableTemplate(template);
|
|
6261
6411
|
const onCancel2 = () => {
|
|
6262
6412
|
resolved.cleanup();
|
|
6263
|
-
|
|
6413
|
+
p12.cancel("Operation cancelled.");
|
|
6264
6414
|
process16.exit(0);
|
|
6265
6415
|
};
|
|
6266
6416
|
let scaffolded;
|
|
@@ -6278,7 +6428,7 @@ async function createProject2(cwdArg, options, listing) {
|
|
|
6278
6428
|
writeProjectConfig(projectPath, { projectId, teamId, projectName });
|
|
6279
6429
|
}
|
|
6280
6430
|
const migrated = await migrateKit2Template(projectPath, template.name);
|
|
6281
|
-
|
|
6431
|
+
p12.log.success("Project created");
|
|
6282
6432
|
let packageManager2;
|
|
6283
6433
|
let installed2 = false;
|
|
6284
6434
|
if (options.install !== false) {
|
|
@@ -6293,7 +6443,7 @@ async function createProject2(cwdArg, options, listing) {
|
|
|
6293
6443
|
}
|
|
6294
6444
|
if (credentials) {
|
|
6295
6445
|
const { email: email2, password: password8 } = credentials;
|
|
6296
|
-
|
|
6446
|
+
p12.log.step("Initializing PocketBase...");
|
|
6297
6447
|
await createSuperuser(projectPath, email2, password8);
|
|
6298
6448
|
writeEnvFile(
|
|
6299
6449
|
projectPath,
|
|
@@ -6303,16 +6453,16 @@ async function createProject2(cwdArg, options, listing) {
|
|
|
6303
6453
|
},
|
|
6304
6454
|
["PocketBase superuser credentials \u2014 used by `vela` commands"]
|
|
6305
6455
|
);
|
|
6306
|
-
|
|
6456
|
+
p12.log.success("PocketBase initialized");
|
|
6307
6457
|
if (gallerySchema) {
|
|
6308
6458
|
if (!installed2) {
|
|
6309
6459
|
throw new Error(
|
|
6310
6460
|
"--schema needs the dependencies installed so PocketBase can run; create without --no-install, or run `vela generate migration --ai` after installing."
|
|
6311
6461
|
);
|
|
6312
6462
|
}
|
|
6313
|
-
|
|
6463
|
+
p12.log.step(`Creating the ${gallerySchema.title} schema...`);
|
|
6314
6464
|
const applied = await applyGallerySchema(projectPath, gallerySchema, { email: email2, password: password8 });
|
|
6315
|
-
|
|
6465
|
+
p12.log.success(
|
|
6316
6466
|
`Created ${applied.collections} collections (${applied.written.length} migration files)`
|
|
6317
6467
|
);
|
|
6318
6468
|
}
|
|
@@ -6320,7 +6470,7 @@ async function createProject2(cwdArg, options, listing) {
|
|
|
6320
6470
|
return { directory: projectPath, packageManager: packageManager2, installed: installed2, migrated, name, template, link: link2 };
|
|
6321
6471
|
}
|
|
6322
6472
|
async function resolveCreatableTemplate(template) {
|
|
6323
|
-
if (template.source === "remote")
|
|
6473
|
+
if (template.source === "remote") p12.log.step(`Downloading template ${template.name}...`);
|
|
6324
6474
|
const resolved = await resolveTemplate(template);
|
|
6325
6475
|
const blocker = findKit3Blocker(resolved.dir);
|
|
6326
6476
|
if (blocker) {
|
|
@@ -6337,29 +6487,29 @@ async function scaffoldProject(cwdArg, options, template, resolved, onCancel2) {
|
|
|
6337
6487
|
} else if (!interactive) {
|
|
6338
6488
|
throw new Error("Pass the directory to create the project in, e.g. `vela create my-app`.");
|
|
6339
6489
|
} else {
|
|
6340
|
-
const answer = await
|
|
6490
|
+
const answer = await p12.text({
|
|
6341
6491
|
message: "Where would you like your project to be created?",
|
|
6342
6492
|
placeholder: " (hit Enter to use current directory)",
|
|
6343
6493
|
defaultValue: "./"
|
|
6344
6494
|
});
|
|
6345
|
-
if (
|
|
6495
|
+
if (p12.isCancel(answer)) onCancel2();
|
|
6346
6496
|
directory = path30.resolve(answer);
|
|
6347
6497
|
}
|
|
6348
6498
|
if (fs31.existsSync(directory) && fs31.readdirSync(directory).filter((f) => !f.startsWith(".git")).length > 0) {
|
|
6349
6499
|
if (!interactive) throw new Error(`${directory} is not empty.`);
|
|
6350
|
-
const force = await
|
|
6500
|
+
const force = await p12.confirm({
|
|
6351
6501
|
message: "Directory not empty. Continue?",
|
|
6352
6502
|
initialValue: false
|
|
6353
6503
|
});
|
|
6354
|
-
if (
|
|
6504
|
+
if (p12.isCancel(force) || !force) onCancel2();
|
|
6355
6505
|
}
|
|
6356
6506
|
const dirName = path30.basename(directory);
|
|
6357
|
-
const { name } = await
|
|
6507
|
+
const { name } = await p12.group(
|
|
6358
6508
|
{
|
|
6359
6509
|
name: () => {
|
|
6360
6510
|
if (options.name) return Promise.resolve(options.name);
|
|
6361
6511
|
if (!interactive) return Promise.resolve(dirName || "SvelteKit");
|
|
6362
|
-
return
|
|
6512
|
+
return p12.text({
|
|
6363
6513
|
message: "App name (written to src/lib/site.ts)",
|
|
6364
6514
|
initialValue: dirName || "SvelteKit",
|
|
6365
6515
|
validate: (value) => value?.trim() ? void 0 : "App name is required"
|
|
@@ -6383,7 +6533,7 @@ async function migrateKit2Template(projectPath, templateName2) {
|
|
|
6383
6533
|
if (!(status3.declaredMajor !== null && status3.declaredMajor < 3 || status3.svelteConfig)) {
|
|
6384
6534
|
return false;
|
|
6385
6535
|
}
|
|
6386
|
-
|
|
6536
|
+
p12.log.step(`Template ${templateName2} is written for SvelteKit 2; migrating it to SvelteKit 3...`);
|
|
6387
6537
|
let result;
|
|
6388
6538
|
try {
|
|
6389
6539
|
result = await runKit3Migration(projectPath, { gitCheck: false, install: false, quiet: true });
|
|
@@ -6404,11 +6554,11 @@ The project is in ${projectPath}. Finish the migration by hand with
|
|
|
6404
6554
|
fs31.rmSync(tasksFile);
|
|
6405
6555
|
}
|
|
6406
6556
|
const left = fs31.existsSync(tasksFile);
|
|
6407
|
-
|
|
6557
|
+
p12.log.success(
|
|
6408
6558
|
`Migrated to SvelteKit 3${left ? `; ${MIGRATION_TASKS_FILE} lists what to check by hand` : ""}.`
|
|
6409
6559
|
);
|
|
6410
6560
|
if (result.followUps.length > 0) {
|
|
6411
|
-
|
|
6561
|
+
p12.log.warn(result.followUps.map((item) => `- ${item}`).join("\n"));
|
|
6412
6562
|
}
|
|
6413
6563
|
return true;
|
|
6414
6564
|
}
|
|
@@ -6448,7 +6598,7 @@ async function linkOnCreate(name, template, options, onCancel2) {
|
|
|
6448
6598
|
}
|
|
6449
6599
|
let linked;
|
|
6450
6600
|
if (decision.kind === "create") {
|
|
6451
|
-
|
|
6601
|
+
p12.log.step(
|
|
6452
6602
|
options.link === "new" ? "Linking to a new velastack.dev project..." : "Linking to a new velastack.dev project (pass `--link none` to skip)..."
|
|
6453
6603
|
);
|
|
6454
6604
|
linked = await linkNewProject(apiKey ?? requireApiKey(), {
|
|
@@ -6458,18 +6608,18 @@ async function linkOnCreate(name, template, options, onCancel2) {
|
|
|
6458
6608
|
interactive
|
|
6459
6609
|
});
|
|
6460
6610
|
} else if (decision.kind === "existing") {
|
|
6461
|
-
|
|
6611
|
+
p12.log.step("Linking to velastack.dev...");
|
|
6462
6612
|
linked = await linkExistingProject(requireApiKey(), decision.projectId);
|
|
6463
6613
|
} else if (decision.kind === "none" && decision.warn) {
|
|
6464
|
-
|
|
6614
|
+
p12.log.warn(decision.warn);
|
|
6465
6615
|
}
|
|
6466
6616
|
if (linked) {
|
|
6467
6617
|
outcome.linked = linked;
|
|
6468
|
-
|
|
6618
|
+
p12.log.success(`Linked to ${linked.projectName} (${linked.dashboardUrl})`);
|
|
6469
6619
|
if (templateCms && !outcome.cmsEndpoint) {
|
|
6470
6620
|
outcome.cmsEndpoint = cmsEndpointFor(linked.projectId);
|
|
6471
6621
|
outcome.cmsSource = "linked";
|
|
6472
|
-
|
|
6622
|
+
p12.log.success(`CMS: ${outcome.cmsEndpoint}`);
|
|
6473
6623
|
outcome.seed = await seedCms(apiKey ?? requireApiKey(), linked, template);
|
|
6474
6624
|
}
|
|
6475
6625
|
}
|
|
@@ -6480,20 +6630,20 @@ async function seedCms(apiKey, linked, template) {
|
|
|
6480
6630
|
const version = template.entry.version;
|
|
6481
6631
|
const seed = await seedLinkedProject(apiKey, linked.projectId, { name: template.name, version });
|
|
6482
6632
|
if (seed.status === "seeded") {
|
|
6483
|
-
|
|
6633
|
+
p12.log.success(`CMS content loaded (${seed.locales.join(", ")})`);
|
|
6484
6634
|
} else if (seed.status === "already-seeded") {
|
|
6485
|
-
|
|
6635
|
+
p12.log.info("The CMS already has content; left as it is.");
|
|
6486
6636
|
} else if (seed.status === "failed") {
|
|
6487
|
-
|
|
6637
|
+
p12.log.warn(`Could not load the template's content into the CMS: ${seed.error}`);
|
|
6488
6638
|
}
|
|
6489
6639
|
const forms = formsCreatedMessage(seed);
|
|
6490
|
-
if (forms)
|
|
6640
|
+
if (forms) p12.log.success(forms);
|
|
6491
6641
|
return seed;
|
|
6492
6642
|
}
|
|
6493
6643
|
async function promptCms(onCancel2) {
|
|
6494
|
-
|
|
6644
|
+
p12.note(`This template reads its copy from a hosted CMS.
|
|
6495
6645
|
${FREE_CMS_HINT}.`, "CMS");
|
|
6496
|
-
const choice = await
|
|
6646
|
+
const choice = await p12.select({
|
|
6497
6647
|
message: "Where should the site read its content from?",
|
|
6498
6648
|
options: [
|
|
6499
6649
|
{ value: "login", label: "Log in to velastack.dev and create one", hint: "free" },
|
|
@@ -6501,14 +6651,14 @@ ${FREE_CMS_HINT}.`, "CMS");
|
|
|
6501
6651
|
{ value: "skip", label: "Skip for now", hint: "the site shows its fallback copy" }
|
|
6502
6652
|
]
|
|
6503
6653
|
});
|
|
6504
|
-
if (
|
|
6654
|
+
if (p12.isCancel(choice)) onCancel2();
|
|
6505
6655
|
if (choice !== "url") return { kind: choice };
|
|
6506
|
-
const url = await
|
|
6656
|
+
const url = await p12.text({
|
|
6507
6657
|
message: "CMS URL",
|
|
6508
6658
|
placeholder: "https://velastack.dev/v1/projects/<project>/cms",
|
|
6509
6659
|
validate: (value) => CMS_URL_RE.test(value?.trim() ?? "") ? void 0 : "Enter an absolute http(s) URL"
|
|
6510
6660
|
});
|
|
6511
|
-
if (
|
|
6661
|
+
if (p12.isCancel(url)) onCancel2();
|
|
6512
6662
|
return { kind: "url", url: normalizeCmsUrl(url) };
|
|
6513
6663
|
}
|
|
6514
6664
|
function hasScript(directory, name) {
|
|
@@ -6525,12 +6675,12 @@ import { Command as Command11 } from "commander";
|
|
|
6525
6675
|
|
|
6526
6676
|
// src/commands/generate/form.ts
|
|
6527
6677
|
import { Command as Command4 } from "commander";
|
|
6528
|
-
import * as
|
|
6678
|
+
import * as p18 from "@clack/prompts";
|
|
6529
6679
|
|
|
6530
6680
|
// src/lib/pattern-runner.ts
|
|
6531
6681
|
import fs32 from "node:fs";
|
|
6532
6682
|
import path31 from "node:path";
|
|
6533
|
-
import * as
|
|
6683
|
+
import * as p13 from "@clack/prompts";
|
|
6534
6684
|
import { bySlug as bySlug3 } from "@velastack/patterns";
|
|
6535
6685
|
|
|
6536
6686
|
// src/lib/require-ui.ts
|
|
@@ -6703,7 +6853,7 @@ async function runPattern(slug2, argv, input, report5, after) {
|
|
|
6703
6853
|
provider: typeof input.provider === "string" ? input.provider : void 0
|
|
6704
6854
|
});
|
|
6705
6855
|
const migrationsBefore = listMigrations2(workspaceRootDir);
|
|
6706
|
-
const
|
|
6856
|
+
const log58 = p13.taskLog({ title: report5.task.title });
|
|
6707
6857
|
let result;
|
|
6708
6858
|
try {
|
|
6709
6859
|
result = await pattern.generate({
|
|
@@ -6725,11 +6875,11 @@ async function runPattern(slug2, argv, input, report5, after) {
|
|
|
6725
6875
|
});
|
|
6726
6876
|
return collections2;
|
|
6727
6877
|
},
|
|
6728
|
-
logger: { info: (message) =>
|
|
6878
|
+
logger: { info: (message) => log58.message(message) }
|
|
6729
6879
|
});
|
|
6730
|
-
|
|
6880
|
+
log58.success(report5.task.success);
|
|
6731
6881
|
} catch (e) {
|
|
6732
|
-
|
|
6882
|
+
log58.error(report5.task.error);
|
|
6733
6883
|
throw e;
|
|
6734
6884
|
}
|
|
6735
6885
|
let afterError;
|
|
@@ -6756,7 +6906,7 @@ async function runPattern(slug2, argv, input, report5, after) {
|
|
|
6756
6906
|
const deleted = result.deletes.filter(isSuccess);
|
|
6757
6907
|
const totalChanges = created.length + modified.length + deleted.length + result.components.length + result.packages.length + result.collections.length;
|
|
6758
6908
|
if (totalChanges === 0 && failures.length === 0) {
|
|
6759
|
-
|
|
6909
|
+
p13.log.info(`${pattern.title ?? slug2} produced no changes.`);
|
|
6760
6910
|
} else {
|
|
6761
6911
|
reportResult({
|
|
6762
6912
|
summary: report5.summary ?? `Applied ${pattern.title ?? slug2}.`,
|
|
@@ -6803,18 +6953,18 @@ function resolveFormInput(root, detectedUi, requested) {
|
|
|
6803
6953
|
// src/lib/ai-flow.ts
|
|
6804
6954
|
import fs33 from "node:fs";
|
|
6805
6955
|
import path33 from "node:path";
|
|
6806
|
-
import * as
|
|
6956
|
+
import * as p17 from "@clack/prompts";
|
|
6807
6957
|
import pc6 from "picocolors";
|
|
6808
6958
|
|
|
6809
6959
|
// src/lib/ai-loop.ts
|
|
6810
|
-
import * as
|
|
6960
|
+
import * as p14 from "@clack/prompts";
|
|
6811
6961
|
async function aiLoop(opts) {
|
|
6812
6962
|
let prompt = opts.initialPrompt;
|
|
6813
6963
|
let history = [];
|
|
6814
6964
|
let attempt = 0;
|
|
6815
6965
|
while (true) {
|
|
6816
6966
|
attempt++;
|
|
6817
|
-
const spinner9 =
|
|
6967
|
+
const spinner9 = p14.spinner();
|
|
6818
6968
|
spinner9.start(`${opts.stageLabel} (${attempt > 1 ? "iteration " + attempt : "first pass"})\u2026`);
|
|
6819
6969
|
let result;
|
|
6820
6970
|
let turn;
|
|
@@ -6828,12 +6978,12 @@ async function aiLoop(opts) {
|
|
|
6828
6978
|
throw e;
|
|
6829
6979
|
}
|
|
6830
6980
|
opts.renderPreview(result);
|
|
6831
|
-
const next = await
|
|
6981
|
+
const next = await p14.text({
|
|
6832
6982
|
message: "Refine the result, or press Enter to apply.",
|
|
6833
6983
|
placeholder: opts.refinePlaceholder,
|
|
6834
6984
|
defaultValue: ""
|
|
6835
6985
|
});
|
|
6836
|
-
if (
|
|
6986
|
+
if (p14.isCancel(next)) return null;
|
|
6837
6987
|
const trimmed = (typeof next === "string" ? next : "").trim();
|
|
6838
6988
|
if (trimmed === "") return result;
|
|
6839
6989
|
history = turn;
|
|
@@ -6842,7 +6992,7 @@ async function aiLoop(opts) {
|
|
|
6842
6992
|
}
|
|
6843
6993
|
|
|
6844
6994
|
// src/lib/ai-existing-models.ts
|
|
6845
|
-
import * as
|
|
6995
|
+
import * as p15 from "@clack/prompts";
|
|
6846
6996
|
async function loadExistingModels(workspaceRootDir) {
|
|
6847
6997
|
let result = [];
|
|
6848
6998
|
try {
|
|
@@ -6867,7 +7017,7 @@ async function loadExistingModels(workspaceRootDir) {
|
|
|
6867
7017
|
});
|
|
6868
7018
|
} catch (e) {
|
|
6869
7019
|
const msg = e instanceof Error ? e.message : String(e);
|
|
6870
|
-
|
|
7020
|
+
p15.log.warn(
|
|
6871
7021
|
`Could not load existing schema from PocketBase (${msg}). The AI agent will design without that context.`
|
|
6872
7022
|
);
|
|
6873
7023
|
return [];
|
|
@@ -6876,7 +7026,7 @@ async function loadExistingModels(workspaceRootDir) {
|
|
|
6876
7026
|
}
|
|
6877
7027
|
|
|
6878
7028
|
// src/lib/ai-to-argv.ts
|
|
6879
|
-
import * as
|
|
7029
|
+
import * as p16 from "@clack/prompts";
|
|
6880
7030
|
var PRIMITIVE_TYPES = /* @__PURE__ */ new Set(["text", "number", "bool", "email", "date", "url", "file"]);
|
|
6881
7031
|
function singularize(name) {
|
|
6882
7032
|
if (name.endsWith("ies") && name.length > 3) return `${name.slice(0, -3)}y`;
|
|
@@ -6899,7 +7049,7 @@ function collectionSpecToArgv(spec) {
|
|
|
6899
7049
|
for (const field of spec.fields) {
|
|
6900
7050
|
const type = typeArg(field);
|
|
6901
7051
|
if (type === null) {
|
|
6902
|
-
|
|
7052
|
+
p16.log.warn(
|
|
6903
7053
|
`Skipping field "${field.name}" (type "${field.type}" cannot be represented as a pattern argument)`
|
|
6904
7054
|
);
|
|
6905
7055
|
continue;
|
|
@@ -7002,10 +7152,10 @@ function renderModel(spec) {
|
|
|
7002
7152
|
const tail = extra.length > 0 ? " " + pc6.dim(extra.join(" ")) : "";
|
|
7003
7153
|
lines.push(` ${f.name.padEnd(nameWidth)} ${f.type.padEnd(typeWidth)} ${required}${tail}`);
|
|
7004
7154
|
}
|
|
7005
|
-
|
|
7155
|
+
p17.log.message(lines.join("\n"));
|
|
7006
7156
|
}
|
|
7007
7157
|
function renderLayout(layout) {
|
|
7008
|
-
|
|
7158
|
+
p17.log.message(renderGrid(layout));
|
|
7009
7159
|
}
|
|
7010
7160
|
async function runSchemaStage(opts) {
|
|
7011
7161
|
const { workspaceRootDir } = await getWorkspace();
|
|
@@ -7076,12 +7226,12 @@ var form = new Command4("form").description("generate a form from a model").argu
|
|
|
7076
7226
|
}
|
|
7077
7227
|
const stage2 = await runSchemaStage({ prompt: options.ai, useCase: "form" });
|
|
7078
7228
|
if (!stage2) {
|
|
7079
|
-
|
|
7229
|
+
p18.cancel("Aborted before any files were written.");
|
|
7080
7230
|
return;
|
|
7081
7231
|
}
|
|
7082
7232
|
const layout = await runLayoutStage(stage2.workspaceRootDir, stage2.model);
|
|
7083
7233
|
if (!layout) {
|
|
7084
|
-
|
|
7234
|
+
p18.cancel("Aborted before any files were written.");
|
|
7085
7235
|
return;
|
|
7086
7236
|
}
|
|
7087
7237
|
argv = specToArgv(stage2.model);
|
|
@@ -7097,7 +7247,7 @@ var form = new Command4("form").description("generate a form from a model").argu
|
|
|
7097
7247
|
const { workspaceRootDir, features } = await getWorkspace();
|
|
7098
7248
|
const formInput = resolveFormInput(workspaceRootDir, features.ui, options.ui);
|
|
7099
7249
|
if (features.ui === "plain" && !options.ui) {
|
|
7100
|
-
|
|
7250
|
+
p18.log.info("shadcn-svelte not detected: generating a plain HTML form.");
|
|
7101
7251
|
}
|
|
7102
7252
|
const slug2 = options.remote ? "generate-form-remote" : "generate-form";
|
|
7103
7253
|
const nextSteps = [
|
|
@@ -7128,7 +7278,7 @@ var form = new Command4("form").description("generate a form from a model").argu
|
|
|
7128
7278
|
|
|
7129
7279
|
// src/commands/generate/schema.ts
|
|
7130
7280
|
import { Command as Command5 } from "commander";
|
|
7131
|
-
import * as
|
|
7281
|
+
import * as p19 from "@clack/prompts";
|
|
7132
7282
|
var schema = new Command5("schema").description("generate a schema from a model").argument("[model]", "model name").argument("[fields...]", "field definitions").option("--ai <description>", "design the schema with AI from a natural-language description").allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
7133
7283
|
(model, fields, options) => runCommand(async () => {
|
|
7134
7284
|
let argv;
|
|
@@ -7139,7 +7289,7 @@ var schema = new Command5("schema").description("generate a schema from a model"
|
|
|
7139
7289
|
}
|
|
7140
7290
|
const stage2 = await runSchemaStage({ prompt: options.ai, useCase: "schema" });
|
|
7141
7291
|
if (!stage2) {
|
|
7142
|
-
|
|
7292
|
+
p19.cancel("Aborted before any files were written.");
|
|
7143
7293
|
return;
|
|
7144
7294
|
}
|
|
7145
7295
|
argv = specToArgv(stage2.model);
|
|
@@ -7199,7 +7349,7 @@ var resource = new Command6("resource").description("generate a resource (model
|
|
|
7199
7349
|
|
|
7200
7350
|
// src/commands/generate/scaffold.ts
|
|
7201
7351
|
import { Command as Command7 } from "commander";
|
|
7202
|
-
import * as
|
|
7352
|
+
import * as p20 from "@clack/prompts";
|
|
7203
7353
|
var scaffold = new Command7("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(
|
|
7204
7354
|
"--route <route>",
|
|
7205
7355
|
'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.'
|
|
@@ -7226,12 +7376,12 @@ var scaffold = new Command7("scaffold").description("generate a full CRUD scaffo
|
|
|
7226
7376
|
}
|
|
7227
7377
|
const stage2 = await runSchemaStage({ prompt: options.ai, useCase: "scaffold" });
|
|
7228
7378
|
if (!stage2) {
|
|
7229
|
-
|
|
7379
|
+
p20.cancel("Aborted before any files were written.");
|
|
7230
7380
|
return;
|
|
7231
7381
|
}
|
|
7232
7382
|
const layout = await runLayoutStage(stage2.workspaceRootDir, stage2.model);
|
|
7233
7383
|
if (!layout) {
|
|
7234
|
-
|
|
7384
|
+
p20.cancel("Aborted before any files were written.");
|
|
7235
7385
|
return;
|
|
7236
7386
|
}
|
|
7237
7387
|
argv = specToArgv(stage2.model);
|
|
@@ -7247,7 +7397,7 @@ var scaffold = new Command7("scaffold").description("generate a full CRUD scaffo
|
|
|
7247
7397
|
const { workspaceRootDir, features } = await getWorkspace();
|
|
7248
7398
|
const formInput = resolveFormInput(workspaceRootDir, features.ui, options.ui);
|
|
7249
7399
|
if (features.ui === "plain" && !options.ui) {
|
|
7250
|
-
|
|
7400
|
+
p20.log.info("shadcn-svelte not detected: generating plain HTML pages.");
|
|
7251
7401
|
}
|
|
7252
7402
|
const slug2 = options.remote ? "generate-scaffold-remote" : "generate-scaffold";
|
|
7253
7403
|
const nextSteps = [
|
|
@@ -7535,7 +7685,7 @@ var apiKeys = new Command16("api-keys").description("enable API key management")
|
|
|
7535
7685
|
import process18 from "node:process";
|
|
7536
7686
|
import * as v6 from "valibot";
|
|
7537
7687
|
import { Command as Command17 } from "commander";
|
|
7538
|
-
import * as
|
|
7688
|
+
import * as p21 from "@clack/prompts";
|
|
7539
7689
|
import pc7 from "picocolors";
|
|
7540
7690
|
var optionsSchema3 = v6.strictObject({
|
|
7541
7691
|
email: emailFlag,
|
|
@@ -7582,7 +7732,7 @@ function backendNextSteps(ui2) {
|
|
|
7582
7732
|
];
|
|
7583
7733
|
}
|
|
7584
7734
|
async function initPocketbase(root, { email: email2, password: password8 }) {
|
|
7585
|
-
|
|
7735
|
+
p21.log.step("Initializing PocketBase...");
|
|
7586
7736
|
await upsertSuperuser(root, email2, password8);
|
|
7587
7737
|
upsertEnvFile(
|
|
7588
7738
|
root,
|
|
@@ -7592,21 +7742,21 @@ async function initPocketbase(root, { email: email2, password: password8 }) {
|
|
|
7592
7742
|
},
|
|
7593
7743
|
["PocketBase superuser credentials \u2014 used by `vela` commands"]
|
|
7594
7744
|
);
|
|
7595
|
-
|
|
7745
|
+
p21.log.success(`PocketBase initialized, credentials written to ${pc7.bold(".env")}`);
|
|
7596
7746
|
}
|
|
7597
7747
|
async function resolveCredentials(options) {
|
|
7598
7748
|
const decision = decideSuperuser(options, superuserFromEnv(), isInteractive());
|
|
7599
7749
|
if (decision.kind === "error") throw new Error(decision.message);
|
|
7600
7750
|
if (decision.kind === "use") {
|
|
7601
7751
|
if (decision.reused) {
|
|
7602
|
-
|
|
7752
|
+
p21.log.info(
|
|
7603
7753
|
`Using the superuser credentials already in your environment (${pc7.cyan(decision.credentials.email)}).`
|
|
7604
7754
|
);
|
|
7605
7755
|
}
|
|
7606
7756
|
return decision.credentials;
|
|
7607
7757
|
}
|
|
7608
7758
|
return promptSuperuser(decision.known, () => {
|
|
7609
|
-
|
|
7759
|
+
p21.cancel("Operation cancelled.");
|
|
7610
7760
|
process18.exit(0);
|
|
7611
7761
|
});
|
|
7612
7762
|
}
|
|
@@ -7668,7 +7818,7 @@ import fs35 from "node:fs";
|
|
|
7668
7818
|
import path35 from "node:path";
|
|
7669
7819
|
import process19 from "node:process";
|
|
7670
7820
|
import { Command as Command20 } from "commander";
|
|
7671
|
-
import * as
|
|
7821
|
+
import * as p22 from "@clack/prompts";
|
|
7672
7822
|
|
|
7673
7823
|
// src/lib/order-form.ts
|
|
7674
7824
|
import fs34 from "node:fs";
|
|
@@ -7817,7 +7967,7 @@ async function askBusiness(flags, currencyRequired) {
|
|
|
7817
7967
|
const ask = isInteractive();
|
|
7818
7968
|
if (!business.currency && !declared.currency) {
|
|
7819
7969
|
if (!ask) return business;
|
|
7820
|
-
business.currency = await
|
|
7970
|
+
business.currency = await text8({
|
|
7821
7971
|
message: "The currency the business prices in (ISO 4217)",
|
|
7822
7972
|
placeholder: "MXN, EUR, USD...",
|
|
7823
7973
|
validate: (value) => value && isCurrency(value) ? void 0 : currencyRequired || value ? "An ISO 4217 code, such as MXN or EUR" : void 0
|
|
@@ -7825,14 +7975,14 @@ async function askBusiness(flags, currencyRequired) {
|
|
|
7825
7975
|
}
|
|
7826
7976
|
const home = (business.currency ?? declared.currency ?? "").toUpperCase();
|
|
7827
7977
|
if (!business.country && !declared.country && ask) {
|
|
7828
|
-
business.country = await
|
|
7978
|
+
business.country = await text8({
|
|
7829
7979
|
message: "The country the business is in (ISO 3166-1, two letters), so prices format for it",
|
|
7830
7980
|
placeholder: "MX, ES, US...",
|
|
7831
7981
|
validate: (value) => !value || isCountry(value) ? void 0 : "A two-letter country code, such as MX"
|
|
7832
7982
|
});
|
|
7833
7983
|
}
|
|
7834
7984
|
if (business.currencies === void 0 && declared.currencies === void 0 && ask && home) {
|
|
7835
|
-
business.currencies = await
|
|
7985
|
+
business.currencies = await text8({
|
|
7836
7986
|
message: `Other currencies to show prices in, as estimates (comma-separated, blank for ${home} only)`,
|
|
7837
7987
|
placeholder: "USD, EUR",
|
|
7838
7988
|
validate: (value) => value && value.split(/[,\s]+/).some((code2) => code2 && !isCurrency(code2)) ? "ISO 4217 codes, comma-separated" : void 0
|
|
@@ -7844,10 +7994,10 @@ async function askBusiness(flags, currencyRequired) {
|
|
|
7844
7994
|
currencies: business.currencies ?? void 0
|
|
7845
7995
|
};
|
|
7846
7996
|
}
|
|
7847
|
-
async function
|
|
7848
|
-
const value = await
|
|
7849
|
-
if (
|
|
7850
|
-
|
|
7997
|
+
async function text8(options) {
|
|
7998
|
+
const value = await p22.text(options);
|
|
7999
|
+
if (p22.isCancel(value)) {
|
|
8000
|
+
p22.cancel("Operation cancelled.");
|
|
7851
8001
|
process19.exit(0);
|
|
7852
8002
|
}
|
|
7853
8003
|
return (value ?? "").trim() || void 0;
|
|
@@ -7865,7 +8015,7 @@ async function prepareOrderForm() {
|
|
|
7865
8015
|
}
|
|
7866
8016
|
function noteWebhookSecret() {
|
|
7867
8017
|
if (process19.env.STRIPE_WEBHOOK_SECRET || !isInteractive()) return;
|
|
7868
|
-
|
|
8018
|
+
p22.note(
|
|
7869
8019
|
[
|
|
7870
8020
|
"Download the Stripe CLI (https://stripe.com/docs/stripe-cli), then run:",
|
|
7871
8021
|
" stripe listen --forward-to localhost:5173/webhooks/stripe",
|
|
@@ -7877,15 +8027,15 @@ function noteWebhookSecret() {
|
|
|
7877
8027
|
}
|
|
7878
8028
|
async function askDemoId(provider) {
|
|
7879
8029
|
if (!isInteractive()) return "";
|
|
7880
|
-
const value = provider.id === "stripe" ? await
|
|
8030
|
+
const value = provider.id === "stripe" ? await p22.text({
|
|
7881
8031
|
message: "Stripe price_id for the demo page (price_...)",
|
|
7882
8032
|
placeholder: "leave blank to create a demo product"
|
|
7883
|
-
}) : await
|
|
8033
|
+
}) : await p22.text({
|
|
7884
8034
|
message: "Shopify product variant for the demo page (gid://shopify/ProductVariant/...)",
|
|
7885
8035
|
placeholder: "leave blank to skip the demo page"
|
|
7886
8036
|
});
|
|
7887
|
-
if (
|
|
7888
|
-
|
|
8037
|
+
if (p22.isCancel(value)) {
|
|
8038
|
+
p22.cancel("Operation cancelled.");
|
|
7889
8039
|
process19.exit(0);
|
|
7890
8040
|
}
|
|
7891
8041
|
return (value ?? "").trim();
|
|
@@ -8017,7 +8167,7 @@ var notifications = new Command24("notifications").description("enable in-app no
|
|
|
8017
8167
|
// src/commands/enable/cms.ts
|
|
8018
8168
|
import process20 from "node:process";
|
|
8019
8169
|
import { Command as Command25 } from "commander";
|
|
8020
|
-
import * as
|
|
8170
|
+
import * as p23 from "@clack/prompts";
|
|
8021
8171
|
import pc8 from "picocolors";
|
|
8022
8172
|
function resolveCmsBackend(facts) {
|
|
8023
8173
|
if (facts.endpoint) return { kind: "hosted", endpoint: facts.endpoint, from: "flag" };
|
|
@@ -8048,7 +8198,7 @@ var cms = new Command25("cms").description("enable an inline-editing CMS with an
|
|
|
8048
8198
|
projectId: readProjectConfig(root)?.projectId
|
|
8049
8199
|
});
|
|
8050
8200
|
if (backend3.kind === "none") {
|
|
8051
|
-
|
|
8201
|
+
p23.log.error(
|
|
8052
8202
|
`${pc8.cyan("vela enable cms")} needs somewhere to run the CMS backend, and this project has no Node server.
|
|
8053
8203
|
|
|
8054
8204
|
Any one of these gives it one:
|
|
@@ -8056,14 +8206,14 @@ Any one of these gives it one:
|
|
|
8056
8206
|
- ${pc8.cyan("vela enable cms --endpoint <url>")} to point at a hosted CMS yourself.
|
|
8057
8207
|
- ${pc8.cyan("vela enable backend")}, or switching to @sveltejs/adapter-node, to host it in this app.`
|
|
8058
8208
|
);
|
|
8059
|
-
|
|
8060
|
-
|
|
8209
|
+
p23.log.message();
|
|
8210
|
+
p23.cancel("Operation failed.");
|
|
8061
8211
|
process20.exitCode = 1;
|
|
8062
8212
|
return;
|
|
8063
8213
|
}
|
|
8064
8214
|
const hosted = backend3.kind === "hosted";
|
|
8065
8215
|
if (hosted && backend3.from === "link") {
|
|
8066
|
-
|
|
8216
|
+
p23.log.info(`Using the hosted CMS of the linked project (${pc8.cyan(backend3.endpoint)}).`);
|
|
8067
8217
|
}
|
|
8068
8218
|
const input = hosted ? { endpoint: backend3.endpoint } : { server: true };
|
|
8069
8219
|
await runPattern("enable-cms", cmd.args, input, {
|
|
@@ -8199,15 +8349,15 @@ import { Command as Command31 } from "commander";
|
|
|
8199
8349
|
|
|
8200
8350
|
// src/commands/disable/_shared.ts
|
|
8201
8351
|
import process22 from "node:process";
|
|
8202
|
-
import * as
|
|
8352
|
+
import * as p24 from "@clack/prompts";
|
|
8203
8353
|
async function runDisable(opts, flags, cmdArgs) {
|
|
8204
8354
|
if (!flags.yes) {
|
|
8205
|
-
const ok = await
|
|
8355
|
+
const ok = await p24.confirm({
|
|
8206
8356
|
message: opts.confirmMessage,
|
|
8207
8357
|
initialValue: false
|
|
8208
8358
|
});
|
|
8209
|
-
if (
|
|
8210
|
-
|
|
8359
|
+
if (p24.isCancel(ok) || !ok) {
|
|
8360
|
+
p24.cancel("Operation cancelled.");
|
|
8211
8361
|
process22.exit(0);
|
|
8212
8362
|
}
|
|
8213
8363
|
}
|
|
@@ -8641,12 +8791,12 @@ import { Command as Command47 } from "commander";
|
|
|
8641
8791
|
|
|
8642
8792
|
// src/commands/destroy/_shared.ts
|
|
8643
8793
|
import process23 from "node:process";
|
|
8644
|
-
import * as
|
|
8794
|
+
import * as p25 from "@clack/prompts";
|
|
8645
8795
|
async function runDestroy(slug2, model, confirmMessage, report5, flags) {
|
|
8646
8796
|
if (!flags.yes) {
|
|
8647
|
-
const ok = await
|
|
8648
|
-
if (
|
|
8649
|
-
|
|
8797
|
+
const ok = await p25.confirm({ message: confirmMessage, initialValue: false });
|
|
8798
|
+
if (p25.isCancel(ok) || !ok) {
|
|
8799
|
+
p25.cancel("Operation cancelled.");
|
|
8650
8800
|
process23.exit(0);
|
|
8651
8801
|
}
|
|
8652
8802
|
}
|
|
@@ -8752,13 +8902,13 @@ var scaffold2 = new Command50("scaffold").description("destroy a scaffold genera
|
|
|
8752
8902
|
// src/commands/destroy/deployment.ts
|
|
8753
8903
|
import process27 from "node:process";
|
|
8754
8904
|
import { Command as Command51 } from "commander";
|
|
8755
|
-
import * as
|
|
8905
|
+
import * as p29 from "@clack/prompts";
|
|
8756
8906
|
import pc12 from "picocolors";
|
|
8757
8907
|
|
|
8758
8908
|
// src/lib/server-command.ts
|
|
8759
8909
|
import process26 from "node:process";
|
|
8760
8910
|
import * as v8 from "valibot";
|
|
8761
|
-
import * as
|
|
8911
|
+
import * as p26 from "@clack/prompts";
|
|
8762
8912
|
import pc9 from "picocolors";
|
|
8763
8913
|
|
|
8764
8914
|
// src/lib/deploy-config.ts
|
|
@@ -9598,8 +9748,8 @@ function describeTarget(target) {
|
|
|
9598
9748
|
return target.name;
|
|
9599
9749
|
}
|
|
9600
9750
|
}
|
|
9601
|
-
function bold(
|
|
9602
|
-
return `\`${
|
|
9751
|
+
function bold(text20) {
|
|
9752
|
+
return `\`${text20}\``;
|
|
9603
9753
|
}
|
|
9604
9754
|
|
|
9605
9755
|
// src/lib/server-command.ts
|
|
@@ -9696,7 +9846,7 @@ async function ensureBinding(workspaceRootDir, target, request = {}) {
|
|
|
9696
9846
|
writeBinding(workspaceRootDir, key, binding);
|
|
9697
9847
|
}
|
|
9698
9848
|
if (moving) {
|
|
9699
|
-
|
|
9849
|
+
p26.log.warn(
|
|
9700
9850
|
`${pc9.cyan(bindingName(target))} now points at ${pc9.cyan(server)}.
|
|
9701
9851
|
|
|
9702
9852
|
Whatever is running on ${existing.server} is left there, and this project can no
|
|
@@ -9715,12 +9865,12 @@ Drop ${pc9.cyan("--server")} to use the recorded one, or move the binding on pur
|
|
|
9715
9865
|
this command once from a terminal (or editing .vela/project.json).`
|
|
9716
9866
|
);
|
|
9717
9867
|
}
|
|
9718
|
-
const ok = await
|
|
9868
|
+
const ok = await p26.confirm({
|
|
9719
9869
|
message: `${name} ${target.kind === "preview" ? "run" : "runs"} on ${from}. Point ${name} at ${to} instead?`,
|
|
9720
9870
|
initialValue: false
|
|
9721
9871
|
});
|
|
9722
|
-
if (
|
|
9723
|
-
|
|
9872
|
+
if (p26.isCancel(ok) || !ok) {
|
|
9873
|
+
p26.cancel("Operation cancelled.");
|
|
9724
9874
|
process26.exit(0);
|
|
9725
9875
|
}
|
|
9726
9876
|
}
|
|
@@ -9737,28 +9887,28 @@ Pass ${pc9.cyan("--server user@host")}, or run the command once from your own ma
|
|
|
9737
9887
|
and commit ${pc9.cyan(".vela/project.json")}.`
|
|
9738
9888
|
);
|
|
9739
9889
|
}
|
|
9740
|
-
|
|
9890
|
+
p26.log.info(
|
|
9741
9891
|
`${pc9.cyan(name)} ${target.kind === "preview" ? "are" : "is"} not bound to a server yet.`
|
|
9742
9892
|
);
|
|
9743
|
-
const value = await
|
|
9893
|
+
const value = await p26.text({
|
|
9744
9894
|
message: `Which server should ${name} run on?`,
|
|
9745
9895
|
placeholder: "root@203.0.113.10",
|
|
9746
9896
|
validate: (input) => input?.trim() ? void 0 : "An ssh_config alias, or user@host"
|
|
9747
9897
|
});
|
|
9748
|
-
if (
|
|
9749
|
-
|
|
9898
|
+
if (p26.isCancel(value)) {
|
|
9899
|
+
p26.cancel("Operation cancelled.");
|
|
9750
9900
|
process26.exit(0);
|
|
9751
9901
|
}
|
|
9752
9902
|
return value.trim();
|
|
9753
9903
|
}
|
|
9754
9904
|
async function promptDomain(target) {
|
|
9755
9905
|
if (!process26.stdout.isTTY || process26.env.CI) return void 0;
|
|
9756
|
-
const value = await
|
|
9906
|
+
const value = await p26.text({
|
|
9757
9907
|
message: `Which hostname should ${target.name} be served on?`,
|
|
9758
9908
|
placeholder: "example.com \u2014 leave blank to decide later"
|
|
9759
9909
|
});
|
|
9760
|
-
if (
|
|
9761
|
-
|
|
9910
|
+
if (p26.isCancel(value)) {
|
|
9911
|
+
p26.cancel("Operation cancelled.");
|
|
9762
9912
|
process26.exit(0);
|
|
9763
9913
|
}
|
|
9764
9914
|
return value.trim() || void 0;
|
|
@@ -9767,10 +9917,10 @@ async function applyRestart(ctx) {
|
|
|
9767
9917
|
const outcome = await restartInstance(ctx.session, ctx.instance);
|
|
9768
9918
|
if (!outcome.deployed) return;
|
|
9769
9919
|
if (outcome.restarted) {
|
|
9770
|
-
|
|
9920
|
+
p26.log.success("App restarted");
|
|
9771
9921
|
return;
|
|
9772
9922
|
}
|
|
9773
|
-
|
|
9923
|
+
p26.log.error(
|
|
9774
9924
|
`App restart failed.
|
|
9775
9925
|
|
|
9776
9926
|
The new value is stored and will be used the next time the app starts.
|
|
@@ -9779,7 +9929,7 @@ ${pc9.dim(outcome.error ?? "")}`
|
|
|
9779
9929
|
}
|
|
9780
9930
|
async function applyEnvRestart(ctx, changed) {
|
|
9781
9931
|
if (touchesSuperuser(changed)) {
|
|
9782
|
-
|
|
9932
|
+
p26.log.warn(
|
|
9783
9933
|
`PocketBase superuser credentials changed.
|
|
9784
9934
|
|
|
9785
9935
|
The database still holds the old ones, so the app has not been restarted.
|
|
@@ -9856,11 +10006,11 @@ function describe({ appName, envTag, purge }) {
|
|
|
9856
10006
|
}
|
|
9857
10007
|
|
|
9858
10008
|
// src/lib/deploy-report.ts
|
|
9859
|
-
import * as
|
|
10009
|
+
import * as p28 from "@clack/prompts";
|
|
9860
10010
|
import pc11 from "picocolors";
|
|
9861
10011
|
|
|
9862
10012
|
// src/lib/server-identity.ts
|
|
9863
|
-
import * as
|
|
10013
|
+
import * as p27 from "@clack/prompts";
|
|
9864
10014
|
import pc10 from "picocolors";
|
|
9865
10015
|
var IPV4 = /^\d{1,3}(?:\.\d{1,3}){3}$/;
|
|
9866
10016
|
async function ensureServerIdentity(session, apiKey) {
|
|
@@ -9874,7 +10024,7 @@ async function ensureServerIdentity(session, apiKey) {
|
|
|
9874
10024
|
if (!existing || existing.serverId !== registered.serverId || existing.originHost !== registered.originHost || existing.token !== registered.token) {
|
|
9875
10025
|
await writeServerIdentity(session, registered);
|
|
9876
10026
|
if (existing) {
|
|
9877
|
-
|
|
10027
|
+
p27.log.info(`${pc10.cyan(session.target)} was re-registered with velastack.dev.`);
|
|
9878
10028
|
}
|
|
9879
10029
|
}
|
|
9880
10030
|
await runServerScript(session, "origin.sh");
|
|
@@ -9914,7 +10064,7 @@ function createDeployReporter(workspaceRootDir) {
|
|
|
9914
10064
|
const link2 = readProjectConfig(workspaceRootDir);
|
|
9915
10065
|
const apiKey = link2 ? readApiKey() : null;
|
|
9916
10066
|
if (link2 && !apiKey) {
|
|
9917
|
-
|
|
10067
|
+
p28.log.warn(
|
|
9918
10068
|
`This project is linked to ${pc11.cyan(link2.projectName)} on velastack.dev, but there is no
|
|
9919
10069
|
API key here, so this deploy will not be recorded. Run ${pc11.cyan("vela login")}, or set
|
|
9920
10070
|
${pc11.cyan("VELA_API_KEY")}.`
|
|
@@ -9965,7 +10115,7 @@ async function reportEnvironmentDestroyed(workspaceRootDir, envTag, { missingOk
|
|
|
9965
10115
|
}
|
|
9966
10116
|
}
|
|
9967
10117
|
function warn(what, err) {
|
|
9968
|
-
|
|
10118
|
+
p28.log.warn(
|
|
9969
10119
|
`velastack.dev could not ${what}.
|
|
9970
10120
|
${pc11.dim(err instanceof Error ? err.message : String(err))}`
|
|
9971
10121
|
);
|
|
@@ -10013,13 +10163,13 @@ var deployment = addLockWaitOption(
|
|
|
10013
10163
|
missingOk: true
|
|
10014
10164
|
});
|
|
10015
10165
|
}
|
|
10016
|
-
|
|
10166
|
+
p29.log.info(
|
|
10017
10167
|
`Nothing named ${pc12.cyan(`${ctx.appName} (${ctx.targetName})`)} on ${ctx.server}; nothing to remove.`
|
|
10018
10168
|
);
|
|
10019
10169
|
return;
|
|
10020
10170
|
}
|
|
10021
10171
|
await reportEnvironmentDestroyed(ctx.workspaceRootDir, ctx.envTag);
|
|
10022
|
-
|
|
10172
|
+
p29.log.success(
|
|
10023
10173
|
`Removed ${pc12.cyan(`${ctx.appName} (${ctx.targetName})`)} from ${ctx.server}.` + (result?.purged ? result.trash ? `
|
|
10024
10174
|
|
|
10025
10175
|
A snapshot of its data is at ${pc12.cyan(result.trash)} on the server for two weeks.` : "" : `
|
|
@@ -10037,22 +10187,22 @@ The database and uploads are still in the instance's shared directory. Pass ${pc
|
|
|
10037
10187
|
);
|
|
10038
10188
|
async function confirm6(appName, targetName, byName) {
|
|
10039
10189
|
if (byName) {
|
|
10040
|
-
const answer = await
|
|
10190
|
+
const answer = await p29.text({
|
|
10041
10191
|
message: `This removes ${pc12.cyan(`${appName} (${targetName})`)}. Type the app name to confirm`,
|
|
10042
10192
|
validate: (value) => value === appName ? void 0 : `Type ${appName} to confirm`
|
|
10043
10193
|
});
|
|
10044
|
-
if (
|
|
10045
|
-
|
|
10194
|
+
if (p29.isCancel(answer)) {
|
|
10195
|
+
p29.cancel("Operation cancelled.");
|
|
10046
10196
|
process27.exit(0);
|
|
10047
10197
|
}
|
|
10048
10198
|
return;
|
|
10049
10199
|
}
|
|
10050
|
-
const ok = await
|
|
10200
|
+
const ok = await p29.confirm({
|
|
10051
10201
|
message: `Remove ${appName} (${targetName})?`,
|
|
10052
10202
|
initialValue: false
|
|
10053
10203
|
});
|
|
10054
|
-
if (
|
|
10055
|
-
|
|
10204
|
+
if (p29.isCancel(ok) || !ok) {
|
|
10205
|
+
p29.cancel("Operation cancelled.");
|
|
10056
10206
|
process27.exit(0);
|
|
10057
10207
|
}
|
|
10058
10208
|
}
|
|
@@ -10060,16 +10210,16 @@ async function confirm6(appName, targetName, byName) {
|
|
|
10060
10210
|
// src/commands/destroy/shop.ts
|
|
10061
10211
|
import process28 from "node:process";
|
|
10062
10212
|
import { Command as Command52 } from "commander";
|
|
10063
|
-
import * as
|
|
10213
|
+
import * as p30 from "@clack/prompts";
|
|
10064
10214
|
var shop2 = new Command52("shop").description("destroy the shop pages generated by `vela generate shop`").option("-y, --yes", "skip confirmation prompt").allowExcessArguments(true).configureHelp(helpConfig).action(
|
|
10065
10215
|
(opts, cmd) => runCommand(async () => {
|
|
10066
10216
|
if (!opts.yes) {
|
|
10067
|
-
const ok = await
|
|
10217
|
+
const ok = await p30.confirm({
|
|
10068
10218
|
message: "Destroy the shop? Removes the listing and product pages (and src/lib/catalog.ts on WhatsApp). The cart and payments stay.",
|
|
10069
10219
|
initialValue: false
|
|
10070
10220
|
});
|
|
10071
|
-
if (
|
|
10072
|
-
|
|
10221
|
+
if (p30.isCancel(ok) || !ok) {
|
|
10222
|
+
p30.cancel("Operation cancelled.");
|
|
10073
10223
|
process28.exit(0);
|
|
10074
10224
|
}
|
|
10075
10225
|
}
|
|
@@ -10097,7 +10247,7 @@ import { Command as Command59 } from "commander";
|
|
|
10097
10247
|
|
|
10098
10248
|
// src/commands/ui/add.ts
|
|
10099
10249
|
import { Command as Command54 } from "commander";
|
|
10100
|
-
import * as
|
|
10250
|
+
import * as p31 from "@clack/prompts";
|
|
10101
10251
|
import { installComponents } from "@velastack/patterns";
|
|
10102
10252
|
|
|
10103
10253
|
// src/lib/ui-add.ts
|
|
@@ -10150,18 +10300,18 @@ var add = new Command54("add").description("add ui components (shadcn-svelte ite
|
|
|
10150
10300
|
(components, options) => runCommand(async () => {
|
|
10151
10301
|
const { workspaceRootDir } = await getWorkspace();
|
|
10152
10302
|
assertShadcn("vela ui add", workspaceRootDir);
|
|
10153
|
-
const
|
|
10303
|
+
const log58 = p31.taskLog({ title: "Adding UI components..." });
|
|
10154
10304
|
let outcome;
|
|
10155
10305
|
try {
|
|
10156
10306
|
outcome = await installComponents({
|
|
10157
10307
|
root: workspaceRootDir,
|
|
10158
10308
|
components,
|
|
10159
10309
|
overwrite: options.overwrite,
|
|
10160
|
-
logger: { info: (message) =>
|
|
10310
|
+
logger: { info: (message) => log58.message(message) }
|
|
10161
10311
|
});
|
|
10162
|
-
|
|
10312
|
+
log58.success("UI components ready");
|
|
10163
10313
|
} catch (e) {
|
|
10164
|
-
|
|
10314
|
+
log58.error("Could not add UI components");
|
|
10165
10315
|
throw e;
|
|
10166
10316
|
}
|
|
10167
10317
|
reportResult(uiAddReport(components, outcome));
|
|
@@ -10170,19 +10320,19 @@ var add = new Command54("add").description("add ui components (shadcn-svelte ite
|
|
|
10170
10320
|
|
|
10171
10321
|
// src/commands/ui/base.ts
|
|
10172
10322
|
import { Command as Command55 } from "commander";
|
|
10173
|
-
import * as
|
|
10323
|
+
import * as p32 from "@clack/prompts";
|
|
10174
10324
|
import { applyBaseColor } from "@velastack/patterns";
|
|
10175
10325
|
var base = new Command55("base").description("change the base (gray) palette").argument("<color>", `base color to use (${BASE_COLORS.join(", ")})`).configureHelp(helpConfig).action(
|
|
10176
10326
|
(color) => runCommand(async () => {
|
|
10177
10327
|
const { workspaceRootDir } = await getWorkspace();
|
|
10178
10328
|
assertShadcn("vela ui base", workspaceRootDir);
|
|
10179
|
-
const
|
|
10329
|
+
const log58 = p32.taskLog({ title: `Applying the ${color} palette...` });
|
|
10180
10330
|
let outcome;
|
|
10181
10331
|
try {
|
|
10182
10332
|
outcome = await applyBaseColor({ root: workspaceRootDir, color });
|
|
10183
|
-
|
|
10333
|
+
log58.success("Palette applied");
|
|
10184
10334
|
} catch (e) {
|
|
10185
|
-
|
|
10335
|
+
log58.error("Could not change the base color");
|
|
10186
10336
|
throw e;
|
|
10187
10337
|
}
|
|
10188
10338
|
reportResult({
|
|
@@ -10199,7 +10349,7 @@ var base = new Command55("base").description("change the base (gray) palette").a
|
|
|
10199
10349
|
|
|
10200
10350
|
// src/commands/ui/list.ts
|
|
10201
10351
|
import { Command as Command56 } from "commander";
|
|
10202
|
-
import * as
|
|
10352
|
+
import * as p33 from "@clack/prompts";
|
|
10203
10353
|
import { listComponents } from "@velastack/patterns";
|
|
10204
10354
|
|
|
10205
10355
|
// src/lib/ui-list.ts
|
|
@@ -10239,7 +10389,7 @@ var list = new Command56("list").description("list installed ui components, vela
|
|
|
10239
10389
|
console.log(JSON.stringify(result2, null, 2));
|
|
10240
10390
|
return;
|
|
10241
10391
|
}
|
|
10242
|
-
const spinner9 =
|
|
10392
|
+
const spinner9 = p33.spinner();
|
|
10243
10393
|
spinner9.start("Reading the registry...");
|
|
10244
10394
|
let result;
|
|
10245
10395
|
try {
|
|
@@ -10251,7 +10401,7 @@ var list = new Command56("list").description("list installed ui components, vela
|
|
|
10251
10401
|
spinner9.stop(`Read the ${result.style} registry`);
|
|
10252
10402
|
reportResult(uiListReport(result));
|
|
10253
10403
|
if (result.registryUnavailable) {
|
|
10254
|
-
|
|
10404
|
+
p33.log.warn(`${result.registryUnavailable}
|
|
10255
10405
|
Registry components are not listed.`);
|
|
10256
10406
|
}
|
|
10257
10407
|
}, "Failed to list UI components.")
|
|
@@ -10259,7 +10409,7 @@ Registry components are not listed.`);
|
|
|
10259
10409
|
|
|
10260
10410
|
// src/commands/ui/style.ts
|
|
10261
10411
|
import { Command as Command57 } from "commander";
|
|
10262
|
-
import * as
|
|
10412
|
+
import * as p34 from "@clack/prompts";
|
|
10263
10413
|
import { switchStyle } from "@velastack/patterns";
|
|
10264
10414
|
|
|
10265
10415
|
// src/lib/ui-style.ts
|
|
@@ -10289,70 +10439,70 @@ var style = new Command57("style").description("switch the shadcn-svelte style,
|
|
|
10289
10439
|
(name, options) => runCommand(async () => {
|
|
10290
10440
|
const { workspaceRootDir } = await getWorkspace();
|
|
10291
10441
|
assertShadcn("vela ui style", workspaceRootDir);
|
|
10292
|
-
const spinner9 =
|
|
10442
|
+
const spinner9 = p34.spinner();
|
|
10293
10443
|
spinner9.start(`Reading the ${name} registry...`);
|
|
10294
|
-
let
|
|
10444
|
+
let log58;
|
|
10295
10445
|
let outcome;
|
|
10296
10446
|
try {
|
|
10297
10447
|
outcome = await switchStyle({
|
|
10298
10448
|
root: workspaceRootDir,
|
|
10299
10449
|
style: name,
|
|
10300
10450
|
font: options.font,
|
|
10301
|
-
logger: { info: (message) =>
|
|
10451
|
+
logger: { info: (message) => log58?.message(message) },
|
|
10302
10452
|
confirm: async (components) => {
|
|
10303
10453
|
spinner9.stop(`Read the ${name} registry`);
|
|
10304
10454
|
if (components.length > 0) {
|
|
10305
|
-
|
|
10455
|
+
p34.log.info(
|
|
10306
10456
|
`Re-adds ${components.length} component(s) from the ${name} registry; local edits to their files are lost:
|
|
10307
10457
|
${components.map((c) => `- ${c}`).join("\n")}`
|
|
10308
10458
|
);
|
|
10309
10459
|
} else {
|
|
10310
|
-
|
|
10460
|
+
p34.log.info(
|
|
10311
10461
|
`No installed component comes from the registry; only the config changes.`
|
|
10312
10462
|
);
|
|
10313
10463
|
}
|
|
10314
10464
|
if (!options.yes) {
|
|
10315
|
-
const ok = await
|
|
10316
|
-
if (
|
|
10465
|
+
const ok = await p34.confirm({ message: `Switch to ${name}?`, initialValue: false });
|
|
10466
|
+
if (p34.isCancel(ok) || !ok) return false;
|
|
10317
10467
|
}
|
|
10318
|
-
|
|
10468
|
+
log58 = p34.taskLog({ title: `Switching to the ${name} style...` });
|
|
10319
10469
|
return true;
|
|
10320
10470
|
}
|
|
10321
10471
|
});
|
|
10322
10472
|
} catch (e) {
|
|
10323
10473
|
spinner9.stop(`Could not switch to ${name}`);
|
|
10324
|
-
|
|
10474
|
+
log58?.error("Could not switch style");
|
|
10325
10475
|
throw e;
|
|
10326
10476
|
}
|
|
10327
10477
|
spinner9.stop(`Read the ${name} registry`);
|
|
10328
10478
|
if (outcome.status === "unchanged") {
|
|
10329
|
-
|
|
10479
|
+
p34.log.info(`Already using the ${name} style.`);
|
|
10330
10480
|
return;
|
|
10331
10481
|
}
|
|
10332
10482
|
if (outcome.status === "cancelled") {
|
|
10333
|
-
|
|
10483
|
+
p34.cancel("Operation cancelled.");
|
|
10334
10484
|
return;
|
|
10335
10485
|
}
|
|
10336
|
-
|
|
10486
|
+
log58?.success("Style switched");
|
|
10337
10487
|
reportResult(uiStyleReport(outcome));
|
|
10338
10488
|
}, "Failed to switch style.")
|
|
10339
10489
|
);
|
|
10340
10490
|
|
|
10341
10491
|
// src/commands/ui/theme.ts
|
|
10342
10492
|
import { Command as Command58 } from "commander";
|
|
10343
|
-
import * as
|
|
10493
|
+
import * as p35 from "@clack/prompts";
|
|
10344
10494
|
import { applyTheme } from "@velastack/patterns";
|
|
10345
10495
|
var theme = new Command58("theme").description("change the accent color, keeping the base palette").argument("<accent>", `accent to use (${THEMES.join(", ")})`).configureHelp(helpConfig).action(
|
|
10346
10496
|
(accent) => runCommand(async () => {
|
|
10347
10497
|
const { workspaceRootDir } = await getWorkspace();
|
|
10348
10498
|
assertShadcn("vela ui theme", workspaceRootDir);
|
|
10349
|
-
const
|
|
10499
|
+
const log58 = p35.taskLog({ title: `Applying the ${accent} accent...` });
|
|
10350
10500
|
let outcome;
|
|
10351
10501
|
try {
|
|
10352
10502
|
outcome = await applyTheme({ root: workspaceRootDir, theme: accent });
|
|
10353
|
-
|
|
10503
|
+
log58.success("Accent applied");
|
|
10354
10504
|
} catch (e) {
|
|
10355
|
-
|
|
10505
|
+
log58.error("Could not change the accent");
|
|
10356
10506
|
throw e;
|
|
10357
10507
|
}
|
|
10358
10508
|
reportResult({
|
|
@@ -10376,17 +10526,17 @@ import { Command as Command62 } from "commander";
|
|
|
10376
10526
|
// src/commands/legal/terms.ts
|
|
10377
10527
|
import path41 from "node:path";
|
|
10378
10528
|
import { Command as Command60 } from "commander";
|
|
10379
|
-
import * as
|
|
10529
|
+
import * as p37 from "@clack/prompts";
|
|
10380
10530
|
|
|
10381
10531
|
// src/commands/legal/shared.ts
|
|
10382
10532
|
import process29 from "node:process";
|
|
10383
10533
|
import fs41 from "node:fs";
|
|
10384
10534
|
import path40 from "node:path";
|
|
10385
|
-
import * as
|
|
10535
|
+
import * as p36 from "@clack/prompts";
|
|
10386
10536
|
function siteFields(site) {
|
|
10387
10537
|
const url = site?.url && !isLocalUrl(site.url) ? site.url : void 0;
|
|
10388
10538
|
return {
|
|
10389
|
-
websiteUrl: () =>
|
|
10539
|
+
websiteUrl: () => p36.text({
|
|
10390
10540
|
message: "What is your website URL?",
|
|
10391
10541
|
placeholder: "http://www.mysite.com",
|
|
10392
10542
|
initialValue: url,
|
|
@@ -10396,7 +10546,7 @@ function siteFields(site) {
|
|
|
10396
10546
|
}
|
|
10397
10547
|
}
|
|
10398
10548
|
}),
|
|
10399
|
-
websiteName: () =>
|
|
10549
|
+
websiteName: () => p36.text({
|
|
10400
10550
|
message: "What is your website name?",
|
|
10401
10551
|
placeholder: "My Site",
|
|
10402
10552
|
initialValue: site?.name,
|
|
@@ -10409,7 +10559,7 @@ function siteFields(site) {
|
|
|
10409
10559
|
};
|
|
10410
10560
|
}
|
|
10411
10561
|
var sharedFields = {
|
|
10412
|
-
entityType: () =>
|
|
10562
|
+
entityType: () => p36.select({
|
|
10413
10563
|
message: "Entity type",
|
|
10414
10564
|
options: [
|
|
10415
10565
|
{
|
|
@@ -10420,7 +10570,7 @@ var sharedFields = {
|
|
|
10420
10570
|
{ value: "individual", label: "I'm an Individual" }
|
|
10421
10571
|
]
|
|
10422
10572
|
}),
|
|
10423
|
-
businessName: ({ results }) => results?.entityType === "business" ?
|
|
10573
|
+
businessName: ({ results }) => results?.entityType === "business" ? p36.text({
|
|
10424
10574
|
message: "What is the name of the business?",
|
|
10425
10575
|
placeholder: "My Company LLC",
|
|
10426
10576
|
validate: (value) => {
|
|
@@ -10429,7 +10579,7 @@ var sharedFields = {
|
|
|
10429
10579
|
}
|
|
10430
10580
|
}
|
|
10431
10581
|
}) : void 0,
|
|
10432
|
-
businessAddress: ({ results }) => results?.entityType === "business" ?
|
|
10582
|
+
businessAddress: ({ results }) => results?.entityType === "business" ? p36.text({
|
|
10433
10583
|
message: "What is the address of the business?",
|
|
10434
10584
|
placeholder: "1 Cupertino, CA 95014",
|
|
10435
10585
|
validate: (value) => {
|
|
@@ -10438,7 +10588,7 @@ var sharedFields = {
|
|
|
10438
10588
|
}
|
|
10439
10589
|
}
|
|
10440
10590
|
}) : void 0,
|
|
10441
|
-
country: () =>
|
|
10591
|
+
country: () => p36.text({
|
|
10442
10592
|
message: "Enter the country",
|
|
10443
10593
|
validate: (value) => {
|
|
10444
10594
|
if (!value) {
|
|
@@ -10446,7 +10596,7 @@ var sharedFields = {
|
|
|
10446
10596
|
}
|
|
10447
10597
|
}
|
|
10448
10598
|
}),
|
|
10449
|
-
state: () =>
|
|
10599
|
+
state: () => p36.text({
|
|
10450
10600
|
message: "Enter the state",
|
|
10451
10601
|
validate: (value) => {
|
|
10452
10602
|
if (!value) {
|
|
@@ -10456,11 +10606,11 @@ var sharedFields = {
|
|
|
10456
10606
|
})
|
|
10457
10607
|
};
|
|
10458
10608
|
var onCancel = () => {
|
|
10459
|
-
|
|
10609
|
+
p36.cancel("Operation cancelled.");
|
|
10460
10610
|
process29.exit(0);
|
|
10461
10611
|
};
|
|
10462
10612
|
async function contactMethods(type) {
|
|
10463
|
-
const selection = await
|
|
10613
|
+
const selection = await p36.multiselect({
|
|
10464
10614
|
message: `How can users contact you for any questions regarding your ${type === "privacy" ? "Privacy Policy" : "Terms & Conditions"}? Check all that apply`,
|
|
10465
10615
|
options: [
|
|
10466
10616
|
{ value: "email", label: "By email" },
|
|
@@ -10469,11 +10619,11 @@ async function contactMethods(type) {
|
|
|
10469
10619
|
{ value: "mail", label: "By sending post mail" }
|
|
10470
10620
|
]
|
|
10471
10621
|
});
|
|
10472
|
-
if (
|
|
10622
|
+
if (p36.isCancel(selection)) onCancel();
|
|
10473
10623
|
const contact = selection;
|
|
10474
10624
|
const details = {};
|
|
10475
10625
|
if (contact.includes("email")) {
|
|
10476
|
-
const email2 = await
|
|
10626
|
+
const email2 = await p36.text({
|
|
10477
10627
|
message: "What's the email?",
|
|
10478
10628
|
placeholder: "office@mycompany.com",
|
|
10479
10629
|
validate: (value) => {
|
|
@@ -10482,11 +10632,11 @@ async function contactMethods(type) {
|
|
|
10482
10632
|
}
|
|
10483
10633
|
}
|
|
10484
10634
|
});
|
|
10485
|
-
if (
|
|
10635
|
+
if (p36.isCancel(email2)) onCancel();
|
|
10486
10636
|
details.email = email2;
|
|
10487
10637
|
}
|
|
10488
10638
|
if (contact.includes("page")) {
|
|
10489
|
-
const page = await
|
|
10639
|
+
const page = await p36.text({
|
|
10490
10640
|
message: "What's the link?",
|
|
10491
10641
|
placeholder: "http://www.mycompany.com/contact",
|
|
10492
10642
|
validate: (value) => {
|
|
@@ -10495,11 +10645,11 @@ async function contactMethods(type) {
|
|
|
10495
10645
|
}
|
|
10496
10646
|
}
|
|
10497
10647
|
});
|
|
10498
|
-
if (
|
|
10648
|
+
if (p36.isCancel(page)) onCancel();
|
|
10499
10649
|
details.page = page;
|
|
10500
10650
|
}
|
|
10501
10651
|
if (contact.includes("phone")) {
|
|
10502
|
-
const phone = await
|
|
10652
|
+
const phone = await p36.text({
|
|
10503
10653
|
message: "What's the phone number?",
|
|
10504
10654
|
placeholder: "408.996.1010",
|
|
10505
10655
|
validate: (value) => {
|
|
@@ -10508,11 +10658,11 @@ async function contactMethods(type) {
|
|
|
10508
10658
|
}
|
|
10509
10659
|
}
|
|
10510
10660
|
});
|
|
10511
|
-
if (
|
|
10661
|
+
if (p36.isCancel(phone)) onCancel();
|
|
10512
10662
|
details.phone = phone;
|
|
10513
10663
|
}
|
|
10514
10664
|
if (contact.includes("mail")) {
|
|
10515
|
-
const address = await
|
|
10665
|
+
const address = await p36.text({
|
|
10516
10666
|
message: "What's the address?",
|
|
10517
10667
|
placeholder: "767 Fifth Avenue New York, NY 10153, United States",
|
|
10518
10668
|
validate: (value) => {
|
|
@@ -10521,7 +10671,7 @@ async function contactMethods(type) {
|
|
|
10521
10671
|
}
|
|
10522
10672
|
}
|
|
10523
10673
|
});
|
|
10524
|
-
if (
|
|
10674
|
+
if (p36.isCancel(address)) onCancel();
|
|
10525
10675
|
details.address = address;
|
|
10526
10676
|
}
|
|
10527
10677
|
return { methods: contact, details };
|
|
@@ -10942,7 +11092,7 @@ var generateTermsHtml = (answers) => {
|
|
|
10942
11092
|
async function termsAction() {
|
|
10943
11093
|
const { workspaceRootDir, publicRoutesDir } = await getWorkspace();
|
|
10944
11094
|
const site = siteFields(await readSite(workspaceRootDir));
|
|
10945
|
-
const core = await
|
|
11095
|
+
const core = await p37.group(
|
|
10946
11096
|
{
|
|
10947
11097
|
websiteUrl: site.websiteUrl,
|
|
10948
11098
|
websiteName: site.websiteName,
|
|
@@ -10954,25 +11104,25 @@ async function termsAction() {
|
|
|
10954
11104
|
},
|
|
10955
11105
|
{ onCancel }
|
|
10956
11106
|
);
|
|
10957
|
-
const accounts = await
|
|
11107
|
+
const accounts = await p37.select({
|
|
10958
11108
|
message: "Can users create accounts?",
|
|
10959
11109
|
options: [
|
|
10960
11110
|
{ value: "yes", label: "Yes, users can create accounts" },
|
|
10961
11111
|
{ value: "no", label: "No" }
|
|
10962
11112
|
]
|
|
10963
11113
|
});
|
|
10964
|
-
if (
|
|
10965
|
-
const userContent = await
|
|
11114
|
+
if (p37.isCancel(accounts)) onCancel();
|
|
11115
|
+
const userContent = await p37.select({
|
|
10966
11116
|
message: "Can users create and/or upload content (ie. text, images)?",
|
|
10967
11117
|
options: [
|
|
10968
11118
|
{ value: "yes", label: "Yes, users can create and/or upload content" },
|
|
10969
11119
|
{ value: "no", label: "No" }
|
|
10970
11120
|
]
|
|
10971
11121
|
});
|
|
10972
|
-
if (
|
|
11122
|
+
if (p37.isCancel(userContent)) onCancel();
|
|
10973
11123
|
let infringementEmail;
|
|
10974
11124
|
if (userContent === "yes") {
|
|
10975
|
-
const email2 = await
|
|
11125
|
+
const email2 = await p37.text({
|
|
10976
11126
|
message: "What's the email address where you will receive infringements notices?",
|
|
10977
11127
|
placeholder: "dmca@website.com",
|
|
10978
11128
|
validate: (value) => {
|
|
@@ -10981,10 +11131,10 @@ async function termsAction() {
|
|
|
10981
11131
|
}
|
|
10982
11132
|
}
|
|
10983
11133
|
});
|
|
10984
|
-
if (
|
|
11134
|
+
if (p37.isCancel(email2)) onCancel();
|
|
10985
11135
|
infringementEmail = email2;
|
|
10986
11136
|
}
|
|
10987
|
-
const canBuyGoods = await
|
|
11137
|
+
const canBuyGoods = await p37.select({
|
|
10988
11138
|
message: "Can users buy goods (products, items)?",
|
|
10989
11139
|
options: [
|
|
10990
11140
|
{
|
|
@@ -10994,28 +11144,28 @@ async function termsAction() {
|
|
|
10994
11144
|
{ value: "no", label: "No" }
|
|
10995
11145
|
]
|
|
10996
11146
|
});
|
|
10997
|
-
if (
|
|
10998
|
-
const subscriptions3 = await
|
|
11147
|
+
if (p37.isCancel(canBuyGoods)) onCancel();
|
|
11148
|
+
const subscriptions3 = await p37.select({
|
|
10999
11149
|
message: "Do you offer subscription plans?",
|
|
11000
11150
|
options: [
|
|
11001
11151
|
{ value: "yes", label: "Yes, we offer subscription plans" },
|
|
11002
11152
|
{ value: "no", label: "No" }
|
|
11003
11153
|
]
|
|
11004
11154
|
});
|
|
11005
|
-
if (
|
|
11155
|
+
if (p37.isCancel(subscriptions3)) onCancel();
|
|
11006
11156
|
let freeTrial;
|
|
11007
11157
|
if (subscriptions3 === "yes") {
|
|
11008
|
-
const ft = await
|
|
11158
|
+
const ft = await p37.select({
|
|
11009
11159
|
message: "Do you offer a free trial?",
|
|
11010
11160
|
options: [
|
|
11011
11161
|
{ value: "yes", label: "Yes" },
|
|
11012
11162
|
{ value: "no", label: "No" }
|
|
11013
11163
|
]
|
|
11014
11164
|
});
|
|
11015
|
-
if (
|
|
11165
|
+
if (p37.isCancel(ft)) onCancel();
|
|
11016
11166
|
freeTrial = ft;
|
|
11017
11167
|
}
|
|
11018
|
-
const exclusiveContent = await
|
|
11168
|
+
const exclusiveContent = await p37.select({
|
|
11019
11169
|
message: "Do you want to make it clear that your own content & trademarks are your exclusive property?",
|
|
11020
11170
|
options: [
|
|
11021
11171
|
{
|
|
@@ -11025,24 +11175,24 @@ async function termsAction() {
|
|
|
11025
11175
|
{ value: "no", label: "No" }
|
|
11026
11176
|
]
|
|
11027
11177
|
});
|
|
11028
|
-
if (
|
|
11029
|
-
const feedbackReuse = await
|
|
11178
|
+
if (p37.isCancel(exclusiveContent)) onCancel();
|
|
11179
|
+
const feedbackReuse = await p37.select({
|
|
11030
11180
|
message: "If users provide you feedback & suggestions, do you want to use this feedback without compensation or credits given?",
|
|
11031
11181
|
options: [
|
|
11032
11182
|
{ value: "yes", label: "Yes, we may implement any feedback or suggestions we receive" },
|
|
11033
11183
|
{ value: "no", label: "No" }
|
|
11034
11184
|
]
|
|
11035
11185
|
});
|
|
11036
|
-
if (
|
|
11037
|
-
const promotions = await
|
|
11186
|
+
if (p37.isCancel(feedbackReuse)) onCancel();
|
|
11187
|
+
const promotions = await p37.select({
|
|
11038
11188
|
message: "Do you plan to offer promotions, contests, sweepstakes?",
|
|
11039
11189
|
options: [
|
|
11040
11190
|
{ value: "yes", label: "Yes, we may offer promotions, contests, sweepstakes" },
|
|
11041
11191
|
{ value: "no", label: "No" }
|
|
11042
11192
|
]
|
|
11043
11193
|
});
|
|
11044
|
-
if (
|
|
11045
|
-
const mobileAppRaw = await
|
|
11194
|
+
if (p37.isCancel(promotions)) onCancel();
|
|
11195
|
+
const mobileAppRaw = await p37.multiselect({
|
|
11046
11196
|
message: "Is the Service distributed through any mobile app stores? Check all that apply",
|
|
11047
11197
|
options: [
|
|
11048
11198
|
{ value: "apple", label: "Apple App Store" },
|
|
@@ -11050,7 +11200,7 @@ async function termsAction() {
|
|
|
11050
11200
|
],
|
|
11051
11201
|
required: false
|
|
11052
11202
|
});
|
|
11053
|
-
if (
|
|
11203
|
+
if (p37.isCancel(mobileAppRaw)) onCancel();
|
|
11054
11204
|
const mobileApp = mobileAppRaw ?? [];
|
|
11055
11205
|
const contact = await contactMethods("terms");
|
|
11056
11206
|
const html = generateTermsHtml({
|
|
@@ -11091,7 +11241,7 @@ var terms = new Command60("terms").description("generate placeholder terms and c
|
|
|
11091
11241
|
// src/commands/legal/privacy.ts
|
|
11092
11242
|
import path42 from "node:path";
|
|
11093
11243
|
import { Command as Command61 } from "commander";
|
|
11094
|
-
import * as
|
|
11244
|
+
import * as p38 from "@clack/prompts";
|
|
11095
11245
|
var mapLabels = {
|
|
11096
11246
|
personalInfo: {
|
|
11097
11247
|
email: "Email address",
|
|
@@ -11509,12 +11659,12 @@ var generatePrivacyHtml = (answers) => {
|
|
|
11509
11659
|
return `<section data-role="content">${sections.join("")}</section>`;
|
|
11510
11660
|
};
|
|
11511
11661
|
async function promptWithCustom(message, options, customMessage) {
|
|
11512
|
-
const selection = await
|
|
11513
|
-
if (
|
|
11662
|
+
const selection = await p38.multiselect({ message, options });
|
|
11663
|
+
if (p38.isCancel(selection)) onCancel();
|
|
11514
11664
|
const values = selection;
|
|
11515
11665
|
if (values.includes("custom")) {
|
|
11516
|
-
const custom = await
|
|
11517
|
-
if (
|
|
11666
|
+
const custom = await p38.text({ message: customMessage });
|
|
11667
|
+
if (p38.isCancel(custom)) onCancel();
|
|
11518
11668
|
const idx = values.indexOf("custom");
|
|
11519
11669
|
if (idx !== -1) values.splice(idx, 1);
|
|
11520
11670
|
if (custom) values.push(String(custom));
|
|
@@ -11524,7 +11674,7 @@ async function promptWithCustom(message, options, customMessage) {
|
|
|
11524
11674
|
async function privacyAction() {
|
|
11525
11675
|
const { workspaceRootDir, publicRoutesDir } = await getWorkspace();
|
|
11526
11676
|
const site = siteFields(await readSite(workspaceRootDir));
|
|
11527
|
-
const core = await
|
|
11677
|
+
const core = await p38.group(
|
|
11528
11678
|
{
|
|
11529
11679
|
websiteUrl: site.websiteUrl,
|
|
11530
11680
|
websiteName: site.websiteName,
|
|
@@ -11536,7 +11686,7 @@ async function privacyAction() {
|
|
|
11536
11686
|
},
|
|
11537
11687
|
{ onCancel }
|
|
11538
11688
|
);
|
|
11539
|
-
const personalInfo = await
|
|
11689
|
+
const personalInfo = await p38.multiselect({
|
|
11540
11690
|
message: "What kind of personal information do you collect from users? Check all that apply",
|
|
11541
11691
|
options: [
|
|
11542
11692
|
{ value: "email", label: "Email address" },
|
|
@@ -11551,16 +11701,16 @@ async function privacyAction() {
|
|
|
11551
11701
|
],
|
|
11552
11702
|
required: false
|
|
11553
11703
|
});
|
|
11554
|
-
if (
|
|
11704
|
+
if (p38.isCancel(personalInfo)) onCancel();
|
|
11555
11705
|
const contact = await contactMethods("privacy");
|
|
11556
|
-
const tracking = await
|
|
11706
|
+
const tracking = await p38.select({
|
|
11557
11707
|
message: "Do you use tracking and/or analytics tools, such as Google Analytics?",
|
|
11558
11708
|
options: [
|
|
11559
11709
|
{ value: "yes", label: "Yes, we use Google Analytics or other related tools" },
|
|
11560
11710
|
{ value: "no", label: "No" }
|
|
11561
11711
|
]
|
|
11562
11712
|
});
|
|
11563
|
-
if (
|
|
11713
|
+
if (p38.isCancel(tracking)) onCancel();
|
|
11564
11714
|
let trackingTools;
|
|
11565
11715
|
if (tracking === "yes") {
|
|
11566
11716
|
trackingTools = await promptWithCustom(
|
|
@@ -11579,7 +11729,7 @@ async function privacyAction() {
|
|
|
11579
11729
|
"Enter your custom tracking/analytics tool name"
|
|
11580
11730
|
);
|
|
11581
11731
|
}
|
|
11582
|
-
const sendEmails = await
|
|
11732
|
+
const sendEmails = await p38.select({
|
|
11583
11733
|
message: "Do you send emails to users?",
|
|
11584
11734
|
options: [
|
|
11585
11735
|
{
|
|
@@ -11589,7 +11739,7 @@ async function privacyAction() {
|
|
|
11589
11739
|
{ value: "no", label: "No" }
|
|
11590
11740
|
]
|
|
11591
11741
|
});
|
|
11592
|
-
if (
|
|
11742
|
+
if (p38.isCancel(sendEmails)) onCancel();
|
|
11593
11743
|
let emailPlatforms;
|
|
11594
11744
|
if (sendEmails === "yes") {
|
|
11595
11745
|
emailPlatforms = await promptWithCustom(
|
|
@@ -11604,14 +11754,14 @@ async function privacyAction() {
|
|
|
11604
11754
|
"Enter your custom email platform"
|
|
11605
11755
|
);
|
|
11606
11756
|
}
|
|
11607
|
-
const showAds = await
|
|
11757
|
+
const showAds = await p38.select({
|
|
11608
11758
|
message: "Do you show ads?",
|
|
11609
11759
|
options: [
|
|
11610
11760
|
{ value: "yes", label: "Yes, we show ads" },
|
|
11611
11761
|
{ value: "no", label: "No" }
|
|
11612
11762
|
]
|
|
11613
11763
|
});
|
|
11614
|
-
if (
|
|
11764
|
+
if (p38.isCancel(showAds)) onCancel();
|
|
11615
11765
|
let adsPlatforms;
|
|
11616
11766
|
if (showAds === "yes") {
|
|
11617
11767
|
adsPlatforms = await promptWithCustom(
|
|
@@ -11634,7 +11784,7 @@ async function privacyAction() {
|
|
|
11634
11784
|
"Enter your custom ads platform"
|
|
11635
11785
|
);
|
|
11636
11786
|
}
|
|
11637
|
-
const canPay = await
|
|
11787
|
+
const canPay = await p38.select({
|
|
11638
11788
|
message: "Can users pay for products or services?",
|
|
11639
11789
|
options: [
|
|
11640
11790
|
{ value: "yes", label: "Yes, users can pay for our products/services" },
|
|
@@ -11644,7 +11794,7 @@ async function privacyAction() {
|
|
|
11644
11794
|
}
|
|
11645
11795
|
]
|
|
11646
11796
|
});
|
|
11647
|
-
if (
|
|
11797
|
+
if (p38.isCancel(canPay)) onCancel();
|
|
11648
11798
|
let paymentProcessors;
|
|
11649
11799
|
if (canPay === "yes") {
|
|
11650
11800
|
paymentProcessors = await promptWithCustom(
|
|
@@ -11675,14 +11825,14 @@ async function privacyAction() {
|
|
|
11675
11825
|
"Enter your custom payment processor/method"
|
|
11676
11826
|
);
|
|
11677
11827
|
}
|
|
11678
|
-
const remarketing = await
|
|
11828
|
+
const remarketing = await p38.select({
|
|
11679
11829
|
message: "Do you use remarketing services for marketing & advertising purposes?",
|
|
11680
11830
|
options: [
|
|
11681
11831
|
{ value: "yes", label: "Yes, we use remarketing services to advertise our business" },
|
|
11682
11832
|
{ value: "no", label: "No" }
|
|
11683
11833
|
]
|
|
11684
11834
|
});
|
|
11685
|
-
if (
|
|
11835
|
+
if (p38.isCancel(remarketing)) onCancel();
|
|
11686
11836
|
let remarketingPlatforms;
|
|
11687
11837
|
if (remarketing === "yes") {
|
|
11688
11838
|
remarketingPlatforms = await promptWithCustom(
|
|
@@ -11701,7 +11851,7 @@ async function privacyAction() {
|
|
|
11701
11851
|
"Enter your custom remarketing platform"
|
|
11702
11852
|
);
|
|
11703
11853
|
}
|
|
11704
|
-
const providersRaw = await
|
|
11854
|
+
const providersRaw = await p38.multiselect({
|
|
11705
11855
|
message: "Select if you use any of the following providers",
|
|
11706
11856
|
options: [
|
|
11707
11857
|
{ value: "recaptcha", label: "Invisible reCAPTCHA" },
|
|
@@ -11712,16 +11862,16 @@ async function privacyAction() {
|
|
|
11712
11862
|
],
|
|
11713
11863
|
required: false
|
|
11714
11864
|
});
|
|
11715
|
-
if (
|
|
11865
|
+
if (p38.isCancel(providersRaw)) onCancel();
|
|
11716
11866
|
const providers = providersRaw;
|
|
11717
11867
|
if (providers.includes("custom")) {
|
|
11718
|
-
const custom = await
|
|
11719
|
-
if (
|
|
11868
|
+
const custom = await p38.text({ message: "Enter your custom provider" });
|
|
11869
|
+
if (p38.isCancel(custom)) onCancel();
|
|
11720
11870
|
const idx = providers.indexOf("custom");
|
|
11721
11871
|
if (idx !== -1) providers.splice(idx, 1);
|
|
11722
11872
|
if (custom) providers.push(String(custom));
|
|
11723
11873
|
}
|
|
11724
|
-
const usStates = await
|
|
11874
|
+
const usStates = await p38.select({
|
|
11725
11875
|
message: "Include U.S. state privacy rights (CCPA/CPRA, VCDPA, CPA, CTDPA, UCPA, TX, OR, etc.)?",
|
|
11726
11876
|
options: [
|
|
11727
11877
|
{
|
|
@@ -11732,55 +11882,55 @@ async function privacyAction() {
|
|
|
11732
11882
|
],
|
|
11733
11883
|
initialValue: "yes"
|
|
11734
11884
|
});
|
|
11735
|
-
if (
|
|
11736
|
-
const gdpr = await
|
|
11885
|
+
if (p38.isCancel(usStates)) onCancel();
|
|
11886
|
+
const gdpr = await p38.select({
|
|
11737
11887
|
message: "Do you want your Privacy Policy to include GDPR / UK GDPR wording?",
|
|
11738
11888
|
options: [
|
|
11739
11889
|
{ value: "yes", label: "Yes. Include GDPR rights for EEA, UK, and Swiss residents" },
|
|
11740
11890
|
{ value: "no", label: "No" }
|
|
11741
11891
|
]
|
|
11742
11892
|
});
|
|
11743
|
-
if (
|
|
11893
|
+
if (p38.isCancel(gdpr)) onCancel();
|
|
11744
11894
|
let facebookFanPage = "no";
|
|
11745
11895
|
const facebookDetails = { name: "", url: "" };
|
|
11746
11896
|
if (gdpr === "yes") {
|
|
11747
|
-
const fan = await
|
|
11897
|
+
const fan = await p38.select({
|
|
11748
11898
|
message: "Do you have a Facebook Fan Page?",
|
|
11749
11899
|
options: [
|
|
11750
11900
|
{ value: "yes", label: "Yes, we have a Facebook Fan Page" },
|
|
11751
11901
|
{ value: "no", label: "No" }
|
|
11752
11902
|
]
|
|
11753
11903
|
});
|
|
11754
|
-
if (
|
|
11904
|
+
if (p38.isCancel(fan)) onCancel();
|
|
11755
11905
|
facebookFanPage = fan;
|
|
11756
11906
|
if (facebookFanPage === "yes") {
|
|
11757
|
-
const name = await
|
|
11907
|
+
const name = await p38.text({
|
|
11758
11908
|
message: "What is the name of the Facebook Fan Page?",
|
|
11759
11909
|
placeholder: "My Facebook Page"
|
|
11760
11910
|
});
|
|
11761
|
-
if (
|
|
11911
|
+
if (p38.isCancel(name)) onCancel();
|
|
11762
11912
|
facebookDetails.name = name;
|
|
11763
|
-
const url = await
|
|
11913
|
+
const url = await p38.text({
|
|
11764
11914
|
message: "What is the URL of the Facebook Fan Page?",
|
|
11765
11915
|
placeholder: "https://facebook.com/my-facebook-page"
|
|
11766
11916
|
});
|
|
11767
|
-
if (
|
|
11917
|
+
if (p38.isCancel(url)) onCancel();
|
|
11768
11918
|
facebookDetails.url = url;
|
|
11769
11919
|
}
|
|
11770
11920
|
}
|
|
11771
|
-
const kids = await
|
|
11921
|
+
const kids = await p38.select({
|
|
11772
11922
|
message: "Do you collect information from kids under the age of 13?",
|
|
11773
11923
|
options: [
|
|
11774
11924
|
{ value: "yes", label: "Yes. We collect information from children under the age of 13" },
|
|
11775
11925
|
{ value: "no", label: "No" }
|
|
11776
11926
|
]
|
|
11777
11927
|
});
|
|
11778
|
-
if (
|
|
11779
|
-
const retention = await
|
|
11928
|
+
if (p38.isCancel(kids)) onCancel();
|
|
11929
|
+
const retention = await p38.text({
|
|
11780
11930
|
message: "How long do you retain personal information? (leave blank for default wording)",
|
|
11781
11931
|
placeholder: "e.g. 12 months after account closure"
|
|
11782
11932
|
});
|
|
11783
|
-
if (
|
|
11933
|
+
if (p38.isCancel(retention)) onCancel();
|
|
11784
11934
|
const html = generatePrivacyHtml({
|
|
11785
11935
|
core,
|
|
11786
11936
|
personalInfo: personalInfo ?? [],
|
|
@@ -12111,7 +12261,7 @@ var reset = new Command65("reset").description("clear and reload fixtures").conf
|
|
|
12111
12261
|
import fs43 from "node:fs";
|
|
12112
12262
|
import path44 from "node:path";
|
|
12113
12263
|
import { Command as Command66, InvalidArgumentError } from "commander";
|
|
12114
|
-
import * as
|
|
12264
|
+
import * as p39 from "@clack/prompts";
|
|
12115
12265
|
import { annotate } from "annotate-json-schema";
|
|
12116
12266
|
import { createGenerator } from "json-schema-faker";
|
|
12117
12267
|
import { faker } from "@faker-js/faker";
|
|
@@ -12250,7 +12400,7 @@ var generate2 = new Command66("generate").description("generate fixture data").o
|
|
|
12250
12400
|
seed: opts.seed
|
|
12251
12401
|
});
|
|
12252
12402
|
});
|
|
12253
|
-
for (const warning of result.warnings)
|
|
12403
|
+
for (const warning of result.warnings) p39.log.warn(warning);
|
|
12254
12404
|
if (result.writtenFiles.length === 0) {
|
|
12255
12405
|
reportResult({
|
|
12256
12406
|
summary: "No eligible collections found to generate fixtures for.",
|
|
@@ -12275,7 +12425,7 @@ var generate2 = new Command66("generate").description("generate fixture data").o
|
|
|
12275
12425
|
|
|
12276
12426
|
// src/commands/fixtures/regen.ts
|
|
12277
12427
|
import { Command as Command67, InvalidArgumentError as InvalidArgumentError2 } from "commander";
|
|
12278
|
-
import * as
|
|
12428
|
+
import * as p40 from "@clack/prompts";
|
|
12279
12429
|
function parseCount2(value) {
|
|
12280
12430
|
const n = parseInt(value, 10);
|
|
12281
12431
|
if (!Number.isFinite(n) || n <= 0 || n > 999) {
|
|
@@ -12304,7 +12454,7 @@ var regen = new Command67("regen").description("clear the database, regenerate f
|
|
|
12304
12454
|
});
|
|
12305
12455
|
loaded = await loadFixtures(pb, workspaceRootDir);
|
|
12306
12456
|
});
|
|
12307
|
-
for (const warning of result.warnings)
|
|
12457
|
+
for (const warning of result.warnings) p40.log.warn(warning);
|
|
12308
12458
|
reportResult({
|
|
12309
12459
|
summary: `Regenerated fixtures (${loaded.length} collection(s) reloaded).`,
|
|
12310
12460
|
filesCreated: result.writtenFiles,
|
|
@@ -12484,72 +12634,81 @@ var seeds = new Command72("seeds").description("manage seed data").configureHelp
|
|
|
12484
12634
|
|
|
12485
12635
|
// src/commands/signup.ts
|
|
12486
12636
|
import { Command as Command73 } from "commander";
|
|
12487
|
-
import * as
|
|
12637
|
+
import * as p41 from "@clack/prompts";
|
|
12488
12638
|
import makeFetchCookie2 from "fetch-cookie";
|
|
12489
12639
|
var signup = new Command73("signup").description("signup to velastack.dev").configureHelp(helpConfig).action(
|
|
12490
12640
|
() => runCommand(async () => {
|
|
12491
|
-
const
|
|
12492
|
-
email: () => p40.text({ message: "Email" }),
|
|
12493
|
-
password: () => p40.password({ message: "Password" }),
|
|
12494
|
-
passwordConfirm: () => p40.password({ message: "Confirm password" })
|
|
12495
|
-
});
|
|
12496
|
-
if (password8 !== passwordConfirm) {
|
|
12497
|
-
throw new Error("Passwords do not match.");
|
|
12498
|
-
}
|
|
12641
|
+
const method = await chooseAuthMethod("signup", await fetchAuthMethods());
|
|
12499
12642
|
const fetchCookie = makeFetchCookie2(fetch);
|
|
12500
|
-
|
|
12501
|
-
|
|
12502
|
-
|
|
12503
|
-
|
|
12504
|
-
|
|
12505
|
-
},
|
|
12506
|
-
body: new URLSearchParams({
|
|
12507
|
-
type: "password",
|
|
12508
|
-
email: email2,
|
|
12509
|
-
password: password8,
|
|
12510
|
-
passwordConfirm
|
|
12511
|
-
}).toString()
|
|
12512
|
-
});
|
|
12513
|
-
if (!res.headers.get("Set-Cookie")) {
|
|
12514
|
-
throw new Error("Failed to signup. Try again or contact support.");
|
|
12643
|
+
let isNew = true;
|
|
12644
|
+
if (method === "whatsapp") {
|
|
12645
|
+
({ isNew } = await signInWithWhatsApp(fetchCookie, "signup"));
|
|
12646
|
+
} else {
|
|
12647
|
+
await signupWithPassword(fetchCookie);
|
|
12515
12648
|
}
|
|
12516
12649
|
const apiKey = await issueApiKey(fetchCookie);
|
|
12517
12650
|
writeConfig({ apiKey });
|
|
12518
|
-
|
|
12519
|
-
|
|
12651
|
+
p41.log.success(isNew ? "Signed up to velastack.dev" : "Logged in to velastack.dev");
|
|
12652
|
+
if (method === "password") {
|
|
12653
|
+
p41.log.info("Check your email for a confirmation link.");
|
|
12654
|
+
}
|
|
12520
12655
|
}, "Failed to signup.")
|
|
12521
12656
|
);
|
|
12657
|
+
async function signupWithPassword(fetchCookie) {
|
|
12658
|
+
const { email: email2, password: password8, passwordConfirm } = await p41.group(
|
|
12659
|
+
{
|
|
12660
|
+
email: () => p41.text({ message: "Email" }),
|
|
12661
|
+
password: () => p41.password({ message: "Password" }),
|
|
12662
|
+
passwordConfirm: () => p41.password({ message: "Confirm password" })
|
|
12663
|
+
},
|
|
12664
|
+
{ onCancel: cancelled }
|
|
12665
|
+
);
|
|
12666
|
+
if (password8 !== passwordConfirm) {
|
|
12667
|
+
throw new Error("Passwords do not match.");
|
|
12668
|
+
}
|
|
12669
|
+
const result = await postForm(fetchCookie, "/signup", {
|
|
12670
|
+
type: "password",
|
|
12671
|
+
email: email2,
|
|
12672
|
+
password: password8,
|
|
12673
|
+
passwordConfirm
|
|
12674
|
+
});
|
|
12675
|
+
if (result.type !== "redirect") {
|
|
12676
|
+
throw new Error(failureText(result, "Could not create the account."));
|
|
12677
|
+
}
|
|
12678
|
+
}
|
|
12522
12679
|
|
|
12523
12680
|
// src/commands/logout.ts
|
|
12524
12681
|
import { Command as Command74 } from "commander";
|
|
12525
|
-
import * as
|
|
12682
|
+
import * as p42 from "@clack/prompts";
|
|
12526
12683
|
var logout = new Command74("logout").alias("signout").description("logout from velastack.dev").configureHelp(helpConfig).action(
|
|
12527
12684
|
() => runCommand(() => {
|
|
12528
12685
|
if (!readConfig()) {
|
|
12529
|
-
|
|
12686
|
+
p42.log.info("Not logged in");
|
|
12530
12687
|
return;
|
|
12531
12688
|
}
|
|
12532
12689
|
clearConfig();
|
|
12533
|
-
|
|
12690
|
+
p42.log.success("Logged out of velastack.dev");
|
|
12534
12691
|
})
|
|
12535
12692
|
);
|
|
12536
12693
|
|
|
12537
12694
|
// src/commands/whoami.ts
|
|
12538
12695
|
import { Command as Command75 } from "commander";
|
|
12539
|
-
import * as
|
|
12696
|
+
import * as p43 from "@clack/prompts";
|
|
12540
12697
|
var whoami = new Command75("whoami").description("show the current user").configureHelp(helpConfig).action(
|
|
12541
12698
|
() => runCommand(async () => {
|
|
12542
12699
|
const apiKey = readConfig()?.apiKey;
|
|
12543
12700
|
if (!apiKey) {
|
|
12544
|
-
|
|
12701
|
+
p43.log.info("Not logged in. Run `vela login` to login.");
|
|
12545
12702
|
return;
|
|
12546
12703
|
}
|
|
12547
12704
|
const res = await fetch(`${API_URL}/api/collections/users/records`, {
|
|
12548
12705
|
headers: { Authorization: `Bearer ${apiKey}` }
|
|
12549
12706
|
});
|
|
12550
12707
|
const data = await res.json();
|
|
12551
|
-
|
|
12552
|
-
|
|
12708
|
+
const user = data.items[0];
|
|
12709
|
+
if (!user) throw new Error("No user found. Run `vela login` to login.");
|
|
12710
|
+
const who = user.email || user.phone || user.name || "an account without a name";
|
|
12711
|
+
p43.log.success(`Logged in as ${who}`);
|
|
12553
12712
|
})
|
|
12554
12713
|
);
|
|
12555
12714
|
|
|
@@ -12700,12 +12859,12 @@ var historySync = new Command80("history-sync").description("drop _migrations ro
|
|
|
12700
12859
|
import path49 from "node:path";
|
|
12701
12860
|
import process31 from "node:process";
|
|
12702
12861
|
import { Command as Command81 } from "commander";
|
|
12703
|
-
import * as
|
|
12862
|
+
import * as p44 from "@clack/prompts";
|
|
12704
12863
|
import pc13 from "picocolors";
|
|
12705
12864
|
var sveltekit3 = new Command81("sveltekit-3").description("upgrade a SvelteKit 2 project to SvelteKit 3 (sv migrate, then the vela steps)").option("--cwd <path>", "the project to migrate (default: the current project)").option("--no-install", "skip installing dependencies").option("--force", "run even when the git working tree has uncommitted changes").option("--skip-sv", "only run the vela steps (sv has already been run)").configureHelp(helpConfig).action(
|
|
12706
12865
|
(options) => runCommand(async () => {
|
|
12707
12866
|
const root = options.cwd ? path49.resolve(options.cwd) : findWorkspaceRoot() ?? process31.cwd();
|
|
12708
|
-
|
|
12867
|
+
p44.intro(pc13.bgCyan(pc13.black(" vela migrate sveltekit-3 ")));
|
|
12709
12868
|
const result = await runKit3Migration(root, {
|
|
12710
12869
|
install: options.install,
|
|
12711
12870
|
force: options.force,
|
|
@@ -12732,14 +12891,14 @@ function printReport(root, result) {
|
|
|
12732
12891
|
"",
|
|
12733
12892
|
`${tasks.filesToReview} file(s) to review, ${tasks.markerComments} \`@migration-task\` comment(s) in the code.`
|
|
12734
12893
|
);
|
|
12735
|
-
|
|
12894
|
+
p44.note(lines.join("\n"), `${MIGRATION_TASKS_FILE}`, { format: (line) => line });
|
|
12736
12895
|
}
|
|
12737
12896
|
if (result.followUps.length > 0) {
|
|
12738
|
-
|
|
12897
|
+
p44.note(result.followUps.map((item) => `- ${item}`).join("\n"), "VelaStack follow-ups", {
|
|
12739
12898
|
format: (line) => line
|
|
12740
12899
|
});
|
|
12741
12900
|
}
|
|
12742
|
-
|
|
12901
|
+
p44.note(
|
|
12743
12902
|
nextStepsFor(result).map((s) => `- ${s}`).join("\n"),
|
|
12744
12903
|
"Next steps",
|
|
12745
12904
|
{
|
|
@@ -12982,7 +13141,7 @@ import fs48 from "node:fs";
|
|
|
12982
13141
|
import path52 from "node:path";
|
|
12983
13142
|
import process35 from "node:process";
|
|
12984
13143
|
import { Command as Command84 } from "commander";
|
|
12985
|
-
import * as
|
|
13144
|
+
import * as p45 from "@clack/prompts";
|
|
12986
13145
|
import pc16 from "picocolors";
|
|
12987
13146
|
import { x as x4 } from "tinyexec";
|
|
12988
13147
|
import { detect as detect7 } from "package-manager-detector";
|
|
@@ -13024,7 +13183,7 @@ function splitHosts(value) {
|
|
|
13024
13183
|
var PRERENDERED_DIR = path52.join(".svelte-kit", "output", "prerendered");
|
|
13025
13184
|
var build = new Command84("build").description("build the app").configureHelp(helpConfig).option("-t, --target <target>", "which copy of the app to build for", PRODUCTION_TARGET).action(async (options) => {
|
|
13026
13185
|
const cwd = process35.cwd();
|
|
13027
|
-
warnIfKit2(findWorkspaceRoot(cwd) ?? cwd, (m) =>
|
|
13186
|
+
warnIfKit2(findWorkspaceRoot(cwd) ?? cwd, (m) => p45.log.warn(m));
|
|
13028
13187
|
warnIfSsrExternalMissing(findWorkspaceRoot(cwd) ?? cwd);
|
|
13029
13188
|
applyBuildEnv(cwd);
|
|
13030
13189
|
const origin = await originForBuild(cwd, options.target);
|
|
@@ -13075,7 +13234,7 @@ function warnIfSsrExternalMissing(root) {
|
|
|
13075
13234
|
}
|
|
13076
13235
|
const check2 = ssrExternalNotInDependencies(root);
|
|
13077
13236
|
const problem = ssrExternalProblem(check2) ?? ssrExternalAllNotice(check2);
|
|
13078
|
-
if (problem)
|
|
13237
|
+
if (problem) p45.log.warn(problem);
|
|
13079
13238
|
}
|
|
13080
13239
|
async function originForBuild(cwd, target) {
|
|
13081
13240
|
const workspaceRootDir = findWorkspaceRoot(cwd);
|
|
@@ -13093,7 +13252,7 @@ function warnIfPrerendered(cwd) {
|
|
|
13093
13252
|
const dir = path52.join(cwd, PRERENDERED_DIR);
|
|
13094
13253
|
if (!fs48.existsSync(dir) || fs48.readdirSync(dir).length === 0) return;
|
|
13095
13254
|
if (process35.env.VELA_ORIGIN === "") {
|
|
13096
|
-
|
|
13255
|
+
p45.log.warn(
|
|
13097
13256
|
`Prerendered pages were built with no origin, on purpose: this app is served on
|
|
13098
13257
|
several hosts (or on none yet), and baking one in would make the others render
|
|
13099
13258
|
as it and refuse their form posts. Each host takes its origin from the request
|
|
@@ -13103,7 +13262,7 @@ from ${pc16.cyan("src/lib/site.ts")}, as the templates' canonical links are.`
|
|
|
13103
13262
|
);
|
|
13104
13263
|
return;
|
|
13105
13264
|
}
|
|
13106
|
-
|
|
13265
|
+
p45.log.warn(
|
|
13107
13266
|
`Prerendered pages were built with no domain configured, so anything they take
|
|
13108
13267
|
from the request's origin points at SvelteKit's placeholder host rather than at
|
|
13109
13268
|
this site. Links built from ${pc16.cyan("src/lib/site.ts")}, as the templates' canonical
|
|
@@ -13118,7 +13277,7 @@ import fs49 from "node:fs";
|
|
|
13118
13277
|
import path53 from "node:path";
|
|
13119
13278
|
import process36 from "node:process";
|
|
13120
13279
|
import { Command as Command85 } from "commander";
|
|
13121
|
-
import * as
|
|
13280
|
+
import * as p46 from "@clack/prompts";
|
|
13122
13281
|
import pc17 from "picocolors";
|
|
13123
13282
|
import { x as x5 } from "tinyexec";
|
|
13124
13283
|
import { detect as detect8 } from "package-manager-detector";
|
|
@@ -13127,7 +13286,7 @@ var ADAPTER_NODE_MODULE = path53.join("build", "adapter-node.js");
|
|
|
13127
13286
|
var preview = new Command85("preview").description("preview the built app").configureHelp(helpConfig).action(async () => {
|
|
13128
13287
|
const cwd = process36.cwd();
|
|
13129
13288
|
process36.env.VELA_DATA_DIR ??= localDataDir(cwd);
|
|
13130
|
-
warnIfKit2(findWorkspaceRoot(cwd) ?? cwd, (m) =>
|
|
13289
|
+
warnIfKit2(findWorkspaceRoot(cwd) ?? cwd, (m) => p46.log.warn(m));
|
|
13131
13290
|
warnIfOriginBaked(cwd);
|
|
13132
13291
|
let pbProc;
|
|
13133
13292
|
const needsStart = hasBackend(cwd) && !process36.env.POCKETBASE_URL;
|
|
@@ -13182,7 +13341,7 @@ function warnIfOriginBaked(cwd) {
|
|
|
13182
13341
|
}
|
|
13183
13342
|
const origin = bakedOrigin(source);
|
|
13184
13343
|
if (!origin || isLocalUrl(origin)) return;
|
|
13185
|
-
|
|
13344
|
+
p46.log.warn(
|
|
13186
13345
|
`This build was made for ${pc17.cyan(origin)}, and SvelteKit treats that as the origin of
|
|
13187
13346
|
every request. Form posts from localhost will be refused as cross-site (403).
|
|
13188
13347
|
|
|
@@ -13208,7 +13367,7 @@ var sync = new Command86("sync").description("sync types from the database").con
|
|
|
13208
13367
|
|
|
13209
13368
|
// src/commands/provision.ts
|
|
13210
13369
|
import { Command as Command87 } from "commander";
|
|
13211
|
-
import * as
|
|
13370
|
+
import * as p47 from "@clack/prompts";
|
|
13212
13371
|
import pc18 from "picocolors";
|
|
13213
13372
|
import * as v9 from "valibot";
|
|
13214
13373
|
var NODE_MAJOR = "24";
|
|
@@ -13231,19 +13390,19 @@ var provision = addSshOptions(
|
|
|
13231
13390
|
(target, raw) => runCommand(async () => {
|
|
13232
13391
|
const options = parseOptions(OptionsSchema2, raw);
|
|
13233
13392
|
const pbVersion = options.pbVersion ?? pocketbaseVersion();
|
|
13234
|
-
|
|
13235
|
-
|
|
13393
|
+
p47.intro(pc18.bgCyan(pc18.black(" vela provision ")));
|
|
13394
|
+
p47.log.info(`Target ${pc18.cyan(target)}`);
|
|
13236
13395
|
await withSsh(target, sshOptionsFrom(options), async (session) => {
|
|
13237
13396
|
await session.detectElevation();
|
|
13238
13397
|
const existing = await readServerInfo(session);
|
|
13239
13398
|
if (existing) {
|
|
13240
|
-
|
|
13399
|
+
p47.log.info(
|
|
13241
13400
|
`Already provisioned by vela ${existing.cliVersion} on ${existing.provisionedAt}. Bringing it up to date.`
|
|
13242
13401
|
);
|
|
13243
13402
|
}
|
|
13244
|
-
|
|
13403
|
+
p47.log.step("Uploading server scripts");
|
|
13245
13404
|
await syncServerScripts(session);
|
|
13246
|
-
|
|
13405
|
+
p47.log.step("Running provision");
|
|
13247
13406
|
const result = await runServerScript(session, "provision.sh", {
|
|
13248
13407
|
args: [
|
|
13249
13408
|
"--pb-version",
|
|
@@ -13255,7 +13414,7 @@ var provision = addSshOptions(
|
|
|
13255
13414
|
],
|
|
13256
13415
|
stream: true
|
|
13257
13416
|
});
|
|
13258
|
-
|
|
13417
|
+
p47.log.success(
|
|
13259
13418
|
`${target} is ready.
|
|
13260
13419
|
|
|
13261
13420
|
Node ${result?.node ?? "installed"}
|
|
@@ -13263,7 +13422,7 @@ var provision = addSshOptions(
|
|
|
13263
13422
|
PocketBase ${result?.pocketbase ?? pbVersion}`
|
|
13264
13423
|
);
|
|
13265
13424
|
});
|
|
13266
|
-
|
|
13425
|
+
p47.outro(`Deploy with ${pc18.cyan(`vela deploy --server ${target}`)}`);
|
|
13267
13426
|
}, "Failed to provision.")
|
|
13268
13427
|
);
|
|
13269
13428
|
|
|
@@ -13272,7 +13431,7 @@ import path58 from "node:path";
|
|
|
13272
13431
|
import fs53 from "node:fs";
|
|
13273
13432
|
import process38 from "node:process";
|
|
13274
13433
|
import { Command as Command88, Option as Option2 } from "commander";
|
|
13275
|
-
import * as
|
|
13434
|
+
import * as p49 from "@clack/prompts";
|
|
13276
13435
|
import pc20 from "picocolors";
|
|
13277
13436
|
import * as v10 from "valibot";
|
|
13278
13437
|
|
|
@@ -13544,7 +13703,7 @@ The build would bake in your development value. Set ${baked.length === 1 ? "it"
|
|
|
13544
13703
|
import fs52 from "node:fs";
|
|
13545
13704
|
import path57 from "node:path";
|
|
13546
13705
|
import process37 from "node:process";
|
|
13547
|
-
import * as
|
|
13706
|
+
import * as p48 from "@clack/prompts";
|
|
13548
13707
|
import pc19 from "picocolors";
|
|
13549
13708
|
var ENV_EXAMPLE = ".env.example";
|
|
13550
13709
|
var SUPPLIED = /^(NODE_ENV|HOST|PORT|ORIGIN|PROTOCOL_HEADER|HOST_HEADER|ADDRESS_HEADER|XFF_DEPTH|PB_PORT|POCKETBASE_URL|POCKETBASE_SUPERUSER_EMAIL|POCKETBASE_SUPERUSER_PASSWORD|APP_NAME|VELA_)/;
|
|
@@ -13559,7 +13718,7 @@ async function nudgeMissingEnv(root, target, present) {
|
|
|
13559
13718
|
if (missing.length === 0) return [];
|
|
13560
13719
|
const where = pc19.cyan(target.targetName);
|
|
13561
13720
|
if (!isInteractive()) {
|
|
13562
|
-
|
|
13721
|
+
p48.log.warn(
|
|
13563
13722
|
`${where} does not have ${missing.length} of the variables ${ENV_EXAMPLE} documents:
|
|
13564
13723
|
|
|
13565
13724
|
` + missing.map((key) => ` ${key}`).join("\n") + `
|
|
@@ -13568,13 +13727,13 @@ Set any it needs with ${pc19.cyan(`vela env set KEY -t ${target.targetName}`)}.`
|
|
|
13568
13727
|
);
|
|
13569
13728
|
return [];
|
|
13570
13729
|
}
|
|
13571
|
-
|
|
13730
|
+
p48.log.warn(
|
|
13572
13731
|
`${where} does not have ${missing.length} of the variables ${ENV_EXAMPLE} documents:
|
|
13573
13732
|
|
|
13574
13733
|
` + missing.map((key) => ` ${key}`).join("\n")
|
|
13575
13734
|
);
|
|
13576
|
-
const go = await
|
|
13577
|
-
if (
|
|
13735
|
+
const go = await p48.confirm({ message: "Set any of them now?", initialValue: true });
|
|
13736
|
+
if (p48.isCancel(go)) cancel22();
|
|
13578
13737
|
if (!go) return [];
|
|
13579
13738
|
const set = [];
|
|
13580
13739
|
for (const key of missing) {
|
|
@@ -13584,7 +13743,7 @@ Set any it needs with ${pc19.cyan(`vela env set KEY -t ${target.targetName}`)}.`
|
|
|
13584
13743
|
const value = await promptValue(key, asPublic);
|
|
13585
13744
|
const files = layer === "instance" ? layerFiles(target.appId, "instance", target.instance) : layerFiles(target.appId, layer);
|
|
13586
13745
|
await setInLayer(target.session, files, key, value, asPublic);
|
|
13587
|
-
|
|
13746
|
+
p48.log.success(
|
|
13588
13747
|
`${key} set${asPublic ? " (public)" : ""} ${pc19.dim(`(${layer === "instance" ? target.targetName : layer})`)}`
|
|
13589
13748
|
);
|
|
13590
13749
|
set.push(key);
|
|
@@ -13598,27 +13757,27 @@ async function pickLayer(key, target) {
|
|
|
13598
13757
|
];
|
|
13599
13758
|
if (target.preview) options.push({ value: "preview", label: "preview", hint: "every preview" });
|
|
13600
13759
|
options.push({ value: "skip", label: "skip", hint: "leave it unset" });
|
|
13601
|
-
const choice = await
|
|
13602
|
-
if (
|
|
13760
|
+
const choice = await p48.select({ message: `Where should ${pc19.cyan(key)} be set?`, options });
|
|
13761
|
+
if (p48.isCancel(choice)) cancel22();
|
|
13603
13762
|
return choice === "skip" ? null : choice;
|
|
13604
13763
|
}
|
|
13605
13764
|
async function askPublic(key) {
|
|
13606
|
-
const choice = await
|
|
13765
|
+
const choice = await p48.confirm({
|
|
13607
13766
|
message: `Is ${pc19.cyan(key)} public? (readable back with vela env list; no for a secret)`,
|
|
13608
13767
|
initialValue: false
|
|
13609
13768
|
});
|
|
13610
|
-
if (
|
|
13769
|
+
if (p48.isCancel(choice)) cancel22();
|
|
13611
13770
|
return choice;
|
|
13612
13771
|
}
|
|
13613
13772
|
async function promptValue(key, asPublic) {
|
|
13614
13773
|
const message = `Value for ${pc19.cyan(key)}${asPublic ? pc19.dim(" (public)") : ""}`;
|
|
13615
13774
|
const validate = (input) => !input?.length ? "Required" : void 0;
|
|
13616
|
-
const value = asPublic ? await
|
|
13617
|
-
if (
|
|
13775
|
+
const value = asPublic ? await p48.text({ message, validate }) : await p48.password({ message, validate });
|
|
13776
|
+
if (p48.isCancel(value)) cancel22();
|
|
13618
13777
|
return value;
|
|
13619
13778
|
}
|
|
13620
13779
|
function cancel22() {
|
|
13621
|
-
|
|
13780
|
+
p48.cancel("Operation cancelled.");
|
|
13622
13781
|
process37.exit(0);
|
|
13623
13782
|
}
|
|
13624
13783
|
|
|
@@ -13653,13 +13812,13 @@ var deploy = addLockWaitOption(
|
|
|
13653
13812
|
(raw) => runCommand(async () => {
|
|
13654
13813
|
const options = parseOptions(OptionsSchema3, raw);
|
|
13655
13814
|
const backend3 = hasBackend();
|
|
13656
|
-
|
|
13815
|
+
p49.intro(pc20.bgCyan(pc20.black(" vela deploy ")));
|
|
13657
13816
|
if (options.build !== false) {
|
|
13658
13817
|
const { workspaceRootDir } = await getWorkspace();
|
|
13659
13818
|
await prepareAdapter(workspaceRootDir);
|
|
13660
13819
|
const foreign = foreignLockfile(workspaceRootDir);
|
|
13661
13820
|
if (foreign) {
|
|
13662
|
-
|
|
13821
|
+
p49.log.warn(
|
|
13663
13822
|
`Dependencies are pinned by ${pc20.cyan(foreign)}, but the server installs with npm, which cannot replay it.
|
|
13664
13823
|
Versions there are resolved from package.json ranges and may differ from yours. Commit a
|
|
13665
13824
|
${pc20.cyan("package-lock.json")} (${pc20.dim("npm install --package-lock-only")}) for a reproducible deploy.`
|
|
@@ -13672,13 +13831,13 @@ ${pc20.cyan("package-lock.json")} (${pc20.dim("npm install --package-lock-only")
|
|
|
13672
13831
|
{
|
|
13673
13832
|
remote: async (ctx) => {
|
|
13674
13833
|
const { session, instance, workspaceRootDir } = ctx;
|
|
13675
|
-
|
|
13834
|
+
p49.log.info(
|
|
13676
13835
|
`${pc20.cyan(ctx.appName)} ${pc20.dim("\u2192")} ${pc20.cyan(ctx.targetName)} ${pc20.dim(`(${ctx.server})`)}`
|
|
13677
13836
|
);
|
|
13678
13837
|
const serverNode = await requireServerNode(session, ctx.server);
|
|
13679
13838
|
const drift = nodeMajorDrift(serverNode, process38.version);
|
|
13680
13839
|
if (drift) {
|
|
13681
|
-
|
|
13840
|
+
p49.log.warn(
|
|
13682
13841
|
`${ctx.server} runs Node ${drift.server}, but this deploy runs Node ${drift.build}. The server's npm can reject a lockfile this one accepts.
|
|
13683
13842
|
Run ${pc20.cyan(`vela provision ${ctx.server}`)} to bring it up to ${drift.build}.`
|
|
13684
13843
|
);
|
|
@@ -13690,7 +13849,7 @@ Run ${pc20.cyan(`vela provision ${ctx.server}`)} to bring it up to ${drift.build
|
|
|
13690
13849
|
const askedForRemoteDb = options.remoteDb;
|
|
13691
13850
|
const remoteDb = askedForRemoteDb ?? instanceHasBackend(existing);
|
|
13692
13851
|
if (existing && instanceHasBackend(existing) !== backend3) {
|
|
13693
|
-
|
|
13852
|
+
p49.log.info(
|
|
13694
13853
|
backend3 ? `${pc20.cyan(ctx.targetName)} was deployed without a backend before. This deploy adds PocketBase.` : `${pc20.cyan(ctx.targetName)} was deployed with a backend before. This deploy removes PocketBase; its database stays on the server.`
|
|
13695
13854
|
);
|
|
13696
13855
|
}
|
|
@@ -13753,7 +13912,7 @@ with DNS of your own pointing at ${ctx.server}.`
|
|
|
13753
13912
|
tunnel = await openDatabaseTunnel(session, instance, existing);
|
|
13754
13913
|
} catch (err) {
|
|
13755
13914
|
if (askedForRemoteDb) throw err;
|
|
13756
|
-
|
|
13915
|
+
p49.log.warn(
|
|
13757
13916
|
`Could not build against the ${pc20.cyan(ctx.targetName)} database, using a local one instead.
|
|
13758
13917
|
${pc20.dim(String(err))}`
|
|
13759
13918
|
);
|
|
@@ -13761,7 +13920,7 @@ ${pc20.dim(String(err))}`
|
|
|
13761
13920
|
}
|
|
13762
13921
|
if (tunnel) {
|
|
13763
13922
|
derived = { ...derived, ...tunnel.env };
|
|
13764
|
-
|
|
13923
|
+
p49.log.info(
|
|
13765
13924
|
`Building against the ${pc20.cyan(ctx.targetName)} database on ${ctx.server} ${pc20.dim(`(port ${tunnel.pbPort})`)}`
|
|
13766
13925
|
);
|
|
13767
13926
|
} else if (backend3) {
|
|
@@ -13773,11 +13932,11 @@ ${pc20.dim(String(err))}`
|
|
|
13773
13932
|
tunnel: tunnel !== null
|
|
13774
13933
|
});
|
|
13775
13934
|
if (blanked.length > 0) {
|
|
13776
|
-
|
|
13935
|
+
p49.log.info(
|
|
13777
13936
|
`Building without ${blanked.join(", ")} \u2014 set in .env but not for ${pc20.cyan(ctx.targetName)}.`
|
|
13778
13937
|
);
|
|
13779
13938
|
}
|
|
13780
|
-
|
|
13939
|
+
p49.log.step("Building");
|
|
13781
13940
|
try {
|
|
13782
13941
|
await runBuild(workspaceRootDir, void 0, buildEnv);
|
|
13783
13942
|
} finally {
|
|
@@ -13785,9 +13944,9 @@ ${pc20.dim(String(err))}`
|
|
|
13785
13944
|
}
|
|
13786
13945
|
}
|
|
13787
13946
|
const entries = collectArtifact(workspaceRootDir);
|
|
13788
|
-
|
|
13947
|
+
p49.log.step(`Uploading release ${pc20.dim(release)}`);
|
|
13789
13948
|
await uploadRelease(session, instance, release, entries);
|
|
13790
|
-
|
|
13949
|
+
p49.log.step("Activating");
|
|
13791
13950
|
result = await runServerScript(session, "apply.sh", {
|
|
13792
13951
|
args: [
|
|
13793
13952
|
instance,
|
|
@@ -13852,7 +14011,7 @@ ${pc20.dim(String(err))}`
|
|
|
13852
14011
|
url: primaryHost ? url : void 0
|
|
13853
14012
|
});
|
|
13854
14013
|
const redirects = started?.environment.redirects ?? [];
|
|
13855
|
-
|
|
14014
|
+
p49.log.success(
|
|
13856
14015
|
`Deployed ${pc20.cyan(ctx.appName)} ${pc20.dim(release)}
|
|
13857
14016
|
|
|
13858
14017
|
URL ${url}
|
|
@@ -13860,10 +14019,10 @@ ${pc20.dim(String(err))}`
|
|
|
13860
14019
|
` : "") + ` Port ${result?.webPort ?? "?"}${backend3 ? ` (PocketBase ${result?.pbPort ?? "?"})` : ""}`
|
|
13861
14020
|
);
|
|
13862
14021
|
if (managed && managed !== existing?.managed) {
|
|
13863
|
-
|
|
14022
|
+
p49.log.info(`${pc20.cyan(managed)} goes live within a minute.`);
|
|
13864
14023
|
}
|
|
13865
14024
|
if (result?.superuserCreated) {
|
|
13866
|
-
|
|
14025
|
+
p49.log.info(
|
|
13867
14026
|
`Created the PocketBase superuser this app authenticates as.
|
|
13868
14027
|
|
|
13869
14028
|
Its credentials are stored in the environment on the server. To use
|
|
@@ -13872,7 +14031,7 @@ and deploy again.`
|
|
|
13872
14031
|
);
|
|
13873
14032
|
}
|
|
13874
14033
|
if (!primaryHost) {
|
|
13875
|
-
|
|
14034
|
+
p49.log.warn(
|
|
13876
14035
|
`No domain configured, so nothing is proxied to this app yet.
|
|
13877
14036
|
Redeploy with ${pc20.cyan("--domain example.com")} once DNS points at ${ctx.server}` + (reporter.enabled ? "" : `,
|
|
13878
14037
|
or ${pc20.cyan("vela link")} it to get a free velastack.app hostname.`) + `.`
|
|
@@ -13882,7 +14041,7 @@ or ${pc20.cyan("vela link")} it to get a free velastack.app hostname.`) + `.`
|
|
|
13882
14041
|
},
|
|
13883
14042
|
{ project: options.project, askDomain: true, label: "deploy" }
|
|
13884
14043
|
);
|
|
13885
|
-
|
|
14044
|
+
p49.outro(`${pc20.cyan("vela status")} to see what is running`);
|
|
13886
14045
|
}, "Failed to deploy.")
|
|
13887
14046
|
);
|
|
13888
14047
|
async function prepareAdapter(workspaceRootDir) {
|
|
@@ -13902,12 +14061,12 @@ ${pc20.cyan(err.snippet)}` : err.message);
|
|
|
13902
14061
|
const editable = current !== void 0 && !/^svelte\.config\./.test(path58.basename(current.file));
|
|
13903
14062
|
if (current && editable && (current.kind === "auto" || current.kind === "none") && isInteractive()) {
|
|
13904
14063
|
const has = current.kind === "auto" ? `is on ${ADAPTER_AUTO}` : "has no SvelteKit adapter configured";
|
|
13905
|
-
const confirmed = await
|
|
14064
|
+
const confirmed = await p49.confirm({
|
|
13906
14065
|
message: `This project ${has}, and vela deploy runs the app as a Node server.
|
|
13907
14066
|
Switch it to ${ADAPTER_NODE}? This edits ${path58.basename(current.file)} and package.json.`
|
|
13908
14067
|
});
|
|
13909
|
-
if (
|
|
13910
|
-
|
|
14068
|
+
if (p49.isCancel(confirmed) || !confirmed) {
|
|
14069
|
+
p49.cancel("Nothing was changed, and nothing was deployed.");
|
|
13911
14070
|
process38.exit(0);
|
|
13912
14071
|
}
|
|
13913
14072
|
}
|
|
@@ -13918,8 +14077,8 @@ Switch it to ${ADAPTER_NODE}? This edits ${path58.basename(current.file)} and pa
|
|
|
13918
14077
|
outcome.packageJsonChanged ? "package.json" : void 0
|
|
13919
14078
|
].filter((f) => Boolean(f));
|
|
13920
14079
|
const why = outcome.previous === "auto" ? `${ADAPTER_AUTO} builds nothing for a server of your own` : outcome.previous === "none" ? "No adapter was configured" : `${ADAPTER_NODE} was configured but not in package.json`;
|
|
13921
|
-
|
|
13922
|
-
|
|
14080
|
+
p49.log.step(`Switching the adapter to ${pc20.cyan(ADAPTER_NODE)}`);
|
|
14081
|
+
p49.log.info(
|
|
13923
14082
|
`${why}, and vela deploy runs the app as a Node server.
|
|
13924
14083
|
|
|
13925
14084
|
Changed ${changed.join(", ")}` + (outcome.removedDeps.length ? `
|
|
@@ -13932,7 +14091,7 @@ Switch it to ${ADAPTER_NODE}? This edits ${path58.basename(current.file)} and pa
|
|
|
13932
14091
|
rethrow(err);
|
|
13933
14092
|
}
|
|
13934
14093
|
}
|
|
13935
|
-
|
|
14094
|
+
p49.log.warn(`Commit ${changed.join(", ")} so every deploy builds the same way.`);
|
|
13936
14095
|
}
|
|
13937
14096
|
function ssrExternalPreflight(root) {
|
|
13938
14097
|
const major = kitMajor(root);
|
|
@@ -13948,7 +14107,7 @@ function ssrExternalPreflight(root) {
|
|
|
13948
14107
|
const problem = ssrExternalProblem(check2);
|
|
13949
14108
|
if (problem) throw new Error(problem);
|
|
13950
14109
|
const notice = ssrExternalAllNotice(check2);
|
|
13951
|
-
if (notice)
|
|
14110
|
+
if (notice) p49.log.warn(notice);
|
|
13952
14111
|
}
|
|
13953
14112
|
async function openDatabaseTunnel(session, instance, state) {
|
|
13954
14113
|
const pbPort = instanceHasBackend(state) ? state?.pbPort : void 0;
|
|
@@ -14063,7 +14222,7 @@ async function serverTimeOrLocal(session) {
|
|
|
14063
14222
|
try {
|
|
14064
14223
|
return await serverTime(session);
|
|
14065
14224
|
} catch {
|
|
14066
|
-
|
|
14225
|
+
p49.log.warn("Could not read the clock on the server; stamping this release from this machine.");
|
|
14067
14226
|
return /* @__PURE__ */ new Date();
|
|
14068
14227
|
}
|
|
14069
14228
|
}
|
|
@@ -14072,14 +14231,14 @@ async function serverTimeOrLocal(session) {
|
|
|
14072
14231
|
import path59 from "node:path";
|
|
14073
14232
|
import process39 from "node:process";
|
|
14074
14233
|
import { Command as Command89 } from "commander";
|
|
14075
|
-
import * as
|
|
14234
|
+
import * as p50 from "@clack/prompts";
|
|
14076
14235
|
var CREATE_NEW = "__new__";
|
|
14077
14236
|
var link = new Command89("link").description("link this project to a velastack.dev project").configureHelp(helpConfig).action(() => runCommand(linkProject, "Failed to link the project."));
|
|
14078
14237
|
async function linkProject() {
|
|
14079
14238
|
const { workspaceRootDir } = await getWorkspace();
|
|
14080
14239
|
const existing = readProjectConfig(workspaceRootDir);
|
|
14081
14240
|
if (existing) {
|
|
14082
|
-
|
|
14241
|
+
p50.log.success(`Linked to ${existing.projectName}.`);
|
|
14083
14242
|
return;
|
|
14084
14243
|
}
|
|
14085
14244
|
const apiKey = requireApiKey();
|
|
@@ -14096,10 +14255,10 @@ async function linkProject() {
|
|
|
14096
14255
|
}
|
|
14097
14256
|
const { projectId, teamId, projectName } = linked;
|
|
14098
14257
|
writeProjectConfig(workspaceRootDir, { projectId, teamId, projectName });
|
|
14099
|
-
|
|
14258
|
+
p50.log.success(`Linked to ${projectName} (${linked.dashboardUrl}).`);
|
|
14100
14259
|
}
|
|
14101
14260
|
async function pickExistingProject(projects) {
|
|
14102
|
-
const choice = await
|
|
14261
|
+
const choice = await p50.select({
|
|
14103
14262
|
message: "Select a project",
|
|
14104
14263
|
options: [
|
|
14105
14264
|
...projects.map((pr) => ({
|
|
@@ -14109,23 +14268,23 @@ async function pickExistingProject(projects) {
|
|
|
14109
14268
|
{ value: CREATE_NEW, label: "Create a new project" }
|
|
14110
14269
|
]
|
|
14111
14270
|
});
|
|
14112
|
-
if (
|
|
14113
|
-
|
|
14271
|
+
if (p50.isCancel(choice)) {
|
|
14272
|
+
p50.cancel("Operation cancelled.");
|
|
14114
14273
|
process39.exit(0);
|
|
14115
14274
|
}
|
|
14116
14275
|
return choice;
|
|
14117
14276
|
}
|
|
14118
14277
|
async function promptProjectName(workspaceRootDir) {
|
|
14119
14278
|
const defaultValue = defaultProjectName2(workspaceRootDir);
|
|
14120
|
-
const value = await
|
|
14279
|
+
const value = await p50.text({
|
|
14121
14280
|
message: "Project name",
|
|
14122
14281
|
defaultValue,
|
|
14123
14282
|
initialValue: defaultValue,
|
|
14124
14283
|
placeholder: defaultValue,
|
|
14125
14284
|
validate: (v14) => !v14?.trim() ? "Required" : void 0
|
|
14126
14285
|
});
|
|
14127
|
-
if (
|
|
14128
|
-
|
|
14286
|
+
if (p50.isCancel(value)) {
|
|
14287
|
+
p50.cancel("Operation cancelled.");
|
|
14129
14288
|
process39.exit(0);
|
|
14130
14289
|
}
|
|
14131
14290
|
return value.trim();
|
|
@@ -14146,12 +14305,12 @@ import { Command as Command95 } from "commander";
|
|
|
14146
14305
|
// src/commands/env/list.ts
|
|
14147
14306
|
import { Command as Command90 } from "commander";
|
|
14148
14307
|
import * as v12 from "valibot";
|
|
14149
|
-
import * as
|
|
14308
|
+
import * as p53 from "@clack/prompts";
|
|
14150
14309
|
import pc23 from "picocolors";
|
|
14151
14310
|
|
|
14152
14311
|
// src/lib/local-env.ts
|
|
14153
14312
|
import fs54 from "node:fs";
|
|
14154
|
-
import * as
|
|
14313
|
+
import * as p51 from "@clack/prompts";
|
|
14155
14314
|
import pc21 from "picocolors";
|
|
14156
14315
|
function readLocalEnv(envFile) {
|
|
14157
14316
|
if (!fs54.existsSync(envFile)) return {};
|
|
@@ -14177,23 +14336,23 @@ async function applyLocalEnvChange(ctx, changed) {
|
|
|
14177
14336
|
process.env.POCKETBASE_SUPERUSER_EMAIL = email2;
|
|
14178
14337
|
process.env.POCKETBASE_SUPERUSER_PASSWORD = password8;
|
|
14179
14338
|
await ensureSuperuser(ctx.workspaceRootDir);
|
|
14180
|
-
|
|
14339
|
+
p51.log.success("Local superuser updated to match");
|
|
14181
14340
|
} else {
|
|
14182
|
-
|
|
14341
|
+
p51.log.warn(
|
|
14183
14342
|
`The local database still has the old superuser.
|
|
14184
14343
|
Set both ${pc21.cyan("POCKETBASE_SUPERUSER_EMAIL")} and ${pc21.cyan("POCKETBASE_SUPERUSER_PASSWORD")} to reconcile it.`
|
|
14185
14344
|
);
|
|
14186
14345
|
}
|
|
14187
14346
|
}
|
|
14188
14347
|
if (getPocketbaseMetadata(ctx.workspaceRootDir)) {
|
|
14189
|
-
|
|
14348
|
+
p51.log.info(`Restart ${pc21.cyan("vela dev")} to pick this up.`);
|
|
14190
14349
|
}
|
|
14191
14350
|
}
|
|
14192
14351
|
|
|
14193
14352
|
// src/lib/env-command.ts
|
|
14194
14353
|
import process40 from "node:process";
|
|
14195
14354
|
import * as v11 from "valibot";
|
|
14196
|
-
import * as
|
|
14355
|
+
import * as p52 from "@clack/prompts";
|
|
14197
14356
|
import pc22 from "picocolors";
|
|
14198
14357
|
var ALL_SCOPE = "all";
|
|
14199
14358
|
var PREVIEW_SCOPE = "preview";
|
|
@@ -14318,12 +14477,12 @@ async function promptScope(workspaceRootDir, label2) {
|
|
|
14318
14477
|
[ALL_SCOPE]: "every deployed target, on every server",
|
|
14319
14478
|
[PREVIEW_SCOPE]: "every preview"
|
|
14320
14479
|
};
|
|
14321
|
-
const choice = await
|
|
14480
|
+
const choice = await p52.select({
|
|
14322
14481
|
message: "Which environment?",
|
|
14323
14482
|
options: scopes.map((scope) => ({ value: scope, label: scope, hint: hints[scope] }))
|
|
14324
14483
|
});
|
|
14325
|
-
if (
|
|
14326
|
-
|
|
14484
|
+
if (p52.isCancel(choice)) {
|
|
14485
|
+
p52.cancel("Operation cancelled.");
|
|
14327
14486
|
process40.exit(0);
|
|
14328
14487
|
}
|
|
14329
14488
|
return parseEnvScope(choice);
|
|
@@ -14334,7 +14493,7 @@ function readAtBuildTime(workspaceRootDir, keys) {
|
|
|
14334
14493
|
}
|
|
14335
14494
|
async function applyLayerRestart(ctx, changed) {
|
|
14336
14495
|
if (touchesSuperuser(changed)) {
|
|
14337
|
-
|
|
14496
|
+
p52.log.warn(
|
|
14338
14497
|
`PocketBase superuser credentials changed.
|
|
14339
14498
|
|
|
14340
14499
|
Each database still holds the old ones, so nothing was restarted.
|
|
@@ -14343,22 +14502,22 @@ Run ${pc22.cyan("vela deploy")} for every target to push them in.`
|
|
|
14343
14502
|
return;
|
|
14344
14503
|
}
|
|
14345
14504
|
if (ctx.reached.length === 0) {
|
|
14346
|
-
|
|
14505
|
+
p52.log.info(`Nothing of this app runs on ${ctx.server} yet; the value applies on first deploy.`);
|
|
14347
14506
|
return;
|
|
14348
14507
|
}
|
|
14349
14508
|
for (const state of ctx.reached) {
|
|
14350
14509
|
const shadowed = await shadowedKeys(ctx.session, ctx.appId, state, ctx.layer, changed);
|
|
14351
14510
|
const reach = changed.filter((key) => !(key in shadowed));
|
|
14352
|
-
if (Object.keys(shadowed).length > 0)
|
|
14511
|
+
if (Object.keys(shadowed).length > 0) p52.log.warn(shadowWarning(state, ctx.layer, shadowed));
|
|
14353
14512
|
if (reach.length === 0) {
|
|
14354
|
-
|
|
14513
|
+
p52.log.info(`${state.env} not restarted ${pc22.dim(`(${ctx.server})`)}`);
|
|
14355
14514
|
continue;
|
|
14356
14515
|
}
|
|
14357
14516
|
const outcome = await restartInstance(ctx.session, state.instance);
|
|
14358
14517
|
if (!outcome.deployed) continue;
|
|
14359
|
-
if (outcome.restarted)
|
|
14518
|
+
if (outcome.restarted) p52.log.success(`${state.env} restarted ${pc22.dim(`(${ctx.server})`)}`);
|
|
14360
14519
|
else {
|
|
14361
|
-
|
|
14520
|
+
p52.log.error(
|
|
14362
14521
|
`${state.env} restart failed.
|
|
14363
14522
|
|
|
14364
14523
|
The new value is stored and will be used the next time it starts.
|
|
@@ -14396,7 +14555,7 @@ function shadowWarning(state, layer, shadowed) {
|
|
|
14396
14555
|
async function applyChange(workspaceRootDir, ctx, changed) {
|
|
14397
14556
|
const { baked, how } = readAtBuildTime(workspaceRootDir, changed);
|
|
14398
14557
|
if (baked.length > 0) {
|
|
14399
|
-
|
|
14558
|
+
p52.log.info(
|
|
14400
14559
|
`${baked.join(", ")} ${baked.length === 1 ? "is" : "are"} read at build time (${pc22.cyan(how)}); redeploy to apply.`
|
|
14401
14560
|
);
|
|
14402
14561
|
const rest = changed.filter((key) => !baked.includes(key));
|
|
@@ -14432,10 +14591,10 @@ var envList = addEnvTargetOptions(
|
|
|
14432
14591
|
local: async (ctx) => {
|
|
14433
14592
|
const keys = Object.keys(readLocalEnv(ctx.envFile)).sort();
|
|
14434
14593
|
if (keys.length === 0) {
|
|
14435
|
-
|
|
14594
|
+
p53.log.info(`No environment variables configured ${pc23.dim("(local)")}.`);
|
|
14436
14595
|
return;
|
|
14437
14596
|
}
|
|
14438
|
-
|
|
14597
|
+
p53.log.info(
|
|
14439
14598
|
`Environment ${pc23.dim("(local, .env)")}
|
|
14440
14599
|
|
|
14441
14600
|
${keys.map((k) => ` ${k}`).join("\n")}`
|
|
@@ -14445,11 +14604,11 @@ ${keys.map((k) => ` ${k}`).join("\n")}`
|
|
|
14445
14604
|
const stack = await resolveStack(ctx.session, ctx.appId, ctx.instance, ctx.preview);
|
|
14446
14605
|
const keys = Object.keys(stack.entries).sort();
|
|
14447
14606
|
if (keys.length === 0) {
|
|
14448
|
-
|
|
14607
|
+
p53.log.info(`No environment variables configured ${pc23.dim(`(${ctx.targetName})`)}.`);
|
|
14449
14608
|
return;
|
|
14450
14609
|
}
|
|
14451
14610
|
const width = Math.max(...keys.map((k) => k.length));
|
|
14452
|
-
|
|
14611
|
+
p53.log.info(
|
|
14453
14612
|
`Environment ${pc23.dim(`(${ctx.targetName}, as the app sees it)`)}
|
|
14454
14613
|
|
|
14455
14614
|
` + keys.map((key) => {
|
|
@@ -14464,11 +14623,11 @@ ${keys.map((k) => ` ${k}`).join("\n")}`
|
|
|
14464
14623
|
const keys = [...Object.keys(contents.secret), ...Object.keys(contents.public)].sort();
|
|
14465
14624
|
const where = `${ctx.layer}, ${ctx.server}`;
|
|
14466
14625
|
if (keys.length === 0) {
|
|
14467
|
-
|
|
14626
|
+
p53.log.info(`No environment variables configured ${pc23.dim(`(${where})`)}.`);
|
|
14468
14627
|
return;
|
|
14469
14628
|
}
|
|
14470
14629
|
const width = Math.max(...keys.map((k) => k.length));
|
|
14471
|
-
|
|
14630
|
+
p53.log.info(
|
|
14472
14631
|
`Environment ${pc23.dim(`(${where})`)}
|
|
14473
14632
|
|
|
14474
14633
|
` + keys.map(
|
|
@@ -14492,14 +14651,14 @@ async function listMatrix(raw) {
|
|
|
14492
14651
|
const app = readAppIdentity(workspaceRootDir);
|
|
14493
14652
|
const bindings = readBindings(workspaceRootDir);
|
|
14494
14653
|
const local = Object.keys(readLocalEnv(`${workspaceRootDir}/.env`)).sort();
|
|
14495
|
-
|
|
14654
|
+
p53.log.info(
|
|
14496
14655
|
local.length ? `Local ${pc23.dim("(.env, names only)")}
|
|
14497
14656
|
|
|
14498
14657
|
${local.map((k) => ` ${k}`).join("\n")}` : `No local environment ${pc23.dim("(.env)")}.`
|
|
14499
14658
|
);
|
|
14500
14659
|
const servers = [...new Set(Object.values(bindings).map((b) => b.server))];
|
|
14501
14660
|
if (!app || servers.length === 0) {
|
|
14502
|
-
|
|
14661
|
+
p53.log.info(`No target is bound to a server yet; ${pc23.cyan("vela deploy")} binds one.`);
|
|
14503
14662
|
return;
|
|
14504
14663
|
}
|
|
14505
14664
|
for (const server of servers) {
|
|
@@ -14538,7 +14697,7 @@ ${local.map((k) => ` ${k}`).join("\n")}` : `No local environment ${pc23.dim("(.
|
|
|
14538
14697
|
)
|
|
14539
14698
|
].sort();
|
|
14540
14699
|
if (keys.length === 0) {
|
|
14541
|
-
|
|
14700
|
+
p53.log.info(`No environment variables configured ${pc23.dim(`(${server})`)}.`);
|
|
14542
14701
|
return;
|
|
14543
14702
|
}
|
|
14544
14703
|
const rows = keys.map((key) => [
|
|
@@ -14550,7 +14709,7 @@ ${local.map((k) => ` ${k}`).join("\n")}` : `No local environment ${pc23.dim("(.
|
|
|
14550
14709
|
(h, i) => Math.max(h.length, ...rows.map((r) => plain(r[i]).length))
|
|
14551
14710
|
);
|
|
14552
14711
|
const line = (cells) => cells.map((c, i) => c + " ".repeat(widths[i] - plain(c).length)).join(" ");
|
|
14553
|
-
|
|
14712
|
+
p53.log.info(
|
|
14554
14713
|
`Environment ${pc23.dim(`(${server})`)}
|
|
14555
14714
|
|
|
14556
14715
|
${pc23.dim(line(headings))}
|
|
@@ -14576,14 +14735,14 @@ function matrixCell(key, columns, index, states) {
|
|
|
14576
14735
|
return pc23.dim("\u2014");
|
|
14577
14736
|
}
|
|
14578
14737
|
var ANSI3 = /\u001b\[[0-9;]*m/g;
|
|
14579
|
-
function plain(
|
|
14580
|
-
return
|
|
14738
|
+
function plain(text20) {
|
|
14739
|
+
return text20.replace(ANSI3, "");
|
|
14581
14740
|
}
|
|
14582
14741
|
|
|
14583
14742
|
// src/commands/env/set.ts
|
|
14584
14743
|
import process41 from "node:process";
|
|
14585
14744
|
import { Command as Command91 } from "commander";
|
|
14586
|
-
import * as
|
|
14745
|
+
import * as p54 from "@clack/prompts";
|
|
14587
14746
|
import pc24 from "picocolors";
|
|
14588
14747
|
var envSet = addEnvTargetOptions(
|
|
14589
14748
|
new Command91("set").description("set an environment variable \u2014 the value is prompted for, never an argument").argument("<key>", "variable name").option(
|
|
@@ -14600,7 +14759,7 @@ var envSet = addEnvTargetOptions(
|
|
|
14600
14759
|
local: async (ctx) => {
|
|
14601
14760
|
const value = await promptValue2(key, "public");
|
|
14602
14761
|
setLocalEnv(ctx.envFile, key, value);
|
|
14603
|
-
|
|
14762
|
+
p54.log.success(`${key} updated ${pc24.dim("(local)")}`);
|
|
14604
14763
|
await applyLocalEnvChange(ctx, [key]);
|
|
14605
14764
|
},
|
|
14606
14765
|
instance: async (ctx) => {
|
|
@@ -14622,9 +14781,9 @@ var envSet = addEnvTargetOptions(
|
|
|
14622
14781
|
);
|
|
14623
14782
|
function report(key, visibility, moved, where) {
|
|
14624
14783
|
const tag = visibility === "public" ? " (public)" : "";
|
|
14625
|
-
|
|
14784
|
+
p54.log.success(`${key} updated${tag} ${pc24.dim(`(${where})`)}`);
|
|
14626
14785
|
if (moved) {
|
|
14627
|
-
|
|
14786
|
+
p54.log.info(
|
|
14628
14787
|
visibility === "public" ? `${key} was secret before; it is readable from now on.` : `${key} was public before; it is write-only from now on.`
|
|
14629
14788
|
);
|
|
14630
14789
|
}
|
|
@@ -14632,9 +14791,9 @@ function report(key, visibility, moved, where) {
|
|
|
14632
14791
|
async function promptValue2(key, visibility) {
|
|
14633
14792
|
const message = `Value for ${pc24.cyan(key)}${visibility === "public" ? pc24.dim(" (public)") : ""}`;
|
|
14634
14793
|
const validate = (input) => !input?.length ? "Required" : void 0;
|
|
14635
|
-
const value = visibility === "public" ? await
|
|
14636
|
-
if (
|
|
14637
|
-
|
|
14794
|
+
const value = visibility === "public" ? await p54.text({ message, validate }) : await p54.password({ message, validate });
|
|
14795
|
+
if (p54.isCancel(value)) {
|
|
14796
|
+
p54.cancel("Operation cancelled.");
|
|
14638
14797
|
process41.exit(0);
|
|
14639
14798
|
}
|
|
14640
14799
|
if (visibility === "secret" && isPublicKey(key)) {
|
|
@@ -14645,7 +14804,7 @@ async function promptValue2(key, visibility) {
|
|
|
14645
14804
|
|
|
14646
14805
|
// src/commands/env/unset.ts
|
|
14647
14806
|
import { Command as Command92 } from "commander";
|
|
14648
|
-
import * as
|
|
14807
|
+
import * as p55 from "@clack/prompts";
|
|
14649
14808
|
import pc25 from "picocolors";
|
|
14650
14809
|
var envUnset = addEnvTargetOptions(
|
|
14651
14810
|
new Command92("unset").description("remove an environment variable").argument("<key>", "variable name").configureHelp(helpConfig)
|
|
@@ -14656,29 +14815,29 @@ var envUnset = addEnvTargetOptions(
|
|
|
14656
14815
|
{
|
|
14657
14816
|
local: async (ctx) => {
|
|
14658
14817
|
if (!(key in readLocalEnv(ctx.envFile))) {
|
|
14659
|
-
|
|
14818
|
+
p55.log.info(`${key} is not set \u2014 nothing to remove.`);
|
|
14660
14819
|
return;
|
|
14661
14820
|
}
|
|
14662
14821
|
unsetLocalEnv(ctx.envFile, key);
|
|
14663
|
-
|
|
14822
|
+
p55.log.success(`${key} removed ${pc25.dim("(local)")}`);
|
|
14664
14823
|
await applyLocalEnvChange(ctx, [key]);
|
|
14665
14824
|
},
|
|
14666
14825
|
// Removed from whichever side it was on; nobody should have to
|
|
14667
14826
|
// remember whether a key was public to take it out.
|
|
14668
14827
|
instance: async (ctx) => {
|
|
14669
14828
|
if (!await unsetInLayer(ctx.session, ctx.files, key)) {
|
|
14670
|
-
|
|
14829
|
+
p55.log.info(`${key} is not set on ${ctx.targetName} \u2014 nothing to remove.`);
|
|
14671
14830
|
return;
|
|
14672
14831
|
}
|
|
14673
|
-
|
|
14832
|
+
p55.log.success(`${key} removed ${pc25.dim(`(${ctx.targetName})`)}`);
|
|
14674
14833
|
await applyChange(ctx.workspaceRootDir, ctx, [key]);
|
|
14675
14834
|
},
|
|
14676
14835
|
layer: async (ctx) => {
|
|
14677
14836
|
if (!await unsetInLayer(ctx.session, ctx.files, key)) {
|
|
14678
|
-
|
|
14837
|
+
p55.log.info(`${key} is not set (${ctx.layer}, ${ctx.server}) \u2014 nothing to remove.`);
|
|
14679
14838
|
return;
|
|
14680
14839
|
}
|
|
14681
|
-
|
|
14840
|
+
p55.log.success(`${key} removed ${pc25.dim(`(${ctx.layer}, ${ctx.server})`)}`);
|
|
14682
14841
|
await applyChange(ctx.workspaceRootDir, ctx, [key]);
|
|
14683
14842
|
}
|
|
14684
14843
|
},
|
|
@@ -14693,7 +14852,7 @@ import fs55 from "node:fs";
|
|
|
14693
14852
|
import path60 from "node:path";
|
|
14694
14853
|
import process42 from "node:process";
|
|
14695
14854
|
import { Command as Command93 } from "commander";
|
|
14696
|
-
import * as
|
|
14855
|
+
import * as p56 from "@clack/prompts";
|
|
14697
14856
|
import pc26 from "picocolors";
|
|
14698
14857
|
var envImport = addEnvTargetOptions(
|
|
14699
14858
|
new Command93("import").description("merge a dotenv file into the environment").argument("<file>", "dotenv file to read").option("--public", "import as readable values; PUBLIC_* keys are public regardless").configureHelp(helpConfig)
|
|
@@ -14710,12 +14869,12 @@ var envImport = addEnvTargetOptions(
|
|
|
14710
14869
|
const incoming = read(source, file);
|
|
14711
14870
|
const keys = Object.keys(incoming);
|
|
14712
14871
|
if (keys.length === 0) return;
|
|
14713
|
-
|
|
14872
|
+
p56.log.step(`Importing ${keys.length} variable(s) from ${pc26.cyan(file)}`);
|
|
14714
14873
|
editLocalEnv(
|
|
14715
14874
|
ctx.envFile,
|
|
14716
14875
|
(content) => keys.reduce((acc, key) => upsertEnvVar(acc, key, incoming[key]), content)
|
|
14717
14876
|
);
|
|
14718
|
-
|
|
14877
|
+
p56.log.success(`${keys.length} variable(s) updated ${pc26.dim("(local)")}`);
|
|
14719
14878
|
await applyLocalEnvChange(ctx, keys);
|
|
14720
14879
|
},
|
|
14721
14880
|
// Merge: values in the layer that the file does not mention stay put.
|
|
@@ -14723,7 +14882,7 @@ var envImport = addEnvTargetOptions(
|
|
|
14723
14882
|
const incoming = read(resolve(file), file);
|
|
14724
14883
|
const keys = Object.keys(incoming);
|
|
14725
14884
|
if (keys.length === 0) return;
|
|
14726
|
-
|
|
14885
|
+
p56.log.step(`Importing ${keys.length} variable(s) from ${pc26.cyan(file)}`);
|
|
14727
14886
|
const outcome = await importIntoLayer(
|
|
14728
14887
|
ctx.session,
|
|
14729
14888
|
ctx.files,
|
|
@@ -14737,7 +14896,7 @@ var envImport = addEnvTargetOptions(
|
|
|
14737
14896
|
const incoming = read(resolve(file), file);
|
|
14738
14897
|
const keys = Object.keys(incoming);
|
|
14739
14898
|
if (keys.length === 0) return;
|
|
14740
|
-
|
|
14899
|
+
p56.log.step(`Importing ${keys.length} variable(s) from ${pc26.cyan(file)}`);
|
|
14741
14900
|
const outcome = await importIntoLayer(
|
|
14742
14901
|
ctx.session,
|
|
14743
14902
|
ctx.files,
|
|
@@ -14758,7 +14917,7 @@ function report2(outcome, where) {
|
|
|
14758
14917
|
outcome.secret.length ? `${outcome.secret.length} secret` : "",
|
|
14759
14918
|
outcome.public.length ? `${outcome.public.length} public` : ""
|
|
14760
14919
|
].filter(Boolean);
|
|
14761
|
-
|
|
14920
|
+
p56.log.success(`${parts.join(", ")} variable(s) updated ${pc26.dim(`(${where})`)}`);
|
|
14762
14921
|
}
|
|
14763
14922
|
function resolve(file) {
|
|
14764
14923
|
return path60.resolve(process42.cwd(), file);
|
|
@@ -14766,14 +14925,14 @@ function resolve(file) {
|
|
|
14766
14925
|
function read(resolved, shown) {
|
|
14767
14926
|
if (!fs55.existsSync(resolved)) throw new Error(`${shown} does not exist.`);
|
|
14768
14927
|
const incoming = readLocalEnvFile(resolved);
|
|
14769
|
-
if (Object.keys(incoming).length === 0)
|
|
14928
|
+
if (Object.keys(incoming).length === 0) p56.log.info(`${shown} has no variables to import.`);
|
|
14770
14929
|
return incoming;
|
|
14771
14930
|
}
|
|
14772
14931
|
|
|
14773
14932
|
// src/commands/env/get.ts
|
|
14774
14933
|
import process43 from "node:process";
|
|
14775
14934
|
import { Command as Command94 } from "commander";
|
|
14776
|
-
import * as
|
|
14935
|
+
import * as p57 from "@clack/prompts";
|
|
14777
14936
|
import pc27 from "picocolors";
|
|
14778
14937
|
var envGet = addEnvTargetOptions(
|
|
14779
14938
|
new Command94("get").description("print a public environment variable").argument("<key>", "variable name").configureHelp(helpConfig)
|
|
@@ -14816,7 +14975,7 @@ var envGet = addEnvTargetOptions(
|
|
|
14816
14975
|
)
|
|
14817
14976
|
);
|
|
14818
14977
|
function secret(key, where, from) {
|
|
14819
|
-
|
|
14978
|
+
p57.log.info(
|
|
14820
14979
|
`${key} is secret ${pc27.dim(`(${where}${from ? `, from ${from}` : ""})`)}, so it is not read back.
|
|
14821
14980
|
Set it again to change it: ${pc27.cyan(`vela env set ${key}`)}`
|
|
14822
14981
|
);
|
|
@@ -14828,7 +14987,7 @@ var env = new Command95("env").description("manage environment variables, locall
|
|
|
14828
14987
|
|
|
14829
14988
|
// src/commands/status.ts
|
|
14830
14989
|
import { Command as Command96 } from "commander";
|
|
14831
|
-
import * as
|
|
14990
|
+
import * as p58 from "@clack/prompts";
|
|
14832
14991
|
import pc28 from "picocolors";
|
|
14833
14992
|
var status = addTargetOptions(
|
|
14834
14993
|
new Command96("status").description("show what is deployed").configureHelp(helpConfig),
|
|
@@ -14862,11 +15021,11 @@ function report3(states, json2) {
|
|
|
14862
15021
|
return;
|
|
14863
15022
|
}
|
|
14864
15023
|
if (states.length === 0) {
|
|
14865
|
-
|
|
15024
|
+
p58.log.info("Nothing is deployed here yet.");
|
|
14866
15025
|
return;
|
|
14867
15026
|
}
|
|
14868
15027
|
for (const state of states) {
|
|
14869
|
-
|
|
15028
|
+
p58.log.info(describe2(state));
|
|
14870
15029
|
}
|
|
14871
15030
|
}
|
|
14872
15031
|
function describe2(state) {
|
|
@@ -14891,7 +15050,7 @@ function describe2(state) {
|
|
|
14891
15050
|
|
|
14892
15051
|
// src/commands/rollback.ts
|
|
14893
15052
|
import { Command as Command97 } from "commander";
|
|
14894
|
-
import * as
|
|
15053
|
+
import * as p59 from "@clack/prompts";
|
|
14895
15054
|
import pc29 from "picocolors";
|
|
14896
15055
|
var rollback = addLockWaitOption(
|
|
14897
15056
|
addTargetOptions(
|
|
@@ -14905,7 +15064,7 @@ var rollback = addLockWaitOption(
|
|
|
14905
15064
|
raw,
|
|
14906
15065
|
{
|
|
14907
15066
|
remote: async (ctx) => {
|
|
14908
|
-
|
|
15067
|
+
p59.log.step(
|
|
14909
15068
|
`Rolling back ${pc29.cyan(ctx.appName)} ${pc29.dim(`(${ctx.targetName})`)} on ${ctx.server}`
|
|
14910
15069
|
);
|
|
14911
15070
|
const result = await runServerScript(
|
|
@@ -14920,7 +15079,7 @@ var rollback = addLockWaitOption(
|
|
|
14920
15079
|
stream: true
|
|
14921
15080
|
}
|
|
14922
15081
|
);
|
|
14923
|
-
|
|
15082
|
+
p59.log.success(
|
|
14924
15083
|
`Rolled back to ${pc29.cyan(result?.release ?? "the previous release")}` + (result?.from ? ` ${pc29.dim(`(was ${result.from})`)}` : "")
|
|
14925
15084
|
);
|
|
14926
15085
|
}
|
|
@@ -15025,7 +15184,7 @@ import { Command as Command100 } from "commander";
|
|
|
15025
15184
|
// src/commands/admin/create.ts
|
|
15026
15185
|
import process44 from "node:process";
|
|
15027
15186
|
import { Command as Command99 } from "commander";
|
|
15028
|
-
import * as
|
|
15187
|
+
import * as p60 from "@clack/prompts";
|
|
15029
15188
|
import pc30 from "picocolors";
|
|
15030
15189
|
var MIN_PASSWORD = 10;
|
|
15031
15190
|
var adminCreate = addTargetOptions(
|
|
@@ -15064,7 +15223,7 @@ Run ${pc30.cyan("vela enable backend")} to add one.`
|
|
|
15064
15223
|
const metadata = getPocketbaseMetadata(ctx.workspaceRootDir);
|
|
15065
15224
|
if (metadata) signIn = `http://${metadata.viteHost}:${metadata.vitePort}`;
|
|
15066
15225
|
}
|
|
15067
|
-
|
|
15226
|
+
p60.log.info(
|
|
15068
15227
|
signIn ? `Sign in at ${pc30.cyan(`${signIn}/admin`)}` : `Sign in at ${pc30.cyan("/admin")} once ${pc30.cyan("vela dev")} is running.`
|
|
15069
15228
|
);
|
|
15070
15229
|
},
|
|
@@ -15079,7 +15238,7 @@ Run ${pc30.cyan("vela enable backend")} to add one.`
|
|
|
15079
15238
|
(pb) => upsertSuperuser2(pb, address, password8)
|
|
15080
15239
|
);
|
|
15081
15240
|
const base2 = state?.domain ? `https://${state.domain.split(",")[0].trim()}` : "";
|
|
15082
|
-
|
|
15241
|
+
p60.log.info(
|
|
15083
15242
|
base2 ? `Sign in at ${pc30.cyan(`${base2}/admin`)}` : `Sign in at ${pc30.cyan("/admin")} once a domain is configured for this target.`
|
|
15084
15243
|
);
|
|
15085
15244
|
}
|
|
@@ -15092,20 +15251,20 @@ Run ${pc30.cyan("vela enable backend")} to add one.`
|
|
|
15092
15251
|
async function upsertSuperuser2(pb, email2, password8) {
|
|
15093
15252
|
const existing = await findSuperuser(pb, email2);
|
|
15094
15253
|
if (existing) {
|
|
15095
|
-
const confirmed = await
|
|
15254
|
+
const confirmed = await p60.confirm({
|
|
15096
15255
|
message: `${email2} already has an account, update its password?`,
|
|
15097
15256
|
initialValue: false
|
|
15098
15257
|
});
|
|
15099
|
-
if (
|
|
15100
|
-
|
|
15258
|
+
if (p60.isCancel(confirmed) || !confirmed) {
|
|
15259
|
+
p60.cancel("Operation cancelled.");
|
|
15101
15260
|
process44.exit(0);
|
|
15102
15261
|
}
|
|
15103
15262
|
await pb.collection("_superusers").update(existing, { password: password8, passwordConfirm: password8 });
|
|
15104
|
-
|
|
15263
|
+
p60.log.success(`Password updated for ${pc30.cyan(email2)}, you can sign in now`);
|
|
15105
15264
|
return;
|
|
15106
15265
|
}
|
|
15107
15266
|
await pb.collection("_superusers").create({ email: email2, password: password8, passwordConfirm: password8 });
|
|
15108
|
-
|
|
15267
|
+
p60.log.success(`${pc30.cyan(email2)} can now sign in`);
|
|
15109
15268
|
}
|
|
15110
15269
|
async function findSuperuser(pb, email2) {
|
|
15111
15270
|
try {
|
|
@@ -15116,31 +15275,31 @@ async function findSuperuser(pb, email2) {
|
|
|
15116
15275
|
}
|
|
15117
15276
|
}
|
|
15118
15277
|
async function promptEmail() {
|
|
15119
|
-
const value = await
|
|
15278
|
+
const value = await p60.text({
|
|
15120
15279
|
message: "Email to sign in with",
|
|
15121
15280
|
validate: (input) => input?.includes("@") ? void 0 : "An email address is required"
|
|
15122
15281
|
});
|
|
15123
|
-
if (
|
|
15124
|
-
|
|
15282
|
+
if (p60.isCancel(value)) {
|
|
15283
|
+
p60.cancel("Operation cancelled.");
|
|
15125
15284
|
process44.exit(0);
|
|
15126
15285
|
}
|
|
15127
15286
|
return value.trim();
|
|
15128
15287
|
}
|
|
15129
15288
|
async function promptPassword() {
|
|
15130
|
-
const value = await
|
|
15289
|
+
const value = await p60.password({
|
|
15131
15290
|
message: "Password",
|
|
15132
15291
|
validate: (input) => (input?.length ?? 0) >= MIN_PASSWORD ? void 0 : `At least ${MIN_PASSWORD} characters is required`
|
|
15133
15292
|
});
|
|
15134
|
-
if (
|
|
15135
|
-
|
|
15293
|
+
if (p60.isCancel(value)) {
|
|
15294
|
+
p60.cancel("Operation cancelled.");
|
|
15136
15295
|
process44.exit(0);
|
|
15137
15296
|
}
|
|
15138
|
-
const again = await
|
|
15297
|
+
const again = await p60.password({
|
|
15139
15298
|
message: "Password again",
|
|
15140
15299
|
validate: (input) => input === value ? void 0 : "The two do not match"
|
|
15141
15300
|
});
|
|
15142
|
-
if (
|
|
15143
|
-
|
|
15301
|
+
if (p60.isCancel(again)) {
|
|
15302
|
+
p60.cancel("Operation cancelled.");
|
|
15144
15303
|
process44.exit(0);
|
|
15145
15304
|
}
|
|
15146
15305
|
return value;
|
|
@@ -15156,7 +15315,7 @@ import { Command as Command106 } from "commander";
|
|
|
15156
15315
|
import fs56 from "node:fs";
|
|
15157
15316
|
import path61 from "node:path";
|
|
15158
15317
|
import { Command as Command101 } from "commander";
|
|
15159
|
-
import * as
|
|
15318
|
+
import * as p61 from "@clack/prompts";
|
|
15160
15319
|
import pc32 from "picocolors";
|
|
15161
15320
|
|
|
15162
15321
|
// src/lib/backup-target.ts
|
|
@@ -15320,7 +15479,7 @@ Backup names are lowercase letters, digits, ${pc32.cyan("-")} and ${pc32.cyan("_
|
|
|
15320
15479
|
}
|
|
15321
15480
|
const storage = await readStorageSettings(ctx.pb);
|
|
15322
15481
|
if (storage.s3Enabled) {
|
|
15323
|
-
|
|
15482
|
+
p61.log.warn(
|
|
15324
15483
|
`Uploads are stored in S3, so this archive holds the database only.
|
|
15325
15484
|
|
|
15326
15485
|
PocketBase leaves ${pc32.cyan("storage/")} out of a backup whenever S3 is on.
|
|
@@ -15328,7 +15487,7 @@ Your bucket's own versioning is what protects the uploaded files.`
|
|
|
15328
15487
|
);
|
|
15329
15488
|
}
|
|
15330
15489
|
if (ctx.session) await checkpointAppDatabases(ctx.session, ctx.instance);
|
|
15331
|
-
const spinner9 =
|
|
15490
|
+
const spinner9 = p61.spinner();
|
|
15332
15491
|
spinner9.start(`Backing up ${ctx.targetName}`);
|
|
15333
15492
|
try {
|
|
15334
15493
|
await createBackup(ctx.pb, key);
|
|
@@ -15375,7 +15534,7 @@ async function download(ctx, key, outputDir) {
|
|
|
15375
15534
|
fs56.copyFileSync(path61.join(ctx.workspaceRootDir, "data", "backups", key), destination);
|
|
15376
15535
|
return path61.relative(ctx.workspaceRootDir, destination);
|
|
15377
15536
|
}
|
|
15378
|
-
const spinner9 =
|
|
15537
|
+
const spinner9 = p61.spinner();
|
|
15379
15538
|
spinner9.start(`Downloading ${key}`);
|
|
15380
15539
|
try {
|
|
15381
15540
|
await ctx.session.download(remotePaths.backup(ctx.instance, key), destination);
|
|
@@ -15389,7 +15548,7 @@ async function download(ctx, key, outputDir) {
|
|
|
15389
15548
|
|
|
15390
15549
|
// src/commands/backup/list.ts
|
|
15391
15550
|
import { Command as Command102 } from "commander";
|
|
15392
|
-
import * as
|
|
15551
|
+
import * as p62 from "@clack/prompts";
|
|
15393
15552
|
import pc33 from "picocolors";
|
|
15394
15553
|
var backupList = addTargetOptions(
|
|
15395
15554
|
new Command102("list").description("list the backups on a target").configureHelp(helpConfig),
|
|
@@ -15399,7 +15558,7 @@ var backupList = addTargetOptions(
|
|
|
15399
15558
|
() => withBackupTarget(raw, "backup list", async (ctx) => {
|
|
15400
15559
|
const backups = await listBackups(ctx.pb);
|
|
15401
15560
|
if (backups.length === 0) {
|
|
15402
|
-
|
|
15561
|
+
p62.log.info(
|
|
15403
15562
|
`${pc33.cyan(ctx.targetName)} has no backups yet.
|
|
15404
15563
|
|
|
15405
15564
|
Take one with ${pc33.cyan("vela backup create")}.`
|
|
@@ -15407,7 +15566,7 @@ Take one with ${pc33.cyan("vela backup create")}.`
|
|
|
15407
15566
|
return;
|
|
15408
15567
|
}
|
|
15409
15568
|
const width = Math.max(...backups.map((b) => b.key.length));
|
|
15410
|
-
|
|
15569
|
+
p62.log.message(
|
|
15411
15570
|
backups.map(
|
|
15412
15571
|
(b) => `${b.key.padEnd(width)} ${pc33.dim(formatBytes(b.size).padStart(8))} ${pc33.dim(b.modified)}`
|
|
15413
15572
|
).join("\n")
|
|
@@ -15421,7 +15580,7 @@ Take one with ${pc33.cyan("vela backup create")}.`
|
|
|
15421
15580
|
import fs57 from "node:fs";
|
|
15422
15581
|
import path62 from "node:path";
|
|
15423
15582
|
import { Command as Command103 } from "commander";
|
|
15424
|
-
import * as
|
|
15583
|
+
import * as p63 from "@clack/prompts";
|
|
15425
15584
|
import pc34 from "picocolors";
|
|
15426
15585
|
var backupDownload = addTargetOptions(
|
|
15427
15586
|
new Command103("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),
|
|
@@ -15452,7 +15611,7 @@ Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
|
|
|
15452
15611
|
if (!ctx.session) {
|
|
15453
15612
|
fs57.copyFileSync(path62.join(ctx.workspaceRootDir, "data", "backups", key), destination);
|
|
15454
15613
|
} else {
|
|
15455
|
-
const spinner9 =
|
|
15614
|
+
const spinner9 = p63.spinner();
|
|
15456
15615
|
spinner9.start(`Downloading ${key} (${formatBytes(found.size)})`);
|
|
15457
15616
|
try {
|
|
15458
15617
|
await ctx.session.download(remotePaths.backup(ctx.instance, key), destination);
|
|
@@ -15473,7 +15632,7 @@ Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
|
|
|
15473
15632
|
// src/commands/backup/delete.ts
|
|
15474
15633
|
import process45 from "node:process";
|
|
15475
15634
|
import { Command as Command104 } from "commander";
|
|
15476
|
-
import * as
|
|
15635
|
+
import * as p64 from "@clack/prompts";
|
|
15477
15636
|
import pc35 from "picocolors";
|
|
15478
15637
|
var backupDelete = addTargetOptions(
|
|
15479
15638
|
new Command104("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),
|
|
@@ -15491,12 +15650,12 @@ Run ${pc35.cyan("vela backup list")} to see what it does have.`
|
|
|
15491
15650
|
);
|
|
15492
15651
|
}
|
|
15493
15652
|
if (!options.yes) {
|
|
15494
|
-
const confirmed = await
|
|
15653
|
+
const confirmed = await p64.confirm({
|
|
15495
15654
|
message: `Delete ${key} (${formatBytes(found.size)}) from ${ctx.targetName}?`,
|
|
15496
15655
|
initialValue: false
|
|
15497
15656
|
});
|
|
15498
|
-
if (
|
|
15499
|
-
|
|
15657
|
+
if (p64.isCancel(confirmed) || !confirmed) {
|
|
15658
|
+
p64.cancel("Operation cancelled.");
|
|
15500
15659
|
process45.exit(0);
|
|
15501
15660
|
}
|
|
15502
15661
|
}
|
|
@@ -15508,7 +15667,7 @@ Run ${pc35.cyan("vela backup list")} to see what it does have.`
|
|
|
15508
15667
|
|
|
15509
15668
|
// src/commands/backup/schedule.ts
|
|
15510
15669
|
import { Command as Command105 } from "commander";
|
|
15511
|
-
import * as
|
|
15670
|
+
import * as p65 from "@clack/prompts";
|
|
15512
15671
|
import pc36 from "picocolors";
|
|
15513
15672
|
var DEFAULT_KEEP = 7;
|
|
15514
15673
|
var backupSchedule = addTargetOptions(
|
|
@@ -15525,7 +15684,7 @@ var backupSchedule = addTargetOptions(
|
|
|
15525
15684
|
}
|
|
15526
15685
|
if (!cron) {
|
|
15527
15686
|
const current = await readSchedule(ctx.pb);
|
|
15528
|
-
|
|
15687
|
+
p65.log.info(
|
|
15529
15688
|
current.cron ? `${ctx.targetName} backs up on ${pc36.cyan(current.cron)}, keeping ${current.maxKeep}.` : `${ctx.targetName} has no backup schedule.
|
|
15530
15689
|
|
|
15531
15690
|
Set one with ${pc36.cyan('vela backup schedule "0 3 * * *"')}.`
|
|
@@ -15563,7 +15722,7 @@ import fs58 from "node:fs";
|
|
|
15563
15722
|
import path63 from "node:path";
|
|
15564
15723
|
import process46 from "node:process";
|
|
15565
15724
|
import { Command as Command107 } from "commander";
|
|
15566
|
-
import * as
|
|
15725
|
+
import * as p66 from "@clack/prompts";
|
|
15567
15726
|
import pc37 from "picocolors";
|
|
15568
15727
|
var restore = addLockWaitOption(
|
|
15569
15728
|
addTargetOptions(
|
|
@@ -15611,18 +15770,18 @@ Run \`vela deploy\` first, then restore.`
|
|
|
15611
15770
|
],
|
|
15612
15771
|
stream: true
|
|
15613
15772
|
});
|
|
15614
|
-
|
|
15773
|
+
p66.log.success(
|
|
15615
15774
|
`Restored ${pc37.cyan(`${ctx.appName} (${ctx.targetName})`)} from ${pc37.cyan(
|
|
15616
15775
|
local ? path63.basename(local) : key
|
|
15617
15776
|
)}.`
|
|
15618
15777
|
);
|
|
15619
15778
|
if (result?.storageCarriedOver) {
|
|
15620
|
-
|
|
15779
|
+
p66.log.info(
|
|
15621
15780
|
"The archive held no uploads, so the files already on the server were kept."
|
|
15622
15781
|
);
|
|
15623
15782
|
}
|
|
15624
15783
|
if (result?.previousDataDir) {
|
|
15625
|
-
|
|
15784
|
+
p66.log.info(
|
|
15626
15785
|
`The database this replaced is at ${pc37.cyan(result.previousDataDir)}.
|
|
15627
15786
|
|
|
15628
15787
|
It is the only way back. Remove it once you are satisfied with the restore.`
|
|
@@ -15663,7 +15822,7 @@ Run ${pc37.cyan("vela backup list")} to see what it does have.`
|
|
|
15663
15822
|
Take one with ${pc37.cyan("vela backup create")}, or pass the path to an archive on this machine.`
|
|
15664
15823
|
);
|
|
15665
15824
|
}
|
|
15666
|
-
const chosen = await
|
|
15825
|
+
const chosen = await p66.select({
|
|
15667
15826
|
message: `Which backup should ${ctx.targetName} be restored from?`,
|
|
15668
15827
|
options: backups.map((b) => ({
|
|
15669
15828
|
value: b.key,
|
|
@@ -15671,8 +15830,8 @@ Take one with ${pc37.cyan("vela backup create")}, or pass the path to an archive
|
|
|
15671
15830
|
hint: `${formatBytes(b.size)}, ${b.modified}`
|
|
15672
15831
|
}))
|
|
15673
15832
|
});
|
|
15674
|
-
if (
|
|
15675
|
-
|
|
15833
|
+
if (p66.isCancel(chosen)) {
|
|
15834
|
+
p66.cancel("Operation cancelled.");
|
|
15676
15835
|
process46.exit(0);
|
|
15677
15836
|
}
|
|
15678
15837
|
return chosen;
|
|
@@ -15680,7 +15839,7 @@ Take one with ${pc37.cyan("vela backup create")}, or pass the path to an archive
|
|
|
15680
15839
|
async function stage(ctx, file) {
|
|
15681
15840
|
const dir = remotePaths.restoreStage(ctx.instance);
|
|
15682
15841
|
const remote = `${dir}/${path63.basename(file)}`;
|
|
15683
|
-
const spinner9 =
|
|
15842
|
+
const spinner9 = p66.spinner();
|
|
15684
15843
|
spinner9.start(`Uploading ${path63.basename(file)}`);
|
|
15685
15844
|
try {
|
|
15686
15845
|
await ctx.session.script(`mkdir -p "$1"`, { args: [dir] });
|
|
@@ -15695,29 +15854,29 @@ async function stage(ctx, file) {
|
|
|
15695
15854
|
async function confirm14(appName, targetName, envTag, from) {
|
|
15696
15855
|
const what = `${pc37.cyan(`${appName} (${targetName})`)} from ${pc37.cyan(path63.basename(from))}`;
|
|
15697
15856
|
if (isProd(envTag)) {
|
|
15698
|
-
const answer = await
|
|
15857
|
+
const answer = await p66.text({
|
|
15699
15858
|
message: `This replaces the database and uploads of ${what}. Type the app name to confirm`,
|
|
15700
15859
|
validate: (value) => value === appName ? void 0 : `Type ${appName} to confirm`
|
|
15701
15860
|
});
|
|
15702
|
-
if (
|
|
15703
|
-
|
|
15861
|
+
if (p66.isCancel(answer)) {
|
|
15862
|
+
p66.cancel("Operation cancelled.");
|
|
15704
15863
|
process46.exit(0);
|
|
15705
15864
|
}
|
|
15706
15865
|
return;
|
|
15707
15866
|
}
|
|
15708
|
-
const ok = await
|
|
15867
|
+
const ok = await p66.confirm({
|
|
15709
15868
|
message: `Replace the database and uploads of ${what}?`,
|
|
15710
15869
|
initialValue: false
|
|
15711
15870
|
});
|
|
15712
|
-
if (
|
|
15713
|
-
|
|
15871
|
+
if (p66.isCancel(ok) || !ok) {
|
|
15872
|
+
p66.cancel("Operation cancelled.");
|
|
15714
15873
|
process46.exit(0);
|
|
15715
15874
|
}
|
|
15716
15875
|
}
|
|
15717
15876
|
|
|
15718
15877
|
// src/commands/targets.ts
|
|
15719
15878
|
import { Command as Command108 } from "commander";
|
|
15720
|
-
import * as
|
|
15879
|
+
import * as p67 from "@clack/prompts";
|
|
15721
15880
|
import pc38 from "picocolors";
|
|
15722
15881
|
import * as v13 from "valibot";
|
|
15723
15882
|
var OptionsSchema6 = v13.object({
|
|
@@ -15791,11 +15950,11 @@ function report4(rows, offline) {
|
|
|
15791
15950
|
const lines = rows.map(
|
|
15792
15951
|
(row) => `${row.kind === "local" ? pc38.dim(row.target.padEnd(target)) : pc38.cyan(row.target.padEnd(target))} ${row.server.padEnd(server)} ${row.domain.padEnd(domain)} ${row.release}`
|
|
15793
15952
|
);
|
|
15794
|
-
|
|
15953
|
+
p67.log.info(`${pc38.dim(header)}
|
|
15795
15954
|
${lines.join("\n")}`);
|
|
15796
15955
|
const unreachable = rows.filter((row) => row.kind === "remote" && !row.reachable);
|
|
15797
15956
|
if (!offline && unreachable.length > 0) {
|
|
15798
|
-
|
|
15957
|
+
p67.log.warn(
|
|
15799
15958
|
`Could not reach ${unreachable.map((row) => row.server).join(", ")}.
|
|
15800
15959
|
Release and domain are shown from what this project recorded.`
|
|
15801
15960
|
);
|
|
@@ -16076,7 +16235,7 @@ import { Command as Command117 } from "commander";
|
|
|
16076
16235
|
// src/commands/cms/deploy.ts
|
|
16077
16236
|
import process49 from "node:process";
|
|
16078
16237
|
import { Command as Command112 } from "commander";
|
|
16079
|
-
import * as
|
|
16238
|
+
import * as p68 from "@clack/prompts";
|
|
16080
16239
|
import pc40 from "picocolors";
|
|
16081
16240
|
var POLL_INTERVAL2 = 5e3;
|
|
16082
16241
|
var POLL_TIMEOUT = 30 * 6e4;
|
|
@@ -16098,18 +16257,18 @@ A site deployed with ${pc40.cyan("vela deploy")} is updated by deploying again.`
|
|
|
16098
16257
|
}
|
|
16099
16258
|
const url = state.site?.url ?? "";
|
|
16100
16259
|
if (inFlight(state.latest)) {
|
|
16101
|
-
|
|
16260
|
+
p68.log.info(`A deploy of ${pc40.cyan(url)} is already in progress.`);
|
|
16102
16261
|
} else {
|
|
16103
16262
|
state = await startSiteDeploy(apiKey, projectId);
|
|
16104
16263
|
}
|
|
16105
16264
|
if (!options.wait) {
|
|
16106
|
-
|
|
16265
|
+
p68.log.success(
|
|
16107
16266
|
`Build started for ${pc40.cyan(url)} (deployment ${pc40.dim(state.latest?.id ?? "")}).
|
|
16108
16267
|
It goes live when the build finishes.`
|
|
16109
16268
|
);
|
|
16110
16269
|
return;
|
|
16111
16270
|
}
|
|
16112
|
-
const spinner9 =
|
|
16271
|
+
const spinner9 = p68.spinner();
|
|
16113
16272
|
spinner9.start(`Building ${url}`);
|
|
16114
16273
|
let latest;
|
|
16115
16274
|
try {
|
|
@@ -16120,7 +16279,7 @@ It goes live when the build finishes.`
|
|
|
16120
16279
|
}
|
|
16121
16280
|
if (!latest) {
|
|
16122
16281
|
spinner9.stop(`Still building ${url}.`);
|
|
16123
|
-
|
|
16282
|
+
p68.log.warn(
|
|
16124
16283
|
`The build has not finished after ${Math.round(POLL_TIMEOUT / 6e4)} minutes.
|
|
16125
16284
|
It goes live on its own if it does; the deployments page on velastack.dev shows how it ends.`
|
|
16126
16285
|
);
|
|
@@ -16175,7 +16334,7 @@ import { Command as Command116 } from "commander";
|
|
|
16175
16334
|
// src/commands/cms/editor/add.ts
|
|
16176
16335
|
import { randomBytes } from "node:crypto";
|
|
16177
16336
|
import { Command as Command113 } from "commander";
|
|
16178
|
-
import * as
|
|
16337
|
+
import * as p69 from "@clack/prompts";
|
|
16179
16338
|
import pc42 from "picocolors";
|
|
16180
16339
|
|
|
16181
16340
|
// src/lib/cms-backend.ts
|
|
@@ -16228,8 +16387,8 @@ var editorAdd = new Command113("add").description("create an editor who can sign
|
|
|
16228
16387
|
if (generated) {
|
|
16229
16388
|
lines.push("", `Password: ${pc42.bold(password8)}`, "", "It is shown once; copy it now.");
|
|
16230
16389
|
}
|
|
16231
|
-
|
|
16232
|
-
|
|
16390
|
+
p69.log.success(lines.join("\n"));
|
|
16391
|
+
p69.log.info(
|
|
16233
16392
|
`Run ${pc42.cyan("vela dev")}, open any page with ${pc42.cyan("?edit")} on the URL (or press ${pc42.cyan("Ctrl+E")}), and sign in.`
|
|
16234
16393
|
);
|
|
16235
16394
|
}, "Failed to add the editor.")
|
|
@@ -16237,12 +16396,12 @@ var editorAdd = new Command113("add").description("create an editor who can sign
|
|
|
16237
16396
|
|
|
16238
16397
|
// src/commands/cms/editor/password.ts
|
|
16239
16398
|
import { Command as Command114 } from "commander";
|
|
16240
|
-
import * as
|
|
16399
|
+
import * as p70 from "@clack/prompts";
|
|
16241
16400
|
import pc43 from "picocolors";
|
|
16242
16401
|
var editorPassword = new Command114("password").description("set an editor's password").argument("<email>", "email of the editor").argument("<password>", "new password").configureHelp(helpConfig).action(
|
|
16243
16402
|
(email2, password8) => runCommand(async () => {
|
|
16244
16403
|
await withCmsBackend((cms3) => cms3.editors.setPassword(email2, password8));
|
|
16245
|
-
|
|
16404
|
+
p70.log.success(
|
|
16246
16405
|
`Updated the password for ${pc43.cyan(email2)}. Existing sessions were signed out.`
|
|
16247
16406
|
);
|
|
16248
16407
|
}, "Failed to set the password.")
|
|
@@ -16250,7 +16409,7 @@ var editorPassword = new Command114("password").description("set an editor's pas
|
|
|
16250
16409
|
|
|
16251
16410
|
// src/commands/cms/editor/list.ts
|
|
16252
16411
|
import { Command as Command115 } from "commander";
|
|
16253
|
-
import * as
|
|
16412
|
+
import * as p71 from "@clack/prompts";
|
|
16254
16413
|
import pc44 from "picocolors";
|
|
16255
16414
|
var editorList = new Command115("list").description("list editors and the projects they may edit").configureHelp(helpConfig).action(
|
|
16256
16415
|
() => runCommand(async () => {
|
|
@@ -16261,11 +16420,11 @@ var editorList = new Command115("list").description("list editors and the projec
|
|
|
16261
16420
|
}))
|
|
16262
16421
|
);
|
|
16263
16422
|
if (rows.length === 0) {
|
|
16264
|
-
|
|
16423
|
+
p71.log.info(`No editors yet. Add one with ${pc44.cyan("vela cms editor add <email>")}.`);
|
|
16265
16424
|
return;
|
|
16266
16425
|
}
|
|
16267
16426
|
const width = Math.max(...rows.map((row) => row.email.length));
|
|
16268
|
-
|
|
16427
|
+
p71.log.info(
|
|
16269
16428
|
`Editors
|
|
16270
16429
|
|
|
16271
16430
|
` + rows.map(
|
|
@@ -16287,7 +16446,7 @@ import { Command as Command121 } from "commander";
|
|
|
16287
16446
|
// src/commands/workflows/list.ts
|
|
16288
16447
|
import process51 from "node:process";
|
|
16289
16448
|
import { Command as Command118, InvalidArgumentError as InvalidArgumentError5 } from "commander";
|
|
16290
|
-
import * as
|
|
16449
|
+
import * as p72 from "@clack/prompts";
|
|
16291
16450
|
import pc45 from "picocolors";
|
|
16292
16451
|
|
|
16293
16452
|
// src/lib/workflows-api.ts
|
|
@@ -16370,7 +16529,7 @@ var workflowsList = new Command118("list").description("list recent workflow run
|
|
|
16370
16529
|
limit: options.limit
|
|
16371
16530
|
});
|
|
16372
16531
|
if (runs.length === 0) {
|
|
16373
|
-
|
|
16532
|
+
p72.log.info(
|
|
16374
16533
|
`No workflow runs yet.
|
|
16375
16534
|
|
|
16376
16535
|
Start one from server code with ${pc45.cyan("<workflow>.run(input)")}, or with ${pc45.cyan("vela workflows run <name>")}.`
|
|
@@ -16378,7 +16537,7 @@ Start one from server code with ${pc45.cyan("<workflow>.run(input)")}, or with $
|
|
|
16378
16537
|
return;
|
|
16379
16538
|
}
|
|
16380
16539
|
const width = Math.max(...runs.map((r) => r.workflowName.length));
|
|
16381
|
-
|
|
16540
|
+
p72.log.message(runs.map((r) => formatRun(r, width)).join("\n"));
|
|
16382
16541
|
});
|
|
16383
16542
|
}, "Failed to list workflow runs.")
|
|
16384
16543
|
);
|
|
@@ -16386,7 +16545,7 @@ Start one from server code with ${pc45.cyan("<workflow>.run(input)")}, or with $
|
|
|
16386
16545
|
// src/commands/workflows/run.ts
|
|
16387
16546
|
import process52 from "node:process";
|
|
16388
16547
|
import { Command as Command119, InvalidArgumentError as InvalidArgumentError6 } from "commander";
|
|
16389
|
-
import * as
|
|
16548
|
+
import * as p73 from "@clack/prompts";
|
|
16390
16549
|
import pc46 from "picocolors";
|
|
16391
16550
|
function parseInput(value) {
|
|
16392
16551
|
try {
|
|
@@ -16399,7 +16558,7 @@ var workflowsRun = new Command119("run").description("start a run of a workflow;
|
|
|
16399
16558
|
(name, input) => runCommand(async () => {
|
|
16400
16559
|
await withPocketbase(process52.cwd(), async (pb) => {
|
|
16401
16560
|
const run = await createRun(pb, name, input);
|
|
16402
|
-
|
|
16561
|
+
p73.log.success(
|
|
16403
16562
|
`Queued ${pc46.cyan(name)} as run ${pc46.bold(run.id)}.
|
|
16404
16563
|
|
|
16405
16564
|
It runs once the app is up (${pc46.cyan("vela dev")}); ${pc46.cyan("vela workflows list")} shows its state.`
|
|
@@ -16411,13 +16570,13 @@ It runs once the app is up (${pc46.cyan("vela dev")}); ${pc46.cyan("vela workflo
|
|
|
16411
16570
|
// src/commands/workflows/cancel.ts
|
|
16412
16571
|
import process53 from "node:process";
|
|
16413
16572
|
import { Command as Command120 } from "commander";
|
|
16414
|
-
import * as
|
|
16573
|
+
import * as p74 from "@clack/prompts";
|
|
16415
16574
|
import pc47 from "picocolors";
|
|
16416
16575
|
var workflowsCancel = new Command120("cancel").description("cancel a pending or running workflow run").argument("<run-id>", "the run id from `vela workflows list`").configureHelp(helpConfig).action(
|
|
16417
16576
|
(id) => runCommand(async () => {
|
|
16418
16577
|
await withPocketbase(process53.cwd(), async (pb) => {
|
|
16419
16578
|
const run = await cancelRun(pb, id);
|
|
16420
|
-
|
|
16579
|
+
p74.log.success(`Canceled run ${pc47.bold(run.id)} of ${pc47.cyan(run.workflowName)}.`);
|
|
16421
16580
|
});
|
|
16422
16581
|
}, "Failed to cancel the workflow run.")
|
|
16423
16582
|
);
|
|
@@ -16507,17 +16666,17 @@ program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
|
16507
16666
|
if (NO_BACKEND_COMMMANDS.has(top)) return;
|
|
16508
16667
|
if (!hasBackend()) {
|
|
16509
16668
|
if (BACKEND_OPTIONAL_COMMANDS.has(top)) return;
|
|
16510
|
-
|
|
16511
|
-
|
|
16512
|
-
|
|
16669
|
+
p75.log.error(missingBackendMessage(`vela ${path68}`));
|
|
16670
|
+
p75.log.message();
|
|
16671
|
+
p75.cancel("Operation failed.");
|
|
16513
16672
|
process54.exit(1);
|
|
16514
16673
|
}
|
|
16515
16674
|
if (SELF_CREDENTIALED_COMMANDS.has(path68)) return;
|
|
16516
16675
|
if (path68 === "generate migration" && actionCommand.opts().ai) return;
|
|
16517
16676
|
if (!hasSuperuserCredentials()) {
|
|
16518
|
-
|
|
16519
|
-
|
|
16520
|
-
|
|
16677
|
+
p75.log.error(missingCredentialsMessage());
|
|
16678
|
+
p75.log.message();
|
|
16679
|
+
p75.cancel("Operation failed.");
|
|
16521
16680
|
process54.exit(1);
|
|
16522
16681
|
}
|
|
16523
16682
|
});
|