@selvajs/cli 4.6.21-beta.1 → 4.7.0-beta.3
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/LICENSE +1 -1
- package/package.json +7 -2
- package/src/cli.js +0 -3
- package/src/commands/pm2.js +1 -7
- package/src/prompts.js +0 -15
package/LICENSE
CHANGED
package/package.json
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@selvajs/cli",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.7.0-beta.3",
|
|
4
4
|
"description": "Scaffold and operate a Selva white-label deployment. `npx @selvajs/cli <dir>` to bootstrap, `selva <cmd>` to manage.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/VektorNode/selva.git",
|
|
12
|
+
"directory": "packages/cli"
|
|
13
|
+
},
|
|
9
14
|
"type": "module",
|
|
10
15
|
"bin": {
|
|
11
16
|
"cli": "./bin/cli.js",
|
|
@@ -16,7 +21,7 @@
|
|
|
16
21
|
"src"
|
|
17
22
|
],
|
|
18
23
|
"engines": {
|
|
19
|
-
"node": ">=
|
|
24
|
+
"node": ">=22.0.0"
|
|
20
25
|
},
|
|
21
26
|
"dependencies": {
|
|
22
27
|
"@clack/prompts": "^0.11.0",
|
package/src/cli.js
CHANGED
|
@@ -35,9 +35,6 @@ export async function runSelva(argv) {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
if (command === '--version' || command === '-v') {
|
|
38
|
-
// We don't pin a version here — selva is installed transitively, so
|
|
39
|
-
// the deployment's package.json doesn't list us directly. Read our
|
|
40
|
-
// own package.json instead.
|
|
41
38
|
const { readFileSync } = await import('node:fs');
|
|
42
39
|
const { fileURLToPath } = await import('node:url');
|
|
43
40
|
const { dirname, join } = await import('node:path');
|
package/src/commands/pm2.js
CHANGED
|
@@ -58,7 +58,7 @@ function runPm2(dir, args, { inherit = true } = {}) {
|
|
|
58
58
|
const result = spawnSync(bin, args, {
|
|
59
59
|
cwd: dir,
|
|
60
60
|
stdio: inherit ? 'inherit' : 'pipe',
|
|
61
|
-
shell: process.platform === 'win32'
|
|
61
|
+
shell: process.platform === 'win32'
|
|
62
62
|
});
|
|
63
63
|
if (result.error) {
|
|
64
64
|
throw new Error(
|
|
@@ -125,10 +125,8 @@ export async function runUpdate() {
|
|
|
125
125
|
return;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
// Resync daemon before state changes (avoid half-state stop/start).
|
|
129
128
|
ensurePm2InSync(dir);
|
|
130
129
|
|
|
131
|
-
// Stop before npm rewrites (SvelteKit lazy-loads chunks; see migrate command).
|
|
132
130
|
const stopStatus = runPm2(dir, ['stop', APP_NAME], { inherit: false });
|
|
133
131
|
if (stopStatus !== 0) {
|
|
134
132
|
p.log.warn('pm2 stop did not succeed — selva-compute may not be running. Continuing.');
|
|
@@ -137,7 +135,6 @@ export async function runUpdate() {
|
|
|
137
135
|
const s = p.spinner();
|
|
138
136
|
s.start(`npm update ${packages.join(' ')}`);
|
|
139
137
|
try {
|
|
140
|
-
// --prefer-online bypasses npm's packument cache (see docs/Hotfix-CLI-Runtime.md).
|
|
141
138
|
execSync(`npm update --save --prefer-online ${packages.join(' ')}`, {
|
|
142
139
|
cwd: dir,
|
|
143
140
|
stdio: 'pipe'
|
|
@@ -145,7 +142,6 @@ export async function runUpdate() {
|
|
|
145
142
|
s.stop('npm update finished');
|
|
146
143
|
} catch (err) {
|
|
147
144
|
s.stop('npm update failed');
|
|
148
|
-
// Best-effort: bring old process back up.
|
|
149
145
|
runPm2(dir, ['start', APP_NAME, '--update-env'], { inherit: false });
|
|
150
146
|
throw err;
|
|
151
147
|
}
|
|
@@ -153,7 +149,6 @@ export async function runUpdate() {
|
|
|
153
149
|
const after = readRuntimeVersion(dir);
|
|
154
150
|
p.log.info(`New @selvajs/selva: ${after ?? 'unknown'}`);
|
|
155
151
|
|
|
156
|
-
// Surface no-op updates (cache may be stale; propagation delay is real).
|
|
157
152
|
if (before && after && before === after) {
|
|
158
153
|
p.log.warn(
|
|
159
154
|
[
|
|
@@ -168,7 +163,6 @@ export async function runUpdate() {
|
|
|
168
163
|
);
|
|
169
164
|
}
|
|
170
165
|
|
|
171
|
-
// Start the new build under PM2.
|
|
172
166
|
const status = runPm2(dir, ['start', APP_NAME, '--update-env'], { inherit: false });
|
|
173
167
|
if (status === 0) {
|
|
174
168
|
p.outro(pc.green('Started ' + APP_NAME));
|
package/src/prompts.js
CHANGED
|
@@ -10,8 +10,6 @@ function envBool(v) {
|
|
|
10
10
|
return TRUTHY.has(String(v).toLowerCase());
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
// Non-interactive sibling of collectConfig: read from env, validate strictly,
|
|
14
|
-
// fail loud for security-relevant fields (no safe defaults).
|
|
15
13
|
export function collectConfigFromEnv(env = process.env) {
|
|
16
14
|
const tenancy = pick(env.SELVA_TENANCY, ['single', 'multi'], 'single', 'SELVA_TENANCY');
|
|
17
15
|
const auth = pick(
|
|
@@ -61,8 +59,6 @@ export function collectConfigFromEnv(env = process.env) {
|
|
|
61
59
|
}
|
|
62
60
|
|
|
63
61
|
if (auth === 'header') {
|
|
64
|
-
// Same loopback default as the prompt — header-auth without network
|
|
65
|
-
// isolation is the documented worst-case footgun.
|
|
66
62
|
values.HOST = env.HOST || '127.0.0.1';
|
|
67
63
|
if (data !== 'local') {
|
|
68
64
|
values.HEADER_AUTH_DATA_DIR = requireEnv(env, 'HEADER_AUTH_DATA_DIR');
|
|
@@ -102,7 +98,6 @@ export function collectConfigFromEnv(env = process.env) {
|
|
|
102
98
|
}
|
|
103
99
|
values.ORIGIN = origin;
|
|
104
100
|
|
|
105
|
-
// Pass-through: SELVA_FLAG_* vars written verbatim; unset = empty string.
|
|
106
101
|
const flagNames = [
|
|
107
102
|
'ALLOW_ORG_CREATION',
|
|
108
103
|
'ALLOW_CROSS_ORG_PUBLIC',
|
|
@@ -140,9 +135,6 @@ export async function collectConfig({ defaults = {}, mode = 'create' } = {}) {
|
|
|
140
135
|
p.intro(pc.bgCyan(pc.black(isInit ? ' selva init ' : ' Selva — new deployment ')));
|
|
141
136
|
|
|
142
137
|
// Brand prompts (SELVA_BRAND_NAME / COPYRIGHT_NAME / TAGLINE / DESCRIPTION)
|
|
143
|
-
// are skipped for now — the runtime falls back to "Selva" defaults when
|
|
144
|
-
// these env vars are absent. To re-enable, add a brand prompt block here
|
|
145
|
-
// and write the values into `values` below.
|
|
146
138
|
|
|
147
139
|
const tenancy = await p.select({
|
|
148
140
|
message: 'Tenancy mode',
|
|
@@ -300,7 +292,6 @@ export async function collectConfig({ defaults = {}, mode = 'create' } = {}) {
|
|
|
300
292
|
cancelOn(dataDir);
|
|
301
293
|
providerValues.HEADER_AUTH_DATA_DIR = String(dataDir);
|
|
302
294
|
} else if (defaults.HEADER_AUTH_DATA_DIR) {
|
|
303
|
-
// Preserve an explicit override if the operator set one previously.
|
|
304
295
|
providerValues.HEADER_AUTH_DATA_DIR = defaults.HEADER_AUTH_DATA_DIR;
|
|
305
296
|
}
|
|
306
297
|
|
|
@@ -397,10 +388,6 @@ export async function collectConfig({ defaults = {}, mode = 'create' } = {}) {
|
|
|
397
388
|
initialValue: defaults.BOOTSTRAP_INSTANCE_ADMIN_EMAIL ?? '',
|
|
398
389
|
validate: (v) => {
|
|
399
390
|
if (!v) {
|
|
400
|
-
// Blank is allowed in single-tenant non-header. Header-auth and
|
|
401
|
-
// multi-tenant both need the email — without it there is no
|
|
402
|
-
// supported path to first-admin (header-auth) or the first
|
|
403
|
-
// random signup gets staff perms (multi-tenant).
|
|
404
391
|
return adminRequired ? 'Required for this configuration.' : undefined;
|
|
405
392
|
}
|
|
406
393
|
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v)) return 'Not a valid email.';
|
|
@@ -435,7 +422,6 @@ export async function collectConfig({ defaults = {}, mode = 'create' } = {}) {
|
|
|
435
422
|
cancelOn(value);
|
|
436
423
|
origin = String(value);
|
|
437
424
|
|
|
438
|
-
// Plain HTTP kills Secure cookies in production (login appears to succeed, then anon).
|
|
439
425
|
if (origin.startsWith('http://')) {
|
|
440
426
|
p.note(
|
|
441
427
|
'Sessions use Secure cookies in production; browsers will silently\n' +
|
|
@@ -528,7 +514,6 @@ function stringValue(v) {
|
|
|
528
514
|
return String(v);
|
|
529
515
|
}
|
|
530
516
|
|
|
531
|
-
// Header-auth security: deployment IS the boundary (runtime enforcement impossible).
|
|
532
517
|
function headerAuthSecurityWarning() {
|
|
533
518
|
return [
|
|
534
519
|
'Header-auth trusts identity headers from the upstream proxy. Anyone who',
|