tutanus 0.12.9 → 0.13.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.
Files changed (195) hide show
  1. package/README.md +3 -0
  2. package/dist/analysts/html/analysts/analyst-html.d.ts +4 -2
  3. package/dist/analysts/html/analysts/analyst-html.d.ts.map +1 -1
  4. package/dist/analysts/html/analysts/analyst-html.js +118 -195
  5. package/dist/analysts/html/analysts/analyst-html.js.map +1 -1
  6. package/dist/analysts/js-ts/analysts/analyst-commands-cli.d.ts.map +1 -1
  7. package/dist/analysts/js-ts/analysts/analyst-commands-cli.js +93 -140
  8. package/dist/analysts/js-ts/analysts/analyst-commands-cli.js.map +1 -1
  9. package/dist/analysts/js-ts/analysts/analyst-functions-long.d.ts.map +1 -1
  10. package/dist/analysts/js-ts/analysts/analyst-functions-long.js +42 -36
  11. package/dist/analysts/js-ts/analysts/analyst-functions-long.js.map +1 -1
  12. package/dist/app/github/app/check-run-builder.d.ts +2 -1
  13. package/dist/app/github/app/check-run-builder.d.ts.map +1 -1
  14. package/dist/app/github/app/check-run-builder.js.map +1 -1
  15. package/dist/app/github/app/check-suite-handler.d.ts.map +1 -1
  16. package/dist/app/github/app/check-suite-handler.js +1 -1
  17. package/dist/app/github/app/check-suite-handler.js.map +1 -1
  18. package/dist/app/github/app/installation-store.d.ts.map +1 -1
  19. package/dist/app/github/app/installation-store.js +42 -2
  20. package/dist/app/github/app/installation-store.js.map +1 -1
  21. package/dist/app/github/app/server.d.ts.map +1 -1
  22. package/dist/app/github/app/server.js +17 -15
  23. package/dist/app/github/app/server.js.map +1 -1
  24. package/dist/app/github/app/setup-routes.d.ts +1 -1
  25. package/dist/app/github/app/setup-routes.d.ts.map +1 -1
  26. package/dist/app/github/app/setup-routes.js +16 -4
  27. package/dist/app/github/app/setup-routes.js.map +1 -1
  28. package/dist/app/github/app/workflow-reader.d.ts +1 -1
  29. package/dist/app/github/app/workflow-reader.d.ts.map +1 -1
  30. package/dist/app/github/app/workflow-reader.js.map +1 -1
  31. package/dist/app/github/dashboard/routes.d.ts.map +1 -1
  32. package/dist/app/github/dashboard/routes.js +35 -32
  33. package/dist/app/github/dashboard/routes.js.map +1 -1
  34. package/dist/app/github/dashboard/stats-store.d.ts.map +1 -1
  35. package/dist/app/github/dashboard/stats-store.js +6 -5
  36. package/dist/app/github/dashboard/stats-store.js.map +1 -1
  37. package/dist/app/github/jobs/job-manager.d.ts.map +1 -1
  38. package/dist/app/github/jobs/job-manager.js +34 -9
  39. package/dist/app/github/jobs/job-manager.js.map +1 -1
  40. package/dist/app/github/middleware/autenticacao.d.ts +9 -0
  41. package/dist/app/github/middleware/autenticacao.d.ts.map +1 -0
  42. package/dist/app/github/middleware/autenticacao.js +88 -0
  43. package/dist/app/github/middleware/autenticacao.js.map +1 -0
  44. package/dist/app/github/middleware/crypto.d.ts +10 -0
  45. package/dist/app/github/middleware/crypto.d.ts.map +1 -0
  46. package/dist/app/github/middleware/crypto.js +104 -0
  47. package/dist/app/github/middleware/crypto.js.map +1 -0
  48. package/dist/app/github/middleware/isolamento.d.ts +11 -0
  49. package/dist/app/github/middleware/isolamento.d.ts.map +1 -0
  50. package/dist/app/github/middleware/isolamento.js +149 -0
  51. package/dist/app/github/middleware/isolamento.js.map +1 -0
  52. package/dist/app/github/middleware/seguranca.d.ts +3 -0
  53. package/dist/app/github/middleware/seguranca.d.ts.map +1 -0
  54. package/dist/app/github/middleware/seguranca.js +114 -0
  55. package/dist/app/github/middleware/seguranca.js.map +1 -0
  56. package/dist/caretakers/caretaker-imports.d.ts.map +1 -1
  57. package/dist/caretakers/caretaker-imports.js +6 -0
  58. package/dist/caretakers/caretaker-imports.js.map +1 -1
  59. package/dist/cli/commands/command-marketplace.js +1 -1
  60. package/dist/cli/commands/command-marketplace.js.map +1 -1
  61. package/dist/core/messages/en/github/github-app-messages.d.ts +0 -3
  62. package/dist/core/messages/en/github/github-app-messages.d.ts.map +1 -1
  63. package/dist/core/messages/en/github/github-app-messages.js +0 -3
  64. package/dist/core/messages/en/github/github-app-messages.js.map +1 -1
  65. package/dist/core/messages/en/guardian/guardian-messages.d.ts +0 -1
  66. package/dist/core/messages/en/guardian/guardian-messages.d.ts.map +1 -1
  67. package/dist/core/messages/en/guardian/guardian-messages.js +0 -1
  68. package/dist/core/messages/en/guardian/guardian-messages.js.map +1 -1
  69. package/dist/core/messages/ja/github/github-app-messages.d.ts +0 -3
  70. package/dist/core/messages/ja/github/github-app-messages.d.ts.map +1 -1
  71. package/dist/core/messages/ja/github/github-app-messages.js +0 -3
  72. package/dist/core/messages/ja/github/github-app-messages.js.map +1 -1
  73. package/dist/core/messages/ja/guardian/guardian-messages.d.ts +0 -1
  74. package/dist/core/messages/ja/guardian/guardian-messages.d.ts.map +1 -1
  75. package/dist/core/messages/ja/guardian/guardian-messages.js +0 -1
  76. package/dist/core/messages/ja/guardian/guardian-messages.js.map +1 -1
  77. package/dist/core/messages/pt/github/github-app-messages.d.ts +0 -3
  78. package/dist/core/messages/pt/github/github-app-messages.d.ts.map +1 -1
  79. package/dist/core/messages/pt/github/github-app-messages.js +0 -3
  80. package/dist/core/messages/pt/github/github-app-messages.js.map +1 -1
  81. package/dist/core/messages/pt/guardian/guardian-messages.d.ts +0 -1
  82. package/dist/core/messages/pt/guardian/guardian-messages.d.ts.map +1 -1
  83. package/dist/core/messages/pt/guardian/guardian-messages.js +0 -1
  84. package/dist/core/messages/pt/guardian/guardian-messages.js.map +1 -1
  85. package/dist/core/messages/zh/github/github-app-messages.d.ts +0 -3
  86. package/dist/core/messages/zh/github/github-app-messages.d.ts.map +1 -1
  87. package/dist/core/messages/zh/github/github-app-messages.js +0 -3
  88. package/dist/core/messages/zh/github/github-app-messages.js.map +1 -1
  89. package/dist/core/messages/zh/guardian/guardian-messages.d.ts +0 -1
  90. package/dist/core/messages/zh/guardian/guardian-messages.d.ts.map +1 -1
  91. package/dist/core/messages/zh/guardian/guardian-messages.js +0 -1
  92. package/dist/core/messages/zh/guardian/guardian-messages.js.map +1 -1
  93. package/dist/guardian/gpg.d.ts +1 -1
  94. package/dist/guardian/gpg.d.ts.map +1 -1
  95. package/dist/guardian/gpg.js +1 -1
  96. package/dist/guardian/gpg.js.map +1 -1
  97. package/dist/node.loader.d.ts.map +1 -1
  98. package/dist/node.loader.js +6 -0
  99. package/dist/node.loader.js.map +1 -1
  100. package/dist/shared/marketplace/remote.js +1 -1
  101. package/dist/shared/marketplace/remote.js.map +1 -1
  102. package/dist/shared/persistence/persistence.d.ts.map +1 -1
  103. package/dist/shared/persistence/persistence.js.map +1 -1
  104. package/dist/types/analysts/index.d.ts +0 -1
  105. package/dist/types/analysts/index.d.ts.map +1 -1
  106. package/dist/types/analysts/index.js +0 -1
  107. package/dist/types/analysts/index.js.map +1 -1
  108. package/dist/types/github/app.d.ts +6 -0
  109. package/dist/types/github/app.d.ts.map +1 -1
  110. package/dist/types/github/app.js.map +1 -1
  111. package/dist/types/guardian/index.d.ts +4 -0
  112. package/dist/types/guardian/index.d.ts.map +1 -1
  113. package/dist/types/guardian/index.js.map +1 -1
  114. package/dist/types/guardian/integrity.d.ts +0 -4
  115. package/dist/types/guardian/integrity.d.ts.map +1 -1
  116. package/dist/types/guardian/integrity.js.map +1 -1
  117. package/dist/types/index.d.ts +1 -6
  118. package/dist/types/index.d.ts.map +1 -1
  119. package/dist/types/index.js +1 -6
  120. package/dist/types/index.js.map +1 -1
  121. package/out/404/index.html +1 -0
  122. package/out/404.html +1 -0
  123. package/out/__next.__PAGE__.txt +25 -0
  124. package/out/__next._full.txt +37 -0
  125. package/out/__next._head.txt +5 -0
  126. package/out/__next._index.txt +6 -0
  127. package/out/__next._tree.txt +4 -0
  128. package/out/_next/static/7AicuowOpmCuGWjCpsQMB/_buildManifest.js +11 -0
  129. package/out/_next/static/7AicuowOpmCuGWjCpsQMB/_clientMiddlewareManifest.js +1 -0
  130. package/out/_next/static/7AicuowOpmCuGWjCpsQMB/_ssgManifest.js +1 -0
  131. package/out/_next/static/chunks/05-c3ty_6dwfk.js +1 -0
  132. package/out/_next/static/chunks/0cz1d0mv5g_q7.js +1 -0
  133. package/out/_next/static/chunks/1061ff024jzvu.js +2 -0
  134. package/out/_next/static/chunks/14mrh2-p_w84d.js +1 -0
  135. package/out/_next/static/chunks/15orcrkp-_9ct.js +4 -0
  136. package/out/_next/static/chunks/1jq4o6yq14o4c.js +31 -0
  137. package/out/_next/static/chunks/1rxncug86bump.js +1 -0
  138. package/out/_next/static/chunks/2n-4qa9h44lgj.js +1 -0
  139. package/out/_next/static/chunks/39aw8cj-oq89z.js +11 -0
  140. package/out/_next/static/chunks/3n7dm2ojtyzwn.js +1 -0
  141. package/out/_next/static/chunks/3uta7d_6k863-.css +1 -0
  142. package/out/_next/static/chunks/turbopack-2xb6mmb6_q43u.js +1 -0
  143. package/out/_next/static/media/icon-1.008jpsm4iakzh.png +0 -0
  144. package/out/_not-found/__next._full.txt +16 -0
  145. package/out/_not-found/__next._head.txt +5 -0
  146. package/out/_not-found/__next._index.txt +6 -0
  147. package/out/_not-found/__next._not-found.__PAGE__.txt +5 -0
  148. package/out/_not-found/__next._not-found.txt +5 -0
  149. package/out/_not-found/__next._tree.txt +3 -0
  150. package/out/_not-found/index.html +1 -0
  151. package/out/_not-found/index.txt +16 -0
  152. package/out/changelog/__next._full.txt +573 -0
  153. package/out/changelog/__next._head.txt +5 -0
  154. package/out/changelog/__next._index.txt +6 -0
  155. package/out/changelog/__next._tree.txt +4 -0
  156. package/out/changelog/__next.changelog.__PAGE__.txt +560 -0
  157. package/out/changelog/__next.changelog.txt +5 -0
  158. package/out/changelog/index.html +550 -0
  159. package/out/changelog/index.txt +573 -0
  160. package/out/github/dashboard/__next._full.txt +20 -0
  161. package/out/github/dashboard/__next._head.txt +5 -0
  162. package/out/github/dashboard/__next._index.txt +6 -0
  163. package/out/github/dashboard/__next._tree.txt +3 -0
  164. package/out/github/dashboard/__next.github.dashboard.__PAGE__.txt +9 -0
  165. package/out/github/dashboard/__next.github.dashboard.txt +4 -0
  166. package/out/github/dashboard/__next.github.txt +5 -0
  167. package/out/github/dashboard/index.html +1 -0
  168. package/out/github/dashboard/index.txt +20 -0
  169. package/out/index.html +1 -0
  170. package/out/index.txt +37 -0
  171. package/out/privacy-policy/__next._full.txt +38 -0
  172. package/out/privacy-policy/__next._head.txt +5 -0
  173. package/out/privacy-policy/__next._index.txt +6 -0
  174. package/out/privacy-policy/__next._tree.txt +4 -0
  175. package/out/privacy-policy/__next.privacy-policy.__PAGE__.txt +23 -0
  176. package/out/privacy-policy/__next.privacy-policy.txt +5 -0
  177. package/out/privacy-policy/index.html +1 -0
  178. package/out/privacy-policy/index.txt +38 -0
  179. package/out/terms-of-use/__next._full.txt +37 -0
  180. package/out/terms-of-use/__next._head.txt +5 -0
  181. package/out/terms-of-use/__next._index.txt +6 -0
  182. package/out/terms-of-use/__next._tree.txt +4 -0
  183. package/out/terms-of-use/__next.terms-of-use.__PAGE__.txt +18 -0
  184. package/out/terms-of-use/__next.terms-of-use.txt +5 -0
  185. package/out/terms-of-use/index.html +1 -0
  186. package/out/terms-of-use/index.txt +37 -0
  187. package/package.json +8 -9
  188. package/dist/app/github/app/seguranca.d.ts +0 -9
  189. package/dist/app/github/app/seguranca.d.ts.map +0 -1
  190. package/dist/app/github/app/seguranca.js +0 -58
  191. package/dist/app/github/app/seguranca.js.map +0 -1
  192. package/dist/types/analysts/html.d.ts +0 -4
  193. package/dist/types/analysts/html.d.ts.map +0 -1
  194. package/dist/types/analysts/html.js +0 -2
  195. package/dist/types/analysts/html.js.map +0 -1
