@nimbuslab/cli 1.2.0 → 1.2.1
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/index.js +377 -1308
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -147,7 +147,7 @@ var require_src = __commonJS((exports, module) => {
|
|
|
147
147
|
});
|
|
148
148
|
|
|
149
149
|
// src/index.ts
|
|
150
|
-
var
|
|
150
|
+
var import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
151
151
|
|
|
152
152
|
// node_modules/@clack/core/dist/index.mjs
|
|
153
153
|
var import_sisteransi = __toESM(require_src(), 1);
|
|
@@ -526,41 +526,6 @@ class dD extends x {
|
|
|
526
526
|
}
|
|
527
527
|
var A;
|
|
528
528
|
A = new WeakMap;
|
|
529
|
-
var kD = Object.defineProperty;
|
|
530
|
-
var $D = (e, u, t) => (u in e) ? kD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
|
|
531
|
-
var H = (e, u, t) => ($D(e, typeof u != "symbol" ? u + "" : u, t), t);
|
|
532
|
-
var SD = class extends x {
|
|
533
|
-
constructor(u) {
|
|
534
|
-
super(u, false), H(this, "options"), H(this, "cursor", 0), this.options = u.options, this.value = [...u.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: t }) => t === u.cursorAt), 0), this.on("key", (t) => {
|
|
535
|
-
t === "a" && this.toggleAll();
|
|
536
|
-
}), this.on("cursor", (t) => {
|
|
537
|
-
switch (t) {
|
|
538
|
-
case "left":
|
|
539
|
-
case "up":
|
|
540
|
-
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
541
|
-
break;
|
|
542
|
-
case "down":
|
|
543
|
-
case "right":
|
|
544
|
-
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
545
|
-
break;
|
|
546
|
-
case "space":
|
|
547
|
-
this.toggleValue();
|
|
548
|
-
break;
|
|
549
|
-
}
|
|
550
|
-
});
|
|
551
|
-
}
|
|
552
|
-
get _value() {
|
|
553
|
-
return this.options[this.cursor].value;
|
|
554
|
-
}
|
|
555
|
-
toggleAll() {
|
|
556
|
-
const u = this.value.length === this.options.length;
|
|
557
|
-
this.value = u ? [] : this.options.map((t) => t.value);
|
|
558
|
-
}
|
|
559
|
-
toggleValue() {
|
|
560
|
-
const u = this.value.includes(this._value);
|
|
561
|
-
this.value = u ? this.value.filter((t) => t !== this._value) : [...this.value, this._value];
|
|
562
|
-
}
|
|
563
|
-
};
|
|
564
529
|
var OD = Object.defineProperty;
|
|
565
530
|
var PD = (e, u, t) => (u in e) ? OD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
|
|
566
531
|
var J = (e, u, t) => (PD(e, typeof u != "symbol" ? u + "" : u, t), t);
|
|
@@ -732,47 +697,6 @@ ${import_picocolors2.default.cyan(d2)}
|
|
|
732
697
|
}
|
|
733
698
|
} }).prompt();
|
|
734
699
|
};
|
|
735
|
-
var fe = (t) => {
|
|
736
|
-
const n = (r2, i) => {
|
|
737
|
-
const s = r2.label ?? String(r2.value);
|
|
738
|
-
return i === "active" ? `${import_picocolors2.default.cyan(A2)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "selected" ? `${import_picocolors2.default.green(T)} ${import_picocolors2.default.dim(s)} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "cancelled" ? `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}` : i === "active-selected" ? `${import_picocolors2.default.green(T)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "submitted" ? `${import_picocolors2.default.dim(s)}` : `${import_picocolors2.default.dim(F)} ${import_picocolors2.default.dim(s)}`;
|
|
739
|
-
};
|
|
740
|
-
return new SD({ options: t.options, initialValues: t.initialValues, required: t.required ?? true, cursorAt: t.cursorAt, validate(r2) {
|
|
741
|
-
if (this.required && r2.length === 0)
|
|
742
|
-
return `Please select at least one option.
|
|
743
|
-
${import_picocolors2.default.reset(import_picocolors2.default.dim(`Press ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" space ")))} to select, ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" enter ")))} to submit`))}`;
|
|
744
|
-
}, render() {
|
|
745
|
-
const r2 = `${import_picocolors2.default.gray(o)}
|
|
746
|
-
${b2(this.state)} ${t.message}
|
|
747
|
-
`, i = (s, c) => {
|
|
748
|
-
const a = this.value.includes(s.value);
|
|
749
|
-
return c && a ? n(s, "active-selected") : a ? n(s, "selected") : n(s, c ? "active" : "inactive");
|
|
750
|
-
};
|
|
751
|
-
switch (this.state) {
|
|
752
|
-
case "submit":
|
|
753
|
-
return `${r2}${import_picocolors2.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "submitted")).join(import_picocolors2.default.dim(", ")) || import_picocolors2.default.dim("none")}`;
|
|
754
|
-
case "cancel": {
|
|
755
|
-
const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => n(c, "cancelled")).join(import_picocolors2.default.dim(", "));
|
|
756
|
-
return `${r2}${import_picocolors2.default.gray(o)} ${s.trim() ? `${s}
|
|
757
|
-
${import_picocolors2.default.gray(o)}` : ""}`;
|
|
758
|
-
}
|
|
759
|
-
case "error": {
|
|
760
|
-
const s = this.error.split(`
|
|
761
|
-
`).map((c, a) => a === 0 ? `${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(c)}` : ` ${c}`).join(`
|
|
762
|
-
`);
|
|
763
|
-
return `${r2 + import_picocolors2.default.yellow(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
|
|
764
|
-
${import_picocolors2.default.yellow(o)} `)}
|
|
765
|
-
${s}
|
|
766
|
-
`;
|
|
767
|
-
}
|
|
768
|
-
default:
|
|
769
|
-
return `${r2}${import_picocolors2.default.cyan(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
|
|
770
|
-
${import_picocolors2.default.cyan(o)} `)}
|
|
771
|
-
${import_picocolors2.default.cyan(d2)}
|
|
772
|
-
`;
|
|
773
|
-
}
|
|
774
|
-
} }).prompt();
|
|
775
|
-
};
|
|
776
700
|
var xe = (t = "") => {
|
|
777
701
|
process.stdout.write(`${import_picocolors2.default.gray(d2)} ${import_picocolors2.default.red(t)}
|
|
778
702
|
|
|
@@ -833,7 +757,7 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
833
757
|
}, R2 = (m2) => m2.replace(/\.+$/, ""), O2 = (m2) => {
|
|
834
758
|
const h2 = (performance.now() - m2) / 1000, w2 = Math.floor(h2 / 60), I2 = Math.floor(h2 % 60);
|
|
835
759
|
return w2 > 0 ? `[${w2}m ${I2}s]` : `[${I2}s]`;
|
|
836
|
-
},
|
|
760
|
+
}, H = (m2 = "") => {
|
|
837
761
|
a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${import_picocolors2.default.gray(o)}
|
|
838
762
|
`);
|
|
839
763
|
let h2 = 0, w2 = 0;
|
|
@@ -859,13 +783,13 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
859
783
|
`) : process.stdout.write(`${w2} ${l2}
|
|
860
784
|
`), E(), s();
|
|
861
785
|
};
|
|
862
|
-
return { start:
|
|
786
|
+
return { start: H, stop: N2, message: (m2 = "") => {
|
|
863
787
|
l2 = R2(m2 ?? l2);
|
|
864
788
|
} };
|
|
865
789
|
};
|
|
866
790
|
|
|
867
791
|
// src/commands/create.ts
|
|
868
|
-
var
|
|
792
|
+
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
869
793
|
var {$: $2 } = globalThis.Bun;
|
|
870
794
|
import { rm, mkdir } from "fs/promises";
|
|
871
795
|
import { join as join2 } from "path";
|
|
@@ -1007,8 +931,8 @@ ${config.features.contactForm ? `### Add form validation
|
|
|
1007
931
|
\`\`\`typescript
|
|
1008
932
|
// lib/validations.ts
|
|
1009
933
|
export const contactSchema = z.object({
|
|
1010
|
-
email: z.string().email('
|
|
1011
|
-
message: z.string().min(10, '
|
|
934
|
+
email: z.string().email('Invalid email'),
|
|
935
|
+
message: z.string().min(10, 'Minimum 10 characters'),
|
|
1012
936
|
})
|
|
1013
937
|
|
|
1014
938
|
// components/forms/contact-form.tsx
|
|
@@ -1293,7 +1217,7 @@ ${config.features.contactForm ? `## Form with Validation
|
|
|
1293
1217
|
// lib/validations.ts
|
|
1294
1218
|
export const contactSchema = z.object({
|
|
1295
1219
|
name: z.string().min(2, 'Nome muito curto'),
|
|
1296
|
-
email: z.string().email('
|
|
1220
|
+
email: z.string().email('Invalid email'),
|
|
1297
1221
|
message: z.string().min(10, 'Mensagem muito curta'),
|
|
1298
1222
|
})
|
|
1299
1223
|
|
|
@@ -1709,197 +1633,12 @@ async function createCompatibilitySymlinks(projectPath) {
|
|
|
1709
1633
|
await Bun.$`mkdir -p ${githubDir}`.quiet();
|
|
1710
1634
|
await Bun.write(join(githubDir, "copilot-instructions.md"), agentsContent);
|
|
1711
1635
|
}
|
|
1712
|
-
// src/lib/generators/interactive-setup.ts
|
|
1713
|
-
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
1714
|
-
var SERVICE_INFO = {
|
|
1715
|
-
resend: {
|
|
1716
|
-
name: "Resend",
|
|
1717
|
-
description: "Servi\xE7o de email transacional",
|
|
1718
|
-
pricing: "Gr\xE1tis: 3,000 emails/m\xEAs",
|
|
1719
|
-
signupUrl: "https://resend.com/signup",
|
|
1720
|
-
apiKeyUrl: "https://resend.com/api-keys",
|
|
1721
|
-
keyPrefix: "re_"
|
|
1722
|
-
},
|
|
1723
|
-
googleAnalytics: {
|
|
1724
|
-
name: "Google Analytics",
|
|
1725
|
-
description: "Analytics e m\xE9tricas do site",
|
|
1726
|
-
pricing: "Gr\xE1tis",
|
|
1727
|
-
setupUrl: "https://analytics.google.com",
|
|
1728
|
-
keyFormat: "G-XXXXXXXXXX"
|
|
1729
|
-
}
|
|
1730
|
-
};
|
|
1731
|
-
async function interactiveSetup(templateType) {
|
|
1732
|
-
console.log();
|
|
1733
|
-
console.log(import_picocolors3.default.cyan(" Configura\xE7\xE3o Interativa"));
|
|
1734
|
-
console.log(import_picocolors3.default.dim(" ======================="));
|
|
1735
|
-
console.log();
|
|
1736
|
-
const skipSetup = await ye({
|
|
1737
|
-
message: "Deseja configurar integra\xE7\xF5es agora?",
|
|
1738
|
-
initialValue: true
|
|
1739
|
-
});
|
|
1740
|
-
if (pD(skipSetup) || !skipSetup) {
|
|
1741
|
-
return {
|
|
1742
|
-
features: {
|
|
1743
|
-
contactForm: false,
|
|
1744
|
-
newsletter: false,
|
|
1745
|
-
analytics: false
|
|
1746
|
-
},
|
|
1747
|
-
apiKeys: {},
|
|
1748
|
-
skipSetup: true
|
|
1749
|
-
};
|
|
1750
|
-
}
|
|
1751
|
-
const result = {
|
|
1752
|
-
features: {
|
|
1753
|
-
contactForm: false,
|
|
1754
|
-
newsletter: false,
|
|
1755
|
-
analytics: false
|
|
1756
|
-
},
|
|
1757
|
-
apiKeys: {},
|
|
1758
|
-
skipSetup: false
|
|
1759
|
-
};
|
|
1760
|
-
if (templateType === "landing" || templateType === "app") {
|
|
1761
|
-
const contactFormSetup = await setupContactForm();
|
|
1762
|
-
if (!pD(contactFormSetup)) {
|
|
1763
|
-
result.features.contactForm = contactFormSetup.enabled;
|
|
1764
|
-
if (contactFormSetup.apiKey) {
|
|
1765
|
-
result.apiKeys.resend = contactFormSetup.apiKey;
|
|
1766
|
-
}
|
|
1767
|
-
}
|
|
1768
|
-
}
|
|
1769
|
-
const analyticsSetup = await setupAnalytics();
|
|
1770
|
-
if (!pD(analyticsSetup)) {
|
|
1771
|
-
result.features.analytics = analyticsSetup.enabled;
|
|
1772
|
-
if (analyticsSetup.trackingId) {
|
|
1773
|
-
result.apiKeys.ga = analyticsSetup.trackingId;
|
|
1774
|
-
}
|
|
1775
|
-
}
|
|
1776
|
-
return result;
|
|
1777
|
-
}
|
|
1778
|
-
async function setupContactForm() {
|
|
1779
|
-
console.log();
|
|
1780
|
-
console.log(import_picocolors3.default.cyan(" \uD83D\uDCE7 Formul\xE1rio de Contato"));
|
|
1781
|
-
console.log();
|
|
1782
|
-
const needsForm = await ve({
|
|
1783
|
-
message: "Incluir formul\xE1rio de contato?",
|
|
1784
|
-
options: [
|
|
1785
|
-
{ value: "now", label: "Sim, configurar agora" },
|
|
1786
|
-
{ value: "later", label: "Sim, mas configurar depois" },
|
|
1787
|
-
{ value: "no", label: "N\xE3o incluir" }
|
|
1788
|
-
]
|
|
1789
|
-
});
|
|
1790
|
-
if (pD(needsForm) || needsForm === "no") {
|
|
1791
|
-
return { enabled: false };
|
|
1792
|
-
}
|
|
1793
|
-
if (needsForm === "later") {
|
|
1794
|
-
return { enabled: true };
|
|
1795
|
-
}
|
|
1796
|
-
showServiceInfo("resend");
|
|
1797
|
-
const apiKey = await he({
|
|
1798
|
-
message: "Resend API Key (deixe vazio para configurar depois):",
|
|
1799
|
-
placeholder: "re_...",
|
|
1800
|
-
validate: (v2) => {
|
|
1801
|
-
if (!v2)
|
|
1802
|
-
return;
|
|
1803
|
-
if (!v2.startsWith(SERVICE_INFO.resend.keyPrefix)) {
|
|
1804
|
-
return `Key inv\xE1lida (deve come\xE7ar com ${SERVICE_INFO.resend.keyPrefix})`;
|
|
1805
|
-
}
|
|
1806
|
-
return;
|
|
1807
|
-
}
|
|
1808
|
-
});
|
|
1809
|
-
if (pD(apiKey)) {
|
|
1810
|
-
return { enabled: true };
|
|
1811
|
-
}
|
|
1812
|
-
return {
|
|
1813
|
-
enabled: true,
|
|
1814
|
-
apiKey: apiKey || undefined
|
|
1815
|
-
};
|
|
1816
|
-
}
|
|
1817
|
-
async function setupAnalytics() {
|
|
1818
|
-
console.log();
|
|
1819
|
-
console.log(import_picocolors3.default.cyan(" \uD83D\uDCCA Analytics"));
|
|
1820
|
-
console.log();
|
|
1821
|
-
const needsAnalytics = await ye({
|
|
1822
|
-
message: "Incluir Google Analytics?",
|
|
1823
|
-
initialValue: false
|
|
1824
|
-
});
|
|
1825
|
-
if (pD(needsAnalytics) || !needsAnalytics) {
|
|
1826
|
-
return { enabled: false };
|
|
1827
|
-
}
|
|
1828
|
-
showServiceInfo("googleAnalytics");
|
|
1829
|
-
const trackingId = await he({
|
|
1830
|
-
message: "Google Analytics Tracking ID (deixe vazio para configurar depois):",
|
|
1831
|
-
placeholder: "G-XXXXXXXXXX",
|
|
1832
|
-
validate: (v2) => {
|
|
1833
|
-
if (!v2)
|
|
1834
|
-
return;
|
|
1835
|
-
if (!v2.startsWith("G-")) {
|
|
1836
|
-
return "ID inv\xE1lido (deve come\xE7ar com G-)";
|
|
1837
|
-
}
|
|
1838
|
-
return;
|
|
1839
|
-
}
|
|
1840
|
-
});
|
|
1841
|
-
if (pD(trackingId)) {
|
|
1842
|
-
return { enabled: false };
|
|
1843
|
-
}
|
|
1844
|
-
return {
|
|
1845
|
-
enabled: true,
|
|
1846
|
-
trackingId: trackingId || undefined
|
|
1847
|
-
};
|
|
1848
|
-
}
|
|
1849
|
-
function showServiceInfo(service) {
|
|
1850
|
-
const info = SERVICE_INFO[service];
|
|
1851
|
-
console.log();
|
|
1852
|
-
console.log(import_picocolors3.default.bold(` ${info.name}`));
|
|
1853
|
-
console.log(import_picocolors3.default.dim(` ${info.description}`));
|
|
1854
|
-
console.log(import_picocolors3.default.dim(` ${info.pricing}`));
|
|
1855
|
-
if ("apiKeyUrl" in info) {
|
|
1856
|
-
console.log(import_picocolors3.default.cyan(` ${info.apiKeyUrl}`));
|
|
1857
|
-
} else if ("setupUrl" in info) {
|
|
1858
|
-
console.log(import_picocolors3.default.cyan(` ${info.setupUrl}`));
|
|
1859
|
-
}
|
|
1860
|
-
console.log();
|
|
1861
|
-
}
|
|
1862
|
-
async function generateEnvFile(projectPath, apiKeys, features) {
|
|
1863
|
-
const lines = [
|
|
1864
|
-
"# ====================================",
|
|
1865
|
-
"# Environment Variables",
|
|
1866
|
-
"# ====================================",
|
|
1867
|
-
"",
|
|
1868
|
-
"# IMPORTANT: Add this file to .gitignore",
|
|
1869
|
-
"# Never commit API keys to version control!",
|
|
1870
|
-
""
|
|
1871
|
-
];
|
|
1872
|
-
if (features.contactForm) {
|
|
1873
|
-
lines.push("# Email (Resend)");
|
|
1874
|
-
lines.push("# Get your key: https://resend.com/api-keys");
|
|
1875
|
-
lines.push(`RESEND_API_KEY=${apiKeys.resend || "your_api_key_here"}`);
|
|
1876
|
-
lines.push("");
|
|
1877
|
-
}
|
|
1878
|
-
if (features.analytics) {
|
|
1879
|
-
lines.push("# Analytics (Google Analytics)");
|
|
1880
|
-
lines.push("# Get your ID: https://analytics.google.com");
|
|
1881
|
-
lines.push(`NEXT_PUBLIC_GA_ID=${apiKeys.ga || "G-XXXXXXXXXX"}`);
|
|
1882
|
-
lines.push("");
|
|
1883
|
-
}
|
|
1884
|
-
lines.push("# ====================================");
|
|
1885
|
-
lines.push("# Docs completa em README.md");
|
|
1886
|
-
lines.push("# ====================================");
|
|
1887
|
-
const content = lines.join(`
|
|
1888
|
-
`);
|
|
1889
|
-
await Bun.write(`${projectPath}/.env`, content);
|
|
1890
|
-
const exampleLines = lines.map((line) => {
|
|
1891
|
-
if (line.includes("RESEND_API_KEY=") && !line.startsWith("#")) {
|
|
1892
|
-
return "RESEND_API_KEY=re_your_key_here";
|
|
1893
|
-
}
|
|
1894
|
-
if (line.includes("NEXT_PUBLIC_GA_ID=") && !line.startsWith("#")) {
|
|
1895
|
-
return "NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX";
|
|
1896
|
-
}
|
|
1897
|
-
return line;
|
|
1898
|
-
});
|
|
1899
|
-
await Bun.write(`${projectPath}/.env.example`, exampleLines.join(`
|
|
1900
|
-
`));
|
|
1901
|
-
}
|
|
1902
1636
|
// src/commands/create.ts
|
|
1637
|
+
var TEMPLATES = {
|
|
1638
|
+
landing: "nimbuslab/create-next-landing",
|
|
1639
|
+
app: "nimbuslab/create-next-app",
|
|
1640
|
+
turborepo: "nimbuslab/create-turborepo"
|
|
1641
|
+
};
|
|
1903
1642
|
var AI_CONFIGS = {
|
|
1904
1643
|
claude: {
|
|
1905
1644
|
filename: "CLAUDE.md",
|
|
@@ -2020,42 +1759,14 @@ async function checkGitHubCli() {
|
|
|
2020
1759
|
return { installed: false, authenticated: false, username: null, orgs: [] };
|
|
2021
1760
|
}
|
|
2022
1761
|
}
|
|
2023
|
-
var PRIVATE_TEMPLATES = {
|
|
2024
|
-
fast: "nimbuslab-templates/fast-template",
|
|
2025
|
-
"fast+": "nimbuslab-templates/fastplus-template",
|
|
2026
|
-
"fast+-monorepo": "nimbuslab-templates/fastplus-monorepo-template",
|
|
2027
|
-
"nimbus-core": "nimbuslab/nimbus-core"
|
|
2028
|
-
};
|
|
2029
|
-
var PUBLIC_TEMPLATES = {
|
|
2030
|
-
landing: "nimbuslab/create-next-landing",
|
|
2031
|
-
app: "nimbuslab/create-next-app",
|
|
2032
|
-
turborepo: "nimbuslab/create-turborepo"
|
|
2033
|
-
};
|
|
2034
|
-
var TEMPLATES = { ...PRIVATE_TEMPLATES, ...PUBLIC_TEMPLATES };
|
|
2035
|
-
var NIMBUSLAB_DOMAINS = ["@nimbuslab.com.br", "@nimbuslab.net.br"];
|
|
2036
|
-
async function isNimbuslabMember() {
|
|
2037
|
-
try {
|
|
2038
|
-
const user = (await $2`git config user.name`.text()).trim();
|
|
2039
|
-
const email = (await $2`git config user.email`.text()).trim();
|
|
2040
|
-
const isMember = NIMBUSLAB_DOMAINS.some((domain) => email.endsWith(domain));
|
|
2041
|
-
return { isMember, user, email };
|
|
2042
|
-
} catch {
|
|
2043
|
-
return { isMember: false, user: null, email: null };
|
|
2044
|
-
}
|
|
2045
|
-
}
|
|
2046
1762
|
function parseFlags(args) {
|
|
2047
1763
|
const flags = {
|
|
2048
1764
|
yes: false,
|
|
2049
1765
|
landing: false,
|
|
2050
1766
|
app: false,
|
|
2051
1767
|
turborepo: false,
|
|
2052
|
-
fast: false,
|
|
2053
|
-
fastPlus: false,
|
|
2054
|
-
fastTurborepo: false,
|
|
2055
|
-
core: false,
|
|
2056
1768
|
noGit: false,
|
|
2057
1769
|
noInstall: false,
|
|
2058
|
-
railway: false,
|
|
2059
1770
|
template: null
|
|
2060
1771
|
};
|
|
2061
1772
|
let projectName;
|
|
@@ -2070,20 +1781,10 @@ function parseFlags(args) {
|
|
|
2070
1781
|
flags.app = true;
|
|
2071
1782
|
} else if (arg === "--turborepo") {
|
|
2072
1783
|
flags.turborepo = true;
|
|
2073
|
-
} else if (arg === "--fast") {
|
|
2074
|
-
flags.fast = true;
|
|
2075
|
-
} else if (arg === "--fast-plus") {
|
|
2076
|
-
flags.fastPlus = true;
|
|
2077
|
-
} else if (arg === "--fast-turborepo") {
|
|
2078
|
-
flags.fastTurborepo = true;
|
|
2079
|
-
} else if (arg === "--core") {
|
|
2080
|
-
flags.core = true;
|
|
2081
1784
|
} else if (arg === "--no-git") {
|
|
2082
1785
|
flags.noGit = true;
|
|
2083
1786
|
} else if (arg === "--no-install") {
|
|
2084
1787
|
flags.noInstall = true;
|
|
2085
|
-
} else if (arg === "--railway") {
|
|
2086
|
-
flags.railway = true;
|
|
2087
1788
|
} else if (arg === "--template") {
|
|
2088
1789
|
i++;
|
|
2089
1790
|
flags.template = args[i] ?? null;
|
|
@@ -2094,320 +1795,56 @@ function parseFlags(args) {
|
|
|
2094
1795
|
}
|
|
2095
1796
|
return { flags, projectName };
|
|
2096
1797
|
}
|
|
2097
|
-
async function ensureRailwayCli() {
|
|
2098
|
-
const checkCmd = process.platform === "win32" ? "where" : "which";
|
|
2099
|
-
const hasRailway = await $2`${checkCmd} railway`.quiet().then(() => true).catch(() => false);
|
|
2100
|
-
if (hasRailway)
|
|
2101
|
-
return true;
|
|
2102
|
-
console.log(import_picocolors4.default.yellow("Railway CLI not found. Installing..."));
|
|
2103
|
-
console.log();
|
|
2104
|
-
try {
|
|
2105
|
-
if (process.platform === "win32") {
|
|
2106
|
-
await $2`powershell -c "iwr https://railway.app/install.ps1 -useb | iex"`.quiet();
|
|
2107
|
-
} else {
|
|
2108
|
-
await $2`curl -fsSL https://railway.app/install.sh | sh`.quiet();
|
|
2109
|
-
}
|
|
2110
|
-
console.log(import_picocolors4.default.green("Railway CLI installed successfully!"));
|
|
2111
|
-
return true;
|
|
2112
|
-
} catch (error) {
|
|
2113
|
-
console.log(import_picocolors4.default.red("Error installing Railway CLI."));
|
|
2114
|
-
console.log(import_picocolors4.default.dim("Install manually: https://docs.railway.app/guides/cli"));
|
|
2115
|
-
return false;
|
|
2116
|
-
}
|
|
2117
|
-
}
|
|
2118
|
-
async function listRailwayProjects() {
|
|
2119
|
-
try {
|
|
2120
|
-
const result = await $2`railway list`.text();
|
|
2121
|
-
const lines = result.trim().split(`
|
|
2122
|
-
`).filter((l2) => l2.trim());
|
|
2123
|
-
return lines.slice(1).map((l2) => l2.trim());
|
|
2124
|
-
} catch {
|
|
2125
|
-
return [];
|
|
2126
|
-
}
|
|
2127
|
-
}
|
|
2128
|
-
async function isRailwayAuthenticated() {
|
|
2129
|
-
try {
|
|
2130
|
-
await $2`railway whoami`.quiet();
|
|
2131
|
-
return true;
|
|
2132
|
-
} catch {
|
|
2133
|
-
return false;
|
|
2134
|
-
}
|
|
2135
|
-
}
|
|
2136
|
-
async function create(args) {
|
|
2137
|
-
const checkCmd = process.platform === "win32" ? "where" : "which";
|
|
2138
|
-
const hasBun = await $2`${checkCmd} bun`.quiet().then(() => true).catch(() => false);
|
|
2139
|
-
const hasGit = await $2`${checkCmd} git`.quiet().then(() => true).catch(() => false);
|
|
2140
|
-
const hasGh = await $2`${checkCmd} gh`.quiet().then(() => true).catch(() => false);
|
|
2141
|
-
if (!hasBun) {
|
|
2142
|
-
console.log(import_picocolors4.default.red("Error: Bun not found."));
|
|
2143
|
-
console.log(import_picocolors4.default.dim("Install from: https://bun.sh"));
|
|
2144
|
-
console.log();
|
|
2145
|
-
if (process.platform === "win32") {
|
|
2146
|
-
console.log(import_picocolors4.default.cyan('powershell -c "irm bun.sh/install.ps1 | iex"'));
|
|
2147
|
-
} else {
|
|
2148
|
-
console.log(import_picocolors4.default.cyan("curl -fsSL https://bun.sh/install | bash"));
|
|
2149
|
-
}
|
|
2150
|
-
console.log();
|
|
2151
|
-
process.exit(1);
|
|
2152
|
-
}
|
|
2153
|
-
if (!hasGit) {
|
|
2154
|
-
console.log(import_picocolors4.default.red("Error: Git not found."));
|
|
2155
|
-
console.log(import_picocolors4.default.dim("Install git to continue."));
|
|
2156
|
-
process.exit(1);
|
|
2157
|
-
}
|
|
2158
|
-
if (!hasGh) {
|
|
2159
|
-
console.log(import_picocolors4.default.dim(" GitHub CLI not found (repo creation will be skipped)"));
|
|
2160
|
-
console.log(import_picocolors4.default.dim(" Install from: https://cli.github.com"));
|
|
2161
|
-
console.log();
|
|
2162
|
-
}
|
|
2163
|
-
const hasRailway = await ensureRailwayCli();
|
|
2164
|
-
if (hasRailway) {
|
|
2165
|
-
const railwayAuth = await isRailwayAuthenticated();
|
|
2166
|
-
if (!railwayAuth) {
|
|
2167
|
-
console.log(import_picocolors4.default.yellow("Railway CLI not authenticated."));
|
|
2168
|
-
console.log(import_picocolors4.default.dim("Run: railway login"));
|
|
2169
|
-
console.log();
|
|
2170
|
-
}
|
|
2171
|
-
}
|
|
2172
|
-
const { flags, projectName } = parseFlags(args);
|
|
2173
|
-
Ie(import_picocolors4.default.bgCyan(import_picocolors4.default.black(" New nimbuslab Project ")));
|
|
2174
|
-
let config;
|
|
2175
|
-
const hasTypeFlag = flags.landing || flags.app || flags.turborepo || flags.fast || flags.fastPlus || flags.fastTurborepo || flags.core;
|
|
2176
|
-
const typeFromFlag = flags.landing ? "landing" : flags.app ? "app" : flags.turborepo ? "turborepo" : flags.fastTurborepo ? "fast+" : flags.fastPlus ? "fast+" : flags.fast ? "fast" : flags.core ? "nimbus-core" : null;
|
|
2177
|
-
const monorepoFromFlag = flags.fastTurborepo;
|
|
2178
|
-
if ((flags.yes || hasTypeFlag) && projectName) {
|
|
2179
|
-
const defaultType = flags.landing || flags.app || flags.turborepo ? "landing" : "fast";
|
|
2180
|
-
config = {
|
|
2181
|
-
name: projectName,
|
|
2182
|
-
type: typeFromFlag || defaultType,
|
|
2183
|
-
monorepo: monorepoFromFlag,
|
|
2184
|
-
git: !flags.noGit,
|
|
2185
|
-
install: !flags.noInstall,
|
|
2186
|
-
github: false,
|
|
2187
|
-
githubOrg: null,
|
|
2188
|
-
githubDescription: "",
|
|
2189
|
-
theme: "dark",
|
|
2190
|
-
aiAssistant: null,
|
|
2191
|
-
contractNumber: "",
|
|
2192
|
-
resendApiKey: "",
|
|
2193
|
-
resendFromEmail: "",
|
|
2194
|
-
contactEmail: "",
|
|
2195
|
-
railwayProject: "",
|
|
2196
|
-
railwayToken: "",
|
|
2197
|
-
stagingUrl: "",
|
|
2198
|
-
productionUrl: "",
|
|
2199
|
-
customTemplate: flags.template
|
|
2200
|
-
};
|
|
2201
|
-
const typeLabel = flags.turborepo ? "fast+ (monorepo)" : config.type;
|
|
2202
|
-
console.log(import_picocolors4.default.dim(` Project: ${projectName}`));
|
|
2203
|
-
console.log(import_picocolors4.default.dim(` Type: ${typeLabel}`));
|
|
2204
|
-
console.log(import_picocolors4.default.dim(` Git: ${config.git ? "yes" : "no"}`));
|
|
2205
|
-
console.log(import_picocolors4.default.dim(` Install: ${config.install ? "yes" : "no"}`));
|
|
2206
|
-
if (flags.railway)
|
|
2207
|
-
console.log(import_picocolors4.default.dim(` Railway: configurar`));
|
|
2208
|
-
if (flags.template)
|
|
2209
|
-
console.log(import_picocolors4.default.dim(` Template: ${flags.template}`));
|
|
2210
|
-
console.log();
|
|
2211
|
-
if (flags.railway) {
|
|
2212
|
-
const railwayAuthenticated = await isRailwayAuthenticated();
|
|
2213
|
-
if (railwayAuthenticated) {
|
|
2214
|
-
if (config.type === "fast") {
|
|
2215
|
-
const projects = await listRailwayProjects();
|
|
2216
|
-
const fastProject = projects.find((p2) => p2.toLowerCase().includes("fast by nimbuslab"));
|
|
2217
|
-
if (fastProject) {
|
|
2218
|
-
config.railwayProject = fastProject;
|
|
2219
|
-
console.log(import_picocolors4.default.green(` Railway: ${fastProject}`));
|
|
2220
|
-
}
|
|
2221
|
-
} else {
|
|
2222
|
-
console.log(import_picocolors4.default.dim(` Creating project Railway: ${projectName}...`));
|
|
2223
|
-
try {
|
|
2224
|
-
const result = await $2`echo "" | railway init -n ${projectName} -w nimbuslab --json`.text();
|
|
2225
|
-
const newProject = JSON.parse(result);
|
|
2226
|
-
config.railwayProject = newProject.name || projectName;
|
|
2227
|
-
console.log(import_picocolors4.default.green(` Railway: ${config.railwayProject} criado`));
|
|
2228
|
-
} catch {
|
|
2229
|
-
console.log(import_picocolors4.default.yellow(` Railway: erro ao criar projeto`));
|
|
2230
|
-
}
|
|
2231
|
-
}
|
|
2232
|
-
} else {
|
|
2233
|
-
console.log(import_picocolors4.default.yellow(` Railway: not authenticated (railway login)`));
|
|
2234
|
-
}
|
|
2235
|
-
console.log();
|
|
2236
|
-
}
|
|
2237
|
-
} else {
|
|
2238
|
-
config = await promptConfig(projectName, flags);
|
|
2239
|
-
}
|
|
2240
|
-
if (pD(config)) {
|
|
2241
|
-
xe("Operation cancelled");
|
|
2242
|
-
process.exit(0);
|
|
2243
|
-
}
|
|
2244
|
-
await createProject(config);
|
|
2245
|
-
const finalConfig = config;
|
|
2246
|
-
const isPublicTemplate = ["landing", "app", "turborepo"].includes(finalConfig.type);
|
|
2247
|
-
if (isPublicTemplate) {
|
|
2248
|
-
const s = Y2();
|
|
2249
|
-
s.start("Configura\xE7\xE3o de servi\xE7os...");
|
|
2250
|
-
const setupResult = await interactiveSetup(finalConfig.type);
|
|
2251
|
-
s.stop("Configura\xE7\xE3o conclu\xEDda");
|
|
2252
|
-
s.start("Gerando documenta\xE7\xE3o AI-friendly...");
|
|
2253
|
-
try {
|
|
2254
|
-
const generatorConfig = {
|
|
2255
|
-
name: finalConfig.name,
|
|
2256
|
-
type: finalConfig.type,
|
|
2257
|
-
description: finalConfig.githubDescription || `${finalConfig.type} criado com nimbus-cli`,
|
|
2258
|
-
stack: {
|
|
2259
|
-
framework: "Next.js 16 (App Router)",
|
|
2260
|
-
styling: "Tailwind CSS 4",
|
|
2261
|
-
components: "shadcn/ui (default)",
|
|
2262
|
-
forms: setupResult.features.contactForm ? "React Hook Form + Zod" : undefined,
|
|
2263
|
-
email: setupResult.features.contactForm ? "Resend" : undefined,
|
|
2264
|
-
auth: finalConfig.type === "app" ? "Better Auth" : undefined
|
|
2265
|
-
},
|
|
2266
|
-
features: {
|
|
2267
|
-
contactForm: setupResult.features.contactForm,
|
|
2268
|
-
newsletter: setupResult.features.newsletter,
|
|
2269
|
-
analytics: setupResult.features.analytics,
|
|
2270
|
-
auth: finalConfig.type === "app"
|
|
2271
|
-
}
|
|
2272
|
-
};
|
|
2273
|
-
await generateAIFriendlyDocs(finalConfig.name, generatorConfig);
|
|
2274
|
-
s.stop("Documenta\xE7\xE3o AI-friendly gerada");
|
|
2275
|
-
} catch (error) {
|
|
2276
|
-
s.stop("Erro ao gerar documenta\xE7\xE3o AI-friendly");
|
|
2277
|
-
console.log(import_picocolors4.default.dim(" Voc\xEA pode gerar manualmente depois"));
|
|
2278
|
-
}
|
|
2279
|
-
if (!setupResult.skipSetup && (setupResult.apiKeys.resend || setupResult.apiKeys.ga)) {
|
|
2280
|
-
s.start("Gerando arquivos .env...");
|
|
2281
|
-
try {
|
|
2282
|
-
await generateEnvFile(finalConfig.name, setupResult.apiKeys, setupResult.features);
|
|
2283
|
-
s.stop("Arquivos .env gerados (.env e .env.example)");
|
|
2284
|
-
} catch (error) {
|
|
2285
|
-
s.stop("Erro ao gerar .env");
|
|
2286
|
-
console.log(import_picocolors4.default.dim(" Voc\xEA pode criar manualmente depois"));
|
|
2287
|
-
}
|
|
2288
|
-
}
|
|
2289
|
-
}
|
|
2290
|
-
Se(import_picocolors4.default.green("Project created successfully!"));
|
|
2291
|
-
showNextSteps(config);
|
|
2292
|
-
}
|
|
2293
1798
|
async function promptConfig(initialName, flags) {
|
|
2294
|
-
const { isMember, user } = await isNimbuslabMember();
|
|
2295
|
-
const greeting = user ? `Hello, ${user}!` : "Hello!";
|
|
2296
|
-
console.log(import_picocolors4.default.dim(` ${greeting}`));
|
|
2297
|
-
console.log();
|
|
2298
1799
|
const name = await he({
|
|
2299
1800
|
message: "Project name:",
|
|
2300
|
-
placeholder: "
|
|
2301
|
-
initialValue: initialName,
|
|
1801
|
+
placeholder: initialName || "my-project",
|
|
1802
|
+
initialValue: initialName || "",
|
|
2302
1803
|
validate: (value) => {
|
|
2303
1804
|
if (!value)
|
|
2304
|
-
return "
|
|
1805
|
+
return "Project name is required";
|
|
2305
1806
|
if (!/^[a-z0-9-]+$/.test(value)) {
|
|
2306
|
-
return "Use
|
|
1807
|
+
return "Use lowercase letters, numbers, and hyphens only";
|
|
2307
1808
|
}
|
|
2308
|
-
return;
|
|
2309
1809
|
}
|
|
2310
1810
|
});
|
|
2311
1811
|
if (pD(name))
|
|
2312
1812
|
return name;
|
|
2313
|
-
const publicOptions = [
|
|
2314
|
-
{
|
|
2315
|
-
value: "landing",
|
|
2316
|
-
label: "Landing Page",
|
|
2317
|
-
hint: "Next.js 16 + Tailwind 4 + shadcn"
|
|
2318
|
-
},
|
|
2319
|
-
{
|
|
2320
|
-
value: "app",
|
|
2321
|
-
label: "Web App",
|
|
2322
|
-
hint: "Landing + Better Auth + Drizzle"
|
|
2323
|
-
},
|
|
2324
|
-
{
|
|
2325
|
-
value: "turborepo",
|
|
2326
|
-
label: "Monorepo",
|
|
2327
|
-
hint: "Turborepo + apps/packages"
|
|
2328
|
-
}
|
|
2329
|
-
];
|
|
2330
|
-
const privateOptions = isMember ? [
|
|
2331
|
-
{
|
|
2332
|
-
value: "fast",
|
|
2333
|
-
label: "fast",
|
|
2334
|
-
hint: "Landing page fast methodology"
|
|
2335
|
-
},
|
|
2336
|
-
{
|
|
2337
|
-
value: "fast+",
|
|
2338
|
-
label: "fast+",
|
|
2339
|
-
hint: "Complete SaaS"
|
|
2340
|
-
},
|
|
2341
|
-
{
|
|
2342
|
-
value: "nimbus-core",
|
|
2343
|
-
label: "nimbus-core",
|
|
2344
|
-
hint: "External projects (stealth mode)"
|
|
2345
|
-
}
|
|
2346
|
-
] : [];
|
|
2347
1813
|
const type = await ve({
|
|
2348
|
-
message: "
|
|
2349
|
-
options: [
|
|
1814
|
+
message: "Choose a template:",
|
|
1815
|
+
options: [
|
|
1816
|
+
{ value: "landing", label: "Landing Page", hint: "Next.js + Tailwind + shadcn/ui" },
|
|
1817
|
+
{ value: "app", label: "Web App", hint: "Landing + Auth + Database" },
|
|
1818
|
+
{ value: "turborepo", label: "Monorepo", hint: "Turborepo + apps/packages" }
|
|
1819
|
+
]
|
|
2350
1820
|
});
|
|
2351
1821
|
if (pD(type))
|
|
2352
1822
|
return type;
|
|
2353
|
-
const
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
name,
|
|
2379
|
-
type: "nimbus-core",
|
|
2380
|
-
monorepo: false,
|
|
2381
|
-
git: true,
|
|
2382
|
-
install: false,
|
|
2383
|
-
github: repoOption === "github",
|
|
2384
|
-
githubOrg: "nimbuslab",
|
|
2385
|
-
githubDescription: `nimbus-core for ${name} - external project`,
|
|
2386
|
-
theme: "dark",
|
|
2387
|
-
aiAssistant: null,
|
|
2388
|
-
contractNumber: "",
|
|
2389
|
-
resendApiKey: "",
|
|
2390
|
-
resendFromEmail: "",
|
|
2391
|
-
contactEmail: "",
|
|
2392
|
-
railwayProject: "",
|
|
2393
|
-
railwayToken: "",
|
|
2394
|
-
stagingUrl: "",
|
|
2395
|
-
productionUrl: "",
|
|
2396
|
-
customTemplate: null,
|
|
2397
|
-
clientRepoUrl: clientRepo || null
|
|
2398
|
-
};
|
|
2399
|
-
}
|
|
2400
|
-
let monorepo = false;
|
|
2401
|
-
if (type === "fast+") {
|
|
2402
|
-
const useMonorepo = await ye({
|
|
2403
|
-
message: "Use monorepo (Turborepo)?",
|
|
2404
|
-
initialValue: false
|
|
2405
|
-
});
|
|
2406
|
-
if (pD(useMonorepo))
|
|
2407
|
-
return useMonorepo;
|
|
2408
|
-
monorepo = useMonorepo;
|
|
2409
|
-
}
|
|
2410
|
-
const git = await ye({
|
|
1823
|
+
const theme = await ve({
|
|
1824
|
+
message: "Default theme:",
|
|
1825
|
+
options: [
|
|
1826
|
+
{ value: "dark", label: "Dark", hint: "recommended" },
|
|
1827
|
+
{ value: "light", label: "Light" },
|
|
1828
|
+
{ value: "system", label: "System" }
|
|
1829
|
+
]
|
|
1830
|
+
});
|
|
1831
|
+
if (pD(theme))
|
|
1832
|
+
return theme;
|
|
1833
|
+
const aiAssistant = await ve({
|
|
1834
|
+
message: "AI Assistant configuration:",
|
|
1835
|
+
options: [
|
|
1836
|
+
{ value: "claude", label: "Claude (Anthropic)", hint: "recommended" },
|
|
1837
|
+
{ value: "cursor", label: "Cursor" },
|
|
1838
|
+
{ value: "copilot", label: "GitHub Copilot" },
|
|
1839
|
+
{ value: "gemini", label: "Google Gemini" },
|
|
1840
|
+
{ value: "windsurf", label: "Windsurf" },
|
|
1841
|
+
{ value: "none", label: "None", hint: "skip" }
|
|
1842
|
+
],
|
|
1843
|
+
initialValue: "claude"
|
|
1844
|
+
});
|
|
1845
|
+
if (pD(aiAssistant))
|
|
1846
|
+
return aiAssistant;
|
|
1847
|
+
const git = flags.noGit ? false : await ye({
|
|
2411
1848
|
message: "Initialize Git repository?",
|
|
2412
1849
|
initialValue: true
|
|
2413
1850
|
});
|
|
@@ -2415,260 +1852,47 @@ async function promptConfig(initialName, flags) {
|
|
|
2415
1852
|
return git;
|
|
2416
1853
|
let github = false;
|
|
2417
1854
|
let githubOrg = null;
|
|
2418
|
-
let
|
|
1855
|
+
let githubVisibility = "public";
|
|
2419
1856
|
if (git) {
|
|
2420
|
-
const
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
return createGithub;
|
|
2426
|
-
github = createGithub;
|
|
2427
|
-
if (github) {
|
|
2428
|
-
const org = await ve({
|
|
2429
|
-
message: "GitHub organization:",
|
|
2430
|
-
options: [
|
|
2431
|
-
{ value: "nimbuslab", label: "nimbuslab", hint: "Main org" },
|
|
2432
|
-
{ value: "fast-by-nimbuslab", label: "fast-by-nimbuslab", hint: "Client projects" },
|
|
2433
|
-
{ value: "nimbuslab-templates", label: "nimbuslab-templates", hint: "Templates" },
|
|
2434
|
-
{ value: null, label: "Pessoal", hint: "Personal" }
|
|
2435
|
-
]
|
|
1857
|
+
const ghCheck = await checkGitHubCli();
|
|
1858
|
+
if (ghCheck.installed && ghCheck.authenticated) {
|
|
1859
|
+
github = await ye({
|
|
1860
|
+
message: "Create GitHub repository?",
|
|
1861
|
+
initialValue: true
|
|
2436
1862
|
});
|
|
2437
|
-
if (pD(
|
|
2438
|
-
return
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
initialValue: type === "fast" ? "Landing page fast by nimbuslab" : "SaaS fast+ by nimbuslab"
|
|
2444
|
-
});
|
|
2445
|
-
if (pD(description))
|
|
2446
|
-
return description;
|
|
2447
|
-
githubDescription = description;
|
|
2448
|
-
}
|
|
2449
|
-
}
|
|
2450
|
-
let contractNumber = "";
|
|
2451
|
-
if (type === "fast") {
|
|
2452
|
-
const contract = await he({
|
|
2453
|
-
message: "Contract number (ex: 001):",
|
|
2454
|
-
placeholder: "001",
|
|
2455
|
-
validate: (v2) => v2 ? undefined : "Contract number is required for fast"
|
|
2456
|
-
});
|
|
2457
|
-
if (pD(contract))
|
|
2458
|
-
return contract;
|
|
2459
|
-
contractNumber = contract;
|
|
2460
|
-
}
|
|
2461
|
-
if (isPublicTemplate) {
|
|
2462
|
-
const theme = await ve({
|
|
2463
|
-
message: "Default theme:",
|
|
2464
|
-
options: [
|
|
2465
|
-
{ value: "dark", label: "Dark", hint: "recommended" },
|
|
2466
|
-
{ value: "light", label: "Light" },
|
|
2467
|
-
{ value: "system", label: "System", hint: "follows OS preference" }
|
|
2468
|
-
]
|
|
2469
|
-
});
|
|
2470
|
-
if (pD(theme))
|
|
2471
|
-
return theme;
|
|
2472
|
-
const aiAssistant = await ve({
|
|
2473
|
-
message: "Which AI assistant do you use?",
|
|
2474
|
-
options: [
|
|
2475
|
-
{ value: "claude", label: "Claude Code", hint: "Anthropic" },
|
|
2476
|
-
{ value: "cursor", label: "Cursor", hint: "AI-first editor" },
|
|
2477
|
-
{ value: "gemini", label: "Gemini CLI", hint: "Google" },
|
|
2478
|
-
{ value: "copilot", label: "GitHub Copilot" },
|
|
2479
|
-
{ value: "windsurf", label: "Windsurf", hint: "Codeium" },
|
|
2480
|
-
{ value: "none", label: "None", hint: "skip AI config" }
|
|
2481
|
-
]
|
|
2482
|
-
});
|
|
2483
|
-
if (pD(aiAssistant))
|
|
2484
|
-
return aiAssistant;
|
|
2485
|
-
let publicGithub = false;
|
|
2486
|
-
let publicGithubOrg = null;
|
|
2487
|
-
if (git) {
|
|
2488
|
-
const gh = await checkGitHubCli();
|
|
2489
|
-
if (gh.installed && gh.authenticated) {
|
|
2490
|
-
const createRepo = await ye({
|
|
2491
|
-
message: "Create GitHub repository?",
|
|
2492
|
-
initialValue: false
|
|
2493
|
-
});
|
|
2494
|
-
if (pD(createRepo))
|
|
2495
|
-
return createRepo;
|
|
2496
|
-
publicGithub = createRepo;
|
|
2497
|
-
if (publicGithub) {
|
|
2498
|
-
const repoOptions = [
|
|
2499
|
-
{ value: gh.username, label: gh.username, hint: "personal account" },
|
|
2500
|
-
...gh.orgs.map((org) => ({ value: org, label: org }))
|
|
2501
|
-
];
|
|
2502
|
-
const repoOwner = await ve({
|
|
2503
|
-
message: "Where to create the repository?",
|
|
2504
|
-
options: repoOptions
|
|
2505
|
-
});
|
|
2506
|
-
if (pD(repoOwner))
|
|
2507
|
-
return repoOwner;
|
|
2508
|
-
publicGithubOrg = repoOwner;
|
|
2509
|
-
const repoVisibility = await ve({
|
|
2510
|
-
message: "Repository visibility:",
|
|
2511
|
-
options: [
|
|
2512
|
-
{ value: "private", label: "Private", hint: "recommended" },
|
|
2513
|
-
{ value: "public", label: "Public" }
|
|
2514
|
-
]
|
|
2515
|
-
});
|
|
2516
|
-
if (pD(repoVisibility))
|
|
2517
|
-
return repoVisibility;
|
|
2518
|
-
githubDescription = repoVisibility;
|
|
2519
|
-
}
|
|
2520
|
-
}
|
|
2521
|
-
}
|
|
2522
|
-
const install2 = await ye({
|
|
2523
|
-
message: "Install dependencies?",
|
|
2524
|
-
initialValue: true
|
|
2525
|
-
});
|
|
2526
|
-
if (pD(install2))
|
|
2527
|
-
return install2;
|
|
2528
|
-
return {
|
|
2529
|
-
name,
|
|
2530
|
-
type,
|
|
2531
|
-
monorepo: false,
|
|
2532
|
-
git,
|
|
2533
|
-
install: install2,
|
|
2534
|
-
github: publicGithub,
|
|
2535
|
-
githubOrg: publicGithubOrg,
|
|
2536
|
-
githubDescription,
|
|
2537
|
-
theme,
|
|
2538
|
-
aiAssistant: aiAssistant === "none" ? null : aiAssistant,
|
|
2539
|
-
contractNumber: "",
|
|
2540
|
-
resendApiKey: "",
|
|
2541
|
-
resendFromEmail: "",
|
|
2542
|
-
contactEmail: "",
|
|
2543
|
-
railwayProject: "",
|
|
2544
|
-
railwayToken: "",
|
|
2545
|
-
stagingUrl: "",
|
|
2546
|
-
productionUrl: "",
|
|
2547
|
-
customTemplate: flags?.template || null
|
|
2548
|
-
};
|
|
2549
|
-
}
|
|
2550
|
-
let resendApiKey = "";
|
|
2551
|
-
let resendFromEmail = "";
|
|
2552
|
-
let contactEmail = "";
|
|
2553
|
-
let railwayProject = "";
|
|
2554
|
-
let railwayToken = "";
|
|
2555
|
-
let stagingUrl = "";
|
|
2556
|
-
let productionUrl = "";
|
|
2557
|
-
const currentYear = new Date().getFullYear().toString().slice(-3);
|
|
2558
|
-
const defaultStagingUrl = type === "fast" ? `https://fast-${contractNumber}-${currentYear}.nimbuslab.net.br` : `https://${name}.nimbuslab.net.br`;
|
|
2559
|
-
const defaultFromEmail = "no-reply@nimbuslab.com.br";
|
|
2560
|
-
const defaultContactEmail = type === "fast" ? "fast@nimbuslab.com.br" : "suporte@nimbuslab.com.br";
|
|
2561
|
-
const infraOptions = await fe({
|
|
2562
|
-
message: "What do you want to configure now?",
|
|
2563
|
-
options: [
|
|
2564
|
-
{ value: "urls", label: "URLs", hint: "staging and production" },
|
|
2565
|
-
{ value: "resend", label: "Resend", hint: "form emails" },
|
|
2566
|
-
{ value: "railway", label: "Railway", hint: "deploy and hosting" }
|
|
2567
|
-
],
|
|
2568
|
-
required: false
|
|
2569
|
-
});
|
|
2570
|
-
if (pD(infraOptions))
|
|
2571
|
-
return infraOptions;
|
|
2572
|
-
const configItems = infraOptions;
|
|
2573
|
-
if (configItems.includes("urls")) {
|
|
2574
|
-
console.log();
|
|
2575
|
-
console.log(import_picocolors4.default.dim(" Project URLs"));
|
|
2576
|
-
const staging = await he({
|
|
2577
|
-
message: "Staging URL:",
|
|
2578
|
-
placeholder: defaultStagingUrl,
|
|
2579
|
-
initialValue: defaultStagingUrl
|
|
2580
|
-
});
|
|
2581
|
-
if (pD(staging))
|
|
2582
|
-
return staging;
|
|
2583
|
-
stagingUrl = staging;
|
|
2584
|
-
const production = await he({
|
|
2585
|
-
message: "Production URL:",
|
|
2586
|
-
placeholder: defaultStagingUrl.replace(".nimbuslab.net.br", ".com.br"),
|
|
2587
|
-
initialValue: ""
|
|
2588
|
-
});
|
|
2589
|
-
if (pD(production))
|
|
2590
|
-
return production;
|
|
2591
|
-
productionUrl = production;
|
|
2592
|
-
}
|
|
2593
|
-
if (configItems.includes("resend")) {
|
|
2594
|
-
console.log();
|
|
2595
|
-
console.log(import_picocolors4.default.dim(" Resend (Email)"));
|
|
2596
|
-
const resendKey = await he({
|
|
2597
|
-
message: "RESEND_API_KEY:",
|
|
2598
|
-
placeholder: "re_xxxxxxxxxxxx"
|
|
2599
|
-
});
|
|
2600
|
-
if (pD(resendKey))
|
|
2601
|
-
return resendKey;
|
|
2602
|
-
resendApiKey = resendKey;
|
|
2603
|
-
const fromEmail = await he({
|
|
2604
|
-
message: "From email:",
|
|
2605
|
-
placeholder: defaultFromEmail,
|
|
2606
|
-
initialValue: defaultFromEmail
|
|
2607
|
-
});
|
|
2608
|
-
if (pD(fromEmail))
|
|
2609
|
-
return fromEmail;
|
|
2610
|
-
resendFromEmail = fromEmail;
|
|
2611
|
-
const contact = await he({
|
|
2612
|
-
message: "Contact email (receives forms):",
|
|
2613
|
-
placeholder: defaultContactEmail,
|
|
2614
|
-
initialValue: defaultContactEmail
|
|
2615
|
-
});
|
|
2616
|
-
if (pD(contact))
|
|
2617
|
-
return contact;
|
|
2618
|
-
contactEmail = contact;
|
|
2619
|
-
}
|
|
2620
|
-
if (configItems.includes("railway")) {
|
|
2621
|
-
const railwayAuthenticated = await isRailwayAuthenticated();
|
|
2622
|
-
if (railwayAuthenticated) {
|
|
2623
|
-
console.log();
|
|
2624
|
-
console.log(import_picocolors4.default.dim(" Railway"));
|
|
2625
|
-
const projects = await listRailwayProjects();
|
|
2626
|
-
if (type === "fast") {
|
|
2627
|
-
const fastProject = projects.find((p2) => p2.toLowerCase().includes("fast by nimbuslab"));
|
|
2628
|
-
if (fastProject) {
|
|
2629
|
-
railwayProject = fastProject;
|
|
2630
|
-
console.log(import_picocolors4.default.green(` Project: ${fastProject} (automatico)`));
|
|
2631
|
-
} else {
|
|
2632
|
-
console.log(import_picocolors4.default.yellow(" Project 'Fast by nimbuslab' not found."));
|
|
2633
|
-
console.log(import_picocolors4.default.dim(" Configure manually in .env"));
|
|
2634
|
-
}
|
|
2635
|
-
} else {
|
|
2636
|
-
const projectOptions = [
|
|
2637
|
-
...projects.map((proj) => ({ value: proj, label: proj })),
|
|
2638
|
-
{ value: "__new__", label: "Create new project", hint: "via railway init" },
|
|
2639
|
-
{ value: "__skip__", label: "Skip", hint: "Configure later" }
|
|
1863
|
+
if (pD(github))
|
|
1864
|
+
return github;
|
|
1865
|
+
if (github) {
|
|
1866
|
+
const orgOptions = [
|
|
1867
|
+
{ value: ghCheck.username, label: `${ghCheck.username} (personal)`, hint: "your account" },
|
|
1868
|
+
...ghCheck.orgs.map((org) => ({ value: org, label: org, hint: "organization" }))
|
|
2640
1869
|
];
|
|
2641
|
-
|
|
2642
|
-
message: "
|
|
2643
|
-
options:
|
|
1870
|
+
githubOrg = await ve({
|
|
1871
|
+
message: "GitHub owner:",
|
|
1872
|
+
options: orgOptions,
|
|
1873
|
+
initialValue: ghCheck.username
|
|
2644
1874
|
});
|
|
2645
|
-
if (pD(
|
|
2646
|
-
return
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
console.log(import_picocolors4.default.yellow(" Error creating project via CLI."));
|
|
2658
|
-
console.log(import_picocolors4.default.dim(" Create manually at: https://railway.app/new"));
|
|
2659
|
-
}
|
|
2660
|
-
} else if (selectedProject !== "__skip__") {
|
|
2661
|
-
railwayProject = selectedProject;
|
|
2662
|
-
console.log(import_picocolors4.default.green(` Project selected: ${railwayProject}`));
|
|
2663
|
-
}
|
|
1875
|
+
if (pD(githubOrg))
|
|
1876
|
+
return githubOrg;
|
|
1877
|
+
githubVisibility = await ve({
|
|
1878
|
+
message: "Repository visibility:",
|
|
1879
|
+
options: [
|
|
1880
|
+
{ value: "public", label: "Public", hint: "anyone can see" },
|
|
1881
|
+
{ value: "private", label: "Private", hint: "you choose who can see" }
|
|
1882
|
+
],
|
|
1883
|
+
initialValue: "public"
|
|
1884
|
+
});
|
|
1885
|
+
if (pD(githubVisibility))
|
|
1886
|
+
return githubVisibility;
|
|
2664
1887
|
}
|
|
2665
|
-
} else {
|
|
2666
|
-
console.log();
|
|
2667
|
-
console.log(
|
|
2668
|
-
|
|
1888
|
+
} else if (!ghCheck.installed) {
|
|
1889
|
+
console.log(import_picocolors3.default.dim(" GitHub CLI not found (repository creation will be skipped)"));
|
|
1890
|
+
console.log(import_picocolors3.default.dim(" Install from: https://cli.github.com"));
|
|
1891
|
+
} else if (!ghCheck.authenticated) {
|
|
1892
|
+
console.log(import_picocolors3.default.yellow(" GitHub CLI not authenticated (run: gh auth login)"));
|
|
2669
1893
|
}
|
|
2670
1894
|
}
|
|
2671
|
-
const install = await ye({
|
|
1895
|
+
const install = flags.noInstall ? false : await ye({
|
|
2672
1896
|
message: "Install dependencies?",
|
|
2673
1897
|
initialValue: true
|
|
2674
1898
|
});
|
|
@@ -2677,323 +1901,174 @@ async function promptConfig(initialName, flags) {
|
|
|
2677
1901
|
return {
|
|
2678
1902
|
name,
|
|
2679
1903
|
type,
|
|
2680
|
-
monorepo,
|
|
2681
1904
|
git,
|
|
2682
1905
|
install,
|
|
2683
1906
|
github,
|
|
2684
1907
|
githubOrg,
|
|
2685
|
-
|
|
2686
|
-
theme
|
|
2687
|
-
aiAssistant: null,
|
|
2688
|
-
|
|
2689
|
-
resendApiKey,
|
|
2690
|
-
resendFromEmail,
|
|
2691
|
-
contactEmail,
|
|
2692
|
-
railwayProject,
|
|
2693
|
-
railwayToken,
|
|
2694
|
-
stagingUrl,
|
|
2695
|
-
productionUrl,
|
|
2696
|
-
customTemplate: flags?.template || null
|
|
1908
|
+
githubVisibility,
|
|
1909
|
+
theme,
|
|
1910
|
+
aiAssistant: aiAssistant === "none" ? null : aiAssistant,
|
|
1911
|
+
customTemplate: flags.template
|
|
2697
1912
|
};
|
|
2698
1913
|
}
|
|
2699
1914
|
async function createProject(config) {
|
|
2700
1915
|
const s = Y2();
|
|
2701
|
-
|
|
2702
|
-
let templateLabel;
|
|
2703
|
-
if (config.customTemplate) {
|
|
2704
|
-
templateRepo = config.customTemplate;
|
|
2705
|
-
templateLabel = `customizado (${config.customTemplate})`;
|
|
2706
|
-
} else {
|
|
2707
|
-
const templateKey = config.type === "fast+" && config.monorepo ? "fast+-monorepo" : config.type;
|
|
2708
|
-
templateRepo = TEMPLATES[templateKey];
|
|
2709
|
-
templateLabel = config.monorepo ? `${config.type} (monorepo)` : config.type;
|
|
2710
|
-
}
|
|
2711
|
-
const isPublicTemplate = ["landing", "app", "turborepo"].includes(config.type);
|
|
2712
|
-
s.start(`Cloning template ${templateLabel}...`);
|
|
1916
|
+
const projectPath = join2(process.cwd(), config.name);
|
|
2713
1917
|
try {
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
await
|
|
2721
|
-
s.stop(`Template cloned`);
|
|
1918
|
+
await rm(projectPath, { recursive: true, force: true });
|
|
1919
|
+
} catch {}
|
|
1920
|
+
const templateRepo = config.customTemplate || TEMPLATES[config.type];
|
|
1921
|
+
const templateUrl = templateRepo.startsWith("http") ? templateRepo : `https://github.com/${templateRepo}`;
|
|
1922
|
+
s.start(`Cloning template: ${config.type}`);
|
|
1923
|
+
try {
|
|
1924
|
+
await $2`git clone --depth 1 ${templateUrl} ${config.name}`.quiet();
|
|
1925
|
+
s.stop(`Template cloned: ${config.type}`);
|
|
2722
1926
|
} catch (error) {
|
|
2723
1927
|
s.stop("Error cloning template");
|
|
2724
|
-
throw new Error(`Failed to clone template ${
|
|
2725
|
-
}
|
|
2726
|
-
if (config.type === "nimbus-core" && config.clientRepoUrl) {
|
|
2727
|
-
const clientRepoUrl = config.clientRepoUrl;
|
|
2728
|
-
s.start(`Cloning client repo in workspace...`);
|
|
2729
|
-
try {
|
|
2730
|
-
let projectName = "client-project";
|
|
2731
|
-
if (clientRepoUrl.includes("visualstudio.com") || clientRepoUrl.includes("dev.azure.com")) {
|
|
2732
|
-
const parts = clientRepoUrl.split("/");
|
|
2733
|
-
projectName = parts[parts.length - 1] || "client-project";
|
|
2734
|
-
} else {
|
|
2735
|
-
projectName = clientRepoUrl.split("/").pop()?.replace(".git", "") || "client-project";
|
|
2736
|
-
}
|
|
2737
|
-
await $2`git clone ${clientRepoUrl} ${config.name}/workspace/${projectName}`.quiet();
|
|
2738
|
-
s.stop(`Client repo cloned: workspace/${projectName}`);
|
|
2739
|
-
} catch (error) {
|
|
2740
|
-
s.stop("Error cloning client repo");
|
|
2741
|
-
console.log(import_picocolors4.default.dim(" You can clone manually: cd workspace && git clone <url>"));
|
|
2742
|
-
}
|
|
1928
|
+
throw new Error(`Failed to clone template from ${templateUrl}`);
|
|
2743
1929
|
}
|
|
2744
|
-
|
|
2745
|
-
|
|
1930
|
+
try {
|
|
1931
|
+
await rm(join2(projectPath, ".git"), { recursive: true, force: true });
|
|
1932
|
+
} catch {}
|
|
1933
|
+
if (config.install) {
|
|
1934
|
+
s.start("Installing dependencies...");
|
|
2746
1935
|
try {
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
pkg.name = config.name;
|
|
2750
|
-
await Bun.write(pkgPath, JSON.stringify(pkg, null, 2));
|
|
2751
|
-
s.stop("Project configured");
|
|
1936
|
+
await $2`bun install`.cwd(projectPath).quiet();
|
|
1937
|
+
s.stop("Dependencies installed");
|
|
2752
1938
|
} catch (error) {
|
|
2753
|
-
s.stop("Error
|
|
2754
|
-
|
|
2755
|
-
}
|
|
2756
|
-
if (isPublicTemplate && config.theme) {
|
|
2757
|
-
s.start(`Setting theme to ${config.theme}...`);
|
|
2758
|
-
try {
|
|
2759
|
-
const layoutPath = `${config.name}/src/app/layout.tsx`;
|
|
2760
|
-
let layout = await Bun.file(layoutPath).text();
|
|
2761
|
-
layout = layout.replace(/defaultTheme="(dark|light|system)"/, `defaultTheme="${config.theme}"`);
|
|
2762
|
-
await Bun.write(layoutPath, layout);
|
|
2763
|
-
s.stop(`Theme set to ${config.theme}`);
|
|
2764
|
-
} catch {
|
|
2765
|
-
s.stop("Theme config skipped");
|
|
2766
|
-
}
|
|
2767
|
-
}
|
|
2768
|
-
if (isPublicTemplate && config.aiAssistant) {
|
|
2769
|
-
const aiConfig = AI_CONFIGS[config.aiAssistant];
|
|
2770
|
-
if (aiConfig) {
|
|
2771
|
-
s.start(`Generating ${config.aiAssistant} config...`);
|
|
2772
|
-
try {
|
|
2773
|
-
const content = aiConfig.content(config.type);
|
|
2774
|
-
const filePath = `${config.name}/${aiConfig.filename}`;
|
|
2775
|
-
if (aiConfig.filename.includes("/")) {
|
|
2776
|
-
const dir = aiConfig.filename.split("/").slice(0, -1).join("/");
|
|
2777
|
-
await mkdir(`${config.name}/${dir}`, { recursive: true });
|
|
2778
|
-
}
|
|
2779
|
-
await Bun.write(filePath, content);
|
|
2780
|
-
s.stop(`${aiConfig.filename} created`);
|
|
2781
|
-
} catch {
|
|
2782
|
-
s.stop("AI config skipped");
|
|
2783
|
-
}
|
|
1939
|
+
s.stop("Error installing dependencies");
|
|
1940
|
+
console.log(import_picocolors3.default.yellow(" You can install manually with: bun install"));
|
|
2784
1941
|
}
|
|
2785
1942
|
}
|
|
2786
|
-
if (config.type === "fast+") {
|
|
2787
|
-
s.start("Configurando fast+ (SaaS)...");
|
|
2788
|
-
s.stop("Configuracao fast+ preparada");
|
|
2789
|
-
}
|
|
2790
1943
|
if (config.git) {
|
|
2791
1944
|
s.start("Initializing Git...");
|
|
2792
1945
|
try {
|
|
2793
|
-
|
|
2794
|
-
await $2`git
|
|
2795
|
-
await $2`git
|
|
2796
|
-
|
|
2797
|
-
await $2`git checkout -b staging`.cwd(cwd).quiet();
|
|
2798
|
-
await $2`git checkout -b develop`.cwd(cwd).quiet();
|
|
2799
|
-
s.stop("Git initialized (main -> staging -> develop)");
|
|
1946
|
+
await $2`git init`.cwd(projectPath).quiet();
|
|
1947
|
+
await $2`git add .`.cwd(projectPath).quiet();
|
|
1948
|
+
await $2`git commit -m "Initial commit"`.cwd(projectPath).quiet();
|
|
1949
|
+
s.stop("Git initialized");
|
|
2800
1950
|
} catch (error) {
|
|
2801
1951
|
s.stop("Error initializing Git");
|
|
2802
|
-
|
|
2803
|
-
if (config.github) {
|
|
2804
|
-
s.start("Creating GitHub repository...");
|
|
2805
|
-
try {
|
|
2806
|
-
const cwd = config.name;
|
|
2807
|
-
const repoName = config.githubOrg ? `${config.githubOrg}/${config.name}` : config.name;
|
|
2808
|
-
let visibility;
|
|
2809
|
-
if (config.type === "nimbus-core") {
|
|
2810
|
-
visibility = "--private";
|
|
2811
|
-
} else if (isPublicTemplate) {
|
|
2812
|
-
visibility = config.githubDescription === "public" ? "--public" : "--private";
|
|
2813
|
-
} else {
|
|
2814
|
-
visibility = config.githubOrg === "fast-by-nimbuslab" ? "--private" : "--public";
|
|
2815
|
-
}
|
|
2816
|
-
if (isPublicTemplate) {
|
|
2817
|
-
await $2`gh repo create ${repoName} ${visibility} --source . --remote origin`.cwd(cwd).quiet();
|
|
2818
|
-
} else {
|
|
2819
|
-
await $2`gh repo create ${repoName} ${visibility} --description ${config.githubDescription} --source . --remote origin`.cwd(cwd).quiet();
|
|
2820
|
-
}
|
|
2821
|
-
await $2`git checkout main`.cwd(cwd).quiet();
|
|
2822
|
-
await $2`git push -u origin main`.cwd(cwd).quiet();
|
|
2823
|
-
await $2`git checkout staging`.cwd(cwd).quiet();
|
|
2824
|
-
await $2`git push -u origin staging`.cwd(cwd).quiet();
|
|
2825
|
-
await $2`git checkout develop`.cwd(cwd).quiet();
|
|
2826
|
-
await $2`git push -u origin develop`.cwd(cwd).quiet();
|
|
2827
|
-
s.stop(`GitHub: ${repoName}`);
|
|
2828
|
-
} catch (error) {
|
|
2829
|
-
s.stop("Error creating GitHub repository");
|
|
2830
|
-
console.log(import_picocolors4.default.dim(" You can create manually with: gh repo create"));
|
|
2831
|
-
}
|
|
1952
|
+
console.log(import_picocolors3.default.yellow(" You can initialize manually with: git init"));
|
|
2832
1953
|
}
|
|
2833
1954
|
}
|
|
2834
|
-
if (config.
|
|
2835
|
-
s.start(`
|
|
1955
|
+
if (config.github && config.githubOrg) {
|
|
1956
|
+
s.start(`Creating GitHub repository...`);
|
|
2836
1957
|
try {
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
await Bun.write(`${config.name}/.env`, envContent);
|
|
2849
|
-
s.stop("Arquivo .env criado");
|
|
2850
|
-
} catch (error) {
|
|
2851
|
-
s.stop("Error creating .env");
|
|
2852
|
-
}
|
|
2853
|
-
}
|
|
2854
|
-
if (config.install) {
|
|
2855
|
-
s.start("Installing dependencies (pode demorar)...");
|
|
2856
|
-
try {
|
|
2857
|
-
await $2`bun install`.cwd(config.name).quiet();
|
|
2858
|
-
s.stop("Dependencies installed");
|
|
1958
|
+
const repoName = config.name;
|
|
1959
|
+
const visibility = config.githubVisibility === "public" ? "--public" : "--private";
|
|
1960
|
+
const isPersonal = config.githubOrg && !config.githubOrg.includes("/");
|
|
1961
|
+
if (isPersonal) {
|
|
1962
|
+
await $2`gh repo create ${config.githubOrg}/${repoName} ${visibility} --source . --push`.cwd(projectPath).quiet();
|
|
1963
|
+
} else {
|
|
1964
|
+
await $2`gh repo create ${repoName} ${visibility} --source . --push`.cwd(projectPath).quiet();
|
|
1965
|
+
}
|
|
1966
|
+
const repoUrl = `https://github.com/${config.githubOrg}/${repoName}`;
|
|
1967
|
+
s.stop(`GitHub repository created`);
|
|
1968
|
+
console.log(import_picocolors3.default.green(` ${repoUrl}`));
|
|
2859
1969
|
} catch (error) {
|
|
2860
|
-
s.stop("Error
|
|
1970
|
+
s.stop("Error creating GitHub repository");
|
|
1971
|
+
console.log(import_picocolors3.default.dim(" You can create manually with: gh repo create"));
|
|
2861
1972
|
}
|
|
2862
1973
|
}
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
"
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
"",
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
1974
|
+
if (config.aiAssistant && AI_CONFIGS[config.aiAssistant]) {
|
|
1975
|
+
const aiConfig = AI_CONFIGS[config.aiAssistant];
|
|
1976
|
+
const filePath = join2(projectPath, aiConfig.filename);
|
|
1977
|
+
if (aiConfig.filename.includes("/")) {
|
|
1978
|
+
const dir = join2(projectPath, aiConfig.filename.split("/")[0]);
|
|
1979
|
+
await mkdir(dir, { recursive: true });
|
|
1980
|
+
}
|
|
1981
|
+
await Bun.write(filePath, aiConfig.content(config.type));
|
|
1982
|
+
}
|
|
1983
|
+
s.start("Generating documentation...");
|
|
1984
|
+
const generatorConfig = {
|
|
1985
|
+
name: config.name,
|
|
1986
|
+
type: config.type,
|
|
1987
|
+
description: `A modern ${config.type === "landing" ? "landing page" : config.type === "app" ? "web application" : "monorepo"} built with Next.js 16, React 19, Tailwind CSS 4, and shadcn/ui.`,
|
|
1988
|
+
stack: {
|
|
1989
|
+
framework: "Next.js 16",
|
|
1990
|
+
styling: "Tailwind CSS 4",
|
|
1991
|
+
components: "shadcn/ui",
|
|
1992
|
+
forms: config.type !== "turborepo" ? "React Hook Form + Zod" : undefined,
|
|
1993
|
+
auth: config.type === "app" ? "Better Auth" : undefined
|
|
1994
|
+
},
|
|
1995
|
+
features: {
|
|
1996
|
+
auth: config.type === "app",
|
|
1997
|
+
contactForm: config.type === "landing",
|
|
1998
|
+
analytics: false
|
|
2887
1999
|
}
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
lines.push("");
|
|
2892
|
-
lines.push("# Database (fast+)");
|
|
2893
|
-
lines.push("DATABASE_URL=postgresql://postgres:postgres@localhost:5432/app");
|
|
2894
|
-
lines.push("");
|
|
2895
|
-
lines.push("# Auth (fast+)");
|
|
2896
|
-
lines.push("BETTER_AUTH_SECRET=");
|
|
2897
|
-
lines.push("BETTER_AUTH_URL=http://localhost:3000");
|
|
2898
|
-
}
|
|
2899
|
-
return lines.join(`
|
|
2900
|
-
`) + `
|
|
2901
|
-
`;
|
|
2902
|
-
}
|
|
2903
|
-
function showNextSteps(config) {
|
|
2904
|
-
const isPublicTemplate = ["landing", "app", "turborepo"].includes(config.type);
|
|
2905
|
-
const needsSetup = config.type === "app";
|
|
2000
|
+
};
|
|
2001
|
+
await generateAIFriendlyDocs(projectPath, generatorConfig);
|
|
2002
|
+
s.stop("Documentation generated");
|
|
2906
2003
|
console.log();
|
|
2907
|
-
|
|
2004
|
+
Se(import_picocolors3.default.green(`\u2713 Project created: ${config.name}`));
|
|
2908
2005
|
console.log();
|
|
2909
|
-
console.log(
|
|
2910
|
-
|
|
2911
|
-
console.log();
|
|
2912
|
-
console.log(import_picocolors4.default.dim(" nimbus-core: Motor para projetos externos"));
|
|
2913
|
-
console.log();
|
|
2914
|
-
console.log(import_picocolors4.default.dim(" Para usar a Lola:"));
|
|
2915
|
-
console.log(` ${import_picocolors4.default.cyan("lola")}`);
|
|
2916
|
-
console.log();
|
|
2917
|
-
console.log(import_picocolors4.default.yellow(" STEALTH MODE: Commits sem mencao a nimbuslab/Lola/IA"));
|
|
2918
|
-
console.log();
|
|
2919
|
-
if (config.github) {
|
|
2920
|
-
const repoUrl = `https://github.com/nimbuslab/${config.name}`;
|
|
2921
|
-
console.log(import_picocolors4.default.green(` GitHub (private): ${repoUrl}`));
|
|
2922
|
-
console.log();
|
|
2923
|
-
}
|
|
2924
|
-
console.log(import_picocolors4.default.dim(" Docs: See README.md for full instructions"));
|
|
2925
|
-
console.log();
|
|
2926
|
-
return;
|
|
2927
|
-
}
|
|
2006
|
+
console.log(import_picocolors3.default.bold("Next steps:"));
|
|
2007
|
+
console.log(` ${import_picocolors3.default.cyan(`cd ${config.name}`)}`);
|
|
2928
2008
|
if (!config.install) {
|
|
2929
|
-
console.log(` ${
|
|
2009
|
+
console.log(` ${import_picocolors3.default.cyan("bun install")}`);
|
|
2930
2010
|
}
|
|
2931
|
-
|
|
2932
|
-
console.log(` ${import_picocolors4.default.cyan("bun")} setup`);
|
|
2933
|
-
}
|
|
2934
|
-
console.log(` ${import_picocolors4.default.cyan("bun")} dev`);
|
|
2011
|
+
console.log(` ${import_picocolors3.default.cyan("bun dev")}`);
|
|
2935
2012
|
console.log();
|
|
2936
|
-
if (
|
|
2937
|
-
console.log(
|
|
2938
|
-
console.log(
|
|
2939
|
-
console.log(import_picocolors4.default.dim(" - Run database migrations"));
|
|
2940
|
-
console.log(import_picocolors4.default.dim(" - Create demo user (demo@example.com / demo1234)"));
|
|
2013
|
+
if (config.type === "app") {
|
|
2014
|
+
console.log(import_picocolors3.default.dim(" For database setup:"));
|
|
2015
|
+
console.log(` ${import_picocolors3.default.cyan("bun setup")}`);
|
|
2941
2016
|
console.log();
|
|
2942
2017
|
}
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2018
|
+
}
|
|
2019
|
+
async function create(args) {
|
|
2020
|
+
const checkCmd = process.platform === "win32" ? "where" : "which";
|
|
2021
|
+
console.log(import_picocolors3.default.dim("Checking dependencies..."));
|
|
2022
|
+
const hasGit = await $2`${checkCmd} git`.quiet().nothrow().then((r2) => r2.exitCode === 0);
|
|
2023
|
+
const hasBun = await $2`${checkCmd} bun`.quiet().nothrow().then((r2) => r2.exitCode === 0);
|
|
2024
|
+
if (!hasGit) {
|
|
2025
|
+
console.log(import_picocolors3.default.red("\u2717 Git not found"));
|
|
2026
|
+
console.log(import_picocolors3.default.dim(" Install from: https://git-scm.com"));
|
|
2027
|
+
process.exit(1);
|
|
2950
2028
|
}
|
|
2951
|
-
if (
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
if (config.aiAssistant) {
|
|
2956
|
-
const aiConfig = AI_CONFIGS[config.aiAssistant];
|
|
2957
|
-
if (aiConfig) {
|
|
2958
|
-
console.log(import_picocolors4.default.dim(` AI config: ${aiConfig.filename}`));
|
|
2959
|
-
}
|
|
2960
|
-
}
|
|
2961
|
-
if (config.theme !== "dark" || config.aiAssistant) {
|
|
2962
|
-
console.log();
|
|
2963
|
-
}
|
|
2029
|
+
if (!hasBun) {
|
|
2030
|
+
console.log(import_picocolors3.default.red("\u2717 Bun not found"));
|
|
2031
|
+
console.log(import_picocolors3.default.dim(" Install from: https://bun.sh"));
|
|
2032
|
+
process.exit(1);
|
|
2964
2033
|
}
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2034
|
+
console.log(import_picocolors3.default.green("\u2713 Dependencies OK"));
|
|
2035
|
+
console.log();
|
|
2036
|
+
const { flags, projectName } = parseFlags(args);
|
|
2037
|
+
Ie(import_picocolors3.default.bgCyan(import_picocolors3.default.black(" Create Next.js Project ")));
|
|
2038
|
+
let config;
|
|
2039
|
+
if (flags.yes && projectName && (flags.landing || flags.app || flags.turborepo)) {
|
|
2040
|
+
const type = flags.landing ? "landing" : flags.app ? "app" : "turborepo";
|
|
2041
|
+
config = {
|
|
2042
|
+
name: projectName,
|
|
2043
|
+
type,
|
|
2044
|
+
git: !flags.noGit,
|
|
2045
|
+
install: !flags.noInstall,
|
|
2046
|
+
github: false,
|
|
2047
|
+
githubOrg: null,
|
|
2048
|
+
githubVisibility: "public",
|
|
2049
|
+
theme: "dark",
|
|
2050
|
+
aiAssistant: null,
|
|
2051
|
+
customTemplate: flags.template
|
|
2052
|
+
};
|
|
2053
|
+
console.log(import_picocolors3.default.dim(` Project: ${projectName}`));
|
|
2054
|
+
console.log(import_picocolors3.default.dim(` Type: ${type}`));
|
|
2055
|
+
console.log(import_picocolors3.default.dim(` Git: ${config.git ? "yes" : "no"}`));
|
|
2056
|
+
console.log(import_picocolors3.default.dim(` Install: ${config.install ? "yes" : "no"}`));
|
|
2057
|
+
if (flags.template)
|
|
2058
|
+
console.log(import_picocolors3.default.dim(` Template: ${flags.template}`));
|
|
2975
2059
|
console.log();
|
|
2976
|
-
}
|
|
2977
|
-
if (!isPublicTemplate) {
|
|
2978
|
-
if (config.resendApiKey || config.stagingUrl) {
|
|
2979
|
-
console.log(import_picocolors4.default.green(" .env configured!"));
|
|
2980
|
-
console.log();
|
|
2981
|
-
} else {
|
|
2982
|
-
console.log(import_picocolors4.default.yellow(" Tip: Configure .env manually or use 'bun setup'."));
|
|
2983
|
-
console.log();
|
|
2984
|
-
}
|
|
2985
|
-
}
|
|
2986
|
-
if (isPublicTemplate) {
|
|
2987
|
-
console.log(import_picocolors4.default.dim(" Open source template (MIT) by nimbuslab"));
|
|
2988
|
-
console.log(import_picocolors4.default.dim(` https://github.com/nimbuslab/create-next-${config.type === "turborepo" ? "turborepo" : config.type}`));
|
|
2989
2060
|
} else {
|
|
2990
|
-
|
|
2061
|
+
config = await promptConfig(projectName, flags);
|
|
2991
2062
|
}
|
|
2992
|
-
|
|
2063
|
+
if (pD(config)) {
|
|
2064
|
+
xe("Operation cancelled");
|
|
2065
|
+
process.exit(0);
|
|
2066
|
+
}
|
|
2067
|
+
await createProject(config);
|
|
2993
2068
|
}
|
|
2994
2069
|
|
|
2995
2070
|
// src/commands/analyze.ts
|
|
2996
|
-
var
|
|
2071
|
+
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
2997
2072
|
import { existsSync, readFileSync } from "fs";
|
|
2998
2073
|
import { join as join3 } from "path";
|
|
2999
2074
|
function detectPackageManager(dir) {
|
|
@@ -3119,12 +2194,12 @@ async function analyze(args) {
|
|
|
3119
2194
|
const targetDir = args[0] || ".";
|
|
3120
2195
|
const absoluteDir = targetDir.startsWith("/") ? targetDir : join3(process.cwd(), targetDir);
|
|
3121
2196
|
console.log();
|
|
3122
|
-
console.log(
|
|
2197
|
+
console.log(import_picocolors4.default.cyan(" Analisando projeto..."));
|
|
3123
2198
|
console.log();
|
|
3124
2199
|
const pkgPath = join3(absoluteDir, "package.json");
|
|
3125
2200
|
if (!existsSync(pkgPath)) {
|
|
3126
|
-
console.log(
|
|
3127
|
-
console.log(
|
|
2201
|
+
console.log(import_picocolors4.default.red(" Erro: package.json nao encontrado"));
|
|
2202
|
+
console.log(import_picocolors4.default.dim(` Diretorio: ${absoluteDir}`));
|
|
3128
2203
|
process.exit(1);
|
|
3129
2204
|
}
|
|
3130
2205
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
@@ -3147,36 +2222,36 @@ async function analyze(args) {
|
|
|
3147
2222
|
recommendations: []
|
|
3148
2223
|
};
|
|
3149
2224
|
result.recommendations = generateRecommendations(result);
|
|
3150
|
-
console.log(
|
|
2225
|
+
console.log(import_picocolors4.default.bold(" Projeto: ") + import_picocolors4.default.cyan(result.name) + import_picocolors4.default.dim(` v${result.version}`));
|
|
3151
2226
|
console.log();
|
|
3152
|
-
console.log(
|
|
3153
|
-
console.log(` Framework: ${result.framework ?
|
|
3154
|
-
console.log(` Styling: ${result.styling.map((s) =>
|
|
3155
|
-
console.log(` Package Manager: ${result.packageManager === "bun" ?
|
|
3156
|
-
console.log(` TypeScript: ${result.typescript ?
|
|
3157
|
-
console.log(` Monorepo: ${result.monorepo ?
|
|
3158
|
-
console.log(` Auth: ${result.auth ?
|
|
3159
|
-
console.log(` Database: ${result.database ?
|
|
2227
|
+
console.log(import_picocolors4.default.bold(" Stack Detectada:"));
|
|
2228
|
+
console.log(` Framework: ${result.framework ? import_picocolors4.default.green(result.framework + "@" + result.frameworkVersion) : import_picocolors4.default.dim("nenhum")}`);
|
|
2229
|
+
console.log(` Styling: ${result.styling.map((s) => import_picocolors4.default.green(s)).join(", ")}`);
|
|
2230
|
+
console.log(` Package Manager: ${result.packageManager === "bun" ? import_picocolors4.default.green(result.packageManager) : import_picocolors4.default.yellow(result.packageManager)}`);
|
|
2231
|
+
console.log(` TypeScript: ${result.typescript ? import_picocolors4.default.green("sim") : import_picocolors4.default.dim("nao")}`);
|
|
2232
|
+
console.log(` Monorepo: ${result.monorepo ? import_picocolors4.default.green(result.monorepo) : import_picocolors4.default.dim("nao")}`);
|
|
2233
|
+
console.log(` Auth: ${result.auth ? import_picocolors4.default.green(result.auth) : import_picocolors4.default.dim("nenhum")}`);
|
|
2234
|
+
console.log(` Database: ${result.database ? import_picocolors4.default.green(result.database) : import_picocolors4.default.dim("nenhum")}`);
|
|
3160
2235
|
console.log();
|
|
3161
2236
|
if (result.recommendations.length > 0) {
|
|
3162
|
-
console.log(
|
|
2237
|
+
console.log(import_picocolors4.default.bold(" Recomendacoes:"));
|
|
3163
2238
|
result.recommendations.forEach((rec, i) => {
|
|
3164
|
-
console.log(
|
|
2239
|
+
console.log(import_picocolors4.default.yellow(` ${i + 1}. ${rec}`));
|
|
3165
2240
|
});
|
|
3166
2241
|
console.log();
|
|
3167
2242
|
} else {
|
|
3168
|
-
console.log(
|
|
2243
|
+
console.log(import_picocolors4.default.green(" Projeto ja esta na stack recomendada!"));
|
|
3169
2244
|
console.log();
|
|
3170
2245
|
}
|
|
3171
2246
|
if (args.includes("--json")) {
|
|
3172
|
-
console.log(
|
|
2247
|
+
console.log(import_picocolors4.default.dim(" JSON:"));
|
|
3173
2248
|
console.log(JSON.stringify(result, null, 2));
|
|
3174
2249
|
}
|
|
3175
2250
|
return result;
|
|
3176
2251
|
}
|
|
3177
2252
|
|
|
3178
2253
|
// src/commands/upgrade.ts
|
|
3179
|
-
var
|
|
2254
|
+
var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
3180
2255
|
var UPGRADE_PLANS = {
|
|
3181
2256
|
next: (current) => {
|
|
3182
2257
|
const major = parseInt(current.replace(/[^0-9]/g, "").slice(0, 2));
|
|
@@ -3293,10 +2368,10 @@ async function upgrade(args) {
|
|
|
3293
2368
|
const target = args.find((a) => !a.startsWith("-"));
|
|
3294
2369
|
console.log();
|
|
3295
2370
|
if (showPlan || !target) {
|
|
3296
|
-
console.log(
|
|
2371
|
+
console.log(import_picocolors5.default.cyan(" Analisando projeto para plano de upgrade..."));
|
|
3297
2372
|
console.log();
|
|
3298
2373
|
const analysis = await analyze([".", "--quiet"]);
|
|
3299
|
-
console.log(
|
|
2374
|
+
console.log(import_picocolors5.default.bold(" Upgrades Disponiveis:"));
|
|
3300
2375
|
console.log();
|
|
3301
2376
|
let hasUpgrades = false;
|
|
3302
2377
|
if (analysis.frameworkVersion && analysis.framework === "nextjs") {
|
|
@@ -3351,44 +2426,44 @@ async function upgrade(args) {
|
|
|
3351
2426
|
}
|
|
3352
2427
|
}
|
|
3353
2428
|
if (!hasUpgrades) {
|
|
3354
|
-
console.log(
|
|
2429
|
+
console.log(import_picocolors5.default.green(" Projeto ja esta atualizado!"));
|
|
3355
2430
|
}
|
|
3356
2431
|
console.log();
|
|
3357
|
-
console.log(
|
|
3358
|
-
console.log(
|
|
3359
|
-
console.log(
|
|
3360
|
-
console.log(
|
|
2432
|
+
console.log(import_picocolors5.default.dim(" Para executar um upgrade especifico:"));
|
|
2433
|
+
console.log(import_picocolors5.default.dim(" nimbus upgrade next"));
|
|
2434
|
+
console.log(import_picocolors5.default.dim(" nimbus upgrade tailwind"));
|
|
2435
|
+
console.log(import_picocolors5.default.dim(" nimbus upgrade bun"));
|
|
3361
2436
|
console.log();
|
|
3362
2437
|
return;
|
|
3363
2438
|
}
|
|
3364
|
-
console.log(
|
|
3365
|
-
console.log(
|
|
2439
|
+
console.log(import_picocolors5.default.yellow(` Upgrade ${target} ainda nao implementado.`));
|
|
2440
|
+
console.log(import_picocolors5.default.dim(" Por enquanto, siga os passos do --plan manualmente."));
|
|
3366
2441
|
console.log();
|
|
3367
2442
|
}
|
|
3368
2443
|
function printUpgradePlan(name, plan) {
|
|
3369
2444
|
const complexityColor = {
|
|
3370
|
-
low:
|
|
3371
|
-
medium:
|
|
3372
|
-
high:
|
|
2445
|
+
low: import_picocolors5.default.green,
|
|
2446
|
+
medium: import_picocolors5.default.yellow,
|
|
2447
|
+
high: import_picocolors5.default.red
|
|
3373
2448
|
};
|
|
3374
|
-
console.log(` ${
|
|
3375
|
-
console.log(` ${
|
|
3376
|
-
console.log(` ${
|
|
2449
|
+
console.log(` ${import_picocolors5.default.bold(name)}`);
|
|
2450
|
+
console.log(` ${import_picocolors5.default.dim("Atual:")} ${plan.current} ${import_picocolors5.default.dim("->")} ${import_picocolors5.default.cyan(plan.target)}`);
|
|
2451
|
+
console.log(` ${import_picocolors5.default.dim("Complexidade:")} ${complexityColor[plan.complexity](plan.complexity)}`);
|
|
3377
2452
|
console.log();
|
|
3378
|
-
console.log(` ${
|
|
2453
|
+
console.log(` ${import_picocolors5.default.dim("Breaking Changes:")}`);
|
|
3379
2454
|
plan.breakingChanges.forEach((bc) => {
|
|
3380
|
-
console.log(` ${
|
|
2455
|
+
console.log(` ${import_picocolors5.default.yellow("!")} ${bc}`);
|
|
3381
2456
|
});
|
|
3382
2457
|
console.log();
|
|
3383
|
-
console.log(` ${
|
|
2458
|
+
console.log(` ${import_picocolors5.default.dim("Passos:")}`);
|
|
3384
2459
|
plan.steps.forEach((step, i) => {
|
|
3385
|
-
console.log(` ${
|
|
2460
|
+
console.log(` ${import_picocolors5.default.dim(`${i + 1}.`)} ${step}`);
|
|
3386
2461
|
});
|
|
3387
2462
|
console.log();
|
|
3388
2463
|
}
|
|
3389
2464
|
|
|
3390
2465
|
// src/commands/update.ts
|
|
3391
|
-
var
|
|
2466
|
+
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
3392
2467
|
import { execSync, spawnSync } from "child_process";
|
|
3393
2468
|
var PACKAGE_NAME = "@nimbuslab/cli";
|
|
3394
2469
|
function hasBunInstall() {
|
|
@@ -3524,7 +2599,7 @@ async function update(args) {
|
|
|
3524
2599
|
const filteredArgs = args.filter((a) => a !== "--force" && a !== "-f");
|
|
3525
2600
|
const flag = filteredArgs[0];
|
|
3526
2601
|
if (flag === "--list" || flag === "-l") {
|
|
3527
|
-
Ie(
|
|
2602
|
+
Ie(import_picocolors6.default.cyan("Versoes disponiveis"));
|
|
3528
2603
|
const spinner2 = Y2();
|
|
3529
2604
|
spinner2.start("Buscando versoes...");
|
|
3530
2605
|
const versions = await getAvailableVersions();
|
|
@@ -3536,29 +2611,29 @@ async function update(args) {
|
|
|
3536
2611
|
const current = getCurrentVersion();
|
|
3537
2612
|
const pm2 = detectPackageManager2();
|
|
3538
2613
|
console.log();
|
|
3539
|
-
console.log(
|
|
2614
|
+
console.log(import_picocolors6.default.bold("Ultimas 10 versoes:"));
|
|
3540
2615
|
versions.slice(0, 10).forEach((v2, i) => {
|
|
3541
2616
|
const isCurrent = v2 === current;
|
|
3542
|
-
const prefix = isCurrent ?
|
|
3543
|
-
const suffix = isCurrent ?
|
|
3544
|
-
const isLatest = i === 0 ?
|
|
2617
|
+
const prefix = isCurrent ? import_picocolors6.default.green("-> ") : " ";
|
|
2618
|
+
const suffix = isCurrent ? import_picocolors6.default.dim(" (instalada)") : "";
|
|
2619
|
+
const isLatest = i === 0 ? import_picocolors6.default.yellow(" (latest)") : "";
|
|
3545
2620
|
console.log(`${prefix}${v2}${suffix}${isLatest}`);
|
|
3546
2621
|
});
|
|
3547
2622
|
console.log();
|
|
3548
|
-
console.log(
|
|
3549
|
-
console.log(
|
|
3550
|
-
console.log(
|
|
3551
|
-
console.log(
|
|
2623
|
+
console.log(import_picocolors6.default.dim(`Total: ${versions.length} versoes`));
|
|
2624
|
+
console.log(import_picocolors6.default.dim(`Package manager detectado: ${pm2 === "unknown" ? "nenhum" : pm2}`));
|
|
2625
|
+
console.log(import_picocolors6.default.dim(`Instalar versao especifica: nimbus update <versao>`));
|
|
2626
|
+
console.log(import_picocolors6.default.dim(`Forcar reinstalacao: nimbus update --force`));
|
|
3552
2627
|
return;
|
|
3553
2628
|
}
|
|
3554
2629
|
const targetVersion = flag || "latest";
|
|
3555
2630
|
const isSpecificVersion = flag && flag !== "latest" && !flag.startsWith("-");
|
|
3556
|
-
Ie(
|
|
2631
|
+
Ie(import_picocolors6.default.cyan(`Atualizando ${PACKAGE_NAME}`));
|
|
3557
2632
|
const spinner = Y2();
|
|
3558
2633
|
spinner.start("Verificando instalacoes...");
|
|
3559
2634
|
const cleanup = cleanupDuplicateInstalls();
|
|
3560
2635
|
if (cleanup.cleaned) {
|
|
3561
|
-
spinner.stop(
|
|
2636
|
+
spinner.stop(import_picocolors6.default.yellow(cleanup.message));
|
|
3562
2637
|
} else {
|
|
3563
2638
|
spinner.stop("OK");
|
|
3564
2639
|
}
|
|
@@ -3576,7 +2651,7 @@ async function update(args) {
|
|
|
3576
2651
|
spinner.stop(`Ultima versao: ${latestVersion || "desconhecida"}`);
|
|
3577
2652
|
if (!forceFlag && latestVersion && latestVersion === currentVersion) {
|
|
3578
2653
|
M2.success("Voce ja esta na ultima versao!");
|
|
3579
|
-
console.log(
|
|
2654
|
+
console.log(import_picocolors6.default.dim(" Use --force para reinstalar"));
|
|
3580
2655
|
return;
|
|
3581
2656
|
}
|
|
3582
2657
|
}
|
|
@@ -3614,33 +2689,33 @@ async function update(args) {
|
|
|
3614
2689
|
const isWindows = process.platform === "win32";
|
|
3615
2690
|
if (isWindows) {
|
|
3616
2691
|
console.log();
|
|
3617
|
-
console.log(
|
|
2692
|
+
console.log(import_picocolors6.default.yellow(" Reinicie o terminal para aplicar a atualizacao."));
|
|
3618
2693
|
} else if (isUsingFnm()) {
|
|
3619
2694
|
console.log();
|
|
3620
|
-
console.log(
|
|
3621
|
-
console.log(
|
|
3622
|
-
console.log(
|
|
2695
|
+
console.log(import_picocolors6.default.yellow(" fnm detectado - execute para aplicar:"));
|
|
2696
|
+
console.log(import_picocolors6.default.cyan(" hash -r"));
|
|
2697
|
+
console.log(import_picocolors6.default.dim(" Ou abra um novo terminal."));
|
|
3623
2698
|
}
|
|
3624
|
-
Se(
|
|
2699
|
+
Se(import_picocolors6.default.green("Pronto!"));
|
|
3625
2700
|
} catch (error) {
|
|
3626
2701
|
spinner.stop("Erro na atualizacao");
|
|
3627
2702
|
const err = error;
|
|
3628
2703
|
M2.error("Falha ao atualizar");
|
|
3629
2704
|
if (err.stderr) {
|
|
3630
|
-
console.log(
|
|
2705
|
+
console.log(import_picocolors6.default.dim(err.stderr));
|
|
3631
2706
|
}
|
|
3632
2707
|
console.log();
|
|
3633
|
-
console.log(
|
|
2708
|
+
console.log(import_picocolors6.default.yellow("Tente manualmente:"));
|
|
3634
2709
|
if (pm === "bun") {
|
|
3635
|
-
console.log(
|
|
2710
|
+
console.log(import_picocolors6.default.cyan(` bun add -g ${PACKAGE_NAME}${isSpecificVersion ? `@${targetVersion}` : ""}`));
|
|
3636
2711
|
} else {
|
|
3637
|
-
console.log(
|
|
2712
|
+
console.log(import_picocolors6.default.cyan(` npm install -g ${PACKAGE_NAME}${isSpecificVersion ? `@${targetVersion}` : ""}`));
|
|
3638
2713
|
}
|
|
3639
2714
|
}
|
|
3640
2715
|
}
|
|
3641
2716
|
|
|
3642
2717
|
// src/commands/setup-node.ts
|
|
3643
|
-
var
|
|
2718
|
+
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
3644
2719
|
import { execSync as execSync2, spawnSync as spawnSync2 } from "child_process";
|
|
3645
2720
|
import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
3646
2721
|
import { homedir } from "os";
|
|
@@ -3909,7 +2984,7 @@ async function removeFnm(fnm) {
|
|
|
3909
2984
|
const scoopCheck = spawnSync2("scoop", ["list"], { encoding: "utf-8", shell: true });
|
|
3910
2985
|
if (scoopCheck.stdout?.includes("fnm")) {
|
|
3911
2986
|
execSync2("scoop uninstall fnm", { stdio: "pipe" });
|
|
3912
|
-
console.log(
|
|
2987
|
+
console.log(import_picocolors7.default.dim(" Removido via Scoop"));
|
|
3913
2988
|
removed = true;
|
|
3914
2989
|
}
|
|
3915
2990
|
} catch {}
|
|
@@ -3918,7 +2993,7 @@ async function removeFnm(fnm) {
|
|
|
3918
2993
|
const chocoCheck = spawnSync2("choco", ["list", "--local-only"], { encoding: "utf-8", shell: true });
|
|
3919
2994
|
if (chocoCheck.stdout?.includes("fnm")) {
|
|
3920
2995
|
execSync2("choco uninstall fnm -y", { stdio: "pipe" });
|
|
3921
|
-
console.log(
|
|
2996
|
+
console.log(import_picocolors7.default.dim(" Removido via Chocolatey"));
|
|
3922
2997
|
removed = true;
|
|
3923
2998
|
}
|
|
3924
2999
|
} catch {}
|
|
@@ -3928,7 +3003,7 @@ async function removeFnm(fnm) {
|
|
|
3928
3003
|
const wingetCheck = spawnSync2("winget", ["list", "--name", "fnm"], { encoding: "utf-8", shell: true });
|
|
3929
3004
|
if (wingetCheck.stdout?.includes("fnm")) {
|
|
3930
3005
|
execSync2("winget uninstall fnm --silent", { stdio: "pipe" });
|
|
3931
|
-
console.log(
|
|
3006
|
+
console.log(import_picocolors7.default.dim(" Removido via winget"));
|
|
3932
3007
|
removed = true;
|
|
3933
3008
|
}
|
|
3934
3009
|
} catch {}
|
|
@@ -3944,12 +3019,12 @@ async function removeFnm(fnm) {
|
|
|
3944
3019
|
if (existsSync2(dir)) {
|
|
3945
3020
|
try {
|
|
3946
3021
|
execSync2(`rmdir /s /q "${dir}"`, { stdio: "pipe", shell: "cmd.exe" });
|
|
3947
|
-
console.log(
|
|
3022
|
+
console.log(import_picocolors7.default.dim(` Removido ${dir}`));
|
|
3948
3023
|
removed = true;
|
|
3949
3024
|
} catch {
|
|
3950
3025
|
try {
|
|
3951
3026
|
execSync2(`powershell -Command "Remove-Item -Path '${dir}' -Recurse -Force"`, { stdio: "pipe" });
|
|
3952
|
-
console.log(
|
|
3027
|
+
console.log(import_picocolors7.default.dim(` Removido ${dir}`));
|
|
3953
3028
|
removed = true;
|
|
3954
3029
|
} catch {}
|
|
3955
3030
|
}
|
|
@@ -3958,16 +3033,16 @@ async function removeFnm(fnm) {
|
|
|
3958
3033
|
try {
|
|
3959
3034
|
execSync2(`powershell -Command "[Environment]::SetEnvironmentVariable('FNM_DIR', $null, 'User')"`, { stdio: "pipe" });
|
|
3960
3035
|
execSync2(`powershell -Command "[Environment]::SetEnvironmentVariable('FNM_MULTISHELL_PATH', $null, 'User')"`, { stdio: "pipe" });
|
|
3961
|
-
console.log(
|
|
3036
|
+
console.log(import_picocolors7.default.dim(" Variaveis de ambiente FNM removidas"));
|
|
3962
3037
|
removed = true;
|
|
3963
3038
|
} catch {}
|
|
3964
3039
|
for (const configFile of fnm.configFiles || []) {
|
|
3965
3040
|
if (removeFnmFromConfig(configFile)) {
|
|
3966
|
-
console.log(
|
|
3041
|
+
console.log(import_picocolors7.default.dim(` Removido de ${configFile}`));
|
|
3967
3042
|
removed = true;
|
|
3968
3043
|
}
|
|
3969
3044
|
}
|
|
3970
|
-
spinner.stop(removed ? "fnm removido!" :
|
|
3045
|
+
spinner.stop(removed ? "fnm removido!" : import_picocolors7.default.yellow("fnm nao encontrado"));
|
|
3971
3046
|
return removed;
|
|
3972
3047
|
} else {
|
|
3973
3048
|
spinner.start("Removendo fnm...");
|
|
@@ -3976,13 +3051,13 @@ async function removeFnm(fnm) {
|
|
|
3976
3051
|
const brewCheck = spawnSync2("brew", ["list", "fnm"], { encoding: "utf-8", shell: true });
|
|
3977
3052
|
if (brewCheck.status === 0) {
|
|
3978
3053
|
execSync2("brew uninstall fnm", { stdio: "pipe" });
|
|
3979
|
-
console.log(
|
|
3054
|
+
console.log(import_picocolors7.default.dim(" Removido via Homebrew"));
|
|
3980
3055
|
removed = true;
|
|
3981
3056
|
}
|
|
3982
3057
|
} catch {}
|
|
3983
3058
|
for (const configFile of fnm.configFiles || []) {
|
|
3984
3059
|
if (removeFnmFromConfig(configFile)) {
|
|
3985
|
-
console.log(
|
|
3060
|
+
console.log(import_picocolors7.default.dim(` Removido de ${configFile}`));
|
|
3986
3061
|
removed = true;
|
|
3987
3062
|
}
|
|
3988
3063
|
}
|
|
@@ -3993,7 +3068,7 @@ async function removeFnm(fnm) {
|
|
|
3993
3068
|
for (const fnmDir of fnmDirs) {
|
|
3994
3069
|
if (existsSync2(fnmDir)) {
|
|
3995
3070
|
execSync2(`rm -rf "${fnmDir}"`, { stdio: "pipe" });
|
|
3996
|
-
console.log(
|
|
3071
|
+
console.log(import_picocolors7.default.dim(` Removido ${fnmDir}`));
|
|
3997
3072
|
removed = true;
|
|
3998
3073
|
}
|
|
3999
3074
|
}
|
|
@@ -4004,7 +3079,7 @@ async function removeFnm(fnm) {
|
|
|
4004
3079
|
for (const bin of fnmBins) {
|
|
4005
3080
|
if (existsSync2(bin)) {
|
|
4006
3081
|
execSync2(`rm -f "${bin}"`, { stdio: "pipe" });
|
|
4007
|
-
console.log(
|
|
3082
|
+
console.log(import_picocolors7.default.dim(` Removido ${bin}`));
|
|
4008
3083
|
removed = true;
|
|
4009
3084
|
}
|
|
4010
3085
|
}
|
|
@@ -4012,7 +3087,7 @@ async function removeFnm(fnm) {
|
|
|
4012
3087
|
return removed;
|
|
4013
3088
|
}
|
|
4014
3089
|
} catch (error) {
|
|
4015
|
-
spinner.stop(
|
|
3090
|
+
spinner.stop(import_picocolors7.default.red("Erro ao remover fnm"));
|
|
4016
3091
|
return false;
|
|
4017
3092
|
}
|
|
4018
3093
|
}
|
|
@@ -4026,7 +3101,7 @@ async function removeNvm(nvm) {
|
|
|
4026
3101
|
const wingetCheck = spawnSync2("winget", ["list", "--name", "nvm"], { encoding: "utf-8", shell: true });
|
|
4027
3102
|
if (wingetCheck.stdout?.toLowerCase().includes("nvm")) {
|
|
4028
3103
|
execSync2("winget uninstall nvm --silent", { stdio: "pipe" });
|
|
4029
|
-
console.log(
|
|
3104
|
+
console.log(import_picocolors7.default.dim(" Removido via winget"));
|
|
4030
3105
|
removed = true;
|
|
4031
3106
|
}
|
|
4032
3107
|
} catch {}
|
|
@@ -4039,46 +3114,46 @@ async function removeNvm(nvm) {
|
|
|
4039
3114
|
if (existsSync2(dir)) {
|
|
4040
3115
|
try {
|
|
4041
3116
|
execSync2(`rmdir /s /q "${dir}"`, { stdio: "pipe", shell: "cmd.exe" });
|
|
4042
|
-
console.log(
|
|
3117
|
+
console.log(import_picocolors7.default.dim(` Removido ${dir}`));
|
|
4043
3118
|
removed = true;
|
|
4044
3119
|
} catch {}
|
|
4045
3120
|
}
|
|
4046
3121
|
}
|
|
4047
3122
|
for (const configFile of nvm.configFiles || []) {
|
|
4048
3123
|
if (removeNvmFromConfig(configFile)) {
|
|
4049
|
-
console.log(
|
|
3124
|
+
console.log(import_picocolors7.default.dim(` Removido de ${configFile}`));
|
|
4050
3125
|
removed = true;
|
|
4051
3126
|
}
|
|
4052
3127
|
}
|
|
4053
3128
|
if (!removed) {
|
|
4054
|
-
console.log(
|
|
3129
|
+
console.log(import_picocolors7.default.yellow(`
|
|
4055
3130
|
nvm-windows pode precisar de remocao manual:`));
|
|
4056
|
-
console.log(
|
|
4057
|
-
console.log(
|
|
4058
|
-
console.log(
|
|
3131
|
+
console.log(import_picocolors7.default.dim(" 1. Abra 'Adicionar ou remover programas'"));
|
|
3132
|
+
console.log(import_picocolors7.default.dim(" 2. Procure por 'NVM for Windows'"));
|
|
3133
|
+
console.log(import_picocolors7.default.dim(" 3. Clique em Desinstalar"));
|
|
4059
3134
|
}
|
|
4060
|
-
spinner.stop(removed ? "nvm removido!" :
|
|
3135
|
+
spinner.stop(removed ? "nvm removido!" : import_picocolors7.default.yellow("Verifique manualmente"));
|
|
4061
3136
|
return removed;
|
|
4062
3137
|
} else {
|
|
4063
3138
|
spinner.start("Removendo nvm...");
|
|
4064
3139
|
let removed = false;
|
|
4065
3140
|
for (const configFile of nvm.configFiles || []) {
|
|
4066
3141
|
if (removeNvmFromConfig(configFile)) {
|
|
4067
|
-
console.log(
|
|
3142
|
+
console.log(import_picocolors7.default.dim(` Removido de ${configFile}`));
|
|
4068
3143
|
removed = true;
|
|
4069
3144
|
}
|
|
4070
3145
|
}
|
|
4071
3146
|
const nvmDir = process.env.NVM_DIR || join4(HOME, ".nvm");
|
|
4072
3147
|
if (existsSync2(nvmDir)) {
|
|
4073
3148
|
execSync2(`rm -rf "${nvmDir}"`, { stdio: "pipe" });
|
|
4074
|
-
console.log(
|
|
3149
|
+
console.log(import_picocolors7.default.dim(` Removido ${nvmDir}`));
|
|
4075
3150
|
removed = true;
|
|
4076
3151
|
}
|
|
4077
3152
|
spinner.stop(removed ? "nvm removido!" : "nvm nao encontrado");
|
|
4078
3153
|
return removed;
|
|
4079
3154
|
}
|
|
4080
3155
|
} catch (error) {
|
|
4081
|
-
spinner.stop(
|
|
3156
|
+
spinner.stop(import_picocolors7.default.red("Erro ao remover nvm"));
|
|
4082
3157
|
return false;
|
|
4083
3158
|
}
|
|
4084
3159
|
}
|
|
@@ -4098,13 +3173,13 @@ async function installVolta() {
|
|
|
4098
3173
|
});
|
|
4099
3174
|
spinner.stop("Volta instalado!");
|
|
4100
3175
|
const voltaPath = join4(HOME, ".volta", "bin");
|
|
4101
|
-
console.log(
|
|
3176
|
+
console.log(import_picocolors7.default.dim(` Adicionando ${voltaPath} ao PATH...`));
|
|
4102
3177
|
try {
|
|
4103
3178
|
execSync2(`setx PATH "%PATH%;${voltaPath}"`, { stdio: "pipe", shell: "cmd.exe" });
|
|
4104
3179
|
} catch {}
|
|
4105
3180
|
return true;
|
|
4106
3181
|
} catch (e2) {
|
|
4107
|
-
spinner.stop(
|
|
3182
|
+
spinner.stop(import_picocolors7.default.yellow("winget falhou, tentando outro metodo..."));
|
|
4108
3183
|
}
|
|
4109
3184
|
}
|
|
4110
3185
|
const chocoCheck = spawnSync2(CHECK_CMD, ["choco"], { encoding: "utf-8", shell: true });
|
|
@@ -4115,7 +3190,7 @@ async function installVolta() {
|
|
|
4115
3190
|
spinner.stop("Volta instalado!");
|
|
4116
3191
|
return true;
|
|
4117
3192
|
} catch {
|
|
4118
|
-
spinner.stop(
|
|
3193
|
+
spinner.stop(import_picocolors7.default.yellow("Chocolatey falhou"));
|
|
4119
3194
|
}
|
|
4120
3195
|
}
|
|
4121
3196
|
spinner.start("Baixando Volta diretamente...");
|
|
@@ -4139,17 +3214,17 @@ async function installVolta() {
|
|
|
4139
3214
|
spinner.stop("Volta instalado!");
|
|
4140
3215
|
return true;
|
|
4141
3216
|
} catch (e2) {
|
|
4142
|
-
spinner.stop(
|
|
3217
|
+
spinner.stop(import_picocolors7.default.yellow("Download direto falhou"));
|
|
4143
3218
|
}
|
|
4144
3219
|
console.log();
|
|
4145
|
-
console.log(
|
|
3220
|
+
console.log(import_picocolors7.default.bold(" Instale manualmente:"));
|
|
4146
3221
|
console.log();
|
|
4147
|
-
console.log(
|
|
4148
|
-
console.log(
|
|
3222
|
+
console.log(import_picocolors7.default.cyan(" 1. Baixe: https://github.com/volta-cli/volta/releases/latest"));
|
|
3223
|
+
console.log(import_picocolors7.default.dim(" (arquivo volta-windows.msi)"));
|
|
4149
3224
|
console.log();
|
|
4150
|
-
console.log(
|
|
3225
|
+
console.log(import_picocolors7.default.cyan(" 2. Execute o instalador"));
|
|
4151
3226
|
console.log();
|
|
4152
|
-
console.log(
|
|
3227
|
+
console.log(import_picocolors7.default.cyan(" 3. Reinicie o terminal"));
|
|
4153
3228
|
console.log();
|
|
4154
3229
|
return false;
|
|
4155
3230
|
} else {
|
|
@@ -4168,15 +3243,15 @@ export PATH="$VOLTA_HOME/bin:$PATH"
|
|
|
4168
3243
|
const content = readFileSync2(shellConfig, "utf-8");
|
|
4169
3244
|
if (!content.includes("VOLTA_HOME")) {
|
|
4170
3245
|
writeFileSync(shellConfig, content + voltaSetup);
|
|
4171
|
-
console.log(
|
|
3246
|
+
console.log(import_picocolors7.default.dim(` Adicionado ao ${shellConfig}`));
|
|
4172
3247
|
}
|
|
4173
3248
|
}
|
|
4174
3249
|
spinner.stop("Volta instalado!");
|
|
4175
3250
|
return true;
|
|
4176
3251
|
}
|
|
4177
3252
|
} catch (error) {
|
|
4178
|
-
spinner.stop(
|
|
4179
|
-
console.log(
|
|
3253
|
+
spinner.stop(import_picocolors7.default.red("Erro ao instalar Volta"));
|
|
3254
|
+
console.log(import_picocolors7.default.dim(` ${error}`));
|
|
4180
3255
|
return false;
|
|
4181
3256
|
}
|
|
4182
3257
|
}
|
|
@@ -4189,7 +3264,7 @@ async function installNodeWithVolta() {
|
|
|
4189
3264
|
spinner.stop("Node.js instalado!");
|
|
4190
3265
|
return true;
|
|
4191
3266
|
} catch (error) {
|
|
4192
|
-
spinner.stop(
|
|
3267
|
+
spinner.stop(import_picocolors7.default.red("Erro ao instalar Node.js"));
|
|
4193
3268
|
return false;
|
|
4194
3269
|
}
|
|
4195
3270
|
}
|
|
@@ -4204,16 +3279,16 @@ async function reinstallGlobalPackages(packages) {
|
|
|
4204
3279
|
execSync2(`"${voltaBin}" install ${pkg}`, { stdio: "pipe" });
|
|
4205
3280
|
spinner.stop(`${pkg} instalado!`);
|
|
4206
3281
|
} catch {
|
|
4207
|
-
spinner.stop(
|
|
3282
|
+
spinner.stop(import_picocolors7.default.yellow(`${pkg} - falha (instale manualmente)`));
|
|
4208
3283
|
}
|
|
4209
3284
|
}
|
|
4210
3285
|
}
|
|
4211
3286
|
async function setupNode(args) {
|
|
4212
3287
|
const checkOnly = args.includes("--check") || args.includes("-c");
|
|
4213
3288
|
console.log();
|
|
4214
|
-
Ie(
|
|
3289
|
+
Ie(import_picocolors7.default.bgCyan(import_picocolors7.default.black(" nimbus setup node ")));
|
|
4215
3290
|
console.log();
|
|
4216
|
-
console.log(
|
|
3291
|
+
console.log(import_picocolors7.default.bold(" Detectando ambiente..."));
|
|
4217
3292
|
console.log();
|
|
4218
3293
|
const fnm = detectFnm();
|
|
4219
3294
|
const nvm = detectNvm();
|
|
@@ -4221,27 +3296,27 @@ async function setupNode(args) {
|
|
|
4221
3296
|
const node = detectNode();
|
|
4222
3297
|
const status = (installed, version) => {
|
|
4223
3298
|
if (!installed)
|
|
4224
|
-
return
|
|
4225
|
-
return
|
|
3299
|
+
return import_picocolors7.default.dim("nao instalado");
|
|
3300
|
+
return import_picocolors7.default.green(`instalado${version ? ` (${version})` : ""}`);
|
|
4226
3301
|
};
|
|
4227
|
-
console.log(` ${
|
|
4228
|
-
console.log(` ${
|
|
4229
|
-
console.log(` ${
|
|
3302
|
+
console.log(` ${import_picocolors7.default.bold("fnm:")} ${status(fnm.installed, fnm.version)}`);
|
|
3303
|
+
console.log(` ${import_picocolors7.default.bold("nvm:")} ${status(nvm.installed, nvm.version)}`);
|
|
3304
|
+
console.log(` ${import_picocolors7.default.bold("volta:")} ${status(volta.installed, volta.version)}`);
|
|
4230
3305
|
console.log();
|
|
4231
|
-
console.log(` ${
|
|
3306
|
+
console.log(` ${import_picocolors7.default.bold("node:")} ${node.version || import_picocolors7.default.dim("nao encontrado")}`);
|
|
4232
3307
|
if (node.manager) {
|
|
4233
|
-
console.log(` ${
|
|
3308
|
+
console.log(` ${import_picocolors7.default.dim(`gerenciado por: ${node.manager}`)}`);
|
|
4234
3309
|
}
|
|
4235
3310
|
console.log();
|
|
4236
3311
|
if (volta.installed && !fnm.installed && !nvm.installed) {
|
|
4237
3312
|
M2.success("Ambiente OK! Volta instalado e configurado.");
|
|
4238
|
-
Se(
|
|
3313
|
+
Se(import_picocolors7.default.green("Nada a fazer."));
|
|
4239
3314
|
return;
|
|
4240
3315
|
}
|
|
4241
3316
|
if (checkOnly) {
|
|
4242
3317
|
if (fnm.installed || nvm.installed) {
|
|
4243
|
-
console.log(
|
|
4244
|
-
console.log(
|
|
3318
|
+
console.log(import_picocolors7.default.yellow(" Recomendacao: migre para Volta"));
|
|
3319
|
+
console.log(import_picocolors7.default.dim(" Execute: nimbus setup node"));
|
|
4245
3320
|
}
|
|
4246
3321
|
Se("");
|
|
4247
3322
|
return;
|
|
@@ -4249,15 +3324,15 @@ async function setupNode(args) {
|
|
|
4249
3324
|
const hasOldManager = fnm.installed || nvm.installed;
|
|
4250
3325
|
const globalPackages = getGlobalPackages();
|
|
4251
3326
|
if (hasOldManager) {
|
|
4252
|
-
console.log(
|
|
3327
|
+
console.log(import_picocolors7.default.yellow(" Gerenciadores antigos detectados!"));
|
|
4253
3328
|
console.log();
|
|
4254
|
-
console.log(
|
|
4255
|
-
console.log(
|
|
3329
|
+
console.log(import_picocolors7.default.dim(" fnm e nvm causam problemas de cache do shell."));
|
|
3330
|
+
console.log(import_picocolors7.default.dim(" Volta resolve isso e funciona melhor no Windows."));
|
|
4256
3331
|
console.log();
|
|
4257
3332
|
if (globalPackages.length > 0) {
|
|
4258
|
-
console.log(
|
|
3333
|
+
console.log(import_picocolors7.default.bold(" Pacotes globais encontrados:"));
|
|
4259
3334
|
for (const pkg of globalPackages) {
|
|
4260
|
-
console.log(
|
|
3335
|
+
console.log(import_picocolors7.default.dim(` - ${pkg}`));
|
|
4261
3336
|
}
|
|
4262
3337
|
console.log();
|
|
4263
3338
|
}
|
|
@@ -4272,9 +3347,9 @@ async function setupNode(args) {
|
|
|
4272
3347
|
actions.push("Instalar Node.js via Volta");
|
|
4273
3348
|
if (globalPackages.length > 0)
|
|
4274
3349
|
actions.push(`Reinstalar ${globalPackages.length} pacotes globais`);
|
|
4275
|
-
console.log(
|
|
3350
|
+
console.log(import_picocolors7.default.bold(" O que sera feito:"));
|
|
4276
3351
|
for (const action of actions) {
|
|
4277
|
-
console.log(
|
|
3352
|
+
console.log(import_picocolors7.default.cyan(` -> ${action}`));
|
|
4278
3353
|
}
|
|
4279
3354
|
console.log();
|
|
4280
3355
|
const confirm = await ye({
|
|
@@ -4287,60 +3362,60 @@ async function setupNode(args) {
|
|
|
4287
3362
|
}
|
|
4288
3363
|
console.log();
|
|
4289
3364
|
if (fnm.installed) {
|
|
4290
|
-
console.log(
|
|
3365
|
+
console.log(import_picocolors7.default.bold(" Removendo fnm..."));
|
|
4291
3366
|
await removeFnm(fnm);
|
|
4292
3367
|
console.log();
|
|
4293
3368
|
}
|
|
4294
3369
|
if (nvm.installed) {
|
|
4295
|
-
console.log(
|
|
3370
|
+
console.log(import_picocolors7.default.bold(" Removendo nvm..."));
|
|
4296
3371
|
await removeNvm(nvm);
|
|
4297
3372
|
console.log();
|
|
4298
3373
|
}
|
|
4299
3374
|
if (!volta.installed) {
|
|
4300
|
-
console.log(
|
|
3375
|
+
console.log(import_picocolors7.default.bold(" Instalando Volta..."));
|
|
4301
3376
|
const installed = await installVolta();
|
|
4302
3377
|
if (!installed) {
|
|
4303
|
-
Se(
|
|
3378
|
+
Se(import_picocolors7.default.red("Falha na instalacao. Tente manualmente."));
|
|
4304
3379
|
return;
|
|
4305
3380
|
}
|
|
4306
3381
|
console.log();
|
|
4307
3382
|
}
|
|
4308
|
-
console.log(
|
|
3383
|
+
console.log(import_picocolors7.default.bold(" Instalando Node.js..."));
|
|
4309
3384
|
await installNodeWithVolta();
|
|
4310
3385
|
console.log();
|
|
4311
3386
|
if (globalPackages.length > 0) {
|
|
4312
|
-
console.log(
|
|
3387
|
+
console.log(import_picocolors7.default.bold(" Reinstalando pacotes globais..."));
|
|
4313
3388
|
await reinstallGlobalPackages(globalPackages);
|
|
4314
3389
|
console.log();
|
|
4315
3390
|
}
|
|
4316
|
-
console.log(
|
|
4317
|
-
console.log(
|
|
4318
|
-
console.log(
|
|
3391
|
+
console.log(import_picocolors7.default.green(" ====================================="));
|
|
3392
|
+
console.log(import_picocolors7.default.green(" Migracao concluida!"));
|
|
3393
|
+
console.log(import_picocolors7.default.green(" ====================================="));
|
|
4319
3394
|
console.log();
|
|
4320
3395
|
if (IS_WINDOWS) {
|
|
4321
|
-
console.log(
|
|
3396
|
+
console.log(import_picocolors7.default.yellow(" IMPORTANTE: Reinicie o terminal!"));
|
|
4322
3397
|
console.log();
|
|
4323
|
-
console.log(
|
|
4324
|
-
console.log(
|
|
3398
|
+
console.log(import_picocolors7.default.dim(" Feche todas as janelas do PowerShell/Terminal"));
|
|
3399
|
+
console.log(import_picocolors7.default.dim(" e abra novamente para aplicar as mudancas."));
|
|
4325
3400
|
} else {
|
|
4326
|
-
console.log(
|
|
3401
|
+
console.log(import_picocolors7.default.yellow(" IMPORTANTE: Reinicie o terminal ou execute:"));
|
|
4327
3402
|
console.log();
|
|
4328
|
-
console.log(
|
|
4329
|
-
console.log(
|
|
4330
|
-
console.log(
|
|
3403
|
+
console.log(import_picocolors7.default.cyan(" source ~/.zshrc"));
|
|
3404
|
+
console.log(import_picocolors7.default.dim(" # ou"));
|
|
3405
|
+
console.log(import_picocolors7.default.cyan(" source ~/.bashrc"));
|
|
4331
3406
|
}
|
|
4332
3407
|
console.log();
|
|
4333
|
-
console.log(
|
|
4334
|
-
console.log(
|
|
4335
|
-
console.log(
|
|
4336
|
-
console.log(
|
|
3408
|
+
console.log(import_picocolors7.default.bold(" Depois, verifique:"));
|
|
3409
|
+
console.log(import_picocolors7.default.dim(" volta --version"));
|
|
3410
|
+
console.log(import_picocolors7.default.dim(" node --version"));
|
|
3411
|
+
console.log(import_picocolors7.default.dim(" nimbus --version"));
|
|
4337
3412
|
console.log();
|
|
4338
|
-
Se(
|
|
3413
|
+
Se(import_picocolors7.default.green("Pronto! Volta configurado."));
|
|
4339
3414
|
}
|
|
4340
3415
|
|
|
4341
3416
|
// src/index.ts
|
|
4342
3417
|
var PACKAGE_NAME2 = "@nimbuslab/cli";
|
|
4343
|
-
var CURRENT_VERSION = "1.2.
|
|
3418
|
+
var CURRENT_VERSION = "1.2.1";
|
|
4344
3419
|
var LOGO = `
|
|
4345
3420
|
\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
|
|
4346
3421
|
\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
|
|
@@ -4372,22 +3447,22 @@ function showUpdateNotice(latestVersion) {
|
|
|
4372
3447
|
const current = CURRENT_VERSION;
|
|
4373
3448
|
const latest = latestVersion;
|
|
4374
3449
|
const command = "nimbus update";
|
|
4375
|
-
const line1 = `
|
|
3450
|
+
const line1 = ` New version available: ${current} \u2192 ${latest}`;
|
|
4376
3451
|
const line2 = ` Atualize com: ${command}`;
|
|
4377
3452
|
const maxLen = Math.max(line1.length, line2.length);
|
|
4378
3453
|
const border = "\u2500".repeat(maxLen + 2);
|
|
4379
|
-
console.log(
|
|
4380
|
-
console.log(
|
|
4381
|
-
console.log(
|
|
4382
|
-
console.log(
|
|
3454
|
+
console.log(import_picocolors8.default.yellow(` \u250C${border}\u2510`));
|
|
3455
|
+
console.log(import_picocolors8.default.yellow(` \u2502`) + import_picocolors8.default.white(line1.padEnd(maxLen + 2)) + import_picocolors8.default.yellow(`\u2502`));
|
|
3456
|
+
console.log(import_picocolors8.default.yellow(` \u2502`) + import_picocolors8.default.cyan(line2.padEnd(maxLen + 2)) + import_picocolors8.default.yellow(`\u2502`));
|
|
3457
|
+
console.log(import_picocolors8.default.yellow(` \u2514${border}\u2518`));
|
|
4383
3458
|
console.log();
|
|
4384
3459
|
}
|
|
4385
3460
|
async function main() {
|
|
4386
3461
|
const args = process.argv.slice(2);
|
|
4387
3462
|
const command = args[0];
|
|
4388
|
-
console.log(
|
|
4389
|
-
console.log(
|
|
4390
|
-
console.log(
|
|
3463
|
+
console.log(import_picocolors8.default.cyan(LOGO));
|
|
3464
|
+
console.log(import_picocolors8.default.white(" nimbuslab CLI"));
|
|
3465
|
+
console.log(import_picocolors8.default.dim(" Create awesome projects"));
|
|
4391
3466
|
console.log();
|
|
4392
3467
|
const latestVersion = await checkForUpdates();
|
|
4393
3468
|
if (latestVersion) {
|
|
@@ -4406,8 +3481,8 @@ async function main() {
|
|
|
4406
3481
|
if (subcommand === "node") {
|
|
4407
3482
|
await setupNode(args.slice(2));
|
|
4408
3483
|
} else {
|
|
4409
|
-
console.log(
|
|
4410
|
-
console.log(
|
|
3484
|
+
console.log(import_picocolors8.default.red(`Subcomando desconhecido: ${subcommand || "(vazio)"}`));
|
|
3485
|
+
console.log(import_picocolors8.default.dim(" Uso: nimbus setup node"));
|
|
4411
3486
|
process.exit(1);
|
|
4412
3487
|
}
|
|
4413
3488
|
} else if (command === "help" || command === "--help" || command === "-h") {
|
|
@@ -4415,71 +3490,65 @@ async function main() {
|
|
|
4415
3490
|
} else if (command === "version" || command === "--version" || command === "-v") {
|
|
4416
3491
|
showVersion();
|
|
4417
3492
|
} else {
|
|
4418
|
-
console.log(
|
|
3493
|
+
console.log(import_picocolors8.default.red(`Comando desconhecido: ${command}`));
|
|
4419
3494
|
showHelp();
|
|
4420
3495
|
process.exit(1);
|
|
4421
3496
|
}
|
|
4422
3497
|
}
|
|
4423
3498
|
function showHelp() {
|
|
4424
3499
|
console.log(`
|
|
4425
|
-
${
|
|
3500
|
+
${import_picocolors8.default.bold("Usage:")} nimbus [command] [options]
|
|
4426
3501
|
|
|
4427
|
-
${
|
|
3502
|
+
${import_picocolors8.default.bold("Comandos:")}
|
|
4428
3503
|
create [nome] Criar novo projeto
|
|
4429
3504
|
analyze [dir] Analisar stack do projeto
|
|
4430
|
-
upgrade [
|
|
4431
|
-
update [
|
|
3505
|
+
upgrade [target] Update dependencies
|
|
3506
|
+
update [version] Update CLI itself
|
|
4432
3507
|
setup [alvo] Configurar ambiente
|
|
4433
|
-
lola [a\xE7\xE3o] Lola - Code Agent
|
|
4434
3508
|
help Mostrar esta ajuda
|
|
4435
|
-
version
|
|
3509
|
+
version Show version
|
|
4436
3510
|
|
|
4437
|
-
${
|
|
3511
|
+
${import_picocolors8.default.bold("Templates:")}
|
|
4438
3512
|
--landing Landing page (Next.js 16 + Tailwind 4 + shadcn)
|
|
4439
3513
|
--app Web app (Landing + Better Auth + Drizzle)
|
|
4440
3514
|
--turborepo Monorepo (Turborepo + apps/packages)
|
|
4441
3515
|
|
|
4442
|
-
${
|
|
4443
|
-
analyze .
|
|
3516
|
+
${import_picocolors8.default.bold("Analyze & Upgrade:")}
|
|
3517
|
+
analyze . Detect stack and show recommendations
|
|
4444
3518
|
analyze --json Output em JSON
|
|
4445
3519
|
upgrade --plan Mostrar plano de upgrade
|
|
4446
3520
|
upgrade next Atualizar Next.js
|
|
4447
3521
|
upgrade tailwind Atualizar Tailwind CSS
|
|
4448
3522
|
|
|
4449
|
-
${
|
|
3523
|
+
${import_picocolors8.default.bold("Update (CLI):")}
|
|
4450
3524
|
update Atualizar para ultima versao
|
|
4451
3525
|
update 0.11.0 Instalar versao especifica
|
|
4452
3526
|
update --list Listar versoes disponiveis
|
|
4453
3527
|
update --force Forcar reinstalacao (limpa cache)
|
|
4454
3528
|
|
|
4455
|
-
${
|
|
3529
|
+
${import_picocolors8.default.bold("Setup (Ambiente):")}
|
|
4456
3530
|
setup node Migrar para Volta (remove fnm/nvm)
|
|
4457
3531
|
setup node --check Verificar ambiente atual
|
|
4458
3532
|
|
|
4459
|
-
${
|
|
4460
|
-
-y, --yes
|
|
4461
|
-
--no-git
|
|
4462
|
-
--no-install
|
|
3533
|
+
${import_picocolors8.default.bold("Options:")}
|
|
3534
|
+
-y, --yes Accept defaults
|
|
3535
|
+
--no-git Skip Git initialization
|
|
3536
|
+
--no-install Skip dependency installation
|
|
4463
3537
|
--template <url> Usar template customizado
|
|
4464
3538
|
|
|
4465
|
-
${
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
${
|
|
4470
|
-
${
|
|
4471
|
-
${
|
|
4472
|
-
${import_picocolors9.default.dim("$")} nimbus analyze ./my-project
|
|
4473
|
-
${import_picocolors9.default.dim("$")} nimbus upgrade --plan
|
|
4474
|
-
${import_picocolors9.default.dim("$")} nimbus update
|
|
4475
|
-
${import_picocolors9.default.dim("$")} nimbus setup node
|
|
4476
|
-
${import_picocolors9.default.dim("$")} nimbus lola install
|
|
3539
|
+
${import_picocolors8.default.bold("Exemplos:")}
|
|
3540
|
+
${import_picocolors8.default.dim("$")} nimbus create my-landing --landing
|
|
3541
|
+
${import_picocolors8.default.dim("$")} nimbus create my-app --app
|
|
3542
|
+
${import_picocolors8.default.dim("$")} nimbus analyze ./my-project
|
|
3543
|
+
${import_picocolors8.default.dim("$")} nimbus upgrade --plan
|
|
3544
|
+
${import_picocolors8.default.dim("$")} nimbus update
|
|
3545
|
+
${import_picocolors8.default.dim("$")} nimbus setup node
|
|
4477
3546
|
`);
|
|
4478
3547
|
}
|
|
4479
3548
|
function showVersion() {
|
|
4480
3549
|
console.log(`${PACKAGE_NAME2} v${CURRENT_VERSION}`);
|
|
4481
3550
|
}
|
|
4482
3551
|
main().catch((err) => {
|
|
4483
|
-
console.error(
|
|
3552
|
+
console.error(import_picocolors8.default.red("Erro:"), err.message);
|
|
4484
3553
|
process.exit(1);
|
|
4485
3554
|
});
|