vela 0.10.8 → 0.10.10
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 +801 -594
- package/dist/bin.js.map +4 -4
- package/package.json +2 -2
package/dist/bin.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/bin.ts
|
|
4
|
-
import
|
|
4
|
+
import process37 from "node:process";
|
|
5
5
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
6
6
|
|
|
7
7
|
// package.json
|
|
8
8
|
var package_default = {
|
|
9
9
|
name: "vela",
|
|
10
|
-
version: "0.10.
|
|
10
|
+
version: "0.10.10",
|
|
11
11
|
type: "module",
|
|
12
12
|
description: "A CLI for creating and updating SvelteKit projects",
|
|
13
13
|
license: "MIT",
|
|
@@ -41,7 +41,7 @@ var package_default = {
|
|
|
41
41
|
dependencies: {
|
|
42
42
|
"@clack/prompts": "^1.7.0",
|
|
43
43
|
"@faker-js/faker": "^10.6.0",
|
|
44
|
-
"@velastack/patterns": "^0.1.
|
|
44
|
+
"@velastack/patterns": "^0.1.6",
|
|
45
45
|
"@velastack/pocketbase-codegen": "^0.1.0",
|
|
46
46
|
"annotate-json-schema": "^0.1.0",
|
|
47
47
|
commander: "^13.1.0",
|
|
@@ -168,12 +168,12 @@ function delegateToLocalCli(opts) {
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
// src/program.ts
|
|
171
|
-
import
|
|
172
|
-
import * as
|
|
173
|
-
import { Command as
|
|
171
|
+
import process36 from "node:process";
|
|
172
|
+
import * as p54 from "@clack/prompts";
|
|
173
|
+
import { Command as Command100 } from "commander";
|
|
174
174
|
import nodePath from "node:path";
|
|
175
175
|
import dotenv2 from "dotenv";
|
|
176
|
-
import
|
|
176
|
+
import pc36 from "picocolors";
|
|
177
177
|
|
|
178
178
|
// src/lib/help.ts
|
|
179
179
|
import pc from "picocolors";
|
|
@@ -350,8 +350,8 @@ function mergePackageJson(user, template) {
|
|
|
350
350
|
}
|
|
351
351
|
return { merged, added, conflicts, replaced };
|
|
352
352
|
}
|
|
353
|
-
function readPackageJson(
|
|
354
|
-
return JSON.parse(fs2.readFileSync(
|
|
353
|
+
function readPackageJson(path49) {
|
|
354
|
+
return JSON.parse(fs2.readFileSync(path49, "utf8"));
|
|
355
355
|
}
|
|
356
356
|
var PACKAGE_NAME_PLACEHOLDER = /~TODO~/g;
|
|
357
357
|
var APP_NAME_PLACEHOLDER = /~APP_NAME~/g;
|
|
@@ -364,12 +364,12 @@ function fillTemplatePlaceholders(raw, values) {
|
|
|
364
364
|
function escapeSingleQuoted(value) {
|
|
365
365
|
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
366
366
|
}
|
|
367
|
-
function readTemplatePackageJson(
|
|
368
|
-
const raw = fillTemplatePlaceholders(fs2.readFileSync(
|
|
367
|
+
function readTemplatePackageJson(path49, values) {
|
|
368
|
+
const raw = fillTemplatePlaceholders(fs2.readFileSync(path49, "utf8"), values);
|
|
369
369
|
return JSON.parse(raw);
|
|
370
370
|
}
|
|
371
|
-
function writePackageJson(
|
|
372
|
-
fs2.writeFileSync(
|
|
371
|
+
function writePackageJson(path49, pkg) {
|
|
372
|
+
fs2.writeFileSync(path49, JSON.stringify(pkg, null, " ") + "\n");
|
|
373
373
|
}
|
|
374
374
|
function toValidPackageName(name) {
|
|
375
375
|
return name.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._]/, "").replace(/[^a-z0-9~.-]+/g, "-");
|
|
@@ -437,11 +437,12 @@ function detectFeatures(root, { isAppMode, isPaymentsMode }) {
|
|
|
437
437
|
api: has("src/routes/api"),
|
|
438
438
|
apiKeys: has("src/routes/api/api-keys") || has("src/routes/(app)/api-keys"),
|
|
439
439
|
backend: has(DATA_DIR),
|
|
440
|
-
i18n: has("
|
|
440
|
+
i18n: has("wuchale.config.js") || hasDep("wuchale"),
|
|
441
441
|
teams: has("src/routes/(app)/teams") || has("src/lib/teams"),
|
|
442
442
|
payments: isPaymentsMode,
|
|
443
443
|
blog: hasDep("mdsvex"),
|
|
444
|
-
contentNegotiation: hasDep("sveltekit-negotiate")
|
|
444
|
+
contentNegotiation: hasDep("sveltekit-negotiate"),
|
|
445
|
+
cms: hasDep("@velastack/cms")
|
|
445
446
|
};
|
|
446
447
|
}
|
|
447
448
|
|
|
@@ -1210,13 +1211,20 @@ function reportResult(report4) {
|
|
|
1210
1211
|
body.push(`${label3}:`);
|
|
1211
1212
|
for (const item of items) body.push(`- ${item}`);
|
|
1212
1213
|
}
|
|
1214
|
+
const failures = report4.failures ?? [];
|
|
1213
1215
|
if (body.length > 0) {
|
|
1214
1216
|
p3.log.success(`${report4.summary}
|
|
1215
1217
|
|
|
1216
1218
|
${body.join("\n")}`);
|
|
1217
|
-
} else {
|
|
1219
|
+
} else if (failures.length === 0) {
|
|
1218
1220
|
p3.log.success(report4.summary);
|
|
1219
1221
|
}
|
|
1222
|
+
for (const failure of failures) {
|
|
1223
|
+
const headline = failure.status === "not-found" ? `Could not find ${failure.path}` : `Could not update ${failure.path}`;
|
|
1224
|
+
p3.log.warn(failure.message ? `${headline}
|
|
1225
|
+
|
|
1226
|
+
${failure.message}` : headline);
|
|
1227
|
+
}
|
|
1220
1228
|
if (report4.nextSteps && report4.nextSteps.length > 0) {
|
|
1221
1229
|
p3.note(report4.nextSteps.map((s) => `- ${s}`).join("\n"), "Next steps", {
|
|
1222
1230
|
format: (line) => line
|
|
@@ -1749,13 +1757,14 @@ import { bySlug } from "@velastack/patterns";
|
|
|
1749
1757
|
function toRelative(root, filePath) {
|
|
1750
1758
|
return path13.isAbsolute(filePath) ? path13.relative(root, filePath) : filePath;
|
|
1751
1759
|
}
|
|
1760
|
+
var isSuccess = (f) => (f.status ?? "success") === "success";
|
|
1752
1761
|
async function runPattern(slug2, argv2, input, report4) {
|
|
1753
1762
|
const pattern = bySlug[slug2];
|
|
1754
1763
|
if (!pattern) {
|
|
1755
1764
|
throw new Error(`Unknown pattern: ${slug2}`);
|
|
1756
1765
|
}
|
|
1757
1766
|
const { workspaceRootDir, features } = await getWorkspace();
|
|
1758
|
-
const
|
|
1767
|
+
const log41 = p6.taskLog({ title: report4.task.title });
|
|
1759
1768
|
let result;
|
|
1760
1769
|
try {
|
|
1761
1770
|
result = await pattern.generate({
|
|
@@ -1775,28 +1784,40 @@ async function runPattern(slug2, argv2, input, report4) {
|
|
|
1775
1784
|
});
|
|
1776
1785
|
return collections2;
|
|
1777
1786
|
},
|
|
1778
|
-
logger: { info: (message) =>
|
|
1787
|
+
logger: { info: (message) => log41.message(message) }
|
|
1779
1788
|
});
|
|
1780
|
-
|
|
1789
|
+
log41.success(report4.task.success);
|
|
1781
1790
|
} catch (e) {
|
|
1782
|
-
|
|
1791
|
+
log41.error(report4.task.error);
|
|
1783
1792
|
throw e;
|
|
1784
1793
|
}
|
|
1785
1794
|
const rel = (f) => toRelative(workspaceRootDir, f);
|
|
1786
|
-
const
|
|
1787
|
-
|
|
1795
|
+
const files = [...result.creates, ...result.modifies, ...result.deletes];
|
|
1796
|
+
const failures = files.filter((f) => !isSuccess(f)).map((f) => ({
|
|
1797
|
+
path: rel(f.path),
|
|
1798
|
+
status: f.status === "not-found" ? "not-found" : "failed",
|
|
1799
|
+
message: f.message
|
|
1800
|
+
}));
|
|
1801
|
+
const created = result.creates.filter(isSuccess);
|
|
1802
|
+
const modified = result.modifies.filter(isSuccess);
|
|
1803
|
+
const deleted = result.deletes.filter(isSuccess);
|
|
1804
|
+
const totalChanges = created.length + modified.length + deleted.length + result.components.length + result.packages.length + result.collections.length;
|
|
1805
|
+
if (totalChanges === 0 && failures.length === 0) {
|
|
1788
1806
|
p6.log.info(`${pattern.title ?? slug2} produced no changes.`);
|
|
1789
1807
|
return;
|
|
1790
1808
|
}
|
|
1791
1809
|
reportResult({
|
|
1792
1810
|
summary: report4.summary ?? `Applied ${pattern.title ?? slug2}.`,
|
|
1793
|
-
filesCreated:
|
|
1794
|
-
filesModified:
|
|
1795
|
-
filesDeleted:
|
|
1811
|
+
filesCreated: created.map((f) => rel(f.path)),
|
|
1812
|
+
filesModified: modified.map((f) => rel(f.path)),
|
|
1813
|
+
filesDeleted: deleted.map((f) => rel(f.path)),
|
|
1796
1814
|
componentsAdded: result.components,
|
|
1797
1815
|
packagesInstalled: result.packages,
|
|
1798
1816
|
collectionsAdded: result.collections.map((c) => c.name),
|
|
1799
|
-
|
|
1817
|
+
failures,
|
|
1818
|
+
// Next steps assume the pattern applied; when part of it didn't, the
|
|
1819
|
+
// remediation snippets above are the actual next step.
|
|
1820
|
+
nextSteps: failures.length > 0 ? void 0 : report4.nextSteps
|
|
1800
1821
|
});
|
|
1801
1822
|
}
|
|
1802
1823
|
|
|
@@ -2378,7 +2399,7 @@ var migration = new Command8("migration").description("generate a migration for
|
|
|
2378
2399
|
var generate = new Command9("generate").description("generate scaffolding for database models and forms").configureHelp(helpConfig).addCommand(form).addCommand(schema).addCommand(resource).addCommand(scaffold).addCommand(migration);
|
|
2379
2400
|
|
|
2380
2401
|
// src/commands/enable.ts
|
|
2381
|
-
import { Command as
|
|
2402
|
+
import { Command as Command23 } from "commander";
|
|
2382
2403
|
|
|
2383
2404
|
// src/commands/enable/auth.ts
|
|
2384
2405
|
import { Command as Command10 } from "commander";
|
|
@@ -3924,11 +3945,47 @@ var smtp = new Command19("smtp").description("configure SMTP for transactional e
|
|
|
3924
3945
|
);
|
|
3925
3946
|
|
|
3926
3947
|
// src/commands/enable/cms.ts
|
|
3927
|
-
|
|
3948
|
+
import process13 from "node:process";
|
|
3949
|
+
import { Command as Command20 } from "commander";
|
|
3950
|
+
import * as p19 from "@clack/prompts";
|
|
3951
|
+
import pc9 from "picocolors";
|
|
3952
|
+
var cms = new Command20("cms").description("enable an inline-editing CMS with an admin bar").allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
3953
|
+
(_opts, cmd) => runCommand(async () => {
|
|
3954
|
+
if (!hasBackend()) {
|
|
3955
|
+
p19.log.error(
|
|
3956
|
+
`${pc9.cyan("vela enable cms")} needs a server to host the CMS backend, and this project is static.
|
|
3957
|
+
|
|
3958
|
+
Run ${pc9.cyan("vela bless")} to add a backend first.`
|
|
3959
|
+
);
|
|
3960
|
+
p19.log.message();
|
|
3961
|
+
p19.cancel("Operation failed.");
|
|
3962
|
+
process13.exitCode = 1;
|
|
3963
|
+
return;
|
|
3964
|
+
}
|
|
3965
|
+
await runPattern(
|
|
3966
|
+
"enable-cms",
|
|
3967
|
+
cmd.args,
|
|
3968
|
+
{},
|
|
3969
|
+
{
|
|
3970
|
+
summary: "Enabled CMS.",
|
|
3971
|
+
nextSteps: [
|
|
3972
|
+
"Run `vela cms editor add you@example.com` to create the first editor login.",
|
|
3973
|
+
"Run `vela dev`, open any page with `?edit` on the URL, and sign in from the admin bar.",
|
|
3974
|
+
"Wrap page copy in `<CmsText>` and images in `<CmsImage>` to make them editable."
|
|
3975
|
+
],
|
|
3976
|
+
task: {
|
|
3977
|
+
title: "Enabling CMS",
|
|
3978
|
+
success: "Enabled CMS",
|
|
3979
|
+
error: "Failed to enable CMS"
|
|
3980
|
+
}
|
|
3981
|
+
}
|
|
3982
|
+
);
|
|
3983
|
+
}, "Failed to enable CMS.")
|
|
3984
|
+
);
|
|
3928
3985
|
|
|
3929
3986
|
// src/commands/enable/blog.ts
|
|
3930
|
-
import { Command as
|
|
3931
|
-
var blog = new
|
|
3987
|
+
import { Command as Command21 } from "commander";
|
|
3988
|
+
var blog = new Command21("blog").description("enable an mdsvex blog with posts, tags, and RSS").allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
3932
3989
|
(_opts, cmd) => runCommand(
|
|
3933
3990
|
() => runPattern(
|
|
3934
3991
|
"enable-blog",
|
|
@@ -3953,8 +4010,8 @@ var blog = new Command20("blog").description("enable an mdsvex blog with posts,
|
|
|
3953
4010
|
);
|
|
3954
4011
|
|
|
3955
4012
|
// src/commands/enable/content-negotiation.ts
|
|
3956
|
-
import { Command as
|
|
3957
|
-
var contentNegotiation = new
|
|
4013
|
+
import { Command as Command22 } from "commander";
|
|
4014
|
+
var contentNegotiation = new Command22("content-negotiation").description("enable content negotiation (sveltekit-negotiate)").allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
3958
4015
|
(_opts, cmd) => runCommand(
|
|
3959
4016
|
() => runPattern(
|
|
3960
4017
|
"enable-content-negotiation",
|
|
@@ -3978,33 +4035,33 @@ var contentNegotiation = new Command21("content-negotiation").description("enabl
|
|
|
3978
4035
|
);
|
|
3979
4036
|
|
|
3980
4037
|
// src/commands/enable.ts
|
|
3981
|
-
var enable = new
|
|
4038
|
+
var enable = new Command23("enable").description("enable features").configureHelp(helpConfig).addCommand(auth).addCommand(api).addCommand(apiKeys).addCommand(backend).addCommand(contentNegotiation).addCommand(i18n).addCommand(teams).addCommand(payments).addCommand(subscriptions).addCommand(s3).addCommand(smtp).addCommand(cms).addCommand(blog);
|
|
3982
4039
|
|
|
3983
4040
|
// src/commands/disable.ts
|
|
3984
|
-
import { Command as
|
|
4041
|
+
import { Command as Command34 } from "commander";
|
|
3985
4042
|
|
|
3986
4043
|
// src/commands/disable/auth.ts
|
|
3987
|
-
import { Command as
|
|
4044
|
+
import { Command as Command24 } from "commander";
|
|
3988
4045
|
|
|
3989
4046
|
// src/commands/disable/_shared.ts
|
|
3990
|
-
import
|
|
3991
|
-
import * as
|
|
4047
|
+
import process14 from "node:process";
|
|
4048
|
+
import * as p20 from "@clack/prompts";
|
|
3992
4049
|
async function runDisable(opts, flags, cmdArgs) {
|
|
3993
4050
|
if (!flags.yes) {
|
|
3994
|
-
const ok = await
|
|
4051
|
+
const ok = await p20.confirm({
|
|
3995
4052
|
message: opts.confirmMessage,
|
|
3996
4053
|
initialValue: false
|
|
3997
4054
|
});
|
|
3998
|
-
if (
|
|
3999
|
-
|
|
4000
|
-
|
|
4055
|
+
if (p20.isCancel(ok) || !ok) {
|
|
4056
|
+
p20.cancel("Operation cancelled.");
|
|
4057
|
+
process14.exit(0);
|
|
4001
4058
|
}
|
|
4002
4059
|
}
|
|
4003
4060
|
await runPattern(opts.slug, cmdArgs, { destructive: true }, opts.report);
|
|
4004
4061
|
}
|
|
4005
4062
|
|
|
4006
4063
|
// src/commands/disable/auth.ts
|
|
4007
|
-
var auth2 = new
|
|
4064
|
+
var auth2 = new Command24("auth").description("disable authentication").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
4008
4065
|
(opts, cmd) => runCommand(
|
|
4009
4066
|
() => runDisable(
|
|
4010
4067
|
{
|
|
@@ -4030,8 +4087,8 @@ var auth2 = new Command23("auth").description("disable authentication").option("
|
|
|
4030
4087
|
);
|
|
4031
4088
|
|
|
4032
4089
|
// src/commands/disable/api.ts
|
|
4033
|
-
import { Command as
|
|
4034
|
-
var api2 = new
|
|
4090
|
+
import { Command as Command25 } from "commander";
|
|
4091
|
+
var api2 = new Command25("api").description("disable the REST API").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
4035
4092
|
(opts, cmd) => runCommand(
|
|
4036
4093
|
() => runDisable(
|
|
4037
4094
|
{
|
|
@@ -4054,8 +4111,8 @@ var api2 = new Command24("api").description("disable the REST API").option("-y,
|
|
|
4054
4111
|
);
|
|
4055
4112
|
|
|
4056
4113
|
// src/commands/disable/api-keys.ts
|
|
4057
|
-
import { Command as
|
|
4058
|
-
var apiKeys2 = new
|
|
4114
|
+
import { Command as Command26 } from "commander";
|
|
4115
|
+
var apiKeys2 = new Command26("api-keys").description("disable API key management").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
4059
4116
|
(opts, cmd) => runCommand(
|
|
4060
4117
|
() => runDisable(
|
|
4061
4118
|
{
|
|
@@ -4078,8 +4135,8 @@ var apiKeys2 = new Command25("api-keys").description("disable API key management
|
|
|
4078
4135
|
);
|
|
4079
4136
|
|
|
4080
4137
|
// src/commands/disable/backend.ts
|
|
4081
|
-
import { Command as
|
|
4082
|
-
var backend2 = new
|
|
4138
|
+
import { Command as Command27 } from "commander";
|
|
4139
|
+
var backend2 = new Command27("backend").description("disable the PocketBase backend").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
4083
4140
|
(opts, cmd) => runCommand(
|
|
4084
4141
|
() => runDisable(
|
|
4085
4142
|
{
|
|
@@ -4102,8 +4159,8 @@ var backend2 = new Command26("backend").description("disable the PocketBase back
|
|
|
4102
4159
|
);
|
|
4103
4160
|
|
|
4104
4161
|
// src/commands/disable/content-negotiation.ts
|
|
4105
|
-
import { Command as
|
|
4106
|
-
var contentNegotiation2 = new
|
|
4162
|
+
import { Command as Command28 } from "commander";
|
|
4163
|
+
var contentNegotiation2 = new Command28("content-negotiation").description("disable content negotiation").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
4107
4164
|
(opts, cmd) => runCommand(
|
|
4108
4165
|
() => runDisable(
|
|
4109
4166
|
{
|
|
@@ -4126,8 +4183,8 @@ var contentNegotiation2 = new Command27("content-negotiation").description("disa
|
|
|
4126
4183
|
);
|
|
4127
4184
|
|
|
4128
4185
|
// src/commands/disable/i18n.ts
|
|
4129
|
-
import { Command as
|
|
4130
|
-
var i18n2 = new
|
|
4186
|
+
import { Command as Command29 } from "commander";
|
|
4187
|
+
var i18n2 = new Command29("i18n").description("disable internationalization").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
4131
4188
|
(opts, cmd) => runCommand(
|
|
4132
4189
|
() => runDisable(
|
|
4133
4190
|
{
|
|
@@ -4153,8 +4210,8 @@ var i18n2 = new Command28("i18n").description("disable internationalization").op
|
|
|
4153
4210
|
);
|
|
4154
4211
|
|
|
4155
4212
|
// src/commands/disable/teams.ts
|
|
4156
|
-
import { Command as
|
|
4157
|
-
var teams2 = new
|
|
4213
|
+
import { Command as Command30 } from "commander";
|
|
4214
|
+
var teams2 = new Command30("teams").description("disable teams").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
4158
4215
|
(opts, cmd) => runCommand(
|
|
4159
4216
|
() => runDisable(
|
|
4160
4217
|
{
|
|
@@ -4180,8 +4237,8 @@ var teams2 = new Command29("teams").description("disable teams").option("-y, --y
|
|
|
4180
4237
|
);
|
|
4181
4238
|
|
|
4182
4239
|
// src/commands/disable/payments.ts
|
|
4183
|
-
import { Command as
|
|
4184
|
-
var payments2 = new
|
|
4240
|
+
import { Command as Command31 } from "commander";
|
|
4241
|
+
var payments2 = new Command31("payments").description("disable payments").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
4185
4242
|
(opts, cmd) => runCommand(
|
|
4186
4243
|
() => runDisable(
|
|
4187
4244
|
{
|
|
@@ -4208,11 +4265,11 @@ var payments2 = new Command30("payments").description("disable payments").option
|
|
|
4208
4265
|
);
|
|
4209
4266
|
|
|
4210
4267
|
// src/commands/disable/s3.ts
|
|
4211
|
-
import { Command as
|
|
4212
|
-
import * as
|
|
4213
|
-
import
|
|
4268
|
+
import { Command as Command32 } from "commander";
|
|
4269
|
+
import * as p21 from "@clack/prompts";
|
|
4270
|
+
import pc10 from "picocolors";
|
|
4214
4271
|
var s32 = addTargetOptions(
|
|
4215
|
-
new
|
|
4272
|
+
new Command32("s3").description("disable S3 file storage").option("--backups", "keep backups on the server again, rather than uploads").configureHelp(helpConfig),
|
|
4216
4273
|
"local"
|
|
4217
4274
|
).action(
|
|
4218
4275
|
(raw) => runCommand(() => {
|
|
@@ -4221,14 +4278,14 @@ var s32 = addTargetOptions(
|
|
|
4221
4278
|
return withBackupTarget(raw, "disable s3", async (ctx) => {
|
|
4222
4279
|
const existing = await readS3(ctx.pb, filesystem);
|
|
4223
4280
|
if (!existing.enabled) {
|
|
4224
|
-
|
|
4281
|
+
p21.log.info(`S3 ${label2(filesystem)} is already off for ${ctx.targetName}.`);
|
|
4225
4282
|
return;
|
|
4226
4283
|
}
|
|
4227
4284
|
await disableS3(ctx.pb, filesystem);
|
|
4228
4285
|
reportResult({
|
|
4229
4286
|
summary: `Disabled S3 ${label2(filesystem)} on ${ctx.targetName}.`,
|
|
4230
4287
|
nextSteps: filesystem === "backups" ? ["New backups are written to the server again."] : [
|
|
4231
|
-
`Anything uploaded while S3 was on is still in ${
|
|
4288
|
+
`Anything uploaded while S3 was on is still in ${pc10.cyan(existing.bucket || "the bucket")} and will now 404.`,
|
|
4232
4289
|
"Copy it back first if you need it: `rclone copy <remote>:<bucket>/ <storage dir>/`.",
|
|
4233
4290
|
"The credentials are kept, so `vela enable s3` does not mean retyping them."
|
|
4234
4291
|
]
|
|
@@ -4241,8 +4298,8 @@ function label2(filesystem) {
|
|
|
4241
4298
|
}
|
|
4242
4299
|
|
|
4243
4300
|
// src/commands/disable/smtp.ts
|
|
4244
|
-
import { Command as
|
|
4245
|
-
var smtp2 = new
|
|
4301
|
+
import { Command as Command33 } from "commander";
|
|
4302
|
+
var smtp2 = new Command33("smtp").description("disable SMTP configuration").configureHelp(helpConfig).action(
|
|
4246
4303
|
() => runCommand(async () => {
|
|
4247
4304
|
const { workspaceRootDir } = await getWorkspace();
|
|
4248
4305
|
await withPocketbase(workspaceRootDir, async (pb) => {
|
|
@@ -4259,30 +4316,30 @@ var smtp2 = new Command32("smtp").description("disable SMTP configuration").conf
|
|
|
4259
4316
|
);
|
|
4260
4317
|
|
|
4261
4318
|
// src/commands/disable.ts
|
|
4262
|
-
var disable = new
|
|
4319
|
+
var disable = new Command34("disable").description("disable features").configureHelp(helpConfig).addCommand(auth2).addCommand(api2).addCommand(apiKeys2).addCommand(backend2).addCommand(contentNegotiation2).addCommand(i18n2).addCommand(teams2).addCommand(payments2).addCommand(s32).addCommand(smtp2);
|
|
4263
4320
|
|
|
4264
4321
|
// src/commands/destroy.ts
|
|
4265
|
-
import { Command as
|
|
4322
|
+
import { Command as Command40 } from "commander";
|
|
4266
4323
|
|
|
4267
4324
|
// src/commands/destroy/form.ts
|
|
4268
|
-
import { Command as
|
|
4325
|
+
import { Command as Command35 } from "commander";
|
|
4269
4326
|
|
|
4270
4327
|
// src/commands/destroy/_shared.ts
|
|
4271
|
-
import
|
|
4272
|
-
import * as
|
|
4328
|
+
import process15 from "node:process";
|
|
4329
|
+
import * as p22 from "@clack/prompts";
|
|
4273
4330
|
async function runDestroy(slug2, model, confirmMessage, report4, flags) {
|
|
4274
4331
|
if (!flags.yes) {
|
|
4275
|
-
const ok = await
|
|
4276
|
-
if (
|
|
4277
|
-
|
|
4278
|
-
|
|
4332
|
+
const ok = await p22.confirm({ message: confirmMessage, initialValue: false });
|
|
4333
|
+
if (p22.isCancel(ok) || !ok) {
|
|
4334
|
+
p22.cancel("Operation cancelled.");
|
|
4335
|
+
process15.exit(0);
|
|
4279
4336
|
}
|
|
4280
4337
|
}
|
|
4281
4338
|
await runPattern(slug2, [model], { destructive: true, route: flags.route }, report4);
|
|
4282
4339
|
}
|
|
4283
4340
|
|
|
4284
4341
|
// src/commands/destroy/form.ts
|
|
4285
|
-
var form2 = new
|
|
4342
|
+
var form2 = new Command35("form").description("destroy a form generated by `vela generate form`").argument("<model>", "model name used when the form was generated (e.g., contact, login)").option("-y, --yes", "skip confirmation prompt").option(
|
|
4286
4343
|
"--route <route>",
|
|
4287
4344
|
"custom route the form was generated at (must match the --route used at generation)"
|
|
4288
4345
|
).allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
@@ -4306,8 +4363,8 @@ var form2 = new Command34("form").description("destroy a form generated by `vela
|
|
|
4306
4363
|
);
|
|
4307
4364
|
|
|
4308
4365
|
// src/commands/destroy/schema.ts
|
|
4309
|
-
import { Command as
|
|
4310
|
-
var schema2 = new
|
|
4366
|
+
import { Command as Command36 } from "commander";
|
|
4367
|
+
var schema2 = new Command36("schema").description("destroy a zod schema generated by `vela generate schema`").argument("<model>", "schema model name (e.g., contact, login)").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
4311
4368
|
(model, opts) => runCommand(
|
|
4312
4369
|
() => runDestroy(
|
|
4313
4370
|
"destroy-schema",
|
|
@@ -4328,8 +4385,8 @@ var schema2 = new Command35("schema").description("destroy a zod schema generate
|
|
|
4328
4385
|
);
|
|
4329
4386
|
|
|
4330
4387
|
// src/commands/destroy/resource.ts
|
|
4331
|
-
import { Command as
|
|
4332
|
-
var resource2 = new
|
|
4388
|
+
import { Command as Command37 } from "commander";
|
|
4389
|
+
var resource2 = new Command37("resource").description("destroy a resource generated by `vela generate resource`").argument("<model>", "model path used when the resource was generated (e.g., contacts, articles)").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
4333
4390
|
(model, opts) => runCommand(
|
|
4334
4391
|
() => runDestroy(
|
|
4335
4392
|
"destroy-resource",
|
|
@@ -4350,8 +4407,8 @@ var resource2 = new Command36("resource").description("destroy a resource genera
|
|
|
4350
4407
|
);
|
|
4351
4408
|
|
|
4352
4409
|
// src/commands/destroy/scaffold.ts
|
|
4353
|
-
import { Command as
|
|
4354
|
-
var scaffold2 = new
|
|
4410
|
+
import { Command as Command38 } from "commander";
|
|
4411
|
+
var scaffold2 = new Command38("scaffold").description("destroy a scaffold generated by `vela generate scaffold`").argument("<model>", "model name used when the scaffold was generated (e.g., contact, todo)").option("-y, --yes", "skip confirmation prompt").option(
|
|
4355
4412
|
"--route <route>",
|
|
4356
4413
|
"custom route the scaffold was generated at (must match the --route used at generation)"
|
|
4357
4414
|
).allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
@@ -4378,12 +4435,12 @@ var scaffold2 = new Command37("scaffold").description("destroy a scaffold genera
|
|
|
4378
4435
|
);
|
|
4379
4436
|
|
|
4380
4437
|
// src/commands/destroy/deployment.ts
|
|
4381
|
-
import
|
|
4382
|
-
import { Command as
|
|
4383
|
-
import * as
|
|
4384
|
-
import
|
|
4438
|
+
import process16 from "node:process";
|
|
4439
|
+
import { Command as Command39 } from "commander";
|
|
4440
|
+
import * as p23 from "@clack/prompts";
|
|
4441
|
+
import pc11 from "picocolors";
|
|
4385
4442
|
var deployment = addTargetOptions(
|
|
4386
|
-
new
|
|
4443
|
+
new Command39("deployment").description("remove a deployed environment from its server").configureHelp(helpConfig),
|
|
4387
4444
|
"production"
|
|
4388
4445
|
).option("--purge", "also delete the database and uploaded files").option("-y, --yes", "skip the confirmation prompt").action(
|
|
4389
4446
|
(raw) => runCommand(async () => {
|
|
@@ -4399,10 +4456,10 @@ var deployment = addTargetOptions(
|
|
|
4399
4456
|
args: [ctx.instance, ...options.purge ? ["--purge"] : []],
|
|
4400
4457
|
stream: true
|
|
4401
4458
|
});
|
|
4402
|
-
|
|
4403
|
-
`Removed ${
|
|
4459
|
+
p23.log.success(
|
|
4460
|
+
`Removed ${pc11.cyan(`${ctx.appName} (${ctx.targetName})`)} from ${ctx.server}.` + (result?.purged ? "" : `
|
|
4404
4461
|
|
|
4405
|
-
The database and uploads are still in the instance's shared directory. Pass ${
|
|
4462
|
+
The database and uploads are still in the instance's shared directory. Pass ${pc11.cyan("--purge")} to delete them.`)
|
|
4406
4463
|
);
|
|
4407
4464
|
}
|
|
4408
4465
|
},
|
|
@@ -4415,37 +4472,37 @@ The database and uploads are still in the instance's shared directory. Pass ${pc
|
|
|
4415
4472
|
);
|
|
4416
4473
|
async function confirm7(appName, targetName, envTag, purge) {
|
|
4417
4474
|
if (isProd(envTag) || purge) {
|
|
4418
|
-
const answer = await
|
|
4419
|
-
message: `This removes ${
|
|
4475
|
+
const answer = await p23.text({
|
|
4476
|
+
message: `This removes ${pc11.cyan(`${appName} (${targetName})`)}${purge ? " and its database" : ""}. Type the app name to confirm`,
|
|
4420
4477
|
validate: (value) => value === appName ? void 0 : `Type ${appName} to confirm`
|
|
4421
4478
|
});
|
|
4422
|
-
if (
|
|
4423
|
-
|
|
4424
|
-
|
|
4479
|
+
if (p23.isCancel(answer)) {
|
|
4480
|
+
p23.cancel("Operation cancelled.");
|
|
4481
|
+
process16.exit(0);
|
|
4425
4482
|
}
|
|
4426
4483
|
return;
|
|
4427
4484
|
}
|
|
4428
|
-
const ok = await
|
|
4485
|
+
const ok = await p23.confirm({
|
|
4429
4486
|
message: `Remove ${appName} (${targetName})?`,
|
|
4430
4487
|
initialValue: false
|
|
4431
4488
|
});
|
|
4432
|
-
if (
|
|
4433
|
-
|
|
4434
|
-
|
|
4489
|
+
if (p23.isCancel(ok) || !ok) {
|
|
4490
|
+
p23.cancel("Operation cancelled.");
|
|
4491
|
+
process16.exit(0);
|
|
4435
4492
|
}
|
|
4436
4493
|
}
|
|
4437
4494
|
|
|
4438
4495
|
// src/commands/destroy.ts
|
|
4439
|
-
var destroy = new
|
|
4496
|
+
var destroy = new Command40("destroy").description("destroy scaffolding, or a deployment").configureHelp(helpConfig).addCommand(form2).addCommand(schema2).addCommand(resource2).addCommand(scaffold2).addCommand(deployment);
|
|
4440
4497
|
|
|
4441
4498
|
// src/commands/ui.ts
|
|
4442
|
-
import { Command as
|
|
4499
|
+
import { Command as Command43 } from "commander";
|
|
4443
4500
|
|
|
4444
4501
|
// src/commands/ui/add.ts
|
|
4445
|
-
import { Command as
|
|
4502
|
+
import { Command as Command41 } from "commander";
|
|
4446
4503
|
import { exec as exec2 } from "tinyexec";
|
|
4447
4504
|
import { detect as detect4, resolveCommand as resolveCommand4 } from "package-manager-detector";
|
|
4448
|
-
var add = new
|
|
4505
|
+
var add = new Command41("add").description("add ui components").argument("<components...>", "the components to add").configureHelp(helpConfig).action(
|
|
4449
4506
|
(components) => runCommand(async () => {
|
|
4450
4507
|
const { workspaceRootDir } = await getWorkspace();
|
|
4451
4508
|
const packageManager = (await detect4({ cwd: workspaceRootDir }))?.name ?? "npm";
|
|
@@ -4486,7 +4543,7 @@ var add = new Command40("add").description("add ui components").argument("<compo
|
|
|
4486
4543
|
// src/commands/ui/base.ts
|
|
4487
4544
|
import fs22 from "node:fs";
|
|
4488
4545
|
import path21 from "node:path";
|
|
4489
|
-
import { Command as
|
|
4546
|
+
import { Command as Command42, InvalidArgumentError } from "commander";
|
|
4490
4547
|
var VALID_COLORS = ["slate", "gray", "zinc", "stone", "neutral"];
|
|
4491
4548
|
function findThemeFile(color) {
|
|
4492
4549
|
const candidate = path21.join(templatesDir(), "ui", "css", `${color}.css`);
|
|
@@ -4513,7 +4570,7 @@ ${out}`;
|
|
|
4513
4570
|
${selectors.dark}`;
|
|
4514
4571
|
return out;
|
|
4515
4572
|
}
|
|
4516
|
-
var base = new
|
|
4573
|
+
var base = new Command42("base").description("change the base color").argument("<color>", "base color to use", (value) => {
|
|
4517
4574
|
if (!VALID_COLORS.includes(value)) {
|
|
4518
4575
|
throw new InvalidArgumentError(`Valid colors are: ${VALID_COLORS.join(", ")}`);
|
|
4519
4576
|
}
|
|
@@ -4541,22 +4598,22 @@ var base = new Command41("base").description("change the base color").argument("
|
|
|
4541
4598
|
);
|
|
4542
4599
|
|
|
4543
4600
|
// src/commands/ui.ts
|
|
4544
|
-
var ui = new
|
|
4601
|
+
var ui = new Command43("ui").description("generate ui components").configureHelp(helpConfig).addCommand(add).addCommand(base);
|
|
4545
4602
|
|
|
4546
4603
|
// src/commands/legal.ts
|
|
4547
|
-
import { Command as
|
|
4604
|
+
import { Command as Command46 } from "commander";
|
|
4548
4605
|
|
|
4549
4606
|
// src/commands/legal/terms.ts
|
|
4550
4607
|
import fs23 from "node:fs";
|
|
4551
4608
|
import path22 from "node:path";
|
|
4552
|
-
import { Command as
|
|
4553
|
-
import * as
|
|
4609
|
+
import { Command as Command44 } from "commander";
|
|
4610
|
+
import * as p25 from "@clack/prompts";
|
|
4554
4611
|
|
|
4555
4612
|
// src/commands/legal/shared.ts
|
|
4556
|
-
import
|
|
4557
|
-
import * as
|
|
4613
|
+
import process17 from "node:process";
|
|
4614
|
+
import * as p24 from "@clack/prompts";
|
|
4558
4615
|
var sharedFields = {
|
|
4559
|
-
websiteUrl: () =>
|
|
4616
|
+
websiteUrl: () => p24.text({
|
|
4560
4617
|
message: "What is your website URL?",
|
|
4561
4618
|
placeholder: "http://www.mysite.com",
|
|
4562
4619
|
validate: (value) => {
|
|
@@ -4565,7 +4622,7 @@ var sharedFields = {
|
|
|
4565
4622
|
}
|
|
4566
4623
|
}
|
|
4567
4624
|
}),
|
|
4568
|
-
websiteName: () =>
|
|
4625
|
+
websiteName: () => p24.text({
|
|
4569
4626
|
message: "What is your website name?",
|
|
4570
4627
|
placeholder: "My Site",
|
|
4571
4628
|
validate: (value) => {
|
|
@@ -4574,7 +4631,7 @@ var sharedFields = {
|
|
|
4574
4631
|
}
|
|
4575
4632
|
}
|
|
4576
4633
|
}),
|
|
4577
|
-
entityType: () =>
|
|
4634
|
+
entityType: () => p24.select({
|
|
4578
4635
|
message: "Entity type",
|
|
4579
4636
|
options: [
|
|
4580
4637
|
{
|
|
@@ -4585,7 +4642,7 @@ var sharedFields = {
|
|
|
4585
4642
|
{ value: "individual", label: "I'm an Individual" }
|
|
4586
4643
|
]
|
|
4587
4644
|
}),
|
|
4588
|
-
businessName: ({ results }) => results?.entityType === "business" ?
|
|
4645
|
+
businessName: ({ results }) => results?.entityType === "business" ? p24.text({
|
|
4589
4646
|
message: "What is the name of the business?",
|
|
4590
4647
|
placeholder: "My Company LLC",
|
|
4591
4648
|
validate: (value) => {
|
|
@@ -4594,7 +4651,7 @@ var sharedFields = {
|
|
|
4594
4651
|
}
|
|
4595
4652
|
}
|
|
4596
4653
|
}) : void 0,
|
|
4597
|
-
businessAddress: ({ results }) => results?.entityType === "business" ?
|
|
4654
|
+
businessAddress: ({ results }) => results?.entityType === "business" ? p24.text({
|
|
4598
4655
|
message: "What is the address of the business?",
|
|
4599
4656
|
placeholder: "1 Cupertino, CA 95014",
|
|
4600
4657
|
validate: (value) => {
|
|
@@ -4603,7 +4660,7 @@ var sharedFields = {
|
|
|
4603
4660
|
}
|
|
4604
4661
|
}
|
|
4605
4662
|
}) : void 0,
|
|
4606
|
-
country: () =>
|
|
4663
|
+
country: () => p24.text({
|
|
4607
4664
|
message: "Enter the country",
|
|
4608
4665
|
validate: (value) => {
|
|
4609
4666
|
if (!value) {
|
|
@@ -4611,7 +4668,7 @@ var sharedFields = {
|
|
|
4611
4668
|
}
|
|
4612
4669
|
}
|
|
4613
4670
|
}),
|
|
4614
|
-
state: () =>
|
|
4671
|
+
state: () => p24.text({
|
|
4615
4672
|
message: "Enter the state",
|
|
4616
4673
|
validate: (value) => {
|
|
4617
4674
|
if (!value) {
|
|
@@ -4621,11 +4678,11 @@ var sharedFields = {
|
|
|
4621
4678
|
})
|
|
4622
4679
|
};
|
|
4623
4680
|
var onCancel = () => {
|
|
4624
|
-
|
|
4625
|
-
|
|
4681
|
+
p24.cancel("Operation cancelled.");
|
|
4682
|
+
process17.exit(0);
|
|
4626
4683
|
};
|
|
4627
4684
|
async function contactMethods(type) {
|
|
4628
|
-
const selection = await
|
|
4685
|
+
const selection = await p24.multiselect({
|
|
4629
4686
|
message: `How can users contact you for any questions regarding your ${type === "privacy" ? "Privacy Policy" : "Terms & Conditions"}? Check all that apply`,
|
|
4630
4687
|
options: [
|
|
4631
4688
|
{ value: "email", label: "By email" },
|
|
@@ -4634,11 +4691,11 @@ async function contactMethods(type) {
|
|
|
4634
4691
|
{ value: "mail", label: "By sending post mail" }
|
|
4635
4692
|
]
|
|
4636
4693
|
});
|
|
4637
|
-
if (
|
|
4694
|
+
if (p24.isCancel(selection)) onCancel();
|
|
4638
4695
|
const contact = selection;
|
|
4639
4696
|
const details = {};
|
|
4640
4697
|
if (contact.includes("email")) {
|
|
4641
|
-
const email3 = await
|
|
4698
|
+
const email3 = await p24.text({
|
|
4642
4699
|
message: "What's the email?",
|
|
4643
4700
|
placeholder: "office@mycompany.com",
|
|
4644
4701
|
validate: (value) => {
|
|
@@ -4647,11 +4704,11 @@ async function contactMethods(type) {
|
|
|
4647
4704
|
}
|
|
4648
4705
|
}
|
|
4649
4706
|
});
|
|
4650
|
-
if (
|
|
4707
|
+
if (p24.isCancel(email3)) onCancel();
|
|
4651
4708
|
details.email = email3;
|
|
4652
4709
|
}
|
|
4653
4710
|
if (contact.includes("page")) {
|
|
4654
|
-
const page = await
|
|
4711
|
+
const page = await p24.text({
|
|
4655
4712
|
message: "What's the link?",
|
|
4656
4713
|
placeholder: "http://www.mycompany.com/contact",
|
|
4657
4714
|
validate: (value) => {
|
|
@@ -4660,11 +4717,11 @@ async function contactMethods(type) {
|
|
|
4660
4717
|
}
|
|
4661
4718
|
}
|
|
4662
4719
|
});
|
|
4663
|
-
if (
|
|
4720
|
+
if (p24.isCancel(page)) onCancel();
|
|
4664
4721
|
details.page = page;
|
|
4665
4722
|
}
|
|
4666
4723
|
if (contact.includes("phone")) {
|
|
4667
|
-
const phone = await
|
|
4724
|
+
const phone = await p24.text({
|
|
4668
4725
|
message: "What's the phone number?",
|
|
4669
4726
|
placeholder: "408.996.1010",
|
|
4670
4727
|
validate: (value) => {
|
|
@@ -4673,11 +4730,11 @@ async function contactMethods(type) {
|
|
|
4673
4730
|
}
|
|
4674
4731
|
}
|
|
4675
4732
|
});
|
|
4676
|
-
if (
|
|
4733
|
+
if (p24.isCancel(phone)) onCancel();
|
|
4677
4734
|
details.phone = phone;
|
|
4678
4735
|
}
|
|
4679
4736
|
if (contact.includes("mail")) {
|
|
4680
|
-
const address = await
|
|
4737
|
+
const address = await p24.text({
|
|
4681
4738
|
message: "What's the address?",
|
|
4682
4739
|
placeholder: "767 Fifth Avenue New York, NY 10153, United States",
|
|
4683
4740
|
validate: (value) => {
|
|
@@ -4686,7 +4743,7 @@ async function contactMethods(type) {
|
|
|
4686
4743
|
}
|
|
4687
4744
|
}
|
|
4688
4745
|
});
|
|
4689
|
-
if (
|
|
4746
|
+
if (p24.isCancel(address)) onCancel();
|
|
4690
4747
|
details.address = address;
|
|
4691
4748
|
}
|
|
4692
4749
|
return { methods: contact, details };
|
|
@@ -5082,7 +5139,7 @@ var generateTermsHtml = (answers) => {
|
|
|
5082
5139
|
};
|
|
5083
5140
|
async function termsAction() {
|
|
5084
5141
|
const { workspaceRootDir, publicRoutesDir } = await getWorkspace();
|
|
5085
|
-
const core = await
|
|
5142
|
+
const core = await p25.group(
|
|
5086
5143
|
{
|
|
5087
5144
|
websiteUrl: sharedFields.websiteUrl,
|
|
5088
5145
|
websiteName: sharedFields.websiteName,
|
|
@@ -5094,25 +5151,25 @@ async function termsAction() {
|
|
|
5094
5151
|
},
|
|
5095
5152
|
{ onCancel }
|
|
5096
5153
|
);
|
|
5097
|
-
const accounts = await
|
|
5154
|
+
const accounts = await p25.select({
|
|
5098
5155
|
message: "Can users create accounts?",
|
|
5099
5156
|
options: [
|
|
5100
5157
|
{ value: "yes", label: "Yes, users can create accounts" },
|
|
5101
5158
|
{ value: "no", label: "No" }
|
|
5102
5159
|
]
|
|
5103
5160
|
});
|
|
5104
|
-
if (
|
|
5105
|
-
const userContent = await
|
|
5161
|
+
if (p25.isCancel(accounts)) onCancel();
|
|
5162
|
+
const userContent = await p25.select({
|
|
5106
5163
|
message: "Can users create and/or upload content (ie. text, images)?",
|
|
5107
5164
|
options: [
|
|
5108
5165
|
{ value: "yes", label: "Yes, users can create and/or upload content" },
|
|
5109
5166
|
{ value: "no", label: "No" }
|
|
5110
5167
|
]
|
|
5111
5168
|
});
|
|
5112
|
-
if (
|
|
5169
|
+
if (p25.isCancel(userContent)) onCancel();
|
|
5113
5170
|
let infringementEmail;
|
|
5114
5171
|
if (userContent === "yes") {
|
|
5115
|
-
const email3 = await
|
|
5172
|
+
const email3 = await p25.text({
|
|
5116
5173
|
message: "What's the email address where you will receive infringements notices?",
|
|
5117
5174
|
placeholder: "dmca@website.com",
|
|
5118
5175
|
validate: (value) => {
|
|
@@ -5121,10 +5178,10 @@ async function termsAction() {
|
|
|
5121
5178
|
}
|
|
5122
5179
|
}
|
|
5123
5180
|
});
|
|
5124
|
-
if (
|
|
5181
|
+
if (p25.isCancel(email3)) onCancel();
|
|
5125
5182
|
infringementEmail = email3;
|
|
5126
5183
|
}
|
|
5127
|
-
const canBuyGoods = await
|
|
5184
|
+
const canBuyGoods = await p25.select({
|
|
5128
5185
|
message: "Can users buy goods (products, items)?",
|
|
5129
5186
|
options: [
|
|
5130
5187
|
{
|
|
@@ -5134,28 +5191,28 @@ async function termsAction() {
|
|
|
5134
5191
|
{ value: "no", label: "No" }
|
|
5135
5192
|
]
|
|
5136
5193
|
});
|
|
5137
|
-
if (
|
|
5138
|
-
const subscriptions2 = await
|
|
5194
|
+
if (p25.isCancel(canBuyGoods)) onCancel();
|
|
5195
|
+
const subscriptions2 = await p25.select({
|
|
5139
5196
|
message: "Do you offer subscription plans?",
|
|
5140
5197
|
options: [
|
|
5141
5198
|
{ value: "yes", label: "Yes, we offer subscription plans" },
|
|
5142
5199
|
{ value: "no", label: "No" }
|
|
5143
5200
|
]
|
|
5144
5201
|
});
|
|
5145
|
-
if (
|
|
5202
|
+
if (p25.isCancel(subscriptions2)) onCancel();
|
|
5146
5203
|
let freeTrial;
|
|
5147
5204
|
if (subscriptions2 === "yes") {
|
|
5148
|
-
const ft = await
|
|
5205
|
+
const ft = await p25.select({
|
|
5149
5206
|
message: "Do you offer a free trial?",
|
|
5150
5207
|
options: [
|
|
5151
5208
|
{ value: "yes", label: "Yes" },
|
|
5152
5209
|
{ value: "no", label: "No" }
|
|
5153
5210
|
]
|
|
5154
5211
|
});
|
|
5155
|
-
if (
|
|
5212
|
+
if (p25.isCancel(ft)) onCancel();
|
|
5156
5213
|
freeTrial = ft;
|
|
5157
5214
|
}
|
|
5158
|
-
const exclusiveContent = await
|
|
5215
|
+
const exclusiveContent = await p25.select({
|
|
5159
5216
|
message: "Do you want to make it clear that your own content & trademarks are your exclusive property?",
|
|
5160
5217
|
options: [
|
|
5161
5218
|
{
|
|
@@ -5165,24 +5222,24 @@ async function termsAction() {
|
|
|
5165
5222
|
{ value: "no", label: "No" }
|
|
5166
5223
|
]
|
|
5167
5224
|
});
|
|
5168
|
-
if (
|
|
5169
|
-
const feedbackReuse = await
|
|
5225
|
+
if (p25.isCancel(exclusiveContent)) onCancel();
|
|
5226
|
+
const feedbackReuse = await p25.select({
|
|
5170
5227
|
message: "If users provide you feedback & suggestions, do you want to use this feedback without compensation or credits given?",
|
|
5171
5228
|
options: [
|
|
5172
5229
|
{ value: "yes", label: "Yes, we may implement any feedback or suggestions we receive" },
|
|
5173
5230
|
{ value: "no", label: "No" }
|
|
5174
5231
|
]
|
|
5175
5232
|
});
|
|
5176
|
-
if (
|
|
5177
|
-
const promotions = await
|
|
5233
|
+
if (p25.isCancel(feedbackReuse)) onCancel();
|
|
5234
|
+
const promotions = await p25.select({
|
|
5178
5235
|
message: "Do you plan to offer promotions, contests, sweepstakes?",
|
|
5179
5236
|
options: [
|
|
5180
5237
|
{ value: "yes", label: "Yes, we may offer promotions, contests, sweepstakes" },
|
|
5181
5238
|
{ value: "no", label: "No" }
|
|
5182
5239
|
]
|
|
5183
5240
|
});
|
|
5184
|
-
if (
|
|
5185
|
-
const mobileAppRaw = await
|
|
5241
|
+
if (p25.isCancel(promotions)) onCancel();
|
|
5242
|
+
const mobileAppRaw = await p25.multiselect({
|
|
5186
5243
|
message: "Is the Service distributed through any mobile app stores? Check all that apply",
|
|
5187
5244
|
options: [
|
|
5188
5245
|
{ value: "apple", label: "Apple App Store" },
|
|
@@ -5190,7 +5247,7 @@ async function termsAction() {
|
|
|
5190
5247
|
],
|
|
5191
5248
|
required: false
|
|
5192
5249
|
});
|
|
5193
|
-
if (
|
|
5250
|
+
if (p25.isCancel(mobileAppRaw)) onCancel();
|
|
5194
5251
|
const mobileApp = mobileAppRaw ?? [];
|
|
5195
5252
|
const contact = await contactMethods("terms");
|
|
5196
5253
|
const html = generateTermsHtml({
|
|
@@ -5233,13 +5290,13 @@ async function termsAction() {
|
|
|
5233
5290
|
]
|
|
5234
5291
|
});
|
|
5235
5292
|
}
|
|
5236
|
-
var terms = new
|
|
5293
|
+
var terms = new Command44("terms").description("generate placeholder terms and conditions").configureHelp(helpConfig).action(() => runCommand(termsAction, "Failed to generate terms and conditions."));
|
|
5237
5294
|
|
|
5238
5295
|
// src/commands/legal/privacy.ts
|
|
5239
5296
|
import fs24 from "node:fs";
|
|
5240
5297
|
import path23 from "node:path";
|
|
5241
|
-
import { Command as
|
|
5242
|
-
import * as
|
|
5298
|
+
import { Command as Command45 } from "commander";
|
|
5299
|
+
import * as p26 from "@clack/prompts";
|
|
5243
5300
|
var mapLabels = {
|
|
5244
5301
|
personalInfo: {
|
|
5245
5302
|
email: "Email address",
|
|
@@ -5657,12 +5714,12 @@ var generatePrivacyHtml = (answers) => {
|
|
|
5657
5714
|
return `<section data-role="content">${sections.join("")}</section>`;
|
|
5658
5715
|
};
|
|
5659
5716
|
async function promptWithCustom(message, options, customMessage) {
|
|
5660
|
-
const selection = await
|
|
5661
|
-
if (
|
|
5717
|
+
const selection = await p26.multiselect({ message, options });
|
|
5718
|
+
if (p26.isCancel(selection)) onCancel();
|
|
5662
5719
|
const values = selection;
|
|
5663
5720
|
if (values.includes("custom")) {
|
|
5664
|
-
const custom = await
|
|
5665
|
-
if (
|
|
5721
|
+
const custom = await p26.text({ message: customMessage });
|
|
5722
|
+
if (p26.isCancel(custom)) onCancel();
|
|
5666
5723
|
const idx = values.indexOf("custom");
|
|
5667
5724
|
if (idx !== -1) values.splice(idx, 1);
|
|
5668
5725
|
if (custom) values.push(String(custom));
|
|
@@ -5671,7 +5728,7 @@ async function promptWithCustom(message, options, customMessage) {
|
|
|
5671
5728
|
}
|
|
5672
5729
|
async function privacyAction() {
|
|
5673
5730
|
const { workspaceRootDir, publicRoutesDir } = await getWorkspace();
|
|
5674
|
-
const core = await
|
|
5731
|
+
const core = await p26.group(
|
|
5675
5732
|
{
|
|
5676
5733
|
websiteUrl: sharedFields.websiteUrl,
|
|
5677
5734
|
websiteName: sharedFields.websiteName,
|
|
@@ -5683,7 +5740,7 @@ async function privacyAction() {
|
|
|
5683
5740
|
},
|
|
5684
5741
|
{ onCancel }
|
|
5685
5742
|
);
|
|
5686
|
-
const personalInfo = await
|
|
5743
|
+
const personalInfo = await p26.multiselect({
|
|
5687
5744
|
message: "What kind of personal information do you collect from users? Check all that apply",
|
|
5688
5745
|
options: [
|
|
5689
5746
|
{ value: "email", label: "Email address" },
|
|
@@ -5698,16 +5755,16 @@ async function privacyAction() {
|
|
|
5698
5755
|
],
|
|
5699
5756
|
required: false
|
|
5700
5757
|
});
|
|
5701
|
-
if (
|
|
5758
|
+
if (p26.isCancel(personalInfo)) onCancel();
|
|
5702
5759
|
const contact = await contactMethods("privacy");
|
|
5703
|
-
const tracking = await
|
|
5760
|
+
const tracking = await p26.select({
|
|
5704
5761
|
message: "Do you use tracking and/or analytics tools, such as Google Analytics?",
|
|
5705
5762
|
options: [
|
|
5706
5763
|
{ value: "yes", label: "Yes, we use Google Analytics or other related tools" },
|
|
5707
5764
|
{ value: "no", label: "No" }
|
|
5708
5765
|
]
|
|
5709
5766
|
});
|
|
5710
|
-
if (
|
|
5767
|
+
if (p26.isCancel(tracking)) onCancel();
|
|
5711
5768
|
let trackingTools;
|
|
5712
5769
|
if (tracking === "yes") {
|
|
5713
5770
|
trackingTools = await promptWithCustom(
|
|
@@ -5726,7 +5783,7 @@ async function privacyAction() {
|
|
|
5726
5783
|
"Enter your custom tracking/analytics tool name"
|
|
5727
5784
|
);
|
|
5728
5785
|
}
|
|
5729
|
-
const sendEmails = await
|
|
5786
|
+
const sendEmails = await p26.select({
|
|
5730
5787
|
message: "Do you send emails to users?",
|
|
5731
5788
|
options: [
|
|
5732
5789
|
{
|
|
@@ -5736,7 +5793,7 @@ async function privacyAction() {
|
|
|
5736
5793
|
{ value: "no", label: "No" }
|
|
5737
5794
|
]
|
|
5738
5795
|
});
|
|
5739
|
-
if (
|
|
5796
|
+
if (p26.isCancel(sendEmails)) onCancel();
|
|
5740
5797
|
let emailPlatforms;
|
|
5741
5798
|
if (sendEmails === "yes") {
|
|
5742
5799
|
emailPlatforms = await promptWithCustom(
|
|
@@ -5751,14 +5808,14 @@ async function privacyAction() {
|
|
|
5751
5808
|
"Enter your custom email platform"
|
|
5752
5809
|
);
|
|
5753
5810
|
}
|
|
5754
|
-
const showAds = await
|
|
5811
|
+
const showAds = await p26.select({
|
|
5755
5812
|
message: "Do you show ads?",
|
|
5756
5813
|
options: [
|
|
5757
5814
|
{ value: "yes", label: "Yes, we show ads" },
|
|
5758
5815
|
{ value: "no", label: "No" }
|
|
5759
5816
|
]
|
|
5760
5817
|
});
|
|
5761
|
-
if (
|
|
5818
|
+
if (p26.isCancel(showAds)) onCancel();
|
|
5762
5819
|
let adsPlatforms;
|
|
5763
5820
|
if (showAds === "yes") {
|
|
5764
5821
|
adsPlatforms = await promptWithCustom(
|
|
@@ -5781,7 +5838,7 @@ async function privacyAction() {
|
|
|
5781
5838
|
"Enter your custom ads platform"
|
|
5782
5839
|
);
|
|
5783
5840
|
}
|
|
5784
|
-
const canPay = await
|
|
5841
|
+
const canPay = await p26.select({
|
|
5785
5842
|
message: "Can users pay for products or services?",
|
|
5786
5843
|
options: [
|
|
5787
5844
|
{ value: "yes", label: "Yes, users can pay for our products/services" },
|
|
@@ -5791,7 +5848,7 @@ async function privacyAction() {
|
|
|
5791
5848
|
}
|
|
5792
5849
|
]
|
|
5793
5850
|
});
|
|
5794
|
-
if (
|
|
5851
|
+
if (p26.isCancel(canPay)) onCancel();
|
|
5795
5852
|
let paymentProcessors;
|
|
5796
5853
|
if (canPay === "yes") {
|
|
5797
5854
|
paymentProcessors = await promptWithCustom(
|
|
@@ -5822,14 +5879,14 @@ async function privacyAction() {
|
|
|
5822
5879
|
"Enter your custom payment processor/method"
|
|
5823
5880
|
);
|
|
5824
5881
|
}
|
|
5825
|
-
const remarketing = await
|
|
5882
|
+
const remarketing = await p26.select({
|
|
5826
5883
|
message: "Do you use remarketing services for marketing & advertising purposes?",
|
|
5827
5884
|
options: [
|
|
5828
5885
|
{ value: "yes", label: "Yes, we use remarketing services to advertise our business" },
|
|
5829
5886
|
{ value: "no", label: "No" }
|
|
5830
5887
|
]
|
|
5831
5888
|
});
|
|
5832
|
-
if (
|
|
5889
|
+
if (p26.isCancel(remarketing)) onCancel();
|
|
5833
5890
|
let remarketingPlatforms;
|
|
5834
5891
|
if (remarketing === "yes") {
|
|
5835
5892
|
remarketingPlatforms = await promptWithCustom(
|
|
@@ -5848,7 +5905,7 @@ async function privacyAction() {
|
|
|
5848
5905
|
"Enter your custom remarketing platform"
|
|
5849
5906
|
);
|
|
5850
5907
|
}
|
|
5851
|
-
const providersRaw = await
|
|
5908
|
+
const providersRaw = await p26.multiselect({
|
|
5852
5909
|
message: "Select if you use any of the following providers",
|
|
5853
5910
|
options: [
|
|
5854
5911
|
{ value: "recaptcha", label: "Invisible reCAPTCHA" },
|
|
@@ -5859,16 +5916,16 @@ async function privacyAction() {
|
|
|
5859
5916
|
],
|
|
5860
5917
|
required: false
|
|
5861
5918
|
});
|
|
5862
|
-
if (
|
|
5919
|
+
if (p26.isCancel(providersRaw)) onCancel();
|
|
5863
5920
|
const providers = providersRaw;
|
|
5864
5921
|
if (providers.includes("custom")) {
|
|
5865
|
-
const custom = await
|
|
5866
|
-
if (
|
|
5922
|
+
const custom = await p26.text({ message: "Enter your custom provider" });
|
|
5923
|
+
if (p26.isCancel(custom)) onCancel();
|
|
5867
5924
|
const idx = providers.indexOf("custom");
|
|
5868
5925
|
if (idx !== -1) providers.splice(idx, 1);
|
|
5869
5926
|
if (custom) providers.push(String(custom));
|
|
5870
5927
|
}
|
|
5871
|
-
const usStates = await
|
|
5928
|
+
const usStates = await p26.select({
|
|
5872
5929
|
message: "Include U.S. state privacy rights (CCPA/CPRA, VCDPA, CPA, CTDPA, UCPA, TX, OR, etc.)?",
|
|
5873
5930
|
options: [
|
|
5874
5931
|
{
|
|
@@ -5879,55 +5936,55 @@ async function privacyAction() {
|
|
|
5879
5936
|
],
|
|
5880
5937
|
initialValue: "yes"
|
|
5881
5938
|
});
|
|
5882
|
-
if (
|
|
5883
|
-
const gdpr = await
|
|
5939
|
+
if (p26.isCancel(usStates)) onCancel();
|
|
5940
|
+
const gdpr = await p26.select({
|
|
5884
5941
|
message: "Do you want your Privacy Policy to include GDPR / UK GDPR wording?",
|
|
5885
5942
|
options: [
|
|
5886
5943
|
{ value: "yes", label: "Yes. Include GDPR rights for EEA, UK, and Swiss residents" },
|
|
5887
5944
|
{ value: "no", label: "No" }
|
|
5888
5945
|
]
|
|
5889
5946
|
});
|
|
5890
|
-
if (
|
|
5947
|
+
if (p26.isCancel(gdpr)) onCancel();
|
|
5891
5948
|
let facebookFanPage = "no";
|
|
5892
5949
|
const facebookDetails = { name: "", url: "" };
|
|
5893
5950
|
if (gdpr === "yes") {
|
|
5894
|
-
const fan = await
|
|
5951
|
+
const fan = await p26.select({
|
|
5895
5952
|
message: "Do you have a Facebook Fan Page?",
|
|
5896
5953
|
options: [
|
|
5897
5954
|
{ value: "yes", label: "Yes, we have a Facebook Fan Page" },
|
|
5898
5955
|
{ value: "no", label: "No" }
|
|
5899
5956
|
]
|
|
5900
5957
|
});
|
|
5901
|
-
if (
|
|
5958
|
+
if (p26.isCancel(fan)) onCancel();
|
|
5902
5959
|
facebookFanPage = fan;
|
|
5903
5960
|
if (facebookFanPage === "yes") {
|
|
5904
|
-
const name = await
|
|
5961
|
+
const name = await p26.text({
|
|
5905
5962
|
message: "What is the name of the Facebook Fan Page?",
|
|
5906
5963
|
placeholder: "My Facebook Page"
|
|
5907
5964
|
});
|
|
5908
|
-
if (
|
|
5965
|
+
if (p26.isCancel(name)) onCancel();
|
|
5909
5966
|
facebookDetails.name = name;
|
|
5910
|
-
const url = await
|
|
5967
|
+
const url = await p26.text({
|
|
5911
5968
|
message: "What is the URL of the Facebook Fan Page?",
|
|
5912
5969
|
placeholder: "https://facebook.com/my-facebook-page"
|
|
5913
5970
|
});
|
|
5914
|
-
if (
|
|
5971
|
+
if (p26.isCancel(url)) onCancel();
|
|
5915
5972
|
facebookDetails.url = url;
|
|
5916
5973
|
}
|
|
5917
5974
|
}
|
|
5918
|
-
const kids = await
|
|
5975
|
+
const kids = await p26.select({
|
|
5919
5976
|
message: "Do you collect information from kids under the age of 13?",
|
|
5920
5977
|
options: [
|
|
5921
5978
|
{ value: "yes", label: "Yes. We collect information from children under the age of 13" },
|
|
5922
5979
|
{ value: "no", label: "No" }
|
|
5923
5980
|
]
|
|
5924
5981
|
});
|
|
5925
|
-
if (
|
|
5926
|
-
const retention = await
|
|
5982
|
+
if (p26.isCancel(kids)) onCancel();
|
|
5983
|
+
const retention = await p26.text({
|
|
5927
5984
|
message: "How long do you retain personal information? (leave blank for default wording)",
|
|
5928
5985
|
placeholder: "e.g. 12 months after account closure"
|
|
5929
5986
|
});
|
|
5930
|
-
if (
|
|
5987
|
+
if (p26.isCancel(retention)) onCancel();
|
|
5931
5988
|
const html = generatePrivacyHtml({
|
|
5932
5989
|
core,
|
|
5933
5990
|
personalInfo: personalInfo ?? [],
|
|
@@ -5982,18 +6039,18 @@ async function privacyAction() {
|
|
|
5982
6039
|
]
|
|
5983
6040
|
});
|
|
5984
6041
|
}
|
|
5985
|
-
var privacy = new
|
|
6042
|
+
var privacy = new Command45("privacy").description("generate placeholder privacy policy").configureHelp(helpConfig).action(() => runCommand(privacyAction, "Failed to generate privacy policy."));
|
|
5986
6043
|
|
|
5987
6044
|
// src/commands/legal.ts
|
|
5988
|
-
var legal = new
|
|
6045
|
+
var legal = new Command46("legal").description("generate placeholder legal documents").configureHelp(helpConfig).addCommand(terms).addCommand(privacy);
|
|
5989
6046
|
|
|
5990
6047
|
// src/commands/fixtures.ts
|
|
5991
|
-
import { Command as
|
|
6048
|
+
import { Command as Command52 } from "commander";
|
|
5992
6049
|
|
|
5993
6050
|
// src/commands/fixtures/load.ts
|
|
5994
6051
|
import fs25 from "node:fs";
|
|
5995
6052
|
import path24 from "node:path";
|
|
5996
|
-
import { Command as
|
|
6053
|
+
import { Command as Command47 } from "commander";
|
|
5997
6054
|
function getFixtureFiles(cwd) {
|
|
5998
6055
|
const fixturesDir = path24.join(cwd, "data", "fixtures");
|
|
5999
6056
|
if (!fs25.existsSync(fixturesDir)) return [];
|
|
@@ -6027,7 +6084,7 @@ async function loadFixtures(pb, workspaceRootDir) {
|
|
|
6027
6084
|
}
|
|
6028
6085
|
return loaded;
|
|
6029
6086
|
}
|
|
6030
|
-
var load = new
|
|
6087
|
+
var load = new Command47("load").description("load fixtures into the database").configureHelp(helpConfig).action(
|
|
6031
6088
|
() => runCommand(async () => {
|
|
6032
6089
|
const { workspaceRootDir } = await getWorkspace();
|
|
6033
6090
|
let loaded = [];
|
|
@@ -6054,7 +6111,7 @@ var load = new Command46("load").description("load fixtures into the database").
|
|
|
6054
6111
|
|
|
6055
6112
|
// src/commands/fixtures/clear.ts
|
|
6056
6113
|
import path25 from "node:path";
|
|
6057
|
-
import { Command as
|
|
6114
|
+
import { Command as Command48 } from "commander";
|
|
6058
6115
|
|
|
6059
6116
|
// src/lib/collections.ts
|
|
6060
6117
|
function dependencyOrder(collections2, startingCollectionId) {
|
|
@@ -6121,7 +6178,7 @@ async function clearFixtures(pb, workspaceRootDir) {
|
|
|
6121
6178
|
}
|
|
6122
6179
|
return cleared;
|
|
6123
6180
|
}
|
|
6124
|
-
var clear = new
|
|
6181
|
+
var clear = new Command48("clear").description("clear loaded fixtures").configureHelp(helpConfig).action(
|
|
6125
6182
|
() => runCommand(async () => {
|
|
6126
6183
|
const { workspaceRootDir } = await getWorkspace();
|
|
6127
6184
|
let cleared = [];
|
|
@@ -6150,8 +6207,8 @@ var clear = new Command47("clear").description("clear loaded fixtures").configur
|
|
|
6150
6207
|
);
|
|
6151
6208
|
|
|
6152
6209
|
// src/commands/fixtures/reset.ts
|
|
6153
|
-
import { Command as
|
|
6154
|
-
var reset = new
|
|
6210
|
+
import { Command as Command49 } from "commander";
|
|
6211
|
+
var reset = new Command49("reset").description("clear and reload fixtures").configureHelp(helpConfig).action(
|
|
6155
6212
|
() => runCommand(async () => {
|
|
6156
6213
|
const { workspaceRootDir } = await getWorkspace();
|
|
6157
6214
|
let cleared = [];
|
|
@@ -6183,8 +6240,8 @@ var reset = new Command48("reset").description("clear and reload fixtures").conf
|
|
|
6183
6240
|
// src/commands/fixtures/generate.ts
|
|
6184
6241
|
import fs26 from "node:fs";
|
|
6185
6242
|
import path26 from "node:path";
|
|
6186
|
-
import { Command as
|
|
6187
|
-
import * as
|
|
6243
|
+
import { Command as Command50, InvalidArgumentError as InvalidArgumentError2 } from "commander";
|
|
6244
|
+
import * as p27 from "@clack/prompts";
|
|
6188
6245
|
import { annotate } from "annotate-json-schema";
|
|
6189
6246
|
import { createGenerator } from "json-schema-faker";
|
|
6190
6247
|
import { faker } from "@faker-js/faker";
|
|
@@ -6304,7 +6361,7 @@ async function generateFixtureFiles(pb, workspaceRootDir, opts) {
|
|
|
6304
6361
|
}
|
|
6305
6362
|
return { writtenFiles, warnings };
|
|
6306
6363
|
}
|
|
6307
|
-
var generate2 = new
|
|
6364
|
+
var generate2 = new Command50("generate").description("generate fixture data").option("-c, --count <count>", "number of records per collection", parseCount, 10).option("-s, --seed <seed>", "seed for deterministic output", parseSeed).option("-f, --force", "overwrite existing fixture files and clear loaded fixtures").configureHelp(helpConfig).action(
|
|
6308
6365
|
(opts) => runCommand(async () => {
|
|
6309
6366
|
const { workspaceRootDir } = await getWorkspace();
|
|
6310
6367
|
const existing = getFixtureFiles(workspaceRootDir);
|
|
@@ -6333,7 +6390,7 @@ var generate2 = new Command49("generate").description("generate fixture data").o
|
|
|
6333
6390
|
seed: opts.seed
|
|
6334
6391
|
});
|
|
6335
6392
|
});
|
|
6336
|
-
for (const warning of result.warnings)
|
|
6393
|
+
for (const warning of result.warnings) p27.log.warn(warning);
|
|
6337
6394
|
if (result.writtenFiles.length === 0) {
|
|
6338
6395
|
reportResult({
|
|
6339
6396
|
summary: "No eligible collections found to generate fixtures for.",
|
|
@@ -6357,8 +6414,8 @@ var generate2 = new Command49("generate").description("generate fixture data").o
|
|
|
6357
6414
|
);
|
|
6358
6415
|
|
|
6359
6416
|
// src/commands/fixtures/regen.ts
|
|
6360
|
-
import { Command as
|
|
6361
|
-
import * as
|
|
6417
|
+
import { Command as Command51, InvalidArgumentError as InvalidArgumentError3 } from "commander";
|
|
6418
|
+
import * as p28 from "@clack/prompts";
|
|
6362
6419
|
function parseCount2(value) {
|
|
6363
6420
|
const n = parseInt(value, 10);
|
|
6364
6421
|
if (!Number.isFinite(n) || n <= 0 || n > 999) {
|
|
@@ -6373,7 +6430,7 @@ function parseSeed2(value) {
|
|
|
6373
6430
|
}
|
|
6374
6431
|
return n;
|
|
6375
6432
|
}
|
|
6376
|
-
var regen = new
|
|
6433
|
+
var regen = new Command51("regen").description("clear the database, regenerate fixture files, and reload them").option("-c, --count <count>", "number of records per collection", parseCount2, 10).option("-s, --seed <seed>", "seed for deterministic output", parseSeed2).configureHelp(helpConfig).action(
|
|
6377
6434
|
(opts) => runCommand(async () => {
|
|
6378
6435
|
const { workspaceRootDir } = await getWorkspace();
|
|
6379
6436
|
let cleared = [];
|
|
@@ -6387,7 +6444,7 @@ var regen = new Command50("regen").description("clear the database, regenerate f
|
|
|
6387
6444
|
});
|
|
6388
6445
|
loaded = await loadFixtures(pb, workspaceRootDir);
|
|
6389
6446
|
});
|
|
6390
|
-
for (const warning of result.warnings)
|
|
6447
|
+
for (const warning of result.warnings) p28.log.warn(warning);
|
|
6391
6448
|
reportResult({
|
|
6392
6449
|
summary: `Regenerated fixtures (${loaded.length} collection(s) reloaded).`,
|
|
6393
6450
|
filesCreated: result.writtenFiles,
|
|
@@ -6402,15 +6459,15 @@ var regen = new Command50("regen").description("clear the database, regenerate f
|
|
|
6402
6459
|
);
|
|
6403
6460
|
|
|
6404
6461
|
// src/commands/fixtures.ts
|
|
6405
|
-
var fixtures = new
|
|
6462
|
+
var fixtures = new Command52("fixtures").description("manage fixture data").configureHelp(helpConfig).addCommand(generate2).addCommand(load).addCommand(clear).addCommand(reset).addCommand(regen);
|
|
6406
6463
|
|
|
6407
6464
|
// src/commands/seeds.ts
|
|
6408
|
-
import { Command as
|
|
6465
|
+
import { Command as Command56 } from "commander";
|
|
6409
6466
|
|
|
6410
6467
|
// src/commands/seeds/load.ts
|
|
6411
6468
|
import fs27 from "node:fs";
|
|
6412
6469
|
import path27 from "node:path";
|
|
6413
|
-
import { Command as
|
|
6470
|
+
import { Command as Command53 } from "commander";
|
|
6414
6471
|
function getSeedFiles(cwd) {
|
|
6415
6472
|
const seedsDir = path27.join(cwd, "data", "seeds");
|
|
6416
6473
|
if (!fs27.existsSync(seedsDir)) return [];
|
|
@@ -6421,7 +6478,7 @@ function getSeedFiles(cwd) {
|
|
|
6421
6478
|
return { collectionName, seedPath };
|
|
6422
6479
|
});
|
|
6423
6480
|
}
|
|
6424
|
-
var load2 = new
|
|
6481
|
+
var load2 = new Command53("load").description("load seeds into the database").option("-f, --force", "load even if target collections already have records").configureHelp(helpConfig).action(
|
|
6425
6482
|
(opts) => runCommand(async () => {
|
|
6426
6483
|
const { workspaceRootDir } = await getWorkspace();
|
|
6427
6484
|
const seedFiles = getSeedFiles(workspaceRootDir);
|
|
@@ -6466,7 +6523,7 @@ var load2 = new Command52("load").description("load seeds into the database").op
|
|
|
6466
6523
|
// src/commands/seeds/save.ts
|
|
6467
6524
|
import fs28 from "node:fs";
|
|
6468
6525
|
import path28 from "node:path";
|
|
6469
|
-
import { Command as
|
|
6526
|
+
import { Command as Command54 } from "commander";
|
|
6470
6527
|
var padZeros2 = (num, length) => num.toString().padStart(length, "0");
|
|
6471
6528
|
function filterSystemFields(record, systemFieldNames) {
|
|
6472
6529
|
const out = {};
|
|
@@ -6477,7 +6534,7 @@ function filterSystemFields(record, systemFieldNames) {
|
|
|
6477
6534
|
}
|
|
6478
6535
|
return out;
|
|
6479
6536
|
}
|
|
6480
|
-
var save = new
|
|
6537
|
+
var save = new Command54("save").description("save the current data as seeds").option("-f, --force", "overwrite existing seed files").configureHelp(helpConfig).action(
|
|
6481
6538
|
(opts) => runCommand(async () => {
|
|
6482
6539
|
const { workspaceRootDir } = await getWorkspace();
|
|
6483
6540
|
const seedsPath = path28.join(workspaceRootDir, "data", "seeds");
|
|
@@ -6551,7 +6608,7 @@ var save = new Command53("save").description("save the current data as seeds").o
|
|
|
6551
6608
|
// src/commands/seeds/clear.ts
|
|
6552
6609
|
import fs29 from "node:fs";
|
|
6553
6610
|
import path29 from "node:path";
|
|
6554
|
-
import { Command as
|
|
6611
|
+
import { Command as Command55 } from "commander";
|
|
6555
6612
|
async function clearSeeds(pb, workspaceRootDir, seedFiles) {
|
|
6556
6613
|
const cleared = [];
|
|
6557
6614
|
for (const { collectionName, seedPath } of seedFiles) {
|
|
@@ -6563,7 +6620,7 @@ async function clearSeeds(pb, workspaceRootDir, seedFiles) {
|
|
|
6563
6620
|
}
|
|
6564
6621
|
return cleared;
|
|
6565
6622
|
}
|
|
6566
|
-
var clear2 = new
|
|
6623
|
+
var clear2 = new Command55("clear").description("clear seeded records").configureHelp(helpConfig).action(
|
|
6567
6624
|
() => runCommand(async () => {
|
|
6568
6625
|
const { workspaceRootDir } = await getWorkspace();
|
|
6569
6626
|
const seedFiles = getSeedFiles(workspaceRootDir);
|
|
@@ -6594,23 +6651,23 @@ var clear2 = new Command54("clear").description("clear seeded records").configur
|
|
|
6594
6651
|
);
|
|
6595
6652
|
|
|
6596
6653
|
// src/commands/seeds.ts
|
|
6597
|
-
var seeds = new
|
|
6654
|
+
var seeds = new Command56("seeds").description("manage seed data").configureHelp(helpConfig).addCommand(load2).addCommand(save).addCommand(clear2);
|
|
6598
6655
|
|
|
6599
6656
|
// src/commands/signup.ts
|
|
6600
|
-
import { Command as
|
|
6601
|
-
import * as
|
|
6657
|
+
import { Command as Command58 } from "commander";
|
|
6658
|
+
import * as p30 from "@clack/prompts";
|
|
6602
6659
|
import makeFetchCookie2 from "fetch-cookie";
|
|
6603
6660
|
|
|
6604
6661
|
// src/commands/login.ts
|
|
6605
6662
|
import os3 from "node:os";
|
|
6606
|
-
import { Command as
|
|
6607
|
-
import * as
|
|
6663
|
+
import { Command as Command57 } from "commander";
|
|
6664
|
+
import * as p29 from "@clack/prompts";
|
|
6608
6665
|
import makeFetchCookie from "fetch-cookie";
|
|
6609
|
-
var login = new
|
|
6666
|
+
var login = new Command57("login").description("login to velastack.dev").configureHelp(helpConfig).action(
|
|
6610
6667
|
() => runCommand(async () => {
|
|
6611
|
-
const { email: email3, password: password11 } = await
|
|
6612
|
-
email: () =>
|
|
6613
|
-
password: () =>
|
|
6668
|
+
const { email: email3, password: password11 } = await p29.group({
|
|
6669
|
+
email: () => p29.text({ message: "Email" }),
|
|
6670
|
+
password: () => p29.password({ message: "Password" })
|
|
6614
6671
|
});
|
|
6615
6672
|
const fetchCookie = makeFetchCookie(fetch);
|
|
6616
6673
|
const loginRes = await fetchCookie(`${API_URL}/login`, {
|
|
@@ -6632,7 +6689,7 @@ var login = new Command56("login").description("login to velastack.dev").configu
|
|
|
6632
6689
|
}
|
|
6633
6690
|
const apiKey = await issueApiKey(fetchCookie);
|
|
6634
6691
|
writeConfig({ apiKey });
|
|
6635
|
-
|
|
6692
|
+
p29.log.success("Logged in to velastack.dev");
|
|
6636
6693
|
}, "Failed to login.")
|
|
6637
6694
|
);
|
|
6638
6695
|
async function issueApiKey(fetchCookie) {
|
|
@@ -6673,12 +6730,12 @@ function extractApiKey(cookie) {
|
|
|
6673
6730
|
}
|
|
6674
6731
|
|
|
6675
6732
|
// src/commands/signup.ts
|
|
6676
|
-
var signup = new
|
|
6733
|
+
var signup = new Command58("signup").description("signup to velastack.dev").configureHelp(helpConfig).action(
|
|
6677
6734
|
() => runCommand(async () => {
|
|
6678
|
-
const { email: email3, password: password11, passwordConfirm } = await
|
|
6679
|
-
email: () =>
|
|
6680
|
-
password: () =>
|
|
6681
|
-
passwordConfirm: () =>
|
|
6735
|
+
const { email: email3, password: password11, passwordConfirm } = await p30.group({
|
|
6736
|
+
email: () => p30.text({ message: "Email" }),
|
|
6737
|
+
password: () => p30.password({ message: "Password" }),
|
|
6738
|
+
passwordConfirm: () => p30.password({ message: "Confirm password" })
|
|
6682
6739
|
});
|
|
6683
6740
|
if (password11 !== passwordConfirm) {
|
|
6684
6741
|
throw new Error("Passwords do not match.");
|
|
@@ -6702,33 +6759,33 @@ var signup = new Command57("signup").description("signup to velastack.dev").conf
|
|
|
6702
6759
|
}
|
|
6703
6760
|
const apiKey = await issueApiKey(fetchCookie);
|
|
6704
6761
|
writeConfig({ apiKey });
|
|
6705
|
-
|
|
6706
|
-
|
|
6762
|
+
p30.log.success("Signed up to velastack.dev");
|
|
6763
|
+
p30.log.info("Check your email for a confirmation link.");
|
|
6707
6764
|
}, "Failed to signup.")
|
|
6708
6765
|
);
|
|
6709
6766
|
|
|
6710
6767
|
// src/commands/logout.ts
|
|
6711
|
-
import { Command as
|
|
6712
|
-
import * as
|
|
6713
|
-
var logout = new
|
|
6768
|
+
import { Command as Command59 } from "commander";
|
|
6769
|
+
import * as p31 from "@clack/prompts";
|
|
6770
|
+
var logout = new Command59("logout").alias("signout").description("logout from velastack.dev").configureHelp(helpConfig).action(
|
|
6714
6771
|
() => runCommand(() => {
|
|
6715
6772
|
if (!readConfig()) {
|
|
6716
|
-
|
|
6773
|
+
p31.log.info("Not logged in");
|
|
6717
6774
|
return;
|
|
6718
6775
|
}
|
|
6719
6776
|
clearConfig();
|
|
6720
|
-
|
|
6777
|
+
p31.log.success("Logged out of velastack.dev");
|
|
6721
6778
|
})
|
|
6722
6779
|
);
|
|
6723
6780
|
|
|
6724
6781
|
// src/commands/whoami.ts
|
|
6725
|
-
import { Command as
|
|
6726
|
-
import * as
|
|
6727
|
-
var whoami = new
|
|
6782
|
+
import { Command as Command60 } from "commander";
|
|
6783
|
+
import * as p32 from "@clack/prompts";
|
|
6784
|
+
var whoami = new Command60("whoami").description("show the current user").configureHelp(helpConfig).action(
|
|
6728
6785
|
() => runCommand(async () => {
|
|
6729
6786
|
const apiKey = readConfig()?.apiKey;
|
|
6730
6787
|
if (!apiKey) {
|
|
6731
|
-
|
|
6788
|
+
p32.log.info("Not logged in. Run `vela login` to login.");
|
|
6732
6789
|
return;
|
|
6733
6790
|
}
|
|
6734
6791
|
const res = await fetch(`${API_URL}/api/collections/users/records`, {
|
|
@@ -6736,22 +6793,22 @@ var whoami = new Command59("whoami").description("show the current user").config
|
|
|
6736
6793
|
});
|
|
6737
6794
|
const data = await res.json();
|
|
6738
6795
|
if (!data.items.length) throw new Error("No user found. Run `vela login` to login.");
|
|
6739
|
-
|
|
6796
|
+
p32.log.success(`Logged in as ${data.items[0].email}`);
|
|
6740
6797
|
})
|
|
6741
6798
|
);
|
|
6742
6799
|
|
|
6743
6800
|
// src/commands/migrate.ts
|
|
6744
|
-
import { Command as
|
|
6801
|
+
import { Command as Command66 } from "commander";
|
|
6745
6802
|
|
|
6746
6803
|
// src/commands/migrate/up.ts
|
|
6747
|
-
import { Command as
|
|
6804
|
+
import { Command as Command61 } from "commander";
|
|
6748
6805
|
|
|
6749
6806
|
// src/lib/migrate.ts
|
|
6750
6807
|
import path30 from "node:path";
|
|
6751
|
-
import
|
|
6808
|
+
import process18 from "node:process";
|
|
6752
6809
|
import { x as x2 } from "tinyexec";
|
|
6753
6810
|
async function runPocketbaseMigrate(args) {
|
|
6754
|
-
const cwd =
|
|
6811
|
+
const cwd = process18.cwd();
|
|
6755
6812
|
const { getBinaryPath } = await import("pocketbase-server");
|
|
6756
6813
|
const binaryPath = getBinaryPath();
|
|
6757
6814
|
await x2(
|
|
@@ -6783,10 +6840,10 @@ async function runMigrateUp() {
|
|
|
6783
6840
|
]
|
|
6784
6841
|
});
|
|
6785
6842
|
}
|
|
6786
|
-
var up = new
|
|
6843
|
+
var up = new Command61("up").description("apply all pending migrations").configureHelp(helpConfig).action(() => runCommand(runMigrateUp, "Failed to run migrations."));
|
|
6787
6844
|
|
|
6788
6845
|
// src/commands/migrate/down.ts
|
|
6789
|
-
import { Command as
|
|
6846
|
+
import { Command as Command62, InvalidArgumentError as InvalidArgumentError4 } from "commander";
|
|
6790
6847
|
function parseSteps(value) {
|
|
6791
6848
|
const n = parseInt(value, 10);
|
|
6792
6849
|
if (!Number.isFinite(n) || n <= 0) {
|
|
@@ -6794,7 +6851,7 @@ function parseSteps(value) {
|
|
|
6794
6851
|
}
|
|
6795
6852
|
return n;
|
|
6796
6853
|
}
|
|
6797
|
-
var down = new
|
|
6854
|
+
var down = new Command62("down").alias("rollback").description("revert the last N applied migrations").argument("[number]", "how many migrations to revert", parseSteps, 1).configureHelp(helpConfig).action(
|
|
6798
6855
|
(n) => runCommand(async () => {
|
|
6799
6856
|
await runPocketbaseMigrate(["down", String(n)]);
|
|
6800
6857
|
reportResult({
|
|
@@ -6810,11 +6867,11 @@ var down = new Command61("down").alias("rollback").description("revert the last
|
|
|
6810
6867
|
// src/commands/migrate/create.ts
|
|
6811
6868
|
import fs30 from "node:fs";
|
|
6812
6869
|
import path31 from "node:path";
|
|
6813
|
-
import
|
|
6814
|
-
import { Command as
|
|
6815
|
-
var create2 = new
|
|
6870
|
+
import process19 from "node:process";
|
|
6871
|
+
import { Command as Command63 } from "commander";
|
|
6872
|
+
var create2 = new Command63("create").alias("new").description("create a new blank migration").argument("<name>", "migration name (snake_case)").configureHelp(helpConfig).action(
|
|
6816
6873
|
(name) => runCommand(async () => {
|
|
6817
|
-
const cwd =
|
|
6874
|
+
const cwd = process19.cwd();
|
|
6818
6875
|
const before = listMigrationFiles(cwd);
|
|
6819
6876
|
await runPocketbaseMigrate(["create", name]);
|
|
6820
6877
|
const after = listMigrationFiles(cwd);
|
|
@@ -6838,11 +6895,11 @@ function listMigrationFiles(cwd) {
|
|
|
6838
6895
|
// src/commands/migrate/collections.ts
|
|
6839
6896
|
import fs31 from "node:fs";
|
|
6840
6897
|
import path32 from "node:path";
|
|
6841
|
-
import
|
|
6842
|
-
import { Command as
|
|
6843
|
-
var collections = new
|
|
6898
|
+
import process20 from "node:process";
|
|
6899
|
+
import { Command as Command64 } from "commander";
|
|
6900
|
+
var collections = new Command64("collections").alias("snapshot").description("snapshot local collections into a new migration").configureHelp(helpConfig).action(
|
|
6844
6901
|
() => runCommand(async () => {
|
|
6845
|
-
const cwd =
|
|
6902
|
+
const cwd = process20.cwd();
|
|
6846
6903
|
const before = listMigrationFiles2(cwd);
|
|
6847
6904
|
await runPocketbaseMigrate(["collections"]);
|
|
6848
6905
|
const after = listMigrationFiles2(cwd);
|
|
@@ -6871,8 +6928,8 @@ function listMigrationFiles2(cwd) {
|
|
|
6871
6928
|
}
|
|
6872
6929
|
|
|
6873
6930
|
// src/commands/migrate/history-sync.ts
|
|
6874
|
-
import { Command as
|
|
6875
|
-
var historySync = new
|
|
6931
|
+
import { Command as Command65 } from "commander";
|
|
6932
|
+
var historySync = new Command65("history-sync").description("drop _migrations rows whose files no longer exist").configureHelp(helpConfig).action(
|
|
6876
6933
|
() => runCommand(async () => {
|
|
6877
6934
|
await runPocketbaseMigrate(["history-sync"]);
|
|
6878
6935
|
reportResult({
|
|
@@ -6883,23 +6940,23 @@ var historySync = new Command64("history-sync").description("drop _migrations ro
|
|
|
6883
6940
|
);
|
|
6884
6941
|
|
|
6885
6942
|
// src/commands/migrate.ts
|
|
6886
|
-
var migrate = new
|
|
6943
|
+
var migrate = new Command66("migrate").description("manage database migrations").configureHelp(helpConfig).action(() => runCommand(runMigrateUp, "Failed to run migrations.")).addCommand(up).addCommand(down).addCommand(create2).addCommand(collections).addCommand(historySync);
|
|
6887
6944
|
|
|
6888
6945
|
// src/commands/dev.ts
|
|
6889
6946
|
import fs32 from "node:fs";
|
|
6890
6947
|
import path34 from "node:path";
|
|
6891
|
-
import
|
|
6948
|
+
import process22 from "node:process";
|
|
6892
6949
|
import { performance } from "node:perf_hooks";
|
|
6893
|
-
import { Command as
|
|
6894
|
-
import
|
|
6950
|
+
import { Command as Command67, InvalidArgumentError as InvalidArgumentError5 } from "commander";
|
|
6951
|
+
import pc13 from "picocolors";
|
|
6895
6952
|
import PocketBase3 from "pocketbase";
|
|
6896
6953
|
|
|
6897
6954
|
// src/lib/vite.ts
|
|
6898
6955
|
import path33 from "node:path";
|
|
6899
|
-
import
|
|
6956
|
+
import process21 from "node:process";
|
|
6900
6957
|
import { createRequire as createRequire2 } from "node:module";
|
|
6901
6958
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
6902
|
-
import
|
|
6959
|
+
import pc12 from "picocolors";
|
|
6903
6960
|
var REQUIRED_VITE_MAJOR = 8;
|
|
6904
6961
|
function viteVersionError(version) {
|
|
6905
6962
|
const major = Number.parseInt(version, 10);
|
|
@@ -6920,13 +6977,13 @@ function resolveProjectVite(cwd) {
|
|
|
6920
6977
|
return null;
|
|
6921
6978
|
}
|
|
6922
6979
|
}
|
|
6923
|
-
async function loadVite(cwd =
|
|
6980
|
+
async function loadVite(cwd = process21.cwd()) {
|
|
6924
6981
|
const entry = resolveProjectVite(cwd);
|
|
6925
6982
|
const vite = entry ? await import(pathToFileURL2(entry).href) : await import("vite");
|
|
6926
6983
|
const error = viteVersionError(vite.version);
|
|
6927
6984
|
if (error) {
|
|
6928
|
-
console.error(`${
|
|
6929
|
-
|
|
6985
|
+
console.error(`${pc12.redBright("\u2717")} ${error}`);
|
|
6986
|
+
process21.exit(1);
|
|
6930
6987
|
}
|
|
6931
6988
|
return vite;
|
|
6932
6989
|
}
|
|
@@ -6939,16 +6996,16 @@ function parsePort(value) {
|
|
|
6939
6996
|
}
|
|
6940
6997
|
return port;
|
|
6941
6998
|
}
|
|
6942
|
-
var dev = new
|
|
6943
|
-
const cwd =
|
|
6944
|
-
|
|
6999
|
+
var dev = new Command67("dev").description("start the development server").option("--open [path]", "open the app in a browser once the server is ready").option("--host [host]", "expose the server on the network").option("--port <port>", "port to listen on", parsePort).option("--strictPort", "exit if the port is already in use instead of taking the next one").option("--cors", "enable CORS").option("--force", "re-bundle dependencies, ignoring the optimizer cache").configureHelp(helpConfig).action(async (options) => {
|
|
7000
|
+
const cwd = process22.cwd();
|
|
7001
|
+
process22.env.VELA_DATA_DIR ??= localDataDir(cwd);
|
|
6945
7002
|
const startTime = performance.now();
|
|
6946
7003
|
const { createServer, version } = await loadVite(cwd);
|
|
6947
7004
|
const viteMetadataDir = path34.join(cwd, "node_modules", ".vite");
|
|
6948
7005
|
const viteMetadataFile = path34.join(viteMetadataDir, "_pocketbase_metadata.json");
|
|
6949
7006
|
let pbProc;
|
|
6950
7007
|
const backend3 = hasBackend(cwd);
|
|
6951
|
-
const needsStart = backend3 && !
|
|
7008
|
+
const needsStart = backend3 && !process22.env.POCKETBASE_URL;
|
|
6952
7009
|
const cleanup = () => {
|
|
6953
7010
|
if (pbProc?.pid) pbProc.kill();
|
|
6954
7011
|
if (fs32.existsSync(viteMetadataFile)) fs32.rmSync(viteMetadataFile);
|
|
@@ -6963,15 +7020,15 @@ var dev = new Command66("dev").description("start the development server").optio
|
|
|
6963
7020
|
stdio: "pipe"
|
|
6964
7021
|
});
|
|
6965
7022
|
pbProc = started.proc;
|
|
6966
|
-
|
|
6967
|
-
pbProc.stdout?.pipe(
|
|
6968
|
-
pbProc.stderr?.pipe(
|
|
7023
|
+
process22.env.POCKETBASE_URL = started.url;
|
|
7024
|
+
pbProc.stdout?.pipe(process22.stdout);
|
|
7025
|
+
pbProc.stderr?.pipe(process22.stderr);
|
|
6969
7026
|
pbProc.on("error", (err) => console.error("PocketBase error:", err));
|
|
6970
7027
|
pbProc.on("exit", (code) => console.log(`PocketBase exited with code ${code}`));
|
|
6971
|
-
|
|
6972
|
-
|
|
7028
|
+
process22.on("exit", cleanup);
|
|
7029
|
+
process22.on("SIGINT", () => {
|
|
6973
7030
|
cleanup();
|
|
6974
|
-
|
|
7031
|
+
process22.exit(0);
|
|
6975
7032
|
});
|
|
6976
7033
|
}
|
|
6977
7034
|
const serverOptions = {};
|
|
@@ -6993,27 +7050,27 @@ var dev = new Command66("dev").description("start the development server").optio
|
|
|
6993
7050
|
await fs32.promises.writeFile(
|
|
6994
7051
|
viteMetadataFile,
|
|
6995
7052
|
JSON.stringify({
|
|
6996
|
-
pocketbaseUrl:
|
|
7053
|
+
pocketbaseUrl: process22.env.POCKETBASE_URL,
|
|
6997
7054
|
vitePort,
|
|
6998
7055
|
viteHost
|
|
6999
7056
|
})
|
|
7000
7057
|
);
|
|
7001
|
-
const pb = new PocketBase3(
|
|
7058
|
+
const pb = new PocketBase3(process22.env.POCKETBASE_URL);
|
|
7002
7059
|
await pb.collection("_superusers").authWithPassword(
|
|
7003
|
-
|
|
7004
|
-
|
|
7060
|
+
process22.env.POCKETBASE_SUPERUSER_EMAIL,
|
|
7061
|
+
process22.env.POCKETBASE_SUPERUSER_PASSWORD
|
|
7005
7062
|
);
|
|
7006
7063
|
await pb.settings.update({ meta: { appURL: `http://${viteHost}:${vitePort}` } });
|
|
7007
7064
|
await startWatchingTypes(cwd, pb);
|
|
7008
7065
|
});
|
|
7009
7066
|
await server.listen();
|
|
7010
|
-
const hasExistingLogs =
|
|
7011
|
-
const startupDurationString =
|
|
7012
|
-
`ready in ${
|
|
7067
|
+
const hasExistingLogs = process22.stdout.bytesWritten > 0 || process22.stderr.bytesWritten > 0;
|
|
7068
|
+
const startupDurationString = pc13.dim(
|
|
7069
|
+
`ready in ${pc13.reset(pc13.bold(Math.ceil(performance.now() - startTime)))} ms`
|
|
7013
7070
|
);
|
|
7014
7071
|
server.config.logger.info(
|
|
7015
7072
|
`
|
|
7016
|
-
${
|
|
7073
|
+
${pc13.green(`${pc13.bold("VITE")} v${version}`)} ${startupDurationString}
|
|
7017
7074
|
`,
|
|
7018
7075
|
{ clear: !hasExistingLogs }
|
|
7019
7076
|
);
|
|
@@ -7047,10 +7104,10 @@ async function startWatchingTypes(cwd, pb) {
|
|
|
7047
7104
|
// src/commands/build.ts
|
|
7048
7105
|
import fs33 from "node:fs";
|
|
7049
7106
|
import path35 from "node:path";
|
|
7050
|
-
import
|
|
7051
|
-
import { Command as
|
|
7052
|
-
import * as
|
|
7053
|
-
import
|
|
7107
|
+
import process24 from "node:process";
|
|
7108
|
+
import { Command as Command68 } from "commander";
|
|
7109
|
+
import * as p33 from "@clack/prompts";
|
|
7110
|
+
import pc14 from "picocolors";
|
|
7054
7111
|
import { x as x3 } from "tinyexec";
|
|
7055
7112
|
import { detect as detect5 } from "package-manager-detector";
|
|
7056
7113
|
import { resolveCommand as resolveCommand5 } from "package-manager-detector/commands";
|
|
@@ -7062,10 +7119,10 @@ function applyBuildEnv(cwd, env2 = process.env) {
|
|
|
7062
7119
|
}
|
|
7063
7120
|
|
|
7064
7121
|
// src/lib/origin.ts
|
|
7065
|
-
import
|
|
7122
|
+
import process23 from "node:process";
|
|
7066
7123
|
function resolveOrigin(workspaceRootDir, envTag, config = {}) {
|
|
7067
7124
|
return normalizeOrigin(
|
|
7068
|
-
|
|
7125
|
+
process23.env.VELA_ORIGIN ?? readBinding(workspaceRootDir, envTag)?.domain ?? config.deploy?.domain
|
|
7069
7126
|
);
|
|
7070
7127
|
}
|
|
7071
7128
|
function normalizeOrigin(value) {
|
|
@@ -7082,13 +7139,13 @@ function normalizeOrigin(value) {
|
|
|
7082
7139
|
|
|
7083
7140
|
// src/commands/build.ts
|
|
7084
7141
|
var PRERENDERED_DIR = path35.join(".svelte-kit", "output", "prerendered");
|
|
7085
|
-
var build = new
|
|
7086
|
-
const cwd =
|
|
7142
|
+
var build = new Command68("build").description("build the app").configureHelp(helpConfig).option("-t, --target <target>", "which copy of the app to build for", PRODUCTION_TARGET).action(async (options) => {
|
|
7143
|
+
const cwd = process24.cwd();
|
|
7087
7144
|
applyBuildEnv(cwd);
|
|
7088
7145
|
const origin = await originForBuild(cwd, options.target);
|
|
7089
|
-
if (origin)
|
|
7146
|
+
if (origin) process24.env.VELA_ORIGIN = origin;
|
|
7090
7147
|
let pbProc;
|
|
7091
|
-
const needsStart = hasBackend(cwd) && !
|
|
7148
|
+
const needsStart = hasBackend(cwd) && !process24.env.POCKETBASE_URL;
|
|
7092
7149
|
const cleanup = () => {
|
|
7093
7150
|
if (pbProc?.pid) pbProc.kill();
|
|
7094
7151
|
};
|
|
@@ -7102,11 +7159,11 @@ var build = new Command67("build").description("build the app").configureHelp(he
|
|
|
7102
7159
|
dev: true
|
|
7103
7160
|
});
|
|
7104
7161
|
pbProc = started.proc;
|
|
7105
|
-
|
|
7106
|
-
|
|
7107
|
-
|
|
7162
|
+
process24.env.POCKETBASE_URL = started.url;
|
|
7163
|
+
process24.on("exit", cleanup);
|
|
7164
|
+
process24.on("SIGINT", () => {
|
|
7108
7165
|
cleanup();
|
|
7109
|
-
|
|
7166
|
+
process24.exit(0);
|
|
7110
7167
|
});
|
|
7111
7168
|
}
|
|
7112
7169
|
try {
|
|
@@ -7138,26 +7195,26 @@ async function originForBuild(cwd, target) {
|
|
|
7138
7195
|
function warnIfPrerendered(cwd) {
|
|
7139
7196
|
const dir = path35.join(cwd, PRERENDERED_DIR);
|
|
7140
7197
|
if (!fs33.existsSync(dir) || fs33.readdirSync(dir).length === 0) return;
|
|
7141
|
-
|
|
7198
|
+
p33.log.warn(
|
|
7142
7199
|
`Prerendered pages were built with no domain configured, so their canonical
|
|
7143
7200
|
links point at SvelteKit's placeholder host rather than at this site.
|
|
7144
7201
|
|
|
7145
|
-
Set one with ${
|
|
7202
|
+
Set one with ${pc14.cyan("vela deploy --domain example.com")}, or pass ${pc14.cyan("VELA_ORIGIN")}.`
|
|
7146
7203
|
);
|
|
7147
7204
|
}
|
|
7148
7205
|
|
|
7149
7206
|
// src/commands/preview.ts
|
|
7150
7207
|
import path36 from "node:path";
|
|
7151
|
-
import
|
|
7152
|
-
import { Command as
|
|
7208
|
+
import process25 from "node:process";
|
|
7209
|
+
import { Command as Command69 } from "commander";
|
|
7153
7210
|
import { x as x4 } from "tinyexec";
|
|
7154
7211
|
import { detect as detect6 } from "package-manager-detector";
|
|
7155
7212
|
import { resolveCommand as resolveCommand6 } from "package-manager-detector/commands";
|
|
7156
|
-
var preview = new
|
|
7157
|
-
const cwd =
|
|
7158
|
-
|
|
7213
|
+
var preview = new Command69("preview").description("preview the built app").configureHelp(helpConfig).action(async () => {
|
|
7214
|
+
const cwd = process25.cwd();
|
|
7215
|
+
process25.env.VELA_DATA_DIR ??= localDataDir(cwd);
|
|
7159
7216
|
let pbProc;
|
|
7160
|
-
const needsStart = hasBackend(cwd) && !
|
|
7217
|
+
const needsStart = hasBackend(cwd) && !process25.env.POCKETBASE_URL;
|
|
7161
7218
|
const cleanup = () => {
|
|
7162
7219
|
if (pbProc?.pid) pbProc.kill();
|
|
7163
7220
|
};
|
|
@@ -7170,11 +7227,11 @@ var preview = new Command68("preview").description("preview the built app").conf
|
|
|
7170
7227
|
dev: true
|
|
7171
7228
|
});
|
|
7172
7229
|
pbProc = started.proc;
|
|
7173
|
-
|
|
7174
|
-
|
|
7175
|
-
|
|
7230
|
+
process25.env.POCKETBASE_URL = started.url;
|
|
7231
|
+
process25.on("exit", cleanup);
|
|
7232
|
+
process25.on("SIGINT", () => {
|
|
7176
7233
|
cleanup();
|
|
7177
|
-
|
|
7234
|
+
process25.exit(0);
|
|
7178
7235
|
});
|
|
7179
7236
|
}
|
|
7180
7237
|
try {
|
|
@@ -7193,8 +7250,8 @@ var preview = new Command68("preview").description("preview the built app").conf
|
|
|
7193
7250
|
|
|
7194
7251
|
// src/commands/sync.ts
|
|
7195
7252
|
import path37 from "node:path";
|
|
7196
|
-
import { Command as
|
|
7197
|
-
var sync = new
|
|
7253
|
+
import { Command as Command70 } from "commander";
|
|
7254
|
+
var sync = new Command70("sync").description("sync types from the database").configureHelp(helpConfig).action(
|
|
7198
7255
|
() => runCommand(async () => {
|
|
7199
7256
|
const { workspaceRootDir } = await getWorkspace();
|
|
7200
7257
|
const typesDir = path37.join(workspaceRootDir, ".svelte-kit", "types");
|
|
@@ -7207,9 +7264,9 @@ var sync = new Command69("sync").description("sync types from the database").con
|
|
|
7207
7264
|
);
|
|
7208
7265
|
|
|
7209
7266
|
// src/commands/provision.ts
|
|
7210
|
-
import { Command as
|
|
7211
|
-
import * as
|
|
7212
|
-
import
|
|
7267
|
+
import { Command as Command71 } from "commander";
|
|
7268
|
+
import * as p34 from "@clack/prompts";
|
|
7269
|
+
import pc15 from "picocolors";
|
|
7213
7270
|
import * as v6 from "valibot";
|
|
7214
7271
|
var OptionsSchema2 = v6.object({
|
|
7215
7272
|
...SSH_OPTION_SCHEMA,
|
|
@@ -7217,24 +7274,24 @@ var OptionsSchema2 = v6.object({
|
|
|
7217
7274
|
nodeMajor: v6.optional(v6.string())
|
|
7218
7275
|
});
|
|
7219
7276
|
var provision = addSshOptions(
|
|
7220
|
-
new
|
|
7277
|
+
new Command71("provision").description("prepare a server to host vela apps").argument("<target>", "SSH target \u2014 an alias from ~/.ssh/config, or user@host").configureHelp(helpConfig)
|
|
7221
7278
|
).option("--pb-version <version>", "PocketBase version to install").option("--node-major <version>", "Node.js major version to install", "22").action(
|
|
7222
7279
|
(target, raw) => runCommand(async () => {
|
|
7223
7280
|
const options = parseOptions(OptionsSchema2, raw);
|
|
7224
7281
|
const pbVersion = options.pbVersion ?? pocketbaseVersion();
|
|
7225
|
-
|
|
7226
|
-
|
|
7282
|
+
p34.intro(pc15.bgCyan(pc15.black(" vela provision ")));
|
|
7283
|
+
p34.log.info(`Target ${pc15.cyan(target)}`);
|
|
7227
7284
|
await withSsh(target, sshOptionsFrom(options), async (session) => {
|
|
7228
7285
|
await session.detectElevation();
|
|
7229
7286
|
const existing = await readServerInfo(session);
|
|
7230
7287
|
if (existing) {
|
|
7231
|
-
|
|
7288
|
+
p34.log.info(
|
|
7232
7289
|
`Already provisioned by vela ${existing.cliVersion} on ${existing.provisionedAt}. Bringing it up to date.`
|
|
7233
7290
|
);
|
|
7234
7291
|
}
|
|
7235
|
-
|
|
7292
|
+
p34.log.step("Uploading server scripts");
|
|
7236
7293
|
await syncServerScripts(session);
|
|
7237
|
-
|
|
7294
|
+
p34.log.step("Running provision");
|
|
7238
7295
|
const result = await runServerScript(session, "provision.sh", {
|
|
7239
7296
|
args: [
|
|
7240
7297
|
"--pb-version",
|
|
@@ -7246,7 +7303,7 @@ var provision = addSshOptions(
|
|
|
7246
7303
|
],
|
|
7247
7304
|
stream: true
|
|
7248
7305
|
});
|
|
7249
|
-
|
|
7306
|
+
p34.log.success(
|
|
7250
7307
|
`${target} is ready.
|
|
7251
7308
|
|
|
7252
7309
|
Node ${result?.node ?? "installed"}
|
|
@@ -7254,29 +7311,29 @@ var provision = addSshOptions(
|
|
|
7254
7311
|
PocketBase ${result?.pocketbase ?? pbVersion}`
|
|
7255
7312
|
);
|
|
7256
7313
|
});
|
|
7257
|
-
|
|
7314
|
+
p34.outro(`Deploy with ${pc15.cyan(`vela deploy --server ${target}`)}`);
|
|
7258
7315
|
}, "Failed to provision.")
|
|
7259
7316
|
);
|
|
7260
7317
|
|
|
7261
7318
|
// src/commands/deploy.ts
|
|
7262
7319
|
import path40 from "node:path";
|
|
7263
7320
|
import fs36 from "node:fs";
|
|
7264
|
-
import { Command as
|
|
7265
|
-
import * as
|
|
7266
|
-
import
|
|
7321
|
+
import { Command as Command72, Option as Option2 } from "commander";
|
|
7322
|
+
import * as p35 from "@clack/prompts";
|
|
7323
|
+
import pc16 from "picocolors";
|
|
7267
7324
|
import * as v7 from "valibot";
|
|
7268
7325
|
|
|
7269
7326
|
// src/lib/pocketbase-settings.ts
|
|
7270
7327
|
import fs34 from "node:fs";
|
|
7271
7328
|
import path38 from "node:path";
|
|
7272
|
-
import
|
|
7329
|
+
import process26 from "node:process";
|
|
7273
7330
|
import PocketBase4 from "pocketbase";
|
|
7274
7331
|
var COPIED_KEYS = ["appName", "senderName", "senderAddress"];
|
|
7275
7332
|
async function readLocalMeta(cwd) {
|
|
7276
7333
|
const dataDir = path38.join(cwd, DATA_DIR);
|
|
7277
7334
|
if (!fs34.existsSync(dataDir)) return null;
|
|
7278
|
-
const email3 =
|
|
7279
|
-
const password11 =
|
|
7335
|
+
const email3 = process26.env.POCKETBASE_SUPERUSER_EMAIL;
|
|
7336
|
+
const password11 = process26.env.POCKETBASE_SUPERUSER_PASSWORD;
|
|
7280
7337
|
if (!email3 || !password11) return null;
|
|
7281
7338
|
let proc;
|
|
7282
7339
|
try {
|
|
@@ -7403,7 +7460,7 @@ var OptionsSchema3 = v7.object({
|
|
|
7403
7460
|
build: v7.optional(v7.boolean())
|
|
7404
7461
|
});
|
|
7405
7462
|
var deploy = addTargetOptions(
|
|
7406
|
-
new
|
|
7463
|
+
new Command72("deploy").description("deploy the app").configureHelp(helpConfig),
|
|
7407
7464
|
"production"
|
|
7408
7465
|
).option("--project <name>", "override the project name").option("--domain <hosts>", "hostname(s) to serve on, comma separated").option("--health-path <path>", "path the health check requests").option("--keep <count>", "how many old releases to keep on the server").option("--pb-version <version>", "PocketBase version to run").option("--no-build", "deploy the existing build output without rebuilding").addOption(
|
|
7409
7466
|
new Option2(
|
|
@@ -7419,14 +7476,14 @@ var deploy = addTargetOptions(
|
|
|
7419
7476
|
const options = parseOptions(OptionsSchema3, raw);
|
|
7420
7477
|
const backend3 = hasBackend();
|
|
7421
7478
|
const release = releaseId();
|
|
7422
|
-
|
|
7479
|
+
p35.intro(pc16.bgCyan(pc16.black(" vela deploy ")));
|
|
7423
7480
|
await withTarget(
|
|
7424
7481
|
raw,
|
|
7425
7482
|
{
|
|
7426
7483
|
remote: async (ctx) => {
|
|
7427
7484
|
const { session, instance, workspaceRootDir, config } = ctx;
|
|
7428
|
-
|
|
7429
|
-
`${
|
|
7485
|
+
p35.log.info(
|
|
7486
|
+
`${pc16.cyan(ctx.appName)} ${pc16.dim("\u2192")} ${pc16.cyan(ctx.targetName)} ${pc16.dim(`(${ctx.server})`)}`
|
|
7430
7487
|
);
|
|
7431
7488
|
const [existing] = await readInstanceStates(session, instance);
|
|
7432
7489
|
const domain = options.domain ?? ctx.binding.domain ?? config.deploy?.domain ?? existing?.domain ?? "";
|
|
@@ -7441,21 +7498,21 @@ var deploy = addTargetOptions(
|
|
|
7441
7498
|
tunnel = await openDatabaseTunnel(session, instance, existing);
|
|
7442
7499
|
} catch (err) {
|
|
7443
7500
|
if (askedForRemoteDb) throw err;
|
|
7444
|
-
|
|
7445
|
-
`Could not build against the ${
|
|
7446
|
-
${
|
|
7501
|
+
p35.log.warn(
|
|
7502
|
+
`Could not build against the ${pc16.cyan(ctx.targetName)} database, using a local one instead.
|
|
7503
|
+
${pc16.dim(String(err))}`
|
|
7447
7504
|
);
|
|
7448
7505
|
}
|
|
7449
7506
|
}
|
|
7450
7507
|
if (tunnel) {
|
|
7451
7508
|
buildEnv = { ...buildEnv, ...tunnel.env };
|
|
7452
|
-
|
|
7453
|
-
`Building against the ${
|
|
7509
|
+
p35.log.info(
|
|
7510
|
+
`Building against the ${pc16.cyan(ctx.targetName)} database on ${ctx.server} ${pc16.dim(`(port ${tunnel.pbPort})`)}`
|
|
7454
7511
|
);
|
|
7455
7512
|
} else if (backend3) {
|
|
7456
7513
|
await ensureSuperuser(workspaceRootDir);
|
|
7457
7514
|
}
|
|
7458
|
-
|
|
7515
|
+
p35.log.step("Building");
|
|
7459
7516
|
try {
|
|
7460
7517
|
await runBuild(workspaceRootDir, config.deploy?.buildCommand, buildEnv);
|
|
7461
7518
|
} finally {
|
|
@@ -7464,9 +7521,9 @@ ${pc15.dim(String(err))}`
|
|
|
7464
7521
|
}
|
|
7465
7522
|
const entries = collectArtifact(workspaceRootDir, config.deploy ?? {});
|
|
7466
7523
|
const sha = await gitSha(workspaceRootDir);
|
|
7467
|
-
|
|
7524
|
+
p35.log.step(`Uploading release ${pc16.dim(release)}`);
|
|
7468
7525
|
await uploadRelease(session, instance, release, entries);
|
|
7469
|
-
|
|
7526
|
+
p35.log.step("Activating");
|
|
7470
7527
|
const result = await runServerScript(session, "apply.sh", {
|
|
7471
7528
|
args: [
|
|
7472
7529
|
instance,
|
|
@@ -7498,8 +7555,8 @@ ${pc15.dim(String(err))}`
|
|
|
7498
7555
|
});
|
|
7499
7556
|
if (!existing) await reportEmptyEnvironment(session, instance, workspaceRootDir);
|
|
7500
7557
|
const url = result?.url ?? "";
|
|
7501
|
-
|
|
7502
|
-
`Deployed ${
|
|
7558
|
+
p35.log.success(
|
|
7559
|
+
`Deployed ${pc16.cyan(ctx.appName)} ${pc16.dim(release)}
|
|
7503
7560
|
|
|
7504
7561
|
URL ${url}
|
|
7505
7562
|
Port ${result?.webPort ?? "?"}${backend3 ? ` (PocketBase ${result?.pbPort ?? "?"})` : ""}`
|
|
@@ -7511,27 +7568,27 @@ ${pc15.dim(String(err))}`
|
|
|
7511
7568
|
workspaceRootDir,
|
|
7512
7569
|
domain ? result?.url ?? "" : ""
|
|
7513
7570
|
);
|
|
7514
|
-
|
|
7571
|
+
p35.log.info(
|
|
7515
7572
|
`Created the PocketBase superuser this app authenticates as.
|
|
7516
7573
|
|
|
7517
7574
|
Its credentials are stored in the environment on the server. To use
|
|
7518
|
-
your own instead, ${
|
|
7575
|
+
your own instead, ${pc16.cyan("vela env set POCKETBASE_SUPERUSER_PASSWORD")}
|
|
7519
7576
|
and deploy again.`
|
|
7520
7577
|
);
|
|
7521
7578
|
} else if (backend3 && domain) {
|
|
7522
7579
|
await reportAppURLDrift(session, instance, domain);
|
|
7523
7580
|
}
|
|
7524
7581
|
if (!domain) {
|
|
7525
|
-
|
|
7582
|
+
p35.log.warn(
|
|
7526
7583
|
`No domain configured, so nothing is proxied to this app yet.
|
|
7527
|
-
Redeploy with ${
|
|
7584
|
+
Redeploy with ${pc16.cyan("--domain example.com")} once DNS points at ${ctx.server}.`
|
|
7528
7585
|
);
|
|
7529
7586
|
}
|
|
7530
7587
|
}
|
|
7531
7588
|
},
|
|
7532
7589
|
{ project: options.project, askDomain: true, label: "deploy" }
|
|
7533
7590
|
);
|
|
7534
|
-
|
|
7591
|
+
p35.outro(`${pc16.cyan("vela status")} to see what is running`);
|
|
7535
7592
|
}, "Failed to deploy.")
|
|
7536
7593
|
);
|
|
7537
7594
|
async function reportAppURLDrift(session, instance, domain) {
|
|
@@ -7539,8 +7596,8 @@ async function reportAppURLDrift(session, instance, domain) {
|
|
|
7539
7596
|
if (!expected) return;
|
|
7540
7597
|
const current = await readRemoteAppURL(session, instance);
|
|
7541
7598
|
if (!current || normalizeOrigin(current) === expected) return;
|
|
7542
|
-
|
|
7543
|
-
`This app's PocketBase ${
|
|
7599
|
+
p35.log.warn(
|
|
7600
|
+
`This app's PocketBase ${pc16.cyan("appURL")} is ${pc16.dim(current)}, but it is served on ${pc16.dim(expected)}.
|
|
7544
7601
|
|
|
7545
7602
|
Emails and anything else PocketBase links to will use the former. Update it in
|
|
7546
7603
|
the admin panel if that is not deliberate.`
|
|
@@ -7554,17 +7611,17 @@ async function copyLocalBranding(session, instance, workspaceRootDir, appURL) {
|
|
|
7554
7611
|
if (copied.length === 0) return;
|
|
7555
7612
|
const outcome = await restartInstance(session, instance);
|
|
7556
7613
|
if (outcome.deployed && !outcome.restarted) {
|
|
7557
|
-
|
|
7614
|
+
p35.log.warn(
|
|
7558
7615
|
`Copied ${copied.join(", ")}, but the app did not restart to pick them up.
|
|
7559
|
-
${
|
|
7616
|
+
${pc16.dim(outcome.error ?? "")}`
|
|
7560
7617
|
);
|
|
7561
7618
|
return;
|
|
7562
7619
|
}
|
|
7563
|
-
|
|
7620
|
+
p35.log.success(`Copied ${copied.join(", ")} from this project's database`);
|
|
7564
7621
|
} catch (err) {
|
|
7565
|
-
|
|
7622
|
+
p35.log.warn(
|
|
7566
7623
|
`Could not copy this project's PocketBase settings across.
|
|
7567
|
-
Set them in the admin panel instead. ${
|
|
7624
|
+
Set them in the admin panel instead. ${pc16.dim(String(err))}`
|
|
7568
7625
|
);
|
|
7569
7626
|
}
|
|
7570
7627
|
}
|
|
@@ -7589,6 +7646,22 @@ Set them with \`vela env set POCKETBASE_SUPERUSER_EMAIL\` and \`vela env set POC
|
|
|
7589
7646
|
}
|
|
7590
7647
|
const localPort = await findFreePort("127.0.0.1");
|
|
7591
7648
|
await session.forwardLocalPort(localPort, "127.0.0.1", pbPort);
|
|
7649
|
+
if (!await superuserAuthenticates(localPort, email3, password11)) {
|
|
7650
|
+
await session.cancelForward(localPort, "127.0.0.1", pbPort);
|
|
7651
|
+
throw new Error(
|
|
7652
|
+
`${instance} does not accept the superuser credentials in its own environment.
|
|
7653
|
+
|
|
7654
|
+
They are what \`--remote-db\` renders the build as. The usual cause is a password
|
|
7655
|
+
changed in the PocketBase admin panel, which leaves the database and
|
|
7656
|
+
${pc16.cyan(`/etc/vela/apps/${instance}/env`)} disagreeing.
|
|
7657
|
+
|
|
7658
|
+
Point the environment at the password the database has:
|
|
7659
|
+
${pc16.cyan("vela env set POCKETBASE_SUPERUSER_PASSWORD")}
|
|
7660
|
+
|
|
7661
|
+
or build against a throwaway local database instead:
|
|
7662
|
+
${pc16.cyan("vela deploy --no-remote-db")}`
|
|
7663
|
+
);
|
|
7664
|
+
}
|
|
7592
7665
|
return {
|
|
7593
7666
|
pbPort,
|
|
7594
7667
|
env: {
|
|
@@ -7599,6 +7672,21 @@ Set them with \`vela env set POCKETBASE_SUPERUSER_EMAIL\` and \`vela env set POC
|
|
|
7599
7672
|
close: () => session.cancelForward(localPort, "127.0.0.1", pbPort)
|
|
7600
7673
|
};
|
|
7601
7674
|
}
|
|
7675
|
+
async function superuserAuthenticates(port, identity, password11) {
|
|
7676
|
+
try {
|
|
7677
|
+
const response = await fetch(
|
|
7678
|
+
`http://127.0.0.1:${port}/api/collections/_superusers/auth-with-password`,
|
|
7679
|
+
{
|
|
7680
|
+
method: "POST",
|
|
7681
|
+
headers: { "content-type": "application/json" },
|
|
7682
|
+
body: JSON.stringify({ identity, password: password11 })
|
|
7683
|
+
}
|
|
7684
|
+
);
|
|
7685
|
+
return response.ok;
|
|
7686
|
+
} catch {
|
|
7687
|
+
return true;
|
|
7688
|
+
}
|
|
7689
|
+
}
|
|
7602
7690
|
async function uploadRelease(session, instance, release, entries) {
|
|
7603
7691
|
const dir = remotePaths.release(instance, release);
|
|
7604
7692
|
await session.script(`mkdir -p "$1"`, { args: [dir] });
|
|
@@ -7624,19 +7712,19 @@ async function reportEmptyEnvironment(session, instance, workspaceRootDir) {
|
|
|
7624
7712
|
const remote = await readRemoteEnv(session, instance);
|
|
7625
7713
|
if (Object.keys(remote).length > 0) return;
|
|
7626
7714
|
if (!fs36.existsSync(path40.join(workspaceRootDir, ".env"))) return;
|
|
7627
|
-
|
|
7715
|
+
p35.log.warn(
|
|
7628
7716
|
`This app has no production environment variables yet.
|
|
7629
7717
|
|
|
7630
|
-
Local ${
|
|
7631
|
-
${
|
|
7718
|
+
Local ${pc16.cyan(".env")} values are not uploaded by a deploy. Set them with
|
|
7719
|
+
${pc16.cyan("vela env set KEY")}, or copy a file across with ${pc16.cyan("vela env import .env.production")}.`
|
|
7632
7720
|
);
|
|
7633
7721
|
}
|
|
7634
7722
|
|
|
7635
7723
|
// src/commands/link.ts
|
|
7636
7724
|
import path41 from "node:path";
|
|
7637
|
-
import
|
|
7638
|
-
import { Command as
|
|
7639
|
-
import * as
|
|
7725
|
+
import process27 from "node:process";
|
|
7726
|
+
import { Command as Command73 } from "commander";
|
|
7727
|
+
import * as p36 from "@clack/prompts";
|
|
7640
7728
|
|
|
7641
7729
|
// src/lib/velastack-api.ts
|
|
7642
7730
|
async function apiFetch(apiKey, pathAndQuery, init) {
|
|
@@ -7687,12 +7775,12 @@ async function createProject2(apiKey, args) {
|
|
|
7687
7775
|
|
|
7688
7776
|
// src/commands/link.ts
|
|
7689
7777
|
var CREATE_NEW = "__new__";
|
|
7690
|
-
var link = new
|
|
7778
|
+
var link = new Command73("link").description("link this project to a velastack.dev project").configureHelp(helpConfig).action(() => runCommand(linkProject, "Failed to link the project."));
|
|
7691
7779
|
async function linkProject() {
|
|
7692
7780
|
const { workspaceRootDir } = await getWorkspace();
|
|
7693
7781
|
const existing = readProjectConfig(workspaceRootDir);
|
|
7694
7782
|
if (existing) {
|
|
7695
|
-
|
|
7783
|
+
p36.log.success(`Linked to ${existing.projectName}.`);
|
|
7696
7784
|
return;
|
|
7697
7785
|
}
|
|
7698
7786
|
const apiKey = requireApiKey();
|
|
@@ -7719,10 +7807,10 @@ async function linkProject() {
|
|
|
7719
7807
|
projectName = created.name;
|
|
7720
7808
|
}
|
|
7721
7809
|
writeProjectConfig(workspaceRootDir, { projectId, teamId, projectName });
|
|
7722
|
-
|
|
7810
|
+
p36.log.success(`Linked to ${projectName}.`);
|
|
7723
7811
|
}
|
|
7724
7812
|
async function pickExistingProject(projects) {
|
|
7725
|
-
const choice = await
|
|
7813
|
+
const choice = await p36.select({
|
|
7726
7814
|
message: "Select a project",
|
|
7727
7815
|
options: [
|
|
7728
7816
|
...projects.map((pr) => ({
|
|
@@ -7732,39 +7820,39 @@ async function pickExistingProject(projects) {
|
|
|
7732
7820
|
{ value: CREATE_NEW, label: "Create a new project" }
|
|
7733
7821
|
]
|
|
7734
7822
|
});
|
|
7735
|
-
if (
|
|
7736
|
-
|
|
7737
|
-
|
|
7823
|
+
if (p36.isCancel(choice)) {
|
|
7824
|
+
p36.cancel("Operation cancelled.");
|
|
7825
|
+
process27.exit(0);
|
|
7738
7826
|
}
|
|
7739
7827
|
return choice;
|
|
7740
7828
|
}
|
|
7741
7829
|
async function pickTeam(teams3) {
|
|
7742
7830
|
if (teams3.length === 1) return teams3[0];
|
|
7743
|
-
const choice = await
|
|
7831
|
+
const choice = await p36.select({
|
|
7744
7832
|
message: "Select a team",
|
|
7745
7833
|
options: teams3.map((team) => ({
|
|
7746
7834
|
value: team.id,
|
|
7747
7835
|
label: team.is_personal ? `${team.name} (personal)` : team.name
|
|
7748
7836
|
}))
|
|
7749
7837
|
});
|
|
7750
|
-
if (
|
|
7751
|
-
|
|
7752
|
-
|
|
7838
|
+
if (p36.isCancel(choice)) {
|
|
7839
|
+
p36.cancel("Operation cancelled.");
|
|
7840
|
+
process27.exit(0);
|
|
7753
7841
|
}
|
|
7754
7842
|
return teams3.find((team) => team.id === choice);
|
|
7755
7843
|
}
|
|
7756
7844
|
async function promptProjectName(workspaceRootDir) {
|
|
7757
7845
|
const defaultValue = defaultProjectName2(workspaceRootDir);
|
|
7758
|
-
const value = await
|
|
7846
|
+
const value = await p36.text({
|
|
7759
7847
|
message: "Project name",
|
|
7760
7848
|
defaultValue,
|
|
7761
7849
|
initialValue: defaultValue,
|
|
7762
7850
|
placeholder: defaultValue,
|
|
7763
7851
|
validate: (v9) => !v9?.trim() ? "Required" : void 0
|
|
7764
7852
|
});
|
|
7765
|
-
if (
|
|
7766
|
-
|
|
7767
|
-
|
|
7853
|
+
if (p36.isCancel(value)) {
|
|
7854
|
+
p36.cancel("Operation cancelled.");
|
|
7855
|
+
process27.exit(0);
|
|
7768
7856
|
}
|
|
7769
7857
|
return value.trim();
|
|
7770
7858
|
}
|
|
@@ -7779,14 +7867,14 @@ function defaultProjectName2(workspaceRootDir) {
|
|
|
7779
7867
|
}
|
|
7780
7868
|
|
|
7781
7869
|
// src/commands/env.ts
|
|
7782
|
-
import { Command as
|
|
7870
|
+
import { Command as Command78 } from "commander";
|
|
7783
7871
|
|
|
7784
7872
|
// src/commands/env/list.ts
|
|
7785
|
-
import { Command as
|
|
7786
|
-
import * as
|
|
7787
|
-
import
|
|
7873
|
+
import { Command as Command74 } from "commander";
|
|
7874
|
+
import * as p37 from "@clack/prompts";
|
|
7875
|
+
import pc17 from "picocolors";
|
|
7788
7876
|
var envList = addTargetOptions(
|
|
7789
|
-
new
|
|
7877
|
+
new Command74("list").description("list environment variable names").configureHelp(helpConfig),
|
|
7790
7878
|
"local"
|
|
7791
7879
|
).action(
|
|
7792
7880
|
(raw) => runCommand(
|
|
@@ -7808,23 +7896,23 @@ var envList = addTargetOptions(
|
|
|
7808
7896
|
);
|
|
7809
7897
|
function report(keys, where) {
|
|
7810
7898
|
if (keys.length === 0) {
|
|
7811
|
-
|
|
7899
|
+
p37.log.info(`No environment variables configured ${pc17.dim(`(${where})`)}.`);
|
|
7812
7900
|
return;
|
|
7813
7901
|
}
|
|
7814
|
-
|
|
7815
|
-
`Environment ${
|
|
7902
|
+
p37.log.info(
|
|
7903
|
+
`Environment ${pc17.dim(`(${where})`)}
|
|
7816
7904
|
|
|
7817
7905
|
` + keys.sort().map((key) => ` ${key}`).join("\n")
|
|
7818
7906
|
);
|
|
7819
7907
|
}
|
|
7820
7908
|
|
|
7821
7909
|
// src/commands/env/set.ts
|
|
7822
|
-
import
|
|
7823
|
-
import { Command as
|
|
7824
|
-
import * as
|
|
7825
|
-
import
|
|
7910
|
+
import process28 from "node:process";
|
|
7911
|
+
import { Command as Command75 } from "commander";
|
|
7912
|
+
import * as p38 from "@clack/prompts";
|
|
7913
|
+
import pc18 from "picocolors";
|
|
7826
7914
|
var envSet = addTargetOptions(
|
|
7827
|
-
new
|
|
7915
|
+
new Command75("set").description("set an environment variable").argument("<key>", "variable name").argument("[value]", "value \u2014 prompted for, without echo, when omitted").configureHelp(helpConfig),
|
|
7828
7916
|
"local"
|
|
7829
7917
|
).action(
|
|
7830
7918
|
(key, value, raw) => runCommand(
|
|
@@ -7834,14 +7922,14 @@ var envSet = addTargetOptions(
|
|
|
7834
7922
|
local: async (ctx) => {
|
|
7835
7923
|
const resolved = await resolveValue(key, value);
|
|
7836
7924
|
setLocalEnv(ctx.envFile, key, resolved);
|
|
7837
|
-
|
|
7925
|
+
p38.log.success(`${key} updated ${pc18.dim("(local)")}`);
|
|
7838
7926
|
await applyLocalEnvChange(ctx, [key]);
|
|
7839
7927
|
},
|
|
7840
7928
|
remote: async (ctx) => {
|
|
7841
7929
|
const resolved = await resolveValue(key, value);
|
|
7842
7930
|
const env2 = await readRemoteEnv(ctx.session, ctx.instance);
|
|
7843
7931
|
await writeRemoteEnv(ctx.session, ctx.instance, { ...env2, [key]: resolved });
|
|
7844
|
-
|
|
7932
|
+
p38.log.success(`${key} updated ${pc18.dim(`(${ctx.targetName})`)}`);
|
|
7845
7933
|
await applyEnvRestart(ctx, [key]);
|
|
7846
7934
|
}
|
|
7847
7935
|
},
|
|
@@ -7855,23 +7943,23 @@ async function resolveValue(key, value) {
|
|
|
7855
7943
|
return value ?? await promptValue(key);
|
|
7856
7944
|
}
|
|
7857
7945
|
async function promptValue(key) {
|
|
7858
|
-
const value = await
|
|
7859
|
-
message: `Value for ${
|
|
7946
|
+
const value = await p38.password({
|
|
7947
|
+
message: `Value for ${pc18.cyan(key)}`,
|
|
7860
7948
|
validate: (input) => !input?.length ? "Required" : void 0
|
|
7861
7949
|
});
|
|
7862
|
-
if (
|
|
7863
|
-
|
|
7864
|
-
|
|
7950
|
+
if (p38.isCancel(value)) {
|
|
7951
|
+
p38.cancel("Operation cancelled.");
|
|
7952
|
+
process28.exit(0);
|
|
7865
7953
|
}
|
|
7866
7954
|
return value;
|
|
7867
7955
|
}
|
|
7868
7956
|
|
|
7869
7957
|
// src/commands/env/unset.ts
|
|
7870
|
-
import { Command as
|
|
7871
|
-
import * as
|
|
7872
|
-
import
|
|
7958
|
+
import { Command as Command76 } from "commander";
|
|
7959
|
+
import * as p39 from "@clack/prompts";
|
|
7960
|
+
import pc19 from "picocolors";
|
|
7873
7961
|
var envUnset = addTargetOptions(
|
|
7874
|
-
new
|
|
7962
|
+
new Command76("unset").description("remove an environment variable").argument("<key>", "variable name").configureHelp(helpConfig),
|
|
7875
7963
|
"local"
|
|
7876
7964
|
).action(
|
|
7877
7965
|
(key, raw) => runCommand(
|
|
@@ -7880,22 +7968,22 @@ var envUnset = addTargetOptions(
|
|
|
7880
7968
|
{
|
|
7881
7969
|
local: async (ctx) => {
|
|
7882
7970
|
if (!(key in readLocalEnv(ctx.envFile))) {
|
|
7883
|
-
|
|
7971
|
+
p39.log.info(`${key} is not set \u2014 nothing to remove.`);
|
|
7884
7972
|
return;
|
|
7885
7973
|
}
|
|
7886
7974
|
unsetLocalEnv(ctx.envFile, key);
|
|
7887
|
-
|
|
7975
|
+
p39.log.success(`${key} removed ${pc19.dim("(local)")}`);
|
|
7888
7976
|
await applyLocalEnvChange(ctx, [key]);
|
|
7889
7977
|
},
|
|
7890
7978
|
remote: async (ctx) => {
|
|
7891
7979
|
const env2 = await readRemoteEnv(ctx.session, ctx.instance);
|
|
7892
7980
|
if (!(key in env2)) {
|
|
7893
|
-
|
|
7981
|
+
p39.log.info(`${key} is not set \u2014 nothing to remove.`);
|
|
7894
7982
|
return;
|
|
7895
7983
|
}
|
|
7896
7984
|
delete env2[key];
|
|
7897
7985
|
await writeRemoteEnv(ctx.session, ctx.instance, env2);
|
|
7898
|
-
|
|
7986
|
+
p39.log.success(`${key} removed ${pc19.dim(`(${ctx.targetName})`)}`);
|
|
7899
7987
|
await applyEnvRestart(ctx, [key]);
|
|
7900
7988
|
}
|
|
7901
7989
|
},
|
|
@@ -7908,12 +7996,12 @@ var envUnset = addTargetOptions(
|
|
|
7908
7996
|
// src/commands/env/import.ts
|
|
7909
7997
|
import fs37 from "node:fs";
|
|
7910
7998
|
import path42 from "node:path";
|
|
7911
|
-
import
|
|
7912
|
-
import { Command as
|
|
7913
|
-
import * as
|
|
7914
|
-
import
|
|
7999
|
+
import process29 from "node:process";
|
|
8000
|
+
import { Command as Command77 } from "commander";
|
|
8001
|
+
import * as p40 from "@clack/prompts";
|
|
8002
|
+
import pc20 from "picocolors";
|
|
7915
8003
|
var envImport = addTargetOptions(
|
|
7916
|
-
new
|
|
8004
|
+
new Command77("import").description("merge a dotenv file into the environment").argument("<file>", "dotenv file to read").configureHelp(helpConfig),
|
|
7917
8005
|
"local"
|
|
7918
8006
|
).action(
|
|
7919
8007
|
(file, raw) => runCommand(
|
|
@@ -7928,22 +8016,22 @@ var envImport = addTargetOptions(
|
|
|
7928
8016
|
const incoming = read(source, file);
|
|
7929
8017
|
const keys = Object.keys(incoming);
|
|
7930
8018
|
if (keys.length === 0) return;
|
|
7931
|
-
|
|
8019
|
+
p40.log.step(`Importing ${keys.length} variable(s) from ${pc20.cyan(file)}`);
|
|
7932
8020
|
editLocalEnv(
|
|
7933
8021
|
ctx.envFile,
|
|
7934
8022
|
(content) => keys.reduce((acc, key) => upsertEnvVar(acc, key, incoming[key]), content)
|
|
7935
8023
|
);
|
|
7936
|
-
|
|
8024
|
+
p40.log.success(`${keys.length} variable(s) updated ${pc20.dim("(local)")}`);
|
|
7937
8025
|
await applyLocalEnvChange(ctx, keys);
|
|
7938
8026
|
},
|
|
7939
8027
|
remote: async (ctx) => {
|
|
7940
8028
|
const incoming = read(resolve(file), file);
|
|
7941
8029
|
const keys = Object.keys(incoming);
|
|
7942
8030
|
if (keys.length === 0) return;
|
|
7943
|
-
|
|
8031
|
+
p40.log.step(`Importing ${keys.length} variable(s) from ${pc20.cyan(file)}`);
|
|
7944
8032
|
const existing = await readRemoteEnv(ctx.session, ctx.instance);
|
|
7945
8033
|
await writeRemoteEnv(ctx.session, ctx.instance, { ...existing, ...incoming });
|
|
7946
|
-
|
|
8034
|
+
p40.log.success(`${keys.length} variable(s) updated ${pc20.dim(`(${ctx.targetName})`)}`);
|
|
7947
8035
|
await applyEnvRestart(ctx, keys);
|
|
7948
8036
|
}
|
|
7949
8037
|
},
|
|
@@ -7953,24 +8041,24 @@ var envImport = addTargetOptions(
|
|
|
7953
8041
|
)
|
|
7954
8042
|
);
|
|
7955
8043
|
function resolve(file) {
|
|
7956
|
-
return path42.resolve(
|
|
8044
|
+
return path42.resolve(process29.cwd(), file);
|
|
7957
8045
|
}
|
|
7958
8046
|
function read(resolved, shown) {
|
|
7959
8047
|
if (!fs37.existsSync(resolved)) throw new Error(`${shown} does not exist.`);
|
|
7960
8048
|
const incoming = readLocalEnvFile(resolved);
|
|
7961
|
-
if (Object.keys(incoming).length === 0)
|
|
8049
|
+
if (Object.keys(incoming).length === 0) p40.log.info(`${shown} has no variables to import.`);
|
|
7962
8050
|
return incoming;
|
|
7963
8051
|
}
|
|
7964
8052
|
|
|
7965
8053
|
// src/commands/env.ts
|
|
7966
|
-
var env = new
|
|
8054
|
+
var env = new Command78("env").description("manage environment variables, locally or on a target").configureHelp(helpConfig).addCommand(envList).addCommand(envSet).addCommand(envUnset).addCommand(envImport);
|
|
7967
8055
|
|
|
7968
8056
|
// src/commands/status.ts
|
|
7969
|
-
import { Command as
|
|
7970
|
-
import * as
|
|
7971
|
-
import
|
|
8057
|
+
import { Command as Command79 } from "commander";
|
|
8058
|
+
import * as p41 from "@clack/prompts";
|
|
8059
|
+
import pc21 from "picocolors";
|
|
7972
8060
|
var status = addTargetOptions(
|
|
7973
|
-
new
|
|
8061
|
+
new Command79("status").description("show what is deployed").configureHelp(helpConfig),
|
|
7974
8062
|
"production"
|
|
7975
8063
|
).option("--all", "show every app on the server, not just this project").option("--json", "print raw JSON").action(
|
|
7976
8064
|
(raw) => runCommand(async () => {
|
|
@@ -8001,15 +8089,15 @@ function report2(states, json) {
|
|
|
8001
8089
|
return;
|
|
8002
8090
|
}
|
|
8003
8091
|
if (states.length === 0) {
|
|
8004
|
-
|
|
8092
|
+
p41.log.info("Nothing is deployed here yet.");
|
|
8005
8093
|
return;
|
|
8006
8094
|
}
|
|
8007
8095
|
for (const state of states) {
|
|
8008
|
-
|
|
8096
|
+
p41.log.info(describe(state));
|
|
8009
8097
|
}
|
|
8010
8098
|
}
|
|
8011
8099
|
function describe(state) {
|
|
8012
|
-
const health = (value) => value === "active" ?
|
|
8100
|
+
const health = (value) => value === "active" ? pc21.green(value) : pc21.red(value || "inactive");
|
|
8013
8101
|
const rows = [
|
|
8014
8102
|
["Instance", state.instance],
|
|
8015
8103
|
["Environment", state.env],
|
|
@@ -8024,15 +8112,15 @@ function describe(state) {
|
|
|
8024
8112
|
...state.gitSha ? [["Commit", state.gitSha.slice(0, 12)]] : []
|
|
8025
8113
|
];
|
|
8026
8114
|
const width = Math.max(...rows.map(([label3]) => label3.length));
|
|
8027
|
-
return
|
|
8115
|
+
return pc21.cyan(state.name) + "\n\n" + rows.map(([label3, value]) => ` ${label3.padEnd(width)} ${value}`).join("\n");
|
|
8028
8116
|
}
|
|
8029
8117
|
|
|
8030
8118
|
// src/commands/rollback.ts
|
|
8031
|
-
import { Command as
|
|
8032
|
-
import * as
|
|
8033
|
-
import
|
|
8119
|
+
import { Command as Command80 } from "commander";
|
|
8120
|
+
import * as p42 from "@clack/prompts";
|
|
8121
|
+
import pc22 from "picocolors";
|
|
8034
8122
|
var rollback = addTargetOptions(
|
|
8035
|
-
new
|
|
8123
|
+
new Command80("rollback").description("put the previous release back").configureHelp(helpConfig),
|
|
8036
8124
|
"production"
|
|
8037
8125
|
).option("--to <release>", "roll back to a specific release instead of the previous one").action(
|
|
8038
8126
|
(raw) => runCommand(async () => {
|
|
@@ -8041,8 +8129,8 @@ var rollback = addTargetOptions(
|
|
|
8041
8129
|
raw,
|
|
8042
8130
|
{
|
|
8043
8131
|
remote: async (ctx) => {
|
|
8044
|
-
|
|
8045
|
-
`Rolling back ${
|
|
8132
|
+
p42.log.step(
|
|
8133
|
+
`Rolling back ${pc22.cyan(ctx.appName)} ${pc22.dim(`(${ctx.targetName})`)} on ${ctx.server}`
|
|
8046
8134
|
);
|
|
8047
8135
|
const result = await runServerScript(
|
|
8048
8136
|
ctx.session,
|
|
@@ -8052,8 +8140,8 @@ var rollback = addTargetOptions(
|
|
|
8052
8140
|
stream: true
|
|
8053
8141
|
}
|
|
8054
8142
|
);
|
|
8055
|
-
|
|
8056
|
-
`Rolled back to ${
|
|
8143
|
+
p42.log.success(
|
|
8144
|
+
`Rolled back to ${pc22.cyan(result?.release ?? "the previous release")}` + (result?.from ? ` ${pc22.dim(`(was ${result.from})`)}` : "")
|
|
8057
8145
|
);
|
|
8058
8146
|
}
|
|
8059
8147
|
},
|
|
@@ -8066,9 +8154,9 @@ var rollback = addTargetOptions(
|
|
|
8066
8154
|
);
|
|
8067
8155
|
|
|
8068
8156
|
// src/commands/logs.ts
|
|
8069
|
-
import { Command as
|
|
8157
|
+
import { Command as Command81 } from "commander";
|
|
8070
8158
|
var logs = addTargetOptions(
|
|
8071
|
-
new
|
|
8159
|
+
new Command81("logs").description("tail the logs of a deployed app").configureHelp(helpConfig),
|
|
8072
8160
|
"production"
|
|
8073
8161
|
).option("-f, --follow", "keep streaming new output").option("-n, --lines <count>", "how many lines of history to show", "100").option("--pocketbase", "show the PocketBase service instead of the app").action(
|
|
8074
8162
|
(raw) => runCommand(async () => {
|
|
@@ -8102,16 +8190,16 @@ var logs = addTargetOptions(
|
|
|
8102
8190
|
);
|
|
8103
8191
|
|
|
8104
8192
|
// src/commands/admin.ts
|
|
8105
|
-
import { Command as
|
|
8193
|
+
import { Command as Command83 } from "commander";
|
|
8106
8194
|
|
|
8107
8195
|
// src/commands/admin/create.ts
|
|
8108
|
-
import
|
|
8109
|
-
import { Command as
|
|
8110
|
-
import * as
|
|
8111
|
-
import
|
|
8196
|
+
import process30 from "node:process";
|
|
8197
|
+
import { Command as Command82 } from "commander";
|
|
8198
|
+
import * as p43 from "@clack/prompts";
|
|
8199
|
+
import pc23 from "picocolors";
|
|
8112
8200
|
var MIN_PASSWORD = 10;
|
|
8113
8201
|
var adminCreate = addTargetOptions(
|
|
8114
|
-
new
|
|
8202
|
+
new Command82("create").description("create a login for the admin panel").argument("[email]", "email to sign in with \u2014 prompted for when omitted").configureHelp(helpConfig),
|
|
8115
8203
|
"local"
|
|
8116
8204
|
).action(
|
|
8117
8205
|
(email3, raw) => runCommand(
|
|
@@ -8139,8 +8227,8 @@ var adminCreate = addTargetOptions(
|
|
|
8139
8227
|
const metadata = getPocketbaseMetadata(ctx.workspaceRootDir);
|
|
8140
8228
|
if (metadata) signIn = `http://${metadata.viteHost}:${metadata.vitePort}`;
|
|
8141
8229
|
}
|
|
8142
|
-
|
|
8143
|
-
signIn ? `Sign in at ${
|
|
8230
|
+
p43.log.info(
|
|
8231
|
+
signIn ? `Sign in at ${pc23.cyan(`${signIn}/admin`)}` : `Sign in at ${pc23.cyan("/admin")} once ${pc23.cyan("vela dev")} is running.`
|
|
8144
8232
|
);
|
|
8145
8233
|
},
|
|
8146
8234
|
remote: async (ctx) => {
|
|
@@ -8153,8 +8241,8 @@ var adminCreate = addTargetOptions(
|
|
|
8153
8241
|
(pb) => upsertSuperuser(pb, address, password11)
|
|
8154
8242
|
);
|
|
8155
8243
|
const base2 = state?.domain ? `https://${state.domain.split(",")[0].trim()}` : "";
|
|
8156
|
-
|
|
8157
|
-
base2 ? `Sign in at ${
|
|
8244
|
+
p43.log.info(
|
|
8245
|
+
base2 ? `Sign in at ${pc23.cyan(`${base2}/admin`)}` : `Sign in at ${pc23.cyan("/admin")} once a domain is configured for this target.`
|
|
8158
8246
|
);
|
|
8159
8247
|
}
|
|
8160
8248
|
},
|
|
@@ -8166,20 +8254,20 @@ var adminCreate = addTargetOptions(
|
|
|
8166
8254
|
async function upsertSuperuser(pb, email3, password11) {
|
|
8167
8255
|
const existing = await findSuperuser(pb, email3);
|
|
8168
8256
|
if (existing) {
|
|
8169
|
-
const confirmed = await
|
|
8257
|
+
const confirmed = await p43.confirm({
|
|
8170
8258
|
message: `${email3} already has an account, update its password?`,
|
|
8171
8259
|
initialValue: false
|
|
8172
8260
|
});
|
|
8173
|
-
if (
|
|
8174
|
-
|
|
8175
|
-
|
|
8261
|
+
if (p43.isCancel(confirmed) || !confirmed) {
|
|
8262
|
+
p43.cancel("Operation cancelled.");
|
|
8263
|
+
process30.exit(0);
|
|
8176
8264
|
}
|
|
8177
8265
|
await pb.collection("_superusers").update(existing, { password: password11, passwordConfirm: password11 });
|
|
8178
|
-
|
|
8266
|
+
p43.log.success(`Password updated for ${pc23.cyan(email3)}, you can sign in now`);
|
|
8179
8267
|
return;
|
|
8180
8268
|
}
|
|
8181
8269
|
await pb.collection("_superusers").create({ email: email3, password: password11, passwordConfirm: password11 });
|
|
8182
|
-
|
|
8270
|
+
p43.log.success(`${pc23.cyan(email3)} can now sign in`);
|
|
8183
8271
|
}
|
|
8184
8272
|
async function findSuperuser(pb, email3) {
|
|
8185
8273
|
try {
|
|
@@ -8190,48 +8278,48 @@ async function findSuperuser(pb, email3) {
|
|
|
8190
8278
|
}
|
|
8191
8279
|
}
|
|
8192
8280
|
async function promptEmail() {
|
|
8193
|
-
const value = await
|
|
8281
|
+
const value = await p43.text({
|
|
8194
8282
|
message: "Email to sign in with",
|
|
8195
8283
|
validate: (input) => input?.includes("@") ? void 0 : "An email address is required"
|
|
8196
8284
|
});
|
|
8197
|
-
if (
|
|
8198
|
-
|
|
8199
|
-
|
|
8285
|
+
if (p43.isCancel(value)) {
|
|
8286
|
+
p43.cancel("Operation cancelled.");
|
|
8287
|
+
process30.exit(0);
|
|
8200
8288
|
}
|
|
8201
8289
|
return value.trim();
|
|
8202
8290
|
}
|
|
8203
8291
|
async function promptPassword2() {
|
|
8204
|
-
const value = await
|
|
8292
|
+
const value = await p43.password({
|
|
8205
8293
|
message: "Password",
|
|
8206
8294
|
validate: (input) => (input?.length ?? 0) >= MIN_PASSWORD ? void 0 : `At least ${MIN_PASSWORD} characters is required`
|
|
8207
8295
|
});
|
|
8208
|
-
if (
|
|
8209
|
-
|
|
8210
|
-
|
|
8296
|
+
if (p43.isCancel(value)) {
|
|
8297
|
+
p43.cancel("Operation cancelled.");
|
|
8298
|
+
process30.exit(0);
|
|
8211
8299
|
}
|
|
8212
|
-
const again = await
|
|
8300
|
+
const again = await p43.password({
|
|
8213
8301
|
message: "Password again",
|
|
8214
8302
|
validate: (input) => input === value ? void 0 : "The two do not match"
|
|
8215
8303
|
});
|
|
8216
|
-
if (
|
|
8217
|
-
|
|
8218
|
-
|
|
8304
|
+
if (p43.isCancel(again)) {
|
|
8305
|
+
p43.cancel("Operation cancelled.");
|
|
8306
|
+
process30.exit(0);
|
|
8219
8307
|
}
|
|
8220
8308
|
return value;
|
|
8221
8309
|
}
|
|
8222
8310
|
|
|
8223
8311
|
// src/commands/admin.ts
|
|
8224
|
-
var admin = new
|
|
8312
|
+
var admin = new Command83("admin").description("manage admin panel logins").configureHelp(helpConfig).addCommand(adminCreate);
|
|
8225
8313
|
|
|
8226
8314
|
// src/commands/backup.ts
|
|
8227
|
-
import { Command as
|
|
8315
|
+
import { Command as Command89 } from "commander";
|
|
8228
8316
|
|
|
8229
8317
|
// src/commands/backup/create.ts
|
|
8230
8318
|
import fs38 from "node:fs";
|
|
8231
8319
|
import path43 from "node:path";
|
|
8232
|
-
import { Command as
|
|
8233
|
-
import * as
|
|
8234
|
-
import
|
|
8320
|
+
import { Command as Command84 } from "commander";
|
|
8321
|
+
import * as p44 from "@clack/prompts";
|
|
8322
|
+
import pc24 from "picocolors";
|
|
8235
8323
|
|
|
8236
8324
|
// src/lib/backups.ts
|
|
8237
8325
|
var BACKUP_KEY = /^[a-z0-9_-]+\.zip$/;
|
|
@@ -8318,7 +8406,7 @@ async function writeSchedule(pb, cron, maxKeep) {
|
|
|
8318
8406
|
// src/commands/backup/create.ts
|
|
8319
8407
|
var DEFAULT_BACKUP_DIR = "backups";
|
|
8320
8408
|
var backupCreate = addTargetOptions(
|
|
8321
|
-
new
|
|
8409
|
+
new Command84("create").description("take a backup of the database and uploads").argument("[name]", "name for the archive \u2014 generated when omitted").option("-o, --output <dir>", "where to save the archive", DEFAULT_BACKUP_DIR).option("--no-download", "leave the archive on the server").configureHelp(helpConfig),
|
|
8322
8410
|
"production"
|
|
8323
8411
|
).action(
|
|
8324
8412
|
(name, raw) => runCommand(() => {
|
|
@@ -8327,22 +8415,22 @@ var backupCreate = addTargetOptions(
|
|
|
8327
8415
|
const key = name ?? backupName(ctx.instance);
|
|
8328
8416
|
if (!isBackupKey(key)) {
|
|
8329
8417
|
throw new Error(
|
|
8330
|
-
`${
|
|
8418
|
+
`${pc24.cyan(key)} is not a name PocketBase will accept.
|
|
8331
8419
|
|
|
8332
|
-
Backup names are lowercase letters, digits, ${
|
|
8420
|
+
Backup names are lowercase letters, digits, ${pc24.cyan("-")} and ${pc24.cyan("_")}, ending in ${pc24.cyan(".zip")}.`
|
|
8333
8421
|
);
|
|
8334
8422
|
}
|
|
8335
8423
|
const storage = await readStorageSettings(ctx.pb);
|
|
8336
8424
|
if (storage.s3Enabled) {
|
|
8337
|
-
|
|
8425
|
+
p44.log.warn(
|
|
8338
8426
|
`Uploads are stored in S3, so this archive holds the database only.
|
|
8339
8427
|
|
|
8340
|
-
PocketBase leaves ${
|
|
8428
|
+
PocketBase leaves ${pc24.cyan("storage/")} out of a backup whenever S3 is on.
|
|
8341
8429
|
Your bucket's own versioning is what protects the uploaded files.`
|
|
8342
8430
|
);
|
|
8343
8431
|
}
|
|
8344
8432
|
if (ctx.session) await checkpointAppDatabases(ctx.session, ctx.instance);
|
|
8345
|
-
const spinner5 =
|
|
8433
|
+
const spinner5 = p44.spinner();
|
|
8346
8434
|
spinner5.start(`Backing up ${ctx.targetName}`);
|
|
8347
8435
|
try {
|
|
8348
8436
|
await createBackup(ctx.pb, key);
|
|
@@ -8389,7 +8477,7 @@ async function download(ctx, key, outputDir) {
|
|
|
8389
8477
|
fs38.copyFileSync(path43.join(ctx.workspaceRootDir, "data", "backups", key), destination);
|
|
8390
8478
|
return path43.relative(ctx.workspaceRootDir, destination);
|
|
8391
8479
|
}
|
|
8392
|
-
const spinner5 =
|
|
8480
|
+
const spinner5 = p44.spinner();
|
|
8393
8481
|
spinner5.start(`Downloading ${key}`);
|
|
8394
8482
|
try {
|
|
8395
8483
|
await ctx.session.download(remotePaths.backup(ctx.instance, key), destination);
|
|
@@ -8402,28 +8490,28 @@ async function download(ctx, key, outputDir) {
|
|
|
8402
8490
|
}
|
|
8403
8491
|
|
|
8404
8492
|
// src/commands/backup/list.ts
|
|
8405
|
-
import { Command as
|
|
8406
|
-
import * as
|
|
8407
|
-
import
|
|
8493
|
+
import { Command as Command85 } from "commander";
|
|
8494
|
+
import * as p45 from "@clack/prompts";
|
|
8495
|
+
import pc25 from "picocolors";
|
|
8408
8496
|
var backupList = addTargetOptions(
|
|
8409
|
-
new
|
|
8497
|
+
new Command85("list").description("list the backups on a target").configureHelp(helpConfig),
|
|
8410
8498
|
"production"
|
|
8411
8499
|
).action(
|
|
8412
8500
|
(raw) => runCommand(
|
|
8413
8501
|
() => withBackupTarget(raw, "backup list", async (ctx) => {
|
|
8414
8502
|
const backups = await listBackups(ctx.pb);
|
|
8415
8503
|
if (backups.length === 0) {
|
|
8416
|
-
|
|
8417
|
-
`${
|
|
8504
|
+
p45.log.info(
|
|
8505
|
+
`${pc25.cyan(ctx.targetName)} has no backups yet.
|
|
8418
8506
|
|
|
8419
|
-
Take one with ${
|
|
8507
|
+
Take one with ${pc25.cyan("vela backup create")}.`
|
|
8420
8508
|
);
|
|
8421
8509
|
return;
|
|
8422
8510
|
}
|
|
8423
8511
|
const width = Math.max(...backups.map((b) => b.key.length));
|
|
8424
|
-
|
|
8512
|
+
p45.log.message(
|
|
8425
8513
|
backups.map(
|
|
8426
|
-
(b) => `${b.key.padEnd(width)} ${
|
|
8514
|
+
(b) => `${b.key.padEnd(width)} ${pc25.dim(formatBytes(b.size).padStart(8))} ${pc25.dim(b.modified)}`
|
|
8427
8515
|
).join("\n")
|
|
8428
8516
|
);
|
|
8429
8517
|
}),
|
|
@@ -8434,11 +8522,11 @@ Take one with ${pc24.cyan("vela backup create")}.`
|
|
|
8434
8522
|
// src/commands/backup/download.ts
|
|
8435
8523
|
import fs39 from "node:fs";
|
|
8436
8524
|
import path44 from "node:path";
|
|
8437
|
-
import { Command as
|
|
8438
|
-
import * as
|
|
8439
|
-
import
|
|
8525
|
+
import { Command as Command86 } from "commander";
|
|
8526
|
+
import * as p46 from "@clack/prompts";
|
|
8527
|
+
import pc26 from "picocolors";
|
|
8440
8528
|
var backupDownload = addTargetOptions(
|
|
8441
|
-
new
|
|
8529
|
+
new Command86("download").description("save a backup off the server").argument("<key>", "archive to download, as shown by `vela backup list`").option("-o, --output <dir>", "where to save the archive", DEFAULT_BACKUP_DIR).configureHelp(helpConfig),
|
|
8442
8530
|
"production"
|
|
8443
8531
|
).action(
|
|
8444
8532
|
(key, raw) => runCommand(() => {
|
|
@@ -8447,9 +8535,9 @@ var backupDownload = addTargetOptions(
|
|
|
8447
8535
|
const found = (await listBackups(ctx.pb)).find((b) => b.key === key);
|
|
8448
8536
|
if (!found) {
|
|
8449
8537
|
throw new Error(
|
|
8450
|
-
`${ctx.targetName} has no backup called ${
|
|
8538
|
+
`${ctx.targetName} has no backup called ${pc26.cyan(key)}.
|
|
8451
8539
|
|
|
8452
|
-
Run ${
|
|
8540
|
+
Run ${pc26.cyan("vela backup list")} to see what it does have.`
|
|
8453
8541
|
);
|
|
8454
8542
|
}
|
|
8455
8543
|
const storage = await readStorageSettings(ctx.pb);
|
|
@@ -8466,7 +8554,7 @@ Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
|
|
|
8466
8554
|
if (!ctx.session) {
|
|
8467
8555
|
fs39.copyFileSync(path44.join(ctx.workspaceRootDir, "data", "backups", key), destination);
|
|
8468
8556
|
} else {
|
|
8469
|
-
const spinner5 =
|
|
8557
|
+
const spinner5 = p46.spinner();
|
|
8470
8558
|
spinner5.start(`Downloading ${key} (${formatBytes(found.size)})`);
|
|
8471
8559
|
try {
|
|
8472
8560
|
await ctx.session.download(remotePaths.backup(ctx.instance, key), destination);
|
|
@@ -8485,12 +8573,12 @@ Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
|
|
|
8485
8573
|
);
|
|
8486
8574
|
|
|
8487
8575
|
// src/commands/backup/delete.ts
|
|
8488
|
-
import
|
|
8489
|
-
import { Command as
|
|
8490
|
-
import * as
|
|
8491
|
-
import
|
|
8576
|
+
import process31 from "node:process";
|
|
8577
|
+
import { Command as Command87 } from "commander";
|
|
8578
|
+
import * as p47 from "@clack/prompts";
|
|
8579
|
+
import pc27 from "picocolors";
|
|
8492
8580
|
var backupDelete = addTargetOptions(
|
|
8493
|
-
new
|
|
8581
|
+
new Command87("delete").description("remove a backup from a target").argument("<key>", "archive to delete, as shown by `vela backup list`").option("-y, --yes", "skip the confirmation").configureHelp(helpConfig),
|
|
8494
8582
|
"production"
|
|
8495
8583
|
).action(
|
|
8496
8584
|
(key, raw) => runCommand(() => {
|
|
@@ -8499,19 +8587,19 @@ var backupDelete = addTargetOptions(
|
|
|
8499
8587
|
const found = (await listBackups(ctx.pb)).find((b) => b.key === key);
|
|
8500
8588
|
if (!found) {
|
|
8501
8589
|
throw new Error(
|
|
8502
|
-
`${ctx.targetName} has no backup called ${
|
|
8590
|
+
`${ctx.targetName} has no backup called ${pc27.cyan(key)}.
|
|
8503
8591
|
|
|
8504
|
-
Run ${
|
|
8592
|
+
Run ${pc27.cyan("vela backup list")} to see what it does have.`
|
|
8505
8593
|
);
|
|
8506
8594
|
}
|
|
8507
8595
|
if (!options.yes) {
|
|
8508
|
-
const confirmed = await
|
|
8596
|
+
const confirmed = await p47.confirm({
|
|
8509
8597
|
message: `Delete ${key} (${formatBytes(found.size)}) from ${ctx.targetName}?`,
|
|
8510
8598
|
initialValue: false
|
|
8511
8599
|
});
|
|
8512
|
-
if (
|
|
8513
|
-
|
|
8514
|
-
|
|
8600
|
+
if (p47.isCancel(confirmed) || !confirmed) {
|
|
8601
|
+
p47.cancel("Operation cancelled.");
|
|
8602
|
+
process31.exit(0);
|
|
8515
8603
|
}
|
|
8516
8604
|
}
|
|
8517
8605
|
await ctx.pb.backups.delete(key);
|
|
@@ -8521,12 +8609,12 @@ Run ${pc26.cyan("vela backup list")} to see what it does have.`
|
|
|
8521
8609
|
);
|
|
8522
8610
|
|
|
8523
8611
|
// src/commands/backup/schedule.ts
|
|
8524
|
-
import { Command as
|
|
8525
|
-
import * as
|
|
8526
|
-
import
|
|
8612
|
+
import { Command as Command88 } from "commander";
|
|
8613
|
+
import * as p48 from "@clack/prompts";
|
|
8614
|
+
import pc28 from "picocolors";
|
|
8527
8615
|
var DEFAULT_KEEP = 7;
|
|
8528
8616
|
var backupSchedule = addTargetOptions(
|
|
8529
|
-
new
|
|
8617
|
+
new Command88("schedule").description("back up automatically on a schedule").argument("[cron]", "when to run, as a cron expression \u2014 shows the current one when omitted").option("--keep <n>", "how many scheduled archives to keep", String(DEFAULT_KEEP)).option("--off", "stop backing up automatically").configureHelp(helpConfig),
|
|
8530
8618
|
"production"
|
|
8531
8619
|
).action(
|
|
8532
8620
|
(cron, raw) => runCommand(() => {
|
|
@@ -8539,17 +8627,17 @@ var backupSchedule = addTargetOptions(
|
|
|
8539
8627
|
}
|
|
8540
8628
|
if (!cron) {
|
|
8541
8629
|
const current = await readSchedule(ctx.pb);
|
|
8542
|
-
|
|
8543
|
-
current.cron ? `${ctx.targetName} backs up on ${
|
|
8630
|
+
p48.log.info(
|
|
8631
|
+
current.cron ? `${ctx.targetName} backs up on ${pc28.cyan(current.cron)}, keeping ${current.maxKeep}.` : `${ctx.targetName} has no backup schedule.
|
|
8544
8632
|
|
|
8545
|
-
Set one with ${
|
|
8633
|
+
Set one with ${pc28.cyan('vela backup schedule "0 3 * * *"')}.`
|
|
8546
8634
|
);
|
|
8547
8635
|
return;
|
|
8548
8636
|
}
|
|
8549
8637
|
const keep = Number.parseInt(options.keep, 10);
|
|
8550
8638
|
if (!Number.isInteger(keep) || keep < 1) {
|
|
8551
8639
|
throw new Error(
|
|
8552
|
-
`${
|
|
8640
|
+
`${pc28.cyan(options.keep)} is not a number of backups to keep \u2014 pass at least 1.`
|
|
8553
8641
|
);
|
|
8554
8642
|
}
|
|
8555
8643
|
await writeSchedule(ctx.pb, cron, keep);
|
|
@@ -8570,17 +8658,17 @@ Set one with ${pc27.cyan('vela backup schedule "0 3 * * *"')}.`
|
|
|
8570
8658
|
);
|
|
8571
8659
|
|
|
8572
8660
|
// src/commands/backup.ts
|
|
8573
|
-
var backup = new
|
|
8661
|
+
var backup = new Command89("backup").description("back up the database and uploads, locally or on a target").configureHelp(helpConfig).addCommand(backupCreate).addCommand(backupList).addCommand(backupDownload).addCommand(backupDelete).addCommand(backupSchedule);
|
|
8574
8662
|
|
|
8575
8663
|
// src/commands/restore.ts
|
|
8576
8664
|
import fs40 from "node:fs";
|
|
8577
8665
|
import path45 from "node:path";
|
|
8578
|
-
import
|
|
8579
|
-
import { Command as
|
|
8580
|
-
import * as
|
|
8581
|
-
import
|
|
8666
|
+
import process32 from "node:process";
|
|
8667
|
+
import { Command as Command90 } from "commander";
|
|
8668
|
+
import * as p49 from "@clack/prompts";
|
|
8669
|
+
import pc29 from "picocolors";
|
|
8582
8670
|
var restore = addTargetOptions(
|
|
8583
|
-
new
|
|
8671
|
+
new Command90("restore").description("replace a deployment\u2019s database and uploads from a backup").argument("[source]", "a backup key on the target, or a path to a local archive").configureHelp(helpConfig),
|
|
8584
8672
|
"production"
|
|
8585
8673
|
).option("-y, --yes", "skip the confirmation prompt").option("--no-migrate", "do not run migrations against the restored database").option("--keep-previous <n>", "how many replaced databases to keep", "1").action(
|
|
8586
8674
|
(source, raw) => runCommand(async () => {
|
|
@@ -8615,19 +8703,19 @@ var restore = addTargetOptions(
|
|
|
8615
8703
|
],
|
|
8616
8704
|
stream: true
|
|
8617
8705
|
});
|
|
8618
|
-
|
|
8619
|
-
`Restored ${
|
|
8706
|
+
p49.log.success(
|
|
8707
|
+
`Restored ${pc29.cyan(`${ctx.appName} (${ctx.targetName})`)} from ${pc29.cyan(
|
|
8620
8708
|
local ? path45.basename(local) : key
|
|
8621
8709
|
)}.`
|
|
8622
8710
|
);
|
|
8623
8711
|
if (result?.storageCarriedOver) {
|
|
8624
|
-
|
|
8712
|
+
p49.log.info(
|
|
8625
8713
|
"The archive held no uploads, so the files already on the server were kept."
|
|
8626
8714
|
);
|
|
8627
8715
|
}
|
|
8628
8716
|
if (result?.previousDataDir) {
|
|
8629
|
-
|
|
8630
|
-
`The database this replaced is at ${
|
|
8717
|
+
p49.log.info(
|
|
8718
|
+
`The database this replaced is at ${pc29.cyan(result.previousDataDir)}.
|
|
8631
8719
|
|
|
8632
8720
|
It is the only way back. Remove it once you are satisfied with the restore.`
|
|
8633
8721
|
);
|
|
@@ -8644,18 +8732,18 @@ It is the only way back. Remove it once you are satisfied with the restore.`
|
|
|
8644
8732
|
async function resolveKey(ctx, source) {
|
|
8645
8733
|
if (source && !isBackupKey(source)) {
|
|
8646
8734
|
throw new Error(
|
|
8647
|
-
`${
|
|
8735
|
+
`${pc29.cyan(source)} is neither a file on this machine nor a backup key.
|
|
8648
8736
|
|
|
8649
|
-
Run ${
|
|
8737
|
+
Run ${pc29.cyan("vela backup list")} to see what ${ctx.targetName} has.`
|
|
8650
8738
|
);
|
|
8651
8739
|
}
|
|
8652
8740
|
const backups = await withRemotePocketbase(ctx.session, ctx.instance, listBackups);
|
|
8653
8741
|
if (source) {
|
|
8654
8742
|
if (!backups.some((b) => b.key === source)) {
|
|
8655
8743
|
throw new Error(
|
|
8656
|
-
`${ctx.targetName} has no backup called ${
|
|
8744
|
+
`${ctx.targetName} has no backup called ${pc29.cyan(source)}.
|
|
8657
8745
|
|
|
8658
|
-
Run ${
|
|
8746
|
+
Run ${pc29.cyan("vela backup list")} to see what it does have.`
|
|
8659
8747
|
);
|
|
8660
8748
|
}
|
|
8661
8749
|
return source;
|
|
@@ -8664,10 +8752,10 @@ Run ${pc28.cyan("vela backup list")} to see what it does have.`
|
|
|
8664
8752
|
throw new Error(
|
|
8665
8753
|
`${ctx.targetName} has no backups to restore from.
|
|
8666
8754
|
|
|
8667
|
-
Take one with ${
|
|
8755
|
+
Take one with ${pc29.cyan("vela backup create")}, or pass the path to an archive on this machine.`
|
|
8668
8756
|
);
|
|
8669
8757
|
}
|
|
8670
|
-
const chosen = await
|
|
8758
|
+
const chosen = await p49.select({
|
|
8671
8759
|
message: `Which backup should ${ctx.targetName} be restored from?`,
|
|
8672
8760
|
options: backups.map((b) => ({
|
|
8673
8761
|
value: b.key,
|
|
@@ -8675,16 +8763,16 @@ Take one with ${pc28.cyan("vela backup create")}, or pass the path to an archive
|
|
|
8675
8763
|
hint: `${formatBytes(b.size)}, ${b.modified}`
|
|
8676
8764
|
}))
|
|
8677
8765
|
});
|
|
8678
|
-
if (
|
|
8679
|
-
|
|
8680
|
-
|
|
8766
|
+
if (p49.isCancel(chosen)) {
|
|
8767
|
+
p49.cancel("Operation cancelled.");
|
|
8768
|
+
process32.exit(0);
|
|
8681
8769
|
}
|
|
8682
8770
|
return chosen;
|
|
8683
8771
|
}
|
|
8684
8772
|
async function stage(ctx, file) {
|
|
8685
8773
|
const dir = remotePaths.restoreStage(ctx.instance);
|
|
8686
8774
|
const remote = `${dir}/${path45.basename(file)}`;
|
|
8687
|
-
const spinner5 =
|
|
8775
|
+
const spinner5 = p49.spinner();
|
|
8688
8776
|
spinner5.start(`Uploading ${path45.basename(file)}`);
|
|
8689
8777
|
try {
|
|
8690
8778
|
await ctx.session.script(`mkdir -p "$1"`, { args: [dir] });
|
|
@@ -8697,32 +8785,32 @@ async function stage(ctx, file) {
|
|
|
8697
8785
|
return remote;
|
|
8698
8786
|
}
|
|
8699
8787
|
async function confirm11(appName, targetName, envTag, from) {
|
|
8700
|
-
const what = `${
|
|
8788
|
+
const what = `${pc29.cyan(`${appName} (${targetName})`)} from ${pc29.cyan(path45.basename(from))}`;
|
|
8701
8789
|
if (isProd(envTag)) {
|
|
8702
|
-
const answer = await
|
|
8790
|
+
const answer = await p49.text({
|
|
8703
8791
|
message: `This replaces the database and uploads of ${what}. Type the app name to confirm`,
|
|
8704
8792
|
validate: (value) => value === appName ? void 0 : `Type ${appName} to confirm`
|
|
8705
8793
|
});
|
|
8706
|
-
if (
|
|
8707
|
-
|
|
8708
|
-
|
|
8794
|
+
if (p49.isCancel(answer)) {
|
|
8795
|
+
p49.cancel("Operation cancelled.");
|
|
8796
|
+
process32.exit(0);
|
|
8709
8797
|
}
|
|
8710
8798
|
return;
|
|
8711
8799
|
}
|
|
8712
|
-
const ok = await
|
|
8800
|
+
const ok = await p49.confirm({
|
|
8713
8801
|
message: `Replace the database and uploads of ${what}?`,
|
|
8714
8802
|
initialValue: false
|
|
8715
8803
|
});
|
|
8716
|
-
if (
|
|
8717
|
-
|
|
8718
|
-
|
|
8804
|
+
if (p49.isCancel(ok) || !ok) {
|
|
8805
|
+
p49.cancel("Operation cancelled.");
|
|
8806
|
+
process32.exit(0);
|
|
8719
8807
|
}
|
|
8720
8808
|
}
|
|
8721
8809
|
|
|
8722
8810
|
// src/commands/targets.ts
|
|
8723
|
-
import { Command as
|
|
8724
|
-
import * as
|
|
8725
|
-
import
|
|
8811
|
+
import { Command as Command91 } from "commander";
|
|
8812
|
+
import * as p50 from "@clack/prompts";
|
|
8813
|
+
import pc30 from "picocolors";
|
|
8726
8814
|
import * as v8 from "valibot";
|
|
8727
8815
|
var OptionsSchema4 = v8.object({
|
|
8728
8816
|
...SSH_OPTION_SCHEMA,
|
|
@@ -8730,7 +8818,7 @@ var OptionsSchema4 = v8.object({
|
|
|
8730
8818
|
offline: v8.optional(v8.boolean())
|
|
8731
8819
|
});
|
|
8732
8820
|
var targets = addSshOptions(
|
|
8733
|
-
new
|
|
8821
|
+
new Command91("targets").description("list the targets this project can deploy to").configureHelp(helpConfig)
|
|
8734
8822
|
).option("--json", "print raw JSON").option("--offline", "skip connecting to servers").action(
|
|
8735
8823
|
(raw) => runCommand(async () => {
|
|
8736
8824
|
const options = parseOptions(OptionsSchema4, raw);
|
|
@@ -8794,13 +8882,13 @@ function report3(rows, offline) {
|
|
|
8794
8882
|
const domain = width("DOMAIN", (row) => row.domain);
|
|
8795
8883
|
const header = `${"TARGET".padEnd(target)} ${"SERVER".padEnd(server)} ${"DOMAIN".padEnd(domain)} RELEASE`;
|
|
8796
8884
|
const lines = rows.map(
|
|
8797
|
-
(row) => `${row.kind === "local" ?
|
|
8885
|
+
(row) => `${row.kind === "local" ? pc30.dim(row.target.padEnd(target)) : pc30.cyan(row.target.padEnd(target))} ${row.server.padEnd(server)} ${row.domain.padEnd(domain)} ${row.release}`
|
|
8798
8886
|
);
|
|
8799
|
-
|
|
8887
|
+
p50.log.info(`${pc30.dim(header)}
|
|
8800
8888
|
${lines.join("\n")}`);
|
|
8801
8889
|
const unreachable = rows.filter((row) => row.kind === "remote" && !row.reachable);
|
|
8802
8890
|
if (!offline && unreachable.length > 0) {
|
|
8803
|
-
|
|
8891
|
+
p50.log.warn(
|
|
8804
8892
|
`Could not reach ${unreachable.map((row) => row.server).join(", ")}.
|
|
8805
8893
|
Release and domain are shown from what this project recorded.`
|
|
8806
8894
|
);
|
|
@@ -8809,16 +8897,16 @@ Release and domain are shown from what this project recorded.`
|
|
|
8809
8897
|
|
|
8810
8898
|
// src/commands/test.ts
|
|
8811
8899
|
import path46 from "node:path";
|
|
8812
|
-
import
|
|
8813
|
-
import { Command as
|
|
8900
|
+
import process33 from "node:process";
|
|
8901
|
+
import { Command as Command92 } from "commander";
|
|
8814
8902
|
import PocketBase5 from "pocketbase";
|
|
8815
|
-
import
|
|
8903
|
+
import pc31 from "picocolors";
|
|
8816
8904
|
import { x as x5 } from "tinyexec";
|
|
8817
8905
|
import { detect as detect8 } from "package-manager-detector";
|
|
8818
8906
|
import { resolveCommand as resolveCommand8 } from "package-manager-detector/commands";
|
|
8819
8907
|
import fs41 from "node:fs";
|
|
8820
|
-
var testServer = new
|
|
8821
|
-
const cwd =
|
|
8908
|
+
var testServer = new Command92("test:server").description("run server tests").allowUnknownOption(true).allowExcessArguments(true).configureHelp(helpConfig).action(async (_opts, cmd) => {
|
|
8909
|
+
const cwd = process33.cwd();
|
|
8822
8910
|
const email3 = `test-${Math.random().toString(36).slice(2)}@example.com`;
|
|
8823
8911
|
const password11 = "password";
|
|
8824
8912
|
const testDataDir = path46.join(cwd, "test-data");
|
|
@@ -8829,12 +8917,12 @@ var testServer = new Command91("test:server").description("run server tests").al
|
|
|
8829
8917
|
email: email3,
|
|
8830
8918
|
password: password11
|
|
8831
8919
|
});
|
|
8832
|
-
|
|
8833
|
-
|
|
8834
|
-
|
|
8835
|
-
|
|
8836
|
-
|
|
8837
|
-
console.log(`${
|
|
8920
|
+
process33.env.POCKETBASE_URL = url;
|
|
8921
|
+
process33.env.POCKETBASE_SUPERUSER_EMAIL = email3;
|
|
8922
|
+
process33.env.POCKETBASE_SUPERUSER_PASSWORD = password11;
|
|
8923
|
+
process33.env.VELA_DATA_DIR = testDataDir;
|
|
8924
|
+
process33.env.TEST = "true";
|
|
8925
|
+
console.log(`${pc31.greenBright("\u2713")} Created test database`);
|
|
8838
8926
|
const { createServer } = await loadVite(cwd);
|
|
8839
8927
|
const vite = await createServer({
|
|
8840
8928
|
mode: "test",
|
|
@@ -8843,9 +8931,9 @@ var testServer = new Command91("test:server").description("run server tests").al
|
|
|
8843
8931
|
});
|
|
8844
8932
|
const vitePort = await findFreePort();
|
|
8845
8933
|
await vite.listen(vitePort);
|
|
8846
|
-
|
|
8847
|
-
console.log(`${
|
|
8848
|
-
console.log(`${
|
|
8934
|
+
process33.env.VITE_TEST_URL = `http://localhost:${vitePort}`;
|
|
8935
|
+
console.log(`${pc31.greenBright("\u2713")} Started Vite: http://localhost:${vitePort}`);
|
|
8936
|
+
console.log(`${pc31.greenBright("\u2713")} Started PocketBase: ${url}`);
|
|
8849
8937
|
const cleanup = async () => {
|
|
8850
8938
|
stop();
|
|
8851
8939
|
await vite.close();
|
|
@@ -8856,8 +8944,8 @@ var testServer = new Command91("test:server").description("run server tests").al
|
|
|
8856
8944
|
await authWithRetries(pb, email3, password11);
|
|
8857
8945
|
} catch (e) {
|
|
8858
8946
|
await cleanup();
|
|
8859
|
-
console.error(`${
|
|
8860
|
-
|
|
8947
|
+
console.error(`${pc31.redBright("\u2717")} Auth failed: ${e.message}`);
|
|
8948
|
+
process33.exit(1);
|
|
8861
8949
|
}
|
|
8862
8950
|
const extraArgs = (cmd.parent?.args ?? []).slice(1);
|
|
8863
8951
|
let filter = extraArgs.find((arg) => !arg.startsWith("-"));
|
|
@@ -8875,7 +8963,7 @@ var testServer = new Command91("test:server").description("run server tests").al
|
|
|
8875
8963
|
const resolvedArgs = resolved.args.slice();
|
|
8876
8964
|
if (pm === "npm") resolvedArgs.unshift("--yes");
|
|
8877
8965
|
await x5(resolved.command, resolvedArgs, {
|
|
8878
|
-
nodeOptions: { cwd, stdio: "inherit", env: { ...
|
|
8966
|
+
nodeOptions: { cwd, stdio: "inherit", env: { ...process33.env, CI: "1" } },
|
|
8879
8967
|
throwOnError: true
|
|
8880
8968
|
});
|
|
8881
8969
|
} catch {
|
|
@@ -8903,7 +8991,7 @@ function stubPagesPlugin() {
|
|
|
8903
8991
|
// src/commands/routes.ts
|
|
8904
8992
|
import fs42 from "node:fs";
|
|
8905
8993
|
import path47 from "node:path";
|
|
8906
|
-
import { Command as
|
|
8994
|
+
import { Command as Command93 } from "commander";
|
|
8907
8995
|
var HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
8908
8996
|
"GET",
|
|
8909
8997
|
"POST",
|
|
@@ -8914,7 +9002,7 @@ var HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
|
8914
9002
|
"HEAD",
|
|
8915
9003
|
"fallback"
|
|
8916
9004
|
]);
|
|
8917
|
-
var routes = new
|
|
9005
|
+
var routes = new Command93("routes").description("list routes").configureHelp(helpConfig).action(async () => {
|
|
8918
9006
|
const { workspaceRootDir, routesDir } = await getWorkspace();
|
|
8919
9007
|
const routesRoot = path47.join(workspaceRootDir, routesDir);
|
|
8920
9008
|
const found = walk(routesRoot, routesRoot).filter((r) => r.methods.length > 0);
|
|
@@ -8989,13 +9077,13 @@ function printTable(routes2) {
|
|
|
8989
9077
|
}
|
|
8990
9078
|
|
|
8991
9079
|
// src/commands/i18n.ts
|
|
8992
|
-
import
|
|
8993
|
-
import { Command as
|
|
9080
|
+
import process34 from "node:process";
|
|
9081
|
+
import { Command as Command94 } from "commander";
|
|
8994
9082
|
import { x as x6 } from "tinyexec";
|
|
8995
9083
|
import { detect as detect9 } from "package-manager-detector";
|
|
8996
9084
|
import { resolveCommand as resolveCommand9 } from "package-manager-detector/commands";
|
|
8997
9085
|
async function runWuchale(extraArgs) {
|
|
8998
|
-
const cwd =
|
|
9086
|
+
const cwd = process34.cwd();
|
|
8999
9087
|
const pm = (await detect9({ cwd }))?.name ?? "npm";
|
|
9000
9088
|
const resolved = resolveCommand9(pm, "execute", ["wuchale", ...extraArgs]);
|
|
9001
9089
|
const args = resolved.args.slice();
|
|
@@ -9005,11 +9093,11 @@ async function runWuchale(extraArgs) {
|
|
|
9005
9093
|
throwOnError: true
|
|
9006
9094
|
});
|
|
9007
9095
|
}
|
|
9008
|
-
var extract = new
|
|
9009
|
-
var watch = new
|
|
9010
|
-
var status2 = new
|
|
9011
|
-
var clean = new
|
|
9012
|
-
var i18n3 = new
|
|
9096
|
+
var extract = new Command94("extract").description("extract translatable strings").configureHelp(helpConfig).action(() => runWuchale([]));
|
|
9097
|
+
var watch = new Command94("watch").description("watch and extract translatable strings").configureHelp(helpConfig).action(() => runWuchale(["--watch"]));
|
|
9098
|
+
var status2 = new Command94("status").description("show i18n status").configureHelp(helpConfig).action(() => runWuchale(["status"]));
|
|
9099
|
+
var clean = new Command94("clean").description("clean unused translatable strings").configureHelp(helpConfig).action(() => runWuchale(["--clean"]));
|
|
9100
|
+
var i18n3 = new Command94("i18n").description("i18n utilities").configureHelp(helpConfig).addCommand(extract, { isDefault: true }).addCommand(watch).addCommand(status2).addCommand(clean);
|
|
9013
9101
|
|
|
9014
9102
|
// src/commands/oauth.ts
|
|
9015
9103
|
var oauth = stubCommand("oauth", "configure OAuth providers");
|
|
@@ -9017,6 +9105,121 @@ var oauth = stubCommand("oauth", "configure OAuth providers");
|
|
|
9017
9105
|
// src/commands/schemas.ts
|
|
9018
9106
|
var schemas = stubCommand("schemas", "manage database schemas");
|
|
9019
9107
|
|
|
9108
|
+
// src/commands/cms.ts
|
|
9109
|
+
import { Command as Command99 } from "commander";
|
|
9110
|
+
|
|
9111
|
+
// src/commands/cms/editor.ts
|
|
9112
|
+
import { Command as Command98 } from "commander";
|
|
9113
|
+
|
|
9114
|
+
// src/commands/cms/editor/add.ts
|
|
9115
|
+
import { randomBytes } from "node:crypto";
|
|
9116
|
+
import { Command as Command95 } from "commander";
|
|
9117
|
+
import * as p51 from "@clack/prompts";
|
|
9118
|
+
import pc33 from "picocolors";
|
|
9119
|
+
|
|
9120
|
+
// src/lib/cms-backend.ts
|
|
9121
|
+
import { createRequire as createRequire3 } from "node:module";
|
|
9122
|
+
import path48 from "node:path";
|
|
9123
|
+
import process35 from "node:process";
|
|
9124
|
+
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
9125
|
+
import pc32 from "picocolors";
|
|
9126
|
+
var DEFAULT_PROJECT = "default";
|
|
9127
|
+
async function loadBackendModule(root) {
|
|
9128
|
+
let entry;
|
|
9129
|
+
try {
|
|
9130
|
+
entry = createRequire3(path48.join(root, "package.json")).resolve("@velastack/cms/backend");
|
|
9131
|
+
} catch {
|
|
9132
|
+
throw new Error(
|
|
9133
|
+
`@velastack/cms is not installed in this project.
|
|
9134
|
+
|
|
9135
|
+
Run ${pc32.cyan("vela enable cms")} first.`
|
|
9136
|
+
);
|
|
9137
|
+
}
|
|
9138
|
+
return await import(pathToFileURL3(entry).href);
|
|
9139
|
+
}
|
|
9140
|
+
async function withCmsBackend(fn, cwd = process35.cwd()) {
|
|
9141
|
+
const root = findWorkspaceRoot(cwd);
|
|
9142
|
+
if (!root) {
|
|
9143
|
+
throw new Error("Could not find workspace root (no package.json found)");
|
|
9144
|
+
}
|
|
9145
|
+
const { createCmsBackend } = await loadBackendModule(root);
|
|
9146
|
+
const dataDir = localDataDir(root);
|
|
9147
|
+
const backend3 = createCmsBackend({
|
|
9148
|
+
dbPath: path48.join(dataDir, "cms.sqlite"),
|
|
9149
|
+
uploadDir: path48.join(dataDir, "uploads")
|
|
9150
|
+
});
|
|
9151
|
+
try {
|
|
9152
|
+
return await fn(backend3);
|
|
9153
|
+
} finally {
|
|
9154
|
+
backend3.close();
|
|
9155
|
+
}
|
|
9156
|
+
}
|
|
9157
|
+
|
|
9158
|
+
// src/commands/cms/editor/add.ts
|
|
9159
|
+
var editorAdd = new Command95("add").description("create an editor who can sign in to the admin bar").argument("<email>", "email the editor signs in with").option("--password <password>", "password to set \u2014 generated and shown once when omitted").option("--project <id>", "project the editor may edit", DEFAULT_PROJECT).configureHelp(helpConfig).action(
|
|
9160
|
+
(email3, options) => runCommand(async () => {
|
|
9161
|
+
const generated = options.password === void 0;
|
|
9162
|
+
const password11 = options.password ?? randomBytes(12).toString("base64url");
|
|
9163
|
+
const editor2 = await withCmsBackend(
|
|
9164
|
+
(cms3) => cms3.editors.create({ email: email3, password: password11, projects: [options.project] })
|
|
9165
|
+
);
|
|
9166
|
+
const lines = [`Added ${pc33.cyan(editor2.email)} as an editor of ${pc33.cyan(options.project)}.`];
|
|
9167
|
+
if (generated) {
|
|
9168
|
+
lines.push("", `Password: ${pc33.bold(password11)}`, "", "It is shown once; copy it now.");
|
|
9169
|
+
}
|
|
9170
|
+
p51.log.success(lines.join("\n"));
|
|
9171
|
+
p51.log.info(
|
|
9172
|
+
`Run ${pc33.cyan("vela dev")}, open any page with ${pc33.cyan("?edit")} on the URL (or press ${pc33.cyan("Ctrl+E")}), and sign in.`
|
|
9173
|
+
);
|
|
9174
|
+
}, "Failed to add the editor.")
|
|
9175
|
+
);
|
|
9176
|
+
|
|
9177
|
+
// src/commands/cms/editor/password.ts
|
|
9178
|
+
import { Command as Command96 } from "commander";
|
|
9179
|
+
import * as p52 from "@clack/prompts";
|
|
9180
|
+
import pc34 from "picocolors";
|
|
9181
|
+
var editorPassword = new Command96("password").description("set an editor's password").argument("<email>", "email of the editor").argument("<password>", "new password").configureHelp(helpConfig).action(
|
|
9182
|
+
(email3, password11) => runCommand(async () => {
|
|
9183
|
+
await withCmsBackend((cms3) => cms3.editors.setPassword(email3, password11));
|
|
9184
|
+
p52.log.success(
|
|
9185
|
+
`Updated the password for ${pc34.cyan(email3)}. Existing sessions were signed out.`
|
|
9186
|
+
);
|
|
9187
|
+
}, "Failed to set the password.")
|
|
9188
|
+
);
|
|
9189
|
+
|
|
9190
|
+
// src/commands/cms/editor/list.ts
|
|
9191
|
+
import { Command as Command97 } from "commander";
|
|
9192
|
+
import * as p53 from "@clack/prompts";
|
|
9193
|
+
import pc35 from "picocolors";
|
|
9194
|
+
var editorList = new Command97("list").description("list editors and the projects they may edit").configureHelp(helpConfig).action(
|
|
9195
|
+
() => runCommand(async () => {
|
|
9196
|
+
const rows = await withCmsBackend(
|
|
9197
|
+
async (cms3) => cms3.editors.list().map((editor2) => ({
|
|
9198
|
+
email: editor2.email,
|
|
9199
|
+
projects: cms3.editors.projectsFor(editor2.id)
|
|
9200
|
+
}))
|
|
9201
|
+
);
|
|
9202
|
+
if (rows.length === 0) {
|
|
9203
|
+
p53.log.info(`No editors yet. Add one with ${pc35.cyan("vela cms editor add <email>")}.`);
|
|
9204
|
+
return;
|
|
9205
|
+
}
|
|
9206
|
+
const width = Math.max(...rows.map((row) => row.email.length));
|
|
9207
|
+
p53.log.info(
|
|
9208
|
+
`Editors
|
|
9209
|
+
|
|
9210
|
+
` + rows.map(
|
|
9211
|
+
(row) => ` ${row.email.padEnd(width)} ${pc35.dim(row.projects.join(", ") || "no projects")}`
|
|
9212
|
+
).join("\n")
|
|
9213
|
+
);
|
|
9214
|
+
}, "Failed to list editors.")
|
|
9215
|
+
);
|
|
9216
|
+
|
|
9217
|
+
// src/commands/cms/editor.ts
|
|
9218
|
+
var editor = new Command98("editor").description("manage who can sign in to the admin bar").configureHelp(helpConfig).addCommand(editorAdd).addCommand(editorPassword).addCommand(editorList);
|
|
9219
|
+
|
|
9220
|
+
// src/commands/cms.ts
|
|
9221
|
+
var cms2 = new Command99("cms").description("manage the CMS").configureHelp(helpConfig).addCommand(editor);
|
|
9222
|
+
|
|
9020
9223
|
// src/program.ts
|
|
9021
9224
|
var NO_BACKEND_COMMMANDS = /* @__PURE__ */ new Set([
|
|
9022
9225
|
"bless",
|
|
@@ -9031,6 +9234,9 @@ var NO_BACKEND_COMMMANDS = /* @__PURE__ */ new Set([
|
|
|
9031
9234
|
"i18n",
|
|
9032
9235
|
"generate schema",
|
|
9033
9236
|
"generate form",
|
|
9237
|
+
// The CMS keeps its own SQLite database and editors; PocketBase is never involved.
|
|
9238
|
+
"enable cms",
|
|
9239
|
+
"cms",
|
|
9034
9240
|
// Server commands talk to a VPS over SSH, never to the local database.
|
|
9035
9241
|
"provision",
|
|
9036
9242
|
"env",
|
|
@@ -9046,40 +9252,40 @@ var NO_BACKEND_COMMMANDS = /* @__PURE__ */ new Set([
|
|
|
9046
9252
|
"restore"
|
|
9047
9253
|
]);
|
|
9048
9254
|
var BACKEND_OPTIONAL_COMMANDS = /* @__PURE__ */ new Set(["dev", "build", "preview", "deploy"]);
|
|
9049
|
-
var program = new
|
|
9255
|
+
var program = new Command100().name(package_default.name).description(package_default.description).version(package_default.version, "-v, --version").configureHelp(helpConfig);
|
|
9050
9256
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
9051
9257
|
if (isStub(actionCommand)) return;
|
|
9052
|
-
const envRoot = findWorkspaceRoot() ??
|
|
9258
|
+
const envRoot = findWorkspaceRoot() ?? process36.cwd();
|
|
9053
9259
|
dotenv2.config({ path: nodePath.join(envRoot, ".env"), quiet: true });
|
|
9054
|
-
const
|
|
9055
|
-
if (NO_BACKEND_COMMMANDS.has(
|
|
9056
|
-
const top =
|
|
9260
|
+
const path49 = getCommandPath(actionCommand);
|
|
9261
|
+
if (NO_BACKEND_COMMMANDS.has(path49)) return;
|
|
9262
|
+
const top = path49.split(" ", 1)[0];
|
|
9057
9263
|
if (NO_BACKEND_COMMMANDS.has(top)) return;
|
|
9058
9264
|
if (!hasBackend()) {
|
|
9059
9265
|
if (BACKEND_OPTIONAL_COMMANDS.has(top)) return;
|
|
9060
|
-
|
|
9061
|
-
`${
|
|
9266
|
+
p54.log.error(
|
|
9267
|
+
`${pc36.cyan(`vela ${path49}`)} needs a backend, and this project does not have one.
|
|
9062
9268
|
|
|
9063
9269
|
Static projects have no database to talk to.
|
|
9064
9270
|
|
|
9065
|
-
To add a backend to this project, run ${
|
|
9271
|
+
To add a backend to this project, run ${pc36.cyan("vela bless")}.`
|
|
9066
9272
|
);
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
|
|
9273
|
+
p54.log.message();
|
|
9274
|
+
p54.cancel("Operation failed.");
|
|
9275
|
+
process36.exit(1);
|
|
9070
9276
|
}
|
|
9071
|
-
if (!
|
|
9072
|
-
|
|
9277
|
+
if (!process36.env.POCKETBASE_SUPERUSER_EMAIL || !process36.env.POCKETBASE_SUPERUSER_PASSWORD) {
|
|
9278
|
+
p54.log.error(
|
|
9073
9279
|
`PocketBase superuser credentials are required.
|
|
9074
9280
|
|
|
9075
|
-
Set ${
|
|
9281
|
+
Set ${pc36.cyan("POCKETBASE_SUPERUSER_EMAIL")} and ${pc36.cyan("POCKETBASE_SUPERUSER_PASSWORD")} in your .env file.
|
|
9076
9282
|
|
|
9077
|
-
To set up a new project, run ${
|
|
9078
|
-
To set up an existing project, run ${
|
|
9283
|
+
To set up a new project, run ${pc36.cyan("vela create")}.
|
|
9284
|
+
To set up an existing project, run ${pc36.cyan("vela bless")}.`
|
|
9079
9285
|
);
|
|
9080
|
-
|
|
9081
|
-
|
|
9082
|
-
|
|
9286
|
+
p54.log.message();
|
|
9287
|
+
p54.cancel("Operation failed.");
|
|
9288
|
+
process36.exit(1);
|
|
9083
9289
|
}
|
|
9084
9290
|
});
|
|
9085
9291
|
function getCommandPath(cmd) {
|
|
@@ -9126,20 +9332,21 @@ for (const command of [
|
|
|
9126
9332
|
routes,
|
|
9127
9333
|
i18n3,
|
|
9128
9334
|
oauth,
|
|
9129
|
-
schemas
|
|
9335
|
+
schemas,
|
|
9336
|
+
cms2
|
|
9130
9337
|
]) {
|
|
9131
9338
|
program.addCommand(command);
|
|
9132
9339
|
}
|
|
9133
9340
|
|
|
9134
9341
|
// src/bin.ts
|
|
9135
|
-
var argv = normalizeArgv(
|
|
9342
|
+
var argv = normalizeArgv(process37.argv.slice(2));
|
|
9136
9343
|
var delegatedExitCode = delegateToLocalCli({
|
|
9137
9344
|
argv,
|
|
9138
9345
|
selfPath: fileURLToPath2(import.meta.url),
|
|
9139
9346
|
selfVersion: package_default.version
|
|
9140
9347
|
});
|
|
9141
9348
|
if (delegatedExitCode !== null) {
|
|
9142
|
-
|
|
9349
|
+
process37.exit(delegatedExitCode);
|
|
9143
9350
|
}
|
|
9144
9351
|
program.parse(argv, { from: "user" });
|
|
9145
9352
|
//# sourceMappingURL=bin.js.map
|