@create-lft-app/cli 1.0.2 → 1.0.4

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/src/index.js CHANGED
@@ -1,16 +1,86 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import path5 from "path";
5
- import { confirm as confirm2 } from "@inquirer/prompts";
4
+ import path4 from "path";
5
+ import { confirm } from "@inquirer/prompts";
6
+
7
+ // src/config/static-config.ts
8
+ import { config } from "dotenv";
9
+ import { fileURLToPath } from "url";
10
+ import { dirname, resolve } from "path";
11
+ var __filename = fileURLToPath(import.meta.url);
12
+ var __dirname = dirname(__filename);
13
+ config({ path: resolve(__dirname, "../../.env"), quiet: true });
14
+ var STATIC_CONFIG = {
15
+ github: {
16
+ token: process.env.LFT_GITHUB_TOKEN || "",
17
+ username: process.env.LFT_GITHUB_USERNAME || "",
18
+ org: process.env.LFT_GITHUB_ORG || ""
19
+ },
20
+ supabase: {
21
+ token: process.env.LFT_SUPABASE_TOKEN || "",
22
+ orgId: process.env.LFT_SUPABASE_ORG_ID || "",
23
+ region: process.env.LFT_SUPABASE_REGION || "us-east-1"
24
+ },
25
+ jira: {
26
+ email: process.env.LFT_JIRA_EMAIL || "",
27
+ token: process.env.LFT_JIRA_TOKEN || "",
28
+ domain: process.env.LFT_JIRA_DOMAIN || ""
29
+ }
30
+ };
6
31
 
7
32
  // src/config/index.ts
8
- import fs from "fs/promises";
9
- import path from "path";
10
- import os from "os";
11
- import { createCipheriv, createDecipheriv, randomBytes, createHash } from "crypto";
12
- import nodeMachineId from "node-machine-id";
13
- import { input, password, select, confirm } from "@inquirer/prompts";
33
+ async function loadConfig() {
34
+ return {
35
+ version: "1.0.0",
36
+ credentials: {
37
+ github: {
38
+ token: STATIC_CONFIG.github.token,
39
+ username: STATIC_CONFIG.github.username
40
+ },
41
+ supabase: {
42
+ accessToken: STATIC_CONFIG.supabase.token,
43
+ organizationId: STATIC_CONFIG.supabase.orgId
44
+ },
45
+ jira: {
46
+ email: STATIC_CONFIG.jira.email,
47
+ apiToken: STATIC_CONFIG.jira.token,
48
+ domain: STATIC_CONFIG.jira.domain
49
+ }
50
+ },
51
+ defaults: {
52
+ githubOrg: STATIC_CONFIG.github.org || void 0,
53
+ supabaseRegion: STATIC_CONFIG.supabase.region,
54
+ jiraProjectType: "software"
55
+ }
56
+ };
57
+ }
58
+ async function hasConfig() {
59
+ return STATIC_CONFIG.github.token !== "" && STATIC_CONFIG.supabase.token !== "" && STATIC_CONFIG.jira.token !== "";
60
+ }
61
+
62
+ // src/services/github.ts
63
+ import { Octokit } from "octokit";
64
+
65
+ // src/ui/spinner.ts
66
+ import ora from "ora";
67
+ function createSpinner(text) {
68
+ return ora({
69
+ text,
70
+ spinner: "dots"
71
+ });
72
+ }
73
+ async function withSpinner(text, fn, successText) {
74
+ const spinner = createSpinner(text).start();
75
+ try {
76
+ const result = await fn();
77
+ spinner.succeed(successText || text);
78
+ return result;
79
+ } catch (error) {
80
+ spinner.fail();
81
+ throw error;
82
+ }
83
+ }
14
84
 
15
85
  // src/ui/logger.ts
16
86
  import chalk from "chalk";
@@ -59,115 +129,20 @@ var logger = {
59
129
  }
60
130
  };
61
131
 