@@ -7,28 +7,16 @@ export function extractHandlerInfo(nodeParam) {
7
7
  if (!nodeParam || !isBabelNode(nodeParam))
8
8
  return null;
9
9
  const node = nodeParam;
10
+ const build = (fn, bodyBlock, isAnonymous) => {
11
+ const rawParams = Array.isArray(fn.params) ? fn.params : [];
12
+ const params = rawParams.filter((p) => textoTitulo.isIdentifier(p));
13
+ return { func: fn, bodyBlock, isAnonymous, params, totalParams: (fn.params ?? []).length };
14
+ };
10
15
  if (textoTitulo.isFunctionDeclaration(node) && node.body && textoTitulo.isBlockStatement(node.body)) {
11
- const rawParams = Array.isArray(node.params) ? node.params : [];
12
- const params = rawParams.filter((caminho) => textoTitulo.isIdentifier(caminho));
13
- return {
14
- func: node,
15
- bodyBlock: node.body,
16
- isAnonymous: !node.id,
17
- params,
18
- totalParams: rawParams.length
19
- };
16
+ return build(node, node.body, !node.id);
20
17
  }
21
18
  if ((textoTitulo.isFunctionExpression(node) || textoTitulo.isArrowFunctionExpression(node)) && node.body && textoTitulo.isBlockStatement(node.body)) {
22
- const rawParams = Array.isArray(node.params) ? node.params : [];
23
- const params = rawParams.filter((caminho) => textoTitulo.isIdentifier(caminho));
24
- const isAnonymous = textoTitulo.isFunctionExpression(node) ? !node.id : true;
25
- return {
26
- func: node,
27
- bodyBlock: node.body,
28
- isAnonymous,
29
- params,
30
- totalParams: rawParams.length
31
- };
19
+ return build(node, node.body, textoTitulo.isFunctionExpression(node) ? !node.id : true);
32
20
  }
33
21
  return null;
34
22
  }
@@ -209,7 +197,7 @@ function detectarOclif(node, state, registrar) {
209
197
  return textoTitulo.isIdentifier(k) && k.name === 'run';
210
198
  };
211
199
  const bodyElem = Array.isArray(bodyArray) ? bodyArray?.find(isRunMethod) : undefined;
212
- if (bodyElem && textoTitulo.isBlockStatement(bodyElem.body)) {
200
+ if (bodyElem && bodyElem.body && textoTitulo.isBlockStatement(bodyElem.body)) {
213
201
  registrar(textoTitulo.callExpression(textoTitulo.identifier('oclifRun'), []), classNome, bodyElem, 'oclif');
214
202
  }
215
203
  }
