easy-vps 0.2.0 → 0.2.2
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/services/deploy.js +53 -4
- package/package.json +1 -1
package/dist/services/deploy.js
CHANGED
|
@@ -227,6 +227,47 @@ function dockerRestart(config) {
|
|
|
227
227
|
const name = (0, ssh_1.quote)(config.name);
|
|
228
228
|
return [step('Restarting the container'), `docker restart ${name}`, `docker ps --filter name=${name}`].join('\n');
|
|
229
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* Generates a bash snippet that patches vite.config.{ts,js,mts,mjs} to add
|
|
232
|
+
* `preview.allowedHosts` for the deployment's domain. Without this Vite 6+
|
|
233
|
+
* rejects incoming requests whose Host header doesn't match localhost.
|
|
234
|
+
*
|
|
235
|
+
* The snippet is idempotent — it skips files that already contain
|
|
236
|
+
* `allowedHosts` and silently does nothing when no vite config is found.
|
|
237
|
+
*/
|
|
238
|
+
function patchViteHosts(config) {
|
|
239
|
+
if (!config.domain)
|
|
240
|
+
return '';
|
|
241
|
+
const domain = config.domain;
|
|
242
|
+
return [
|
|
243
|
+
step('Patching vite.config for domain access'),
|
|
244
|
+
// Write a small Node helper to /tmp, then execute it per config file.
|
|
245
|
+
// A single-quoted heredoc (<<'EOF') keeps every character literal so
|
|
246
|
+
// backslashes in regexes and $-prefixed strings survive untouched.
|
|
247
|
+
`DOMAIN=${(0, ssh_1.quote)(domain)}`,
|
|
248
|
+
'cat > /tmp/patch-vite.js << \'VITEPATCH\'\n' +
|
|
249
|
+
'const fs = require("fs");\n' +
|
|
250
|
+
'const domain = process.argv[2];\n' +
|
|
251
|
+
'const cfg = process.argv[3];\n' +
|
|
252
|
+
'let src = fs.readFileSync(cfg, "utf8");\n' +
|
|
253
|
+
'const hostEntry = "allowedHosts: [\\"" + domain + "\\"],";\n' +
|
|
254
|
+
'if (/preview\\s*:\\s*\\{/.test(src)) {\n' +
|
|
255
|
+
' src = src.replace(/(preview\\s*:\\s*\\{)/, "$1\\n " + hostEntry);\n' +
|
|
256
|
+
'} else {\n' +
|
|
257
|
+
' const lastBrace = src.lastIndexOf("}");\n' +
|
|
258
|
+
' if (lastBrace !== -1) {\n' +
|
|
259
|
+
' src = src.slice(0, lastBrace) + " preview: {\\n " + hostEntry + "\\n },\\n" + src.slice(lastBrace);\n' +
|
|
260
|
+
' }\n' +
|
|
261
|
+
'}\n' +
|
|
262
|
+
'fs.writeFileSync(cfg, src);\n' +
|
|
263
|
+
'VITEPATCH\n',
|
|
264
|
+
'for cfg in vite.config.ts vite.config.js vite.config.mts vite.config.mjs; do\n' +
|
|
265
|
+
' if [ -f "$cfg" ] && ! grep -q \'allowedHosts\' "$cfg"; then\n' +
|
|
266
|
+
' node /tmp/patch-vite.js "$DOMAIN" "$cfg"\n' +
|
|
267
|
+
' echo " Patched $cfg \\u2014 added allowedHosts for $DOMAIN"\n' +
|
|
268
|
+
' fi\ndone',
|
|
269
|
+
].join('\n');
|
|
270
|
+
}
|
|
230
271
|
/**
|
|
231
272
|
* The whole deploy as one script. `set -e` stops at the first failing step, so a
|
|
232
273
|
* broken build never reaches the run stage and the exit code reaches the UI.
|
|
@@ -272,11 +313,13 @@ else
|
|
|
272
313
|
cd ${dir}
|
|
273
314
|
fi`,
|
|
274
315
|
'git --no-pager log -1 --pretty="cloned %h %s"',
|
|
316
|
+
patchViteHosts(config),
|
|
275
317
|
step('Installing dependencies'),
|
|
276
318
|
config.installCommand,
|
|
277
319
|
step('Building'),
|
|
278
320
|
config.buildCommand,
|
|
279
321
|
config.runtime === 'pm2' ? pm2Start(config) : dockerStart(config),
|
|
322
|
+
'rm -f /tmp/patch-vite.js',
|
|
280
323
|
`echo ""; echo "==> ${config.name} is live on port ${config.port}"`,
|
|
281
324
|
].join('\n');
|
|
282
325
|
}
|
|
@@ -370,7 +413,10 @@ async function clones(remote) {
|
|
|
370
413
|
' name=$(basename "$dir")',
|
|
371
414
|
' repo=$(git -C "$dir" config --get remote.origin.url 2>/dev/null)',
|
|
372
415
|
' branch=$(git -C "$dir" rev-parse --abbrev-ref HEAD 2>/dev/null)',
|
|
373
|
-
'
|
|
416
|
+
// The port is the authoritative one (it's what Nginx proxies to); read it
|
|
417
|
+
// from the deploy config the panel mirrors next to the clone.
|
|
418
|
+
' port=$(grep -oE \'"port"[[:space:]]*:[[:space:]]*[0-9]+\' "$dir/.easy-vps.json" 2>/dev/null | grep -oE \'[0-9]+\' | head -n1)',
|
|
419
|
+
' printf "%s\\t%s\\t%s\\t%s\\n" "$name" "$repo" "$branch" "$port"',
|
|
374
420
|
'done',
|
|
375
421
|
].join('\n');
|
|
376
422
|
const { stdout, code } = await remote.exec((0, ssh_1.loginShell)(script), 15_000);
|
|
@@ -380,10 +426,11 @@ async function clones(remote) {
|
|
|
380
426
|
.split('\n')
|
|
381
427
|
.map((line) => line.split('\t'))
|
|
382
428
|
.filter((parts) => parts[0]?.trim())
|
|
383
|
-
.map(([name, repository, branch]) => ({
|
|
429
|
+
.map(([name, repository, branch, port]) => ({
|
|
384
430
|
name: name.trim(),
|
|
385
431
|
repository: repository?.trim() ?? '',
|
|
386
432
|
branch: branch?.trim() || 'main',
|
|
433
|
+
port: port?.trim() ? Number(port.trim()) : undefined,
|
|
387
434
|
}));
|
|
388
435
|
}
|
|
389
436
|
/** PM2 processes by name, with the port they were started on. */
|
|
@@ -447,11 +494,13 @@ async function list(remote) {
|
|
|
447
494
|
domains.list(remote).catch(() => []),
|
|
448
495
|
]);
|
|
449
496
|
const domainForPort = new Map(configured.map((entry) => [entry.port, entry.domain]));
|
|
450
|
-
return cloned.map(({ name, repository, branch }) => {
|
|
497
|
+
return cloned.map(({ name, repository, branch, port: configPort }) => {
|
|
451
498
|
const process = pm2.get(name);
|
|
452
499
|
const container = docker.get(name);
|
|
453
500
|
const runtime = container && !process ? 'docker' : 'pm2';
|
|
454
|
-
|
|
501
|
+
// Prefer the saved deploy config's port (authoritative for the domain
|
|
502
|
+
// mapping); fall back to what PM2/Docker report, then 0.
|
|
503
|
+
const port = configPort ?? process?.port ?? container?.port ?? 0;
|
|
455
504
|
let status = 'unknown';
|
|
456
505
|
if (process)
|
|
457
506
|
status = process.status === 'online' ? 'running' : 'stopped';
|