novatec-cli 1.0.0 → 1.0.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/bin/index.js +81 -72
- package/lib/create.js +15 -16
- package/lib/utils.js +22 -9
- package/package.json +2 -2
package/bin/index.js
CHANGED
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
import { program } from 'commander';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import figlet from 'figlet';
|
|
6
|
-
import gradient from 'gradient-string';
|
|
7
6
|
import boxen from 'boxen';
|
|
8
|
-
import chalkAnimation from 'chalk-animation';
|
|
9
7
|
import { checkRequirements } from '../lib/utils.js';
|
|
10
8
|
import { runCreate } from '../lib/create.js';
|
|
11
9
|
|
|
@@ -13,108 +11,119 @@ function sleep(ms) {
|
|
|
13
11
|
return new Promise(r => setTimeout(r, ms));
|
|
14
12
|
}
|
|
15
13
|
|
|
16
|
-
// Cicla cada carácter entre morado puro → blanco → morado oscuro (efecto RGB)
|
|
17
|
-
function rgbCycle(text, offset = 0) {
|
|
18
|
-
const palette = [
|
|
19
|
-
[120, 0, 200], // morado oscuro
|
|
20
|
-
[160, 0, 255], // morado puro
|
|
21
|
-
[190, 60, 255], // morado medio
|
|
22
|
-
[215,120, 255], // lavanda
|
|
23
|
-
[235,180, 255], // lavanda claro
|
|
24
|
-
[255,255, 255], // blanco
|
|
25
|
-
[235,180, 255], // lavanda claro
|
|
26
|
-
[215,120, 255], // lavanda
|
|
27
|
-
[190, 60, 255], // morado medio
|
|
28
|
-
[160, 0, 255], // morado puro
|
|
29
|
-
];
|
|
30
|
-
return text.split('').map((ch, i) => {
|
|
31
|
-
if (ch === ' ') return ch;
|
|
32
|
-
const [r, g, b] = palette[(i + offset) % palette.length];
|
|
33
|
-
return chalk.rgb(r, g, b)(ch);
|
|
34
|
-
}).join('');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
14
|
async function showBanner() {
|
|
38
15
|
console.clear();
|
|
39
16
|
|
|
17
|
+
// Logo en blanco puro con sombra gris (efecto profundidad)
|
|
40
18
|
const logo = figlet.textSync('NOVATEC', { font: 'ANSI Shadow' });
|
|
41
19
|
const lines = logo.split('\n').filter(l => l.trim());
|
|
42
20
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
console.log();
|
|
48
|
-
lines.forEach((line, i) => {
|
|
49
|
-
console.log(' ' + rgbCycle(line, frame * 3 + i * 4));
|
|
50
|
-
});
|
|
51
|
-
await sleep(55);
|
|
52
|
-
}
|
|
21
|
+
console.log();
|
|
22
|
+
lines.forEach(line => {
|
|
23
|
+
console.log(' ' + chalk.bold.white(line));
|
|
24
|
+
});
|
|
53
25
|
|
|
54
26
|
console.log();
|
|
55
27
|
|
|
56
|
-
// Subtítulo
|
|
57
|
-
const sub = '
|
|
58
|
-
|
|
59
|
-
await sleep(1200);
|
|
60
|
-
anim.stop();
|
|
61
|
-
process.stdout.write('\r');
|
|
62
|
-
console.log(gradient(['#7B00FF', '#FFFFFF', '#7B00FF'])(sub));
|
|
28
|
+
// Subtítulo elegante
|
|
29
|
+
const sub = ' ◈ NOVATEC FULLSTACK CLI · Generador Profesional de Proyectos ◈';
|
|
30
|
+
console.log(chalk.gray(sub));
|
|
63
31
|
console.log();
|
|
64
32
|
|
|
65
|
-
// Separador
|
|
66
|
-
|
|
67
|
-
console.log(' ' + rgbCycle(sep, 0));
|
|
33
|
+
// Separador
|
|
34
|
+
console.log(' ' + chalk.white('─'.repeat(66)));
|
|
68
35
|
console.log();
|
|
69
36
|
|
|
70
|
-
//
|
|
37
|
+
// Stats rápidos
|
|
38
|
+
console.log(
|
|
39
|
+
' ' +
|
|
40
|
+
chalk.white.bold('10') + chalk.gray(' frontends ') +
|
|
41
|
+
chalk.white('·') +
|
|
42
|
+
chalk.white.bold(' 10') + chalk.gray(' backends ') +
|
|
43
|
+
chalk.white('·') +
|
|
44
|
+
chalk.white.bold(' 100%') + chalk.gray(' listo para producción')
|
|
45
|
+
);
|
|
46
|
+
console.log();
|
|
47
|
+
|
|
48
|
+
// Caja de tecnologías — blanco y negro elegante
|
|
71
49
|
console.log(
|
|
72
50
|
boxen(
|
|
73
|
-
|
|
74
|
-
|
|
51
|
+
chalk.bold.white(' TECNOLOGÍAS DISPONIBLES') + '\n\n' +
|
|
52
|
+
|
|
53
|
+
chalk.white.bold(' Frontend') + chalk.gray(' │ ') +
|
|
75
54
|
[
|
|
76
|
-
chalk.
|
|
55
|
+
chalk.white('React'),
|
|
77
56
|
chalk.white('Next.js'),
|
|
78
|
-
chalk.
|
|
79
|
-
chalk.
|
|
80
|
-
chalk.
|
|
81
|
-
chalk.
|
|
82
|
-
chalk.
|
|
83
|
-
chalk.
|
|
84
|
-
chalk.
|
|
85
|
-
chalk.
|
|
86
|
-
].join(chalk.gray('
|
|
87
|
-
|
|
57
|
+
chalk.white('Vue'),
|
|
58
|
+
chalk.white('Nuxt'),
|
|
59
|
+
chalk.white('Astro'),
|
|
60
|
+
chalk.white('Svelte'),
|
|
61
|
+
chalk.white('SolidJS'),
|
|
62
|
+
chalk.white('Angular'),
|
|
63
|
+
chalk.white('Remix'),
|
|
64
|
+
chalk.white('Qwik'),
|
|
65
|
+
].join(chalk.gray(' · ')) + '\n\n' +
|
|
66
|
+
|
|
67
|
+
chalk.white.bold(' Backend ') + chalk.gray(' │ ') +
|
|
88
68
|
[
|
|
89
|
-
chalk.
|
|
90
|
-
chalk.
|
|
69
|
+
chalk.white('Express'),
|
|
70
|
+
chalk.white('NestJS'),
|
|
91
71
|
chalk.white('Fastify'),
|
|
92
|
-
chalk.
|
|
93
|
-
chalk.
|
|
94
|
-
chalk.
|
|
95
|
-
chalk.
|
|
96
|
-
chalk.
|
|
72
|
+
chalk.white('Hono'),
|
|
73
|
+
chalk.white('FastAPI'),
|
|
74
|
+
chalk.white('Django'),
|
|
75
|
+
chalk.white('Flask'),
|
|
76
|
+
chalk.white('Spring'),
|
|
97
77
|
chalk.white('Deno'),
|
|
98
|
-
chalk.
|
|
99
|
-
].join(chalk.gray('
|
|
78
|
+
chalk.white('Go/Gin'),
|
|
79
|
+
].join(chalk.gray(' · ')) + '\n\n' +
|
|
80
|
+
|
|
81
|
+
chalk.white.bold(' Extras ') + chalk.gray(' │ ') +
|
|
82
|
+
[
|
|
83
|
+
chalk.gray('Docker'),
|
|
84
|
+
chalk.gray('ESLint + Prettier'),
|
|
85
|
+
chalk.gray('Husky'),
|
|
86
|
+
chalk.gray('Jest / Vitest'),
|
|
87
|
+
chalk.gray('GitHub Actions'),
|
|
88
|
+
chalk.gray('.env'),
|
|
89
|
+
].join(chalk.gray(' · ')),
|
|
90
|
+
{
|
|
91
|
+
padding: { top: 1, bottom: 1, left: 2, right: 4 },
|
|
92
|
+
margin: { left: 2 },
|
|
93
|
+
borderStyle: 'round',
|
|
94
|
+
borderColor: 'white',
|
|
95
|
+
dimBorder: true,
|
|
96
|
+
}
|
|
97
|
+
)
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
console.log();
|
|
101
|
+
|
|
102
|
+
// Uso rápido
|
|
103
|
+
console.log(
|
|
104
|
+
boxen(
|
|
105
|
+
chalk.gray(' Uso rápido\n\n') +
|
|
106
|
+
chalk.white(' $ novatec-cli create ') + chalk.gray('<nombre-proyecto>') + '\n\n' +
|
|
107
|
+
chalk.white(' $ novatec-cli create my-app ') + chalk.gray('--frontend react --backend express'),
|
|
100
108
|
{
|
|
101
|
-
padding: { top:
|
|
109
|
+
padding: { top: 0, bottom: 0, left: 1, right: 4 },
|
|
102
110
|
margin: { left: 2 },
|
|
103
|
-
borderStyle: '
|
|
104
|
-
borderColor: '
|
|
111
|
+
borderStyle: 'single',
|
|
112
|
+
borderColor: 'gray',
|
|
113
|
+
dimBorder: true,
|
|
105
114
|
}
|
|
106
115
|
)
|
|
107
116
|
);
|
|
108
117
|
|
|
109
118
|
console.log();
|
|
110
|
-
console.log(' ' +
|
|
119
|
+
console.log(' ' + chalk.white('─'.repeat(66)));
|
|
111
120
|
console.log();
|
|
112
121
|
}
|
|
113
122
|
|
|
114
123
|
program
|
|
115
|
-
.name('novatec
|
|
124
|
+
.name('novatec')
|
|
116
125
|
.description('NOVATEC FULLSTACK CLI — Generador profesional de proyectos full stack')
|
|
117
|
-
.version('1.0.
|
|
126
|
+
.version('1.0.2', '-v, --version', 'Mostrar versión');
|
|
118
127
|
|
|
119
128
|
program
|
|
120
129
|
.command('create [name]')
|
package/lib/create.js
CHANGED
|
@@ -8,7 +8,6 @@ import { generateReadme } from './generators/readme.js';
|
|
|
8
8
|
import { run, isInstalled } from './utils.js';
|
|
9
9
|
|
|
10
10
|
const boxen = await import('boxen');
|
|
11
|
-
const gradient = await import('gradient-string');
|
|
12
11
|
|
|
13
12
|
async function runCreate(nameArg, options) {
|
|
14
13
|
const config = await askProjectOptions(nameArg, options);
|
|
@@ -41,7 +40,6 @@ async function runCreate(nameArg, options) {
|
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
// Resumen final
|
|
44
|
-
const novatecGradient = gradient.default(['#00C6FF', '#0072FF', '#7B2FF7']);
|
|
45
43
|
const backendCmd = {
|
|
46
44
|
express: 'npm run dev',
|
|
47
45
|
nestjs: 'npm run start:dev',
|
|
@@ -55,25 +53,26 @@ async function runCreate(nameArg, options) {
|
|
|
55
53
|
gin: 'go run main.go'
|
|
56
54
|
};
|
|
57
55
|
|
|
56
|
+
// Resumen final
|
|
58
57
|
console.log(
|
|
59
58
|
boxen.default(
|
|
60
|
-
|
|
61
|
-
chalk.
|
|
62
|
-
chalk.white('
|
|
63
|
-
chalk.white('
|
|
64
|
-
chalk.
|
|
65
|
-
chalk.
|
|
66
|
-
chalk.
|
|
67
|
-
chalk.white(
|
|
68
|
-
chalk.
|
|
69
|
-
chalk.
|
|
70
|
-
chalk.white(`
|
|
71
|
-
chalk.cyan(` ${backendCmd[config.backend] || 'npm start'}`),
|
|
59
|
+
chalk.bold.white(' ✔ PROYECTO CREADO EXITOSAMENTE\n\n') +
|
|
60
|
+
chalk.white(' Nombre ') + chalk.gray('│ ') + chalk.bold.white(config.name) + '\n' +
|
|
61
|
+
chalk.white(' Frontend ') + chalk.gray('│ ') + chalk.bold.white(config.frontend) + '\n' +
|
|
62
|
+
chalk.white(' Backend ') + chalk.gray('│ ') + chalk.bold.white(config.backend) + '\n\n' +
|
|
63
|
+
chalk.gray(' ─────────────────────────────────────────\n\n') +
|
|
64
|
+
chalk.white(' Iniciar Frontend\n') +
|
|
65
|
+
chalk.gray(` cd ${config.name}/frontend\n`) +
|
|
66
|
+
chalk.white(' npm run dev\n\n') +
|
|
67
|
+
chalk.white(' Iniciar Backend\n') +
|
|
68
|
+
chalk.gray(` cd ${config.name}/backend\n`) +
|
|
69
|
+
chalk.white(` ${backendCmd[config.backend] || 'npm start'}`),
|
|
72
70
|
{
|
|
73
71
|
padding: 1,
|
|
74
72
|
margin: { top: 1, left: 2 },
|
|
75
|
-
borderStyle: '
|
|
76
|
-
borderColor: '
|
|
73
|
+
borderStyle: 'round',
|
|
74
|
+
borderColor: 'white',
|
|
75
|
+
dimBorder: true,
|
|
77
76
|
}
|
|
78
77
|
)
|
|
79
78
|
);
|
package/lib/utils.js
CHANGED
|
@@ -8,33 +8,46 @@ export function isInstalled(cmd) {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export async function checkRequirements() {
|
|
11
|
-
const spinner = ora({
|
|
11
|
+
const spinner = ora({
|
|
12
|
+
text: chalk.white('Verificando entorno del sistema...'),
|
|
13
|
+
spinner: 'aesthetic',
|
|
14
|
+
color: 'white',
|
|
15
|
+
}).start();
|
|
16
|
+
|
|
12
17
|
const missing = [];
|
|
13
18
|
if (!isInstalled('node')) missing.push('Node.js');
|
|
14
19
|
if (!isInstalled('npm')) missing.push('npm');
|
|
20
|
+
|
|
15
21
|
if (missing.length) {
|
|
16
22
|
spinner.fail(chalk.red('Faltan herramientas: ' + missing.join(', ')));
|
|
17
23
|
throw new Error('Instala las herramientas faltantes y vuelve a intentarlo.');
|
|
18
24
|
}
|
|
25
|
+
|
|
19
26
|
const nodeVer = execSync('node --version', { encoding: 'utf8' }).trim();
|
|
20
27
|
const npmVer = execSync('npm --version', { encoding: 'utf8' }).trim();
|
|
28
|
+
|
|
21
29
|
spinner.succeed(
|
|
22
|
-
chalk.
|
|
23
|
-
chalk.gray('
|
|
24
|
-
chalk.
|
|
25
|
-
chalk.gray('│') +
|
|
26
|
-
chalk.cyan(` npm v${npmVer}`)
|
|
30
|
+
chalk.white('Entorno listo ') +
|
|
31
|
+
chalk.gray('· Node ') + chalk.bold.white(nodeVer) +
|
|
32
|
+
chalk.gray(' · npm ') + chalk.bold.white('v' + npmVer)
|
|
27
33
|
);
|
|
28
34
|
console.log();
|
|
29
35
|
}
|
|
30
36
|
|
|
31
37
|
export function run(cmd, cwd, label) {
|
|
32
|
-
const spinner = ora({
|
|
38
|
+
const spinner = ora({
|
|
39
|
+
text: chalk.white(label),
|
|
40
|
+
spinner: 'dots',
|
|
41
|
+
color: 'white',
|
|
42
|
+
}).start();
|
|
43
|
+
|
|
33
44
|
const result = spawnSync(cmd, { cwd, shell: true, stdio: 'pipe', encoding: 'utf8' });
|
|
45
|
+
|
|
34
46
|
if (result.status !== 0) {
|
|
35
|
-
spinner.fail(chalk.red(
|
|
47
|
+
spinner.fail(chalk.red('✖ ' + label));
|
|
36
48
|
const msg = result.stderr || result.stdout || 'Error desconocido';
|
|
37
49
|
throw new Error(msg.trim());
|
|
38
50
|
}
|
|
39
|
-
|
|
51
|
+
|
|
52
|
+
spinner.succeed(chalk.white('✔ ' + label));
|
|
40
53
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "novatec-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "🚀 NOVATEC FULLSTACK CLI — Generador profesional de proyectos full stack | React, Next.js, Vue, Express, NestJS, FastAPI y más",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/create.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"novatec
|
|
8
|
+
"novatec": "bin/index.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"start": "node ./bin/index.js create test-project",
|