@create-lft-app/cli 1.0.3 → 1.0.5
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/README.md +120 -0
- package/dist/bin/cli.js +143 -88
- package/dist/bin/cli.js.map +1 -1
- package/dist/src/index.js +143 -88
- package/dist/src/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# @create-lft-app/cli
|
|
2
|
+
|
|
3
|
+
CLI para crear proyectos LFT con Next.js, GitHub, Supabase y Jira integrados.
|
|
4
|
+
|
|
5
|
+
## Instalacion
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @create-lft-app/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Configuracion
|
|
12
|
+
|
|
13
|
+
Antes de usar el CLI, configura las credenciales en un archivo `.env` en el directorio del paquete:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# ===========================================
|
|
17
|
+
# GITHUB
|
|
18
|
+
# ===========================================
|
|
19
|
+
# Token: https://github.com/settings/tokens/new
|
|
20
|
+
# Permisos necesarios: repo, read:org, admin:org (para crear repos en org)
|
|
21
|
+
LFT_GITHUB_TOKEN=ghp_xxxxxxxxxxxx
|
|
22
|
+
LFT_GITHUB_USERNAME=tu-usuario
|
|
23
|
+
LFT_GITHUB_ORG=tu-organizacion # Opcional, deja vacio para cuenta personal
|
|
24
|
+
|
|
25
|
+
# ===========================================
|
|
26
|
+
# SUPABASE
|
|
27
|
+
# ===========================================
|
|
28
|
+
# Token: https://supabase.com/dashboard/account/tokens
|
|
29
|
+
LFT_SUPABASE_TOKEN=sbp_xxxxxxxxxxxx
|
|
30
|
+
# Org ID: https://supabase.com/dashboard/org/[ORG_ID]/settings
|
|
31
|
+
LFT_SUPABASE_ORG_ID=xxxxxxxxxxxx
|
|
32
|
+
LFT_SUPABASE_REGION=us-east-1 # Opcional
|
|
33
|
+
|
|
34
|
+
# ===========================================
|
|
35
|
+
# JIRA
|
|
36
|
+
# ===========================================
|
|
37
|
+
# Token: https://id.atlassian.com/manage-profile/security/api-tokens
|
|
38
|
+
LFT_JIRA_TOKEN=ATATT3xxxxxxxxxxx
|
|
39
|
+
LFT_JIRA_EMAIL=tu-email@ejemplo.com
|
|
40
|
+
LFT_JIRA_DOMAIN=tu-dominio.atlassian.net
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Uso
|
|
44
|
+
|
|
45
|
+
### Crear un proyecto nuevo
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
create-lft-app mi-proyecto
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Crear proyecto con confirmacion automatica
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
create-lft-app mi-proyecto -y
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Opciones disponibles
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
create-lft-app [nombre-proyecto] [opciones]
|
|
61
|
+
|
|
62
|
+
Opciones:
|
|
63
|
+
-V, --version Muestra la version
|
|
64
|
+
--skip-github No crear repositorio en GitHub
|
|
65
|
+
--skip-supabase No crear proyecto en Supabase
|
|
66
|
+
--skip-jira No crear proyecto en Jira
|
|
67
|
+
--skip-git No inicializar git ni hacer push
|
|
68
|
+
-y, --yes Aceptar todas las confirmaciones
|
|
69
|
+
-h, --help Muestra ayuda
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Ejemplos
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# Crear proyecto completo
|
|
76
|
+
create-lft-app mi-app
|
|
77
|
+
|
|
78
|
+
# Crear solo con GitHub y Next.js (sin Supabase ni Jira)
|
|
79
|
+
create-lft-app mi-app --skip-supabase --skip-jira
|
|
80
|
+
|
|
81
|
+
# Crear proyecto local sin servicios externos
|
|
82
|
+
create-lft-app mi-app --skip-github --skip-supabase --skip-jira --skip-git
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Que crea el CLI
|
|
86
|
+
|
|
87
|
+
1. **GitHub**: Repositorio privado en tu cuenta u organizacion
|
|
88
|
+
2. **Supabase**: Proyecto con base de datos PostgreSQL
|
|
89
|
+
3. **Jira**: Proyecto de software con template Scrum
|
|
90
|
+
4. **Next.js**: Aplicacion con:
|
|
91
|
+
- TypeScript
|
|
92
|
+
- Tailwind CSS
|
|
93
|
+
- App Router
|
|
94
|
+
- ESLint
|
|
95
|
+
- Turbopack
|
|
96
|
+
|
|
97
|
+
## Recursos existentes
|
|
98
|
+
|
|
99
|
+
Si alguno de los recursos ya existe (repo, proyecto Supabase, proyecto Jira, o directorio), el CLI lo detecta y continua sin error, mostrando un checkmark con "(ya existe)".
|
|
100
|
+
|
|
101
|
+
## Desarrollo local
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Clonar repositorio
|
|
105
|
+
git clone https://github.com/Test-Boiler/create-lft-app.git
|
|
106
|
+
cd create-lft-app
|
|
107
|
+
|
|
108
|
+
# Instalar dependencias
|
|
109
|
+
npm install
|
|
110
|
+
|
|
111
|
+
# Build
|
|
112
|
+
npm run build
|
|
113
|
+
|
|
114
|
+
# Ejecutar localmente
|
|
115
|
+
node dist/bin/cli.js mi-proyecto
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Licencia
|
|
119
|
+
|
|
120
|
+
MIT
|
package/dist/bin/cli.js
CHANGED
|
@@ -8,21 +8,27 @@ import path4 from "path";
|
|
|
8
8
|
import { confirm } from "@inquirer/prompts";
|
|
9
9
|
|
|
10
10
|
// src/config/static-config.ts
|
|
11
|
+
import { config } from "dotenv";
|
|
12
|
+
import { fileURLToPath } from "url";
|
|
13
|
+
import { dirname, resolve } from "path";
|
|
14
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
15
|
+
var __dirname = dirname(__filename);
|
|
16
|
+
config({ path: resolve(__dirname, "../../.env"), quiet: true });
|
|
11
17
|
var STATIC_CONFIG = {
|
|
12
18
|
github: {
|
|
13
|
-
token: "
|
|
14
|
-
username: "
|
|
15
|
-
org: "
|
|
19
|
+
token: process.env.LFT_GITHUB_TOKEN || "",
|
|
20
|
+
username: process.env.LFT_GITHUB_USERNAME || "",
|
|
21
|
+
org: process.env.LFT_GITHUB_ORG || ""
|
|
16
22
|
},
|
|
17
23
|
supabase: {
|
|
18
|
-
token: "
|
|
19
|
-
orgId: "
|
|
20
|
-
region: "us-east-1"
|
|
24
|
+
token: process.env.LFT_SUPABASE_TOKEN || "",
|
|
25
|
+
orgId: process.env.LFT_SUPABASE_ORG_ID || "",
|
|
26
|
+
region: process.env.LFT_SUPABASE_REGION || "us-east-1"
|
|
21
27
|
},
|
|
22
28
|
jira: {
|
|
23
|
-
email: "
|
|
24
|
-
token: "
|
|
25
|
-
domain: "
|
|
29
|
+
email: process.env.LFT_JIRA_EMAIL || "",
|
|
30
|
+
token: process.env.LFT_JIRA_TOKEN || "",
|
|
31
|
+
domain: process.env.LFT_JIRA_DOMAIN || ""
|
|
26
32
|
}
|
|
27
33
|
};
|
|
28
34
|
|
|
@@ -53,7 +59,7 @@ async function loadConfig() {
|
|
|
53
59
|
};
|
|
54
60
|
}
|
|
55
61
|
async function hasConfig() {
|
|
56
|
-
return STATIC_CONFIG.github.token !== "
|
|
62
|
+
return STATIC_CONFIG.github.token !== "" && STATIC_CONFIG.supabase.token !== "" && STATIC_CONFIG.jira.token !== "";
|
|
57
63
|
}
|
|
58
64
|
|
|
59
65
|
// src/services/github.ts
|
|
@@ -79,10 +85,67 @@ async function withSpinner(text, fn, successText) {
|
|
|
79
85
|
}
|
|
80
86
|
}
|
|
81
87
|
|
|
88
|
+
// src/ui/logger.ts
|
|
89
|
+
import chalk from "chalk";
|
|
90
|
+
var logger = {
|
|
91
|
+
info: (message) => {
|
|
92
|
+
console.log(chalk.blue("\u2139"), message);
|
|
93
|
+
},
|
|
94
|
+
success: (message) => {
|
|
95
|
+
console.log(chalk.green("\u2714"), message);
|
|
96
|
+
},
|
|
97
|
+
warning: (message) => {
|
|
98
|
+
console.log(chalk.yellow("\u26A0"), message);
|
|
99
|
+
},
|
|
100
|
+
error: (message) => {
|
|
101
|
+
console.log(chalk.red("\u2716"), message);
|
|
102
|
+
},
|
|
103
|
+
step: (step, total, message) => {
|
|
104
|
+
console.log(chalk.cyan(`[${step}/${total}]`), message);
|
|
105
|
+
},
|
|
106
|
+
newLine: () => {
|
|
107
|
+
console.log();
|
|
108
|
+
},
|
|
109
|
+
divider: () => {
|
|
110
|
+
console.log(chalk.gray("\u2500".repeat(50)));
|
|
111
|
+
},
|
|
112
|
+
title: (message) => {
|
|
113
|
+
console.log(chalk.bold.white(message));
|
|
114
|
+
},
|
|
115
|
+
subtitle: (message) => {
|
|
116
|
+
console.log(chalk.gray(message));
|
|
117
|
+
},
|
|
118
|
+
link: (label, url) => {
|
|
119
|
+
console.log(` ${chalk.gray(label + ":")} ${chalk.cyan.underline(url)}`);
|
|
120
|
+
},
|
|
121
|
+
list: (items) => {
|
|
122
|
+
items.forEach((item) => {
|
|
123
|
+
console.log(chalk.gray(" \u2022"), item);
|
|
124
|
+
});
|
|
125
|
+
},
|
|
126
|
+
table: (rows) => {
|
|
127
|
+
const maxLabelLength = Math.max(...rows.map((r) => r.label.length));
|
|
128
|
+
rows.forEach(({ label, value }) => {
|
|
129
|
+
const paddedLabel = label.padEnd(maxLabelLength);
|
|
130
|
+
console.log(` ${chalk.gray(paddedLabel)} ${value}`);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
82
135
|
// src/services/github.ts
|
|
83
|
-
async function createGitHubRepo(projectName,
|
|
84
|
-
const octokit = new Octokit({ auth:
|
|
85
|
-
const org =
|
|
136
|
+
async function createGitHubRepo(projectName, config2) {
|
|
137
|
+
const octokit = new Octokit({ auth: config2.credentials.github.token });
|
|
138
|
+
const org = config2.defaults.githubOrg;
|
|
139
|
+
const owner = org || config2.credentials.github.username;
|
|
140
|
+
try {
|
|
141
|
+
const existing = await octokit.rest.repos.get({
|
|
142
|
+
owner,
|
|
143
|
+
repo: projectName
|
|
144
|
+
});
|
|
145
|
+
logger.success(`GitHub: ${owner}/${projectName} (ya existe)`);
|
|
146
|
+
return existing.data.html_url;
|
|
147
|
+
} catch {
|
|
148
|
+
}
|
|
86
149
|
return withSpinner(
|
|
87
150
|
"Creando repositorio en GitHub...",
|
|
88
151
|
async () => {
|
|
@@ -105,7 +168,7 @@ async function createGitHubRepo(projectName, config) {
|
|
|
105
168
|
}
|
|
106
169
|
return repo.data.html_url;
|
|
107
170
|
},
|
|
108
|
-
`
|
|
171
|
+
`GitHub: ${owner}/${projectName}`
|
|
109
172
|
);
|
|
110
173
|
}
|
|
111
174
|
|
|
@@ -124,7 +187,7 @@ async function waitForProjectReady(projectId, token, maxAttempts = 60) {
|
|
|
124
187
|
return;
|
|
125
188
|
}
|
|
126
189
|
}
|
|
127
|
-
await new Promise((
|
|
190
|
+
await new Promise((resolve2) => setTimeout(resolve2, 5e3));
|
|
128
191
|
spinner.text = `Provisionando base de datos... (${Math.floor((i + 1) * 5 / 60)}min ${(i + 1) * 5 % 60}s)`;
|
|
129
192
|
}
|
|
130
193
|
spinner.fail("Timeout esperando a que el proyecto est\xE9 listo");
|
|
@@ -145,10 +208,28 @@ async function getProjectApiKeys(projectId, token) {
|
|
|
145
208
|
}
|
|
146
209
|
return { anonKey, serviceKey };
|
|
147
210
|
}
|
|
148
|
-
async function
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
211
|
+
async function findExistingProject(projectName, token) {
|
|
212
|
+
const response = await fetch(`${SUPABASE_API_URL}/projects`, {
|
|
213
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
214
|
+
});
|
|
215
|
+
if (!response.ok) return null;
|
|
216
|
+
const projects = await response.json();
|
|
217
|
+
return projects.find((p) => p.name === projectName) || null;
|
|
218
|
+
}
|
|
219
|
+
async function createSupabaseProject(projectName, config2) {
|
|
220
|
+
const token = config2.credentials.supabase.accessToken;
|
|
221
|
+
const orgId = config2.credentials.supabase.organizationId;
|
|
222
|
+
const region = config2.defaults.supabaseRegion;
|
|
223
|
+
const existing = await findExistingProject(projectName, token);
|
|
224
|
+
if (existing) {
|
|
225
|
+
logger.success(`Supabase: ${projectName} (ya existe)`);
|
|
226
|
+
const { anonKey: anonKey2, serviceKey: serviceKey2 } = await getProjectApiKeys(existing.id, token);
|
|
227
|
+
return {
|
|
228
|
+
url: `https://${existing.id}.supabase.co`,
|
|
229
|
+
anonKey: anonKey2,
|
|
230
|
+
serviceKey: serviceKey2
|
|
231
|
+
};
|
|
232
|
+
}
|
|
152
233
|
const dbPassword = generateSecurePassword();
|
|
153
234
|
const project = await withSpinner(
|
|
154
235
|
"Creando proyecto en Supabase...",
|
|
@@ -193,8 +274,6 @@ function generateSecurePassword() {
|
|
|
193
274
|
}
|
|
194
275
|
|
|
195
276
|
// src/utils/validation.ts
|
|
196
|
-
import fs from "fs";
|
|
197
|
-
import path from "path";
|
|
198
277
|
function validateProjectName(name) {
|
|
199
278
|
if (!name || name.trim() === "") {
|
|
200
279
|
return { valid: false, error: "El nombre del proyecto no puede estar vac\xEDo" };
|
|
@@ -218,10 +297,6 @@ function validateProjectName(name) {
|
|
|
218
297
|
if (name.length > 50) {
|
|
219
298
|
return { valid: false, error: "El nombre no puede tener m\xE1s de 50 caracteres" };
|
|
220
299
|
}
|
|
221
|
-
const projectPath = path.resolve(process.cwd(), name);
|
|
222
|
-
if (fs.existsSync(projectPath)) {
|
|
223
|
-
return { valid: false, error: `El directorio "${name}" ya existe` };
|
|
224
|
-
}
|
|
225
300
|
return { valid: true };
|
|
226
301
|
}
|
|
227
302
|
function generateJiraKey(projectName) {
|
|
@@ -230,10 +305,29 @@ function generateJiraKey(projectName) {
|
|
|
230
305
|
}
|
|
231
306
|
|
|
232
307
|
// src/services/jira.ts
|
|
233
|
-
async function
|
|
234
|
-
const
|
|
308
|
+
async function findExistingJiraProject(projectName, auth, domain) {
|
|
309
|
+
const response = await fetch(
|
|
310
|
+
`https://${domain}/rest/api/3/project/search?query=${encodeURIComponent(projectName)}`,
|
|
311
|
+
{
|
|
312
|
+
headers: {
|
|
313
|
+
Authorization: `Basic ${auth}`,
|
|
314
|
+
"Content-Type": "application/json"
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
);
|
|
318
|
+
if (!response.ok) return null;
|
|
319
|
+
const data = await response.json();
|
|
320
|
+
return data.values.find((p) => p.name === projectName) || null;
|
|
321
|
+
}
|
|
322
|
+
async function createJiraProject(projectName, config2) {
|
|
323
|
+
const { email, apiToken, domain } = config2.credentials.jira;
|
|
235
324
|
const auth = Buffer.from(`${email}:${apiToken}`).toString("base64");
|
|
236
325
|
const projectKey = generateJiraKey(projectName);
|
|
326
|
+
const existing = await findExistingJiraProject(projectName, auth, domain);
|
|
327
|
+
if (existing) {
|
|
328
|
+
logger.success(`Jira: ${existing.key} (ya existe)`);
|
|
329
|
+
return `https://${domain}/browse/${existing.key}`;
|
|
330
|
+
}
|
|
237
331
|
return withSpinner(
|
|
238
332
|
"Creando proyecto en Jira...",
|
|
239
333
|
async () => {
|
|
@@ -290,13 +384,20 @@ async function createJiraProject(projectName, config) {
|
|
|
290
384
|
const project = await response.json();
|
|
291
385
|
return `https://${domain}/browse/${project.key}`;
|
|
292
386
|
},
|
|
293
|
-
`Proyecto Jira
|
|
387
|
+
`Proyecto Jira: ${projectKey}`
|
|
294
388
|
);
|
|
295
389
|
}
|
|
296
390
|
|
|
297
391
|
// src/steps/scaffold-nextjs.ts
|
|
298
392
|
import { execa } from "execa";
|
|
393
|
+
import { existsSync } from "fs";
|
|
394
|
+
import path from "path";
|
|
299
395
|
async function scaffoldNextJs(projectName, projectPath) {
|
|
396
|
+
const targetDir = path.join(process.cwd(), projectName);
|
|
397
|
+
if (existsSync(targetDir)) {
|
|
398
|
+
logger.success(`Next.js: ${projectName} (ya existe)`);
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
300
401
|
await withSpinner(
|
|
301
402
|
"Inicializando proyecto Next.js...",
|
|
302
403
|
async () => {
|
|
@@ -311,27 +412,28 @@ async function scaffoldNextJs(projectName, projectPath) {
|
|
|
311
412
|
"--src-dir",
|
|
312
413
|
"--import-alias",
|
|
313
414
|
"@/*",
|
|
314
|
-
"--use-npm"
|
|
415
|
+
"--use-npm",
|
|
416
|
+
"--yes"
|
|
315
417
|
], {
|
|
316
418
|
cwd: process.cwd(),
|
|
317
419
|
stdio: "pipe"
|
|
318
420
|
});
|
|
319
421
|
},
|
|
320
|
-
|
|
422
|
+
`Next.js: ${projectName}`
|
|
321
423
|
);
|
|
322
424
|
}
|
|
323
425
|
|
|
324
426
|
// src/steps/copy-template.ts
|
|
325
427
|
import { cp, mkdir, readFile, writeFile } from "fs/promises";
|
|
326
428
|
import path2 from "path";
|
|
327
|
-
import { fileURLToPath } from "url";
|
|
328
|
-
var
|
|
329
|
-
var
|
|
429
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
430
|
+
var __filename3 = fileURLToPath2(import.meta.url);
|
|
431
|
+
var __dirname3 = path2.dirname(__filename3);
|
|
330
432
|
async function copyTemplate(projectPath) {
|
|
331
433
|
await withSpinner(
|
|
332
434
|
"Copiando template LFT...",
|
|
333
435
|
async () => {
|
|
334
|
-
const templatesDir = path2.join(
|
|
436
|
+
const templatesDir = path2.join(__dirname3, "..", "..", "templates");
|
|
335
437
|
const srcDir = path2.join(projectPath, "src");
|
|
336
438
|
await cp(
|
|
337
439
|
path2.join(templatesDir, "components", "ui"),
|
|
@@ -519,53 +621,6 @@ async function setupGit(projectPath, remoteUrl) {
|
|
|
519
621
|
);
|
|
520
622
|
}
|
|
521
623
|
|
|
522
|
-
// src/ui/logger.ts
|
|
523
|
-
import chalk from "chalk";
|
|
524
|
-
var logger = {
|
|
525
|
-
info: (message) => {
|
|
526
|
-
console.log(chalk.blue("\u2139"), message);
|
|
527
|
-
},
|
|
528
|
-
success: (message) => {
|
|
529
|
-
console.log(chalk.green("\u2714"), message);
|
|
530
|
-
},
|
|
531
|
-
warning: (message) => {
|
|
532
|
-
console.log(chalk.yellow("\u26A0"), message);
|
|
533
|
-
},
|
|
534
|
-
error: (message) => {
|
|
535
|
-
console.log(chalk.red("\u2716"), message);
|
|
536
|
-
},
|
|
537
|
-
step: (step, total, message) => {
|
|
538
|
-
console.log(chalk.cyan(`[${step}/${total}]`), message);
|
|
539
|
-
},
|
|
540
|
-
newLine: () => {
|
|
541
|
-
console.log();
|
|
542
|
-
},
|
|
543
|
-
divider: () => {
|
|
544
|
-
console.log(chalk.gray("\u2500".repeat(50)));
|
|
545
|
-
},
|
|
546
|
-
title: (message) => {
|
|
547
|
-
console.log(chalk.bold.white(message));
|
|
548
|
-
},
|
|
549
|
-
subtitle: (message) => {
|
|
550
|
-
console.log(chalk.gray(message));
|
|
551
|
-
},
|
|
552
|
-
link: (label, url) => {
|
|
553
|
-
console.log(` ${chalk.gray(label + ":")} ${chalk.cyan.underline(url)}`);
|
|
554
|
-
},
|
|
555
|
-
list: (items) => {
|
|
556
|
-
items.forEach((item) => {
|
|
557
|
-
console.log(chalk.gray(" \u2022"), item);
|
|
558
|
-
});
|
|
559
|
-
},
|
|
560
|
-
table: (rows) => {
|
|
561
|
-
const maxLabelLength = Math.max(...rows.map((r) => r.label.length));
|
|
562
|
-
rows.forEach(({ label, value }) => {
|
|
563
|
-
const paddedLabel = label.padEnd(maxLabelLength);
|
|
564
|
-
console.log(` ${chalk.gray(paddedLabel)} ${value}`);
|
|
565
|
-
});
|
|
566
|
-
}
|
|
567
|
-
};
|
|
568
|
-
|
|
569
624
|
// src/ui/banner.ts
|
|
570
625
|
import boxen from "boxen";
|
|
571
626
|
import chalk2 from "chalk";
|
|
@@ -625,19 +680,19 @@ async function createProject(projectName, options = {}) {
|
|
|
625
680
|
logger.warning('No se encontr\xF3 configuraci\xF3n. Ejecuta "create-lft-app config" primero.');
|
|
626
681
|
throw new Error("Configuraci\xF3n no encontrada");
|
|
627
682
|
}
|
|
628
|
-
const
|
|
683
|
+
const config2 = await loadConfig();
|
|
629
684
|
logger.newLine();
|
|
630
685
|
logger.title("Resumen de recursos a crear:");
|
|
631
686
|
logger.newLine();
|
|
632
687
|
const resources = [];
|
|
633
688
|
if (!options.skipGithub) {
|
|
634
|
-
resources.push({ label: "GitHub", value: `${
|
|
689
|
+
resources.push({ label: "GitHub", value: `${config2.defaults.githubOrg || config2.credentials.github.username}/${projectName} (privado)` });
|
|
635
690
|
}
|
|
636
691
|
if (!options.skipSupabase) {
|
|
637
|
-
resources.push({ label: "Supabase", value: `${projectName} en ${
|
|
692
|
+
resources.push({ label: "Supabase", value: `${projectName} en ${config2.defaults.supabaseRegion}` });
|
|
638
693
|
}
|
|
639
694
|
if (!options.skipJira) {
|
|
640
|
-
resources.push({ label: "Jira", value: `Proyecto "${projectName}" en ${
|
|
695
|
+
resources.push({ label: "Jira", value: `Proyecto "${projectName}" en ${config2.credentials.jira.domain}` });
|
|
641
696
|
}
|
|
642
697
|
resources.push({ label: "Next.js", value: "App Router + TypeScript + Tailwind + Dashboard" });
|
|
643
698
|
logger.table(resources);
|
|
@@ -660,14 +715,14 @@ async function createProject(projectName, options = {}) {
|
|
|
660
715
|
const externalTasks = [];
|
|
661
716
|
if (!options.skipGithub) {
|
|
662
717
|
externalTasks.push(
|
|
663
|
-
createGitHubRepo(projectName,
|
|
718
|
+
createGitHubRepo(projectName, config2).then((url) => {
|
|
664
719
|
urls.github = url;
|
|
665
720
|
})
|
|
666
721
|
);
|
|
667
722
|
}
|
|
668
723
|
if (!options.skipSupabase) {
|
|
669
724
|
externalTasks.push(
|
|
670
|
-
createSupabaseProject(projectName,
|
|
725
|
+
createSupabaseProject(projectName, config2).then((result) => {
|
|
671
726
|
urls.supabase = result.url;
|
|
672
727
|
supabaseKeys = result;
|
|
673
728
|
})
|
|
@@ -675,7 +730,7 @@ async function createProject(projectName, options = {}) {
|
|
|
675
730
|
}
|
|
676
731
|
if (!options.skipJira) {
|
|
677
732
|
externalTasks.push(
|
|
678
|
-
createJiraProject(projectName,
|
|
733
|
+
createJiraProject(projectName, config2).then((url) => {
|
|
679
734
|
urls.jira = url;
|
|
680
735
|
})
|
|
681
736
|
);
|