@nimbuslab/cli 0.16.4 → 0.16.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -75
- package/dist/index.js +4 -3
- package/package.json +4 -1
- package/.github/workflows/publish.yml +0 -67
- package/CLAUDE.md +0 -106
- package/MIGRATION-ROADMAP.md +0 -201
- package/bun.lock +0 -36
- package/docs/CI-CD.md +0 -181
- package/docs/analyze.md +0 -148
- package/docs/create.md +0 -219
- package/docs/migrate.md +0 -177
- package/docs/package.md +0 -229
- package/docs/upgrade.md +0 -152
- package/src/commands/analyze.ts +0 -210
- package/src/commands/create.ts +0 -1323
- package/src/commands/lola.ts +0 -1029
- package/src/commands/update.ts +0 -334
- package/src/commands/upgrade.ts +0 -251
- package/src/index.ts +0 -161
- package/tsconfig.json +0 -29
package/src/commands/update.ts
DELETED
|
@@ -1,334 +0,0 @@
|
|
|
1
|
-
import * as p from "@clack/prompts"
|
|
2
|
-
import pc from "picocolors"
|
|
3
|
-
import { execSync, spawnSync } from "child_process"
|
|
4
|
-
|
|
5
|
-
const PACKAGE_NAME = "@nimbuslab/cli"
|
|
6
|
-
|
|
7
|
-
type PackageManager = "bun" | "npm" | "unknown"
|
|
8
|
-
|
|
9
|
-
// Verifica se existe instalacao no bun global
|
|
10
|
-
function hasBunInstall(): boolean {
|
|
11
|
-
try {
|
|
12
|
-
const result = spawnSync("bun", ["pm", "ls", "-g"], {
|
|
13
|
-
encoding: "utf-8",
|
|
14
|
-
shell: true,
|
|
15
|
-
timeout: 5000,
|
|
16
|
-
})
|
|
17
|
-
return !!(result.stdout && result.stdout.includes(PACKAGE_NAME))
|
|
18
|
-
} catch {
|
|
19
|
-
return false
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Verifica se existe instalacao no npm global
|
|
24
|
-
function hasNpmInstall(): boolean {
|
|
25
|
-
try {
|
|
26
|
-
const result = spawnSync("npm", ["ls", "-g", PACKAGE_NAME, "--json"], {
|
|
27
|
-
encoding: "utf-8",
|
|
28
|
-
shell: true,
|
|
29
|
-
timeout: 5000,
|
|
30
|
-
})
|
|
31
|
-
if (result.stdout) {
|
|
32
|
-
const data = JSON.parse(result.stdout)
|
|
33
|
-
return !!data.dependencies?.[PACKAGE_NAME]
|
|
34
|
-
}
|
|
35
|
-
} catch {
|
|
36
|
-
// ignore
|
|
37
|
-
}
|
|
38
|
-
return false
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Remove instalacao duplicada para evitar conflitos
|
|
42
|
-
// Prioriza npm (fnm/nvm), remove bun se tiver npm
|
|
43
|
-
function cleanupDuplicateInstalls(): { cleaned: boolean; message: string } {
|
|
44
|
-
const hasNpm = hasNpmInstall()
|
|
45
|
-
const hasBun = hasBunInstall()
|
|
46
|
-
|
|
47
|
-
if (hasNpm && hasBun) {
|
|
48
|
-
// Tem nos dois - remover do bun (prioriza npm)
|
|
49
|
-
try {
|
|
50
|
-
execSync("bun remove -g @nimbuslab/cli", { stdio: "pipe", encoding: "utf-8" })
|
|
51
|
-
return {
|
|
52
|
-
cleaned: true,
|
|
53
|
-
message: "Instalacao duplicada removida do bun (usando npm)",
|
|
54
|
-
}
|
|
55
|
-
} catch {
|
|
56
|
-
return {
|
|
57
|
-
cleaned: false,
|
|
58
|
-
message: "Falha ao remover instalacao duplicada do bun",
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return { cleaned: false, message: "" }
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Detecta se está usando fnm (Fast Node Manager)
|
|
67
|
-
function isUsingFnm(): boolean {
|
|
68
|
-
const fnmDir = process.env.FNM_DIR || process.env.FNM_MULTISHELL_PATH
|
|
69
|
-
const checkCmd = process.platform === "win32" ? "where" : "which"
|
|
70
|
-
const whichNode = spawnSync(checkCmd, ["node"], { encoding: "utf-8", shell: true })
|
|
71
|
-
return !!(fnmDir || (whichNode.stdout && whichNode.stdout.includes("fnm")))
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
async function getAvailableVersions(): Promise<string[]> {
|
|
75
|
-
try {
|
|
76
|
-
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}`)
|
|
77
|
-
if (!res.ok) return []
|
|
78
|
-
const data = await res.json() as { versions?: Record<string, unknown> }
|
|
79
|
-
return Object.keys(data.versions || {}).reverse()
|
|
80
|
-
} catch {
|
|
81
|
-
return []
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
async function getLatestVersion(): Promise<string | null> {
|
|
86
|
-
try {
|
|
87
|
-
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`)
|
|
88
|
-
if (!res.ok) return null
|
|
89
|
-
const data = await res.json() as { version?: string }
|
|
90
|
-
return data.version || null
|
|
91
|
-
} catch {
|
|
92
|
-
return null
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Detecta qual package manager tem o pacote instalado globalmente
|
|
97
|
-
// Prioriza npm (mais comum com fnm/nvm)
|
|
98
|
-
function detectPackageManager(): PackageManager {
|
|
99
|
-
// Tentar npm primeiro (prioridade)
|
|
100
|
-
try {
|
|
101
|
-
const npmResult = spawnSync("npm", ["ls", "-g", PACKAGE_NAME, "--json"], {
|
|
102
|
-
encoding: "utf-8",
|
|
103
|
-
shell: true,
|
|
104
|
-
timeout: 5000,
|
|
105
|
-
})
|
|
106
|
-
if (npmResult.stdout) {
|
|
107
|
-
const data = JSON.parse(npmResult.stdout)
|
|
108
|
-
if (data.dependencies?.[PACKAGE_NAME]) {
|
|
109
|
-
return "npm"
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
} catch {
|
|
113
|
-
// ignore
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Fallback para bun
|
|
117
|
-
try {
|
|
118
|
-
const bunResult = spawnSync("bun", ["pm", "ls", "-g"], {
|
|
119
|
-
encoding: "utf-8",
|
|
120
|
-
shell: true,
|
|
121
|
-
timeout: 5000,
|
|
122
|
-
})
|
|
123
|
-
if (bunResult.stdout && bunResult.stdout.includes(PACKAGE_NAME)) {
|
|
124
|
-
return "bun"
|
|
125
|
-
}
|
|
126
|
-
} catch {
|
|
127
|
-
// ignore
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return "unknown"
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function getCurrentVersion(): string {
|
|
134
|
-
// Tentar npm primeiro (prioridade)
|
|
135
|
-
try {
|
|
136
|
-
const result = spawnSync("npm", ["ls", "-g", PACKAGE_NAME, "--json"], {
|
|
137
|
-
encoding: "utf-8",
|
|
138
|
-
shell: true,
|
|
139
|
-
timeout: 5000,
|
|
140
|
-
})
|
|
141
|
-
if (result.stdout) {
|
|
142
|
-
const data = JSON.parse(result.stdout)
|
|
143
|
-
if (data.dependencies?.[PACKAGE_NAME]?.version) {
|
|
144
|
-
return data.dependencies[PACKAGE_NAME].version
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
} catch {
|
|
148
|
-
// ignore
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// Fallback para bun
|
|
152
|
-
try {
|
|
153
|
-
const bunResult = spawnSync("bun", ["pm", "ls", "-g"], {
|
|
154
|
-
encoding: "utf-8",
|
|
155
|
-
shell: true,
|
|
156
|
-
timeout: 5000,
|
|
157
|
-
})
|
|
158
|
-
if (bunResult.stdout) {
|
|
159
|
-
// Formato: "@nimbuslab/cli@0.14.0"
|
|
160
|
-
const match = bunResult.stdout.match(new RegExp(`${PACKAGE_NAME.replace("/", "\\/")}@([\\d.]+)`))
|
|
161
|
-
if (match?.[1]) {
|
|
162
|
-
return match[1]
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
} catch {
|
|
166
|
-
// ignore
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return "unknown"
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export async function update(args: string[]) {
|
|
173
|
-
// Parse flags
|
|
174
|
-
const forceFlag = args.includes("--force") || args.includes("-f")
|
|
175
|
-
const filteredArgs = args.filter(a => a !== "--force" && a !== "-f")
|
|
176
|
-
const flag = filteredArgs[0]
|
|
177
|
-
|
|
178
|
-
// nimbus update --list
|
|
179
|
-
if (flag === "--list" || flag === "-l") {
|
|
180
|
-
p.intro(pc.cyan("Versoes disponiveis"))
|
|
181
|
-
|
|
182
|
-
const spinner = p.spinner()
|
|
183
|
-
spinner.start("Buscando versoes...")
|
|
184
|
-
|
|
185
|
-
const versions = await getAvailableVersions()
|
|
186
|
-
spinner.stop("Versoes encontradas")
|
|
187
|
-
|
|
188
|
-
if (versions.length === 0) {
|
|
189
|
-
p.log.error("Nao foi possivel buscar as versoes")
|
|
190
|
-
return
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
const current = getCurrentVersion()
|
|
194
|
-
const pm = detectPackageManager()
|
|
195
|
-
|
|
196
|
-
console.log()
|
|
197
|
-
console.log(pc.bold("Ultimas 10 versoes:"))
|
|
198
|
-
versions.slice(0, 10).forEach((v, i) => {
|
|
199
|
-
const isCurrent = v === current
|
|
200
|
-
const prefix = isCurrent ? pc.green("-> ") : " "
|
|
201
|
-
const suffix = isCurrent ? pc.dim(" (instalada)") : ""
|
|
202
|
-
const isLatest = i === 0 ? pc.yellow(" (latest)") : ""
|
|
203
|
-
console.log(`${prefix}${v}${suffix}${isLatest}`)
|
|
204
|
-
})
|
|
205
|
-
console.log()
|
|
206
|
-
console.log(pc.dim(`Total: ${versions.length} versoes`))
|
|
207
|
-
console.log(pc.dim(`Package manager detectado: ${pm === "unknown" ? "nenhum" : pm}`))
|
|
208
|
-
console.log(pc.dim(`Instalar versao especifica: nimbus update <versao>`))
|
|
209
|
-
console.log(pc.dim(`Forcar reinstalacao: nimbus update --force`))
|
|
210
|
-
return
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// nimbus update [version]
|
|
214
|
-
const targetVersion = flag || "latest"
|
|
215
|
-
const isSpecificVersion = flag && flag !== "latest" && !flag.startsWith("-")
|
|
216
|
-
|
|
217
|
-
p.intro(pc.cyan(`Atualizando ${PACKAGE_NAME}`))
|
|
218
|
-
|
|
219
|
-
const spinner = p.spinner()
|
|
220
|
-
|
|
221
|
-
// Limpar instalacoes duplicadas automaticamente
|
|
222
|
-
spinner.start("Verificando instalacoes...")
|
|
223
|
-
const cleanup = cleanupDuplicateInstalls()
|
|
224
|
-
if (cleanup.cleaned) {
|
|
225
|
-
spinner.stop(pc.yellow(cleanup.message))
|
|
226
|
-
} else {
|
|
227
|
-
spinner.stop("OK")
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// Detectar package manager
|
|
231
|
-
spinner.start("Detectando package manager...")
|
|
232
|
-
const detectedPm = detectPackageManager()
|
|
233
|
-
// Usar npm como padrao se nenhum detectado (compativel com fnm/nvm)
|
|
234
|
-
const pm = detectedPm === "unknown" ? "npm" : detectedPm
|
|
235
|
-
spinner.stop(`Package manager: ${pm}${detectedPm === "unknown" ? " (padrao)" : ""}`)
|
|
236
|
-
|
|
237
|
-
// Verificar versao atual
|
|
238
|
-
spinner.start("Verificando versao atual...")
|
|
239
|
-
const currentVersion = getCurrentVersion()
|
|
240
|
-
spinner.stop(`Versao atual: ${currentVersion === "unknown" ? "nao instalado" : currentVersion}`)
|
|
241
|
-
|
|
242
|
-
// Verificar versao alvo
|
|
243
|
-
let latestVersion: string | null = null
|
|
244
|
-
if (!isSpecificVersion) {
|
|
245
|
-
spinner.start("Verificando ultima versao no npm...")
|
|
246
|
-
latestVersion = await getLatestVersion()
|
|
247
|
-
spinner.stop(`Ultima versao: ${latestVersion || "desconhecida"}`)
|
|
248
|
-
|
|
249
|
-
if (!forceFlag && latestVersion && latestVersion === currentVersion) {
|
|
250
|
-
p.log.success("Voce ja esta na ultima versao!")
|
|
251
|
-
console.log(pc.dim(" Use --force para reinstalar"))
|
|
252
|
-
return
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Confirmar
|
|
257
|
-
const versionText = isSpecificVersion ? targetVersion : (latestVersion || "latest")
|
|
258
|
-
const actionText = forceFlag ? "Reinstalar" : "Atualizar"
|
|
259
|
-
const confirmUpdate = await p.confirm({
|
|
260
|
-
message: `${actionText} para ${versionText} usando ${pm}?`,
|
|
261
|
-
initialValue: true,
|
|
262
|
-
})
|
|
263
|
-
|
|
264
|
-
if (p.isCancel(confirmUpdate) || !confirmUpdate) {
|
|
265
|
-
p.cancel("Atualizacao cancelada")
|
|
266
|
-
return
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// Executar update
|
|
270
|
-
spinner.start("Atualizando...")
|
|
271
|
-
|
|
272
|
-
try {
|
|
273
|
-
const packageSpec = isSpecificVersion
|
|
274
|
-
? `${PACKAGE_NAME}@${targetVersion}`
|
|
275
|
-
: latestVersion
|
|
276
|
-
? `${PACKAGE_NAME}@${latestVersion}`
|
|
277
|
-
: PACKAGE_NAME
|
|
278
|
-
|
|
279
|
-
// Usar o package manager detectado
|
|
280
|
-
if (pm === "bun") {
|
|
281
|
-
// Bun: remover primeiro se --force, depois instalar
|
|
282
|
-
if (forceFlag) {
|
|
283
|
-
try {
|
|
284
|
-
execSync(`bun remove -g ${PACKAGE_NAME}`, { stdio: "pipe", encoding: "utf-8" })
|
|
285
|
-
} catch {
|
|
286
|
-
// ignore - pode nao estar instalado
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
execSync(`bun add -g ${packageSpec}`, { stdio: "pipe", encoding: "utf-8" })
|
|
290
|
-
} else {
|
|
291
|
-
// npm: usar --force se solicitado
|
|
292
|
-
const forceArg = forceFlag ? " --force" : ""
|
|
293
|
-
execSync(`npm install -g ${packageSpec}${forceArg}`, { stdio: "pipe", encoding: "utf-8" })
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
spinner.stop("Atualizacao concluida!")
|
|
297
|
-
|
|
298
|
-
// Verificar nova versao
|
|
299
|
-
const newVersion = getCurrentVersion()
|
|
300
|
-
|
|
301
|
-
if (currentVersion === newVersion && !forceFlag) {
|
|
302
|
-
p.log.warn("Versao nao mudou. Tente com --force")
|
|
303
|
-
} else {
|
|
304
|
-
p.log.success(`${PACKAGE_NAME} atualizado: ${currentVersion} -> ${newVersion}`)
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
// Se usa fnm, avisar sobre hash
|
|
308
|
-
if (isUsingFnm()) {
|
|
309
|
-
console.log()
|
|
310
|
-
console.log(pc.yellow(" fnm detectado - execute para aplicar:"))
|
|
311
|
-
console.log(pc.cyan(" hash -r"))
|
|
312
|
-
console.log(pc.dim(" Ou abra um novo terminal."))
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
p.outro(pc.green("Pronto!"))
|
|
316
|
-
} catch (error) {
|
|
317
|
-
spinner.stop("Erro na atualizacao")
|
|
318
|
-
|
|
319
|
-
const err = error as Error & { stderr?: string }
|
|
320
|
-
p.log.error("Falha ao atualizar")
|
|
321
|
-
|
|
322
|
-
if (err.stderr) {
|
|
323
|
-
console.log(pc.dim(err.stderr))
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
console.log()
|
|
327
|
-
console.log(pc.yellow("Tente manualmente:"))
|
|
328
|
-
if (pm === "bun") {
|
|
329
|
-
console.log(pc.cyan(` bun add -g ${PACKAGE_NAME}${isSpecificVersion ? `@${targetVersion}` : ""}`))
|
|
330
|
-
} else {
|
|
331
|
-
console.log(pc.cyan(` npm install -g ${PACKAGE_NAME}${isSpecificVersion ? `@${targetVersion}` : ""}`))
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
}
|
package/src/commands/upgrade.ts
DELETED
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
import * as p from "@clack/prompts"
|
|
2
|
-
import pc from "picocolors"
|
|
3
|
-
import { analyze } from "./analyze"
|
|
4
|
-
|
|
5
|
-
interface UpgradePlan {
|
|
6
|
-
current: string
|
|
7
|
-
target: string
|
|
8
|
-
breakingChanges: string[]
|
|
9
|
-
steps: string[]
|
|
10
|
-
complexity: "low" | "medium" | "high"
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const UPGRADE_PLANS: Record<string, (currentVersion: string) => UpgradePlan | null> = {
|
|
14
|
-
next: (current) => {
|
|
15
|
-
const major = parseInt(current.replace(/[^0-9]/g, "").slice(0, 2))
|
|
16
|
-
if (major >= 16) return null
|
|
17
|
-
|
|
18
|
-
return {
|
|
19
|
-
current: current,
|
|
20
|
-
target: "16.x",
|
|
21
|
-
complexity: major < 15 ? "high" : "medium",
|
|
22
|
-
breakingChanges: [
|
|
23
|
-
"next/image: Mudancas na API de otimizacao",
|
|
24
|
-
"Middleware: Novo formato de config",
|
|
25
|
-
"next.config: Algumas opcoes depreciadas",
|
|
26
|
-
"Turbopack: Agora e o bundler padrao",
|
|
27
|
-
],
|
|
28
|
-
steps: [
|
|
29
|
-
"Atualizar next para ^16.0.0",
|
|
30
|
-
"Atualizar react para ^19.0.0",
|
|
31
|
-
"Atualizar react-dom para ^19.0.0",
|
|
32
|
-
"Revisar next.config.ts",
|
|
33
|
-
"Testar build: bun run build",
|
|
34
|
-
"Testar dev: bun dev",
|
|
35
|
-
],
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
react: (current) => {
|
|
40
|
-
if (current.startsWith("19") || current.startsWith("^19")) return null
|
|
41
|
-
|
|
42
|
-
return {
|
|
43
|
-
current: current,
|
|
44
|
-
target: "19.x",
|
|
45
|
-
complexity: "medium",
|
|
46
|
-
breakingChanges: [
|
|
47
|
-
"forwardRef: Nao mais necessario, ref e prop regular",
|
|
48
|
-
"useContext: Pode ser substituido por use(Context)",
|
|
49
|
-
"Suspense: Mudancas em fallback behavior",
|
|
50
|
-
"Async components: Novo suporte nativo",
|
|
51
|
-
],
|
|
52
|
-
steps: [
|
|
53
|
-
"Atualizar react para ^19.0.0",
|
|
54
|
-
"Atualizar react-dom para ^19.0.0",
|
|
55
|
-
"Atualizar @types/react para ^19.0.0",
|
|
56
|
-
"Remover forwardRef (usar ref como prop)",
|
|
57
|
-
"Revisar Suspense boundaries",
|
|
58
|
-
"Testar todos os componentes",
|
|
59
|
-
],
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
tailwind: (current) => {
|
|
64
|
-
if (current.startsWith("4") || current.startsWith("^4")) return null
|
|
65
|
-
|
|
66
|
-
return {
|
|
67
|
-
current: current,
|
|
68
|
-
target: "4.x",
|
|
69
|
-
complexity: "medium",
|
|
70
|
-
breakingChanges: [
|
|
71
|
-
"Config: Agora e CSS-first (nao mais tailwind.config.js)",
|
|
72
|
-
"@apply: Sintaxe mudou",
|
|
73
|
-
"Cores: Novo sistema de tokens",
|
|
74
|
-
"Plugins: API diferente",
|
|
75
|
-
],
|
|
76
|
-
steps: [
|
|
77
|
-
"Atualizar tailwindcss para ^4.0.0",
|
|
78
|
-
"Converter tailwind.config.js para CSS",
|
|
79
|
-
"Atualizar globals.css com @import 'tailwindcss'",
|
|
80
|
-
"Revisar @apply usages",
|
|
81
|
-
"Atualizar plugins para v4",
|
|
82
|
-
"Testar todas as paginas",
|
|
83
|
-
],
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
|
|
87
|
-
bun: () => ({
|
|
88
|
-
current: "pnpm/npm/yarn",
|
|
89
|
-
target: "bun",
|
|
90
|
-
complexity: "low",
|
|
91
|
-
breakingChanges: [
|
|
92
|
-
"Lockfile: Formato diferente (bun.lockb)",
|
|
93
|
-
"Scripts: Alguns podem precisar ajuste",
|
|
94
|
-
"Workspaces: Sintaxe levemente diferente",
|
|
95
|
-
],
|
|
96
|
-
steps: [
|
|
97
|
-
"Remover node_modules",
|
|
98
|
-
"Remover pnpm-lock.yaml / package-lock.json / yarn.lock",
|
|
99
|
-
"Executar: bun install",
|
|
100
|
-
"Atualizar scripts no package.json (npx -> bunx)",
|
|
101
|
-
"Atualizar CI/CD configs",
|
|
102
|
-
"Testar: bun dev, bun build",
|
|
103
|
-
],
|
|
104
|
-
}),
|
|
105
|
-
|
|
106
|
-
drizzle: () => ({
|
|
107
|
-
current: "prisma",
|
|
108
|
-
target: "drizzle",
|
|
109
|
-
complexity: "high",
|
|
110
|
-
breakingChanges: [
|
|
111
|
-
"Schema: Formato TypeScript (nao mais .prisma)",
|
|
112
|
-
"Queries: API completamente diferente",
|
|
113
|
-
"Migrations: Sistema diferente",
|
|
114
|
-
"Relations: Declaracao diferente",
|
|
115
|
-
],
|
|
116
|
-
steps: [
|
|
117
|
-
"Instalar drizzle-orm e drizzle-kit",
|
|
118
|
-
"Converter schema.prisma para drizzle/schema.ts",
|
|
119
|
-
"Configurar drizzle.config.ts",
|
|
120
|
-
"Gerar migrations: bunx drizzle-kit generate",
|
|
121
|
-
"Atualizar todas as queries",
|
|
122
|
-
"Atualizar auth config (se usar)",
|
|
123
|
-
"Remover @prisma/client e prisma",
|
|
124
|
-
"Testar todas as operacoes de banco",
|
|
125
|
-
],
|
|
126
|
-
}),
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export async function upgrade(args: string[]) {
|
|
130
|
-
const showPlan = args.includes("--plan")
|
|
131
|
-
const target = args.find(a => !a.startsWith("-"))
|
|
132
|
-
|
|
133
|
-
console.log()
|
|
134
|
-
|
|
135
|
-
if (showPlan || !target) {
|
|
136
|
-
// Analyze first
|
|
137
|
-
console.log(pc.cyan(" Analisando projeto para plano de upgrade..."))
|
|
138
|
-
console.log()
|
|
139
|
-
|
|
140
|
-
const analysis = await analyze([".", "--quiet"])
|
|
141
|
-
|
|
142
|
-
console.log(pc.bold(" Upgrades Disponiveis:"))
|
|
143
|
-
console.log()
|
|
144
|
-
|
|
145
|
-
let hasUpgrades = false
|
|
146
|
-
|
|
147
|
-
// Check Next.js
|
|
148
|
-
if (analysis.frameworkVersion && analysis.framework === "nextjs") {
|
|
149
|
-
const planFn = UPGRADE_PLANS["next"]
|
|
150
|
-
if (planFn) {
|
|
151
|
-
const plan = planFn(analysis.frameworkVersion)
|
|
152
|
-
if (plan) {
|
|
153
|
-
hasUpgrades = true
|
|
154
|
-
printUpgradePlan("Next.js", plan)
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Check React
|
|
160
|
-
if (analysis.dependencies["react"]) {
|
|
161
|
-
const planFn = UPGRADE_PLANS["react"]
|
|
162
|
-
if (planFn) {
|
|
163
|
-
const plan = planFn(analysis.dependencies["react"])
|
|
164
|
-
if (plan) {
|
|
165
|
-
hasUpgrades = true
|
|
166
|
-
printUpgradePlan("React", plan)
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// Check Tailwind
|
|
172
|
-
const tailwindDep = analysis.dependencies["tailwindcss"] || analysis.devDependencies["tailwindcss"]
|
|
173
|
-
if (tailwindDep) {
|
|
174
|
-
const planFn = UPGRADE_PLANS["tailwind"]
|
|
175
|
-
if (planFn) {
|
|
176
|
-
const plan = planFn(tailwindDep)
|
|
177
|
-
if (plan) {
|
|
178
|
-
hasUpgrades = true
|
|
179
|
-
printUpgradePlan("Tailwind CSS", plan)
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// Check package manager
|
|
185
|
-
if (analysis.packageManager !== "bun") {
|
|
186
|
-
const planFn = UPGRADE_PLANS["bun"]
|
|
187
|
-
if (planFn) {
|
|
188
|
-
const plan = planFn("")
|
|
189
|
-
if (plan) {
|
|
190
|
-
hasUpgrades = true
|
|
191
|
-
printUpgradePlan("Package Manager", plan)
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// Check Prisma -> Drizzle
|
|
197
|
-
if (analysis.database === "prisma") {
|
|
198
|
-
const planFn = UPGRADE_PLANS["drizzle"]
|
|
199
|
-
if (planFn) {
|
|
200
|
-
const plan = planFn("")
|
|
201
|
-
if (plan) {
|
|
202
|
-
hasUpgrades = true
|
|
203
|
-
printUpgradePlan("Database", plan)
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
if (!hasUpgrades) {
|
|
209
|
-
console.log(pc.green(" Projeto ja esta atualizado!"))
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
console.log()
|
|
213
|
-
console.log(pc.dim(" Para executar um upgrade especifico:"))
|
|
214
|
-
console.log(pc.dim(" nimbus upgrade next"))
|
|
215
|
-
console.log(pc.dim(" nimbus upgrade tailwind"))
|
|
216
|
-
console.log(pc.dim(" nimbus upgrade bun"))
|
|
217
|
-
console.log()
|
|
218
|
-
|
|
219
|
-
return
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// Execute specific upgrade
|
|
223
|
-
console.log(pc.yellow(` Upgrade ${target} ainda nao implementado.`))
|
|
224
|
-
console.log(pc.dim(" Por enquanto, siga os passos do --plan manualmente."))
|
|
225
|
-
console.log()
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function printUpgradePlan(name: string, plan: UpgradePlan) {
|
|
229
|
-
const complexityColor = {
|
|
230
|
-
low: pc.green,
|
|
231
|
-
medium: pc.yellow,
|
|
232
|
-
high: pc.red,
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
console.log(` ${pc.bold(name)}`)
|
|
236
|
-
console.log(` ${pc.dim("Atual:")} ${plan.current} ${pc.dim("->")} ${pc.cyan(plan.target)}`)
|
|
237
|
-
console.log(` ${pc.dim("Complexidade:")} ${complexityColor[plan.complexity](plan.complexity)}`)
|
|
238
|
-
console.log()
|
|
239
|
-
|
|
240
|
-
console.log(` ${pc.dim("Breaking Changes:")}`)
|
|
241
|
-
plan.breakingChanges.forEach(bc => {
|
|
242
|
-
console.log(` ${pc.yellow("!")} ${bc}`)
|
|
243
|
-
})
|
|
244
|
-
console.log()
|
|
245
|
-
|
|
246
|
-
console.log(` ${pc.dim("Passos:")}`)
|
|
247
|
-
plan.steps.forEach((step, i) => {
|
|
248
|
-
console.log(` ${pc.dim(`${i + 1}.`)} ${step}`)
|
|
249
|
-
})
|
|
250
|
-
console.log()
|
|
251
|
-
}
|