novatec-cli 3.0.1 β†’ 3.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/lib/create.js CHANGED
@@ -2,7 +2,7 @@ import path from 'path';
2
2
  import chalk from 'chalk';
3
3
  import fse from 'fs-extra';
4
4
  import boxen from 'boxen';
5
- import { spawnSync } from 'child_process';
5
+ import { execSync } from 'child_process';
6
6
  import { askProjectOptions } from './prompts.js';
7
7
  import { generateFrontend } from './generators/frontend.js';
8
8
  import { generateBackend } from './generators/backend.js';
@@ -123,7 +123,7 @@ export async function runCreate(nameArg, options) {
123
123
  if (extras.includes('git') && isInstalled('git')) {
124
124
  tick('Git init...');
125
125
  try {
126
- spawnSync('git', ['init'], { cwd: root, shell: true, stdio: 'pipe' });
126
+ execSync('git init', { cwd: root, stdio: 'pipe' });
127
127
  await fse.writeFile(path.join(root, '.gitignore'), GITIGNORE);
128
128
  } catch {}
129
129
  }
@@ -134,9 +134,9 @@ export async function runCreate(nameArg, options) {
134
134
  const fe = path.join(root, 'frontend');
135
135
  const be = path.join(root, 'backend');
136
136
  const installCmd = pm === 'yarn' ? 'yarn' : `${pm} install`;
137
- try { spawnSync(installCmd, { cwd: fe, shell: true, stdio: 'pipe' }); } catch {}
137
+ try { execSync(installCmd, { cwd: fe, stdio: 'pipe' }); } catch {}
138
138
  if (!isPython) {
139
- try { spawnSync(installCmd, { cwd: be, shell: true, stdio: 'pipe' }); } catch {}
139
+ try { execSync(installCmd, { cwd: be, stdio: 'pipe' }); } catch {}
140
140
  }
141
141
  }
142
142
 
@@ -168,7 +168,7 @@ export async function runCreate(nameArg, options) {
168
168
 
169
169
  // Abrir VS Code
170
170
  if (isInstalled('code')) {
171
- try { spawnSync('code', [root], { shell: true, stdio: 'ignore', detached: true }); } catch {}
171
+ try { execSync(`code "${root}"`, { stdio: 'ignore' }); } catch {}
172
172
  console.log(' ' + chalk.gray('VS Code abierto βœ”'));
173
173
  }
174
174
  console.log();
package/lib/doctor.js CHANGED
@@ -1,12 +1,6 @@
1
1
  import chalk from 'chalk';
2
2
  import boxen from 'boxen';
3
- import { spawnSync, execSync } from 'child_process';
4
-
5
- function check(cmd, args = ['--version']) {
6
- const r = spawnSync(cmd, args, { stdio: 'pipe', shell: true, encoding: 'utf8' });
7
- if (r.status !== 0) return null;
8
- return (r.stdout || r.stderr || '').trim().split('\n')[0];
9
- }
3
+ import { execSync } from 'child_process';
10
4
 
11
5
  function getVersion(cmd) {
12
6
  try { return execSync(`${cmd} --version`, { encoding: 'utf8', stdio: 'pipe' }).trim().split('\n')[0]; } catch { return null; }
@@ -1,8 +1,20 @@
1
1
  import path from 'path';
2
2
  import chalk from 'chalk';
3
3
  import fse from 'fs-extra';
4
+ import { spawnSync } from 'child_process';
4
5
  import { run, isInstalled } from '../utils.js';
5
6
 
7
+ function installNodeDeps(prod, dev, cwd, label) {
8
+ if (prod.length) {
9
+ const r = spawnSync('npm', ['install', ...prod], { cwd, stdio: 'pipe', encoding: 'utf8' });
10
+ if (r.status !== 0) throw new Error((r.stderr || r.stdout || '').trim() || `Error instalando: ${prod.join(', ')}`);
11
+ }
12
+ if (dev.length) {
13
+ const r = spawnSync('npm', ['install', '-D', ...dev], { cwd, stdio: 'pipe', encoding: 'utf8' });
14
+ if (r.status !== 0) throw new Error((r.stderr || r.stdout || '').trim() || `Error instalando dev: ${dev.join(', ')}`);
15
+ }
16
+ }
17
+
6
18
  async function generateBackend(config, projectPath) {
7
19
  console.log(chalk.blue(`\nπŸ”§ Generando backend (${chalk.bold(config.backend)})...`));
8
20
  const handlers = { express, nestjs, fastify, hono, fastapi, django, flask, spring, deno, gin };
@@ -2,7 +2,7 @@ import path from 'path';
2
2
  import fse from 'fs-extra';
3
3
  import chalk from 'chalk';
4
4
  import boxen from 'boxen';
5
- import { spawnSync } from 'child_process';
5
+ import { execSync } from 'child_process';
6
6
  import { isInstalled } from '../utils.js';
7
7
 
8
8
  // ── GitHub Actions CI ─────────────────────────────────────────────────────────
@@ -108,8 +108,12 @@ export async function runBuild(options) {
108
108
 
109
109
  if ((options.frontend || !options.backend) && hasFe) {
110
110
  const spinner = (await import('ora')).default({ text: chalk.white('Build frontend...'), spinner: 'dots', color: 'white' }).start();
111
- const r = spawnSync('npm run build', { cwd: path.join(root, 'frontend'), shell: true, stdio: 'pipe', encoding: 'utf8' });
112
- r.status === 0 ? spinner.succeed(chalk.white('Frontend build OK')) : spinner.fail(chalk.red('Frontend build fallΓ³\n' + r.stderr));
111
+ try {
112
+ execSync('npm run build', { cwd: path.join(root, 'frontend'), stdio: 'pipe', encoding: 'utf8' });
113
+ spinner.succeed(chalk.white('Frontend build OK'));
114
+ } catch (err) {
115
+ spinner.fail(chalk.red('Frontend build fallΓ³\n' + (err.stderr || '')));
116
+ }
113
117
  }
114
118
 
115
119
  if ((options.backend || !options.frontend) && hasBe) {
@@ -118,8 +122,12 @@ export async function runBuild(options) {
118
122
  const pkg = await fse.readJSON(pkgPath);
119
123
  if (pkg.scripts?.build) {
120
124
  const spinner = (await import('ora')).default({ text: chalk.white('Build backend...'), spinner: 'dots', color: 'white' }).start();
121
- const r = spawnSync('npm run build', { cwd: path.join(root, 'backend'), shell: true, stdio: 'pipe', encoding: 'utf8' });
122
- r.status === 0 ? spinner.succeed(chalk.white('Backend build OK')) : spinner.fail(chalk.red('Backend build fallΓ³'));
125
+ try {
126
+ execSync('npm run build', { cwd: path.join(root, 'backend'), stdio: 'pipe', encoding: 'utf8' });
127
+ spinner.succeed(chalk.white('Backend build OK'));
128
+ } catch {
129
+ spinner.fail(chalk.red('Backend build fallΓ³'));
130
+ }
123
131
  }
124
132
  }
125
133
  }
@@ -147,19 +155,19 @@ export async function runDeploy(options) {
147
155
  if ((options.frontend || !options.backend)) {
148
156
  if (!isInstalled('vercel')) {
149
157
  console.log(chalk.yellow('\n Instalando Vercel CLI...'));
150
- spawnSync('npm install -g vercel', { shell: true, stdio: 'inherit' });
158
+ execSync('npm install -g vercel', { stdio: 'inherit' });
151
159
  }
152
160
  console.log(chalk.white('\n Desplegando frontend en Vercel...'));
153
- spawnSync('vercel --prod', { cwd: path.join(root, 'frontend'), shell: true, stdio: 'inherit' });
161
+ execSync('vercel --prod', { cwd: path.join(root, 'frontend'), stdio: 'inherit' });
154
162
  }
155
163
 
156
164
  if ((options.backend || !options.frontend)) {
157
165
  if (!isInstalled('railway')) {
158
166
  console.log(chalk.yellow('\n Instalando Railway CLI...'));
159
- spawnSync('npm install -g @railway/cli', { shell: true, stdio: 'inherit' });
167
+ execSync('npm install -g @railway/cli', { stdio: 'inherit' });
160
168
  }
161
169
  console.log(chalk.white('\n Desplegando backend en Railway...'));
162
- spawnSync('railway up', { cwd: path.join(root, 'backend'), shell: true, stdio: 'inherit' });
170
+ execSync('railway up', { cwd: path.join(root, 'backend'), stdio: 'inherit' });
163
171
  }
164
172
 
165
173
  console.log();
package/lib/utils.js CHANGED
@@ -1,10 +1,14 @@
1
- import { execSync, spawnSync } from 'child_process';
1
+ import { execSync } from 'child_process';
2
2
  import chalk from 'chalk';
3
3
  import ora from 'ora';
4
4
 
5
5
  export function isInstalled(cmd) {
6
- const r = spawnSync(cmd, ['--version'], { stdio: 'pipe', shell: true });
7
- return r.status === 0;
6
+ try {
7
+ execSync(`${cmd} --version`, { stdio: 'pipe' });
8
+ return true;
9
+ } catch {
10
+ return false;
11
+ }
8
12
  }
9
13
 
10
14
  export async function checkRequirements() {
@@ -41,13 +45,11 @@ export function run(cmd, cwd, label) {
41
45
  color: 'white',
42
46
  }).start();
43
47
 
44
- const result = spawnSync(cmd, { cwd, shell: true, stdio: 'pipe', encoding: 'utf8' });
45
-
46
- if (result.status !== 0) {
48
+ try {
49
+ execSync(cmd, { cwd, stdio: 'pipe', encoding: 'utf8' });
50
+ spinner.succeed(chalk.white('βœ” ' + label));
51
+ } catch (err) {
47
52
  spinner.fail(chalk.red('βœ– ' + label));
48
- const msg = result.stderr || result.stdout || 'Error desconocido';
49
- throw new Error(msg.trim());
53
+ throw new Error((err.stderr || err.stdout || err.message || 'Error desconocido').trim());
50
54
  }
51
-
52
- spinner.succeed(chalk.white('βœ” ' + label));
53
55
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "novatec-cli",
3
- "version": "3.0.1",
3
+ "version": "3.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",