vela 0.10.9 → 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 +746 -590
- 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
|
|
|
@@ -1763,7 +1764,7 @@ async function runPattern(slug2, argv2, input, report4) {
|
|
|
1763
1764
|
throw new Error(`Unknown pattern: ${slug2}`);
|
|
1764
1765
|
}
|
|
1765
1766
|
const { workspaceRootDir, features } = await getWorkspace();
|
|
1766
|
-
const
|
|
1767
|
+
const log41 = p6.taskLog({ title: report4.task.title });
|
|
1767
1768
|
let result;
|
|
1768
1769
|
try {
|
|
1769
1770
|
result = await pattern.generate({
|
|
@@ -1783,11 +1784,11 @@ async function runPattern(slug2, argv2, input, report4) {
|
|
|
1783
1784
|
});
|
|
1784
1785
|
return collections2;
|
|
1785
1786
|
},
|
|
1786
|
-
logger: { info: (message) =>
|
|
1787
|
+
logger: { info: (message) => log41.message(message) }
|
|
1787
1788
|
});
|
|
1788
|
-
|
|
1789
|
+
log41.success(report4.task.success);
|
|
1789
1790
|
} catch (e) {
|
|
1790
|
-
|
|
1791
|
+
log41.error(report4.task.error);
|
|
1791
1792
|
throw e;
|
|
1792
1793
|
}
|
|
1793
1794
|
const rel = (f) => toRelative(workspaceRootDir, f);
|
|
@@ -2398,7 +2399,7 @@ var migration = new Command8("migration").description("generate a migration for
|
|
|
2398
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);
|
|
2399
2400
|
|
|
2400
2401
|
// src/commands/enable.ts
|
|
2401
|
-
import { Command as
|
|
2402
|
+
import { Command as Command23 } from "commander";
|
|
2402
2403
|
|
|
2403
2404
|
// src/commands/enable/auth.ts
|
|
2404
2405
|
import { Command as Command10 } from "commander";
|
|
@@ -3944,11 +3945,47 @@ var smtp = new Command19("smtp").description("configure SMTP for transactional e
|
|
|
3944
3945
|
);
|
|
3945
3946
|
|
|
3946
3947
|
// src/commands/enable/cms.ts
|
|
3947
|
-
|
|
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
|
+
);
|
|
3948
3985
|
|
|
3949
3986
|
// src/commands/enable/blog.ts
|
|
3950
|
-
import { Command as
|
|
3951
|
-
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(
|
|
3952
3989
|
(_opts, cmd) => runCommand(
|
|
3953
3990
|
() => runPattern(
|
|
3954
3991
|
"enable-blog",
|
|
@@ -3973,8 +4010,8 @@ var blog = new Command20("blog").description("enable an mdsvex blog with posts,
|
|
|
3973
4010
|
);
|
|
3974
4011
|
|
|
3975
4012
|
// src/commands/enable/content-negotiation.ts
|
|
3976
|
-
import { Command as
|
|
3977
|
-
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(
|
|
3978
4015
|
(_opts, cmd) => runCommand(
|
|
3979
4016
|
() => runPattern(
|
|
3980
4017
|
"enable-content-negotiation",
|
|
@@ -3998,33 +4035,33 @@ var contentNegotiation = new Command21("content-negotiation").description("enabl
|
|
|
3998
4035
|
);
|
|
3999
4036
|
|
|
4000
4037
|
// src/commands/enable.ts
|
|
4001
|
-
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);
|
|
4002
4039
|
|
|
4003
4040
|
// src/commands/disable.ts
|
|
4004
|
-
import { Command as
|
|
4041
|
+
import { Command as Command34 } from "commander";
|
|
4005
4042
|
|
|
4006
4043
|
// src/commands/disable/auth.ts
|
|
4007
|
-
import { Command as
|
|
4044
|
+
import { Command as Command24 } from "commander";
|
|
4008
4045
|
|
|
4009
4046
|
// src/commands/disable/_shared.ts
|
|
4010
|
-
import
|
|
4011
|
-
import * as
|
|
4047
|
+
import process14 from "node:process";
|
|
4048
|
+
import * as p20 from "@clack/prompts";
|
|
4012
4049
|
async function runDisable(opts, flags, cmdArgs) {
|
|
4013
4050
|
if (!flags.yes) {
|
|
4014
|
-
const ok = await
|
|
4051
|
+
const ok = await p20.confirm({
|
|
4015
4052
|
message: opts.confirmMessage,
|
|
4016
4053
|
initialValue: false
|
|
4017
4054
|
});
|
|
4018
|
-
if (
|
|
4019
|
-
|
|
4020
|
-
|
|
4055
|
+
if (p20.isCancel(ok) || !ok) {
|
|
4056
|
+
p20.cancel("Operation cancelled.");
|
|
4057
|
+
process14.exit(0);
|
|
4021
4058
|
}
|
|
4022
4059
|
}
|
|
4023
4060
|
await runPattern(opts.slug, cmdArgs, { destructive: true }, opts.report);
|
|
4024
4061
|
}
|
|
4025
4062
|
|
|
4026
4063
|
// src/commands/disable/auth.ts
|
|
4027
|
-
var auth2 = new
|
|
4064
|
+
var auth2 = new Command24("auth").description("disable authentication").option("-y, --yes", "skip confirmation prompt").allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
4028
4065
|
(opts, cmd) => runCommand(
|
|
4029
4066
|
() => runDisable(
|
|
4030
4067
|
{
|
|
@@ -4050,8 +4087,8 @@ var auth2 = new Command23("auth").description("disable authentication").option("
|
|
|
4050
4087
|
);
|
|
4051
4088
|
|
|
4052
4089
|
// src/commands/disable/api.ts
|
|
4053
|
-
import { Command as
|
|
4054
|
-
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(
|
|
4055
4092
|
(opts, cmd) => runCommand(
|
|
4056
4093
|
() => runDisable(
|
|
4057
4094
|
{
|
|
@@ -4074,8 +4111,8 @@ var api2 = new Command24("api").description("disable the REST API").option("-y,
|
|
|
4074
4111
|
);
|
|
4075
4112
|
|
|
4076
4113
|
// src/commands/disable/api-keys.ts
|
|
4077
|
-
import { Command as
|
|
4078
|
-
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(
|
|
4079
4116
|
(opts, cmd) => runCommand(
|
|
4080
4117
|
() => runDisable(
|
|
4081
4118
|
{
|
|
@@ -4098,8 +4135,8 @@ var apiKeys2 = new Command25("api-keys").description("disable API key management
|
|
|
4098
4135
|
);
|
|
4099
4136
|
|
|
4100
4137
|
// src/commands/disable/backend.ts
|
|
4101
|
-
import { Command as
|
|
4102
|
-
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(
|
|
4103
4140
|
(opts, cmd) => runCommand(
|
|
4104
4141
|
() => runDisable(
|
|
4105
4142
|
{
|
|
@@ -4122,8 +4159,8 @@ var backend2 = new Command26("backend").description("disable the PocketBase back
|
|
|
4122
4159
|
);
|
|
4123
4160
|
|
|
4124
4161
|
// src/commands/disable/content-negotiation.ts
|
|
4125
|
-
import { Command as
|
|
4126
|
-
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(
|
|
4127
4164
|
(opts, cmd) => runCommand(
|
|
4128
4165
|
() => runDisable(
|
|
4129
4166
|
{
|
|
@@ -4146,8 +4183,8 @@ var contentNegotiation2 = new Command27("content-negotiation").description("disa
|
|
|
4146
4183
|
);
|
|
4147
4184
|
|
|
4148
4185
|
// src/commands/disable/i18n.ts
|
|
4149
|
-
import { Command as
|
|
4150
|
-
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(
|
|
4151
4188
|
(opts, cmd) => runCommand(
|
|
4152
4189
|
() => runDisable(
|
|
4153
4190
|
{
|
|
@@ -4173,8 +4210,8 @@ var i18n2 = new Command28("i18n").description("disable internationalization").op
|
|
|
4173
4210
|
);
|
|
4174
4211
|
|
|
4175
4212
|
// src/commands/disable/teams.ts
|
|
4176
|
-
import { Command as
|
|
4177
|
-
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(
|
|
4178
4215
|
(opts, cmd) => runCommand(
|
|
4179
4216
|
() => runDisable(
|
|
4180
4217
|
{
|
|
@@ -4200,8 +4237,8 @@ var teams2 = new Command29("teams").description("disable teams").option("-y, --y
|
|
|
4200
4237
|
);
|
|
4201
4238
|
|
|
4202
4239
|
// src/commands/disable/payments.ts
|
|
4203
|
-
import { Command as
|
|
4204
|
-
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(
|
|
4205
4242
|
(opts, cmd) => runCommand(
|
|
4206
4243
|
() => runDisable(
|
|
4207
4244
|
{
|
|
@@ -4228,11 +4265,11 @@ var payments2 = new Command30("payments").description("disable payments").option
|
|
|
4228
4265
|
);
|
|
4229
4266
|
|
|
4230
4267
|
// src/commands/disable/s3.ts
|
|
4231
|
-
import { Command as
|
|
4232
|
-
import * as
|
|
4233
|
-
import
|
|
4268
|
+
import { Command as Command32 } from "commander";
|
|
4269
|
+
import * as p21 from "@clack/prompts";
|
|
4270
|
+
import pc10 from "picocolors";
|
|
4234
4271
|
var s32 = addTargetOptions(
|
|
4235
|
-
new
|
|
4272
|
+
new Command32("s3").description("disable S3 file storage").option("--backups", "keep backups on the server again, rather than uploads").configureHelp(helpConfig),
|
|
4236
4273
|
"local"
|
|
4237
4274
|
).action(
|
|
4238
4275
|
(raw) => runCommand(() => {
|
|
@@ -4241,14 +4278,14 @@ var s32 = addTargetOptions(
|
|
|
4241
4278
|
return withBackupTarget(raw, "disable s3", async (ctx) => {
|
|
4242
4279
|
const existing = await readS3(ctx.pb, filesystem);
|
|
4243
4280
|
if (!existing.enabled) {
|
|
4244
|
-
|
|
4281
|
+
p21.log.info(`S3 ${label2(filesystem)} is already off for ${ctx.targetName}.`);
|
|
4245
4282
|
return;
|
|
4246
4283
|
}
|
|
4247
4284
|
await disableS3(ctx.pb, filesystem);
|
|
4248
4285
|
reportResult({
|
|
4249
4286
|
summary: `Disabled S3 ${label2(filesystem)} on ${ctx.targetName}.`,
|
|
4250
4287
|
nextSteps: filesystem === "backups" ? ["New backups are written to the server again."] : [
|
|
4251
|
-
`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.`,
|
|
4252
4289
|
"Copy it back first if you need it: `rclone copy <remote>:<bucket>/ <storage dir>/`.",
|
|
4253
4290
|
"The credentials are kept, so `vela enable s3` does not mean retyping them."
|
|
4254
4291
|
]
|
|
@@ -4261,8 +4298,8 @@ function label2(filesystem) {
|
|
|
4261
4298
|
}
|
|
4262
4299
|
|
|
4263
4300
|
// src/commands/disable/smtp.ts
|
|
4264
|
-
import { Command as
|
|
4265
|
-
var smtp2 = new
|
|
4301
|
+
import { Command as Command33 } from "commander";
|
|
4302
|
+
var smtp2 = new Command33("smtp").description("disable SMTP configuration").configureHelp(helpConfig).action(
|
|
4266
4303
|
() => runCommand(async () => {
|
|
4267
4304
|
const { workspaceRootDir } = await getWorkspace();
|
|
4268
4305
|
await withPocketbase(workspaceRootDir, async (pb) => {
|
|
@@ -4279,30 +4316,30 @@ var smtp2 = new Command32("smtp").description("disable SMTP configuration").conf
|
|
|
4279
4316
|
);
|
|
4280
4317
|
|
|
4281
4318
|
// src/commands/disable.ts
|
|
4282
|
-
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);
|
|
4283
4320
|
|
|
4284
4321
|
// src/commands/destroy.ts
|
|
4285
|
-
import { Command as
|
|
4322
|
+
import { Command as Command40 } from "commander";
|
|
4286
4323
|
|
|
4287
4324
|
// src/commands/destroy/form.ts
|
|
4288
|
-
import { Command as
|
|
4325
|
+
import { Command as Command35 } from "commander";
|
|
4289
4326
|
|
|
4290
4327
|
// src/commands/destroy/_shared.ts
|
|
4291
|
-
import
|
|
4292
|
-
import * as
|
|
4328
|
+
import process15 from "node:process";
|
|
4329
|
+
import * as p22 from "@clack/prompts";
|
|
4293
4330
|
async function runDestroy(slug2, model, confirmMessage, report4, flags) {
|
|
4294
4331
|
if (!flags.yes) {
|
|
4295
|
-
const ok = await
|
|
4296
|
-
if (
|
|
4297
|
-
|
|
4298
|
-
|
|
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);
|
|
4299
4336
|
}
|
|
4300
4337
|
}
|
|
4301
4338
|
await runPattern(slug2, [model], { destructive: true, route: flags.route }, report4);
|
|
4302
4339
|
}
|
|
4303
4340
|
|
|
4304
4341
|
// src/commands/destroy/form.ts
|
|
4305
|
-
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(
|
|
4306
4343
|
"--route <route>",
|
|
4307
4344
|
"custom route the form was generated at (must match the --route used at generation)"
|
|
4308
4345
|
).allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
@@ -4326,8 +4363,8 @@ var form2 = new Command34("form").description("destroy a form generated by `vela
|
|
|
4326
4363
|
);
|
|
4327
4364
|
|
|
4328
4365
|
// src/commands/destroy/schema.ts
|
|
4329
|
-
import { Command as
|
|
4330
|
-
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(
|
|
4331
4368
|
(model, opts) => runCommand(
|
|
4332
4369
|
() => runDestroy(
|
|
4333
4370
|
"destroy-schema",
|
|
@@ -4348,8 +4385,8 @@ var schema2 = new Command35("schema").description("destroy a zod schema generate
|
|
|
4348
4385
|
);
|
|
4349
4386
|
|
|
4350
4387
|
// src/commands/destroy/resource.ts
|
|
4351
|
-
import { Command as
|
|
4352
|
-
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(
|
|
4353
4390
|
(model, opts) => runCommand(
|
|
4354
4391
|
() => runDestroy(
|
|
4355
4392
|
"destroy-resource",
|
|
@@ -4370,8 +4407,8 @@ var resource2 = new Command36("resource").description("destroy a resource genera
|
|
|
4370
4407
|
);
|
|
4371
4408
|
|
|
4372
4409
|
// src/commands/destroy/scaffold.ts
|
|
4373
|
-
import { Command as
|
|
4374
|
-
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(
|
|
4375
4412
|
"--route <route>",
|
|
4376
4413
|
"custom route the scaffold was generated at (must match the --route used at generation)"
|
|
4377
4414
|
).allowUnknownOption(true).configureHelp(helpConfig).action(
|
|
@@ -4398,12 +4435,12 @@ var scaffold2 = new Command37("scaffold").description("destroy a scaffold genera
|
|
|
4398
4435
|
);
|
|
4399
4436
|
|
|
4400
4437
|
// src/commands/destroy/deployment.ts
|
|
4401
|
-
import
|
|
4402
|
-
import { Command as
|
|
4403
|
-
import * as
|
|
4404
|
-
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";
|
|
4405
4442
|
var deployment = addTargetOptions(
|
|
4406
|
-
new
|
|
4443
|
+
new Command39("deployment").description("remove a deployed environment from its server").configureHelp(helpConfig),
|
|
4407
4444
|
"production"
|
|
4408
4445
|
).option("--purge", "also delete the database and uploaded files").option("-y, --yes", "skip the confirmation prompt").action(
|
|
4409
4446
|
(raw) => runCommand(async () => {
|
|
@@ -4419,10 +4456,10 @@ var deployment = addTargetOptions(
|
|
|
4419
4456
|
args: [ctx.instance, ...options.purge ? ["--purge"] : []],
|
|
4420
4457
|
stream: true
|
|
4421
4458
|
});
|
|
4422
|
-
|
|
4423
|
-
`Removed ${
|
|
4459
|
+
p23.log.success(
|
|
4460
|
+
`Removed ${pc11.cyan(`${ctx.appName} (${ctx.targetName})`)} from ${ctx.server}.` + (result?.purged ? "" : `
|
|
4424
4461
|
|
|
4425
|
-
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.`)
|
|
4426
4463
|
);
|
|
4427
4464
|
}
|
|
4428
4465
|
},
|
|
@@ -4435,37 +4472,37 @@ The database and uploads are still in the instance's shared directory. Pass ${pc
|
|
|
4435
4472
|
);
|
|
4436
4473
|
async function confirm7(appName, targetName, envTag, purge) {
|
|
4437
4474
|
if (isProd(envTag) || purge) {
|
|
4438
|
-
const answer = await
|
|
4439
|
-
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`,
|
|
4440
4477
|
validate: (value) => value === appName ? void 0 : `Type ${appName} to confirm`
|
|
4441
4478
|
});
|
|
4442
|
-
if (
|
|
4443
|
-
|
|
4444
|
-
|
|
4479
|
+
if (p23.isCancel(answer)) {
|
|
4480
|
+
p23.cancel("Operation cancelled.");
|
|
4481
|
+
process16.exit(0);
|
|
4445
4482
|
}
|
|
4446
4483
|
return;
|
|
4447
4484
|
}
|
|
4448
|
-
const ok = await
|
|
4485
|
+
const ok = await p23.confirm({
|
|
4449
4486
|
message: `Remove ${appName} (${targetName})?`,
|
|
4450
4487
|
initialValue: false
|
|
4451
4488
|
});
|
|
4452
|
-
if (
|
|
4453
|
-
|
|
4454
|
-
|
|
4489
|
+
if (p23.isCancel(ok) || !ok) {
|
|
4490
|
+
p23.cancel("Operation cancelled.");
|
|
4491
|
+
process16.exit(0);
|
|
4455
4492
|
}
|
|
4456
4493
|
}
|
|
4457
4494
|
|
|
4458
4495
|
// src/commands/destroy.ts
|
|
4459
|
-
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);
|
|
4460
4497
|
|
|
4461
4498
|
// src/commands/ui.ts
|
|
4462
|
-
import { Command as
|
|
4499
|
+
import { Command as Command43 } from "commander";
|
|
4463
4500
|
|
|
4464
4501
|
// src/commands/ui/add.ts
|
|
4465
|
-
import { Command as
|
|
4502
|
+
import { Command as Command41 } from "commander";
|
|
4466
4503
|
import { exec as exec2 } from "tinyexec";
|
|
4467
4504
|
import { detect as detect4, resolveCommand as resolveCommand4 } from "package-manager-detector";
|
|
4468
|
-
var add = new
|
|
4505
|
+
var add = new Command41("add").description("add ui components").argument("<components...>", "the components to add").configureHelp(helpConfig).action(
|
|
4469
4506
|
(components) => runCommand(async () => {
|
|
4470
4507
|
const { workspaceRootDir } = await getWorkspace();
|
|
4471
4508
|
const packageManager = (await detect4({ cwd: workspaceRootDir }))?.name ?? "npm";
|
|
@@ -4506,7 +4543,7 @@ var add = new Command40("add").description("add ui components").argument("<compo
|
|
|
4506
4543
|
// src/commands/ui/base.ts
|
|
4507
4544
|
import fs22 from "node:fs";
|
|
4508
4545
|
import path21 from "node:path";
|
|
4509
|
-
import { Command as
|
|
4546
|
+
import { Command as Command42, InvalidArgumentError } from "commander";
|
|
4510
4547
|
var VALID_COLORS = ["slate", "gray", "zinc", "stone", "neutral"];
|
|
4511
4548
|
function findThemeFile(color) {
|
|
4512
4549
|
const candidate = path21.join(templatesDir(), "ui", "css", `${color}.css`);
|
|
@@ -4533,7 +4570,7 @@ ${out}`;
|
|
|
4533
4570
|
${selectors.dark}`;
|
|
4534
4571
|
return out;
|
|
4535
4572
|
}
|
|
4536
|
-
var base = new
|
|
4573
|
+
var base = new Command42("base").description("change the base color").argument("<color>", "base color to use", (value) => {
|
|
4537
4574
|
if (!VALID_COLORS.includes(value)) {
|
|
4538
4575
|
throw new InvalidArgumentError(`Valid colors are: ${VALID_COLORS.join(", ")}`);
|
|
4539
4576
|
}
|
|
@@ -4561,22 +4598,22 @@ var base = new Command41("base").description("change the base color").argument("
|
|
|
4561
4598
|
);
|
|
4562
4599
|
|
|
4563
4600
|
// src/commands/ui.ts
|
|
4564
|
-
var ui = new
|
|
4601
|
+
var ui = new Command43("ui").description("generate ui components").configureHelp(helpConfig).addCommand(add).addCommand(base);
|
|
4565
4602
|
|
|
4566
4603
|
// src/commands/legal.ts
|
|
4567
|
-
import { Command as
|
|
4604
|
+
import { Command as Command46 } from "commander";
|
|
4568
4605
|
|
|
4569
4606
|
// src/commands/legal/terms.ts
|
|
4570
4607
|
import fs23 from "node:fs";
|
|
4571
4608
|
import path22 from "node:path";
|
|
4572
|
-
import { Command as
|
|
4573
|
-
import * as
|
|
4609
|
+
import { Command as Command44 } from "commander";
|
|
4610
|
+
import * as p25 from "@clack/prompts";
|
|
4574
4611
|
|
|
4575
4612
|
// src/commands/legal/shared.ts
|
|
4576
|
-
import
|
|
4577
|
-
import * as
|
|
4613
|
+
import process17 from "node:process";
|
|
4614
|
+
import * as p24 from "@clack/prompts";
|
|
4578
4615
|
var sharedFields = {
|
|
4579
|
-
websiteUrl: () =>
|
|
4616
|
+
websiteUrl: () => p24.text({
|
|
4580
4617
|
message: "What is your website URL?",
|
|
4581
4618
|
placeholder: "http://www.mysite.com",
|
|
4582
4619
|
validate: (value) => {
|
|
@@ -4585,7 +4622,7 @@ var sharedFields = {
|
|
|
4585
4622
|
}
|
|
4586
4623
|
}
|
|
4587
4624
|
}),
|
|
4588
|
-
websiteName: () =>
|
|
4625
|
+
websiteName: () => p24.text({
|
|
4589
4626
|
message: "What is your website name?",
|
|
4590
4627
|
placeholder: "My Site",
|
|
4591
4628
|
validate: (value) => {
|
|
@@ -4594,7 +4631,7 @@ var sharedFields = {
|
|
|
4594
4631
|
}
|
|
4595
4632
|
}
|
|
4596
4633
|
}),
|
|
4597
|
-
entityType: () =>
|
|
4634
|
+
entityType: () => p24.select({
|
|
4598
4635
|
message: "Entity type",
|
|
4599
4636
|
options: [
|
|
4600
4637
|
{
|
|
@@ -4605,7 +4642,7 @@ var sharedFields = {
|
|
|
4605
4642
|
{ value: "individual", label: "I'm an Individual" }
|
|
4606
4643
|
]
|
|
4607
4644
|
}),
|
|
4608
|
-
businessName: ({ results }) => results?.entityType === "business" ?
|
|
4645
|
+
businessName: ({ results }) => results?.entityType === "business" ? p24.text({
|
|
4609
4646
|
message: "What is the name of the business?",
|
|
4610
4647
|
placeholder: "My Company LLC",
|
|
4611
4648
|
validate: (value) => {
|
|
@@ -4614,7 +4651,7 @@ var sharedFields = {
|
|
|
4614
4651
|
}
|
|
4615
4652
|
}
|
|
4616
4653
|
}) : void 0,
|
|
4617
|
-
businessAddress: ({ results }) => results?.entityType === "business" ?
|
|
4654
|
+
businessAddress: ({ results }) => results?.entityType === "business" ? p24.text({
|
|
4618
4655
|
message: "What is the address of the business?",
|
|
4619
4656
|
placeholder: "1 Cupertino, CA 95014",
|
|
4620
4657
|
validate: (value) => {
|
|
@@ -4623,7 +4660,7 @@ var sharedFields = {
|
|
|
4623
4660
|
}
|
|
4624
4661
|
}
|
|
4625
4662
|
}) : void 0,
|
|
4626
|
-
country: () =>
|
|
4663
|
+
country: () => p24.text({
|
|
4627
4664
|
message: "Enter the country",
|
|
4628
4665
|
validate: (value) => {
|
|
4629
4666
|
if (!value) {
|
|
@@ -4631,7 +4668,7 @@ var sharedFields = {
|
|
|
4631
4668
|
}
|
|
4632
4669
|
}
|
|
4633
4670
|
}),
|
|
4634
|
-
state: () =>
|
|
4671
|
+
state: () => p24.text({
|
|
4635
4672
|
message: "Enter the state",
|
|
4636
4673
|
validate: (value) => {
|
|
4637
4674
|
if (!value) {
|
|
@@ -4641,11 +4678,11 @@ var sharedFields = {
|
|
|
4641
4678
|
})
|
|
4642
4679
|
};
|
|
4643
4680
|
var onCancel = () => {
|
|
4644
|
-
|
|
4645
|
-
|
|
4681
|
+
p24.cancel("Operation cancelled.");
|
|
4682
|
+
process17.exit(0);
|
|
4646
4683
|
};
|
|
4647
4684
|
async function contactMethods(type) {
|
|
4648
|
-
const selection = await
|
|
4685
|
+
const selection = await p24.multiselect({
|
|
4649
4686
|
message: `How can users contact you for any questions regarding your ${type === "privacy" ? "Privacy Policy" : "Terms & Conditions"}? Check all that apply`,
|
|
4650
4687
|
options: [
|
|
4651
4688
|
{ value: "email", label: "By email" },
|
|
@@ -4654,11 +4691,11 @@ async function contactMethods(type) {
|
|
|
4654
4691
|
{ value: "mail", label: "By sending post mail" }
|
|
4655
4692
|
]
|
|
4656
4693
|
});
|
|
4657
|
-
if (
|
|
4694
|
+
if (p24.isCancel(selection)) onCancel();
|
|
4658
4695
|
const contact = selection;
|
|
4659
4696
|
const details = {};
|
|
4660
4697
|
if (contact.includes("email")) {
|
|
4661
|
-
const email3 = await
|
|
4698
|
+
const email3 = await p24.text({
|
|
4662
4699
|
message: "What's the email?",
|
|
4663
4700
|
placeholder: "office@mycompany.com",
|
|
4664
4701
|
validate: (value) => {
|
|
@@ -4667,11 +4704,11 @@ async function contactMethods(type) {
|
|
|
4667
4704
|
}
|
|
4668
4705
|
}
|
|
4669
4706
|
});
|
|
4670
|
-
if (
|
|
4707
|
+
if (p24.isCancel(email3)) onCancel();
|
|
4671
4708
|
details.email = email3;
|
|
4672
4709
|
}
|
|
4673
4710
|
if (contact.includes("page")) {
|
|
4674
|
-
const page = await
|
|
4711
|
+
const page = await p24.text({
|
|
4675
4712
|
message: "What's the link?",
|
|
4676
4713
|
placeholder: "http://www.mycompany.com/contact",
|
|
4677
4714
|
validate: (value) => {
|
|
@@ -4680,11 +4717,11 @@ async function contactMethods(type) {
|
|
|
4680
4717
|
}
|
|
4681
4718
|
}
|
|
4682
4719
|
});
|
|
4683
|
-
if (
|
|
4720
|
+
if (p24.isCancel(page)) onCancel();
|
|
4684
4721
|
details.page = page;
|
|
4685
4722
|
}
|
|
4686
4723
|
if (contact.includes("phone")) {
|
|
4687
|
-
const phone = await
|
|
4724
|
+
const phone = await p24.text({
|
|
4688
4725
|
message: "What's the phone number?",
|
|
4689
4726
|
placeholder: "408.996.1010",
|
|
4690
4727
|
validate: (value) => {
|
|
@@ -4693,11 +4730,11 @@ async function contactMethods(type) {
|
|
|
4693
4730
|
}
|
|
4694
4731
|
}
|
|
4695
4732
|
});
|
|
4696
|
-
if (
|
|
4733
|
+
if (p24.isCancel(phone)) onCancel();
|
|
4697
4734
|
details.phone = phone;
|
|
4698
4735
|
}
|
|
4699
4736
|
if (contact.includes("mail")) {
|
|
4700
|
-
const address = await
|
|
4737
|
+
const address = await p24.text({
|
|
4701
4738
|
message: "What's the address?",
|
|
4702
4739
|
placeholder: "767 Fifth Avenue New York, NY 10153, United States",
|
|
4703
4740
|
validate: (value) => {
|
|
@@ -4706,7 +4743,7 @@ async function contactMethods(type) {
|
|
|
4706
4743
|
}
|
|
4707
4744
|
}
|
|
4708
4745
|
});
|
|
4709
|
-
if (
|
|
4746
|
+
if (p24.isCancel(address)) onCancel();
|
|
4710
4747
|
details.address = address;
|
|
4711
4748
|
}
|
|
4712
4749
|
return { methods: contact, details };
|
|
@@ -5102,7 +5139,7 @@ var generateTermsHtml = (answers) => {
|
|
|
5102
5139
|
};
|
|
5103
5140
|
async function termsAction() {
|
|
5104
5141
|
const { workspaceRootDir, publicRoutesDir } = await getWorkspace();
|
|
5105
|
-
const core = await
|
|
5142
|
+
const core = await p25.group(
|
|
5106
5143
|
{
|
|
5107
5144
|
websiteUrl: sharedFields.websiteUrl,
|
|
5108
5145
|
websiteName: sharedFields.websiteName,
|
|
@@ -5114,25 +5151,25 @@ async function termsAction() {
|
|
|
5114
5151
|
},
|
|
5115
5152
|
{ onCancel }
|
|
5116
5153
|
);
|
|
5117
|
-
const accounts = await
|
|
5154
|
+
const accounts = await p25.select({
|
|
5118
5155
|
message: "Can users create accounts?",
|
|
5119
5156
|
options: [
|
|
5120
5157
|
{ value: "yes", label: "Yes, users can create accounts" },
|
|
5121
5158
|
{ value: "no", label: "No" }
|
|
5122
5159
|
]
|
|
5123
5160
|
});
|
|
5124
|
-
if (
|
|
5125
|
-
const userContent = await
|
|
5161
|
+
if (p25.isCancel(accounts)) onCancel();
|
|
5162
|
+
const userContent = await p25.select({
|
|
5126
5163
|
message: "Can users create and/or upload content (ie. text, images)?",
|
|
5127
5164
|
options: [
|
|
5128
5165
|
{ value: "yes", label: "Yes, users can create and/or upload content" },
|
|
5129
5166
|
{ value: "no", label: "No" }
|
|
5130
5167
|
]
|
|
5131
5168
|
});
|
|
5132
|
-
if (
|
|
5169
|
+
if (p25.isCancel(userContent)) onCancel();
|
|
5133
5170
|
let infringementEmail;
|
|
5134
5171
|
if (userContent === "yes") {
|
|
5135
|
-
const email3 = await
|
|
5172
|
+
const email3 = await p25.text({
|
|
5136
5173
|
message: "What's the email address where you will receive infringements notices?",
|
|
5137
5174
|
placeholder: "dmca@website.com",
|
|
5138
5175
|
validate: (value) => {
|
|
@@ -5141,10 +5178,10 @@ async function termsAction() {
|
|
|
5141
5178
|
}
|
|
5142
5179
|
}
|
|
5143
5180
|
});
|
|
5144
|
-
if (
|
|
5181
|
+
if (p25.isCancel(email3)) onCancel();
|
|
5145
5182
|
infringementEmail = email3;
|
|
5146
5183
|
}
|
|
5147
|
-
const canBuyGoods = await
|
|
5184
|
+
const canBuyGoods = await p25.select({
|
|
5148
5185
|
message: "Can users buy goods (products, items)?",
|
|
5149
5186
|
options: [
|
|
5150
5187
|
{
|
|
@@ -5154,28 +5191,28 @@ async function termsAction() {
|
|
|
5154
5191
|
{ value: "no", label: "No" }
|
|
5155
5192
|
]
|
|
5156
5193
|
});
|
|
5157
|
-
if (
|
|
5158
|
-
const subscriptions2 = await
|
|
5194
|
+
if (p25.isCancel(canBuyGoods)) onCancel();
|
|
5195
|
+
const subscriptions2 = await p25.select({
|
|
5159
5196
|
message: "Do you offer subscription plans?",
|
|
5160
5197
|
options: [
|
|
5161
5198
|
{ value: "yes", label: "Yes, we offer subscription plans" },
|
|
5162
5199
|
{ value: "no", label: "No" }
|
|
5163
5200
|
]
|
|
5164
5201
|
});
|
|
5165
|
-
if (
|
|
5202
|
+
if (p25.isCancel(subscriptions2)) onCancel();
|
|
5166
5203
|
let freeTrial;
|
|
5167
5204
|
if (subscriptions2 === "yes") {
|
|
5168
|
-
const ft = await
|
|
5205
|
+
const ft = await p25.select({
|
|
5169
5206
|
message: "Do you offer a free trial?",
|
|
5170
5207
|
options: [
|
|
5171
5208
|
{ value: "yes", label: "Yes" },
|
|
5172
5209
|
{ value: "no", label: "No" }
|
|
5173
5210
|
]
|
|
5174
5211
|
});
|
|
5175
|
-
if (
|
|
5212
|
+
if (p25.isCancel(ft)) onCancel();
|
|
5176
5213
|
freeTrial = ft;
|
|
5177
5214
|
}
|
|
5178
|
-
const exclusiveContent = await
|
|
5215
|
+
const exclusiveContent = await p25.select({
|
|
5179
5216
|
message: "Do you want to make it clear that your own content & trademarks are your exclusive property?",
|
|
5180
5217
|
options: [
|
|
5181
5218
|
{
|
|
@@ -5185,24 +5222,24 @@ async function termsAction() {
|
|
|
5185
5222
|
{ value: "no", label: "No" }
|
|
5186
5223
|
]
|
|
5187
5224
|
});
|
|
5188
|
-
if (
|
|
5189
|
-
const feedbackReuse = await
|
|
5225
|
+
if (p25.isCancel(exclusiveContent)) onCancel();
|
|
5226
|
+
const feedbackReuse = await p25.select({
|
|
5190
5227
|
message: "If users provide you feedback & suggestions, do you want to use this feedback without compensation or credits given?",
|
|
5191
5228
|
options: [
|
|
5192
5229
|
{ value: "yes", label: "Yes, we may implement any feedback or suggestions we receive" },
|
|
5193
5230
|
{ value: "no", label: "No" }
|
|
5194
5231
|
]
|
|
5195
5232
|
});
|
|
5196
|
-
if (
|
|
5197
|
-
const promotions = await
|
|
5233
|
+
if (p25.isCancel(feedbackReuse)) onCancel();
|
|
5234
|
+
const promotions = await p25.select({
|
|
5198
5235
|
message: "Do you plan to offer promotions, contests, sweepstakes?",
|
|
5199
5236
|
options: [
|
|
5200
5237
|
{ value: "yes", label: "Yes, we may offer promotions, contests, sweepstakes" },
|
|
5201
5238
|
{ value: "no", label: "No" }
|
|
5202
5239
|
]
|
|
5203
5240
|
});
|
|
5204
|
-
if (
|
|
5205
|
-
const mobileAppRaw = await
|
|
5241
|
+
if (p25.isCancel(promotions)) onCancel();
|
|
5242
|
+
const mobileAppRaw = await p25.multiselect({
|
|
5206
5243
|
message: "Is the Service distributed through any mobile app stores? Check all that apply",
|
|
5207
5244
|
options: [
|
|
5208
5245
|
{ value: "apple", label: "Apple App Store" },
|
|
@@ -5210,7 +5247,7 @@ async function termsAction() {
|
|
|
5210
5247
|
],
|
|
5211
5248
|
required: false
|
|
5212
5249
|
});
|
|
5213
|
-
if (
|
|
5250
|
+
if (p25.isCancel(mobileAppRaw)) onCancel();
|
|
5214
5251
|
const mobileApp = mobileAppRaw ?? [];
|
|
5215
5252
|
const contact = await contactMethods("terms");
|
|
5216
5253
|
const html = generateTermsHtml({
|
|
@@ -5253,13 +5290,13 @@ async function termsAction() {
|
|
|
5253
5290
|
]
|
|
5254
5291
|
});
|
|
5255
5292
|
}
|
|
5256
|
-
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."));
|
|
5257
5294
|
|
|
5258
5295
|
// src/commands/legal/privacy.ts
|
|
5259
5296
|
import fs24 from "node:fs";
|
|
5260
5297
|
import path23 from "node:path";
|
|
5261
|
-
import { Command as
|
|
5262
|
-
import * as
|
|
5298
|
+
import { Command as Command45 } from "commander";
|
|
5299
|
+
import * as p26 from "@clack/prompts";
|
|
5263
5300
|
var mapLabels = {
|
|
5264
5301
|
personalInfo: {
|
|
5265
5302
|
email: "Email address",
|
|
@@ -5677,12 +5714,12 @@ var generatePrivacyHtml = (answers) => {
|
|
|
5677
5714
|
return `<section data-role="content">${sections.join("")}</section>`;
|
|
5678
5715
|
};
|
|
5679
5716
|
async function promptWithCustom(message, options, customMessage) {
|
|
5680
|
-
const selection = await
|
|
5681
|
-
if (
|
|
5717
|
+
const selection = await p26.multiselect({ message, options });
|
|
5718
|
+
if (p26.isCancel(selection)) onCancel();
|
|
5682
5719
|
const values = selection;
|
|
5683
5720
|
if (values.includes("custom")) {
|
|
5684
|
-
const custom = await
|
|
5685
|
-
if (
|
|
5721
|
+
const custom = await p26.text({ message: customMessage });
|
|
5722
|
+
if (p26.isCancel(custom)) onCancel();
|
|
5686
5723
|
const idx = values.indexOf("custom");
|
|
5687
5724
|
if (idx !== -1) values.splice(idx, 1);
|
|
5688
5725
|
if (custom) values.push(String(custom));
|
|
@@ -5691,7 +5728,7 @@ async function promptWithCustom(message, options, customMessage) {
|
|
|
5691
5728
|
}
|
|
5692
5729
|
async function privacyAction() {
|
|
5693
5730
|
const { workspaceRootDir, publicRoutesDir } = await getWorkspace();
|
|
5694
|
-
const core = await
|
|
5731
|
+
const core = await p26.group(
|
|
5695
5732
|
{
|
|
5696
5733
|
websiteUrl: sharedFields.websiteUrl,
|
|
5697
5734
|
websiteName: sharedFields.websiteName,
|
|
@@ -5703,7 +5740,7 @@ async function privacyAction() {
|
|
|
5703
5740
|
},
|
|
5704
5741
|
{ onCancel }
|
|
5705
5742
|
);
|
|
5706
|
-
const personalInfo = await
|
|
5743
|
+
const personalInfo = await p26.multiselect({
|
|
5707
5744
|
message: "What kind of personal information do you collect from users? Check all that apply",
|
|
5708
5745
|
options: [
|
|
5709
5746
|
{ value: "email", label: "Email address" },
|
|
@@ -5718,16 +5755,16 @@ async function privacyAction() {
|
|
|
5718
5755
|
],
|
|
5719
5756
|
required: false
|
|
5720
5757
|
});
|
|
5721
|
-
if (
|
|
5758
|
+
if (p26.isCancel(personalInfo)) onCancel();
|
|
5722
5759
|
const contact = await contactMethods("privacy");
|
|
5723
|
-
const tracking = await
|
|
5760
|
+
const tracking = await p26.select({
|
|
5724
5761
|
message: "Do you use tracking and/or analytics tools, such as Google Analytics?",
|
|
5725
5762
|
options: [
|
|
5726
5763
|
{ value: "yes", label: "Yes, we use Google Analytics or other related tools" },
|
|
5727
5764
|
{ value: "no", label: "No" }
|
|
5728
5765
|
]
|
|
5729
5766
|
});
|
|
5730
|
-
if (
|
|
5767
|
+
if (p26.isCancel(tracking)) onCancel();
|
|
5731
5768
|
let trackingTools;
|
|
5732
5769
|
if (tracking === "yes") {
|
|
5733
5770
|
trackingTools = await promptWithCustom(
|
|
@@ -5746,7 +5783,7 @@ async function privacyAction() {
|
|
|
5746
5783
|
"Enter your custom tracking/analytics tool name"
|
|
5747
5784
|
);
|
|
5748
5785
|
}
|
|
5749
|
-
const sendEmails = await
|
|
5786
|
+
const sendEmails = await p26.select({
|
|
5750
5787
|
message: "Do you send emails to users?",
|
|
5751
5788
|
options: [
|
|
5752
5789
|
{
|
|
@@ -5756,7 +5793,7 @@ async function privacyAction() {
|
|
|
5756
5793
|
{ value: "no", label: "No" }
|
|
5757
5794
|
]
|
|
5758
5795
|
});
|
|
5759
|
-
if (
|
|
5796
|
+
if (p26.isCancel(sendEmails)) onCancel();
|
|
5760
5797
|
let emailPlatforms;
|
|
5761
5798
|
if (sendEmails === "yes") {
|
|
5762
5799
|
emailPlatforms = await promptWithCustom(
|
|
@@ -5771,14 +5808,14 @@ async function privacyAction() {
|
|
|
5771
5808
|
"Enter your custom email platform"
|
|
5772
5809
|
);
|
|
5773
5810
|
}
|
|
5774
|
-
const showAds = await
|
|
5811
|
+
const showAds = await p26.select({
|
|
5775
5812
|
message: "Do you show ads?",
|
|
5776
5813
|
options: [
|
|
5777
5814
|
{ value: "yes", label: "Yes, we show ads" },
|
|
5778
5815
|
{ value: "no", label: "No" }
|
|
5779
5816
|
]
|
|
5780
5817
|
});
|
|
5781
|
-
if (
|
|
5818
|
+
if (p26.isCancel(showAds)) onCancel();
|
|
5782
5819
|
let adsPlatforms;
|
|
5783
5820
|
if (showAds === "yes") {
|
|
5784
5821
|
adsPlatforms = await promptWithCustom(
|
|
@@ -5801,7 +5838,7 @@ async function privacyAction() {
|
|
|
5801
5838
|
"Enter your custom ads platform"
|
|
5802
5839
|
);
|
|
5803
5840
|
}
|
|
5804
|
-
const canPay = await
|
|
5841
|
+
const canPay = await p26.select({
|
|
5805
5842
|
message: "Can users pay for products or services?",
|
|
5806
5843
|
options: [
|
|
5807
5844
|
{ value: "yes", label: "Yes, users can pay for our products/services" },
|
|
@@ -5811,7 +5848,7 @@ async function privacyAction() {
|
|
|
5811
5848
|
}
|
|
5812
5849
|
]
|
|
5813
5850
|
});
|
|
5814
|
-
if (
|
|
5851
|
+
if (p26.isCancel(canPay)) onCancel();
|
|
5815
5852
|
let paymentProcessors;
|
|
5816
5853
|
if (canPay === "yes") {
|
|
5817
5854
|
paymentProcessors = await promptWithCustom(
|
|
@@ -5842,14 +5879,14 @@ async function privacyAction() {
|
|
|
5842
5879
|
"Enter your custom payment processor/method"
|
|
5843
5880
|
);
|
|
5844
5881
|
}
|
|
5845
|
-
const remarketing = await
|
|
5882
|
+
const remarketing = await p26.select({
|
|
5846
5883
|
message: "Do you use remarketing services for marketing & advertising purposes?",
|
|
5847
5884
|
options: [
|
|
5848
5885
|
{ value: "yes", label: "Yes, we use remarketing services to advertise our business" },
|
|
5849
5886
|
{ value: "no", label: "No" }
|
|
5850
5887
|
]
|
|
5851
5888
|
});
|
|
5852
|
-
if (
|
|
5889
|
+
if (p26.isCancel(remarketing)) onCancel();
|
|
5853
5890
|
let remarketingPlatforms;
|
|
5854
5891
|
if (remarketing === "yes") {
|
|
5855
5892
|
remarketingPlatforms = await promptWithCustom(
|
|
@@ -5868,7 +5905,7 @@ async function privacyAction() {
|
|
|
5868
5905
|
"Enter your custom remarketing platform"
|
|
5869
5906
|
);
|
|
5870
5907
|
}
|
|
5871
|
-
const providersRaw = await
|
|
5908
|
+
const providersRaw = await p26.multiselect({
|
|
5872
5909
|
message: "Select if you use any of the following providers",
|
|
5873
5910
|
options: [
|
|
5874
5911
|
{ value: "recaptcha", label: "Invisible reCAPTCHA" },
|
|
@@ -5879,16 +5916,16 @@ async function privacyAction() {
|
|
|
5879
5916
|
],
|
|
5880
5917
|
required: false
|
|
5881
5918
|
});
|
|
5882
|
-
if (
|
|
5919
|
+
if (p26.isCancel(providersRaw)) onCancel();
|
|
5883
5920
|
const providers = providersRaw;
|
|
5884
5921
|
if (providers.includes("custom")) {
|
|
5885
|
-
const custom = await
|
|
5886
|
-
if (
|
|
5922
|
+
const custom = await p26.text({ message: "Enter your custom provider" });
|
|
5923
|
+
if (p26.isCancel(custom)) onCancel();
|
|
5887
5924
|
const idx = providers.indexOf("custom");
|
|
5888
5925
|
if (idx !== -1) providers.splice(idx, 1);
|
|
5889
5926
|
if (custom) providers.push(String(custom));
|
|
5890
5927
|
}
|
|
5891
|
-
const usStates = await
|
|
5928
|
+
const usStates = await p26.select({
|
|
5892
5929
|
message: "Include U.S. state privacy rights (CCPA/CPRA, VCDPA, CPA, CTDPA, UCPA, TX, OR, etc.)?",
|
|
5893
5930
|
options: [
|
|
5894
5931
|
{
|
|
@@ -5899,55 +5936,55 @@ async function privacyAction() {
|
|
|
5899
5936
|
],
|
|
5900
5937
|
initialValue: "yes"
|
|
5901
5938
|
});
|
|
5902
|
-
if (
|
|
5903
|
-
const gdpr = await
|
|
5939
|
+
if (p26.isCancel(usStates)) onCancel();
|
|
5940
|
+
const gdpr = await p26.select({
|
|
5904
5941
|
message: "Do you want your Privacy Policy to include GDPR / UK GDPR wording?",
|
|
5905
5942
|
options: [
|
|
5906
5943
|
{ value: "yes", label: "Yes. Include GDPR rights for EEA, UK, and Swiss residents" },
|
|
5907
5944
|
{ value: "no", label: "No" }
|
|
5908
5945
|
]
|
|
5909
5946
|
});
|
|
5910
|
-
if (
|
|
5947
|
+
if (p26.isCancel(gdpr)) onCancel();
|
|
5911
5948
|
let facebookFanPage = "no";
|
|
5912
5949
|
const facebookDetails = { name: "", url: "" };
|
|
5913
5950
|
if (gdpr === "yes") {
|
|
5914
|
-
const fan = await
|
|
5951
|
+
const fan = await p26.select({
|
|
5915
5952
|
message: "Do you have a Facebook Fan Page?",
|
|
5916
5953
|
options: [
|
|
5917
5954
|
{ value: "yes", label: "Yes, we have a Facebook Fan Page" },
|
|
5918
5955
|
{ value: "no", label: "No" }
|
|
5919
5956
|
]
|
|
5920
5957
|
});
|
|
5921
|
-
if (
|
|
5958
|
+
if (p26.isCancel(fan)) onCancel();
|
|
5922
5959
|
facebookFanPage = fan;
|
|
5923
5960
|
if (facebookFanPage === "yes") {
|
|
5924
|
-
const name = await
|
|
5961
|
+
const name = await p26.text({
|
|
5925
5962
|
message: "What is the name of the Facebook Fan Page?",
|
|
5926
5963
|
placeholder: "My Facebook Page"
|
|
5927
5964
|
});
|
|
5928
|
-
if (
|
|
5965
|
+
if (p26.isCancel(name)) onCancel();
|
|
5929
5966
|
facebookDetails.name = name;
|
|
5930
|
-
const url = await
|
|
5967
|
+
const url = await p26.text({
|
|
5931
5968
|
message: "What is the URL of the Facebook Fan Page?",
|
|
5932
5969
|
placeholder: "https://facebook.com/my-facebook-page"
|
|
5933
5970
|
});
|
|
5934
|
-
if (
|
|
5971
|
+
if (p26.isCancel(url)) onCancel();
|
|
5935
5972
|
facebookDetails.url = url;
|
|
5936
5973
|
}
|
|
5937
5974
|
}
|
|
5938
|
-
const kids = await
|
|
5975
|
+
const kids = await p26.select({
|
|
5939
5976
|
message: "Do you collect information from kids under the age of 13?",
|
|
5940
5977
|
options: [
|
|
5941
5978
|
{ value: "yes", label: "Yes. We collect information from children under the age of 13" },
|
|
5942
5979
|
{ value: "no", label: "No" }
|
|
5943
5980
|
]
|
|
5944
5981
|
});
|
|
5945
|
-
if (
|
|
5946
|
-
const retention = await
|
|
5982
|
+
if (p26.isCancel(kids)) onCancel();
|
|
5983
|
+
const retention = await p26.text({
|
|
5947
5984
|
message: "How long do you retain personal information? (leave blank for default wording)",
|
|
5948
5985
|
placeholder: "e.g. 12 months after account closure"
|
|
5949
5986
|
});
|
|
5950
|
-
if (
|
|
5987
|
+
if (p26.isCancel(retention)) onCancel();
|
|
5951
5988
|
const html = generatePrivacyHtml({
|
|
5952
5989
|
core,
|
|
5953
5990
|
personalInfo: personalInfo ?? [],
|
|
@@ -6002,18 +6039,18 @@ async function privacyAction() {
|
|
|
6002
6039
|
]
|
|
6003
6040
|
});
|
|
6004
6041
|
}
|
|
6005
|
-
var privacy = new
|
|
6042
|
+
var privacy = new Command45("privacy").description("generate placeholder privacy policy").configureHelp(helpConfig).action(() => runCommand(privacyAction, "Failed to generate privacy policy."));
|
|
6006
6043
|
|
|
6007
6044
|
// src/commands/legal.ts
|
|
6008
|
-
var legal = new
|
|
6045
|
+
var legal = new Command46("legal").description("generate placeholder legal documents").configureHelp(helpConfig).addCommand(terms).addCommand(privacy);
|
|
6009
6046
|
|
|
6010
6047
|
// src/commands/fixtures.ts
|
|
6011
|
-
import { Command as
|
|
6048
|
+
import { Command as Command52 } from "commander";
|
|
6012
6049
|
|
|
6013
6050
|
// src/commands/fixtures/load.ts
|
|
6014
6051
|
import fs25 from "node:fs";
|
|
6015
6052
|
import path24 from "node:path";
|
|
6016
|
-
import { Command as
|
|
6053
|
+
import { Command as Command47 } from "commander";
|
|
6017
6054
|
function getFixtureFiles(cwd) {
|
|
6018
6055
|
const fixturesDir = path24.join(cwd, "data", "fixtures");
|
|
6019
6056
|
if (!fs25.existsSync(fixturesDir)) return [];
|
|
@@ -6047,7 +6084,7 @@ async function loadFixtures(pb, workspaceRootDir) {
|
|
|
6047
6084
|
}
|
|
6048
6085
|
return loaded;
|
|
6049
6086
|
}
|
|
6050
|
-
var load = new
|
|
6087
|
+
var load = new Command47("load").description("load fixtures into the database").configureHelp(helpConfig).action(
|
|
6051
6088
|
() => runCommand(async () => {
|
|
6052
6089
|
const { workspaceRootDir } = await getWorkspace();
|
|
6053
6090
|
let loaded = [];
|
|
@@ -6074,7 +6111,7 @@ var load = new Command46("load").description("load fixtures into the database").
|
|
|
6074
6111
|
|
|
6075
6112
|
// src/commands/fixtures/clear.ts
|
|
6076
6113
|
import path25 from "node:path";
|
|
6077
|
-
import { Command as
|
|
6114
|
+
import { Command as Command48 } from "commander";
|
|
6078
6115
|
|
|
6079
6116
|
// src/lib/collections.ts
|
|
6080
6117
|
function dependencyOrder(collections2, startingCollectionId) {
|
|
@@ -6141,7 +6178,7 @@ async function clearFixtures(pb, workspaceRootDir) {
|
|
|
6141
6178
|
}
|
|
6142
6179
|
return cleared;
|
|
6143
6180
|
}
|
|
6144
|
-
var clear = new
|
|
6181
|
+
var clear = new Command48("clear").description("clear loaded fixtures").configureHelp(helpConfig).action(
|
|
6145
6182
|
() => runCommand(async () => {
|
|
6146
6183
|
const { workspaceRootDir } = await getWorkspace();
|
|
6147
6184
|
let cleared = [];
|
|
@@ -6170,8 +6207,8 @@ var clear = new Command47("clear").description("clear loaded fixtures").configur
|
|
|
6170
6207
|
);
|
|
6171
6208
|
|
|
6172
6209
|
// src/commands/fixtures/reset.ts
|
|
6173
|
-
import { Command as
|
|
6174
|
-
var reset = new
|
|
6210
|
+
import { Command as Command49 } from "commander";
|
|
6211
|
+
var reset = new Command49("reset").description("clear and reload fixtures").configureHelp(helpConfig).action(
|
|
6175
6212
|
() => runCommand(async () => {
|
|
6176
6213
|
const { workspaceRootDir } = await getWorkspace();
|
|
6177
6214
|
let cleared = [];
|
|
@@ -6203,8 +6240,8 @@ var reset = new Command48("reset").description("clear and reload fixtures").conf
|
|
|
6203
6240
|
// src/commands/fixtures/generate.ts
|
|
6204
6241
|
import fs26 from "node:fs";
|
|
6205
6242
|
import path26 from "node:path";
|
|
6206
|
-
import { Command as
|
|
6207
|
-
import * as
|
|
6243
|
+
import { Command as Command50, InvalidArgumentError as InvalidArgumentError2 } from "commander";
|
|
6244
|
+
import * as p27 from "@clack/prompts";
|
|
6208
6245
|
import { annotate } from "annotate-json-schema";
|
|
6209
6246
|
import { createGenerator } from "json-schema-faker";
|
|
6210
6247
|
import { faker } from "@faker-js/faker";
|
|
@@ -6324,7 +6361,7 @@ async function generateFixtureFiles(pb, workspaceRootDir, opts) {
|
|
|
6324
6361
|
}
|
|
6325
6362
|
return { writtenFiles, warnings };
|
|
6326
6363
|
}
|
|
6327
|
-
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(
|
|
6328
6365
|
(opts) => runCommand(async () => {
|
|
6329
6366
|
const { workspaceRootDir } = await getWorkspace();
|
|
6330
6367
|
const existing = getFixtureFiles(workspaceRootDir);
|
|
@@ -6353,7 +6390,7 @@ var generate2 = new Command49("generate").description("generate fixture data").o
|
|
|
6353
6390
|
seed: opts.seed
|
|
6354
6391
|
});
|
|
6355
6392
|
});
|
|
6356
|
-
for (const warning of result.warnings)
|
|
6393
|
+
for (const warning of result.warnings) p27.log.warn(warning);
|
|
6357
6394
|
if (result.writtenFiles.length === 0) {
|
|
6358
6395
|
reportResult({
|
|
6359
6396
|
summary: "No eligible collections found to generate fixtures for.",
|
|
@@ -6377,8 +6414,8 @@ var generate2 = new Command49("generate").description("generate fixture data").o
|
|
|
6377
6414
|
);
|
|
6378
6415
|
|
|
6379
6416
|
// src/commands/fixtures/regen.ts
|
|
6380
|
-
import { Command as
|
|
6381
|
-
import * as
|
|
6417
|
+
import { Command as Command51, InvalidArgumentError as InvalidArgumentError3 } from "commander";
|
|
6418
|
+
import * as p28 from "@clack/prompts";
|
|
6382
6419
|
function parseCount2(value) {
|
|
6383
6420
|
const n = parseInt(value, 10);
|
|
6384
6421
|
if (!Number.isFinite(n) || n <= 0 || n > 999) {
|
|
@@ -6393,7 +6430,7 @@ function parseSeed2(value) {
|
|
|
6393
6430
|
}
|
|
6394
6431
|
return n;
|
|
6395
6432
|
}
|
|
6396
|
-
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(
|
|
6397
6434
|
(opts) => runCommand(async () => {
|
|
6398
6435
|
const { workspaceRootDir } = await getWorkspace();
|
|
6399
6436
|
let cleared = [];
|
|
@@ -6407,7 +6444,7 @@ var regen = new Command50("regen").description("clear the database, regenerate f
|
|
|
6407
6444
|
});
|
|
6408
6445
|
loaded = await loadFixtures(pb, workspaceRootDir);
|
|
6409
6446
|
});
|
|
6410
|
-
for (const warning of result.warnings)
|
|
6447
|
+
for (const warning of result.warnings) p28.log.warn(warning);
|
|
6411
6448
|
reportResult({
|
|
6412
6449
|
summary: `Regenerated fixtures (${loaded.length} collection(s) reloaded).`,
|
|
6413
6450
|
filesCreated: result.writtenFiles,
|
|
@@ -6422,15 +6459,15 @@ var regen = new Command50("regen").description("clear the database, regenerate f
|
|
|
6422
6459
|
);
|
|
6423
6460
|
|
|
6424
6461
|
// src/commands/fixtures.ts
|
|
6425
|
-
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);
|
|
6426
6463
|
|
|
6427
6464
|
// src/commands/seeds.ts
|
|
6428
|
-
import { Command as
|
|
6465
|
+
import { Command as Command56 } from "commander";
|
|
6429
6466
|
|
|
6430
6467
|
// src/commands/seeds/load.ts
|
|
6431
6468
|
import fs27 from "node:fs";
|
|
6432
6469
|
import path27 from "node:path";
|
|
6433
|
-
import { Command as
|
|
6470
|
+
import { Command as Command53 } from "commander";
|
|
6434
6471
|
function getSeedFiles(cwd) {
|
|
6435
6472
|
const seedsDir = path27.join(cwd, "data", "seeds");
|
|
6436
6473
|
if (!fs27.existsSync(seedsDir)) return [];
|
|
@@ -6441,7 +6478,7 @@ function getSeedFiles(cwd) {
|
|
|
6441
6478
|
return { collectionName, seedPath };
|
|
6442
6479
|
});
|
|
6443
6480
|
}
|
|
6444
|
-
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(
|
|
6445
6482
|
(opts) => runCommand(async () => {
|
|
6446
6483
|
const { workspaceRootDir } = await getWorkspace();
|
|
6447
6484
|
const seedFiles = getSeedFiles(workspaceRootDir);
|
|
@@ -6486,7 +6523,7 @@ var load2 = new Command52("load").description("load seeds into the database").op
|
|
|
6486
6523
|
// src/commands/seeds/save.ts
|
|
6487
6524
|
import fs28 from "node:fs";
|
|
6488
6525
|
import path28 from "node:path";
|
|
6489
|
-
import { Command as
|
|
6526
|
+
import { Command as Command54 } from "commander";
|
|
6490
6527
|
var padZeros2 = (num, length) => num.toString().padStart(length, "0");
|
|
6491
6528
|
function filterSystemFields(record, systemFieldNames) {
|
|
6492
6529
|
const out = {};
|
|
@@ -6497,7 +6534,7 @@ function filterSystemFields(record, systemFieldNames) {
|
|
|
6497
6534
|
}
|
|
6498
6535
|
return out;
|
|
6499
6536
|
}
|
|
6500
|
-
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(
|
|
6501
6538
|
(opts) => runCommand(async () => {
|
|
6502
6539
|
const { workspaceRootDir } = await getWorkspace();
|
|
6503
6540
|
const seedsPath = path28.join(workspaceRootDir, "data", "seeds");
|
|
@@ -6571,7 +6608,7 @@ var save = new Command53("save").description("save the current data as seeds").o
|
|
|
6571
6608
|
// src/commands/seeds/clear.ts
|
|
6572
6609
|
import fs29 from "node:fs";
|
|
6573
6610
|
import path29 from "node:path";
|
|
6574
|
-
import { Command as
|
|
6611
|
+
import { Command as Command55 } from "commander";
|
|
6575
6612
|
async function clearSeeds(pb, workspaceRootDir, seedFiles) {
|
|
6576
6613
|
const cleared = [];
|
|
6577
6614
|
for (const { collectionName, seedPath } of seedFiles) {
|
|
@@ -6583,7 +6620,7 @@ async function clearSeeds(pb, workspaceRootDir, seedFiles) {
|
|
|
6583
6620
|
}
|
|
6584
6621
|
return cleared;
|
|
6585
6622
|
}
|
|
6586
|
-
var clear2 = new
|
|
6623
|
+
var clear2 = new Command55("clear").description("clear seeded records").configureHelp(helpConfig).action(
|
|
6587
6624
|
() => runCommand(async () => {
|
|
6588
6625
|
const { workspaceRootDir } = await getWorkspace();
|
|
6589
6626
|
const seedFiles = getSeedFiles(workspaceRootDir);
|
|
@@ -6614,23 +6651,23 @@ var clear2 = new Command54("clear").description("clear seeded records").configur
|
|
|
6614
6651
|
);
|
|
6615
6652
|
|
|
6616
6653
|
// src/commands/seeds.ts
|
|
6617
|
-
var seeds = new
|
|
6654
|
+
var seeds = new Command56("seeds").description("manage seed data").configureHelp(helpConfig).addCommand(load2).addCommand(save).addCommand(clear2);
|
|
6618
6655
|
|
|
6619
6656
|
// src/commands/signup.ts
|
|
6620
|
-
import { Command as
|
|
6621
|
-
import * as
|
|
6657
|
+
import { Command as Command58 } from "commander";
|
|
6658
|
+
import * as p30 from "@clack/prompts";
|
|
6622
6659
|
import makeFetchCookie2 from "fetch-cookie";
|
|
6623
6660
|
|
|
6624
6661
|
// src/commands/login.ts
|
|
6625
6662
|
import os3 from "node:os";
|
|
6626
|
-
import { Command as
|
|
6627
|
-
import * as
|
|
6663
|
+
import { Command as Command57 } from "commander";
|
|
6664
|
+
import * as p29 from "@clack/prompts";
|
|
6628
6665
|
import makeFetchCookie from "fetch-cookie";
|
|
6629
|
-
var login = new
|
|
6666
|
+
var login = new Command57("login").description("login to velastack.dev").configureHelp(helpConfig).action(
|
|
6630
6667
|
() => runCommand(async () => {
|
|
6631
|
-
const { email: email3, password: password11 } = await
|
|
6632
|
-
email: () =>
|
|
6633
|
-
password: () =>
|
|
6668
|
+
const { email: email3, password: password11 } = await p29.group({
|
|
6669
|
+
email: () => p29.text({ message: "Email" }),
|
|
6670
|
+
password: () => p29.password({ message: "Password" })
|
|
6634
6671
|
});
|
|
6635
6672
|
const fetchCookie = makeFetchCookie(fetch);
|
|
6636
6673
|
const loginRes = await fetchCookie(`${API_URL}/login`, {
|
|
@@ -6652,7 +6689,7 @@ var login = new Command56("login").description("login to velastack.dev").configu
|
|
|
6652
6689
|
}
|
|
6653
6690
|
const apiKey = await issueApiKey(fetchCookie);
|
|
6654
6691
|
writeConfig({ apiKey });
|
|
6655
|
-
|
|
6692
|
+
p29.log.success("Logged in to velastack.dev");
|
|
6656
6693
|
}, "Failed to login.")
|
|
6657
6694
|
);
|
|
6658
6695
|
async function issueApiKey(fetchCookie) {
|
|
@@ -6693,12 +6730,12 @@ function extractApiKey(cookie) {
|
|
|
6693
6730
|
}
|
|
6694
6731
|
|
|
6695
6732
|
// src/commands/signup.ts
|
|
6696
|
-
var signup = new
|
|
6733
|
+
var signup = new Command58("signup").description("signup to velastack.dev").configureHelp(helpConfig).action(
|
|
6697
6734
|
() => runCommand(async () => {
|
|
6698
|
-
const { email: email3, password: password11, passwordConfirm } = await
|
|
6699
|
-
email: () =>
|
|
6700
|
-
password: () =>
|
|
6701
|
-
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" })
|
|
6702
6739
|
});
|
|
6703
6740
|
if (password11 !== passwordConfirm) {
|
|
6704
6741
|
throw new Error("Passwords do not match.");
|
|
@@ -6722,33 +6759,33 @@ var signup = new Command57("signup").description("signup to velastack.dev").conf
|
|
|
6722
6759
|
}
|
|
6723
6760
|
const apiKey = await issueApiKey(fetchCookie);
|
|
6724
6761
|
writeConfig({ apiKey });
|
|
6725
|
-
|
|
6726
|
-
|
|
6762
|
+
p30.log.success("Signed up to velastack.dev");
|
|
6763
|
+
p30.log.info("Check your email for a confirmation link.");
|
|
6727
6764
|
}, "Failed to signup.")
|
|
6728
6765
|
);
|
|
6729
6766
|
|
|
6730
6767
|
// src/commands/logout.ts
|
|
6731
|
-
import { Command as
|
|
6732
|
-
import * as
|
|
6733
|
-
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(
|
|
6734
6771
|
() => runCommand(() => {
|
|
6735
6772
|
if (!readConfig()) {
|
|
6736
|
-
|
|
6773
|
+
p31.log.info("Not logged in");
|
|
6737
6774
|
return;
|
|
6738
6775
|
}
|
|
6739
6776
|
clearConfig();
|
|
6740
|
-
|
|
6777
|
+
p31.log.success("Logged out of velastack.dev");
|
|
6741
6778
|
})
|
|
6742
6779
|
);
|
|
6743
6780
|
|
|
6744
6781
|
// src/commands/whoami.ts
|
|
6745
|
-
import { Command as
|
|
6746
|
-
import * as
|
|
6747
|
-
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(
|
|
6748
6785
|
() => runCommand(async () => {
|
|
6749
6786
|
const apiKey = readConfig()?.apiKey;
|
|
6750
6787
|
if (!apiKey) {
|
|
6751
|
-
|
|
6788
|
+
p32.log.info("Not logged in. Run `vela login` to login.");
|
|
6752
6789
|
return;
|
|
6753
6790
|
}
|
|
6754
6791
|
const res = await fetch(`${API_URL}/api/collections/users/records`, {
|
|
@@ -6756,22 +6793,22 @@ var whoami = new Command59("whoami").description("show the current user").config
|
|
|
6756
6793
|
});
|
|
6757
6794
|
const data = await res.json();
|
|
6758
6795
|
if (!data.items.length) throw new Error("No user found. Run `vela login` to login.");
|
|
6759
|
-
|
|
6796
|
+
p32.log.success(`Logged in as ${data.items[0].email}`);
|
|
6760
6797
|
})
|
|
6761
6798
|
);
|
|
6762
6799
|
|
|
6763
6800
|
// src/commands/migrate.ts
|
|
6764
|
-
import { Command as
|
|
6801
|
+
import { Command as Command66 } from "commander";
|
|
6765
6802
|
|
|
6766
6803
|
// src/commands/migrate/up.ts
|
|
6767
|
-
import { Command as
|
|
6804
|
+
import { Command as Command61 } from "commander";
|
|
6768
6805
|
|
|
6769
6806
|
// src/lib/migrate.ts
|
|
6770
6807
|
import path30 from "node:path";
|
|
6771
|
-
import
|
|
6808
|
+
import process18 from "node:process";
|
|
6772
6809
|
import { x as x2 } from "tinyexec";
|
|
6773
6810
|
async function runPocketbaseMigrate(args) {
|
|
6774
|
-
const cwd =
|
|
6811
|
+
const cwd = process18.cwd();
|
|
6775
6812
|
const { getBinaryPath } = await import("pocketbase-server");
|
|
6776
6813
|
const binaryPath = getBinaryPath();
|
|
6777
6814
|
await x2(
|
|
@@ -6803,10 +6840,10 @@ async function runMigrateUp() {
|
|
|
6803
6840
|
]
|
|
6804
6841
|
});
|
|
6805
6842
|
}
|
|
6806
|
-
var up = new
|
|
6843
|
+
var up = new Command61("up").description("apply all pending migrations").configureHelp(helpConfig).action(() => runCommand(runMigrateUp, "Failed to run migrations."));
|
|
6807
6844
|
|
|
6808
6845
|
// src/commands/migrate/down.ts
|
|
6809
|
-
import { Command as
|
|
6846
|
+
import { Command as Command62, InvalidArgumentError as InvalidArgumentError4 } from "commander";
|
|
6810
6847
|
function parseSteps(value) {
|
|
6811
6848
|
const n = parseInt(value, 10);
|
|
6812
6849
|
if (!Number.isFinite(n) || n <= 0) {
|
|
@@ -6814,7 +6851,7 @@ function parseSteps(value) {
|
|
|
6814
6851
|
}
|
|
6815
6852
|
return n;
|
|
6816
6853
|
}
|
|
6817
|
-
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(
|
|
6818
6855
|
(n) => runCommand(async () => {
|
|
6819
6856
|
await runPocketbaseMigrate(["down", String(n)]);
|
|
6820
6857
|
reportResult({
|
|
@@ -6830,11 +6867,11 @@ var down = new Command61("down").alias("rollback").description("revert the last
|
|
|
6830
6867
|
// src/commands/migrate/create.ts
|
|
6831
6868
|
import fs30 from "node:fs";
|
|
6832
6869
|
import path31 from "node:path";
|
|
6833
|
-
import
|
|
6834
|
-
import { Command as
|
|
6835
|
-
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(
|
|
6836
6873
|
(name) => runCommand(async () => {
|
|
6837
|
-
const cwd =
|
|
6874
|
+
const cwd = process19.cwd();
|
|
6838
6875
|
const before = listMigrationFiles(cwd);
|
|
6839
6876
|
await runPocketbaseMigrate(["create", name]);
|
|
6840
6877
|
const after = listMigrationFiles(cwd);
|
|
@@ -6858,11 +6895,11 @@ function listMigrationFiles(cwd) {
|
|
|
6858
6895
|
// src/commands/migrate/collections.ts
|
|
6859
6896
|
import fs31 from "node:fs";
|
|
6860
6897
|
import path32 from "node:path";
|
|
6861
|
-
import
|
|
6862
|
-
import { Command as
|
|
6863
|
-
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(
|
|
6864
6901
|
() => runCommand(async () => {
|
|
6865
|
-
const cwd =
|
|
6902
|
+
const cwd = process20.cwd();
|
|
6866
6903
|
const before = listMigrationFiles2(cwd);
|
|
6867
6904
|
await runPocketbaseMigrate(["collections"]);
|
|
6868
6905
|
const after = listMigrationFiles2(cwd);
|
|
@@ -6891,8 +6928,8 @@ function listMigrationFiles2(cwd) {
|
|
|
6891
6928
|
}
|
|
6892
6929
|
|
|
6893
6930
|
// src/commands/migrate/history-sync.ts
|
|
6894
|
-
import { Command as
|
|
6895
|
-
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(
|
|
6896
6933
|
() => runCommand(async () => {
|
|
6897
6934
|
await runPocketbaseMigrate(["history-sync"]);
|
|
6898
6935
|
reportResult({
|
|
@@ -6903,23 +6940,23 @@ var historySync = new Command64("history-sync").description("drop _migrations ro
|
|
|
6903
6940
|
);
|
|
6904
6941
|
|
|
6905
6942
|
// src/commands/migrate.ts
|
|
6906
|
-
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);
|
|
6907
6944
|
|
|
6908
6945
|
// src/commands/dev.ts
|
|
6909
6946
|
import fs32 from "node:fs";
|
|
6910
6947
|
import path34 from "node:path";
|
|
6911
|
-
import
|
|
6948
|
+
import process22 from "node:process";
|
|
6912
6949
|
import { performance } from "node:perf_hooks";
|
|
6913
|
-
import { Command as
|
|
6914
|
-
import
|
|
6950
|
+
import { Command as Command67, InvalidArgumentError as InvalidArgumentError5 } from "commander";
|
|
6951
|
+
import pc13 from "picocolors";
|
|
6915
6952
|
import PocketBase3 from "pocketbase";
|
|
6916
6953
|
|
|
6917
6954
|
// src/lib/vite.ts
|
|
6918
6955
|
import path33 from "node:path";
|
|
6919
|
-
import
|
|
6956
|
+
import process21 from "node:process";
|
|
6920
6957
|
import { createRequire as createRequire2 } from "node:module";
|
|
6921
6958
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
6922
|
-
import
|
|
6959
|
+
import pc12 from "picocolors";
|
|
6923
6960
|
var REQUIRED_VITE_MAJOR = 8;
|
|
6924
6961
|
function viteVersionError(version) {
|
|
6925
6962
|
const major = Number.parseInt(version, 10);
|
|
@@ -6940,13 +6977,13 @@ function resolveProjectVite(cwd) {
|
|
|
6940
6977
|
return null;
|
|
6941
6978
|
}
|
|
6942
6979
|
}
|
|
6943
|
-
async function loadVite(cwd =
|
|
6980
|
+
async function loadVite(cwd = process21.cwd()) {
|
|
6944
6981
|
const entry = resolveProjectVite(cwd);
|
|
6945
6982
|
const vite = entry ? await import(pathToFileURL2(entry).href) : await import("vite");
|
|
6946
6983
|
const error = viteVersionError(vite.version);
|
|
6947
6984
|
if (error) {
|
|
6948
|
-
console.error(`${
|
|
6949
|
-
|
|
6985
|
+
console.error(`${pc12.redBright("\u2717")} ${error}`);
|
|
6986
|
+
process21.exit(1);
|
|
6950
6987
|
}
|
|
6951
6988
|
return vite;
|
|
6952
6989
|
}
|
|
@@ -6959,16 +6996,16 @@ function parsePort(value) {
|
|
|
6959
6996
|
}
|
|
6960
6997
|
return port;
|
|
6961
6998
|
}
|
|
6962
|
-
var dev = new
|
|
6963
|
-
const cwd =
|
|
6964
|
-
|
|
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);
|
|
6965
7002
|
const startTime = performance.now();
|
|
6966
7003
|
const { createServer, version } = await loadVite(cwd);
|
|
6967
7004
|
const viteMetadataDir = path34.join(cwd, "node_modules", ".vite");
|
|
6968
7005
|
const viteMetadataFile = path34.join(viteMetadataDir, "_pocketbase_metadata.json");
|
|
6969
7006
|
let pbProc;
|
|
6970
7007
|
const backend3 = hasBackend(cwd);
|
|
6971
|
-
const needsStart = backend3 && !
|
|
7008
|
+
const needsStart = backend3 && !process22.env.POCKETBASE_URL;
|
|
6972
7009
|
const cleanup = () => {
|
|
6973
7010
|
if (pbProc?.pid) pbProc.kill();
|
|
6974
7011
|
if (fs32.existsSync(viteMetadataFile)) fs32.rmSync(viteMetadataFile);
|
|
@@ -6983,15 +7020,15 @@ var dev = new Command66("dev").description("start the development server").optio
|
|
|
6983
7020
|
stdio: "pipe"
|
|
6984
7021
|
});
|
|
6985
7022
|
pbProc = started.proc;
|
|
6986
|
-
|
|
6987
|
-
pbProc.stdout?.pipe(
|
|
6988
|
-
pbProc.stderr?.pipe(
|
|
7023
|
+
process22.env.POCKETBASE_URL = started.url;
|
|
7024
|
+
pbProc.stdout?.pipe(process22.stdout);
|
|
7025
|
+
pbProc.stderr?.pipe(process22.stderr);
|
|
6989
7026
|
pbProc.on("error", (err) => console.error("PocketBase error:", err));
|
|
6990
7027
|
pbProc.on("exit", (code) => console.log(`PocketBase exited with code ${code}`));
|
|
6991
|
-
|
|
6992
|
-
|
|
7028
|
+
process22.on("exit", cleanup);
|
|
7029
|
+
process22.on("SIGINT", () => {
|
|
6993
7030
|
cleanup();
|
|
6994
|
-
|
|
7031
|
+
process22.exit(0);
|
|
6995
7032
|
});
|
|
6996
7033
|
}
|
|
6997
7034
|
const serverOptions = {};
|
|
@@ -7013,27 +7050,27 @@ var dev = new Command66("dev").description("start the development server").optio
|
|
|
7013
7050
|
await fs32.promises.writeFile(
|
|
7014
7051
|
viteMetadataFile,
|
|
7015
7052
|
JSON.stringify({
|
|
7016
|
-
pocketbaseUrl:
|
|
7053
|
+
pocketbaseUrl: process22.env.POCKETBASE_URL,
|
|
7017
7054
|
vitePort,
|
|
7018
7055
|
viteHost
|
|
7019
7056
|
})
|
|
7020
7057
|
);
|
|
7021
|
-
const pb = new PocketBase3(
|
|
7058
|
+
const pb = new PocketBase3(process22.env.POCKETBASE_URL);
|
|
7022
7059
|
await pb.collection("_superusers").authWithPassword(
|
|
7023
|
-
|
|
7024
|
-
|
|
7060
|
+
process22.env.POCKETBASE_SUPERUSER_EMAIL,
|
|
7061
|
+
process22.env.POCKETBASE_SUPERUSER_PASSWORD
|
|
7025
7062
|
);
|
|
7026
7063
|
await pb.settings.update({ meta: { appURL: `http://${viteHost}:${vitePort}` } });
|
|
7027
7064
|
await startWatchingTypes(cwd, pb);
|
|
7028
7065
|
});
|
|
7029
7066
|
await server.listen();
|
|
7030
|
-
const hasExistingLogs =
|
|
7031
|
-
const startupDurationString =
|
|
7032
|
-
`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`
|
|
7033
7070
|
);
|
|
7034
7071
|
server.config.logger.info(
|
|
7035
7072
|
`
|
|
7036
|
-
${
|
|
7073
|
+
${pc13.green(`${pc13.bold("VITE")} v${version}`)} ${startupDurationString}
|
|
7037
7074
|
`,
|
|
7038
7075
|
{ clear: !hasExistingLogs }
|
|
7039
7076
|
);
|
|
@@ -7067,10 +7104,10 @@ async function startWatchingTypes(cwd, pb) {
|
|
|
7067
7104
|
// src/commands/build.ts
|
|
7068
7105
|
import fs33 from "node:fs";
|
|
7069
7106
|
import path35 from "node:path";
|
|
7070
|
-
import
|
|
7071
|
-
import { Command as
|
|
7072
|
-
import * as
|
|
7073
|
-
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";
|
|
7074
7111
|
import { x as x3 } from "tinyexec";
|
|
7075
7112
|
import { detect as detect5 } from "package-manager-detector";
|
|
7076
7113
|
import { resolveCommand as resolveCommand5 } from "package-manager-detector/commands";
|
|
@@ -7082,10 +7119,10 @@ function applyBuildEnv(cwd, env2 = process.env) {
|
|
|
7082
7119
|
}
|
|
7083
7120
|
|
|
7084
7121
|
// src/lib/origin.ts
|
|
7085
|
-
import
|
|
7122
|
+
import process23 from "node:process";
|
|
7086
7123
|
function resolveOrigin(workspaceRootDir, envTag, config = {}) {
|
|
7087
7124
|
return normalizeOrigin(
|
|
7088
|
-
|
|
7125
|
+
process23.env.VELA_ORIGIN ?? readBinding(workspaceRootDir, envTag)?.domain ?? config.deploy?.domain
|
|
7089
7126
|
);
|
|
7090
7127
|
}
|
|
7091
7128
|
function normalizeOrigin(value) {
|
|
@@ -7102,13 +7139,13 @@ function normalizeOrigin(value) {
|
|
|
7102
7139
|
|
|
7103
7140
|
// src/commands/build.ts
|
|
7104
7141
|
var PRERENDERED_DIR = path35.join(".svelte-kit", "output", "prerendered");
|
|
7105
|
-
var build = new
|
|
7106
|
-
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();
|
|
7107
7144
|
applyBuildEnv(cwd);
|
|
7108
7145
|
const origin = await originForBuild(cwd, options.target);
|
|
7109
|
-
if (origin)
|
|
7146
|
+
if (origin) process24.env.VELA_ORIGIN = origin;
|
|
7110
7147
|
let pbProc;
|
|
7111
|
-
const needsStart = hasBackend(cwd) && !
|
|
7148
|
+
const needsStart = hasBackend(cwd) && !process24.env.POCKETBASE_URL;
|
|
7112
7149
|
const cleanup = () => {
|
|
7113
7150
|
if (pbProc?.pid) pbProc.kill();
|
|
7114
7151
|
};
|
|
@@ -7122,11 +7159,11 @@ var build = new Command67("build").description("build the app").configureHelp(he
|
|
|
7122
7159
|
dev: true
|
|
7123
7160
|
});
|
|
7124
7161
|
pbProc = started.proc;
|
|
7125
|
-
|
|
7126
|
-
|
|
7127
|
-
|
|
7162
|
+
process24.env.POCKETBASE_URL = started.url;
|
|
7163
|
+
process24.on("exit", cleanup);
|
|
7164
|
+
process24.on("SIGINT", () => {
|
|
7128
7165
|
cleanup();
|
|
7129
|
-
|
|
7166
|
+
process24.exit(0);
|
|
7130
7167
|
});
|
|
7131
7168
|
}
|
|
7132
7169
|
try {
|
|
@@ -7158,26 +7195,26 @@ async function originForBuild(cwd, target) {
|
|
|
7158
7195
|
function warnIfPrerendered(cwd) {
|
|
7159
7196
|
const dir = path35.join(cwd, PRERENDERED_DIR);
|
|
7160
7197
|
if (!fs33.existsSync(dir) || fs33.readdirSync(dir).length === 0) return;
|
|
7161
|
-
|
|
7198
|
+
p33.log.warn(
|
|
7162
7199
|
`Prerendered pages were built with no domain configured, so their canonical
|
|
7163
7200
|
links point at SvelteKit's placeholder host rather than at this site.
|
|
7164
7201
|
|
|
7165
|
-
Set one with ${
|
|
7202
|
+
Set one with ${pc14.cyan("vela deploy --domain example.com")}, or pass ${pc14.cyan("VELA_ORIGIN")}.`
|
|
7166
7203
|
);
|
|
7167
7204
|
}
|
|
7168
7205
|
|
|
7169
7206
|
// src/commands/preview.ts
|
|
7170
7207
|
import path36 from "node:path";
|
|
7171
|
-
import
|
|
7172
|
-
import { Command as
|
|
7208
|
+
import process25 from "node:process";
|
|
7209
|
+
import { Command as Command69 } from "commander";
|
|
7173
7210
|
import { x as x4 } from "tinyexec";
|
|
7174
7211
|
import { detect as detect6 } from "package-manager-detector";
|
|
7175
7212
|
import { resolveCommand as resolveCommand6 } from "package-manager-detector/commands";
|
|
7176
|
-
var preview = new
|
|
7177
|
-
const cwd =
|
|
7178
|
-
|
|
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);
|
|
7179
7216
|
let pbProc;
|
|
7180
|
-
const needsStart = hasBackend(cwd) && !
|
|
7217
|
+
const needsStart = hasBackend(cwd) && !process25.env.POCKETBASE_URL;
|
|
7181
7218
|
const cleanup = () => {
|
|
7182
7219
|
if (pbProc?.pid) pbProc.kill();
|
|
7183
7220
|
};
|
|
@@ -7190,11 +7227,11 @@ var preview = new Command68("preview").description("preview the built app").conf
|
|
|
7190
7227
|
dev: true
|
|
7191
7228
|
});
|
|
7192
7229
|
pbProc = started.proc;
|
|
7193
|
-
|
|
7194
|
-
|
|
7195
|
-
|
|
7230
|
+
process25.env.POCKETBASE_URL = started.url;
|
|
7231
|
+
process25.on("exit", cleanup);
|
|
7232
|
+
process25.on("SIGINT", () => {
|
|
7196
7233
|
cleanup();
|
|
7197
|
-
|
|
7234
|
+
process25.exit(0);
|
|
7198
7235
|
});
|
|
7199
7236
|
}
|
|
7200
7237
|
try {
|
|
@@ -7213,8 +7250,8 @@ var preview = new Command68("preview").description("preview the built app").conf
|
|
|
7213
7250
|
|
|
7214
7251
|
// src/commands/sync.ts
|
|
7215
7252
|
import path37 from "node:path";
|
|
7216
|
-
import { Command as
|
|
7217
|
-
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(
|
|
7218
7255
|
() => runCommand(async () => {
|
|
7219
7256
|
const { workspaceRootDir } = await getWorkspace();
|
|
7220
7257
|
const typesDir = path37.join(workspaceRootDir, ".svelte-kit", "types");
|
|
@@ -7227,9 +7264,9 @@ var sync = new Command69("sync").description("sync types from the database").con
|
|
|
7227
7264
|
);
|
|
7228
7265
|
|
|
7229
7266
|
// src/commands/provision.ts
|
|
7230
|
-
import { Command as
|
|
7231
|
-
import * as
|
|
7232
|
-
import
|
|
7267
|
+
import { Command as Command71 } from "commander";
|
|
7268
|
+
import * as p34 from "@clack/prompts";
|
|
7269
|
+
import pc15 from "picocolors";
|
|
7233
7270
|
import * as v6 from "valibot";
|
|
7234
7271
|
var OptionsSchema2 = v6.object({
|
|
7235
7272
|
...SSH_OPTION_SCHEMA,
|
|
@@ -7237,24 +7274,24 @@ var OptionsSchema2 = v6.object({
|
|
|
7237
7274
|
nodeMajor: v6.optional(v6.string())
|
|
7238
7275
|
});
|
|
7239
7276
|
var provision = addSshOptions(
|
|
7240
|
-
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)
|
|
7241
7278
|
).option("--pb-version <version>", "PocketBase version to install").option("--node-major <version>", "Node.js major version to install", "22").action(
|
|
7242
7279
|
(target, raw) => runCommand(async () => {
|
|
7243
7280
|
const options = parseOptions(OptionsSchema2, raw);
|
|
7244
7281
|
const pbVersion = options.pbVersion ?? pocketbaseVersion();
|
|
7245
|
-
|
|
7246
|
-
|
|
7282
|
+
p34.intro(pc15.bgCyan(pc15.black(" vela provision ")));
|
|
7283
|
+
p34.log.info(`Target ${pc15.cyan(target)}`);
|
|
7247
7284
|
await withSsh(target, sshOptionsFrom(options), async (session) => {
|
|
7248
7285
|
await session.detectElevation();
|
|
7249
7286
|
const existing = await readServerInfo(session);
|
|
7250
7287
|
if (existing) {
|
|
7251
|
-
|
|
7288
|
+
p34.log.info(
|
|
7252
7289
|
`Already provisioned by vela ${existing.cliVersion} on ${existing.provisionedAt}. Bringing it up to date.`
|
|
7253
7290
|
);
|
|
7254
7291
|
}
|
|
7255
|
-
|
|
7292
|
+
p34.log.step("Uploading server scripts");
|
|
7256
7293
|
await syncServerScripts(session);
|
|
7257
|
-
|
|
7294
|
+
p34.log.step("Running provision");
|
|
7258
7295
|
const result = await runServerScript(session, "provision.sh", {
|
|
7259
7296
|
args: [
|
|
7260
7297
|
"--pb-version",
|
|
@@ -7266,7 +7303,7 @@ var provision = addSshOptions(
|
|
|
7266
7303
|
],
|
|
7267
7304
|
stream: true
|
|
7268
7305
|
});
|
|
7269
|
-
|
|
7306
|
+
p34.log.success(
|
|
7270
7307
|
`${target} is ready.
|
|
7271
7308
|
|
|
7272
7309
|
Node ${result?.node ?? "installed"}
|
|
@@ -7274,29 +7311,29 @@ var provision = addSshOptions(
|
|
|
7274
7311
|
PocketBase ${result?.pocketbase ?? pbVersion}`
|
|
7275
7312
|
);
|
|
7276
7313
|
});
|
|
7277
|
-
|
|
7314
|
+
p34.outro(`Deploy with ${pc15.cyan(`vela deploy --server ${target}`)}`);
|
|
7278
7315
|
}, "Failed to provision.")
|
|
7279
7316
|
);
|
|
7280
7317
|
|
|
7281
7318
|
// src/commands/deploy.ts
|
|
7282
7319
|
import path40 from "node:path";
|
|
7283
7320
|
import fs36 from "node:fs";
|
|
7284
|
-
import { Command as
|
|
7285
|
-
import * as
|
|
7286
|
-
import
|
|
7321
|
+
import { Command as Command72, Option as Option2 } from "commander";
|
|
7322
|
+
import * as p35 from "@clack/prompts";
|
|
7323
|
+
import pc16 from "picocolors";
|
|
7287
7324
|
import * as v7 from "valibot";
|
|
7288
7325
|
|
|
7289
7326
|
// src/lib/pocketbase-settings.ts
|
|
7290
7327
|
import fs34 from "node:fs";
|
|
7291
7328
|
import path38 from "node:path";
|
|
7292
|
-
import
|
|
7329
|
+
import process26 from "node:process";
|
|
7293
7330
|
import PocketBase4 from "pocketbase";
|
|
7294
7331
|
var COPIED_KEYS = ["appName", "senderName", "senderAddress"];
|
|
7295
7332
|
async function readLocalMeta(cwd) {
|
|
7296
7333
|
const dataDir = path38.join(cwd, DATA_DIR);
|
|
7297
7334
|
if (!fs34.existsSync(dataDir)) return null;
|
|
7298
|
-
const email3 =
|
|
7299
|
-
const password11 =
|
|
7335
|
+
const email3 = process26.env.POCKETBASE_SUPERUSER_EMAIL;
|
|
7336
|
+
const password11 = process26.env.POCKETBASE_SUPERUSER_PASSWORD;
|
|
7300
7337
|
if (!email3 || !password11) return null;
|
|
7301
7338
|
let proc;
|
|
7302
7339
|
try {
|
|
@@ -7423,7 +7460,7 @@ var OptionsSchema3 = v7.object({
|
|
|
7423
7460
|
build: v7.optional(v7.boolean())
|
|
7424
7461
|
});
|
|
7425
7462
|
var deploy = addTargetOptions(
|
|
7426
|
-
new
|
|
7463
|
+
new Command72("deploy").description("deploy the app").configureHelp(helpConfig),
|
|
7427
7464
|
"production"
|
|
7428
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(
|
|
7429
7466
|
new Option2(
|
|
@@ -7439,14 +7476,14 @@ var deploy = addTargetOptions(
|
|
|
7439
7476
|
const options = parseOptions(OptionsSchema3, raw);
|
|
7440
7477
|
const backend3 = hasBackend();
|
|
7441
7478
|
const release = releaseId();
|
|
7442
|
-
|
|
7479
|
+
p35.intro(pc16.bgCyan(pc16.black(" vela deploy ")));
|
|
7443
7480
|
await withTarget(
|
|
7444
7481
|
raw,
|
|
7445
7482
|
{
|
|
7446
7483
|
remote: async (ctx) => {
|
|
7447
7484
|
const { session, instance, workspaceRootDir, config } = ctx;
|
|
7448
|
-
|
|
7449
|
-
`${
|
|
7485
|
+
p35.log.info(
|
|
7486
|
+
`${pc16.cyan(ctx.appName)} ${pc16.dim("\u2192")} ${pc16.cyan(ctx.targetName)} ${pc16.dim(`(${ctx.server})`)}`
|
|
7450
7487
|
);
|
|
7451
7488
|
const [existing] = await readInstanceStates(session, instance);
|
|
7452
7489
|
const domain = options.domain ?? ctx.binding.domain ?? config.deploy?.domain ?? existing?.domain ?? "";
|
|
@@ -7461,21 +7498,21 @@ var deploy = addTargetOptions(
|
|
|
7461
7498
|
tunnel = await openDatabaseTunnel(session, instance, existing);
|
|
7462
7499
|
} catch (err) {
|
|
7463
7500
|
if (askedForRemoteDb) throw err;
|
|
7464
|
-
|
|
7465
|
-
`Could not build against the ${
|
|
7466
|
-
${
|
|
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))}`
|
|
7467
7504
|
);
|
|
7468
7505
|
}
|
|
7469
7506
|
}
|
|
7470
7507
|
if (tunnel) {
|
|
7471
7508
|
buildEnv = { ...buildEnv, ...tunnel.env };
|
|
7472
|
-
|
|
7473
|
-
`Building against the ${
|
|
7509
|
+
p35.log.info(
|
|
7510
|
+
`Building against the ${pc16.cyan(ctx.targetName)} database on ${ctx.server} ${pc16.dim(`(port ${tunnel.pbPort})`)}`
|
|
7474
7511
|
);
|
|
7475
7512
|
} else if (backend3) {
|
|
7476
7513
|
await ensureSuperuser(workspaceRootDir);
|
|
7477
7514
|
}
|
|
7478
|
-
|
|
7515
|
+
p35.log.step("Building");
|
|
7479
7516
|
try {
|
|
7480
7517
|
await runBuild(workspaceRootDir, config.deploy?.buildCommand, buildEnv);
|
|
7481
7518
|
} finally {
|
|
@@ -7484,9 +7521,9 @@ ${pc15.dim(String(err))}`
|
|
|
7484
7521
|
}
|
|
7485
7522
|
const entries = collectArtifact(workspaceRootDir, config.deploy ?? {});
|
|
7486
7523
|
const sha = await gitSha(workspaceRootDir);
|
|
7487
|
-
|
|
7524
|
+
p35.log.step(`Uploading release ${pc16.dim(release)}`);
|
|
7488
7525
|
await uploadRelease(session, instance, release, entries);
|
|
7489
|
-
|
|
7526
|
+
p35.log.step("Activating");
|
|
7490
7527
|
const result = await runServerScript(session, "apply.sh", {
|
|
7491
7528
|
args: [
|
|
7492
7529
|
instance,
|
|
@@ -7518,8 +7555,8 @@ ${pc15.dim(String(err))}`
|
|
|
7518
7555
|
});
|
|
7519
7556
|
if (!existing) await reportEmptyEnvironment(session, instance, workspaceRootDir);
|
|
7520
7557
|
const url = result?.url ?? "";
|
|
7521
|
-
|
|
7522
|
-
`Deployed ${
|
|
7558
|
+
p35.log.success(
|
|
7559
|
+
`Deployed ${pc16.cyan(ctx.appName)} ${pc16.dim(release)}
|
|
7523
7560
|
|
|
7524
7561
|
URL ${url}
|
|
7525
7562
|
Port ${result?.webPort ?? "?"}${backend3 ? ` (PocketBase ${result?.pbPort ?? "?"})` : ""}`
|
|
@@ -7531,27 +7568,27 @@ ${pc15.dim(String(err))}`
|
|
|
7531
7568
|
workspaceRootDir,
|
|
7532
7569
|
domain ? result?.url ?? "" : ""
|
|
7533
7570
|
);
|
|
7534
|
-
|
|
7571
|
+
p35.log.info(
|
|
7535
7572
|
`Created the PocketBase superuser this app authenticates as.
|
|
7536
7573
|
|
|
7537
7574
|
Its credentials are stored in the environment on the server. To use
|
|
7538
|
-
your own instead, ${
|
|
7575
|
+
your own instead, ${pc16.cyan("vela env set POCKETBASE_SUPERUSER_PASSWORD")}
|
|
7539
7576
|
and deploy again.`
|
|
7540
7577
|
);
|
|
7541
7578
|
} else if (backend3 && domain) {
|
|
7542
7579
|
await reportAppURLDrift(session, instance, domain);
|
|
7543
7580
|
}
|
|
7544
7581
|
if (!domain) {
|
|
7545
|
-
|
|
7582
|
+
p35.log.warn(
|
|
7546
7583
|
`No domain configured, so nothing is proxied to this app yet.
|
|
7547
|
-
Redeploy with ${
|
|
7584
|
+
Redeploy with ${pc16.cyan("--domain example.com")} once DNS points at ${ctx.server}.`
|
|
7548
7585
|
);
|
|
7549
7586
|
}
|
|
7550
7587
|
}
|
|
7551
7588
|
},
|
|
7552
7589
|
{ project: options.project, askDomain: true, label: "deploy" }
|
|
7553
7590
|
);
|
|
7554
|
-
|
|
7591
|
+
p35.outro(`${pc16.cyan("vela status")} to see what is running`);
|
|
7555
7592
|
}, "Failed to deploy.")
|
|
7556
7593
|
);
|
|
7557
7594
|
async function reportAppURLDrift(session, instance, domain) {
|
|
@@ -7559,8 +7596,8 @@ async function reportAppURLDrift(session, instance, domain) {
|
|
|
7559
7596
|
if (!expected) return;
|
|
7560
7597
|
const current = await readRemoteAppURL(session, instance);
|
|
7561
7598
|
if (!current || normalizeOrigin(current) === expected) return;
|
|
7562
|
-
|
|
7563
|
-
`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)}.
|
|
7564
7601
|
|
|
7565
7602
|
Emails and anything else PocketBase links to will use the former. Update it in
|
|
7566
7603
|
the admin panel if that is not deliberate.`
|
|
@@ -7574,17 +7611,17 @@ async function copyLocalBranding(session, instance, workspaceRootDir, appURL) {
|
|
|
7574
7611
|
if (copied.length === 0) return;
|
|
7575
7612
|
const outcome = await restartInstance(session, instance);
|
|
7576
7613
|
if (outcome.deployed && !outcome.restarted) {
|
|
7577
|
-
|
|
7614
|
+
p35.log.warn(
|
|
7578
7615
|
`Copied ${copied.join(", ")}, but the app did not restart to pick them up.
|
|
7579
|
-
${
|
|
7616
|
+
${pc16.dim(outcome.error ?? "")}`
|
|
7580
7617
|
);
|
|
7581
7618
|
return;
|
|
7582
7619
|
}
|
|
7583
|
-
|
|
7620
|
+
p35.log.success(`Copied ${copied.join(", ")} from this project's database`);
|
|
7584
7621
|
} catch (err) {
|
|
7585
|
-
|
|
7622
|
+
p35.log.warn(
|
|
7586
7623
|
`Could not copy this project's PocketBase settings across.
|
|
7587
|
-
Set them in the admin panel instead. ${
|
|
7624
|
+
Set them in the admin panel instead. ${pc16.dim(String(err))}`
|
|
7588
7625
|
);
|
|
7589
7626
|
}
|
|
7590
7627
|
}
|
|
@@ -7616,13 +7653,13 @@ Set them with \`vela env set POCKETBASE_SUPERUSER_EMAIL\` and \`vela env set POC
|
|
|
7616
7653
|
|
|
7617
7654
|
They are what \`--remote-db\` renders the build as. The usual cause is a password
|
|
7618
7655
|
changed in the PocketBase admin panel, which leaves the database and
|
|
7619
|
-
${
|
|
7656
|
+
${pc16.cyan(`/etc/vela/apps/${instance}/env`)} disagreeing.
|
|
7620
7657
|
|
|
7621
7658
|
Point the environment at the password the database has:
|
|
7622
|
-
${
|
|
7659
|
+
${pc16.cyan("vela env set POCKETBASE_SUPERUSER_PASSWORD")}
|
|
7623
7660
|
|
|
7624
7661
|
or build against a throwaway local database instead:
|
|
7625
|
-
${
|
|
7662
|
+
${pc16.cyan("vela deploy --no-remote-db")}`
|
|
7626
7663
|
);
|
|
7627
7664
|
}
|
|
7628
7665
|
return {
|
|
@@ -7675,19 +7712,19 @@ async function reportEmptyEnvironment(session, instance, workspaceRootDir) {
|
|
|
7675
7712
|
const remote = await readRemoteEnv(session, instance);
|
|
7676
7713
|
if (Object.keys(remote).length > 0) return;
|
|
7677
7714
|
if (!fs36.existsSync(path40.join(workspaceRootDir, ".env"))) return;
|
|
7678
|
-
|
|
7715
|
+
p35.log.warn(
|
|
7679
7716
|
`This app has no production environment variables yet.
|
|
7680
7717
|
|
|
7681
|
-
Local ${
|
|
7682
|
-
${
|
|
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")}.`
|
|
7683
7720
|
);
|
|
7684
7721
|
}
|
|
7685
7722
|
|
|
7686
7723
|
// src/commands/link.ts
|
|
7687
7724
|
import path41 from "node:path";
|
|
7688
|
-
import
|
|
7689
|
-
import { Command as
|
|
7690
|
-
import * as
|
|
7725
|
+
import process27 from "node:process";
|
|
7726
|
+
import { Command as Command73 } from "commander";
|
|
7727
|
+
import * as p36 from "@clack/prompts";
|
|
7691
7728
|
|
|
7692
7729
|
// src/lib/velastack-api.ts
|
|
7693
7730
|
async function apiFetch(apiKey, pathAndQuery, init) {
|
|
@@ -7738,12 +7775,12 @@ async function createProject2(apiKey, args) {
|
|
|
7738
7775
|
|
|
7739
7776
|
// src/commands/link.ts
|
|
7740
7777
|
var CREATE_NEW = "__new__";
|
|
7741
|
-
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."));
|
|
7742
7779
|
async function linkProject() {
|
|
7743
7780
|
const { workspaceRootDir } = await getWorkspace();
|
|
7744
7781
|
const existing = readProjectConfig(workspaceRootDir);
|
|
7745
7782
|
if (existing) {
|
|
7746
|
-
|
|
7783
|
+
p36.log.success(`Linked to ${existing.projectName}.`);
|
|
7747
7784
|
return;
|
|
7748
7785
|
}
|
|
7749
7786
|
const apiKey = requireApiKey();
|
|
@@ -7770,10 +7807,10 @@ async function linkProject() {
|
|
|
7770
7807
|
projectName = created.name;
|
|
7771
7808
|
}
|
|
7772
7809
|
writeProjectConfig(workspaceRootDir, { projectId, teamId, projectName });
|
|
7773
|
-
|
|
7810
|
+
p36.log.success(`Linked to ${projectName}.`);
|
|
7774
7811
|
}
|
|
7775
7812
|
async function pickExistingProject(projects) {
|
|
7776
|
-
const choice = await
|
|
7813
|
+
const choice = await p36.select({
|
|
7777
7814
|
message: "Select a project",
|
|
7778
7815
|
options: [
|
|
7779
7816
|
...projects.map((pr) => ({
|
|
@@ -7783,39 +7820,39 @@ async function pickExistingProject(projects) {
|
|
|
7783
7820
|
{ value: CREATE_NEW, label: "Create a new project" }
|
|
7784
7821
|
]
|
|
7785
7822
|
});
|
|
7786
|
-
if (
|
|
7787
|
-
|
|
7788
|
-
|
|
7823
|
+
if (p36.isCancel(choice)) {
|
|
7824
|
+
p36.cancel("Operation cancelled.");
|
|
7825
|
+
process27.exit(0);
|
|
7789
7826
|
}
|
|
7790
7827
|
return choice;
|
|
7791
7828
|
}
|
|
7792
7829
|
async function pickTeam(teams3) {
|
|
7793
7830
|
if (teams3.length === 1) return teams3[0];
|
|
7794
|
-
const choice = await
|
|
7831
|
+
const choice = await p36.select({
|
|
7795
7832
|
message: "Select a team",
|
|
7796
7833
|
options: teams3.map((team) => ({
|
|
7797
7834
|
value: team.id,
|
|
7798
7835
|
label: team.is_personal ? `${team.name} (personal)` : team.name
|
|
7799
7836
|
}))
|
|
7800
7837
|
});
|
|
7801
|
-
if (
|
|
7802
|
-
|
|
7803
|
-
|
|
7838
|
+
if (p36.isCancel(choice)) {
|
|
7839
|
+
p36.cancel("Operation cancelled.");
|
|
7840
|
+
process27.exit(0);
|
|
7804
7841
|
}
|
|
7805
7842
|
return teams3.find((team) => team.id === choice);
|
|
7806
7843
|
}
|
|
7807
7844
|
async function promptProjectName(workspaceRootDir) {
|
|
7808
7845
|
const defaultValue = defaultProjectName2(workspaceRootDir);
|
|
7809
|
-
const value = await
|
|
7846
|
+
const value = await p36.text({
|
|
7810
7847
|
message: "Project name",
|
|
7811
7848
|
defaultValue,
|
|
7812
7849
|
initialValue: defaultValue,
|
|
7813
7850
|
placeholder: defaultValue,
|
|
7814
7851
|
validate: (v9) => !v9?.trim() ? "Required" : void 0
|
|
7815
7852
|
});
|
|
7816
|
-
if (
|
|
7817
|
-
|
|
7818
|
-
|
|
7853
|
+
if (p36.isCancel(value)) {
|
|
7854
|
+
p36.cancel("Operation cancelled.");
|
|
7855
|
+
process27.exit(0);
|
|
7819
7856
|
}
|
|
7820
7857
|
return value.trim();
|
|
7821
7858
|
}
|
|
@@ -7830,14 +7867,14 @@ function defaultProjectName2(workspaceRootDir) {
|
|
|
7830
7867
|
}
|
|
7831
7868
|
|
|
7832
7869
|
// src/commands/env.ts
|
|
7833
|
-
import { Command as
|
|
7870
|
+
import { Command as Command78 } from "commander";
|
|
7834
7871
|
|
|
7835
7872
|
// src/commands/env/list.ts
|
|
7836
|
-
import { Command as
|
|
7837
|
-
import * as
|
|
7838
|
-
import
|
|
7873
|
+
import { Command as Command74 } from "commander";
|
|
7874
|
+
import * as p37 from "@clack/prompts";
|
|
7875
|
+
import pc17 from "picocolors";
|
|
7839
7876
|
var envList = addTargetOptions(
|
|
7840
|
-
new
|
|
7877
|
+
new Command74("list").description("list environment variable names").configureHelp(helpConfig),
|
|
7841
7878
|
"local"
|
|
7842
7879
|
).action(
|
|
7843
7880
|
(raw) => runCommand(
|
|
@@ -7859,23 +7896,23 @@ var envList = addTargetOptions(
|
|
|
7859
7896
|
);
|
|
7860
7897
|
function report(keys, where) {
|
|
7861
7898
|
if (keys.length === 0) {
|
|
7862
|
-
|
|
7899
|
+
p37.log.info(`No environment variables configured ${pc17.dim(`(${where})`)}.`);
|
|
7863
7900
|
return;
|
|
7864
7901
|
}
|
|
7865
|
-
|
|
7866
|
-
`Environment ${
|
|
7902
|
+
p37.log.info(
|
|
7903
|
+
`Environment ${pc17.dim(`(${where})`)}
|
|
7867
7904
|
|
|
7868
7905
|
` + keys.sort().map((key) => ` ${key}`).join("\n")
|
|
7869
7906
|
);
|
|
7870
7907
|
}
|
|
7871
7908
|
|
|
7872
7909
|
// src/commands/env/set.ts
|
|
7873
|
-
import
|
|
7874
|
-
import { Command as
|
|
7875
|
-
import * as
|
|
7876
|
-
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";
|
|
7877
7914
|
var envSet = addTargetOptions(
|
|
7878
|
-
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),
|
|
7879
7916
|
"local"
|
|
7880
7917
|
).action(
|
|
7881
7918
|
(key, value, raw) => runCommand(
|
|
@@ -7885,14 +7922,14 @@ var envSet = addTargetOptions(
|
|
|
7885
7922
|
local: async (ctx) => {
|
|
7886
7923
|
const resolved = await resolveValue(key, value);
|
|
7887
7924
|
setLocalEnv(ctx.envFile, key, resolved);
|
|
7888
|
-
|
|
7925
|
+
p38.log.success(`${key} updated ${pc18.dim("(local)")}`);
|
|
7889
7926
|
await applyLocalEnvChange(ctx, [key]);
|
|
7890
7927
|
},
|
|
7891
7928
|
remote: async (ctx) => {
|
|
7892
7929
|
const resolved = await resolveValue(key, value);
|
|
7893
7930
|
const env2 = await readRemoteEnv(ctx.session, ctx.instance);
|
|
7894
7931
|
await writeRemoteEnv(ctx.session, ctx.instance, { ...env2, [key]: resolved });
|
|
7895
|
-
|
|
7932
|
+
p38.log.success(`${key} updated ${pc18.dim(`(${ctx.targetName})`)}`);
|
|
7896
7933
|
await applyEnvRestart(ctx, [key]);
|
|
7897
7934
|
}
|
|
7898
7935
|
},
|
|
@@ -7906,23 +7943,23 @@ async function resolveValue(key, value) {
|
|
|
7906
7943
|
return value ?? await promptValue(key);
|
|
7907
7944
|
}
|
|
7908
7945
|
async function promptValue(key) {
|
|
7909
|
-
const value = await
|
|
7910
|
-
message: `Value for ${
|
|
7946
|
+
const value = await p38.password({
|
|
7947
|
+
message: `Value for ${pc18.cyan(key)}`,
|
|
7911
7948
|
validate: (input) => !input?.length ? "Required" : void 0
|
|
7912
7949
|
});
|
|
7913
|
-
if (
|
|
7914
|
-
|
|
7915
|
-
|
|
7950
|
+
if (p38.isCancel(value)) {
|
|
7951
|
+
p38.cancel("Operation cancelled.");
|
|
7952
|
+
process28.exit(0);
|
|
7916
7953
|
}
|
|
7917
7954
|
return value;
|
|
7918
7955
|
}
|
|
7919
7956
|
|
|
7920
7957
|
// src/commands/env/unset.ts
|
|
7921
|
-
import { Command as
|
|
7922
|
-
import * as
|
|
7923
|
-
import
|
|
7958
|
+
import { Command as Command76 } from "commander";
|
|
7959
|
+
import * as p39 from "@clack/prompts";
|
|
7960
|
+
import pc19 from "picocolors";
|
|
7924
7961
|
var envUnset = addTargetOptions(
|
|
7925
|
-
new
|
|
7962
|
+
new Command76("unset").description("remove an environment variable").argument("<key>", "variable name").configureHelp(helpConfig),
|
|
7926
7963
|
"local"
|
|
7927
7964
|
).action(
|
|
7928
7965
|
(key, raw) => runCommand(
|
|
@@ -7931,22 +7968,22 @@ var envUnset = addTargetOptions(
|
|
|
7931
7968
|
{
|
|
7932
7969
|
local: async (ctx) => {
|
|
7933
7970
|
if (!(key in readLocalEnv(ctx.envFile))) {
|
|
7934
|
-
|
|
7971
|
+
p39.log.info(`${key} is not set \u2014 nothing to remove.`);
|
|
7935
7972
|
return;
|
|
7936
7973
|
}
|
|
7937
7974
|
unsetLocalEnv(ctx.envFile, key);
|
|
7938
|
-
|
|
7975
|
+
p39.log.success(`${key} removed ${pc19.dim("(local)")}`);
|
|
7939
7976
|
await applyLocalEnvChange(ctx, [key]);
|
|
7940
7977
|
},
|
|
7941
7978
|
remote: async (ctx) => {
|
|
7942
7979
|
const env2 = await readRemoteEnv(ctx.session, ctx.instance);
|
|
7943
7980
|
if (!(key in env2)) {
|
|
7944
|
-
|
|
7981
|
+
p39.log.info(`${key} is not set \u2014 nothing to remove.`);
|
|
7945
7982
|
return;
|
|
7946
7983
|
}
|
|
7947
7984
|
delete env2[key];
|
|
7948
7985
|
await writeRemoteEnv(ctx.session, ctx.instance, env2);
|
|
7949
|
-
|
|
7986
|
+
p39.log.success(`${key} removed ${pc19.dim(`(${ctx.targetName})`)}`);
|
|
7950
7987
|
await applyEnvRestart(ctx, [key]);
|
|
7951
7988
|
}
|
|
7952
7989
|
},
|
|
@@ -7959,12 +7996,12 @@ var envUnset = addTargetOptions(
|
|
|
7959
7996
|
// src/commands/env/import.ts
|
|
7960
7997
|
import fs37 from "node:fs";
|
|
7961
7998
|
import path42 from "node:path";
|
|
7962
|
-
import
|
|
7963
|
-
import { Command as
|
|
7964
|
-
import * as
|
|
7965
|
-
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";
|
|
7966
8003
|
var envImport = addTargetOptions(
|
|
7967
|
-
new
|
|
8004
|
+
new Command77("import").description("merge a dotenv file into the environment").argument("<file>", "dotenv file to read").configureHelp(helpConfig),
|
|
7968
8005
|
"local"
|
|
7969
8006
|
).action(
|
|
7970
8007
|
(file, raw) => runCommand(
|
|
@@ -7979,22 +8016,22 @@ var envImport = addTargetOptions(
|
|
|
7979
8016
|
const incoming = read(source, file);
|
|
7980
8017
|
const keys = Object.keys(incoming);
|
|
7981
8018
|
if (keys.length === 0) return;
|
|
7982
|
-
|
|
8019
|
+
p40.log.step(`Importing ${keys.length} variable(s) from ${pc20.cyan(file)}`);
|
|
7983
8020
|
editLocalEnv(
|
|
7984
8021
|
ctx.envFile,
|
|
7985
8022
|
(content) => keys.reduce((acc, key) => upsertEnvVar(acc, key, incoming[key]), content)
|
|
7986
8023
|
);
|
|
7987
|
-
|
|
8024
|
+
p40.log.success(`${keys.length} variable(s) updated ${pc20.dim("(local)")}`);
|
|
7988
8025
|
await applyLocalEnvChange(ctx, keys);
|
|
7989
8026
|
},
|
|
7990
8027
|
remote: async (ctx) => {
|
|
7991
8028
|
const incoming = read(resolve(file), file);
|
|
7992
8029
|
const keys = Object.keys(incoming);
|
|
7993
8030
|
if (keys.length === 0) return;
|
|
7994
|
-
|
|
8031
|
+
p40.log.step(`Importing ${keys.length} variable(s) from ${pc20.cyan(file)}`);
|
|
7995
8032
|
const existing = await readRemoteEnv(ctx.session, ctx.instance);
|
|
7996
8033
|
await writeRemoteEnv(ctx.session, ctx.instance, { ...existing, ...incoming });
|
|
7997
|
-
|
|
8034
|
+
p40.log.success(`${keys.length} variable(s) updated ${pc20.dim(`(${ctx.targetName})`)}`);
|
|
7998
8035
|
await applyEnvRestart(ctx, keys);
|
|
7999
8036
|
}
|
|
8000
8037
|
},
|
|
@@ -8004,24 +8041,24 @@ var envImport = addTargetOptions(
|
|
|
8004
8041
|
)
|
|
8005
8042
|
);
|
|
8006
8043
|
function resolve(file) {
|
|
8007
|
-
return path42.resolve(
|
|
8044
|
+
return path42.resolve(process29.cwd(), file);
|
|
8008
8045
|
}
|
|
8009
8046
|
function read(resolved, shown) {
|
|
8010
8047
|
if (!fs37.existsSync(resolved)) throw new Error(`${shown} does not exist.`);
|
|
8011
8048
|
const incoming = readLocalEnvFile(resolved);
|
|
8012
|
-
if (Object.keys(incoming).length === 0)
|
|
8049
|
+
if (Object.keys(incoming).length === 0) p40.log.info(`${shown} has no variables to import.`);
|
|
8013
8050
|
return incoming;
|
|
8014
8051
|
}
|
|
8015
8052
|
|
|
8016
8053
|
// src/commands/env.ts
|
|
8017
|
-
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);
|
|
8018
8055
|
|
|
8019
8056
|
// src/commands/status.ts
|
|
8020
|
-
import { Command as
|
|
8021
|
-
import * as
|
|
8022
|
-
import
|
|
8057
|
+
import { Command as Command79 } from "commander";
|
|
8058
|
+
import * as p41 from "@clack/prompts";
|
|
8059
|
+
import pc21 from "picocolors";
|
|
8023
8060
|
var status = addTargetOptions(
|
|
8024
|
-
new
|
|
8061
|
+
new Command79("status").description("show what is deployed").configureHelp(helpConfig),
|
|
8025
8062
|
"production"
|
|
8026
8063
|
).option("--all", "show every app on the server, not just this project").option("--json", "print raw JSON").action(
|
|
8027
8064
|
(raw) => runCommand(async () => {
|
|
@@ -8052,15 +8089,15 @@ function report2(states, json) {
|
|
|
8052
8089
|
return;
|
|
8053
8090
|
}
|
|
8054
8091
|
if (states.length === 0) {
|
|
8055
|
-
|
|
8092
|
+
p41.log.info("Nothing is deployed here yet.");
|
|
8056
8093
|
return;
|
|
8057
8094
|
}
|
|
8058
8095
|
for (const state of states) {
|
|
8059
|
-
|
|
8096
|
+
p41.log.info(describe(state));
|
|
8060
8097
|
}
|
|
8061
8098
|
}
|
|
8062
8099
|
function describe(state) {
|
|
8063
|
-
const health = (value) => value === "active" ?
|
|
8100
|
+
const health = (value) => value === "active" ? pc21.green(value) : pc21.red(value || "inactive");
|
|
8064
8101
|
const rows = [
|
|
8065
8102
|
["Instance", state.instance],
|
|
8066
8103
|
["Environment", state.env],
|
|
@@ -8075,15 +8112,15 @@ function describe(state) {
|
|
|
8075
8112
|
...state.gitSha ? [["Commit", state.gitSha.slice(0, 12)]] : []
|
|
8076
8113
|
];
|
|
8077
8114
|
const width = Math.max(...rows.map(([label3]) => label3.length));
|
|
8078
|
-
return
|
|
8115
|
+
return pc21.cyan(state.name) + "\n\n" + rows.map(([label3, value]) => ` ${label3.padEnd(width)} ${value}`).join("\n");
|
|
8079
8116
|
}
|
|
8080
8117
|
|
|
8081
8118
|
// src/commands/rollback.ts
|
|
8082
|
-
import { Command as
|
|
8083
|
-
import * as
|
|
8084
|
-
import
|
|
8119
|
+
import { Command as Command80 } from "commander";
|
|
8120
|
+
import * as p42 from "@clack/prompts";
|
|
8121
|
+
import pc22 from "picocolors";
|
|
8085
8122
|
var rollback = addTargetOptions(
|
|
8086
|
-
new
|
|
8123
|
+
new Command80("rollback").description("put the previous release back").configureHelp(helpConfig),
|
|
8087
8124
|
"production"
|
|
8088
8125
|
).option("--to <release>", "roll back to a specific release instead of the previous one").action(
|
|
8089
8126
|
(raw) => runCommand(async () => {
|
|
@@ -8092,8 +8129,8 @@ var rollback = addTargetOptions(
|
|
|
8092
8129
|
raw,
|
|
8093
8130
|
{
|
|
8094
8131
|
remote: async (ctx) => {
|
|
8095
|
-
|
|
8096
|
-
`Rolling back ${
|
|
8132
|
+
p42.log.step(
|
|
8133
|
+
`Rolling back ${pc22.cyan(ctx.appName)} ${pc22.dim(`(${ctx.targetName})`)} on ${ctx.server}`
|
|
8097
8134
|
);
|
|
8098
8135
|
const result = await runServerScript(
|
|
8099
8136
|
ctx.session,
|
|
@@ -8103,8 +8140,8 @@ var rollback = addTargetOptions(
|
|
|
8103
8140
|
stream: true
|
|
8104
8141
|
}
|
|
8105
8142
|
);
|
|
8106
|
-
|
|
8107
|
-
`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})`)}` : "")
|
|
8108
8145
|
);
|
|
8109
8146
|
}
|
|
8110
8147
|
},
|
|
@@ -8117,9 +8154,9 @@ var rollback = addTargetOptions(
|
|
|
8117
8154
|
);
|
|
8118
8155
|
|
|
8119
8156
|
// src/commands/logs.ts
|
|
8120
|
-
import { Command as
|
|
8157
|
+
import { Command as Command81 } from "commander";
|
|
8121
8158
|
var logs = addTargetOptions(
|
|
8122
|
-
new
|
|
8159
|
+
new Command81("logs").description("tail the logs of a deployed app").configureHelp(helpConfig),
|
|
8123
8160
|
"production"
|
|
8124
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(
|
|
8125
8162
|
(raw) => runCommand(async () => {
|
|
@@ -8153,16 +8190,16 @@ var logs = addTargetOptions(
|
|
|
8153
8190
|
);
|
|
8154
8191
|
|
|
8155
8192
|
// src/commands/admin.ts
|
|
8156
|
-
import { Command as
|
|
8193
|
+
import { Command as Command83 } from "commander";
|
|
8157
8194
|
|
|
8158
8195
|
// src/commands/admin/create.ts
|
|
8159
|
-
import
|
|
8160
|
-
import { Command as
|
|
8161
|
-
import * as
|
|
8162
|
-
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";
|
|
8163
8200
|
var MIN_PASSWORD = 10;
|
|
8164
8201
|
var adminCreate = addTargetOptions(
|
|
8165
|
-
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),
|
|
8166
8203
|
"local"
|
|
8167
8204
|
).action(
|
|
8168
8205
|
(email3, raw) => runCommand(
|
|
@@ -8190,8 +8227,8 @@ var adminCreate = addTargetOptions(
|
|
|
8190
8227
|
const metadata = getPocketbaseMetadata(ctx.workspaceRootDir);
|
|
8191
8228
|
if (metadata) signIn = `http://${metadata.viteHost}:${metadata.vitePort}`;
|
|
8192
8229
|
}
|
|
8193
|
-
|
|
8194
|
-
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.`
|
|
8195
8232
|
);
|
|
8196
8233
|
},
|
|
8197
8234
|
remote: async (ctx) => {
|
|
@@ -8204,8 +8241,8 @@ var adminCreate = addTargetOptions(
|
|
|
8204
8241
|
(pb) => upsertSuperuser(pb, address, password11)
|
|
8205
8242
|
);
|
|
8206
8243
|
const base2 = state?.domain ? `https://${state.domain.split(",")[0].trim()}` : "";
|
|
8207
|
-
|
|
8208
|
-
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.`
|
|
8209
8246
|
);
|
|
8210
8247
|
}
|
|
8211
8248
|
},
|
|
@@ -8217,20 +8254,20 @@ var adminCreate = addTargetOptions(
|
|
|
8217
8254
|
async function upsertSuperuser(pb, email3, password11) {
|
|
8218
8255
|
const existing = await findSuperuser(pb, email3);
|
|
8219
8256
|
if (existing) {
|
|
8220
|
-
const confirmed = await
|
|
8257
|
+
const confirmed = await p43.confirm({
|
|
8221
8258
|
message: `${email3} already has an account, update its password?`,
|
|
8222
8259
|
initialValue: false
|
|
8223
8260
|
});
|
|
8224
|
-
if (
|
|
8225
|
-
|
|
8226
|
-
|
|
8261
|
+
if (p43.isCancel(confirmed) || !confirmed) {
|
|
8262
|
+
p43.cancel("Operation cancelled.");
|
|
8263
|
+
process30.exit(0);
|
|
8227
8264
|
}
|
|
8228
8265
|
await pb.collection("_superusers").update(existing, { password: password11, passwordConfirm: password11 });
|
|
8229
|
-
|
|
8266
|
+
p43.log.success(`Password updated for ${pc23.cyan(email3)}, you can sign in now`);
|
|
8230
8267
|
return;
|
|
8231
8268
|
}
|
|
8232
8269
|
await pb.collection("_superusers").create({ email: email3, password: password11, passwordConfirm: password11 });
|
|
8233
|
-
|
|
8270
|
+
p43.log.success(`${pc23.cyan(email3)} can now sign in`);
|
|
8234
8271
|
}
|
|
8235
8272
|
async function findSuperuser(pb, email3) {
|
|
8236
8273
|
try {
|
|
@@ -8241,48 +8278,48 @@ async function findSuperuser(pb, email3) {
|
|
|
8241
8278
|
}
|
|
8242
8279
|
}
|
|
8243
8280
|
async function promptEmail() {
|
|
8244
|
-
const value = await
|
|
8281
|
+
const value = await p43.text({
|
|
8245
8282
|
message: "Email to sign in with",
|
|
8246
8283
|
validate: (input) => input?.includes("@") ? void 0 : "An email address is required"
|
|
8247
8284
|
});
|
|
8248
|
-
if (
|
|
8249
|
-
|
|
8250
|
-
|
|
8285
|
+
if (p43.isCancel(value)) {
|
|
8286
|
+
p43.cancel("Operation cancelled.");
|
|
8287
|
+
process30.exit(0);
|
|
8251
8288
|
}
|
|
8252
8289
|
return value.trim();
|
|
8253
8290
|
}
|
|
8254
8291
|
async function promptPassword2() {
|
|
8255
|
-
const value = await
|
|
8292
|
+
const value = await p43.password({
|
|
8256
8293
|
message: "Password",
|
|
8257
8294
|
validate: (input) => (input?.length ?? 0) >= MIN_PASSWORD ? void 0 : `At least ${MIN_PASSWORD} characters is required`
|
|
8258
8295
|
});
|
|
8259
|
-
if (
|
|
8260
|
-
|
|
8261
|
-
|
|
8296
|
+
if (p43.isCancel(value)) {
|
|
8297
|
+
p43.cancel("Operation cancelled.");
|
|
8298
|
+
process30.exit(0);
|
|
8262
8299
|
}
|
|
8263
|
-
const again = await
|
|
8300
|
+
const again = await p43.password({
|
|
8264
8301
|
message: "Password again",
|
|
8265
8302
|
validate: (input) => input === value ? void 0 : "The two do not match"
|
|
8266
8303
|
});
|
|
8267
|
-
if (
|
|
8268
|
-
|
|
8269
|
-
|
|
8304
|
+
if (p43.isCancel(again)) {
|
|
8305
|
+
p43.cancel("Operation cancelled.");
|
|
8306
|
+
process30.exit(0);
|
|
8270
8307
|
}
|
|
8271
8308
|
return value;
|
|
8272
8309
|
}
|
|
8273
8310
|
|
|
8274
8311
|
// src/commands/admin.ts
|
|
8275
|
-
var admin = new
|
|
8312
|
+
var admin = new Command83("admin").description("manage admin panel logins").configureHelp(helpConfig).addCommand(adminCreate);
|
|
8276
8313
|
|
|
8277
8314
|
// src/commands/backup.ts
|
|
8278
|
-
import { Command as
|
|
8315
|
+
import { Command as Command89 } from "commander";
|
|
8279
8316
|
|
|
8280
8317
|
// src/commands/backup/create.ts
|
|
8281
8318
|
import fs38 from "node:fs";
|
|
8282
8319
|
import path43 from "node:path";
|
|
8283
|
-
import { Command as
|
|
8284
|
-
import * as
|
|
8285
|
-
import
|
|
8320
|
+
import { Command as Command84 } from "commander";
|
|
8321
|
+
import * as p44 from "@clack/prompts";
|
|
8322
|
+
import pc24 from "picocolors";
|
|
8286
8323
|
|
|
8287
8324
|
// src/lib/backups.ts
|
|
8288
8325
|
var BACKUP_KEY = /^[a-z0-9_-]+\.zip$/;
|
|
@@ -8369,7 +8406,7 @@ async function writeSchedule(pb, cron, maxKeep) {
|
|
|
8369
8406
|
// src/commands/backup/create.ts
|
|
8370
8407
|
var DEFAULT_BACKUP_DIR = "backups";
|
|
8371
8408
|
var backupCreate = addTargetOptions(
|
|
8372
|
-
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),
|
|
8373
8410
|
"production"
|
|
8374
8411
|
).action(
|
|
8375
8412
|
(name, raw) => runCommand(() => {
|
|
@@ -8378,22 +8415,22 @@ var backupCreate = addTargetOptions(
|
|
|
8378
8415
|
const key = name ?? backupName(ctx.instance);
|
|
8379
8416
|
if (!isBackupKey(key)) {
|
|
8380
8417
|
throw new Error(
|
|
8381
|
-
`${
|
|
8418
|
+
`${pc24.cyan(key)} is not a name PocketBase will accept.
|
|
8382
8419
|
|
|
8383
|
-
Backup names are lowercase letters, digits, ${
|
|
8420
|
+
Backup names are lowercase letters, digits, ${pc24.cyan("-")} and ${pc24.cyan("_")}, ending in ${pc24.cyan(".zip")}.`
|
|
8384
8421
|
);
|
|
8385
8422
|
}
|
|
8386
8423
|
const storage = await readStorageSettings(ctx.pb);
|
|
8387
8424
|
if (storage.s3Enabled) {
|
|
8388
|
-
|
|
8425
|
+
p44.log.warn(
|
|
8389
8426
|
`Uploads are stored in S3, so this archive holds the database only.
|
|
8390
8427
|
|
|
8391
|
-
PocketBase leaves ${
|
|
8428
|
+
PocketBase leaves ${pc24.cyan("storage/")} out of a backup whenever S3 is on.
|
|
8392
8429
|
Your bucket's own versioning is what protects the uploaded files.`
|
|
8393
8430
|
);
|
|
8394
8431
|
}
|
|
8395
8432
|
if (ctx.session) await checkpointAppDatabases(ctx.session, ctx.instance);
|
|
8396
|
-
const spinner5 =
|
|
8433
|
+
const spinner5 = p44.spinner();
|
|
8397
8434
|
spinner5.start(`Backing up ${ctx.targetName}`);
|
|
8398
8435
|
try {
|
|
8399
8436
|
await createBackup(ctx.pb, key);
|
|
@@ -8440,7 +8477,7 @@ async function download(ctx, key, outputDir) {
|
|
|
8440
8477
|
fs38.copyFileSync(path43.join(ctx.workspaceRootDir, "data", "backups", key), destination);
|
|
8441
8478
|
return path43.relative(ctx.workspaceRootDir, destination);
|
|
8442
8479
|
}
|
|
8443
|
-
const spinner5 =
|
|
8480
|
+
const spinner5 = p44.spinner();
|
|
8444
8481
|
spinner5.start(`Downloading ${key}`);
|
|
8445
8482
|
try {
|
|
8446
8483
|
await ctx.session.download(remotePaths.backup(ctx.instance, key), destination);
|
|
@@ -8453,28 +8490,28 @@ async function download(ctx, key, outputDir) {
|
|
|
8453
8490
|
}
|
|
8454
8491
|
|
|
8455
8492
|
// src/commands/backup/list.ts
|
|
8456
|
-
import { Command as
|
|
8457
|
-
import * as
|
|
8458
|
-
import
|
|
8493
|
+
import { Command as Command85 } from "commander";
|
|
8494
|
+
import * as p45 from "@clack/prompts";
|
|
8495
|
+
import pc25 from "picocolors";
|
|
8459
8496
|
var backupList = addTargetOptions(
|
|
8460
|
-
new
|
|
8497
|
+
new Command85("list").description("list the backups on a target").configureHelp(helpConfig),
|
|
8461
8498
|
"production"
|
|
8462
8499
|
).action(
|
|
8463
8500
|
(raw) => runCommand(
|
|
8464
8501
|
() => withBackupTarget(raw, "backup list", async (ctx) => {
|
|
8465
8502
|
const backups = await listBackups(ctx.pb);
|
|
8466
8503
|
if (backups.length === 0) {
|
|
8467
|
-
|
|
8468
|
-
`${
|
|
8504
|
+
p45.log.info(
|
|
8505
|
+
`${pc25.cyan(ctx.targetName)} has no backups yet.
|
|
8469
8506
|
|
|
8470
|
-
Take one with ${
|
|
8507
|
+
Take one with ${pc25.cyan("vela backup create")}.`
|
|
8471
8508
|
);
|
|
8472
8509
|
return;
|
|
8473
8510
|
}
|
|
8474
8511
|
const width = Math.max(...backups.map((b) => b.key.length));
|
|
8475
|
-
|
|
8512
|
+
p45.log.message(
|
|
8476
8513
|
backups.map(
|
|
8477
|
-
(b) => `${b.key.padEnd(width)} ${
|
|
8514
|
+
(b) => `${b.key.padEnd(width)} ${pc25.dim(formatBytes(b.size).padStart(8))} ${pc25.dim(b.modified)}`
|
|
8478
8515
|
).join("\n")
|
|
8479
8516
|
);
|
|
8480
8517
|
}),
|
|
@@ -8485,11 +8522,11 @@ Take one with ${pc24.cyan("vela backup create")}.`
|
|
|
8485
8522
|
// src/commands/backup/download.ts
|
|
8486
8523
|
import fs39 from "node:fs";
|
|
8487
8524
|
import path44 from "node:path";
|
|
8488
|
-
import { Command as
|
|
8489
|
-
import * as
|
|
8490
|
-
import
|
|
8525
|
+
import { Command as Command86 } from "commander";
|
|
8526
|
+
import * as p46 from "@clack/prompts";
|
|
8527
|
+
import pc26 from "picocolors";
|
|
8491
8528
|
var backupDownload = addTargetOptions(
|
|
8492
|
-
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),
|
|
8493
8530
|
"production"
|
|
8494
8531
|
).action(
|
|
8495
8532
|
(key, raw) => runCommand(() => {
|
|
@@ -8498,9 +8535,9 @@ var backupDownload = addTargetOptions(
|
|
|
8498
8535
|
const found = (await listBackups(ctx.pb)).find((b) => b.key === key);
|
|
8499
8536
|
if (!found) {
|
|
8500
8537
|
throw new Error(
|
|
8501
|
-
`${ctx.targetName} has no backup called ${
|
|
8538
|
+
`${ctx.targetName} has no backup called ${pc26.cyan(key)}.
|
|
8502
8539
|
|
|
8503
|
-
Run ${
|
|
8540
|
+
Run ${pc26.cyan("vela backup list")} to see what it does have.`
|
|
8504
8541
|
);
|
|
8505
8542
|
}
|
|
8506
8543
|
const storage = await readStorageSettings(ctx.pb);
|
|
@@ -8517,7 +8554,7 @@ Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
|
|
|
8517
8554
|
if (!ctx.session) {
|
|
8518
8555
|
fs39.copyFileSync(path44.join(ctx.workspaceRootDir, "data", "backups", key), destination);
|
|
8519
8556
|
} else {
|
|
8520
|
-
const spinner5 =
|
|
8557
|
+
const spinner5 = p46.spinner();
|
|
8521
8558
|
spinner5.start(`Downloading ${key} (${formatBytes(found.size)})`);
|
|
8522
8559
|
try {
|
|
8523
8560
|
await ctx.session.download(remotePaths.backup(ctx.instance, key), destination);
|
|
@@ -8536,12 +8573,12 @@ Fetch it from the bucket directly \u2014 vela does not hold its credentials.`
|
|
|
8536
8573
|
);
|
|
8537
8574
|
|
|
8538
8575
|
// src/commands/backup/delete.ts
|
|
8539
|
-
import
|
|
8540
|
-
import { Command as
|
|
8541
|
-
import * as
|
|
8542
|
-
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";
|
|
8543
8580
|
var backupDelete = addTargetOptions(
|
|
8544
|
-
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),
|
|
8545
8582
|
"production"
|
|
8546
8583
|
).action(
|
|
8547
8584
|
(key, raw) => runCommand(() => {
|
|
@@ -8550,19 +8587,19 @@ var backupDelete = addTargetOptions(
|
|
|
8550
8587
|
const found = (await listBackups(ctx.pb)).find((b) => b.key === key);
|
|
8551
8588
|
if (!found) {
|
|
8552
8589
|
throw new Error(
|
|
8553
|
-
`${ctx.targetName} has no backup called ${
|
|
8590
|
+
`${ctx.targetName} has no backup called ${pc27.cyan(key)}.
|
|
8554
8591
|
|
|
8555
|
-
Run ${
|
|
8592
|
+
Run ${pc27.cyan("vela backup list")} to see what it does have.`
|
|
8556
8593
|
);
|
|
8557
8594
|
}
|
|
8558
8595
|
if (!options.yes) {
|
|
8559
|
-
const confirmed = await
|
|
8596
|
+
const confirmed = await p47.confirm({
|
|
8560
8597
|
message: `Delete ${key} (${formatBytes(found.size)}) from ${ctx.targetName}?`,
|
|
8561
8598
|
initialValue: false
|
|
8562
8599
|
});
|
|
8563
|
-
if (
|
|
8564
|
-
|
|
8565
|
-
|
|
8600
|
+
if (p47.isCancel(confirmed) || !confirmed) {
|
|
8601
|
+
p47.cancel("Operation cancelled.");
|
|
8602
|
+
process31.exit(0);
|
|
8566
8603
|
}
|
|
8567
8604
|
}
|
|
8568
8605
|
await ctx.pb.backups.delete(key);
|
|
@@ -8572,12 +8609,12 @@ Run ${pc26.cyan("vela backup list")} to see what it does have.`
|
|
|
8572
8609
|
);
|
|
8573
8610
|
|
|
8574
8611
|
// src/commands/backup/schedule.ts
|
|
8575
|
-
import { Command as
|
|
8576
|
-
import * as
|
|
8577
|
-
import
|
|
8612
|
+
import { Command as Command88 } from "commander";
|
|
8613
|
+
import * as p48 from "@clack/prompts";
|
|
8614
|
+
import pc28 from "picocolors";
|
|
8578
8615
|
var DEFAULT_KEEP = 7;
|
|
8579
8616
|
var backupSchedule = addTargetOptions(
|
|
8580
|
-
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),
|
|
8581
8618
|
"production"
|
|
8582
8619
|
).action(
|
|
8583
8620
|
(cron, raw) => runCommand(() => {
|
|
@@ -8590,17 +8627,17 @@ var backupSchedule = addTargetOptions(
|
|
|
8590
8627
|
}
|
|
8591
8628
|
if (!cron) {
|
|
8592
8629
|
const current = await readSchedule(ctx.pb);
|
|
8593
|
-
|
|
8594
|
-
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.
|
|
8595
8632
|
|
|
8596
|
-
Set one with ${
|
|
8633
|
+
Set one with ${pc28.cyan('vela backup schedule "0 3 * * *"')}.`
|
|
8597
8634
|
);
|
|
8598
8635
|
return;
|
|
8599
8636
|
}
|
|
8600
8637
|
const keep = Number.parseInt(options.keep, 10);
|
|
8601
8638
|
if (!Number.isInteger(keep) || keep < 1) {
|
|
8602
8639
|
throw new Error(
|
|
8603
|
-
`${
|
|
8640
|
+
`${pc28.cyan(options.keep)} is not a number of backups to keep \u2014 pass at least 1.`
|
|
8604
8641
|
);
|
|
8605
8642
|
}
|
|
8606
8643
|
await writeSchedule(ctx.pb, cron, keep);
|
|
@@ -8621,17 +8658,17 @@ Set one with ${pc27.cyan('vela backup schedule "0 3 * * *"')}.`
|
|
|
8621
8658
|
);
|
|
8622
8659
|
|
|
8623
8660
|
// src/commands/backup.ts
|
|
8624
|
-
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);
|
|
8625
8662
|
|
|
8626
8663
|
// src/commands/restore.ts
|
|
8627
8664
|
import fs40 from "node:fs";
|
|
8628
8665
|
import path45 from "node:path";
|
|
8629
|
-
import
|
|
8630
|
-
import { Command as
|
|
8631
|
-
import * as
|
|
8632
|
-
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";
|
|
8633
8670
|
var restore = addTargetOptions(
|
|
8634
|
-
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),
|
|
8635
8672
|
"production"
|
|
8636
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(
|
|
8637
8674
|
(source, raw) => runCommand(async () => {
|
|
@@ -8666,19 +8703,19 @@ var restore = addTargetOptions(
|
|
|
8666
8703
|
],
|
|
8667
8704
|
stream: true
|
|
8668
8705
|
});
|
|
8669
|
-
|
|
8670
|
-
`Restored ${
|
|
8706
|
+
p49.log.success(
|
|
8707
|
+
`Restored ${pc29.cyan(`${ctx.appName} (${ctx.targetName})`)} from ${pc29.cyan(
|
|
8671
8708
|
local ? path45.basename(local) : key
|
|
8672
8709
|
)}.`
|
|
8673
8710
|
);
|
|
8674
8711
|
if (result?.storageCarriedOver) {
|
|
8675
|
-
|
|
8712
|
+
p49.log.info(
|
|
8676
8713
|
"The archive held no uploads, so the files already on the server were kept."
|
|
8677
8714
|
);
|
|
8678
8715
|
}
|
|
8679
8716
|
if (result?.previousDataDir) {
|
|
8680
|
-
|
|
8681
|
-
`The database this replaced is at ${
|
|
8717
|
+
p49.log.info(
|
|
8718
|
+
`The database this replaced is at ${pc29.cyan(result.previousDataDir)}.
|
|
8682
8719
|
|
|
8683
8720
|
It is the only way back. Remove it once you are satisfied with the restore.`
|
|
8684
8721
|
);
|
|
@@ -8695,18 +8732,18 @@ It is the only way back. Remove it once you are satisfied with the restore.`
|
|
|
8695
8732
|
async function resolveKey(ctx, source) {
|
|
8696
8733
|
if (source && !isBackupKey(source)) {
|
|
8697
8734
|
throw new Error(
|
|
8698
|
-
`${
|
|
8735
|
+
`${pc29.cyan(source)} is neither a file on this machine nor a backup key.
|
|
8699
8736
|
|
|
8700
|
-
Run ${
|
|
8737
|
+
Run ${pc29.cyan("vela backup list")} to see what ${ctx.targetName} has.`
|
|
8701
8738
|
);
|
|
8702
8739
|
}
|
|
8703
8740
|
const backups = await withRemotePocketbase(ctx.session, ctx.instance, listBackups);
|
|
8704
8741
|
if (source) {
|
|
8705
8742
|
if (!backups.some((b) => b.key === source)) {
|
|
8706
8743
|
throw new Error(
|
|
8707
|
-
`${ctx.targetName} has no backup called ${
|
|
8744
|
+
`${ctx.targetName} has no backup called ${pc29.cyan(source)}.
|
|
8708
8745
|
|
|
8709
|
-
Run ${
|
|
8746
|
+
Run ${pc29.cyan("vela backup list")} to see what it does have.`
|
|
8710
8747
|
);
|
|
8711
8748
|
}
|
|
8712
8749
|
return source;
|
|
@@ -8715,10 +8752,10 @@ Run ${pc28.cyan("vela backup list")} to see what it does have.`
|
|
|
8715
8752
|
throw new Error(
|
|
8716
8753
|
`${ctx.targetName} has no backups to restore from.
|
|
8717
8754
|
|
|
8718
|
-
Take one with ${
|
|
8755
|
+
Take one with ${pc29.cyan("vela backup create")}, or pass the path to an archive on this machine.`
|
|
8719
8756
|
);
|
|
8720
8757
|
}
|
|
8721
|
-
const chosen = await
|
|
8758
|
+
const chosen = await p49.select({
|
|
8722
8759
|
message: `Which backup should ${ctx.targetName} be restored from?`,
|
|
8723
8760
|
options: backups.map((b) => ({
|
|
8724
8761
|
value: b.key,
|
|
@@ -8726,16 +8763,16 @@ Take one with ${pc28.cyan("vela backup create")}, or pass the path to an archive
|
|
|
8726
8763
|
hint: `${formatBytes(b.size)}, ${b.modified}`
|
|
8727
8764
|
}))
|
|
8728
8765
|
});
|
|
8729
|
-
if (
|
|
8730
|
-
|
|
8731
|
-
|
|
8766
|
+
if (p49.isCancel(chosen)) {
|
|
8767
|
+
p49.cancel("Operation cancelled.");
|
|
8768
|
+
process32.exit(0);
|
|
8732
8769
|
}
|
|
8733
8770
|
return chosen;
|
|
8734
8771
|
}
|
|
8735
8772
|
async function stage(ctx, file) {
|
|
8736
8773
|
const dir = remotePaths.restoreStage(ctx.instance);
|
|
8737
8774
|
const remote = `${dir}/${path45.basename(file)}`;
|
|
8738
|
-
const spinner5 =
|
|
8775
|
+
const spinner5 = p49.spinner();
|
|
8739
8776
|
spinner5.start(`Uploading ${path45.basename(file)}`);
|
|
8740
8777
|
try {
|
|
8741
8778
|
await ctx.session.script(`mkdir -p "$1"`, { args: [dir] });
|
|
@@ -8748,32 +8785,32 @@ async function stage(ctx, file) {
|
|
|
8748
8785
|
return remote;
|
|
8749
8786
|
}
|
|
8750
8787
|
async function confirm11(appName, targetName, envTag, from) {
|
|
8751
|
-
const what = `${
|
|
8788
|
+
const what = `${pc29.cyan(`${appName} (${targetName})`)} from ${pc29.cyan(path45.basename(from))}`;
|
|
8752
8789
|
if (isProd(envTag)) {
|
|
8753
|
-
const answer = await
|
|
8790
|
+
const answer = await p49.text({
|
|
8754
8791
|
message: `This replaces the database and uploads of ${what}. Type the app name to confirm`,
|
|
8755
8792
|
validate: (value) => value === appName ? void 0 : `Type ${appName} to confirm`
|
|
8756
8793
|
});
|
|
8757
|
-
if (
|
|
8758
|
-
|
|
8759
|
-
|
|
8794
|
+
if (p49.isCancel(answer)) {
|
|
8795
|
+
p49.cancel("Operation cancelled.");
|
|
8796
|
+
process32.exit(0);
|
|
8760
8797
|
}
|
|
8761
8798
|
return;
|
|
8762
8799
|
}
|
|
8763
|
-
const ok = await
|
|
8800
|
+
const ok = await p49.confirm({
|
|
8764
8801
|
message: `Replace the database and uploads of ${what}?`,
|
|
8765
8802
|
initialValue: false
|
|
8766
8803
|
});
|
|
8767
|
-
if (
|
|
8768
|
-
|
|
8769
|
-
|
|
8804
|
+
if (p49.isCancel(ok) || !ok) {
|
|
8805
|
+
p49.cancel("Operation cancelled.");
|
|
8806
|
+
process32.exit(0);
|
|
8770
8807
|
}
|
|
8771
8808
|
}
|
|
8772
8809
|
|
|
8773
8810
|
// src/commands/targets.ts
|
|
8774
|
-
import { Command as
|
|
8775
|
-
import * as
|
|
8776
|
-
import
|
|
8811
|
+
import { Command as Command91 } from "commander";
|
|
8812
|
+
import * as p50 from "@clack/prompts";
|
|
8813
|
+
import pc30 from "picocolors";
|
|
8777
8814
|
import * as v8 from "valibot";
|
|
8778
8815
|
var OptionsSchema4 = v8.object({
|
|
8779
8816
|
...SSH_OPTION_SCHEMA,
|
|
@@ -8781,7 +8818,7 @@ var OptionsSchema4 = v8.object({
|
|
|
8781
8818
|
offline: v8.optional(v8.boolean())
|
|
8782
8819
|
});
|
|
8783
8820
|
var targets = addSshOptions(
|
|
8784
|
-
new
|
|
8821
|
+
new Command91("targets").description("list the targets this project can deploy to").configureHelp(helpConfig)
|
|
8785
8822
|
).option("--json", "print raw JSON").option("--offline", "skip connecting to servers").action(
|
|
8786
8823
|
(raw) => runCommand(async () => {
|
|
8787
8824
|
const options = parseOptions(OptionsSchema4, raw);
|
|
@@ -8845,13 +8882,13 @@ function report3(rows, offline) {
|
|
|
8845
8882
|
const domain = width("DOMAIN", (row) => row.domain);
|
|
8846
8883
|
const header = `${"TARGET".padEnd(target)} ${"SERVER".padEnd(server)} ${"DOMAIN".padEnd(domain)} RELEASE`;
|
|
8847
8884
|
const lines = rows.map(
|
|
8848
|
-
(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}`
|
|
8849
8886
|
);
|
|
8850
|
-
|
|
8887
|
+
p50.log.info(`${pc30.dim(header)}
|
|
8851
8888
|
${lines.join("\n")}`);
|
|
8852
8889
|
const unreachable = rows.filter((row) => row.kind === "remote" && !row.reachable);
|
|
8853
8890
|
if (!offline && unreachable.length > 0) {
|
|
8854
|
-
|
|
8891
|
+
p50.log.warn(
|
|
8855
8892
|
`Could not reach ${unreachable.map((row) => row.server).join(", ")}.
|
|
8856
8893
|
Release and domain are shown from what this project recorded.`
|
|
8857
8894
|
);
|
|
@@ -8860,16 +8897,16 @@ Release and domain are shown from what this project recorded.`
|
|
|
8860
8897
|
|
|
8861
8898
|
// src/commands/test.ts
|
|
8862
8899
|
import path46 from "node:path";
|
|
8863
|
-
import
|
|
8864
|
-
import { Command as
|
|
8900
|
+
import process33 from "node:process";
|
|
8901
|
+
import { Command as Command92 } from "commander";
|
|
8865
8902
|
import PocketBase5 from "pocketbase";
|
|
8866
|
-
import
|
|
8903
|
+
import pc31 from "picocolors";
|
|
8867
8904
|
import { x as x5 } from "tinyexec";
|
|
8868
8905
|
import { detect as detect8 } from "package-manager-detector";
|
|
8869
8906
|
import { resolveCommand as resolveCommand8 } from "package-manager-detector/commands";
|
|
8870
8907
|
import fs41 from "node:fs";
|
|
8871
|
-
var testServer = new
|
|
8872
|
-
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();
|
|
8873
8910
|
const email3 = `test-${Math.random().toString(36).slice(2)}@example.com`;
|
|
8874
8911
|
const password11 = "password";
|
|
8875
8912
|
const testDataDir = path46.join(cwd, "test-data");
|
|
@@ -8880,12 +8917,12 @@ var testServer = new Command91("test:server").description("run server tests").al
|
|
|
8880
8917
|
email: email3,
|
|
8881
8918
|
password: password11
|
|
8882
8919
|
});
|
|
8883
|
-
|
|
8884
|
-
|
|
8885
|
-
|
|
8886
|
-
|
|
8887
|
-
|
|
8888
|
-
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`);
|
|
8889
8926
|
const { createServer } = await loadVite(cwd);
|
|
8890
8927
|
const vite = await createServer({
|
|
8891
8928
|
mode: "test",
|
|
@@ -8894,9 +8931,9 @@ var testServer = new Command91("test:server").description("run server tests").al
|
|
|
8894
8931
|
});
|
|
8895
8932
|
const vitePort = await findFreePort();
|
|
8896
8933
|
await vite.listen(vitePort);
|
|
8897
|
-
|
|
8898
|
-
console.log(`${
|
|
8899
|
-
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}`);
|
|
8900
8937
|
const cleanup = async () => {
|
|
8901
8938
|
stop();
|
|
8902
8939
|
await vite.close();
|
|
@@ -8907,8 +8944,8 @@ var testServer = new Command91("test:server").description("run server tests").al
|
|
|
8907
8944
|
await authWithRetries(pb, email3, password11);
|
|
8908
8945
|
} catch (e) {
|
|
8909
8946
|
await cleanup();
|
|
8910
|
-
console.error(`${
|
|
8911
|
-
|
|
8947
|
+
console.error(`${pc31.redBright("\u2717")} Auth failed: ${e.message}`);
|
|
8948
|
+
process33.exit(1);
|
|
8912
8949
|
}
|
|
8913
8950
|
const extraArgs = (cmd.parent?.args ?? []).slice(1);
|
|
8914
8951
|
let filter = extraArgs.find((arg) => !arg.startsWith("-"));
|
|
@@ -8926,7 +8963,7 @@ var testServer = new Command91("test:server").description("run server tests").al
|
|
|
8926
8963
|
const resolvedArgs = resolved.args.slice();
|
|
8927
8964
|
if (pm === "npm") resolvedArgs.unshift("--yes");
|
|
8928
8965
|
await x5(resolved.command, resolvedArgs, {
|
|
8929
|
-
nodeOptions: { cwd, stdio: "inherit", env: { ...
|
|
8966
|
+
nodeOptions: { cwd, stdio: "inherit", env: { ...process33.env, CI: "1" } },
|
|
8930
8967
|
throwOnError: true
|
|
8931
8968
|
});
|
|
8932
8969
|
} catch {
|
|
@@ -8954,7 +8991,7 @@ function stubPagesPlugin() {
|
|
|
8954
8991
|
// src/commands/routes.ts
|
|
8955
8992
|
import fs42 from "node:fs";
|
|
8956
8993
|
import path47 from "node:path";
|
|
8957
|
-
import { Command as
|
|
8994
|
+
import { Command as Command93 } from "commander";
|
|
8958
8995
|
var HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
8959
8996
|
"GET",
|
|
8960
8997
|
"POST",
|
|
@@ -8965,7 +9002,7 @@ var HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
|
8965
9002
|
"HEAD",
|
|
8966
9003
|
"fallback"
|
|
8967
9004
|
]);
|
|
8968
|
-
var routes = new
|
|
9005
|
+
var routes = new Command93("routes").description("list routes").configureHelp(helpConfig).action(async () => {
|
|
8969
9006
|
const { workspaceRootDir, routesDir } = await getWorkspace();
|
|
8970
9007
|
const routesRoot = path47.join(workspaceRootDir, routesDir);
|
|
8971
9008
|
const found = walk(routesRoot, routesRoot).filter((r) => r.methods.length > 0);
|
|
@@ -9040,13 +9077,13 @@ function printTable(routes2) {
|
|
|
9040
9077
|
}
|
|
9041
9078
|
|
|
9042
9079
|
// src/commands/i18n.ts
|
|
9043
|
-
import
|
|
9044
|
-
import { Command as
|
|
9080
|
+
import process34 from "node:process";
|
|
9081
|
+
import { Command as Command94 } from "commander";
|
|
9045
9082
|
import { x as x6 } from "tinyexec";
|
|
9046
9083
|
import { detect as detect9 } from "package-manager-detector";
|
|
9047
9084
|
import { resolveCommand as resolveCommand9 } from "package-manager-detector/commands";
|
|
9048
9085
|
async function runWuchale(extraArgs) {
|
|
9049
|
-
const cwd =
|
|
9086
|
+
const cwd = process34.cwd();
|
|
9050
9087
|
const pm = (await detect9({ cwd }))?.name ?? "npm";
|
|
9051
9088
|
const resolved = resolveCommand9(pm, "execute", ["wuchale", ...extraArgs]);
|
|
9052
9089
|
const args = resolved.args.slice();
|
|
@@ -9056,11 +9093,11 @@ async function runWuchale(extraArgs) {
|
|
|
9056
9093
|
throwOnError: true
|
|
9057
9094
|
});
|
|
9058
9095
|
}
|
|
9059
|
-
var extract = new
|
|
9060
|
-
var watch = new
|
|
9061
|
-
var status2 = new
|
|
9062
|
-
var clean = new
|
|
9063
|
-
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);
|
|
9064
9101
|
|
|
9065
9102
|
// src/commands/oauth.ts
|
|
9066
9103
|
var oauth = stubCommand("oauth", "configure OAuth providers");
|
|
@@ -9068,6 +9105,121 @@ var oauth = stubCommand("oauth", "configure OAuth providers");
|
|
|
9068
9105
|
// src/commands/schemas.ts
|
|
9069
9106
|
var schemas = stubCommand("schemas", "manage database schemas");
|
|
9070
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
|
+
|
|
9071
9223
|
// src/program.ts
|
|
9072
9224
|
var NO_BACKEND_COMMMANDS = /* @__PURE__ */ new Set([
|
|
9073
9225
|
"bless",
|
|
@@ -9082,6 +9234,9 @@ var NO_BACKEND_COMMMANDS = /* @__PURE__ */ new Set([
|
|
|
9082
9234
|
"i18n",
|
|
9083
9235
|
"generate schema",
|
|
9084
9236
|
"generate form",
|
|
9237
|
+
// The CMS keeps its own SQLite database and editors; PocketBase is never involved.
|
|
9238
|
+
"enable cms",
|
|
9239
|
+
"cms",
|
|
9085
9240
|
// Server commands talk to a VPS over SSH, never to the local database.
|
|
9086
9241
|
"provision",
|
|
9087
9242
|
"env",
|
|
@@ -9097,40 +9252,40 @@ var NO_BACKEND_COMMMANDS = /* @__PURE__ */ new Set([
|
|
|
9097
9252
|
"restore"
|
|
9098
9253
|
]);
|
|
9099
9254
|
var BACKEND_OPTIONAL_COMMANDS = /* @__PURE__ */ new Set(["dev", "build", "preview", "deploy"]);
|
|
9100
|
-
var program = new
|
|
9255
|
+
var program = new Command100().name(package_default.name).description(package_default.description).version(package_default.version, "-v, --version").configureHelp(helpConfig);
|
|
9101
9256
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
9102
9257
|
if (isStub(actionCommand)) return;
|
|
9103
|
-
const envRoot = findWorkspaceRoot() ??
|
|
9258
|
+
const envRoot = findWorkspaceRoot() ?? process36.cwd();
|
|
9104
9259
|
dotenv2.config({ path: nodePath.join(envRoot, ".env"), quiet: true });
|
|
9105
|
-
const
|
|
9106
|
-
if (NO_BACKEND_COMMMANDS.has(
|
|
9107
|
-
const top =
|
|
9260
|
+
const path49 = getCommandPath(actionCommand);
|
|
9261
|
+
if (NO_BACKEND_COMMMANDS.has(path49)) return;
|
|
9262
|
+
const top = path49.split(" ", 1)[0];
|
|
9108
9263
|
if (NO_BACKEND_COMMMANDS.has(top)) return;
|
|
9109
9264
|
if (!hasBackend()) {
|
|
9110
9265
|
if (BACKEND_OPTIONAL_COMMANDS.has(top)) return;
|
|
9111
|
-
|
|
9112
|
-
`${
|
|
9266
|
+
p54.log.error(
|
|
9267
|
+
`${pc36.cyan(`vela ${path49}`)} needs a backend, and this project does not have one.
|
|
9113
9268
|
|
|
9114
9269
|
Static projects have no database to talk to.
|
|
9115
9270
|
|
|
9116
|
-
To add a backend to this project, run ${
|
|
9271
|
+
To add a backend to this project, run ${pc36.cyan("vela bless")}.`
|
|
9117
9272
|
);
|
|
9118
|
-
|
|
9119
|
-
|
|
9120
|
-
|
|
9273
|
+
p54.log.message();
|
|
9274
|
+
p54.cancel("Operation failed.");
|
|
9275
|
+
process36.exit(1);
|
|
9121
9276
|
}
|
|
9122
|
-
if (!
|
|
9123
|
-
|
|
9277
|
+
if (!process36.env.POCKETBASE_SUPERUSER_EMAIL || !process36.env.POCKETBASE_SUPERUSER_PASSWORD) {
|
|
9278
|
+
p54.log.error(
|
|
9124
9279
|
`PocketBase superuser credentials are required.
|
|
9125
9280
|
|
|
9126
|
-
Set ${
|
|
9281
|
+
Set ${pc36.cyan("POCKETBASE_SUPERUSER_EMAIL")} and ${pc36.cyan("POCKETBASE_SUPERUSER_PASSWORD")} in your .env file.
|
|
9127
9282
|
|
|
9128
|
-
To set up a new project, run ${
|
|
9129
|
-
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")}.`
|
|
9130
9285
|
);
|
|
9131
|
-
|
|
9132
|
-
|
|
9133
|
-
|
|
9286
|
+
p54.log.message();
|
|
9287
|
+
p54.cancel("Operation failed.");
|
|
9288
|
+
process36.exit(1);
|
|
9134
9289
|
}
|
|
9135
9290
|
});
|
|
9136
9291
|
function getCommandPath(cmd) {
|
|
@@ -9177,20 +9332,21 @@ for (const command of [
|
|
|
9177
9332
|
routes,
|
|
9178
9333
|
i18n3,
|
|
9179
9334
|
oauth,
|
|
9180
|
-
schemas
|
|
9335
|
+
schemas,
|
|
9336
|
+
cms2
|
|
9181
9337
|
]) {
|
|
9182
9338
|
program.addCommand(command);
|
|
9183
9339
|
}
|
|
9184
9340
|
|
|
9185
9341
|
// src/bin.ts
|
|
9186
|
-
var argv = normalizeArgv(
|
|
9342
|
+
var argv = normalizeArgv(process37.argv.slice(2));
|
|
9187
9343
|
var delegatedExitCode = delegateToLocalCli({
|
|
9188
9344
|
argv,
|
|
9189
9345
|
selfPath: fileURLToPath2(import.meta.url),
|
|
9190
9346
|
selfVersion: package_default.version
|
|
9191
9347
|
});
|
|
9192
9348
|
if (delegatedExitCode !== null) {
|
|
9193
|
-
|
|
9349
|
+
process37.exit(delegatedExitCode);
|
|
9194
9350
|
}
|
|
9195
9351
|
program.parse(argv, { from: "user" });
|
|
9196
9352
|
//# sourceMappingURL=bin.js.map
|