62
- // src/ui/spinner.ts
63
- import ora from "ora";
64
- function createSpinner(text) {
65
- return ora({
66
- text,
67
- spinner: "dots"
68
- });
69
- }
70
- async function withSpinner(text, fn, successText) {
71
- const spinner = createSpinner(text).start();
72
- try {
73
- const result = await fn();
74
- spinner.succeed(successText || text);
75
- return result;
76
- } catch (error) {
77
- spinner.fail();
78
- throw error;
79
- }
80
- }
81
-
82
- // src/config/index.ts
83
- var { machineIdSync } = nodeMachineId;
84
- var CONFIG_FILE = path.join(os.homedir(), ".lftrc");
85
- var ALGORITHM = "aes-256-gcm";
86
- function getEncryptionKey() {
87
- const machineId = machineIdSync();
88
- return createHash("sha256").update(machineId + "lft-secret").digest();
89
- }
90
- function decryptConfig(encrypted) {
91
- const { iv, tag, data } = JSON.parse(encrypted);
92
- const key = getEncryptionKey();
93
- const decipher = createDecipheriv(ALGORITHM, key, Buffer.from(iv, "hex"));
94
- decipher.setAuthTag(Buffer.from(tag, "hex"));
95
- let decrypted = decipher.update(data, "hex", "utf8");
96
- decrypted += decipher.final("utf8");
97
- return JSON.parse(decrypted);
98
- }
99
- var ENV_VARS = {
100
- GITHUB_TOKEN: "LFT_GITHUB_TOKEN",
101
- GITHUB_USERNAME: "LFT_GITHUB_USERNAME",
102
- GITHUB_ORG: "LFT_GITHUB_ORG",
103
- SUPABASE_TOKEN: "LFT_SUPABASE_TOKEN",
104
- SUPABASE_ORG_ID: "LFT_SUPABASE_ORG_ID",
105
- SUPABASE_REGION: "LFT_SUPABASE_REGION",
106
- JIRA_EMAIL: "LFT_JIRA_EMAIL",
107
- JIRA_TOKEN: "LFT_JIRA_TOKEN",
108
- JIRA_DOMAIN: "LFT_JIRA_DOMAIN"
109
- };
110
- function loadConfigFromEnv() {
111
- const githubToken = process.env[ENV_VARS.GITHUB_TOKEN];
112
- const githubUsername = process.env[ENV_VARS.GITHUB_USERNAME];
113
- const supabaseToken = process.env[ENV_VARS.SUPABASE_TOKEN];
114
- const supabaseOrgId = process.env[ENV_VARS.SUPABASE_ORG_ID];
115
- const jiraEmail = process.env[ENV_VARS.JIRA_EMAIL];
116
- const jiraToken = process.env[ENV_VARS.JIRA_TOKEN];
117
- const jiraDomain = process.env[ENV_VARS.JIRA_DOMAIN];
118
- if (!githubToken || !supabaseToken || !jiraToken) {
119
- return null;
120
- }
121
- return {
122
- version: "1.0.0",
123
- credentials: {
124
- github: {
125
- token: githubToken,
126
- username: githubUsername || ""
127
- },
128
- supabase: {
129
- accessToken: supabaseToken,
130
- organizationId: supabaseOrgId || ""
131
- },
132
- jira: {
133
- email: jiraEmail || "",
134
- apiToken: jiraToken,
135
- domain: jiraDomain || ""
136
- }
137
- },
138
- defaults: {
139
- githubOrg: process.env[ENV_VARS.GITHUB_ORG],
140
- supabaseRegion: process.env[ENV_VARS.SUPABASE_REGION] || "us-east-1",
141
- jiraProjectType: "software"
142
- }
143
- };
144
- }
145
- function hasEnvConfig() {
146
- return !!(process.env[ENV_VARS.GITHUB_TOKEN] && process.env[ENV_VARS.SUPABASE_TOKEN] && process.env[ENV_VARS.JIRA_TOKEN]);
147
- }
148
- async function hasConfig() {
149
- if (hasEnvConfig()) return true;
132
+ // src/services/github.ts
133
+ async function createGitHubRepo(projectName, config2) {
134
+ const octokit = new Octokit({ auth: config2.credentials.github.token });
135
+ const org = config2.defaults.githubOrg;
136
+ const owner = org || config2.credentials.github.username;
150
137
  try {
151
- await fs.access(CONFIG_FILE);
152
- return true;
138
+ const existing = await octokit.rest.repos.get({
139
+ owner,
140
+ repo: projectName
141
+ });
142
+ logger.success(`GitHub: ${owner}/${projectName} (ya existe)`);
143
+ return existing.data.html_url;
153
144
  } catch {
154
- return false;
155
- }
156
- }
157
- async function loadConfig() {
158
- const envConfig = loadConfigFromEnv();
159
- if (envConfig) {
160
- return envConfig;
161
145
  }
162
- const encrypted = await fs.readFile(CONFIG_FILE, "utf8");
163
- return decryptConfig(encrypted);
164
- }
165
-
166
- // src/services/github.ts
167
- import { Octokit } from "octokit";
168
- async function createGitHubRepo(projectName, config) {
169
- const octokit = new Octokit({ auth: config.credentials.github.token });
170
- const org = config.defaults.githubOrg;
171
146
  return withSpinner(
172
147
  "Creando repositorio en GitHub...",
173
148
  async () => {
@@ -190,7 +165,7 @@ async function createGitHubRepo(projectName, config) {
190
165
  }
191
166
  return repo.data.html_url;
192
167
  },
193
- `Repositorio creado: ${org || config.credentials.github.username}/${projectName}`
168
+ `GitHub: ${owner}/${projectName}`
194
169
  );
195
170
  }
196
171
 
@@ -209,7 +184,7 @@ async function waitForProjectReady(projectId, token, maxAttempts = 60) {
209
184
  return;
210
185
  }
211
186
  }
