@create-lft-app/cli 1.0.1 → 1.0.3

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/dist/bin/cli.js CHANGED
@@ -4,64 +4,61 @@
4
4
  import { program } from "commander";
5
5
 
6
6
  // src/index.ts
7
- import path5 from "path";
8
- import { confirm as confirm2 } from "@inquirer/prompts";
9
-
10
- // src/config/index.ts
11
- import fs from "fs/promises";
12
- import path from "path";
13
- import os from "os";
14
- import { createCipheriv, createDecipheriv, randomBytes, createHash } from "crypto";
15
- import nodeMachineId from "node-machine-id";
16
- import { input, password, select, confirm } from "@inquirer/prompts";
7
+ import path4 from "path";
8
+ import { confirm } from "@inquirer/prompts";
17
9
 
18
- // src/ui/logger.ts
19
- import chalk from "chalk";
20
- var logger = {
21
- info: (message) => {
22
- console.log(chalk.blue("\u2139"), message);
23
- },
24
- success: (message) => {
25
- console.log(chalk.green("\u2714"), message);
10
+ // src/config/static-config.ts
11
+ var STATIC_CONFIG = {
12
+ github: {
13
+ token: "__GITHUB_TOKEN__",
14
+ username: "__GITHUB_USERNAME__",
15
+ org: "__GITHUB_ORG__"
26
16
  },
27
- warning: (message) => {
28
- console.log(chalk.yellow("\u26A0"), message);
29
- },
30
- error: (message) => {
31
- console.log(chalk.red("\u2716"), message);
32
- },
33
- step: (step, total, message) => {
34
- console.log(chalk.cyan(`[${step}/${total}]`), message);
35
- },
36
- newLine: () => {
37
- console.log();
17
+ supabase: {
18
+ token: "__SUPABASE_TOKEN__",
19
+ orgId: "__SUPABASE_ORG_ID__",
20
+ region: "us-east-1"
38
21
  },
39
- divider: () => {
40
- console.log(chalk.gray("\u2500".repeat(50)));
41
- },
42
- title: (message) => {
43
- console.log(chalk.bold.white(message));
44
- },
45
- subtitle: (message) => {
46
- console.log(chalk.gray(message));
47
- },
48
- link: (label, url) => {
49
- console.log(` ${chalk.gray(label + ":")} ${chalk.cyan.underline(url)}`);
50
- },
51
- list: (items) => {
52
- items.forEach((item) => {
53
- console.log(chalk.gray(" \u2022"), item);
54
- });
55
- },
56
- table: (rows) => {
57
- const maxLabelLength = Math.max(...rows.map((r) => r.label.length));
58
- rows.forEach(({ label, value }) => {
59
- const paddedLabel = label.padEnd(maxLabelLength);
60
- console.log(` ${chalk.gray(paddedLabel)} ${value}`);
61
- });
22
+ jira: {
23
+ email: "__JIRA_EMAIL__",
24
+ token: "__JIRA_TOKEN__",
25
+ domain: "__JIRA_DOMAIN__"
62
26
  }
63
27
  };
64
28
 
29
+ // src/config/index.ts
30
+ async function loadConfig() {
31
+ return {
32
+ version: "1.0.0",
33
+ credentials: {
34
+ github: {
35
+ token: STATIC_CONFIG.github.token,
36
+ username: STATIC_CONFIG.github.username
37
+ },
38
+ supabase: {
39
+ accessToken: STATIC_CONFIG.supabase.token,
40
+ organizationId: STATIC_CONFIG.supabase.orgId
41
+ },
42
+ jira: {
43
+ email: STATIC_CONFIG.jira.email,
44
+ apiToken: STATIC_CONFIG.jira.token,
45
+ domain: STATIC_CONFIG.jira.domain
46
+ }
47
+ },
48
+ defaults: {
49
+ githubOrg: STATIC_CONFIG.github.org || void 0,
50
+ supabaseRegion: STATIC_CONFIG.supabase.region,
51
+ jiraProjectType: "software"
52
+ }
53
+ };
54
+ }
55
+ async function hasConfig() {
56
+ return STATIC_CONFIG.github.token !== "__GITHUB_TOKEN__" && STATIC_CONFIG.supabase.token !== "__SUPABASE_TOKEN__" && STATIC_CONFIG.jira.token !== "__JIRA_TOKEN__";
57
+ }
58
+
59
+ // src/services/github.ts
60
+ import { Octokit } from "octokit";
61
+
65
62
  // src/ui/spinner.ts
66
63
  import ora from "ora";
67
64
  function createSpinner(text) {
@@ -82,247 +79,7 @@ async function withSpinner(text, fn, successText) {
82
79
  }
83
80
  }
84
81
 
85
- // src/config/index.ts
86
- var { machineIdSync } = nodeMachineId;
87
- var CONFIG_FILE = path.join(os.homedir(), ".lftrc");
88
- var ALGORITHM = "aes-256-gcm";
89
- function getEncryptionKey() {
90
- const machineId = machineIdSync();
91
- return createHash("sha256").update(machineId + "lft-secret").digest();
92
- }
93
- function encryptConfig(config) {
94
- const key = getEncryptionKey();
95
- const iv = randomBytes(16);
96
- const cipher = createCipheriv(ALGORITHM, key, iv);
97
- let encrypted = cipher.update(JSON.stringify(config), "utf8", "hex");
98
- encrypted += cipher.final("hex");
99
- const authTag = cipher.getAuthTag();
100
- return JSON.stringify({
101
- iv: iv.toString("hex"),
102
- tag: authTag.toString("hex"),
103
- data: encrypted
104
- });
105
- }
106
- function decryptConfig(encrypted) {
107
- const { iv, tag, data } = JSON.parse(encrypted);
108
- const key = getEncryptionKey();
109
- const decipher = createDecipheriv(ALGORITHM, key, Buffer.from(iv, "hex"));
110
- decipher.setAuthTag(Buffer.from(tag, "hex"));
111
- let decrypted = decipher.update(data, "hex", "utf8");
112
- decrypted += decipher.final("utf8");
113
- return JSON.parse(decrypted);
114
- }
115
- async function hasConfig() {
116
- try {
117
- await fs.access(CONFIG_FILE);
118
- return true;
119
- } catch {
120
- return false;
121
- }
122
- }
123
- async function loadConfig() {
124
- const encrypted = await fs.readFile(CONFIG_FILE, "utf8");
125
- return decryptConfig(encrypted);
126
- }
127
- async function saveConfig(config) {
128
- const encrypted = encryptConfig(config);
129
- await fs.writeFile(CONFIG_FILE, encrypted, "utf8");
130
- }
131
- async function showConfig() {
132
- if (!await hasConfig()) {
133
- logger.warning("No hay configuraci\xF3n guardada");
134
- logger.info('Ejecuta "create-lft-app config" para configurar');
135
- return;
136
- }
137
- const config = await loadConfig();
138
- logger.newLine();
139
- logger.title("Configuraci\xF3n actual:");
140
- logger.newLine();
141
- logger.subtitle("GitHub:");
142
- logger.table([
143
- { label: "Usuario", value: config.credentials.github.username },
144
- { label: "Token", value: "***" + config.credentials.github.token.slice(-4) },
145
- { label: "Org por defecto", value: config.defaults.githubOrg || "(ninguna)" }
146
- ]);
147
- logger.newLine();
148
- logger.subtitle("Supabase:");
149
- logger.table([
150
- { label: "Org ID", value: config.credentials.supabase.organizationId },
151
- { label: "Token", value: "***" + config.credentials.supabase.accessToken.slice(-4) },
152
- { label: "Regi\xF3n", value: config.defaults.supabaseRegion }
153
- ]);
154
- logger.newLine();
155
- logger.subtitle("Jira:");
156
- logger.table([
157
- { label: "Email", value: config.credentials.jira.email },
158
- { label: "Dominio", value: config.credentials.jira.domain },
159
- { label: "Token", value: "***" + config.credentials.jira.apiToken.slice(-4) }
160
- ]);
161
- }
162
- async function resetConfig() {
163
- if (!await hasConfig()) {
164
- logger.info("No hay configuraci\xF3n para resetear");
165
- return;
166
- }
167
- const shouldReset = await confirm({
168
- message: "\xBFEst\xE1s seguro de que quieres eliminar la configuraci\xF3n?",
169
- default: false
170
- });
171
- if (shouldReset) {
172
- await fs.unlink(CONFIG_FILE);
173
- logger.success("Configuraci\xF3n eliminada");
174
- }
175
- }
176
- async function configureCredentials(options = {}) {
177
- let config;
178
- if (await hasConfig()) {
179
- config = await loadConfig();
180
- logger.info("Configuraci\xF3n existente encontrada. Actualizando...");
181
- } else {
182
- config = {
183
- version: "1.0.0",
184
- credentials: {
185
- github: { token: "", username: "" },
186
- supabase: { accessToken: "", organizationId: "" },
187
- jira: { email: "", apiToken: "", domain: "" }
188
- },
189
- defaults: {
190
- supabaseRegion: "us-east-1",
191
- jiraProjectType: "software"
192
- }
193
- };
194
- }
195
- const configureAll = !options.onlyGithub && !options.onlySupabase && !options.onlyJira;
196
- if (configureAll || options.onlyGithub) {
197
- logger.newLine();
198
- logger.title("Configuraci\xF3n de GitHub");
199
- logger.subtitle("Necesitas un Personal Access Token con permisos: repo, read:org");
200
- logger.link("Crear token", "https://github.com/settings/tokens/new");
201
- logger.newLine();
202
- const githubToken = await password({
203
- message: "GitHub Personal Access Token:",
204
- mask: "*"
205
- });
206
- const isValid = await withSpinner(
207
- "Validando token de GitHub...",
208
- async () => {
209
- const response = await fetch("https://api.github.com/user", {
210
- headers: { Authorization: `Bearer ${githubToken}` }
211
- });
212
- if (!response.ok) return null;
213
- return response.json();
214
- }
215
- );
216
- if (!isValid) {
217
- throw new Error("Token de GitHub inv\xE1lido");
218
- }
219
- config.credentials.github.token = githubToken;
220
- config.credentials.github.username = isValid.login;
221
- logger.success(`Conectado como: ${isValid.login}`);
222
- const useOrg = await confirm({
223
- message: "\xBFQuieres usar una organizaci\xF3n por defecto?",
224
- default: false
225
- });
226
- if (useOrg) {
227
- config.defaults.githubOrg = await input({
228
- message: "Nombre de la organizaci\xF3n:"
229
- });
230
- }
231
- }
232
- if (configureAll || options.onlySupabase) {
233
- logger.newLine();
234
- logger.title("Configuraci\xF3n de Supabase");
235
- logger.subtitle("Necesitas un Access Token de la Management API");
236
- logger.link("Crear token", "https://supabase.com/dashboard/account/tokens");
237
- logger.newLine();
238
- const supabaseToken = await password({
239
- message: "Supabase Access Token:",
240
- mask: "*"
241
- });
242
- const orgs = await withSpinner(
243
- "Obteniendo organizaciones de Supabase...",
244
- async () => {
245
- const response = await fetch("https://api.supabase.com/v1/organizations", {
246
- headers: { Authorization: `Bearer ${supabaseToken}` }
247
- });
248
- if (!response.ok) return null;
249
- return response.json();
250
- }
251
- );
252
- if (!orgs || orgs.length === 0) {
253
- throw new Error("Token de Supabase inv\xE1lido o no tienes organizaciones");
254
- }
255
- config.credentials.supabase.accessToken = supabaseToken;
256
- if (orgs.length === 1) {
257
- config.credentials.supabase.organizationId = orgs[0].id;
258
- logger.success(`Usando organizaci\xF3n: ${orgs[0].name}`);
259
- } else {
260
- const selectedOrg = await select({
261
- message: "Selecciona la organizaci\xF3n:",
262
- choices: orgs.map((org) => ({ name: org.name, value: org.id }))
263
- });
264
- config.credentials.supabase.organizationId = selectedOrg;
265
- }
266
- config.defaults.supabaseRegion = await select({
267
- message: "Regi\xF3n por defecto:",
268
- choices: [
269
- { name: "US East (Virginia)", value: "us-east-1" },
270
- { name: "US West (Oregon)", value: "us-west-1" },
271
- { name: "EU West (Ireland)", value: "eu-west-1" },
272
- { name: "AP Southeast (Singapore)", value: "ap-southeast-1" },
273
- { name: "AP Northeast (Tokyo)", value: "ap-northeast-1" },
274
- { name: "SA East (S\xE3o Paulo)", value: "sa-east-1" }
275
- ],
276
- default: "us-east-1"
277
- });
278
- }
279
- if (configureAll || options.onlyJira) {
280
- logger.newLine();
281
- logger.title("Configuraci\xF3n de Jira");
282
- logger.subtitle("Necesitas un API Token de Atlassian");
283
- logger.link("Crear token", "https://id.atlassian.com/manage-profile/security/api-tokens");
284
- logger.newLine();
285
- const jiraEmail = await input({
286
- message: "Email de Atlassian:"
287
- });
288
- const jiraToken = await password({
289
- message: "Jira API Token:",
290
- mask: "*"
291
- });
292
- const jiraDomain = await input({
293
- message: "Dominio de Jira (ej: empresa.atlassian.net):",
294
- validate: (value) => {
295
- if (!value.includes(".atlassian.net")) {
296
- return "El dominio debe terminar en .atlassian.net";
297
- }
298
- return true;
299
- }
300
- });
301
- const isValid = await withSpinner(
302
- "Validando credenciales de Jira...",
303
- async () => {
304
- const auth = Buffer.from(`${jiraEmail}:${jiraToken}`).toString("base64");
305
- const response = await fetch(`https://${jiraDomain}/rest/api/3/myself`, {
306
- headers: { Authorization: `Basic ${auth}` }
307
- });
308
- return response.ok;
309
- }
310
- );
311
- if (!isValid) {
312
- throw new Error("Credenciales de Jira inv\xE1lidas");
313
- }
314
- config.credentials.jira.email = jiraEmail;
315
- config.credentials.jira.apiToken = jiraToken;
316
- config.credentials.jira.domain = jiraDomain;
317
- logger.success("Credenciales de Jira v\xE1lidas");
318
- }
319
- await saveConfig(config);
320
- logger.newLine();
321
- logger.success("Configuraci\xF3n guardada en ~/.lftrc");
322
- }
323
-
324
82
  // src/services/github.ts
325
- import { Octokit } from "octokit";
326
83
  async function createGitHubRepo(projectName, config) {
327
84
  const octokit = new Octokit({ auth: config.credentials.github.token });
328
85
  const org = config.defaults.githubOrg;
@@ -428,16 +185,16 @@ async function createSupabaseProject(projectName, config) {
428
185
  }
429
186
  function generateSecurePassword() {
430
187
  const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*";
431
- let password2 = "";
188
+ let password = "";
432
189
  for (let i = 0; i < 32; i++) {
433
- password2 += chars.charAt(Math.floor(Math.random() * chars.length));
190
+ password += chars.charAt(Math.floor(Math.random() * chars.length));
434
191
  }
435
- return password2;
192
+ return password;
436
193
  }
437
194
 
438
195
  // src/utils/validation.ts
439
- import fs2 from "fs";
440
- import path2 from "path";
196
+ import fs from "fs";
197
+ import path from "path";
441
198
  function validateProjectName(name) {
442
199
  if (!name || name.trim() === "") {
443
200
  return { valid: false, error: "El nombre del proyecto no puede estar vac\xEDo" };
@@ -461,8 +218,8 @@ function validateProjectName(name) {
461
218
  if (name.length > 50) {
462
219
  return { valid: false, error: "El nombre no puede tener m\xE1s de 50 caracteres" };
463
220
  }
464
- const projectPath = path2.resolve(process.cwd(), name);
465
- if (fs2.existsSync(projectPath)) {
221
+ const projectPath = path.resolve(process.cwd(), name);
222
+ if (fs.existsSync(projectPath)) {
466
223
  return { valid: false, error: `El directorio "${name}" ya existe` };
467
224
  }
468
225
  return { valid: true };
@@ -566,59 +323,59 @@ async function scaffoldNextJs(projectName, projectPath) {
566
323
 
567
324
  // src/steps/copy-template.ts
568
325
  import { cp, mkdir, readFile, writeFile } from "fs/promises";
569
- import path3 from "path";
326
+ import path2 from "path";
570
327
  import { fileURLToPath } from "url";
571
328
  var __filename2 = fileURLToPath(import.meta.url);
572
- var __dirname2 = path3.dirname(__filename2);
329
+ var __dirname2 = path2.dirname(__filename2);
573
330
  async function copyTemplate(projectPath) {
574
331
  await withSpinner(
575
332
  "Copiando template LFT...",
576
333
  async () => {
577
- const templatesDir = path3.join(__dirname2, "..", "..", "templates");
578
- const srcDir = path3.join(projectPath, "src");
334
+ const templatesDir = path2.join(__dirname2, "..", "..", "templates");
335
+ const srcDir = path2.join(projectPath, "src");
579
336
  await cp(
580
- path3.join(templatesDir, "components", "ui"),
581
- path3.join(srcDir, "components", "ui"),
337
+ path2.join(templatesDir, "components", "ui"),
338
+ path2.join(srcDir, "components", "ui"),
582
339
  { recursive: true }
583
340
  );
584
341
  await cp(
585
- path3.join(templatesDir, "components", "layout"),
586
- path3.join(srcDir, "components", "layout"),
342
+ path2.join(templatesDir, "components", "layout"),
343
+ path2.join(srcDir, "components", "layout"),
587
344
  { recursive: true }
588
345
  );
589
346
  await cp(
590
- path3.join(templatesDir, "components", "dashboard"),
591
- path3.join(srcDir, "components", "dashboard"),
347
+ path2.join(templatesDir, "components", "dashboard"),
348
+ path2.join(srcDir, "components", "dashboard"),
592
349
  { recursive: true }
593
350
  );
594
- await mkdir(path3.join(srcDir, "lib"), { recursive: true });
351
+ await mkdir(path2.join(srcDir, "lib"), { recursive: true });
595
352
  await cp(
596
- path3.join(templatesDir, "lib", "utils.ts"),
597
- path3.join(srcDir, "lib", "utils.ts")
353
+ path2.join(templatesDir, "lib", "utils.ts"),
354
+ path2.join(srcDir, "lib", "utils.ts")
598
355
  );
599
- await mkdir(path3.join(srcDir, "hooks"), { recursive: true });
356
+ await mkdir(path2.join(srcDir, "hooks"), { recursive: true });
600
357
  await cp(
601
- path3.join(templatesDir, "hooks"),
602
- path3.join(srcDir, "hooks"),
358
+ path2.join(templatesDir, "hooks"),
359
+ path2.join(srcDir, "hooks"),
603
360
  { recursive: true }
604
361
  );
605
362
  await cp(
606
- path3.join(templatesDir, "app", "layout.tsx"),
607
- path3.join(srcDir, "app", "layout.tsx")
363
+ path2.join(templatesDir, "app", "layout.tsx"),
364
+ path2.join(srcDir, "app", "layout.tsx")
608
365
  );
609
366
  await cp(
610
- path3.join(templatesDir, "app", "page.tsx"),
611
- path3.join(srcDir, "app", "page.tsx")
367
+ path2.join(templatesDir, "app", "page.tsx"),
368
+ path2.join(srcDir, "app", "page.tsx")
612
369
  );
613
- await mkdir(path3.join(srcDir, "app", "dashboard"), { recursive: true });
370
+ await mkdir(path2.join(srcDir, "app", "dashboard"), { recursive: true });
614
371
  await cp(
615
- path3.join(templatesDir, "app", "dashboard", "page.tsx"),
616
- path3.join(srcDir, "app", "dashboard", "page.tsx")
372
+ path2.join(templatesDir, "app", "dashboard", "page.tsx"),
373
+ path2.join(srcDir, "app", "dashboard", "page.tsx")
617
374
  );
618
- await mkdir(path3.join(srcDir, "app", "auth", "login"), { recursive: true });
375
+ await mkdir(path2.join(srcDir, "app", "auth", "login"), { recursive: true });
619
376
  await cp(
620
- path3.join(templatesDir, "app", "auth", "login", "page.tsx"),
621
- path3.join(srcDir, "app", "auth", "login", "page.tsx")
377
+ path2.join(templatesDir, "app", "auth", "login", "page.tsx"),
378
+ path2.join(srcDir, "app", "auth", "login", "page.tsx")
622
379
  );
623
380
  await mergeGlobalStyles(projectPath, templatesDir);
624
381
  },
@@ -626,8 +383,8 @@ async function copyTemplate(projectPath) {
626
383
  );
627
384
  }
628
385
  async function mergeGlobalStyles(projectPath, templatesDir) {
629
- const templateCssPath = path3.join(templatesDir, "app", "globals.css");
630
- const projectCssPath = path3.join(projectPath, "src", "app", "globals.css");
386
+ const templateCssPath = path2.join(templatesDir, "app", "globals.css");
387
+ const projectCssPath = path2.join(projectPath, "src", "app", "globals.css");
631
388
  try {
632
389
  const templateCss = await readFile(templateCssPath, "utf-8");
633
390
  const existingCss = await readFile(projectCssPath, "utf-8");
@@ -704,7 +461,7 @@ async function installDependencies(projectPath) {
704
461
 
705
462
  // src/steps/create-env.ts
706
463
  import { writeFile as writeFile2, readFile as readFile2, appendFile } from "fs/promises";
707
- import path4 from "path";
464
+ import path3 from "path";
708
465
  async function createEnvFile(projectPath, supabaseKeys) {
709
466
  await withSpinner(
710
467
  "Creando archivo .env.local...",
@@ -715,10 +472,10 @@ NEXT_PUBLIC_SUPABASE_ANON_KEY=${supabaseKeys.anonKey}
715
472
  SUPABASE_SERVICE_ROLE_KEY=${supabaseKeys.serviceKey}
716
473
  `;
717
474
  await writeFile2(
718
- path4.join(projectPath, ".env.local"),
475
+ path3.join(projectPath, ".env.local"),
719
476
  envContent
720
477
  );
721
- const gitignorePath = path4.join(projectPath, ".gitignore");
478
+ const gitignorePath = path3.join(projectPath, ".gitignore");
722
479
  try {
723
480
  const gitignore = await readFile2(gitignorePath, "utf-8");
724
481
  if (!gitignore.includes(".env.local")) {
@@ -762,6 +519,53 @@ async function setupGit(projectPath, remoteUrl) {
762
519
  );
763
520
  }
764
521
 
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
+
765
569
  // src/ui/banner.ts
766
570
  import boxen from "boxen";
767
571
  import chalk2 from "chalk";
@@ -816,7 +620,7 @@ async function createProject(projectName, options = {}) {
816
620
  if (!validation.valid) {
817
621
  throw new Error(validation.error);
818
622
  }
819
- const projectPath = path5.resolve(process.cwd(), projectName);
623
+ const projectPath = path4.resolve(process.cwd(), projectName);
820
624
  if (!await hasConfig()) {
821
625
  logger.warning('No se encontr\xF3 configuraci\xF3n. Ejecuta "create-lft-app config" primero.');
822
626
  throw new Error("Configuraci\xF3n no encontrada");
@@ -839,7 +643,7 @@ async function createProject(projectName, options = {}) {
839
643
  logger.table(resources);
840
644
  logger.newLine();
841
645
  if (!options.autoConfirm) {
842
- const shouldContinue = await confirm2({
646
+ const shouldContinue = await confirm({
843
647
  message: "\xBFContinuar con la creaci\xF3n?",
844
648
  default: true
845
649
  });
@@ -904,6 +708,11 @@ program.argument("[project-name]", "Nombre del proyecto a crear").option("--skip
904
708
  logger.info("Uso: create-lft-app <nombre-proyecto>");
905
709
  process.exit(1);
906
710
  }
711
+ if (!await hasConfig()) {
712
+ logger.error("Las credenciales no est\xE1n configuradas en el paquete");
713
+ logger.info("Contacta al administrador del CLI");
714
+ process.exit(1);
715
+ }
907
716
  try {
908
717
  await createProject(projectName, {
909
718
  skipGithub: options.skipGithub,
@@ -919,21 +728,5 @@ program.argument("[project-name]", "Nombre del proyecto a crear").option("--skip
919
728
  process.exit(1);
920
729
  }
921
730
  });
922
- program.command("config").description("Configurar credenciales de APIs").option("--show", "Mostrar configuraci\xF3n actual").option("--reset", "Resetear configuraci\xF3n").option("--github", "Configurar solo GitHub").option("--supabase", "Configurar solo Supabase").option("--jira", "Configurar solo Jira").action(async (options) => {
923
- showBanner();
924
- if (options.show) {
925
- await showConfig();
926
- return;
927
- }
928
- if (options.reset) {
929
- await resetConfig();
930
- return;
931
- }
932
- await configureCredentials({
933
- onlyGithub: options.github,
934
- onlySupabase: options.supabase,
935
- onlyJira: options.jira
936
- });
937
- });
938
731
  program.parse();
939
732
  //# sourceMappingURL=cli.js.map