@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/docs/package.md
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
# nimbus create --package
|
|
2
|
-
|
|
3
|
-
Cria um pacote npm pronto para publicar.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Uso
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
nimbus create meu-pacote --package
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## Estrutura gerada
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
meu-pacote/
|
|
19
|
-
├── src/
|
|
20
|
-
│ └── index.ts # Entry point
|
|
21
|
-
├── dist/ # Build output (gitignored)
|
|
22
|
-
├── package.json # Configurado para npm
|
|
23
|
-
├── tsconfig.json # TypeScript config
|
|
24
|
-
├── tsup.config.ts # Build config
|
|
25
|
-
├── README.md # Documentacao
|
|
26
|
-
├── CHANGELOG.md # Historico de versoes
|
|
27
|
-
├── LICENSE # MIT
|
|
28
|
-
└── .github/
|
|
29
|
-
└── workflows/
|
|
30
|
-
└── publish.yml # CI/CD para npm
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## package.json
|
|
36
|
-
|
|
37
|
-
```json
|
|
38
|
-
{
|
|
39
|
-
"name": "@nimbuslab/meu-pacote",
|
|
40
|
-
"version": "0.1.0",
|
|
41
|
-
"type": "module",
|
|
42
|
-
"main": "./dist/index.js",
|
|
43
|
-
"module": "./dist/index.mjs",
|
|
44
|
-
"types": "./dist/index.d.ts",
|
|
45
|
-
"exports": {
|
|
46
|
-
".": {
|
|
47
|
-
"import": "./dist/index.mjs",
|
|
48
|
-
"require": "./dist/index.js",
|
|
49
|
-
"types": "./dist/index.d.ts"
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
|
-
"files": ["dist"],
|
|
53
|
-
"scripts": {
|
|
54
|
-
"build": "tsup",
|
|
55
|
-
"dev": "tsup --watch",
|
|
56
|
-
"prepublishOnly": "bun run build"
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
---
|
|
62
|
-
|
|
63
|
-
## Build com tsup
|
|
64
|
-
|
|
65
|
-
O template usa [tsup](https://tsup.egoist.dev/) para build:
|
|
66
|
-
|
|
67
|
-
```typescript
|
|
68
|
-
// tsup.config.ts
|
|
69
|
-
import { defineConfig } from "tsup"
|
|
70
|
-
|
|
71
|
-
export default defineConfig({
|
|
72
|
-
entry: ["src/index.ts"],
|
|
73
|
-
format: ["cjs", "esm"],
|
|
74
|
-
dts: true,
|
|
75
|
-
clean: true,
|
|
76
|
-
minify: true,
|
|
77
|
-
})
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
**Por que tsup?**
|
|
81
|
-
- Zero config
|
|
82
|
-
- ESM + CJS em um comando
|
|
83
|
-
- TypeScript declarations automaticas
|
|
84
|
-
- Rapido (usa esbuild)
|
|
85
|
-
|
|
86
|
-
---
|
|
87
|
-
|
|
88
|
-
## Workflow de desenvolvimento
|
|
89
|
-
|
|
90
|
-
### 1. Desenvolver
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
cd meu-pacote
|
|
94
|
-
bun run dev # Watch mode
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### 2. Testar localmente
|
|
98
|
-
|
|
99
|
-
```bash
|
|
100
|
-
# Em outro projeto
|
|
101
|
-
bun add ../meu-pacote
|
|
102
|
-
|
|
103
|
-
# Ou com link
|
|
104
|
-
cd meu-pacote && bun link
|
|
105
|
-
cd outro-projeto && bun link @nimbuslab/meu-pacote
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### 3. Build
|
|
109
|
-
|
|
110
|
-
```bash
|
|
111
|
-
bun run build
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### 4. Publicar
|
|
115
|
-
|
|
116
|
-
```bash
|
|
117
|
-
# Bump version
|
|
118
|
-
npm version patch # 0.1.0 -> 0.1.1
|
|
119
|
-
npm version minor # 0.1.0 -> 0.2.0
|
|
120
|
-
npm version major # 0.1.0 -> 1.0.0
|
|
121
|
-
|
|
122
|
-
# Publicar
|
|
123
|
-
npm publish --access public
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
---
|
|
127
|
-
|
|
128
|
-
## CI/CD automatico
|
|
129
|
-
|
|
130
|
-
O template inclui GitHub Action para publicar automaticamente:
|
|
131
|
-
|
|
132
|
-
```yaml
|
|
133
|
-
# .github/workflows/publish.yml
|
|
134
|
-
name: Publish
|
|
135
|
-
|
|
136
|
-
on:
|
|
137
|
-
push:
|
|
138
|
-
tags:
|
|
139
|
-
- "v*"
|
|
140
|
-
|
|
141
|
-
jobs:
|
|
142
|
-
publish:
|
|
143
|
-
runs-on: ubuntu-latest
|
|
144
|
-
steps:
|
|
145
|
-
- uses: actions/checkout@v4
|
|
146
|
-
- uses: oven-sh/setup-bun@v1
|
|
147
|
-
- run: bun install
|
|
148
|
-
- run: bun run build
|
|
149
|
-
- run: npm publish --access public
|
|
150
|
-
env:
|
|
151
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
**Para usar:**
|
|
155
|
-
1. Criar token em npmjs.com
|
|
156
|
-
2. Adicionar `NPM_TOKEN` nos secrets do repo
|
|
157
|
-
3. Criar tag: `git tag v0.1.0 && git push --tags`
|
|
158
|
-
|
|
159
|
-
---
|
|
160
|
-
|
|
161
|
-
## Escopo @nimbuslab
|
|
162
|
-
|
|
163
|
-
Para publicar no escopo `@nimbuslab`:
|
|
164
|
-
|
|
165
|
-
```bash
|
|
166
|
-
# Primeira vez: logar no npm
|
|
167
|
-
npm login
|
|
168
|
-
|
|
169
|
-
# Verificar organizacao
|
|
170
|
-
npm org ls nimbuslab
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
**Nota:** Pacotes com escopo precisam de `--access public` para serem publicos.
|
|
174
|
-
|
|
175
|
-
---
|
|
176
|
-
|
|
177
|
-
## Boas praticas
|
|
178
|
-
|
|
179
|
-
### Versionamento (SemVer)
|
|
180
|
-
|
|
181
|
-
| Tipo | Quando usar | Exemplo |
|
|
182
|
-
|------|-------------|---------|
|
|
183
|
-
| `patch` | Bug fixes | 0.1.0 -> 0.1.1 |
|
|
184
|
-
| `minor` | Novas features (retrocompativeis) | 0.1.0 -> 0.2.0 |
|
|
185
|
-
| `major` | Breaking changes | 0.1.0 -> 1.0.0 |
|
|
186
|
-
|
|
187
|
-
### CHANGELOG
|
|
188
|
-
|
|
189
|
-
Manter atualizado com cada release:
|
|
190
|
-
|
|
191
|
-
```markdown
|
|
192
|
-
# Changelog
|
|
193
|
-
|
|
194
|
-
## [0.2.0] - 2026-01-28
|
|
195
|
-
|
|
196
|
-
### Added
|
|
197
|
-
- Nova funcionalidade X
|
|
198
|
-
|
|
199
|
-
### Fixed
|
|
200
|
-
- Bug Y corrigido
|
|
201
|
-
|
|
202
|
-
## [0.1.0] - 2026-01-27
|
|
203
|
-
|
|
204
|
-
- Release inicial
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
### README
|
|
208
|
-
|
|
209
|
-
Incluir:
|
|
210
|
-
- O que o pacote faz
|
|
211
|
-
- Como instalar
|
|
212
|
-
- Como usar (exemplos)
|
|
213
|
-
- API reference
|
|
214
|
-
- License
|
|
215
|
-
|
|
216
|
-
---
|
|
217
|
-
|
|
218
|
-
## Exemplos de pacotes
|
|
219
|
-
|
|
220
|
-
| Pacote | Descricao |
|
|
221
|
-
|--------|-----------|
|
|
222
|
-
| `@nimbuslab/cli` | CLI oficial |
|
|
223
|
-
| `@nimbuslab/utils` | Utilitarios compartilhados |
|
|
224
|
-
| `@nimbuslab/ui` | Design system |
|
|
225
|
-
| `@nimbuslab/config` | Configs compartilhadas |
|
|
226
|
-
|
|
227
|
-
---
|
|
228
|
-
|
|
229
|
-
[Voltar ao README](../README.md) | [create](./create.md) | [analyze](./analyze.md)
|
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)
|
package/src/commands/analyze.ts
DELETED
|
@@ -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
|
-
}
|