212
- await new Promise((resolve) => setTimeout(resolve, 5e3));
187
+ await new Promise((resolve2) => setTimeout(resolve2, 5e3));
213
188
  spinner.text = `Provisionando base de datos... (${Math.floor((i + 1) * 5 / 60)}min ${(i + 1) * 5 % 60}s)`;
214
189
  }
215
190
  spinner.fail("Timeout esperando a que el proyecto est\xE9 listo");
@@ -230,10 +205,28 @@ async function getProjectApiKeys(projectId, token) {
230
205
  }
231
206
  return { anonKey, serviceKey };
232
207
  }
233
- async function createSupabaseProject(projectName, config) {
234
- const token = config.credentials.supabase.accessToken;
235
- const orgId = config.credentials.supabase.organizationId;
236
- const region = config.defaults.supabaseRegion;
208
+ async function findExistingProject(projectName, token) {
209
+ const response = await fetch(`${SUPABASE_API_URL}/projects`, {
210
+ headers: { Authorization: `Bearer ${token}` }
211
+ });
212
+ if (!response.ok) return null;
213
+ const projects = await response.json();
214
+ return projects.find((p) => p.name === projectName) || null;
215
+ }
216
+ async function createSupabaseProject(projectName, config2) {
217
+ const token = config2.credentials.supabase.accessToken;
218
+ const orgId = config2.credentials.supabase.organizationId;
219
+ const region = config2.defaults.supabaseRegion;
220
+ const existing = await findExistingProject(projectName, token);
221
+ if (existing) {
222
+ logger.success(`Supabase: ${projectName} (ya existe)`);
223
+ const { anonKey: anonKey2, serviceKey: serviceKey2 } = await getProjectApiKeys(existing.id, token);
224
+ return {
225
+ url: `https://${existing.id}.supabase.co`,
226
+ anonKey: anonKey2,
227
+ serviceKey: serviceKey2
228
+ };
229
+ }
237
230
  const dbPassword = generateSecurePassword();
238
231
  const project = await withSpinner(
239
232
  "Creando proyecto en Supabase...",
@@ -270,16 +263,14 @@ async function createSupabaseProject(projectName, config) {
270
263
  }
271
264
  function generateSecurePassword() {
272
265
  const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*";
273
- let password2 = "";
266
+ let password = "";
274
267
  for (let i = 0; i < 32; i++) {
275
- password2 += chars.charAt(Math.floor(Math.random() * chars.length));
268
+ password += chars.charAt(Math.floor(Math.random() * chars.length));
276
269
  }
277
- return password2;
270
+ return password;
278
271
  }
279
272
 
280
273
  // src/utils/validation.ts
281
- import fs2 from "fs";
282
- import path2 from "path";
283
274
  function validateProjectName(name) {
284
275
  if (!name || name.trim() === "") {
285
276
  return { valid: false, error: "El nombre del proyecto no puede estar vac\xEDo" };
@@ -303,10 +294,6 @@ function validateProjectName(name) {
303
294
  if (name.length > 50) {
304
295
  return { valid: false, error: "El nombre no puede tener m\xE1s de 50 caracteres" };
305
296
  }
306
- const projectPath = path2.resolve(process.cwd(), name);
307
- if (fs2.existsSync(projectPath)) {
308
- return { valid: false, error: `El directorio "${name}" ya existe` };
309
- }
310
297
  return { valid: true };
311
298
  }
312
299
  function generateJiraKey(projectName) {
@@ -315,10 +302,29 @@ function generateJiraKey(projectName) {
315
302
  }
316
303
 
317
304
  // src/services/jira.ts
318
- async function createJiraProject(projectName, config) {
319
- const { email, apiToken, domain } = config.credentials.jira;
305
+ async function findExistingJiraProject(projectName, auth, domain) {
306
+ const response = await fetch(
307
+ `https://${domain}/rest/api/3/project/search?query=${encodeURIComponent(projectName)}`,
308
+ {
309
+ headers: {
310
+ Authorization: `Basic ${auth}`,
311
+ "Content-Type": "application/json"
312
+ }
313
+ }
314
+ );
315
+ if (!response.ok) return null;
316
+ const data = await response.json();
317
+ return data.values.find((p) => p.name === projectName) || null;
318
+ }
319
+ async function createJiraProject(projectName, config2) {
320
+ const { email, apiToken, domain } = config2.credentials.jira;
320
321
  const auth = Buffer.from(`${email}:${apiToken}`).toString("base64");
321
322
  const projectKey = generateJiraKey(projectName);
323
+ const existing = await findExistingJiraProject(projectName, auth, domain);
324
+ if (existing) {
325
+ logger.success(`Jira: ${existing.key} (ya existe)`);
326
+ return `https://${domain}/browse/${existing.key}`;
327
+ }
322
328
  return withSpinner(
323
329
  "Creando proyecto en Jira...",
324
330
  async () => {
@@ -375,13 +381,20 @@ async function createJiraProject(projectName, config) {
375
381
  const project = await response.json();
376
382
  return `https://${domain}/browse/${project.key}`;
377
383
  },
378
- `Proyecto Jira creado: ${projectKey}`
384
+ `Proyecto Jira: ${projectKey}`
379
385
  );
380
386
  }
381
387
 
382
388
  // src/steps/scaffold-nextjs.ts
383
389
  import { execa } from "execa";
390
+ import { existsSync } from "fs";
391
+ import path from "path";
384
392
  async function scaffoldNextJs(projectName, projectPath) {
393
+ const targetDir = path.join(process.cwd(), projectName);
394
+ if (existsSync(targetDir)) {
395
+ logger.success(`Next.js: ${projectName} (ya existe)`);
396
+ return;
397
+ }
385
398
  await withSpinner(
386
399
  "Inicializando proyecto Next.js...",
387
400
  async () => {
@@ -396,71 +409,72 @@ async function scaffoldNextJs(projectName, projectPath) {
396
409
  "--src-dir",
397
410
  "--import-alias",
398
411
  "@/*",
399
- "--use-npm"
412
+ "--use-npm",
413
+ "--yes"
400
414
  ], {
401
415
  cwd: process.cwd(),
402
416
  stdio: "pipe"
403
417
  });
404
418
  },
405
- "Proyecto Next.js inicializado"
419
+ `Next.js: ${projectName}`
406
420
  );
407
421
  }
408
422
 
409
423
  // src/steps/copy-template.ts
410
424
  import { cp, mkdir, readFile, writeFile } from "fs/promises";
411
- import path3 from "path";
412
- import { fileURLToPath } from "url";
413
- var __filename2 = fileURLToPath(import.meta.url);
414
- var __dirname2 = path3.dirname(__filename2);
425
+ import path2 from "path";
426
+ import { fileURLToPath as fileURLToPath2 } from "url";
427
+ var __filename3 = fileURLToPath2(import.meta.url);
428
+ var __dirname3 = path2.dirname(__filename3);
415
429
  async function copyTemplate(projectPath) {
416
430
  await withSpinner(
417
431
  "Copiando template LFT...",
418
432
  async () => {
419
- const templatesDir = path3.join(__dirname2, "..", "..", "templates");
420
- const srcDir = path3.join(projectPath, "src");
433
+ const templatesDir = path2.join(__dirname3, "..", "..", "templates");
434
+ const srcDir = path2.join(projectPath, "src");
421
435
  await cp(
422
- path3.join(templatesDir, "components", "ui"),
423
- path3.join(srcDir, "components", "ui"),
436
+ path2.join(templatesDir, "components", "ui"),
437
+ path2.join(srcDir, "components", "ui"),
424
438
  { recursive: true }
425
439
  );
426
440
  await cp(
427
- path3.join(templatesDir, "components", "layout"),
428
- path3.join(srcDir, "components", "layout"),
441
+ path2.join(templatesDir, "components", "layout"),
442
+ path2.join(srcDir, "components", "layout"),
429
443
  { recursive: true }
430
444
  );
431
445
  await cp(
432
- path3.join(templatesDir, "components", "dashboard"),
433
- path3.join(srcDir, "components", "dashboard"),
446
+ path2.join(templatesDir, "components", "dashboard"),
447
+ path2.join(srcDir, "components", "dashboard"),
434
448
  { recursive: true }
435
449
  );
436
- await mkdir(path3.join(srcDir, "lib"), { recursive: true });
450
+ await mkdir(path2.join(srcDir, "lib"), { recursive: true });
437
451
  await cp(
438
- path3.join(templatesDir, "lib", "utils.ts"),
439
- path3.join(srcDir, "lib", "utils.ts")
452
+ path2.join(templatesDir, "lib", "utils.ts"),
453
+ path2.join(srcDir, "lib", "utils.ts")
440
454
  );
441
- await mkdir(path3.join(srcDir, "hooks"), { recursive: true });
455
+ await mkdir(path2.join(srcDir, "hooks"), { recursive: true });
442
456
  await cp(
443
- path3.join(templatesDir, "hooks"),
444
- path3.join(srcDir, "hooks"),
457
+ path2.join(templatesDir, "hooks"),
458
+ path2.join(srcDir, "hooks"),
445
459
  { recursive: true }
446
460
  );
447
461
  await cp(
448
- path3.join(templatesDir, "app", "layout.tsx"),
449
- path3.join(srcDir, "app", "layout.tsx")
462
+ path2.join(templatesDir, "app", "layout.tsx"),
463
+ path2.join(srcDir, "app", "layout.tsx")
450
464
  );
451
465
  await cp(
452
- path3.join(templatesDir, "app", "page.tsx"),
453
- path3.join(srcDir, "app", "page.tsx")
466
+ path2.join(templatesDir, "app", "page.tsx"),
467
+ path2.join(srcDir, "app", "page.tsx")
454
468
  );
455
- await mkdir(path3.join(srcDir, "app", "dashboard"), { recursive: true });
469
+ await mkdir(path2.join(srcDir, "app", "dashboard"), { recursive: true });
456
470
  await cp(
457
- path3.join(templatesDir, "app", "dashboard", "page.tsx"),
458
- path3.join(srcDir, "app", "dashboard", "page.tsx")
471
+ path2.join(templatesDir, "app", "dashboard", "page.tsx"),
472
+ path2.join(srcDir, "app", "dashboard", "page.tsx")
459
473
  );
460
- await mkdir(path3.join(srcDir, "app", "auth", "login"), { recursive: true });
474
+ await mkdir(path2.join(srcDir, "app", "auth", "login"), { recursive: true });
461
475
  await cp(
462
- path3.join(templatesDir, "app", "auth", "login", "page.tsx"),
463
- path3.join(srcDir, "app", "auth", "login", "page.tsx")
476
+ path2.join(templatesDir, "app", "auth", "login", "page.tsx"),
477
+ path2.join(srcDir, "app", "auth", "login", "page.tsx")
464
478
  );
465
479
  await mergeGlobalStyles(projectPath, templatesDir);
466
480
  },
@@ -468,8 +482,8 @@ async function copyTemplate(projectPath) {
468
482
  );
469
483
  }
470
484
  async function mergeGlobalStyles(projectPath, templatesDir) {
471
- const templateCssPath = path3.join(templatesDir, "app", "globals.css");
472
- const projectCssPath = path3.join(projectPath, "src", "app", "globals.css");
485
+ const templateCssPath = path2.join(templatesDir, "app", "globals.css");
486
+ const projectCssPath = path2.join(projectPath, "src", "app", "globals.css");
473
487
  try {
474
488
  const templateCss = await readFile(templateCssPath, "utf-8");
475
489
  const existingCss = await readFile(projectCssPath, "utf-8");
@@ -546,7 +560,7 @@ async function installDependencies(projectPath) {
546
560
 
547
561
  // src/steps/create-env.ts
548
562
  import { writeFile as writeFile2, readFile as readFile2, appendFile } from "fs/promises";
549
- import path4 from "path";
563
+ import path3 from "path";
550
564
  async function createEnvFile(projectPath, supabaseKeys) {
551
565
  await withSpinner(
552
566
  "Creando archivo .env.local...",
@@ -557,10 +571,10 @@ NEXT_PUBLIC_SUPABASE_ANON_KEY=${supabaseKeys.anonKey}
557
571
  SUPABASE_SERVICE_ROLE_KEY=${supabaseKeys.serviceKey}
558
572
  `;
559
573
  await writeFile2(
560
- path4.join(projectPath, ".env.local"),
574
+ path3.join(projectPath, ".env.local"),
561
575
  envContent
562
576
  );
563
- const gitignorePath = path4.join(projectPath, ".gitignore");
577
+ const gitignorePath = path3.join(projectPath, ".gitignore");
564
578
  try {
565
579
  const gitignore = await readFile2(gitignorePath, "utf-8");
566
580
  if (!gitignore.includes(".env.local")) {
@@ -645,30 +659,30 @@ async function createProject(projectName, options = {}) {
645
659
  if (!validation.valid) {
646
660
  throw new Error(validation.error);
647
661
  }
648
- const projectPath = path5.resolve(process.cwd(), projectName);
662
+ const projectPath = path4.resolve(process.cwd(), projectName);
649
663
  if (!await hasConfig()) {
650
664
  logger.warning('No se encontr\xF3 configuraci\xF3n. Ejecuta "create-lft-app config" primero.');
651
665
  throw new Error("Configuraci\xF3n no encontrada");
652
666
  }
653
- const config = await loadConfig();
667
+ const config2 = await loadConfig();
654
668
  logger.newLine();
655
669
  logger.title("Resumen de recursos a crear:");
656
670
  logger.newLine();
657
671
  const resources = [];
658
672
  if (!options.skipGithub) {
659
- resources.push({ label: "GitHub", value: `${config.defaults.githubOrg || config.credentials.github.username}/${projectName} (privado)` });
673
+ resources.push({ label: "GitHub", value: `${config2.defaults.githubOrg || config2.credentials.github.username}/${projectName} (privado)` });
660
674
  }
661
675
  if (!options.skipSupabase) {
662
- resources.push({ label: "Supabase", value: `${projectName} en ${config.defaults.supabaseRegion}` });
676
+ resources.push({ label: "Supabase", value: `${projectName} en ${config2.defaults.supabaseRegion}` });
663
677
  }
664
678
  if (!options.skipJira) {
665
- resources.push({ label: "Jira", value: `Proyecto "${projectName}" en ${config.credentials.jira.domain}` });
679
+ resources.push({ label: "Jira", value: `Proyecto "${projectName}" en ${config2.credentials.jira.domain}` });
666
680
  }
667
681
  resources.push({ label: "Next.js", value: "App Router + TypeScript + Tailwind + Dashboard" });
668
682
  logger.table(resources);
669
683
  logger.newLine();
670
684
  if (!options.autoConfirm) {
671
- const shouldContinue = await confirm2({
685
+ const shouldContinue = await confirm({
672
686
  message: "\xBFContinuar con la creaci\xF3n?",
673
687
  default: true
674
688
  });
@@ -685,14 +699,14 @@ async function createProject(projectName, options = {}) {
685
699
  const externalTasks = [];
686
700
  if (!options.skipGithub) {
687
701
  externalTasks.push(
688
- createGitHubRepo(projectName, config).then((url) => {
702
+ createGitHubRepo(projectName, config2).then((url) => {
689
703
  urls.github = url;
690
704
  })
691
705
  );
692
706
  }
693
707
  if (!options.skipSupabase) {
694
708
  externalTasks.push(
695
- createSupabaseProject(projectName, config).then((result) => {
709
+ createSupabaseProject(projectName, config2).then((result) => {
696
710
  urls.supabase = result.url;
697
711
  supabaseKeys = result;
698
712
  })
@@ -700,7 +714,7 @@ async function createProject(projectName, options = {}) {
700
714
  }
701
715
  if (!options.skipJira) {
702
716
  externalTasks.push(
703
- createJiraProject(projectName, config).then((url) => {
717
+ createJiraProject(projectName, config2).then((url) => {
704
718
  urls.jira = url;
705
719
  })
706
720
  );