@nimbuslab/cli 0.16.3 → 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/docs/upgrade.md DELETED
@@ -1,152 +0,0 @@
1
- # nimbus upgrade
2
-
3
- Planeja e executa upgrades de dependencias para a stack nimbuslab.
4
-
5
- ## Uso
6
-
7
- ```bash
8
- # Ver plano completo de upgrades
9
- nimbus upgrade --plan
10
-
11
- # Upgrade especifico (em desenvolvimento)
12
- nimbus upgrade next
13
- nimbus upgrade react
14
- nimbus upgrade tailwind
15
- nimbus upgrade bun
16
- ```
17
-
18
- ## Upgrades Suportados
19
-
20
- ### Next.js 14/15 -> 16
21
-
22
- | Aspecto | Detalhes |
23
- |---------|----------|
24
- | Complexidade | Media |
25
- | Breaking Changes | next/image API, middleware, turbopack |
26
- | Tempo Estimado | 1-2 horas |
27
-
28
- **Passos:**
29
- 1. Atualizar next para ^16.0.0
30
- 2. Atualizar react para ^19.0.0
31
- 3. Atualizar react-dom para ^19.0.0
32
- 4. Revisar next.config.ts
33
- 5. Testar build e dev
34
-
35
- ### React 18 -> 19
36
-
37
- | Aspecto | Detalhes |
38
- |---------|----------|
39
- | Complexidade | Media |
40
- | Breaking Changes | forwardRef, Suspense, async components |
41
- | Tempo Estimado | 1-2 horas |
42
-
43
- **Passos:**
44
- 1. Atualizar react e react-dom para ^19.0.0
45
- 2. Remover forwardRef (ref agora e prop regular)
46
- 3. Atualizar @types/react
47
- 4. Revisar Suspense boundaries
48
-
49
- ### Tailwind 3 -> 4
50
-
51
- | Aspecto | Detalhes |
52
- |---------|----------|
53
- | Complexidade | Media |
54
- | Breaking Changes | Config em CSS, @apply syntax |
55
- | Tempo Estimado | 2-4 horas |
56
-
57
- **Passos:**
58
- 1. Atualizar tailwindcss para ^4.0.0
59
- 2. Converter tailwind.config.js para CSS
60
- 3. Atualizar globals.css com @import 'tailwindcss'
61
- 4. Revisar @apply usages
62
- 5. Atualizar plugins
63
-
64
- ### pnpm/npm/yarn -> bun
65
-
66
- | Aspecto | Detalhes |
67
- |---------|----------|
68
- | Complexidade | Baixa |
69
- | Breaking Changes | Lockfile, alguns scripts |
70
- | Tempo Estimado | 30 min |
71
-
72
- **Passos:**
73
- 1. Remover node_modules
74
- 2. Remover lockfile antigo
75
- 3. Executar bun install
76
- 4. Atualizar scripts (npx -> bunx)
77
- 5. Atualizar CI/CD
78
-
79
- ### Prisma -> Drizzle
80
-
81
- | Aspecto | Detalhes |
82
- |---------|----------|
83
- | Complexidade | Alta |
84
- | Breaking Changes | Schema, queries, migrations |
85
- | Tempo Estimado | 4-8 horas |
86
-
87
- **Passos:**
88
- 1. Instalar drizzle-orm e drizzle-kit
89
- 2. Converter schema.prisma para drizzle
90
- 3. Configurar drizzle.config.ts
91
- 4. Gerar migrations
92
- 5. Atualizar todas as queries
93
- 6. Atualizar auth config
94
-
95
- ## Exemplo de Output
96
-
97
- ```
98
- Upgrades Disponiveis:
99
-
100
- Next.js
101
- Atual: 15.0.2 -> 16.x
102
- Complexidade: media
103
-
104
- Breaking Changes:
105
- ! next/image: Mudancas na API de otimizacao
106
- ! Middleware: Novo formato de config
107
- ! Turbopack: Agora e o bundler padrao
108
-
109
- Passos:
110
- 1. Atualizar next para ^16.0.0
111
- 2. Atualizar react para ^19.0.0
112
- 3. Revisar next.config.ts
113
- 4. Testar build: bun run build
114
-
115
- React
116
- Atual: 18.2.0 -> 19.x
117
- Complexidade: media
118
-
119
- Breaking Changes:
120
- ! forwardRef: Nao mais necessario
121
- ! Suspense: Mudancas em fallback
122
- ! Async components: Novo suporte
123
-
124
- Passos:
125
- 1. Atualizar react para ^19.0.0
126
- 2. Remover forwardRef
127
- 3. Revisar Suspense boundaries
128
- ```
129
-
130
- ## Codemods (Em Desenvolvimento)
131
-
132
- Codemods sao transformacoes automaticas de codigo usando AST:
133
-
134
- ```bash
135
- # Futuros comandos
136
- nimbus codemod tailwind-v4 # Transforma Tailwind 3 -> 4
137
- nimbus codemod react-19 # Transforma React 18 -> 19
138
- nimbus codemod drizzle # Transforma Prisma -> Drizzle
139
- nimbus codemod bun # Transforma para Bun
140
- ```
141
-
142
- ## Estrategia de Upgrade
143
-
144
- 1. **Sempre** fazer backup/branch antes
145
- 2. **Sempre** rodar `nimbus analyze` primeiro
146
- 3. **Sempre** testar apos cada upgrade
147
- 4. **Nunca** fazer todos os upgrades de uma vez
148
- 5. **Preferir** ordem: bun -> tailwind -> react -> next
149
-
150
- ---
151
-
152
- [Voltar ao README](../README.md) | [create](./create.md) | [analyze](./analyze.md) | [migrate](./migrate.md)
@@ -1,210 +0,0 @@
1
- import * as p from "@clack/prompts"
2
- import pc from "picocolors"
3
- import { existsSync, readFileSync } from "node:fs"
4
- import { join } from "node:path"
5
-
6
- interface AnalysisResult {
7
- name: string
8
- version: string
9
- framework: string | null
10
- frameworkVersion: string | null
11
- styling: string[]
12
- packageManager: string
13
- monorepo: string | null
14
- auth: string | null
15
- database: string | null
16
- typescript: boolean
17
- dependencies: Record<string, string>
18
- devDependencies: Record<string, string>
19
- recommendations: string[]
20
- }
21
-
22
- function detectPackageManager(dir: string): string {
23
- if (existsSync(join(dir, "bun.lockb"))) return "bun"
24
- if (existsSync(join(dir, "pnpm-lock.yaml"))) return "pnpm"
25
- if (existsSync(join(dir, "yarn.lock"))) return "yarn"
26
- if (existsSync(join(dir, "package-lock.json"))) return "npm"
27
- return "unknown"
28
- }
29
-
30
- function detectMonorepo(dir: string, pkg: any): string | null {
31
- if (existsSync(join(dir, "turbo.json"))) return "turborepo"
32
- if (existsSync(join(dir, "nx.json"))) return "nx"
33
- if (existsSync(join(dir, "lerna.json"))) return "lerna"
34
- if (pkg.workspaces) return "workspaces"
35
- return null
36
- }
37
-
38
- function detectFramework(deps: Record<string, string>): { name: string | null; version: string | null } {
39
- if (deps["next"]) return { name: "nextjs", version: deps["next"] }
40
- if (deps["@angular/core"]) return { name: "angular", version: deps["@angular/core"] }
41
- if (deps["vue"]) return { name: "vue", version: deps["vue"] }
42
- if (deps["svelte"]) return { name: "svelte", version: deps["svelte"] }
43
- if (deps["react"] && !deps["next"]) return { name: "react", version: deps["react"] }
44
- return { name: null, version: null }
45
- }
46
-
47
- function detectStyling(deps: Record<string, string>, devDeps: Record<string, string>): string[] {
48
- const styling: string[] = []
49
- const allDeps = { ...deps, ...devDeps }
50
-
51
- if (allDeps["tailwindcss"]) styling.push(`tailwind@${allDeps["tailwindcss"]}`)
52
- if (allDeps["styled-components"]) styling.push("styled-components")
53
- if (allDeps["@emotion/react"]) styling.push("emotion")
54
- if (allDeps["sass"]) styling.push("sass")
55
- if (allDeps["less"]) styling.push("less")
56
-
57
- return styling.length > 0 ? styling : ["css"]
58
- }
59
-
60
- function detectAuth(deps: Record<string, string>): string | null {
61
- if (deps["better-auth"]) return "better-auth"
62
- if (deps["next-auth"]) return "next-auth"
63
- if (deps["@clerk/nextjs"]) return "clerk"
64
- if (deps["@auth0/nextjs-auth0"]) return "auth0"
65
- if (deps["@supabase/supabase-js"]) return "supabase"
66
- return null
67
- }
68
-
69
- function detectDatabase(deps: Record<string, string>): string | null {
70
- if (deps["drizzle-orm"]) return "drizzle"
71
- if (deps["@prisma/client"]) return "prisma"
72
- if (deps["typeorm"]) return "typeorm"
73
- if (deps["mongoose"]) return "mongoose"
74
- if (deps["pg"]) return "pg"
75
- if (deps["mysql2"]) return "mysql"
76
- return null
77
- }
78
-
79
- function generateRecommendations(result: AnalysisResult): string[] {
80
- const recs: string[] = []
81
-
82
- // Package manager
83
- if (result.packageManager !== "bun") {
84
- recs.push(`Migrar ${result.packageManager} -> bun (nimbus codemod bun)`)
85
- }
86
-
87
- // Framework version
88
- if (result.framework === "nextjs" && result.frameworkVersion) {
89
- const majorVersion = parseInt(result.frameworkVersion.replace(/[^0-9]/g, "").slice(0, 2))
90
- if (majorVersion < 16) {
91
- recs.push(`Atualizar Next.js ${result.frameworkVersion} -> 16 (nimbus upgrade next)`)
92
- }
93
- }
94
-
95
- // Tailwind
96
- const tailwind = result.styling.find(s => s.startsWith("tailwind"))
97
- if (tailwind) {
98
- const version = tailwind.split("@")[1] || ""
99
- if (version.startsWith("3")) {
100
- recs.push(`Atualizar Tailwind 3 -> 4 (nimbus upgrade tailwind)`)
101
- }
102
- } else if (!result.styling.includes("tailwind")) {
103
- recs.push(`Considerar adicionar Tailwind CSS (nimbus add tailwind)`)
104
- }
105
-
106
- // React version
107
- if (result.dependencies["react"]) {
108
- const reactVersion = result.dependencies["react"]
109
- if (reactVersion.startsWith("18") || reactVersion.startsWith("^18")) {
110
- recs.push(`Atualizar React 18 -> 19 (nimbus upgrade react)`)
111
- }
112
- }
113
-
114
- // Database
115
- if (result.database === "prisma") {
116
- recs.push(`Considerar migrar Prisma -> Drizzle (nimbus codemod drizzle)`)
117
- } else if (!result.database && result.framework === "nextjs") {
118
- recs.push(`Considerar adicionar banco de dados (nimbus add db)`)
119
- }
120
-
121
- // Auth
122
- if (!result.auth && result.framework === "nextjs") {
123
- recs.push(`Considerar adicionar autenticacao (nimbus add auth)`)
124
- } else if (result.auth === "next-auth") {
125
- recs.push(`Considerar migrar NextAuth -> Better Auth`)
126
- }
127
-
128
- // Monorepo
129
- if (result.monorepo === "workspaces" && !result.monorepo) {
130
- recs.push(`Considerar usar Turborepo para monorepo (nimbus add monorepo)`)
131
- }
132
-
133
- return recs
134
- }
135
-
136
- export async function analyze(args: string[]) {
137
- const targetDir = args[0] || "."
138
- const absoluteDir = targetDir.startsWith("/") ? targetDir : join(process.cwd(), targetDir)
139
-
140
- console.log()
141
- console.log(pc.cyan(" Analisando projeto..."))
142
- console.log()
143
-
144
- // Check if package.json exists
145
- const pkgPath = join(absoluteDir, "package.json")
146
- if (!existsSync(pkgPath)) {
147
- console.log(pc.red(" Erro: package.json nao encontrado"))
148
- console.log(pc.dim(` Diretorio: ${absoluteDir}`))
149
- process.exit(1)
150
- }
151
-
152
- // Read package.json
153
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"))
154
- const deps = pkg.dependencies || {}
155
- const devDeps = pkg.devDependencies || {}
156
-
157
- // Detect everything
158
- const framework = detectFramework(deps)
159
- const result: AnalysisResult = {
160
- name: pkg.name || "unknown",
161
- version: pkg.version || "0.0.0",
162
- framework: framework.name,
163
- frameworkVersion: framework.version,
164
- styling: detectStyling(deps, devDeps),
165
- packageManager: detectPackageManager(absoluteDir),
166
- monorepo: detectMonorepo(absoluteDir, pkg),
167
- auth: detectAuth(deps),
168
- database: detectDatabase(deps),
169
- typescript: existsSync(join(absoluteDir, "tsconfig.json")),
170
- dependencies: deps,
171
- devDependencies: devDeps,
172
- recommendations: [],
173
- }
174
-
175
- // Generate recommendations
176
- result.recommendations = generateRecommendations(result)
177
-
178
- // Display results
179
- console.log(pc.bold(" Projeto: ") + pc.cyan(result.name) + pc.dim(` v${result.version}`))
180
- console.log()
181
-
182
- console.log(pc.bold(" Stack Detectada:"))
183
- console.log(` Framework: ${result.framework ? pc.green(result.framework + "@" + result.frameworkVersion) : pc.dim("nenhum")}`)
184
- console.log(` Styling: ${result.styling.map(s => pc.green(s)).join(", ")}`)
185
- console.log(` Package Manager: ${result.packageManager === "bun" ? pc.green(result.packageManager) : pc.yellow(result.packageManager)}`)
186
- console.log(` TypeScript: ${result.typescript ? pc.green("sim") : pc.dim("nao")}`)
187
- console.log(` Monorepo: ${result.monorepo ? pc.green(result.monorepo) : pc.dim("nao")}`)
188
- console.log(` Auth: ${result.auth ? pc.green(result.auth) : pc.dim("nenhum")}`)
189
- console.log(` Database: ${result.database ? pc.green(result.database) : pc.dim("nenhum")}`)
190
- console.log()
191
-
192
- if (result.recommendations.length > 0) {
193
- console.log(pc.bold(" Recomendacoes:"))
194
- result.recommendations.forEach((rec, i) => {
195
- console.log(pc.yellow(` ${i + 1}. ${rec}`))
196
- })
197
- console.log()
198
- } else {
199
- console.log(pc.green(" Projeto ja esta na stack recomendada!"))
200
- console.log()
201
- }
202
-
203
- // JSON output option
204
- if (args.includes("--json")) {
205
- console.log(pc.dim(" JSON:"))
206
- console.log(JSON.stringify(result, null, 2))
207
- }
208
-
209
- return result
210
- }