entexto-cli 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/entexto.js CHANGED
@@ -55,7 +55,18 @@ program
55
55
  saveConfig({ token: null, user: null });
56
56
  console.log('Sesión cerrada.');
57
57
  });
58
-
58
+ // ─── entexto pull / clone ────────────────────────────
59
+ const pullAction = require('../lib/commands/pull');
60
+ [
61
+ program.command('pull'),
62
+ program.command('clone'),
63
+ ].forEach(cmd => {
64
+ cmd
65
+ .description('Descargar archivos de un proyecto al disco local')
66
+ .option('-i, --id <uuid>', 'UUID del proyecto a descargar')
67
+ .option('-d, --dir <path>', 'Carpeta destino (default: carpeta actual)', '.')
68
+ .action(pullAction);
69
+ });
59
70
  program.parse(process.argv);
60
71
 
61
72
  if (!process.argv.slice(2).length) {
@@ -0,0 +1,105 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const inquirer = require('inquirer');
6
+ const chalk = require('chalk');
7
+ const ora = require('ora');
8
+ const { getToken } = require('../utils/config');
9
+ const { getProjects, pullProject } = require('../utils/api');
10
+
11
+ module.exports = async function pull(options) {
12
+ if (!getToken()) {
13
+ console.error(chalk.red('✖ No has iniciado sesión. Ejecuta: entexto login'));
14
+ process.exit(1);
15
+ }
16
+
17
+ let uuid = options.id || null;
18
+
19
+ // Si no se pasó --id, mostrar selector interactivo
20
+ if (!uuid) {
21
+ let proyectos;
22
+ const spinner = ora('Cargando proyectos...').start();
23
+ try {
24
+ proyectos = await getProjects();
25
+ spinner.stop();
26
+ } catch (err) {
27
+ spinner.stop();
28
+ console.error(chalk.red('✖ Error al obtener proyectos:'), err.message);
29
+ process.exit(1);
30
+ }
31
+
32
+ if (!proyectos || proyectos.length === 0) {
33
+ console.log(chalk.yellow('No tienes proyectos todavía.'));
34
+ return;
35
+ }
36
+
37
+ const choices = proyectos.map((p, i) => ({
38
+ name: `${String(i + 1).padStart(2, ' ')}. ${p.name}${p.is_published ? chalk.green(' [publicado]') : ''} ${chalk.gray(p.project_uuid)}`,
39
+ value: p.project_uuid,
40
+ short: p.name,
41
+ }));
42
+
43
+ const { selectedUuid } = await inquirer.prompt([{
44
+ type: 'list',
45
+ name: 'selectedUuid',
46
+ message: 'Elige el proyecto a descargar:',
47
+ choices,
48
+ pageSize: 15,
49
+ }]);
50
+
51
+ uuid = selectedUuid;
52
+ }
53
+
54
+ // Carpeta destino
55
+ let destDir = options.dir || null;
56
+ if (!destDir) {
57
+ const { dir } = await inquirer.prompt([{
58
+ type: 'input',
59
+ name: 'dir',
60
+ message: 'Carpeta de destino (Enter = carpeta actual):',
61
+ default: '.',
62
+ }]);
63
+ destDir = dir || '.';
64
+ }
65
+
66
+ const absDir = path.resolve(destDir);
67
+
68
+ // Descargar
69
+ const spinnerPull = ora('Descargando archivos...').start();
70
+ let data;
71
+ try {
72
+ data = await pullProject(uuid);
73
+ spinnerPull.succeed(`Proyecto "${data.proyecto.name}" — ${data.total} archivo(s)`);
74
+ } catch (err) {
75
+ spinnerPull.fail('Error al descargar');
76
+ const msg = err.response ? err.response.data : err.message;
77
+ console.error(chalk.red(typeof msg === 'object' ? msg.error : msg));
78
+ process.exit(1);
79
+ }
80
+
81
+ if (!data.archivos || data.archivos.length === 0) {
82
+ console.log(chalk.yellow('El proyecto no tiene archivos.'));
83
+ return;
84
+ }
85
+
86
+ // Escribir archivos localmente
87
+ let escritos = 0;
88
+ for (const { ruta, content } of data.archivos) {
89
+ const destFile = path.join(absDir, ruta);
90
+ const dir = path.dirname(destFile);
91
+
92
+ try {
93
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
94
+ fs.writeFileSync(destFile, content, 'utf8');
95
+ escritos++;
96
+ } catch (err) {
97
+ console.warn(chalk.yellow(` ⚠ No se pudo escribir: ${ruta} — ${err.message}`));
98
+ }
99
+ }
100
+
101
+ console.log(chalk.green(`\n✔ ${escritos} archivo(s) descargados en: ${absDir}`));
102
+ if (data.proyecto.slug) {
103
+ console.log(chalk.gray(` Preview: https://entexto.com/p/${data.proyecto.slug}`));
104
+ }
105
+ };
package/lib/utils/api.js CHANGED
@@ -59,4 +59,9 @@ async function publishProject(uuid) {
59
59
  return res.data;
60
60
  }
61
61
 
62
- module.exports = { login, getProjects, deployFiles, deployWithPublish, publishProject };
62
+ async function pullProject(uuid) {
63
+ const res = await client().get(`/api/cli/pull/${uuid}`);
64
+ return res.data;
65
+ }
66
+
67
+ module.exports = { login, getProjects, deployFiles, deployWithPublish, publishProject, pullProject };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "entexto-cli",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "CLI oficial de Entexto — Deploy y gestión de proyectos desde tu terminal",
5
5
  "main": "lib/index.js",
6
6
  "bin": {