@batistafull/deploy-server 1.0.0 β 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/deploy-server.js +22 -37
- package/lib/deploy.js +108 -0
- package/package.json +15 -2
package/bin/deploy-server.js
CHANGED
|
@@ -1,39 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const {
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
execSync("npm run build", {
|
|
26
|
-
cwd: projectRoot,
|
|
27
|
-
stdio: "inherit"
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
console.log("π¦ Copiando dist...");
|
|
31
|
-
fs.cpSync(distPath, destination, { recursive: true });
|
|
32
|
-
|
|
33
|
-
console.log("π¦ Copiando server/api...");
|
|
34
|
-
fs.cpSync(apiPath, destination, { recursive: true });
|
|
35
|
-
|
|
36
|
-
console.log("β
Deploy completado en:", destination);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
run();
|
|
3
|
+
const { program } = require("commander");
|
|
4
|
+
const chalk = require("chalk");
|
|
5
|
+
const deploy = require("../lib/deploy");
|
|
6
|
+
|
|
7
|
+
program
|
|
8
|
+
.name("deploy-server")
|
|
9
|
+
.description("Config-driven deploy tool")
|
|
10
|
+
.option("--config <path>", "config file path", "deploy.config.json")
|
|
11
|
+
.option("--clean", "clean output folder before deploy")
|
|
12
|
+
.action(async (options) => {
|
|
13
|
+
console.log(chalk.blue("π Loading deploy config..."));
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
await deploy(options);
|
|
17
|
+
console.log(chalk.green("β
Deploy completed"));
|
|
18
|
+
} catch (err) {
|
|
19
|
+
console.error(chalk.red("β Deploy failed:"), err);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
program.parse();
|
package/lib/deploy.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const os = require("os");
|
|
3
|
+
const fs = require("fs-extra");
|
|
4
|
+
const chalk = require("chalk");
|
|
5
|
+
const { execSync } = require("child_process");
|
|
6
|
+
const ftp = require("basic-ftp");
|
|
7
|
+
|
|
8
|
+
// Ejecuta una lista de comandos de build en orden
|
|
9
|
+
function runBuildCommands(commands, cwd) {
|
|
10
|
+
for (const command of commands) {
|
|
11
|
+
console.log(chalk.gray(`π¨ $ ${command}`));
|
|
12
|
+
execSync(command, { cwd, stdio: "inherit" });
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Copia un directorio excluyendo los patrones indicados (match por nombre o ruta relativa)
|
|
17
|
+
async function copyFiltered(srcPath, destPath, exclude = []) {
|
|
18
|
+
if (!(await fs.pathExists(srcPath))) {
|
|
19
|
+
console.log(chalk.yellow(`β οΈ Origen no encontrado, se omite: ${srcPath}`));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
await fs.copy(srcPath, destPath, {
|
|
24
|
+
filter: (src) => {
|
|
25
|
+
const relative = path.relative(srcPath, src);
|
|
26
|
+
if (!relative) return true; // el propio directorio raΓz
|
|
27
|
+
const name = path.basename(src);
|
|
28
|
+
return !exclude.some(
|
|
29
|
+
(pattern) => name === pattern || relative.split(path.sep).includes(pattern)
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = async function deploy(options) {
|
|
36
|
+
const config = require(path.resolve(process.cwd(), options.config));
|
|
37
|
+
|
|
38
|
+
const projectRoot = process.cwd();
|
|
39
|
+
|
|
40
|
+
const documentsPath =
|
|
41
|
+
process.platform === "win32"
|
|
42
|
+
? path.join(process.env.USERPROFILE, "Documents")
|
|
43
|
+
: path.join(os.homedir(), "Documents");
|
|
44
|
+
|
|
45
|
+
const outputPath = path.join(documentsPath, config.output);
|
|
46
|
+
|
|
47
|
+
const distPath = path.join(projectRoot, config.dist);
|
|
48
|
+
const serverPath = path.join(projectRoot, config.server);
|
|
49
|
+
|
|
50
|
+
// Clean
|
|
51
|
+
if (options.clean) {
|
|
52
|
+
console.log(chalk.gray("π§Ή Cleaning output..."));
|
|
53
|
+
await fs.remove(outputPath);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
await fs.ensureDir(outputPath);
|
|
57
|
+
|
|
58
|
+
// BUILD (ARRAY)
|
|
59
|
+
if (Array.isArray(config.buildCommand)) {
|
|
60
|
+
runBuildCommands(config.buildCommand, projectRoot);
|
|
61
|
+
} else {
|
|
62
|
+
execSync(config.buildCommand, {
|
|
63
|
+
cwd: projectRoot,
|
|
64
|
+
stdio: "inherit"
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// COPY DIST
|
|
69
|
+
console.log(chalk.blue("π¦ Copying dist..."));
|
|
70
|
+
await copyFiltered(distPath, outputPath, config.exclude || []);
|
|
71
|
+
|
|
72
|
+
// COPY SERVER
|
|
73
|
+
console.log(chalk.blue("π¦ Copying server..."));
|
|
74
|
+
await copyFiltered(serverPath, outputPath, config.exclude || []);
|
|
75
|
+
|
|
76
|
+
// FTP (opcional)
|
|
77
|
+
if (config.ftp?.enabled) {
|
|
78
|
+
const client = new ftp.Client();
|
|
79
|
+
|
|
80
|
+
// Las credenciales se leen preferentemente de variables de entorno.
|
|
81
|
+
// El config solo debe usarse como fallback para valores no sensibles.
|
|
82
|
+
const host = process.env.FTP_HOST || config.ftp.host;
|
|
83
|
+
const user = process.env.FTP_USER || config.ftp.user;
|
|
84
|
+
const password = process.env.FTP_PASSWORD || config.ftp.password;
|
|
85
|
+
// FTPS por defecto; poner ftp.secure=false en el config solo si el
|
|
86
|
+
// servidor no soporta TLS (no recomendado).
|
|
87
|
+
const secure = config.ftp.secure !== false;
|
|
88
|
+
|
|
89
|
+
if (!host || !user || !password) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
"FTP habilitado pero faltan credenciales. Define FTP_HOST, FTP_USER y FTP_PASSWORD (o config.ftp.*)."
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
console.log(chalk.yellow(`π‘ Connecting FTP (${secure ? "FTPS" : "sin cifrar"})...`));
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
await client.access({ host, user, password, secure });
|
|
99
|
+
|
|
100
|
+
await client.ensureDir(config.ftp.remotePath);
|
|
101
|
+
await client.uploadFromDir(outputPath);
|
|
102
|
+
|
|
103
|
+
console.log(chalk.green("π FTP upload done"));
|
|
104
|
+
} finally {
|
|
105
|
+
client.close();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
package/package.json
CHANGED
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@batistafull/deploy-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Deploy tool that builds and copies dist + api to Documents/app.host",
|
|
5
5
|
"main": "bin/deploy-server.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"deploy-server": "bin/deploy-server.js"
|
|
8
8
|
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"lib/"
|
|
12
|
+
],
|
|
9
13
|
"keywords": ["deploy", "cli", "nodejs"],
|
|
10
14
|
"author": "batistafull",
|
|
11
15
|
"license": "MIT",
|
|
12
|
-
"type": "commonjs"
|
|
16
|
+
"type": "commonjs",
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=16"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"basic-ftp": "^5.0.5",
|
|
22
|
+
"chalk": "^4.1.2",
|
|
23
|
+
"commander": "^12.1.0",
|
|
24
|
+
"fs-extra": "^11.2.0"
|
|
25
|
+
}
|
|
13
26
|
}
|