vireum-spec-cli 0.2.0 → 0.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/commands/retrofit.js +47 -33
- package/package.json +1 -1
|
@@ -114,11 +114,11 @@ async function runRetrofit() {
|
|
|
114
114
|
default: false,
|
|
115
115
|
});
|
|
116
116
|
const featuresAtivas = await (0, prompts_1.input)({
|
|
117
|
-
message: 'Liste as funcionalidades JA implementadas (separadas por virgula):',
|
|
118
|
-
default: analise.features.join(', '),
|
|
117
|
+
message: 'Liste as funcionalidades JA implementadas (separadas por virgula — Enter para pular):',
|
|
118
|
+
default: analise.features.length ? analise.features.join(', ') : '',
|
|
119
119
|
});
|
|
120
120
|
const featuresPendentes = await (0, prompts_1.input)({
|
|
121
|
-
message: 'Liste as funcionalidades PENDENTES
|
|
121
|
+
message: 'Liste as funcionalidades PENDENTES (separadas por virgula — Enter para pular):',
|
|
122
122
|
});
|
|
123
123
|
const riscos = await (0, prompts_1.input)({
|
|
124
124
|
message: 'Riscos tecnicos identificados:',
|
|
@@ -128,8 +128,8 @@ async function runRetrofit() {
|
|
|
128
128
|
const dados = {
|
|
129
129
|
projeto, cliente, objetivo, problema, prioridade,
|
|
130
130
|
usuarios, regras, fase, multiTenant, lgpd,
|
|
131
|
-
featuresAtivas: featuresAtivas.split(',').map(f => f.trim()).filter(Boolean),
|
|
132
|
-
featuresPendentes: featuresPendentes.split(',').map(f => f.trim()).filter(Boolean),
|
|
131
|
+
featuresAtivas: featuresAtivas ? featuresAtivas.split(',').map(f => f.trim()).filter(Boolean) : [],
|
|
132
|
+
featuresPendentes: featuresPendentes ? featuresPendentes.split(',').map(f => f.trim()).filter(Boolean) : [],
|
|
133
133
|
riscos, analise,
|
|
134
134
|
data: new Date().toLocaleDateString('pt-BR'),
|
|
135
135
|
};
|
|
@@ -154,7 +154,6 @@ async function runRetrofit() {
|
|
|
154
154
|
fs.writeFileSync(path.join(specDir, arq.nome), arq.conteudo, 'utf-8');
|
|
155
155
|
s.succeed(arq.nome);
|
|
156
156
|
}
|
|
157
|
-
// tasks
|
|
158
157
|
const s1 = (0, ora_1.default)('Gerando tasks...').start();
|
|
159
158
|
await sleep(400);
|
|
160
159
|
fs.writeFileSync(path.join(tasksDir, 'active.md'), gerarTasksActive(dados), 'utf-8');
|
|
@@ -185,7 +184,6 @@ function analisarProjeto(cwd) {
|
|
|
185
184
|
cache: '',
|
|
186
185
|
},
|
|
187
186
|
};
|
|
188
|
-
// package.json
|
|
189
187
|
const pkgPath = path.join(cwd, 'package.json');
|
|
190
188
|
if (fs.existsSync(pkgPath)) {
|
|
191
189
|
try {
|
|
@@ -193,7 +191,6 @@ function analisarProjeto(cwd) {
|
|
|
193
191
|
resultado.nome = pkg.name || '';
|
|
194
192
|
resultado.descricao = pkg.description || '';
|
|
195
193
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
196
|
-
// Frontend
|
|
197
194
|
if (deps['next'])
|
|
198
195
|
resultado.stack.frontend = 'Next.js';
|
|
199
196
|
else if (deps['react'])
|
|
@@ -202,14 +199,12 @@ function analisarProjeto(cwd) {
|
|
|
202
199
|
resultado.stack.frontend = 'Vue';
|
|
203
200
|
else if (deps['nuxt'])
|
|
204
201
|
resultado.stack.frontend = 'Nuxt';
|
|
205
|
-
// Backend
|
|
206
202
|
if (deps['fastify'])
|
|
207
203
|
resultado.stack.backend = 'Node.js + Fastify';
|
|
208
204
|
else if (deps['express'])
|
|
209
205
|
resultado.stack.backend = 'Node.js + Express';
|
|
210
206
|
else if (deps['@nestjs/core'])
|
|
211
207
|
resultado.stack.backend = 'NestJS';
|
|
212
|
-
// Banco
|
|
213
208
|
if (deps['pg'] || deps['postgres'])
|
|
214
209
|
resultado.stack.banco = 'PostgreSQL';
|
|
215
210
|
else if (deps['mysql2'])
|
|
@@ -218,29 +213,25 @@ function analisarProjeto(cwd) {
|
|
|
218
213
|
resultado.stack.banco = 'SQLite';
|
|
219
214
|
else if (deps['mongoose'])
|
|
220
215
|
resultado.stack.banco = 'MongoDB';
|
|
221
|
-
// ORM
|
|
222
216
|
if (deps['prisma'] || deps['@prisma/client'])
|
|
223
217
|
resultado.stack.orm = 'Prisma';
|
|
224
218
|
else if (deps['typeorm'])
|
|
225
219
|
resultado.stack.orm = 'TypeORM';
|
|
226
220
|
else if (deps['drizzle-orm'])
|
|
227
221
|
resultado.stack.orm = 'Drizzle';
|
|
228
|
-
// Auth
|
|
229
222
|
if (deps['jsonwebtoken'])
|
|
230
223
|
resultado.stack.auth = 'JWT';
|
|
231
224
|
else if (deps['next-auth'])
|
|
232
225
|
resultado.stack.auth = 'NextAuth';
|
|
233
226
|
else if (deps['@clerk/nextjs'])
|
|
234
227
|
resultado.stack.auth = 'Clerk';
|
|
235
|
-
// Cache
|
|
236
|
-
if (deps['ioredis'] || deps['redis'])
|
|
237
|
-
resultado.stack.cache = 'Redis';
|
|
238
228
|
if (deps['bullmq'])
|
|
239
229
|
resultado.stack.cache = 'Redis + BullMQ';
|
|
230
|
+
else if (deps['ioredis'] || deps['redis'])
|
|
231
|
+
resultado.stack.cache = 'Redis';
|
|
240
232
|
}
|
|
241
233
|
catch { }
|
|
242
234
|
}
|
|
243
|
-
// README
|
|
244
235
|
const readmePath = path.join(cwd, 'README.md');
|
|
245
236
|
if (fs.existsSync(readmePath)) {
|
|
246
237
|
resultado.readme = true;
|
|
@@ -249,41 +240,63 @@ function analisarProjeto(cwd) {
|
|
|
249
240
|
if (desc)
|
|
250
241
|
resultado.descricao = resultado.descricao || desc.trim();
|
|
251
242
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
243
|
+
const pastasCodigo = ['src', 'app', 'pages', 'components', 'server', 'api'];
|
|
244
|
+
let totalArquivos = 0;
|
|
245
|
+
const todasRotas = [];
|
|
246
|
+
for (const pasta of pastasCodigo) {
|
|
247
|
+
const dir = path.join(cwd, pasta);
|
|
248
|
+
if (fs.existsSync(dir)) {
|
|
249
|
+
todasRotas.push(...extrairRotas(dir));
|
|
250
|
+
totalArquivos += contarArquivos(dir);
|
|
251
|
+
}
|
|
257
252
|
}
|
|
253
|
+
resultado.features = [...new Set(todasRotas)].slice(0, 20);
|
|
254
|
+
resultado.arquivos = totalArquivos;
|
|
258
255
|
return resultado;
|
|
259
256
|
}
|
|
260
257
|
function extrairRotas(dir) {
|
|
261
258
|
const rotas = [];
|
|
262
|
-
const exts = ['.ts', '.js'];
|
|
259
|
+
const exts = ['.ts', '.tsx', '.js', '.jsx'];
|
|
263
260
|
function walk(d) {
|
|
264
261
|
if (!fs.existsSync(d))
|
|
265
262
|
return;
|
|
266
263
|
for (const entry of fs.readdirSync(d)) {
|
|
267
264
|
const full = path.join(d, entry);
|
|
268
265
|
const stat = fs.statSync(full);
|
|
269
|
-
if (stat.isDirectory() && !
|
|
266
|
+
if (stat.isDirectory() && !['node_modules', '.next', 'dist', '.git'].includes(entry)) {
|
|
270
267
|
walk(full);
|
|
271
268
|
}
|
|
272
269
|
else if (exts.includes(path.extname(entry))) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
rotas.
|
|
280
|
-
|
|
270
|
+
try {
|
|
271
|
+
const content = fs.readFileSync(full, 'utf-8');
|
|
272
|
+
const apiMatches = content.match(/\.(get|post|put|patch|delete|route)\(['"`]([^'"`]+)/gi);
|
|
273
|
+
if (apiMatches) {
|
|
274
|
+
apiMatches.forEach(m => {
|
|
275
|
+
const rota = m.replace(/\.(get|post|put|patch|delete|route)\(['"`]/i, '').trim();
|
|
276
|
+
if (rota && !rotas.includes(rota))
|
|
277
|
+
rotas.push(rota);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
if (entry === 'page.tsx' || entry === 'page.ts') {
|
|
281
|
+
const relativo = path.relative(dir, full)
|
|
282
|
+
.replace(/\\/g, '/')
|
|
283
|
+
.replace('/page.tsx', '')
|
|
284
|
+
.replace('/page.ts', '');
|
|
285
|
+
if (relativo && !rotas.includes(relativo))
|
|
286
|
+
rotas.push(`page: /${relativo}`);
|
|
287
|
+
}
|
|
288
|
+
if (d.includes('pages') && (entry.endsWith('.tsx') || entry.endsWith('.ts')) && !entry.startsWith('_')) {
|
|
289
|
+
const pagina = entry.replace('.tsx', '').replace('.ts', '');
|
|
290
|
+
if (!rotas.includes(pagina))
|
|
291
|
+
rotas.push(`page: ${pagina}`);
|
|
292
|
+
}
|
|
281
293
|
}
|
|
294
|
+
catch { }
|
|
282
295
|
}
|
|
283
296
|
}
|
|
284
297
|
}
|
|
285
298
|
walk(dir);
|
|
286
|
-
return rotas
|
|
299
|
+
return rotas;
|
|
287
300
|
}
|
|
288
301
|
function contarArquivos(dir) {
|
|
289
302
|
let count = 0;
|
|
@@ -292,8 +305,9 @@ function contarArquivos(dir) {
|
|
|
292
305
|
return;
|
|
293
306
|
for (const entry of fs.readdirSync(d)) {
|
|
294
307
|
const full = path.join(d, entry);
|
|
295
|
-
if (fs.statSync(full).isDirectory() && !
|
|
308
|
+
if (fs.statSync(full).isDirectory() && !['node_modules', '.next', 'dist', '.git'].includes(entry)) {
|
|
296
309
|
walk(full);
|
|
310
|
+
}
|
|
297
311
|
else
|
|
298
312
|
count++;
|
|
299
313
|
}
|