@nimbuslab/cli 0.3.5 → 0.4.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/README.md +37 -0
- package/dist/index.js +153 -22
- package/package.json +1 -1
- package/src/commands/create.ts +123 -19
- package/src/index.ts +66 -3
package/README.md
CHANGED
|
@@ -37,12 +37,49 @@ nimbus help
|
|
|
37
37
|
| `help` | Mostrar ajuda |
|
|
38
38
|
| `version` | Mostrar versao |
|
|
39
39
|
|
|
40
|
+
## Flags
|
|
41
|
+
|
|
42
|
+
### Tipo de projeto
|
|
43
|
+
|
|
44
|
+
| Flag | Descricao |
|
|
45
|
+
|------|-----------|
|
|
46
|
+
| `--fast` | Landing page (template fast) |
|
|
47
|
+
| `--fast-plus` | SaaS single-repo (template fast+) |
|
|
48
|
+
| `--turborepo` | SaaS monorepo (template fast+ turborepo) |
|
|
49
|
+
|
|
50
|
+
### Opcoes
|
|
51
|
+
|
|
52
|
+
| Flag | Descricao |
|
|
53
|
+
|------|-----------|
|
|
54
|
+
| `-y, --yes` | Aceitar defaults |
|
|
55
|
+
| `--no-git` | Nao inicializar Git |
|
|
56
|
+
| `--no-install` | Nao instalar dependencias |
|
|
57
|
+
| `--railway` | Configurar Railway automaticamente |
|
|
58
|
+
| `--template <url>` | Usar template customizado |
|
|
59
|
+
|
|
60
|
+
### Exemplos
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Landing page rapida
|
|
64
|
+
nimbus create meu-site --fast
|
|
65
|
+
|
|
66
|
+
# SaaS com Railway
|
|
67
|
+
nimbus create meu-saas --fast-plus --railway
|
|
68
|
+
|
|
69
|
+
# Monorepo sem instalar deps
|
|
70
|
+
nimbus create meu-app --turborepo --no-install
|
|
71
|
+
|
|
72
|
+
# Template customizado
|
|
73
|
+
nimbus create projeto --template usuario/repositorio
|
|
74
|
+
```
|
|
75
|
+
|
|
40
76
|
## Tipos de Projeto
|
|
41
77
|
|
|
42
78
|
| Tipo | Descricao |
|
|
43
79
|
|------|-----------|
|
|
44
80
|
| `fast` | Landing page em 6 dias |
|
|
45
81
|
| `fast+` | SaaS completo com backend |
|
|
82
|
+
| `fast+ (monorepo)` | SaaS com Turborepo |
|
|
46
83
|
|
|
47
84
|
## Requisitos
|
|
48
85
|
|
package/dist/index.js
CHANGED
|
@@ -851,6 +851,45 @@ var TEMPLATES = {
|
|
|
851
851
|
"fast+": "nimbuslab-templates/fastplus-template",
|
|
852
852
|
"fast+-monorepo": "nimbuslab-templates/fastplus-monorepo-template"
|
|
853
853
|
};
|
|
854
|
+
function parseFlags(args) {
|
|
855
|
+
const flags = {
|
|
856
|
+
yes: false,
|
|
857
|
+
fast: false,
|
|
858
|
+
fastPlus: false,
|
|
859
|
+
turborepo: false,
|
|
860
|
+
noGit: false,
|
|
861
|
+
noInstall: false,
|
|
862
|
+
railway: false,
|
|
863
|
+
template: null
|
|
864
|
+
};
|
|
865
|
+
let projectName;
|
|
866
|
+
let i = 0;
|
|
867
|
+
while (i < args.length) {
|
|
868
|
+
const arg = args[i];
|
|
869
|
+
if (arg === "-y" || arg === "--yes") {
|
|
870
|
+
flags.yes = true;
|
|
871
|
+
} else if (arg === "--fast") {
|
|
872
|
+
flags.fast = true;
|
|
873
|
+
} else if (arg === "--fast-plus") {
|
|
874
|
+
flags.fastPlus = true;
|
|
875
|
+
} else if (arg === "--turborepo") {
|
|
876
|
+
flags.turborepo = true;
|
|
877
|
+
} else if (arg === "--no-git") {
|
|
878
|
+
flags.noGit = true;
|
|
879
|
+
} else if (arg === "--no-install") {
|
|
880
|
+
flags.noInstall = true;
|
|
881
|
+
} else if (arg === "--railway") {
|
|
882
|
+
flags.railway = true;
|
|
883
|
+
} else if (arg === "--template") {
|
|
884
|
+
i++;
|
|
885
|
+
flags.template = args[i] ?? null;
|
|
886
|
+
} else if (!arg.startsWith("-")) {
|
|
887
|
+
projectName = arg;
|
|
888
|
+
}
|
|
889
|
+
i++;
|
|
890
|
+
}
|
|
891
|
+
return { flags, projectName };
|
|
892
|
+
}
|
|
854
893
|
async function ensureRailwayCli() {
|
|
855
894
|
const checkCmd = process.platform === "win32" ? "where" : "which";
|
|
856
895
|
const hasRailway = await $2`${checkCmd} railway`.quiet().then(() => true).catch(() => false);
|
|
@@ -939,17 +978,19 @@ async function create(args) {
|
|
|
939
978
|
console.log();
|
|
940
979
|
}
|
|
941
980
|
}
|
|
942
|
-
const
|
|
943
|
-
const projectName = args.find((a) => !a.startsWith("-"));
|
|
981
|
+
const { flags, projectName } = parseFlags(args);
|
|
944
982
|
Ie(import_picocolors3.default.bgCyan(import_picocolors3.default.black(" Novo Projeto nimbuslab ")));
|
|
945
983
|
let config;
|
|
946
|
-
|
|
984
|
+
const hasTypeFlag = flags.fast || flags.fastPlus || flags.turborepo;
|
|
985
|
+
const typeFromFlag = flags.turborepo ? "fast+" : flags.fastPlus ? "fast+" : flags.fast ? "fast" : null;
|
|
986
|
+
const monorepoFromFlag = flags.turborepo;
|
|
987
|
+
if ((flags.yes || hasTypeFlag) && projectName) {
|
|
947
988
|
config = {
|
|
948
989
|
name: projectName,
|
|
949
|
-
type: "fast",
|
|
950
|
-
monorepo:
|
|
951
|
-
git:
|
|
952
|
-
install:
|
|
990
|
+
type: typeFromFlag || "fast",
|
|
991
|
+
monorepo: monorepoFromFlag,
|
|
992
|
+
git: !flags.noGit,
|
|
993
|
+
install: !flags.noInstall,
|
|
953
994
|
github: false,
|
|
954
995
|
githubOrg: null,
|
|
955
996
|
githubDescription: "",
|
|
@@ -960,17 +1001,47 @@ async function create(args) {
|
|
|
960
1001
|
railwayProject: "",
|
|
961
1002
|
railwayToken: "",
|
|
962
1003
|
stagingUrl: "",
|
|
963
|
-
productionUrl: ""
|
|
1004
|
+
productionUrl: "",
|
|
1005
|
+
customTemplate: flags.template
|
|
964
1006
|
};
|
|
1007
|
+
const typeLabel = flags.turborepo ? "fast+ (monorepo)" : config.type;
|
|
965
1008
|
console.log(import_picocolors3.default.dim(` Projeto: ${projectName}`));
|
|
966
|
-
console.log(import_picocolors3.default.dim(` Tipo:
|
|
967
|
-
console.log(import_picocolors3.default.dim(` Git: sim`));
|
|
968
|
-
console.log(import_picocolors3.default.dim(`
|
|
969
|
-
|
|
970
|
-
|
|
1009
|
+
console.log(import_picocolors3.default.dim(` Tipo: ${typeLabel}`));
|
|
1010
|
+
console.log(import_picocolors3.default.dim(` Git: ${config.git ? "sim" : "nao"}`));
|
|
1011
|
+
console.log(import_picocolors3.default.dim(` Instalar: ${config.install ? "sim" : "nao"}`));
|
|
1012
|
+
if (flags.railway)
|
|
1013
|
+
console.log(import_picocolors3.default.dim(` Railway: configurar`));
|
|
1014
|
+
if (flags.template)
|
|
1015
|
+
console.log(import_picocolors3.default.dim(` Template: ${flags.template}`));
|
|
971
1016
|
console.log();
|
|
1017
|
+
if (flags.railway) {
|
|
1018
|
+
const railwayAuthenticated = await isRailwayAuthenticated();
|
|
1019
|
+
if (railwayAuthenticated) {
|
|
1020
|
+
if (config.type === "fast") {
|
|
1021
|
+
const projects = await listRailwayProjects();
|
|
1022
|
+
const fastProject = projects.find((p2) => p2.toLowerCase().includes("fast by nimbuslab"));
|
|
1023
|
+
if (fastProject) {
|
|
1024
|
+
config.railwayProject = fastProject;
|
|
1025
|
+
console.log(import_picocolors3.default.green(` Railway: ${fastProject}`));
|
|
1026
|
+
}
|
|
1027
|
+
} else {
|
|
1028
|
+
console.log(import_picocolors3.default.dim(` Criando projeto Railway: ${projectName}...`));
|
|
1029
|
+
try {
|
|
1030
|
+
const result = await $2`echo "" | railway init -n ${projectName} -w nimbuslab --json`.text();
|
|
1031
|
+
const newProject = JSON.parse(result);
|
|
1032
|
+
config.railwayProject = newProject.name || projectName;
|
|
1033
|
+
console.log(import_picocolors3.default.green(` Railway: ${config.railwayProject} criado`));
|
|
1034
|
+
} catch {
|
|
1035
|
+
console.log(import_picocolors3.default.yellow(` Railway: erro ao criar projeto`));
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
} else {
|
|
1039
|
+
console.log(import_picocolors3.default.yellow(` Railway: nao autenticado (railway login)`));
|
|
1040
|
+
}
|
|
1041
|
+
console.log();
|
|
1042
|
+
}
|
|
972
1043
|
} else {
|
|
973
|
-
config = await promptConfig(projectName);
|
|
1044
|
+
config = await promptConfig(projectName, flags);
|
|
974
1045
|
}
|
|
975
1046
|
if (pD(config)) {
|
|
976
1047
|
xe("Operacao cancelada");
|
|
@@ -980,7 +1051,7 @@ async function create(args) {
|
|
|
980
1051
|
Se(import_picocolors3.default.green("Projeto criado com sucesso!"));
|
|
981
1052
|
showNextSteps(config);
|
|
982
1053
|
}
|
|
983
|
-
async function promptConfig(initialName) {
|
|
1054
|
+
async function promptConfig(initialName, flags) {
|
|
984
1055
|
const name = await he({
|
|
985
1056
|
message: "Nome do projeto:",
|
|
986
1057
|
placeholder: "meu-projeto",
|
|
@@ -1217,14 +1288,22 @@ async function promptConfig(initialName) {
|
|
|
1217
1288
|
railwayProject,
|
|
1218
1289
|
railwayToken,
|
|
1219
1290
|
stagingUrl,
|
|
1220
|
-
productionUrl
|
|
1291
|
+
productionUrl,
|
|
1292
|
+
customTemplate: flags?.template || null
|
|
1221
1293
|
};
|
|
1222
1294
|
}
|
|
1223
1295
|
async function createProject(config) {
|
|
1224
1296
|
const s = Y2();
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1297
|
+
let templateRepo;
|
|
1298
|
+
let templateLabel;
|
|
1299
|
+
if (config.customTemplate) {
|
|
1300
|
+
templateRepo = config.customTemplate;
|
|
1301
|
+
templateLabel = `customizado (${config.customTemplate})`;
|
|
1302
|
+
} else {
|
|
1303
|
+
const templateKey = config.type === "fast+" && config.monorepo ? "fast+-monorepo" : config.type;
|
|
1304
|
+
templateRepo = TEMPLATES[templateKey];
|
|
1305
|
+
templateLabel = config.monorepo ? `${config.type} (monorepo)` : config.type;
|
|
1306
|
+
}
|
|
1228
1307
|
s.start(`Clonando template ${templateLabel}...`);
|
|
1229
1308
|
try {
|
|
1230
1309
|
await $2`gh repo clone ${templateRepo} ${config.name} -- --depth 1`.quiet();
|
|
@@ -1392,6 +1471,8 @@ function showNextSteps(config) {
|
|
|
1392
1471
|
}
|
|
1393
1472
|
|
|
1394
1473
|
// src/index.ts
|
|
1474
|
+
var PACKAGE_NAME = "@nimbuslab/cli";
|
|
1475
|
+
var CURRENT_VERSION = "0.4.2";
|
|
1395
1476
|
var LOGO = `
|
|
1396
1477
|
\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557
|
|
1397
1478
|
\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D
|
|
@@ -1399,6 +1480,40 @@ var LOGO = `
|
|
|
1399
1480
|
\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551
|
|
1400
1481
|
\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551
|
|
1401
1482
|
\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D`;
|
|
1483
|
+
async function checkForUpdates() {
|
|
1484
|
+
try {
|
|
1485
|
+
const controller = new AbortController;
|
|
1486
|
+
const timeout = setTimeout(() => controller.abort(), 3000);
|
|
1487
|
+
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, {
|
|
1488
|
+
signal: controller.signal
|
|
1489
|
+
});
|
|
1490
|
+
clearTimeout(timeout);
|
|
1491
|
+
if (!res.ok)
|
|
1492
|
+
return null;
|
|
1493
|
+
const data = await res.json();
|
|
1494
|
+
const latestVersion = data.version;
|
|
1495
|
+
if (latestVersion && latestVersion !== CURRENT_VERSION) {
|
|
1496
|
+
return latestVersion;
|
|
1497
|
+
}
|
|
1498
|
+
return null;
|
|
1499
|
+
} catch {
|
|
1500
|
+
return null;
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
function showUpdateNotice(latestVersion) {
|
|
1504
|
+
const current = CURRENT_VERSION;
|
|
1505
|
+
const latest = latestVersion;
|
|
1506
|
+
const command = `bun add -g ${PACKAGE_NAME}`;
|
|
1507
|
+
const line1 = ` Nova versao disponivel: ${current} \u2192 ${latest}`;
|
|
1508
|
+
const line2 = ` Atualize com: ${command}`;
|
|
1509
|
+
const maxLen = Math.max(line1.length, line2.length);
|
|
1510
|
+
const border = "\u2500".repeat(maxLen + 2);
|
|
1511
|
+
console.log(import_picocolors4.default.yellow(` \u250C${border}\u2510`));
|
|
1512
|
+
console.log(import_picocolors4.default.yellow(` \u2502`) + import_picocolors4.default.white(line1.padEnd(maxLen + 1)) + import_picocolors4.default.yellow(`\u2502`));
|
|
1513
|
+
console.log(import_picocolors4.default.yellow(` \u2502`) + import_picocolors4.default.cyan(line2.padEnd(maxLen + 1)) + import_picocolors4.default.yellow(`\u2502`));
|
|
1514
|
+
console.log(import_picocolors4.default.yellow(` \u2514${border}\u2518`));
|
|
1515
|
+
console.log();
|
|
1516
|
+
}
|
|
1402
1517
|
async function main() {
|
|
1403
1518
|
const args = process.argv.slice(2);
|
|
1404
1519
|
const command = args[0];
|
|
@@ -1406,6 +1521,10 @@ async function main() {
|
|
|
1406
1521
|
console.log(import_picocolors4.default.white(" CLI da nimbuslab"));
|
|
1407
1522
|
console.log(import_picocolors4.default.dim(" Crie projetos incriveis"));
|
|
1408
1523
|
console.log();
|
|
1524
|
+
const latestVersion = await checkForUpdates();
|
|
1525
|
+
if (latestVersion) {
|
|
1526
|
+
showUpdateNotice(latestVersion);
|
|
1527
|
+
}
|
|
1409
1528
|
if (!command || command === "create") {
|
|
1410
1529
|
await create(args.slice(1));
|
|
1411
1530
|
} else if (command === "help" || command === "--help" || command === "-h") {
|
|
@@ -1427,17 +1546,29 @@ ${import_picocolors4.default.bold("Comandos:")}
|
|
|
1427
1546
|
help Mostrar esta ajuda
|
|
1428
1547
|
version Mostrar versao
|
|
1429
1548
|
|
|
1549
|
+
${import_picocolors4.default.bold("Tipo de projeto:")}
|
|
1550
|
+
--fast Landing page (template fast)
|
|
1551
|
+
--fast-plus SaaS single-repo (template fast+)
|
|
1552
|
+
--turborepo SaaS monorepo (template fast+ turborepo)
|
|
1553
|
+
|
|
1430
1554
|
${import_picocolors4.default.bold("Opcoes:")}
|
|
1431
|
-
-y, --yes Aceitar defaults
|
|
1555
|
+
-y, --yes Aceitar defaults
|
|
1556
|
+
--no-git Nao inicializar Git
|
|
1557
|
+
--no-install Nao instalar dependencias
|
|
1558
|
+
--railway Configurar Railway automaticamente
|
|
1559
|
+
--template <url> Usar template customizado
|
|
1432
1560
|
|
|
1433
1561
|
${import_picocolors4.default.bold("Exemplos:")}
|
|
1434
1562
|
${import_picocolors4.default.dim("$")} nimbus create meu-projeto
|
|
1435
1563
|
${import_picocolors4.default.dim("$")} nimbus create meu-projeto -y
|
|
1436
|
-
${import_picocolors4.default.dim("$")} nimbus create
|
|
1564
|
+
${import_picocolors4.default.dim("$")} nimbus create meu-projeto --fast
|
|
1565
|
+
${import_picocolors4.default.dim("$")} nimbus create meu-saas --fast-plus --railway
|
|
1566
|
+
${import_picocolors4.default.dim("$")} nimbus create meu-app --turborepo --no-install
|
|
1567
|
+
${import_picocolors4.default.dim("$")} nimbus create custom --template user/repo
|
|
1437
1568
|
`);
|
|
1438
1569
|
}
|
|
1439
1570
|
function showVersion() {
|
|
1440
|
-
console.log(
|
|
1571
|
+
console.log(`${PACKAGE_NAME} v${CURRENT_VERSION}`);
|
|
1441
1572
|
}
|
|
1442
1573
|
main().catch((err) => {
|
|
1443
1574
|
console.error(import_picocolors4.default.red("Erro:"), err.message);
|
package/package.json
CHANGED
package/src/commands/create.ts
CHANGED
|
@@ -31,6 +31,64 @@ interface ProjectConfig {
|
|
|
31
31
|
railwayToken: string
|
|
32
32
|
stagingUrl: string
|
|
33
33
|
productionUrl: string
|
|
34
|
+
// Template customizado
|
|
35
|
+
customTemplate: string | null
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface CreateFlags {
|
|
39
|
+
yes: boolean
|
|
40
|
+
fast: boolean
|
|
41
|
+
fastPlus: boolean
|
|
42
|
+
turborepo: boolean
|
|
43
|
+
noGit: boolean
|
|
44
|
+
noInstall: boolean
|
|
45
|
+
railway: boolean
|
|
46
|
+
template: string | null
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function parseFlags(args: string[]): { flags: CreateFlags; projectName: string | undefined } {
|
|
50
|
+
const flags: CreateFlags = {
|
|
51
|
+
yes: false,
|
|
52
|
+
fast: false,
|
|
53
|
+
fastPlus: false,
|
|
54
|
+
turborepo: false,
|
|
55
|
+
noGit: false,
|
|
56
|
+
noInstall: false,
|
|
57
|
+
railway: false,
|
|
58
|
+
template: null,
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let projectName: string | undefined
|
|
62
|
+
let i = 0
|
|
63
|
+
|
|
64
|
+
while (i < args.length) {
|
|
65
|
+
const arg = args[i]!
|
|
66
|
+
|
|
67
|
+
if (arg === "-y" || arg === "--yes") {
|
|
68
|
+
flags.yes = true
|
|
69
|
+
} else if (arg === "--fast") {
|
|
70
|
+
flags.fast = true
|
|
71
|
+
} else if (arg === "--fast-plus") {
|
|
72
|
+
flags.fastPlus = true
|
|
73
|
+
} else if (arg === "--turborepo") {
|
|
74
|
+
flags.turborepo = true
|
|
75
|
+
} else if (arg === "--no-git") {
|
|
76
|
+
flags.noGit = true
|
|
77
|
+
} else if (arg === "--no-install") {
|
|
78
|
+
flags.noInstall = true
|
|
79
|
+
} else if (arg === "--railway") {
|
|
80
|
+
flags.railway = true
|
|
81
|
+
} else if (arg === "--template") {
|
|
82
|
+
i++
|
|
83
|
+
flags.template = args[i] ?? null
|
|
84
|
+
} else if (!arg.startsWith("-")) {
|
|
85
|
+
projectName = arg
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
i++
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return { flags, projectName }
|
|
34
92
|
}
|
|
35
93
|
|
|
36
94
|
// M30: Verificar e instalar Railway CLI
|
|
@@ -139,21 +197,25 @@ export async function create(args: string[]) {
|
|
|
139
197
|
}
|
|
140
198
|
}
|
|
141
199
|
|
|
142
|
-
const
|
|
143
|
-
const projectName = args.find(a => !a.startsWith("-"))
|
|
200
|
+
const { flags, projectName } = parseFlags(args)
|
|
144
201
|
|
|
145
202
|
p.intro(pc.bgCyan(pc.black(" Novo Projeto nimbuslab ")))
|
|
146
203
|
|
|
147
204
|
let config: ProjectConfig | symbol
|
|
148
205
|
|
|
149
|
-
|
|
150
|
-
|
|
206
|
+
// Determina tipo baseado nas flags
|
|
207
|
+
const hasTypeFlag = flags.fast || flags.fastPlus || flags.turborepo
|
|
208
|
+
const typeFromFlag = flags.turborepo ? "fast+" : flags.fastPlus ? "fast+" : flags.fast ? "fast" : null
|
|
209
|
+
const monorepoFromFlag = flags.turborepo
|
|
210
|
+
|
|
211
|
+
// Modo automatico: -y com nome OU flags de tipo com nome
|
|
212
|
+
if ((flags.yes || hasTypeFlag) && projectName) {
|
|
151
213
|
config = {
|
|
152
214
|
name: projectName,
|
|
153
|
-
type: "fast",
|
|
154
|
-
monorepo:
|
|
155
|
-
git:
|
|
156
|
-
install:
|
|
215
|
+
type: typeFromFlag || "fast",
|
|
216
|
+
monorepo: monorepoFromFlag,
|
|
217
|
+
git: !flags.noGit,
|
|
218
|
+
install: !flags.noInstall,
|
|
157
219
|
github: false,
|
|
158
220
|
githubOrg: null,
|
|
159
221
|
githubDescription: "",
|
|
@@ -165,16 +227,48 @@ export async function create(args: string[]) {
|
|
|
165
227
|
railwayToken: "",
|
|
166
228
|
stagingUrl: "",
|
|
167
229
|
productionUrl: "",
|
|
230
|
+
customTemplate: flags.template,
|
|
168
231
|
}
|
|
232
|
+
|
|
233
|
+
const typeLabel = flags.turborepo ? "fast+ (monorepo)" : config.type
|
|
169
234
|
console.log(pc.dim(` Projeto: ${projectName}`))
|
|
170
|
-
console.log(pc.dim(` Tipo:
|
|
171
|
-
console.log(pc.dim(` Git: sim`))
|
|
172
|
-
console.log(pc.dim(`
|
|
173
|
-
console.log(pc.dim(`
|
|
174
|
-
console.log(pc.dim(`
|
|
235
|
+
console.log(pc.dim(` Tipo: ${typeLabel}`))
|
|
236
|
+
console.log(pc.dim(` Git: ${config.git ? "sim" : "nao"}`))
|
|
237
|
+
console.log(pc.dim(` Instalar: ${config.install ? "sim" : "nao"}`))
|
|
238
|
+
if (flags.railway) console.log(pc.dim(` Railway: configurar`))
|
|
239
|
+
if (flags.template) console.log(pc.dim(` Template: ${flags.template}`))
|
|
175
240
|
console.log()
|
|
241
|
+
|
|
242
|
+
// Railway automatico se flag --railway
|
|
243
|
+
if (flags.railway) {
|
|
244
|
+
const railwayAuthenticated = await isRailwayAuthenticated()
|
|
245
|
+
if (railwayAuthenticated) {
|
|
246
|
+
if (config.type === "fast") {
|
|
247
|
+
const projects = await listRailwayProjects()
|
|
248
|
+
const fastProject = projects.find(p => p.toLowerCase().includes("fast by nimbuslab"))
|
|
249
|
+
if (fastProject) {
|
|
250
|
+
config.railwayProject = fastProject
|
|
251
|
+
console.log(pc.green(` Railway: ${fastProject}`))
|
|
252
|
+
}
|
|
253
|
+
} else {
|
|
254
|
+
// Fast+: cria projeto novo automaticamente
|
|
255
|
+
console.log(pc.dim(` Criando projeto Railway: ${projectName}...`))
|
|
256
|
+
try {
|
|
257
|
+
const result = await $`echo "" | railway init -n ${projectName} -w nimbuslab --json`.text()
|
|
258
|
+
const newProject = JSON.parse(result)
|
|
259
|
+
config.railwayProject = newProject.name || projectName
|
|
260
|
+
console.log(pc.green(` Railway: ${config.railwayProject} criado`))
|
|
261
|
+
} catch {
|
|
262
|
+
console.log(pc.yellow(` Railway: erro ao criar projeto`))
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
} else {
|
|
266
|
+
console.log(pc.yellow(` Railway: nao autenticado (railway login)`))
|
|
267
|
+
}
|
|
268
|
+
console.log()
|
|
269
|
+
}
|
|
176
270
|
} else {
|
|
177
|
-
config = await promptConfig(projectName)
|
|
271
|
+
config = await promptConfig(projectName, flags)
|
|
178
272
|
}
|
|
179
273
|
|
|
180
274
|
if (p.isCancel(config)) {
|
|
@@ -189,7 +283,7 @@ export async function create(args: string[]) {
|
|
|
189
283
|
showNextSteps(config as ProjectConfig)
|
|
190
284
|
}
|
|
191
285
|
|
|
192
|
-
async function promptConfig(initialName?: string): Promise<ProjectConfig | symbol> {
|
|
286
|
+
async function promptConfig(initialName?: string, flags?: CreateFlags): Promise<ProjectConfig | symbol> {
|
|
193
287
|
const name = await p.text({
|
|
194
288
|
message: "Nome do projeto:",
|
|
195
289
|
placeholder: "meu-projeto",
|
|
@@ -468,16 +562,26 @@ async function promptConfig(initialName?: string): Promise<ProjectConfig | symbo
|
|
|
468
562
|
railwayToken,
|
|
469
563
|
stagingUrl,
|
|
470
564
|
productionUrl,
|
|
565
|
+
customTemplate: flags?.template || null,
|
|
471
566
|
}
|
|
472
567
|
}
|
|
473
568
|
|
|
474
569
|
async function createProject(config: ProjectConfig) {
|
|
475
570
|
const s = p.spinner()
|
|
476
571
|
|
|
477
|
-
//
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
572
|
+
// Determina template: customizado ou padrao
|
|
573
|
+
let templateRepo: string
|
|
574
|
+
let templateLabel: string
|
|
575
|
+
|
|
576
|
+
if (config.customTemplate) {
|
|
577
|
+
templateRepo = config.customTemplate
|
|
578
|
+
templateLabel = `customizado (${config.customTemplate})`
|
|
579
|
+
} else {
|
|
580
|
+
const templateKey = config.type === "fast+" && config.monorepo ? "fast+-monorepo" : config.type
|
|
581
|
+
templateRepo = TEMPLATES[templateKey]
|
|
582
|
+
templateLabel = config.monorepo ? `${config.type} (monorepo)` : config.type
|
|
583
|
+
}
|
|
584
|
+
|
|
481
585
|
s.start(`Clonando template ${templateLabel}...`)
|
|
482
586
|
try {
|
|
483
587
|
await $`gh repo clone ${templateRepo} ${config.name} -- --depth 1`.quiet()
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,9 @@ import * as p from "@clack/prompts"
|
|
|
4
4
|
import pc from "picocolors"
|
|
5
5
|
import { create } from "./commands/create"
|
|
6
6
|
|
|
7
|
+
const PACKAGE_NAME = "@nimbuslab/cli"
|
|
8
|
+
const CURRENT_VERSION = "0.4.2"
|
|
9
|
+
|
|
7
10
|
const LOGO = `
|
|
8
11
|
███╗ ██╗██╗███╗ ███╗██████╗ ██╗ ██╗███████╗
|
|
9
12
|
████╗ ██║██║████╗ ████║██╔══██╗██║ ██║██╔════╝
|
|
@@ -12,6 +15,48 @@ const LOGO = `
|
|
|
12
15
|
██║ ╚████║██║██║ ╚═╝ ██║██████╔╝╚██████╔╝███████║
|
|
13
16
|
╚═╝ ╚═══╝╚═╝╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚══════╝`
|
|
14
17
|
|
|
18
|
+
async function checkForUpdates(): Promise<string | null> {
|
|
19
|
+
try {
|
|
20
|
+
const controller = new AbortController()
|
|
21
|
+
const timeout = setTimeout(() => controller.abort(), 3000)
|
|
22
|
+
|
|
23
|
+
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, {
|
|
24
|
+
signal: controller.signal,
|
|
25
|
+
})
|
|
26
|
+
clearTimeout(timeout)
|
|
27
|
+
|
|
28
|
+
if (!res.ok) return null
|
|
29
|
+
|
|
30
|
+
const data = await res.json() as { version?: string }
|
|
31
|
+
const latestVersion = data.version
|
|
32
|
+
|
|
33
|
+
if (latestVersion && latestVersion !== CURRENT_VERSION) {
|
|
34
|
+
return latestVersion
|
|
35
|
+
}
|
|
36
|
+
return null
|
|
37
|
+
} catch {
|
|
38
|
+
return null
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function showUpdateNotice(latestVersion: string) {
|
|
43
|
+
const current = CURRENT_VERSION
|
|
44
|
+
const latest = latestVersion
|
|
45
|
+
const command = `bun add -g ${PACKAGE_NAME}`
|
|
46
|
+
|
|
47
|
+
const line1 = ` Nova versao disponivel: ${current} → ${latest}`
|
|
48
|
+
const line2 = ` Atualize com: ${command}`
|
|
49
|
+
|
|
50
|
+
const maxLen = Math.max(line1.length, line2.length)
|
|
51
|
+
const border = "─".repeat(maxLen + 2)
|
|
52
|
+
|
|
53
|
+
console.log(pc.yellow(` ┌${border}┐`))
|
|
54
|
+
console.log(pc.yellow(` │`) + pc.white(line1.padEnd(maxLen + 1)) + pc.yellow(`│`))
|
|
55
|
+
console.log(pc.yellow(` │`) + pc.cyan(line2.padEnd(maxLen + 1)) + pc.yellow(`│`))
|
|
56
|
+
console.log(pc.yellow(` └${border}┘`))
|
|
57
|
+
console.log()
|
|
58
|
+
}
|
|
59
|
+
|
|
15
60
|
async function main() {
|
|
16
61
|
const args = process.argv.slice(2)
|
|
17
62
|
const command = args[0]
|
|
@@ -21,6 +66,12 @@ async function main() {
|
|
|
21
66
|
console.log(pc.dim(" Crie projetos incriveis"))
|
|
22
67
|
console.log()
|
|
23
68
|
|
|
69
|
+
// Check for updates (non-blocking)
|
|
70
|
+
const latestVersion = await checkForUpdates()
|
|
71
|
+
if (latestVersion) {
|
|
72
|
+
showUpdateNotice(latestVersion)
|
|
73
|
+
}
|
|
74
|
+
|
|
24
75
|
if (!command || command === "create") {
|
|
25
76
|
await create(args.slice(1))
|
|
26
77
|
} else if (command === "help" || command === "--help" || command === "-h") {
|
|
@@ -43,18 +94,30 @@ ${pc.bold("Comandos:")}
|
|
|
43
94
|
help Mostrar esta ajuda
|
|
44
95
|
version Mostrar versao
|
|
45
96
|
|
|
97
|
+
${pc.bold("Tipo de projeto:")}
|
|
98
|
+
--fast Landing page (template fast)
|
|
99
|
+
--fast-plus SaaS single-repo (template fast+)
|
|
100
|
+
--turborepo SaaS monorepo (template fast+ turborepo)
|
|
101
|
+
|
|
46
102
|
${pc.bold("Opcoes:")}
|
|
47
|
-
-y, --yes Aceitar defaults
|
|
103
|
+
-y, --yes Aceitar defaults
|
|
104
|
+
--no-git Nao inicializar Git
|
|
105
|
+
--no-install Nao instalar dependencias
|
|
106
|
+
--railway Configurar Railway automaticamente
|
|
107
|
+
--template <url> Usar template customizado
|
|
48
108
|
|
|
49
109
|
${pc.bold("Exemplos:")}
|
|
50
110
|
${pc.dim("$")} nimbus create meu-projeto
|
|
51
111
|
${pc.dim("$")} nimbus create meu-projeto -y
|
|
52
|
-
${pc.dim("$")} nimbus create
|
|
112
|
+
${pc.dim("$")} nimbus create meu-projeto --fast
|
|
113
|
+
${pc.dim("$")} nimbus create meu-saas --fast-plus --railway
|
|
114
|
+
${pc.dim("$")} nimbus create meu-app --turborepo --no-install
|
|
115
|
+
${pc.dim("$")} nimbus create custom --template user/repo
|
|
53
116
|
`)
|
|
54
117
|
}
|
|
55
118
|
|
|
56
119
|
function showVersion() {
|
|
57
|
-
console.log(
|
|
120
|
+
console.log(`${PACKAGE_NAME} v${CURRENT_VERSION}`)
|
|
58
121
|
}
|
|
59
122
|
|
|
60
123
|
main().catch((err) => {
|