@@ -229,37 +217,29 @@ function detectarImportCommander(node, state) {
229
217
  function detectarVarUsage(node, state) {
230
218
  if (!textoTitulo.isFunctionDeclaration(node) && !textoTitulo.isFunctionExpression(node) && !textoTitulo.isArrowFunctionExpression(node))
231
219
  return;
232
- const fn = node;
233
- const body = fn.body;
234
- if (!body || !textoTitulo.isBlockStatement(body))
220
+ const fnBody = node.body;
221
+ if (!fnBody || !textoTitulo.isBlockStatement(fnBody))
235
222
  return;
236
223
  const createdVars = new Set();
237
- for (const stmt of body.body || []) {
224
+ for (const stmt of fnBody.body || []) {
238
225
  if (textoTitulo.isVariableDeclaration(stmt)) {
239
- const varDecl = stmt;
240
- for (const decl of varDecl.declarations) {
241
- const d = decl;
242
- if (d.id && textoTitulo.isIdentifier(d.id) && d.init && textoTitulo.isNewExpression(d.init) && textoTitulo.isIdentifier(d.init.callee) && state.commandClassNomes.has(d.init.callee.name)) {
243
- createdVars.add(d.id.name);
226
+ for (const decl of stmt.declarations) {
227
+ if (decl.id && textoTitulo.isIdentifier(decl.id) && decl.init && textoTitulo.isNewExpression(decl.init) && textoTitulo.isIdentifier(decl.init.callee) && state.commandClassNomes.has(decl.init.callee.name)) {
228
+ createdVars.add(decl.id.name);
244
229
  }
245
230
  }
246
231
  }
247
- if (textoTitulo.isExpressionStatement(stmt)) {
248
- const exprStmt = stmt;
249
- if (textoTitulo.isCallExpression(exprStmt.expression) && textoTitulo.isMemberExpression(exprStmt.expression.callee)) {
250
- const callee = exprStmt.expression.callee;
251
- const obj = callee.object;
252
- if (textoTitulo.isIdentifier(obj) && createdVars.has(obj.name)) {
253
- state.hasFrameworkSignal = true;
254
- }
232
+ else if (textoTitulo.isExpressionStatement(stmt) && textoTitulo.isCallExpression(stmt.expression) && textoTitulo.isMemberExpression(stmt.expression.callee)) {
233
+ const obj = stmt.expression.callee.object;
234
+ if (textoTitulo.isIdentifier(obj) && createdVars.has(obj.name)) {
235
+ state.hasFrameworkSignal = true;
255
236
  }
256
237
  }
257
- }
258
- for (const stmt of body.body || []) {
259
- if (textoTitulo.isReturnStatement(stmt) && stmt.argument && textoTitulo.isIdentifier(stmt.argument) && createdVars.has(stmt.argument.name)) {
260
- state.hasFrameworkSignal = true;
261
- if (state.comandosInvocados === 0) {
262
- state.comandosInvocados++;
238
+ else if (textoTitulo.isReturnStatement(stmt) && stmt.argument) {
239
+ if (textoTitulo.isIdentifier(stmt.argument) && createdVars.has(stmt.argument.name)) {
240
+ state.hasFrameworkSignal = true;
241
+ if (state.comandosInvocados === 0)
242
+ state.comandosInvocados++;
263
243
  }
264
244
  }
265
245
  }
@@ -329,106 +309,75 @@ function verificarComandosDuplicados(comandoNomes, relPath) {
329
309
  origem: 'analista-comandos-cli'
330
310
  };
331
311
  }
312
+ function extrairLinha(handlerInfo, node) {
313
+ const fromHandler = extractLineFromNode(handlerInfo);
314
+ if (typeof fromHandler === 'number')
315
+ return fromHandler;
316
+ const fromNode = extractLineFromNode(node);
317
+ return typeof fromNode === 'number' ? fromNode : 1;
318
+ }
319
+ function verificarHandlerAnonimo(handlerInfo, comandoNome, linha, relPath) {
320
+ if (!handlerInfo.isAnonymous || !comandoNome)
321
+ return null;
322
+ return { tipo: 'padrao-problematico', nivel: 'aviso', mensagem: messages.ComandosCliMensagens.handlerAnonimo(comandoNome), relPath, linha, origem: 'analista-comandos-cli' };
323
+ }
324
+ function verificarMuitosParams(handlerInfo, comandoNome, linha, relPath) {
325
+ const contagem = handlerInfo.totalParams ?? (Array.isArray(handlerInfo.params) ? handlerInfo.params.length : 0);
326
+ if (contagem <= 3 || !comandoNome)
327
+ return null;
328
+ return { tipo: 'padrao-problematico', nivel: 'aviso', mensagem: messages.ComandosCliMensagens.handlerMuitosParametros(comandoNome, contagem), relPath, linha, origem: 'analista-comandos-cli' };
329
+ }
330
+ function verificarHandlerLongo(statements, comandoNome, linha, relPath) {
331
+ if (statements.length <= 30 || !comandoNome)
332
+ return null;
333
+ return { tipo: 'padrao-problematico', nivel: 'aviso', mensagem: messages.ComandosCliMensagens.handlerMuitoLongo(comandoNome, statements.length), relPath, linha, origem: 'analista-comandos-cli' };
334
+ }
335
+ function verificarTryCatch(statements, comandoNome, linha, relPath) {
336
+ if (statements.length === 0 || !comandoNome)
337
+ return null;
338
+ if (statements.some((stmt) => textoTitulo.isTryStatement(stmt)))
339
+ return null;
340
+ return { tipo: 'boa-pratica-ausente', nivel: 'aviso', mensagem: messages.ComandosCliMensagens.handlerSemTryCatch(comandoNome), relPath, linha, origem: 'analista-comandos-cli' };
341
+ }
342
+ function verificarFeedback(handlerInfo, statements, comandoNome, linha, relPath, conteudo) {
343
+ if (statements.length === 0 || !comandoNome)
344
+ return null;
345
+ const bodyInicio = getNumberProp(handlerInfo.bodyBlock, 'start');
346
+ const bodyFim = getNumberProp(handlerInfo.bodyBlock, 'end');
347
+ const bodySlice = typeof bodyInicio === 'number' && typeof bodyFim === 'number' ? conteudo.substring(bodyInicio, bodyFim) : '';
348
+ const bodySrc = (bodySlice && bodySlice.length > 5 ? bodySlice : conteudo);
349
+ const regexLog = /console\.(log|warn|error)|logger\.|ctx\.(reply|send|res|response)/;
350
+ if (regexLog.test(bodySrc) || regexLog.test(conteudo))
351
+ return null;
352
+ return { tipo: 'boa-pratica-ausente', nivel: 'aviso', mensagem: messages.ComandosCliMensagens.handlerSemFeedback(comandoNome), relPath, linha, origem: 'analista-comandos-cli' };
353
+ }
332
354
  function processarComandosRegistrados(comandos, comandoNomes, comandosInvocados, hasFrameworkSignal, relPath, conteudo, contextoProjeto) {
333
355
  const ocorrencias = [];
334
- if (comandosInvocados === 0 && !hasFrameworkSignal) {
335
- if ((contextoProjeto.isBot || contextoProjeto.isCLI) && !contextoProjeto.isInfrastructure) {
336
- ocorrencias.push({
337
- tipo: 'padrao-ausente',
338
- nivel: 'info',
339
- mensagem: messages.ComandosCliMensagens.padraoAusente,
340
- relPath,
341
- origem: 'analista-comandos-cli'
342
- });
343
- }
356
+ if (comandosInvocados === 0 && !hasFrameworkSignal && (contextoProjeto.isBot || contextoProjeto.isCLI) && !contextoProjeto.isInfrastructure) {
357
+ ocorrencias.push({ tipo: 'padrao-ausente', nivel: 'info', mensagem: messages.ComandosCliMensagens.padraoAusente, relPath, origem: 'analista-comandos-cli' });
344
358
  }
345
359
  const duplicata = verificarComandosDuplicados(comandoNomes, relPath);
346
360
  if (duplicata)
347
361
  ocorrencias.push(duplicata);
348
362
  for (const cmd of comandos) {
349
- const { comandoNome, node } = cmd;
350
363
  const handlerInfo = cmd.handler;
351
- let linha = 1;
352
- const fromHandler = extractLineFromNode(handlerInfo);
353
- const fromNode = extractLineFromNode(node);
354
- if (typeof fromHandler === 'number')
355
- linha = fromHandler;
356
- else if (typeof fromNode === 'number')
357
- linha = fromNode;
358
- if (!handlerInfo || !handlerInfo.bodyBlock) {
364
+ if (!handlerInfo || !handlerInfo.bodyBlock)
359
365
  continue;
360
- }
366
+ const linha = extrairLinha(handlerInfo, cmd.node);
361
367
  const statements = Array.isArray(handlerInfo.bodyBlock.body) ? handlerInfo.bodyBlock.body : [];
362
- if (handlerInfo.isAnonymous && comandoNome) {
363
- ocorrencias.push({
364
- tipo: 'padrao-problematico',
365
- nivel: 'aviso',
366
- mensagem: messages.ComandosCliMensagens.handlerAnonimo(comandoNome),
367
- relPath,
368
- linha,
369
- origem: 'analista-comandos-cli'
370
- });
371
- }
372
- const paramContagem = handlerInfo.totalParams ?? (Array.isArray(handlerInfo.params) ? handlerInfo.params.length : 0);
373
- if (paramContagem > 3) {
374
- ocorrencias.push({
375
- tipo: 'padrao-problematico',
376
- nivel: 'aviso',
377
- mensagem: messages.ComandosCliMensagens.handlerMuitosParametros(comandoNome, paramContagem),
378
- relPath,
379
- linha,
380
- origem: 'analista-comandos-cli'
381
- });
382
- }
383
- if (statements.length > 30) {
384
- ocorrencias.push({
385
- tipo: 'padrao-problematico',
386
- nivel: 'aviso',
387
- mensagem: messages.ComandosCliMensagens.handlerMuitoLongo(comandoNome, statements.length),
388
- relPath,
389
- linha,
390
- origem: 'analista-comandos-cli'
391
- });
392
- }
393
- if (statements.length > 0) {
394
- const hasTryCatch = statements.some((stmt) => textoTitulo.isTryStatement(stmt));
395
- if (!hasTryCatch) {
396
- ocorrencias.push({
397
- tipo: 'boa-pratica-ausente',
398
- nivel: 'aviso',
399
- mensagem: messages.ComandosCliMensagens.handlerSemTryCatch(comandoNome),
400
- relPath,
401
- linha,
402
- origem: 'analista-comandos-cli'
403
- });
404
- }
405
- const bodyInicio = getNumberProp(handlerInfo.bodyBlock, 'start');
406
- const bodyFim = getNumberProp(handlerInfo.bodyBlock, 'end');
407
- const bodySlice = typeof bodyInicio === 'number' && typeof bodyFim === 'number' ? conteudo.substring(bodyInicio, bodyFim) : '';
408
- const bodySrc = bodySlice && bodySlice.length > 5 ? bodySlice : conteudo;
409
- const regexLog = /console\.(log|warn|error)|logger\.|ctx\.(reply|send|res|response)/;
410
- if (!regexLog.test(bodySrc)) {
411
- if (!regexLog.test(conteudo)) {
412
- ocorrencias.push({
413
- tipo: 'boa-pratica-ausente',
414
- nivel: 'aviso',
415
- mensagem: messages.ComandosCliMensagens.handlerSemFeedback(comandoNome),
416
- relPath,
417
- linha,
418
- origem: 'analista-comandos-cli'
419
- });
420
- }
421
- }
368
+ for (const ocorrencia of [
369
+ verificarHandlerAnonimo(handlerInfo, cmd.comandoNome, linha, relPath),
370
+ verificarMuitosParams(handlerInfo, cmd.comandoNome, linha, relPath),
371
+ verificarHandlerLongo(statements, cmd.comandoNome, linha, relPath),
372
+ verificarTryCatch(statements, cmd.comandoNome, linha, relPath),
373
+ verificarFeedback(handlerInfo, statements, cmd.comandoNome, linha, relPath, conteudo),
374
+ ]) {
375
+ if (ocorrencia)
376
+ ocorrencias.push(ocorrencia);
422
377
  }
423
378
  }
424
379
  if (comandos.length > 1) {
425
- ocorrencias.push({
426
- tipo: 'padrao-estrutural',
427
- nivel: 'info',
428
- mensagem: messages.ComandosCliMensagens.multiplosComandos(comandos.length),
429
- relPath,
430
- origem: 'analista-comandos-cli'
431
- });
380
+ ocorrencias.push({ tipo: 'padrao-estrutural', nivel: 'info', mensagem: messages.ComandosCliMensagens.multiplosComandos(comandos.length), relPath, origem: 'analista-comandos-cli' });
432
381
  }
433
382
  return ocorrencias;
434
383
  }
@@ -458,19 +407,23 @@ export const analistaComandosCli = {
458
407
  commandClassNomes: new Set(['Command']),
459
408
  };
460
409
  const registrar = criarRegistrar(state);
410
+ const detectores = [
411
+ (n) => detectarNewCommand(n, state),
412
+ (n) => detectarDiscordJs(n, state),
413
+ (n) => detectarCommanderChainMethods(n, state),
414
+ (n) => detectarGenericCommand(n, state, registrar),
415
+ (n) => detectarCommanderAction(n, state, registrar),
416
+ (n) => detectarCommanderCommand(n, state, registrar),
417
+ (n) => detectarYargs(n, state, registrar),
418
+ (n) => detectarOclif(n, state, registrar),
419
+ (n) => detectarImportCommander(n, state),
420
+ (n) => detectarVarUsage(n, state),
421
+ ];
461
422
  traverse(ast.node, {
462
423
  enter(path) {
463
424
  const nodeAtual = path.node;
464
- detectarNewCommand(nodeAtual, state);
465
- detectarDiscordJs(nodeAtual, state);
466
- detectarCommanderChainMethods(nodeAtual, state);
467
- detectarGenericCommand(nodeAtual, state, registrar);
468
- detectarCommanderAction(nodeAtual, state, registrar);
469
- detectarCommanderCommand(nodeAtual, state, registrar);
470
- detectarYargs(nodeAtual, state, registrar);
471
- detectarOclif(nodeAtual, state, registrar);
472
- detectarImportCommander(nodeAtual, state);
473
- detectarVarUsage(nodeAtual, state);
425
+ for (const detector of detectores)
426
+ detector(nodeAtual);
474
427
  }
475
428
  });
476
429
  return processarComandosRegistrados(state.comandos, state.comandoNomes, state.comandosInvocados, state.hasFrameworkSignal, arquivo, conteudo, contextoProjeto);
@@ -1 +1 @@
1
- {"version":3,"file":"analyst-commands-cli.js","sourceRoot":"","sources":["../../../../src/analysts/js-ts/analysts/analyst-commands-cli.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: MIT\n// @tutanus-disable tipo-inseguro-unknown\n// Justificativa: unknown é usado para manipulação segura de nós AST com tipagem defensiva\nimport type { NodePath } from '@babel/traverse';\nimport type { ArrowFunctionExpression, BlockStatement, CallExpression, ClassDeclaration, ClassMethod, FunctionDeclaration, FunctionExpression, ImportDeclaration, MemberExpression, NewExpression, Node, StringLiteral, VariableDeclaration, VariableDeclarator } from '@babel/types';\nimport * as textoTitulo from '@babel/types';\nimport { traverse } from '@core/config';\nimport { messages } from '@core/messages';\nimport { detectarContextoProjeto, isRelevanteParaAnalise } from '@shared';\n\nimport type { ComandoRegistro, ContextoExecucao, HandlerInfo, Ocorrencia, RegistrarFn, TecnicaAplicarResultado } from '@';\nimport { isBabelNode } from '@';\n\ntype BabelNode = Node;\nexport function extractHandlerInfo(nodeParam: Node | unknown): HandlerInfo | null {\n if (!nodeParam || !isBabelNode(nodeParam)) return null;\n const node = nodeParam as Node;\n if (textoTitulo.isFunctionDeclaration(node) && node.body && textoTitulo.isBlockStatement(node.body)) {\n const rawParams = Array.isArray(node.params) ? node.params : [];\n const params: textoTitulo.Identifier[] = rawParams.filter((caminho): caminho is textoTitulo.Identifier => textoTitulo.isIdentifier(caminho as textoTitulo.Node));\n return {\n func: node,\n bodyBlock: node.body as BlockStatement,\n isAnonymous: !node.id,\n params,\n totalParams: rawParams.length\n };\n }\n if ((textoTitulo.isFunctionExpression(node) || textoTitulo.isArrowFunctionExpression(node)) && node.body && textoTitulo.isBlockStatement(node.body)) {\n const rawParams = Array.isArray(node.params) ? node.params : [];\n const params: textoTitulo.Identifier[] = rawParams.filter((caminho): caminho is textoTitulo.Identifier => textoTitulo.isIdentifier(caminho as textoTitulo.Node));\n const isAnonymous = textoTitulo.isFunctionExpression(node) ? !node.id : true;\n return {\n func: node,\n bodyBlock: node.body as BlockStatement,\n isAnonymous,\n params,\n totalParams: rawParams.length\n };\n }\n return null;\n}\n\n// ── State ──────────────────────────────────────────────────────────────\n\ninterface AnaliseState {\n comandos: ComandoRegistro[];\n comandoNomes: string[];\n comandosInvocados: number;\n hasFrameworkSignal: boolean;\n commandClassNomes: Set<string>;\n}\n\n// ── Line extraction helpers ────────────────────────────────────────────\n\nfunction getNumberProp(obj: unknown, prop: string): number | undefined {\n if (typeof obj !== 'object' || obj === null) return undefined;\n const dict = obj as Record<string, unknown>;\n const val = dict[prop];\n return typeof val === 'number' ? val : undefined;\n}\n\nfunction extractLineFromNode(obj: unknown): number | undefined {\n if (typeof obj !== 'object' || obj === null) return undefined;\n const dict = obj as Record<string, unknown>;\n const loc = dict.loc;\n if (typeof loc !== 'object' || loc === null) return undefined;\n const start = (loc as Record<string, unknown>).start;\n if (typeof start !== 'object' || start === null) return undefined;\n const line = (start as Record<string, unknown>).line;\n return typeof line === 'number' ? line : undefined;\n}\n\n// ── Framework detection ────────────────────────────────────────────────\n\nfunction detectarNewCommand(node: textoTitulo.Node, state: AnaliseState): void {\n if (!textoTitulo.isNewExpression(node)) return;\n const newExpr = node as NewExpression;\n if (!textoTitulo.isIdentifier(newExpr.callee) || newExpr.callee.name !== 'Command') return;\n state.hasFrameworkSignal = true;\n let nome = '';\n const arg0 = newExpr.arguments && newExpr.arguments[0];\n if (arg0 && textoTitulo.isStringLiteral(arg0)) nome = (arg0 as StringLiteral).value;\n if (state.comandosInvocados === 0) {\n state.comandosInvocados++;\n if (nome) state.comandoNomes.push(nome);\n }\n}\n\nfunction detectarDiscordJs(node: textoTitulo.Node, state: AnaliseState): void {\n if (!textoTitulo.isCallExpression(node) && !textoTitulo.isMemberExpression(node)) return;\n if (textoTitulo.isCallExpression(node)) {\n const call = node as CallExpression;\n if (!textoTitulo.isMemberExpression(call.callee)) return;\n const prop = (call.callee as MemberExpression).property;\n if (!textoTitulo.isIdentifier(prop)) return;\n const chamaMetodos = ['addSlashCommand', 'setName', 'setDescription', 'addStringOption', 'addUserOption', 'addChannelOption'];\n if (!chamaMetodos.includes(prop.name)) return;\n state.hasFrameworkSignal = true;\n if (state.comandosInvocados === 0) {\n state.comandosInvocados++;\n const arg0 = call.arguments && call.arguments[0];\n const nome = prop.name === 'setName' && arg0 && textoTitulo.isStringLiteral(arg0) ? (arg0 as StringLiteral).value : 'slash-command';\n state.comandoNomes.push(nome);\n }\n return;\n }\n if (textoTitulo.isMemberExpression(node)) {\n const member = node as MemberExpression;\n const prop = member.property;\n if (!textoTitulo.isIdentifier(prop)) return;\n const membros = ['commandName', 'options', 'isCommand', 'reply', 'editReply', 'deferReply', 'isChatInputCommand', 'isAutocomplete'];\n if (!membros.includes(prop.name)) return;\n state.hasFrameworkSignal = true;\n if (state.comandosInvocados === 0) state.comandosInvocados++;\n }\n}\n\nconst METODOS_CADEIA_COMMANDER = new Set(['option', 'description', 'alias', 'argument', 'usage', 'help']);\n\nfunction detectarCommanderChainMethods(node: textoTitulo.Node, state: AnaliseState): void {\n if (!textoTitulo.isCallExpression(node)) return;\n const callee = (node as CallExpression).callee;\n if (!textoTitulo.isMemberExpression(callee)) return;\n const prop = (callee as MemberExpression).property;\n if (!textoTitulo.isIdentifier(prop)) return;\n if (METODOS_CADEIA_COMMANDER.has(prop.name)) {\n state.hasFrameworkSignal = true;\n }\n}\n\nfunction detectarGenericCommand(node: textoTitulo.Node, state: AnaliseState, registrar: RegistrarFn): void {\n if (!textoTitulo.isCallExpression(node)) return;\n const call = node as CallExpression;\n const callee = call.callee;\n if (!textoTitulo.isIdentifier(callee)) return;\n if (!['onCommand', 'registerCommand'].includes(callee.name)) return;\n let comandoNome = '';\n const primeiroArg = call.arguments && call.arguments[0];\n if (primeiroArg && textoTitulo.isStringLiteral(primeiroArg)) comandoNome = (primeiroArg as StringLiteral).value;\n const handler = call.arguments && call.arguments.length > 1 ? call.arguments[1] : undefined;\n registrar(call, comandoNome, handler as Node | undefined, 'generico');\n}\n\nfunction detectarCommanderAction(node: textoTitulo.Node, state: AnaliseState, registrar: RegistrarFn): void {\n if (!textoTitulo.isCallExpression(node)) return;\n const call = node as CallExpression;\n const callee = call.callee;\n if (!textoTitulo.isMemberExpression(callee)) return;\n const prop = (callee as MemberExpression).property;\n if (!textoTitulo.isIdentifier(prop) || prop.name !== 'action') return;\n const handler = call.arguments && call.arguments[0] as Node | undefined;\n const nome = extrairNomeDeCadeia(call);\n registrar(call, nome, handler, 'commander');\n}\n\nfunction detectarCommanderCommand(node: textoTitulo.Node, state: AnaliseState, registrar: RegistrarFn): void {\n if (!textoTitulo.isCallExpression(node)) return;\n const call = node as CallExpression;\n const callee = call.callee;\n if (!textoTitulo.isMemberExpression(callee)) return;\n const prop = (callee as MemberExpression).property;\n if (!textoTitulo.isIdentifier(prop) || prop.name !== 'command') return;\n const args = call.arguments || [];\n const nameArg = args[0];\n let nome = '';\n if (nameArg && textoTitulo.isStringLiteral(nameArg)) nome = (nameArg as StringLiteral).value;\n let handler: Node | undefined;\n for (let i = args.length - 1; i >= 0; i--) {\n const arg = args[i] as Node;\n if (textoTitulo.isFunctionExpression(arg) || textoTitulo.isArrowFunctionExpression(arg)) {\n handler = arg as Node;\n break;\n }\n }\n registrar(call, nome, handler, 'multi');\n}\n\nfunction detectarYargs(node: textoTitulo.Node, state: AnaliseState, registrar: RegistrarFn): void {\n if (!textoTitulo.isCallExpression(node)) return;\n const call = node as CallExpression;\n const callee = call.callee;\n if (!textoTitulo.isMemberExpression(callee)) return;\n const obj = (callee as MemberExpression).object;\n const prop = (callee as MemberExpression).property;\n if (!textoTitulo.isIdentifier(prop) || prop.name !== 'command') return;\n if (!textoTitulo.isIdentifier(obj) || !/yargs?/i.test(obj.name)) return;\n const args = call.arguments || [];\n let nome = '';\n if (args[0] && textoTitulo.isStringLiteral(args[0])) nome = (args[0] as StringLiteral).value;\n const handlerCandidates = args.filter((arg: unknown) => textoTitulo.isFunctionExpression(arg as Node) || textoTitulo.isArrowFunctionExpression(arg as Node));\n const handler = handlerCandidates.at(-1) as Node | undefined;\n registrar(call, nome, handler, 'yargs');\n}\n\nfunction detectarOclif(node: textoTitulo.Node, state: AnaliseState, registrar: RegistrarFn): void {\n if (!textoTitulo.isClassDeclaration(node)) return;\n const cls = node as ClassDeclaration;\n if (!cls.superClass || !textoTitulo.isIdentifier(cls.superClass) || cls.superClass.name !== 'Command') return;\n const classNome = cls.id?.name || '';\n const bodyArray = (cls.body as { body?: unknown }).body;\n const isRunMethod = (method: unknown): method is ClassMethod => {\n if (!textoTitulo.isClassMethod(method as Node)) return false;\n const k = (method as ClassMethod).key;\n return textoTitulo.isIdentifier(k) && k.name === 'run';\n };\n const bodyElem = Array.isArray(bodyArray) ? bodyArray?.find(isRunMethod) as ClassMethod | undefined : undefined;\n if (bodyElem && textoTitulo.isBlockStatement((bodyElem as unknown as { body?: unknown }).body as textoTitulo.Node)) {\n registrar(textoTitulo.callExpression(textoTitulo.identifier('oclifRun'), []), classNome, bodyElem as Node, 'oclif');\n }\n}\n\nfunction detectarImportCommander(node: textoTitulo.Node, state: AnaliseState): void {\n if (!textoTitulo.isImportDeclaration(node)) return;\n const imp = node as ImportDeclaration;\n if (typeof imp.source.value !== 'string' || !/commander/.test(imp.source.value)) return;\n for (const spec of imp.specifiers) {\n if (textoTitulo.isImportSpecifier(spec) && textoTitulo.isIdentifier(spec.imported) && spec.imported.name === 'Command') {\n if (textoTitulo.isIdentifier(spec.local)) state.commandClassNomes.add(spec.local.name);\n }\n }\n}\n\nfunction detectarVarUsage(node: textoTitulo.Node, state: AnaliseState): void {\n if (!textoTitulo.isFunctionDeclaration(node) && !textoTitulo.isFunctionExpression(node) && !textoTitulo.isArrowFunctionExpression(node)) return;\n const fn = node as FunctionDeclaration | FunctionExpression | ArrowFunctionExpression;\n const body = (fn as unknown as { body?: unknown }).body as BlockStatement | undefined;\n if (!body || !textoTitulo.isBlockStatement(body)) return;\n const createdVars = new Set<string>();\n for (const stmt of body.body || []) {\n if (textoTitulo.isVariableDeclaration(stmt)) {\n const varDecl = stmt as VariableDeclaration;\n for (const decl of varDecl.declarations) {\n const d = decl as VariableDeclarator;\n if (d.id && textoTitulo.isIdentifier(d.id) && d.init && textoTitulo.isNewExpression(d.init) && textoTitulo.isIdentifier(d.init.callee) && state.commandClassNomes.has(d.init.callee.name)) {\n createdVars.add(d.id.name);\n }\n }\n }\n if (textoTitulo.isExpressionStatement(stmt)) {\n const exprStmt = stmt as import('@babel/types').ExpressionStatement;\n if (textoTitulo.isCallExpression(exprStmt.expression) && textoTitulo.isMemberExpression(exprStmt.expression.callee)) {\n const callee = exprStmt.expression.callee as MemberExpression;\n const obj = callee.object;\n if (textoTitulo.isIdentifier(obj) && createdVars.has(obj.name)) {\n state.hasFrameworkSignal = true;\n }\n }\n }\n }\n for (const stmt of body.body || []) {\n if (textoTitulo.isReturnStatement(stmt) && stmt.argument && textoTitulo.isIdentifier(stmt.argument) && createdVars.has(stmt.argument.name)) {\n state.hasFrameworkSignal = true;\n if (state.comandosInvocados === 0) {\n state.comandosInvocados++;\n }\n }\n }\n}\n\n// ── Registrar factory ──────────────────────────────────────────────────\n\nfunction criarRegistrar(state: AnaliseState): RegistrarFn {\n return (node: unknown, comandoNome: string, handler: unknown, origemFramework: string) => {\n state.comandosInvocados++;\n if (comandoNome) state.comandoNomes.push(comandoNome);\n const userInfo = extractHandlerInfo(handler as Node | undefined);\n const registro: ComandoRegistro = {\n comandoNome,\n id: undefined,\n timestamp: new Date().toISOString(),\n origemFramework\n };\n registro.handler = userInfo ? {\n ...userInfo\n } as HandlerInfo : undefined;\n registro.node = node as Node | undefined;\n state.comandos.push(registro);\n };\n}\n\n// ── Name extraction ────────────────────────────────────────────────────\n\nfunction extrairNomeDeCadeia(call: textoTitulo.CallExpression): string {\n let current: textoTitulo.Node | null = call as textoTitulo.Node;\n const visitados = new Set<textoTitulo.Node>();\n while (current && !visitados.has(current)) {\n visitados.add(current);\n if (textoTitulo.isCallExpression(current) && textoTitulo.isMemberExpression(current.callee)) {\n const callee = current.callee;\n const prop = callee.property;\n if (textoTitulo.isIdentifier(prop) && prop.name === 'command') {\n const arg0 = current.arguments && current.arguments[0];\n if (arg0 && textoTitulo.isStringLiteral(arg0)) return arg0.value;\n }\n const owner = callee.object;\n if (textoTitulo.isCallExpression(owner)) {\n current = owner as textoTitulo.Node;\n continue;\n } else if (textoTitulo.isMemberExpression(owner)) {\n current = owner.object as textoTitulo.Node;\n continue;\n } else {\n break;\n }\n } else if (textoTitulo.isMemberExpression(current)) {\n current = current.object as textoTitulo.Node;\n continue;\n }\n break;\n }\n return '';\n}\n\n// ── Post-traversal processing ──────────────────────────────────────────\n\nfunction verificarComandosDuplicados(comandoNomes: string[], relPath: string): Ocorrencia | null {\n const duplicados = comandoNomes.filter((item, idx) => item && comandoNomes.indexOf(item) !== idx);\n if (duplicados.length === 0) return null;\n return {\n tipo: 'padrao-problematico',\n nivel: 'aviso',\n mensagem: messages.ComandosCliMensagens.comandosDuplicados(duplicados),\n relPath,\n origem: 'analista-comandos-cli'\n };\n}\n\nfunction processarComandosRegistrados(\n comandos: ComandoRegistro[],\n comandoNomes: string[],\n comandosInvocados: number,\n hasFrameworkSignal: boolean,\n relPath: string,\n conteudo: string,\n contextoProjeto: ReturnType<typeof detectarContextoProjeto>,\n): Ocorrencia[] {\n const ocorrencias: Ocorrencia[] = [];\n\n if (comandosInvocados === 0 && !hasFrameworkSignal) {\n if ((contextoProjeto.isBot || contextoProjeto.isCLI) && !contextoProjeto.isInfrastructure) {\n ocorrencias.push({\n tipo: 'padrao-ausente',\n nivel: 'info',\n mensagem: messages.ComandosCliMensagens.padraoAusente,\n relPath,\n origem: 'analista-comandos-cli'\n });\n }\n }\n\n const duplicata = verificarComandosDuplicados(comandoNomes, relPath);\n if (duplicata) ocorrencias.push(duplicata);\n\n for (const cmd of comandos) {\n const { comandoNome, node } = cmd;\n const handlerInfo = cmd.handler;\n let linha = 1;\n\n const fromHandler = extractLineFromNode(handlerInfo);\n const fromNode = extractLineFromNode(node);\n if (typeof fromHandler === 'number') linha = fromHandler;\n else if (typeof fromNode === 'number') linha = fromNode;\n\n if (!handlerInfo || !handlerInfo.bodyBlock) {\n continue;\n }\n\n const statements = Array.isArray(handlerInfo.bodyBlock.body) ? handlerInfo.bodyBlock.body : [];\n\n if (handlerInfo.isAnonymous && comandoNome) {\n ocorrencias.push({\n tipo: 'padrao-problematico',\n nivel: 'aviso',\n mensagem: messages.ComandosCliMensagens.handlerAnonimo(comandoNome),\n relPath,\n linha,\n origem: 'analista-comandos-cli'\n });\n }\n\n const paramContagem = handlerInfo.totalParams ?? (Array.isArray(handlerInfo.params) ? handlerInfo.params.length : 0);\n if (paramContagem > 3) {\n ocorrencias.push({\n tipo: 'padrao-problematico',\n nivel: 'aviso',\n mensagem: messages.ComandosCliMensagens.handlerMuitosParametros(comandoNome, paramContagem),\n relPath,\n linha,\n origem: 'analista-comandos-cli'\n });\n }\n\n if (statements.length > 30) {\n ocorrencias.push({\n tipo: 'padrao-problematico',\n nivel: 'aviso',\n mensagem: messages.ComandosCliMensagens.handlerMuitoLongo(comandoNome, statements.length),\n relPath,\n linha,\n origem: 'analista-comandos-cli'\n });\n }\n\n if (statements.length > 0) {\n const hasTryCatch = statements.some((stmt: unknown) => textoTitulo.isTryStatement(stmt as textoTitulo.Node));\n if (!hasTryCatch) {\n ocorrencias.push({\n tipo: 'boa-pratica-ausente',\n nivel: 'aviso',\n mensagem: messages.ComandosCliMensagens.handlerSemTryCatch(comandoNome),\n relPath,\n linha,\n origem: 'analista-comandos-cli'\n });\n }\n\n const bodyInicio = getNumberProp((handlerInfo as unknown as Record<string, unknown>).bodyBlock, 'start');\n const bodyFim = getNumberProp((handlerInfo as unknown as Record<string, unknown>).bodyBlock, 'end');\n const bodySlice = typeof bodyInicio === 'number' && typeof bodyFim === 'number' ? conteudo.substring(bodyInicio, bodyFim) : '';\n const bodySrc = bodySlice && bodySlice.length > 5 ? bodySlice : conteudo;\n const regexLog = /console\\.(log|warn|error)|logger\\.|ctx\\.(reply|send|res|response)/;\n if (!regexLog.test(bodySrc)) {\n if (!regexLog.test(conteudo)) {\n ocorrencias.push({\n tipo: 'boa-pratica-ausente',\n nivel: 'aviso',\n mensagem: messages.ComandosCliMensagens.handlerSemFeedback(comandoNome),\n relPath,\n linha,\n origem: 'analista-comandos-cli'\n });\n }\n }\n }\n }\n\n if (comandos.length > 1) {\n ocorrencias.push({\n tipo: 'padrao-estrutural',\n nivel: 'info',\n mensagem: messages.ComandosCliMensagens.multiplosComandos(comandos.length),\n relPath,\n origem: 'analista-comandos-cli'\n });\n }\n\n return ocorrencias;\n}\n\n// ── Analyst export ─────────────────────────────────────────────────────\n\nexport const analistaComandosCli = {\n nome: 'analista-comandos-cli',\n test: (relPath: string): boolean => {\n const caminho = relPath.replace(/\\\\/g, '/').toLowerCase();\n if (/(^|\\/)tests?(\\/)/i.test(caminho) || /\\.(test|spec)\\.(ts|js|tsx|jsx)$/i.test(caminho)) return false;\n return /(\\.ts|\\.tsx|\\.js|\\.jsx)$/.test(caminho);\n },\n aplicar(conteudo: string, arquivo: string, ast: NodePath | null, _fullPath?: string, _contexto?: ContextoExecucao): TecnicaAplicarResultado {\n const contextoProjeto = detectarContextoProjeto({\n arquivo,\n conteudo,\n relPath: arquivo\n });\n if (!isRelevanteParaAnalise(contextoProjeto, 'comando')) return [];\n if (!ast) return [];\n\n const state: AnaliseState = {\n comandos: [],\n comandoNomes: [],\n comandosInvocados: 0,\n hasFrameworkSignal: false,\n commandClassNomes: new Set<string>(['Command']),\n };\n\n const registrar = criarRegistrar(state);\n\n traverse(ast.node, {\n enter(path: NodePath<textoTitulo.Node>) {\n const nodeAtual = path.node as BabelNode;\n detectarNewCommand(nodeAtual, state);\n detectarDiscordJs(nodeAtual, state);\n detectarCommanderChainMethods(nodeAtual, state);\n detectarGenericCommand(nodeAtual, state, registrar);\n detectarCommanderAction(nodeAtual, state, registrar);\n detectarCommanderCommand(nodeAtual, state, registrar);\n detectarYargs(nodeAtual, state, registrar);\n detectarOclif(nodeAtual, state, registrar);\n detectarImportCommander(nodeAtual, state);\n detectarVarUsage(nodeAtual, state);\n }\n });\n\n return processarComandosRegistrados(\n state.comandos,\n state.comandoNomes,\n state.comandosInvocados,\n state.hasFrameworkSignal,\n arquivo,\n conteudo,\n contextoProjeto,\n );\n }\n};\n"]}
1
+ {"version":3,"file":"analyst-commands-cli.js","sourceRoot":"","sources":["../../../../src/analysts/js-ts/analysts/analyst-commands-cli.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: MIT\n// @tutanus-disable tipo-inseguro-unknown\n// Justificativa: unknown é usado para manipulação segura de nós AST com tipagem defensiva\nimport type { NodePath } from '@babel/traverse';\nimport type { ArrowFunctionExpression, BlockStatement, CallExpression, ClassDeclaration, ClassMethod, FunctionDeclaration, FunctionExpression, ImportDeclaration, MemberExpression, NewExpression, Node, StringLiteral, VariableDeclaration, VariableDeclarator } from '@babel/types';\nimport * as textoTitulo from '@babel/types';\nimport { traverse } from '@core/config';\nimport { messages } from '@core/messages';\nimport { detectarContextoProjeto, isRelevanteParaAnalise } from '@shared';\n\nimport type { ComandoRegistro, ContextoExecucao, HandlerInfo, Ocorrencia, RegistrarFn, TecnicaAplicarResultado } from '@';\nimport { isBabelNode } from '@';\n\ntype BabelNode = Node;\ntype FunctionWithParams = textoTitulo.FunctionDeclaration | textoTitulo.FunctionExpression | textoTitulo.ArrowFunctionExpression;\n\nexport function extractHandlerInfo(nodeParam: Node | unknown): HandlerInfo | null {\n if (!nodeParam || !isBabelNode(nodeParam)) return null;\n const node = nodeParam as Node;\n const build = (fn: FunctionWithParams, bodyBlock: BlockStatement, isAnonymous: boolean): HandlerInfo => {\n const rawParams = Array.isArray(fn.params) ? fn.params : [];\n const params = rawParams.filter((p): p is textoTitulo.Identifier => textoTitulo.isIdentifier(p as textoTitulo.Node));\n return { func: fn, bodyBlock, isAnonymous, params, totalParams: (fn.params ?? []).length };\n };\n if (textoTitulo.isFunctionDeclaration(node) && node.body && textoTitulo.isBlockStatement(node.body)) {\n return build(node, node.body as BlockStatement, !node.id);\n }\n if ((textoTitulo.isFunctionExpression(node) || textoTitulo.isArrowFunctionExpression(node)) && node.body && textoTitulo.isBlockStatement(node.body)) {\n return build(node, node.body as BlockStatement, textoTitulo.isFunctionExpression(node) ? !node.id : true);\n }\n return null;\n}\n\n// ── State ──────────────────────────────────────────────────────────────\n\ninterface AnaliseState {\n comandos: ComandoRegistro[];\n comandoNomes: string[];\n comandosInvocados: number;\n hasFrameworkSignal: boolean;\n commandClassNomes: Set<string>;\n}\n\n// ── Line extraction helpers ────────────────────────────────────────────\n\nfunction getNumberProp(obj: unknown, prop: string): number | undefined {\n if (typeof obj !== 'object' || obj === null) return undefined;\n const dict = obj as Record<string, unknown>;\n const val = dict[prop];\n return typeof val === 'number' ? val : undefined;\n}\n\nfunction extractLineFromNode(obj: unknown): number | undefined {\n if (typeof obj !== 'object' || obj === null) return undefined;\n const dict = obj as Record<string, unknown>;\n const loc = dict.loc;\n if (typeof loc !== 'object' || loc === null) return undefined;\n const start = (loc as Record<string, unknown>).start;\n if (typeof start !== 'object' || start === null) return undefined;\n const line = (start as Record<string, unknown>).line;\n return typeof line === 'number' ? line : undefined;\n}\n\n// ── Framework detection ────────────────────────────────────────────────\n\nfunction detectarNewCommand(node: textoTitulo.Node, state: AnaliseState): void {\n if (!textoTitulo.isNewExpression(node)) return;\n const newExpr = node as NewExpression;\n if (!textoTitulo.isIdentifier(newExpr.callee) || newExpr.callee.name !== 'Command') return;\n state.hasFrameworkSignal = true;\n let nome = '';\n const arg0 = newExpr.arguments && newExpr.arguments[0];\n if (arg0 && textoTitulo.isStringLiteral(arg0)) nome = (arg0 as StringLiteral).value;\n if (state.comandosInvocados === 0) {\n state.comandosInvocados++;\n if (nome) state.comandoNomes.push(nome);\n }\n}\n\nfunction detectarDiscordJs(node: textoTitulo.Node, state: AnaliseState): void {\n if (!textoTitulo.isCallExpression(node) && !textoTitulo.isMemberExpression(node)) return;\n if (textoTitulo.isCallExpression(node)) {\n const call = node as CallExpression;\n if (!textoTitulo.isMemberExpression(call.callee)) return;\n const prop = (call.callee as MemberExpression).property;\n if (!textoTitulo.isIdentifier(prop)) return;\n const chamaMetodos = ['addSlashCommand', 'setName', 'setDescription', 'addStringOption', 'addUserOption', 'addChannelOption'];\n if (!chamaMetodos.includes(prop.name)) return;\n state.hasFrameworkSignal = true;\n if (state.comandosInvocados === 0) {\n state.comandosInvocados++;\n const arg0 = call.arguments && call.arguments[0];\n const nome = prop.name === 'setName' && arg0 && textoTitulo.isStringLiteral(arg0) ? (arg0 as StringLiteral).value : 'slash-command';\n state.comandoNomes.push(nome);\n }\n return;\n }\n if (textoTitulo.isMemberExpression(node)) {\n const member = node as MemberExpression;\n const prop = member.property;\n if (!textoTitulo.isIdentifier(prop)) return;\n const membros = ['commandName', 'options', 'isCommand', 'reply', 'editReply', 'deferReply', 'isChatInputCommand', 'isAutocomplete'];\n if (!membros.includes(prop.name)) return;\n state.hasFrameworkSignal = true;\n if (state.comandosInvocados === 0) state.comandosInvocados++;\n }\n}\n\nconst METODOS_CADEIA_COMMANDER = new Set(['option', 'description', 'alias', 'argument', 'usage', 'help']);\n\nfunction detectarCommanderChainMethods(node: textoTitulo.Node, state: AnaliseState): void {\n if (!textoTitulo.isCallExpression(node)) return;\n const callee = (node as CallExpression).callee;\n if (!textoTitulo.isMemberExpression(callee)) return;\n const prop = (callee as MemberExpression).property;\n if (!textoTitulo.isIdentifier(prop)) return;\n if (METODOS_CADEIA_COMMANDER.has(prop.name)) {\n state.hasFrameworkSignal = true;\n }\n}\n\nfunction detectarGenericCommand(node: textoTitulo.Node, state: AnaliseState, registrar: RegistrarFn): void {\n if (!textoTitulo.isCallExpression(node)) return;\n const call = node as CallExpression;\n const callee = call.callee;\n if (!textoTitulo.isIdentifier(callee)) return;\n if (!['onCommand', 'registerCommand'].includes(callee.name)) return;\n let comandoNome = '';\n const primeiroArg = call.arguments && call.arguments[0];\n if (primeiroArg && textoTitulo.isStringLiteral(primeiroArg)) comandoNome = (primeiroArg as StringLiteral).value;\n const handler = call.arguments && call.arguments.length > 1 ? call.arguments[1] : undefined;\n registrar(call, comandoNome, handler as Node | undefined, 'generico');\n}\n\nfunction detectarCommanderAction(node: textoTitulo.Node, state: AnaliseState, registrar: RegistrarFn): void {\n if (!textoTitulo.isCallExpression(node)) return;\n const call = node as CallExpression;\n const callee = call.callee;\n if (!textoTitulo.isMemberExpression(callee)) return;\n const prop = (callee as MemberExpression).property;\n if (!textoTitulo.isIdentifier(prop) || prop.name !== 'action') return;\n const handler = call.arguments && call.arguments[0] as Node | undefined;\n const nome = extrairNomeDeCadeia(call);\n registrar(call, nome, handler, 'commander');\n}\n\nfunction detectarCommanderCommand(node: textoTitulo.Node, state: AnaliseState, registrar: RegistrarFn): void {\n if (!textoTitulo.isCallExpression(node)) return;\n const call = node as CallExpression;\n const callee = call.callee;\n if (!textoTitulo.isMemberExpression(callee)) return;\n const prop = (callee as MemberExpression).property;\n if (!textoTitulo.isIdentifier(prop) || prop.name !== 'command') return;\n const args = call.arguments || [];\n const nameArg = args[0];\n let nome = '';\n if (nameArg && textoTitulo.isStringLiteral(nameArg)) nome = (nameArg as StringLiteral).value;\n let handler: Node | undefined;\n for (let i = args.length - 1; i >= 0; i--) {\n const arg = args[i] as Node;\n if (textoTitulo.isFunctionExpression(arg) || textoTitulo.isArrowFunctionExpression(arg)) {\n handler = arg as Node;\n break;\n }\n }\n registrar(call, nome, handler, 'multi');\n}\n\nfunction detectarYargs(node: textoTitulo.Node, state: AnaliseState, registrar: RegistrarFn): void {\n if (!textoTitulo.isCallExpression(node)) return;\n const call = node as CallExpression;\n const callee = call.callee;\n if (!textoTitulo.isMemberExpression(callee)) return;\n const obj = (callee as MemberExpression).object;\n const prop = (callee as MemberExpression).property;\n if (!textoTitulo.isIdentifier(prop) || prop.name !== 'command') return;\n if (!textoTitulo.isIdentifier(obj) || !/yargs?/i.test(obj.name)) return;\n const args = call.arguments || [];\n let nome = '';\n if (args[0] && textoTitulo.isStringLiteral(args[0])) nome = (args[0] as StringLiteral).value;\n const handlerCandidates = args.filter((arg: unknown) => textoTitulo.isFunctionExpression(arg as Node) || textoTitulo.isArrowFunctionExpression(arg as Node));\n const handler = handlerCandidates.at(-1) as Node | undefined;\n registrar(call, nome, handler, 'yargs');\n}\n\nfunction detectarOclif(node: textoTitulo.Node, state: AnaliseState, registrar: RegistrarFn): void {\n if (!textoTitulo.isClassDeclaration(node)) return;\n const cls = node as ClassDeclaration;\n if (!cls.superClass || !textoTitulo.isIdentifier(cls.superClass) || cls.superClass.name !== 'Command') return;\n const classNome = cls.id?.name || '';\n const bodyArray = (cls.body as { body?: unknown }).body;\n const isRunMethod = (method: unknown): method is ClassMethod => {\n if (!textoTitulo.isClassMethod(method as Node)) return false;\n const k = (method as ClassMethod).key;\n return textoTitulo.isIdentifier(k) && k.name === 'run';\n };\n const bodyElem = Array.isArray(bodyArray) ? bodyArray?.find(isRunMethod) as ClassMethod | undefined : undefined;\n if (bodyElem && bodyElem.body && textoTitulo.isBlockStatement(bodyElem.body)) {\n registrar(textoTitulo.callExpression(textoTitulo.identifier('oclifRun'), []), classNome, bodyElem as Node, 'oclif');\n }\n}\n\nfunction detectarImportCommander(node: textoTitulo.Node, state: AnaliseState): void {\n if (!textoTitulo.isImportDeclaration(node)) return;\n const imp = node as ImportDeclaration;\n if (typeof imp.source.value !== 'string' || !/commander/.test(imp.source.value)) return;\n for (const spec of imp.specifiers) {\n if (textoTitulo.isImportSpecifier(spec) && textoTitulo.isIdentifier(spec.imported) && spec.imported.name === 'Command') {\n if (textoTitulo.isIdentifier(spec.local)) state.commandClassNomes.add(spec.local.name);\n }\n }\n}\n\nfunction detectarVarUsage(node: textoTitulo.Node, state: AnaliseState): void {\n if (!textoTitulo.isFunctionDeclaration(node) && !textoTitulo.isFunctionExpression(node) && !textoTitulo.isArrowFunctionExpression(node)) return;\n const fnBody = (node as FunctionDeclaration | FunctionExpression | ArrowFunctionExpression).body;\n if (!fnBody || !textoTitulo.isBlockStatement(fnBody)) return;\n const createdVars = new Set<string>();\n for (const stmt of fnBody.body || []) {\n if (textoTitulo.isVariableDeclaration(stmt)) {\n for (const decl of stmt.declarations) {\n if (decl.id && textoTitulo.isIdentifier(decl.id) && decl.init && textoTitulo.isNewExpression(decl.init) && textoTitulo.isIdentifier(decl.init.callee) && state.commandClassNomes.has(decl.init.callee.name)) {\n createdVars.add(decl.id.name);\n }\n }\n } else if (textoTitulo.isExpressionStatement(stmt) && textoTitulo.isCallExpression(stmt.expression) && textoTitulo.isMemberExpression(stmt.expression.callee)) {\n const obj = stmt.expression.callee.object;\n if (textoTitulo.isIdentifier(obj) && createdVars.has(obj.name)) {\n state.hasFrameworkSignal = true;\n }\n } else if (textoTitulo.isReturnStatement(stmt) && stmt.argument) {\n if (textoTitulo.isIdentifier(stmt.argument) && createdVars.has(stmt.argument.name)) {\n state.hasFrameworkSignal = true;\n if (state.comandosInvocados === 0) state.comandosInvocados++;\n }\n }\n }\n}\n\n// ── Registrar factory ──────────────────────────────────────────────────\n\nfunction criarRegistrar(state: AnaliseState): RegistrarFn {\n return (node: unknown, comandoNome: string, handler: unknown, origemFramework: string) => {\n state.comandosInvocados++;\n if (comandoNome) state.comandoNomes.push(comandoNome);\n const userInfo = extractHandlerInfo(handler as Node | undefined);\n const registro: ComandoRegistro = {\n comandoNome,\n id: undefined,\n timestamp: new Date().toISOString(),\n origemFramework\n };\n registro.handler = userInfo ? {\n ...userInfo\n } as HandlerInfo : undefined;\n registro.node = node as Node | undefined;\n state.comandos.push(registro);\n };\n}\n\n// ── Name extraction ────────────────────────────────────────────────────\n\nfunction extrairNomeDeCadeia(call: textoTitulo.CallExpression): string {\n let current: textoTitulo.Node | null = call as textoTitulo.Node;\n const visitados = new Set<textoTitulo.Node>();\n while (current && !visitados.has(current)) {\n visitados.add(current);\n if (textoTitulo.isCallExpression(current) && textoTitulo.isMemberExpression(current.callee)) {\n const callee = current.callee;\n const prop = callee.property;\n if (textoTitulo.isIdentifier(prop) && prop.name === 'command') {\n const arg0 = current.arguments && current.arguments[0];\n if (arg0 && textoTitulo.isStringLiteral(arg0)) return arg0.value;\n }\n const owner = callee.object;\n if (textoTitulo.isCallExpression(owner)) {\n current = owner as textoTitulo.Node;\n continue;\n } else if (textoTitulo.isMemberExpression(owner)) {\n current = owner.object as textoTitulo.Node;\n continue;\n } else {\n break;\n }\n } else if (textoTitulo.isMemberExpression(current)) {\n current = current.object as textoTitulo.Node;\n continue;\n }\n break;\n }\n return '';\n}\n\n// ── Post-traversal processing ──────────────────────────────────────────\n\nfunction verificarComandosDuplicados(comandoNomes: string[], relPath: string): Ocorrencia | null {\n const duplicados = comandoNomes.filter((item, idx) => item && comandoNomes.indexOf(item) !== idx);\n if (duplicados.length === 0) return null;\n return {\n tipo: 'padrao-problematico',\n nivel: 'aviso',\n mensagem: messages.ComandosCliMensagens.comandosDuplicados(duplicados),\n relPath,\n origem: 'analista-comandos-cli'\n };\n}\n\nfunction extrairLinha(handlerInfo: HandlerInfo | undefined, node: Node | undefined): number {\n const fromHandler = extractLineFromNode(handlerInfo);\n if (typeof fromHandler === 'number') return fromHandler;\n const fromNode = extractLineFromNode(node);\n return typeof fromNode === 'number' ? fromNode : 1;\n}\n\nfunction verificarHandlerAnonimo(handlerInfo: HandlerInfo, comandoNome: string | undefined, linha: number, relPath: string): Ocorrencia | null {\n if (!handlerInfo.isAnonymous || !comandoNome) return null;\n return { tipo: 'padrao-problematico', nivel: 'aviso', mensagem: messages.ComandosCliMensagens.handlerAnonimo(comandoNome), relPath, linha, origem: 'analista-comandos-cli' };\n}\n\nfunction verificarMuitosParams(handlerInfo: HandlerInfo, comandoNome: string | undefined, linha: number, relPath: string): Ocorrencia | null {\n const contagem = handlerInfo.totalParams ?? (Array.isArray(handlerInfo.params) ? handlerInfo.params.length : 0);\n if (contagem <= 3 || !comandoNome) return null;\n return { tipo: 'padrao-problematico', nivel: 'aviso', mensagem: messages.ComandosCliMensagens.handlerMuitosParametros(comandoNome, contagem), relPath, linha, origem: 'analista-comandos-cli' };\n}\n\nfunction verificarHandlerLongo(statements: unknown[], comandoNome: string | undefined, linha: number, relPath: string): Ocorrencia | null {\n if (statements.length <= 30 || !comandoNome) return null;\n return { tipo: 'padrao-problematico', nivel: 'aviso', mensagem: messages.ComandosCliMensagens.handlerMuitoLongo(comandoNome, statements.length), relPath, linha, origem: 'analista-comandos-cli' };\n}\n\nfunction verificarTryCatch(statements: unknown[], comandoNome: string | undefined, linha: number, relPath: string): Ocorrencia | null {\n if (statements.length === 0 || !comandoNome) return null;\n if (statements.some((stmt: unknown) => textoTitulo.isTryStatement(stmt as textoTitulo.Node))) return null;\n return { tipo: 'boa-pratica-ausente', nivel: 'aviso', mensagem: messages.ComandosCliMensagens.handlerSemTryCatch(comandoNome), relPath, linha, origem: 'analista-comandos-cli' };\n}\n\nfunction verificarFeedback(handlerInfo: HandlerInfo, statements: unknown[], comandoNome: string | undefined, linha: number, relPath: string, conteudo: string): Ocorrencia | null {\n if (statements.length === 0 || !comandoNome) return null;\n const bodyInicio = getNumberProp(handlerInfo.bodyBlock, 'start');\n const bodyFim = getNumberProp(handlerInfo.bodyBlock, 'end');\n const bodySlice = typeof bodyInicio === 'number' && typeof bodyFim === 'number' ? conteudo.substring(bodyInicio, bodyFim) : '';\n const bodySrc = (bodySlice && bodySlice.length > 5 ? bodySlice : conteudo);\n const regexLog = /console\\.(log|warn|error)|logger\\.|ctx\\.(reply|send|res|response)/;\n if (regexLog.test(bodySrc) || regexLog.test(conteudo)) return null;\n return { tipo: 'boa-pratica-ausente', nivel: 'aviso', mensagem: messages.ComandosCliMensagens.handlerSemFeedback(comandoNome), relPath, linha, origem: 'analista-comandos-cli' };\n}\n\nfunction processarComandosRegistrados(\n comandos: ComandoRegistro[],\n comandoNomes: string[],\n comandosInvocados: number,\n hasFrameworkSignal: boolean,\n relPath: string,\n conteudo: string,\n contextoProjeto: ReturnType<typeof detectarContextoProjeto>,\n): Ocorrencia[] {\n const ocorrencias: Ocorrencia[] = [];\n\n if (comandosInvocados === 0 && !hasFrameworkSignal && (contextoProjeto.isBot || contextoProjeto.isCLI) && !contextoProjeto.isInfrastructure) {\n ocorrencias.push({ tipo: 'padrao-ausente', nivel: 'info', mensagem: messages.ComandosCliMensagens.padraoAusente, relPath, origem: 'analista-comandos-cli' });\n }\n\n const duplicata = verificarComandosDuplicados(comandoNomes, relPath);\n if (duplicata) ocorrencias.push(duplicata);\n\n for (const cmd of comandos) {\n const handlerInfo = cmd.handler;\n if (!handlerInfo || !handlerInfo.bodyBlock) continue;\n const linha = extrairLinha(handlerInfo, cmd.node);\n const statements = Array.isArray(handlerInfo.bodyBlock.body) ? handlerInfo.bodyBlock.body : [];\n\n for (const ocorrencia of [\n verificarHandlerAnonimo(handlerInfo, cmd.comandoNome, linha, relPath),\n verificarMuitosParams(handlerInfo, cmd.comandoNome, linha, relPath),\n verificarHandlerLongo(statements, cmd.comandoNome, linha, relPath),\n verificarTryCatch(statements, cmd.comandoNome, linha, relPath),\n verificarFeedback(handlerInfo, statements, cmd.comandoNome, linha, relPath, conteudo),\n ]) {\n if (ocorrencia) ocorrencias.push(ocorrencia);\n }\n }\n\n if (comandos.length > 1) {\n ocorrencias.push({ tipo: 'padrao-estrutural', nivel: 'info', mensagem: messages.ComandosCliMensagens.multiplosComandos(comandos.length), relPath, origem: 'analista-comandos-cli' });\n }\n\n return ocorrencias;\n}\n\n// ── Analyst export ─────────────────────────────────────────────────────\n\nexport const analistaComandosCli = {\n nome: 'analista-comandos-cli',\n test: (relPath: string): boolean => {\n const caminho = relPath.replace(/\\\\/g, '/').toLowerCase();\n if (/(^|\\/)tests?(\\/)/i.test(caminho) || /\\.(test|spec)\\.(ts|js|tsx|jsx)$/i.test(caminho)) return false;\n return /(\\.ts|\\.tsx|\\.js|\\.jsx)$/.test(caminho);\n },\n aplicar(conteudo: string, arquivo: string, ast: NodePath | null, _fullPath?: string, _contexto?: ContextoExecucao): TecnicaAplicarResultado {\n const contextoProjeto = detectarContextoProjeto({\n arquivo,\n conteudo,\n relPath: arquivo\n });\n if (!isRelevanteParaAnalise(contextoProjeto, 'comando')) return [];\n if (!ast) return [];\n\n const state: AnaliseState = {\n comandos: [],\n comandoNomes: [],\n comandosInvocados: 0,\n hasFrameworkSignal: false,\n commandClassNomes: new Set<string>(['Command']),\n };\n\n const registrar = criarRegistrar(state);\n type Detector = (node: textoTitulo.Node) => void;\n const detectores: Detector[] = [\n (n) => detectarNewCommand(n, state),\n (n) => detectarDiscordJs(n, state),\n (n) => detectarCommanderChainMethods(n, state),\n (n) => detectarGenericCommand(n, state, registrar),\n (n) => detectarCommanderAction(n, state, registrar),\n (n) => detectarCommanderCommand(n, state, registrar),\n (n) => detectarYargs(n, state, registrar),\n (n) => detectarOclif(n, state, registrar),\n (n) => detectarImportCommander(n, state),\n (n) => detectarVarUsage(n, state),\n ];\n\n traverse(ast.node, {\n enter(path: NodePath<textoTitulo.Node>) {\n const nodeAtual = path.node as BabelNode;\n for (const detector of detectores) detector(nodeAtual);\n }\n });\n\n return processarComandosRegistrados(\n state.comandos,\n state.comandoNomes,\n state.comandosInvocados,\n state.hasFrameworkSignal,\n arquivo,\n conteudo,\n contextoProjeto,\n );\n }\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"analyst-functions-long.d.ts","sourceRoot":"","sources":["../../../../src/analysts/js-ts/analysts/analyst-functions-long.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAIzC,OAAO,KAAK,EAA8B,UAAU,EAAE,MAAM,GAAG,CAAC;AAyGhE,eAAO,MAAM,qBAAqB;iBACnB,MAAM,WAAW,MAAM,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,cAAc,MAAM;;;;;;;;;oBAyC3E,MAAM,KAAG,OAAO;;CAEhC,CAAC"}
1
+ {"version":3,"file":"analyst-functions-long.d.ts","sourceRoot":"","sources":["../../../../src/analysts/js-ts/analysts/analyst-functions-long.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAIzC,OAAO,KAAK,EAA8B,UAAU,EAAE,MAAM,GAAG,CAAC;AAiHhE,eAAO,MAAM,qBAAqB;iBACnB,MAAM,WAAW,MAAM,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,cAAc,MAAM;;;;;;;;;oBA0C3E,MAAM,KAAG,OAAO;;CAEhC,CAAC"}
@@ -8,23 +8,24 @@ const LIMITE_LINHAS = config.ANALISE_LIMITES?.FUNCOES_LONGAS?.MAX_LINHAS ?? 30;
8
8
  const LIMITE_PARAMETROS = config.ANALISE_LIMITES?.FUNCOES_LONGAS?.MAX_PARAMETROS ?? 4;
9
9
  const LIMITE_ANINHAMENTO = config.ANALISE_LIMITES?.FUNCOES_LONGAS?.MAX_ANINHAMENTO ?? 3;
10
10
  function pushOcorrencia(ocorrencias, tipo, nivel, relPath, linha, mensagem) {
11
- ocorrencias.push({
12
- tipo,
13
- nivel,
14
- relPath,
15
- arquivo: relPath,
16
- linha,
17
- mensagem,
18
- origem: 'analista-funcoes-longas'
19
- });
11
+ ocorrencias.push({ tipo, nivel, relPath, arquivo: relPath, linha, mensagem, origem: 'analista-funcoes-longas' });
12
+ }
13
+ function locValido(loc) {
14
+ if (!loc || typeof loc !== 'object')
15
+ return false;
16
+ const s = loc.start;
17
+ const e = loc.end;
18
+ if (!s || typeof s !== 'object' || !e || typeof e !== 'object')
19
+ return false;
20
+ const sl = s.line;
21
+ const el = e.line;
22
+ return typeof sl === 'number' && typeof el === 'number' && sl >= 1 && el >= sl;
20
23
  }
21
24
  function verificarFuncao(fn, limitesAjustados, contextoArquivo, aninhamento, ocorrencias, relPath) {
22
- const loc = fn.loc;
23
- if (!loc || typeof loc.start !== 'object' || typeof loc.end !== 'object' || typeof loc.start.line !== 'number' || typeof loc.end.line !== 'number' || loc.start.line < 1 || loc.end.line < loc.start.line) {
25
+ if (!locValido(fn.loc))
24
26
  return;
25
- }
26
- const startLine = loc.start.line;
27
- const endLine = loc.end.line;
27
+ const startLine = fn.loc.start.line;
28
+ const endLine = fn.loc.end.line;
28
29
  const linhas = endLine - startLine + 1;
29
30
  if (linhas > limitesAjustados.linhas) {
30
31
  pushOcorrencia(ocorrencias, 'FUNCAO_LONGA', 'aviso', relPath, startLine, `Função com ${linhas} linhas (máx: ${limitesAjustados.linhas})`);
@@ -36,10 +37,9 @@ function verificarFuncao(fn, limitesAjustados, contextoArquivo, aninhamento, oco
36
37
  if (aninhamento > limitesAjustados.aninhamento) {
37
38
  pushOcorrencia(ocorrencias, 'FUNCAO_ANINHADA', 'aviso', relPath, startLine, `Função aninhada em nível ${aninhamento} (máx: ${limitesAjustados.aninhamento})`);
38
39
  }
39
- if (fn.leadingComments == null || Array.isArray(fn.leadingComments) && fn.leadingComments.length === 0) {
40
- if (!contextoArquivo.isTest) {
41
- pushOcorrencia(ocorrencias, 'FUNCAO_SEM_COMENTARIO', 'info', relPath, startLine, `Função sem comentário acima.`);
42
- }
40
+ const semComentario = fn.leadingComments == null || (Array.isArray(fn.leadingComments) && fn.leadingComments.length === 0);
41
+ if (semComentario && !contextoArquivo.isTest) {
42
+ pushOcorrencia(ocorrencias, 'FUNCAO_SEM_COMENTARIO', 'info', relPath, startLine, 'Função sem comentário acima.');
43
43
  }
44
44
  }
45
45
  const TIPOS_FUNCAO = new Set(['FunctionDeclaration', 'FunctionExpression', 'ArrowFunctionExpression']);
@@ -50,33 +50,38 @@ function criarVisitors(analisarRecursivo, aninhamento) {
50
50
  ArrowFunctionExpression: (caminho) => analisarRecursivo(caminho, aninhamento + 1),
51
51
  };
52
52
  }
53
- function processarFileAst(fileAst, limitesAjustados, contextoArquivo, ocorrencias, relPath) {
54
- if (!fileAst)
55
- return ocorrencias;
56
- let fileNode = null;
53
+ function extrairFileNode(fileAst) {
54
+ if (!fileAst || typeof fileAst !== 'object')
55
+ return null;
57
56
  try {
58
- const fa = fileAst;
59
- if (!fa || typeof fa !== 'object')
60
- return ocorrencias;
61
- const maybeNode = fa.node;
57
+ const maybeNode = fileAst.node;
62
58
  if (maybeNode && typeof maybeNode === 'object' && Array.isArray(maybeNode.body)) {
63
- fileNode = maybeNode;
59
+ return maybeNode;
64
60
  }
65
- else if (Array.isArray(fa.body)) {
66
- fileNode = fileAst;
61
+ if (Array.isArray(fileAst.body)) {
62
+ return fileAst;
67
63
  }
68
64
  }
69
65
  catch {
70
- fileNode = null;
66
+ return null;
71
67
  }
72
- if (!fileNode)
73
- return ocorrencias;
74
- const body = Array.isArray(fileNode.body) ? fileNode.body : [];
68
+ return null;
69
+ }
70
+ function verificarFuncoesDoBody(body, limitesAjustados, contextoArquivo, ocorrencias, relPath) {
75
71
  for (const child of body) {
76
72
  if (child && typeof child === 'object' && TIPOS_FUNCAO.has(child.type ?? '')) {
77
73
  verificarFuncao(child, limitesAjustados, contextoArquivo, 0, ocorrencias, relPath);
78
74
  }
79
75
  }
76
+ }
77
+ function processarFileAst(fileAst, limitesAjustados, contextoArquivo, ocorrencias, relPath) {
78
+ if (!fileAst)
79
+ return ocorrencias;
80
+ const fileNode = extrairFileNode(fileAst);
81
+ if (!fileNode)
82
+ return ocorrencias;
83
+ const body = Array.isArray(fileNode.body) ? fileNode.body : [];
84
+ verificarFuncoesDoBody(body, limitesAjustados, contextoArquivo, ocorrencias, relPath);
80
85
  return ocorrencias;
81
86
  }
82
87
  export const analistaFuncoesLongas = criarAnalista({
@@ -94,12 +99,13 @@ export const analistaFuncoesLongas = criarAnalista({
94
99
  const ocorrencias = [];
95
100
  function analisarRecursivo(path, aninhamento = 0) {
96
101
  const node = isNodePath(path) ? path.node : path;
97
- if (TIPOS_FUNCAO.has(node.type ?? '')) {
102
+ const ehFuncao = TIPOS_FUNCAO.has(node.type ?? '');
103
+ if (ehFuncao) {
98
104
  verificarFuncao(node, limitesAjustados, contextoArquivo, aninhamento, ocorrencias, relPath);
99
- aninhamento++;
100
105
  }
106
+ const nivelAtual = ehFuncao ? aninhamento + 1 : aninhamento;
101
107
  if (isNodePath(path) && typeof path.traverse === 'function') {
102
- path.traverse(criarVisitors(analisarRecursivo, aninhamento));
108
+ path.traverse(criarVisitors(analisarRecursivo, nivelAtual));
103
109
  }
104
110
  }
105
111
  if (ast && typeof ast.traverse === 'function') {