UNPKG

graphql-lint-clint-platform

Version:

GraphQL unused fields linter for Clint platform - Custom patterns and actions.graphql support

149 lines 7.81 kB
#!/usr/bin/env node "use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const commander_1 = require("commander"); const path_1 = __importDefault(require("path")); const clintExtractor_1 = require("./clintExtractor"); const clintAnalyzer_1 = require("./clintAnalyzer"); const program = new commander_1.Command(); program .name("graphql-lint-clint") .description("🎯 Ferramenta específica da Clint para análise de actions GraphQL do Hasura") .version("1.0.0") .argument("[paths...]", "Caminhos dos arquivos ou diretórios para analisar", ["."]) .option("-i, --include <patterns...>", "Padrões de arquivos para incluir", ["**/*.{ts,tsx,js,jsx}", "**/actions.graphql"]) .option("-e, --exclude <patterns...>", "Padrões de arquivos para excluir", ["node_modules/**", "dist/**", "build/**"]) .option("-f, --format <format>", "Formato de saída (console, json)", "console") .option("-o, --output <file>", "Arquivo de saída (se não especificado, usa stdout)") .option("--verbose", "Modo verboso") .action(async (paths, options) => { try { console.log("🎯 CLINT GRAPHQL LINT - HASURA ACTIONS ANALYZER\n"); if (options.verbose) { console.log("📋 Configuração:"); console.log(` 🎯 Caminhos: ${paths.join(", ")}`); console.log(` 📁 Incluir: ${options.include.join(", ")}`); console.log(` 🚫 Excluir: ${options.exclude.join(", ")}`); console.log(""); } // 1. Extrair actions do Hasura console.log("🔍 Extraindo actions do Hasura..."); const extractor = new clintExtractor_1.ClintGraphQLExtractor(); const actions = []; for (const targetPath of paths) { const absolutePath = path_1.default.resolve(targetPath); await extractor.extractFromPath(absolutePath, actions, options.include, options.exclude); } const actionPatterns = extractor.getActionPatterns(); const totalActions = Object.keys(actionPatterns).length; console.log(` ✅ ${totalActions} actions encontradas\n`); // 2. Analisar uso das actions no código console.log("🔍 Analisando uso das actions no código..."); const analyzer = new clintAnalyzer_1.ClintUsageAnalyzer(actionPatterns); const sourcePath = paths[0] ? path_1.default.resolve(paths[0]) : process.cwd(); const result = await analyzer.analyzeUsageInPath(sourcePath, options.verbose); // 3. Reportar resultados console.log("📊 RESULTADOS DA ANÁLISE CLINT:"); console.log("".padEnd(50, "=")); const usedActions = Object.keys(result.usedActions).length; const unusedActions = result.unusedActions.length; console.log(`🎯 Actions analisadas: ${totalActions}`); console.log(`✅ Actions em uso: ${usedActions} (${Math.round((usedActions / totalActions) * 100)}%)`); console.log(`❌ Actions não utilizadas: ${unusedActions} (${Math.round((unusedActions / totalActions) * 100)}%)`); if (unusedActions > 0) { console.log("\n🚨 ACTIONS NÃO UTILIZADAS (NECESSITAM OTIMIZAÇÃO):"); console.log("".padEnd(60, "=")); result.unusedActions.forEach(actionName => { // Usar códigos ANSI para cor vermelha const redText = `\x1b[31m❌ ${actionName}\x1b[0m`; const patternText = `\x1b[33m→ Padrões: ${actionPatterns[actionName].join(', ')}\x1b[0m`; console.log(` ${redText}`); console.log(` 🔗 ${patternText}`); console.log(""); }); console.log("".padEnd(60, "=")); console.log(`\x1b[31m⚠️ TOTAL DE ACTIONS DESPERDIÇADAS: ${unusedActions}\x1b[0m`); console.log(`\x1b[33m💡 Remova ou implemente o uso dessas actions para otimizar o projeto!\x1b[0m`); } if (options.format === "json") { const jsonOutput = { summary: { total: totalActions, used: usedActions, unused: unusedActions, usagePercentage: Math.round((usedActions / totalActions) * 100) }, result: result }; if (options.output) { const fs = await Promise.resolve().then(() => __importStar(require("fs"))); fs.writeFileSync(options.output, JSON.stringify(jsonOutput, null, 2)); console.log(`\n📁 Resultado salvo em: ${options.output}`); } else { console.log("\n📄 JSON OUTPUT:"); console.log(JSON.stringify(jsonOutput, null, 2)); } } console.log("\n🎯 Análise Clint concluída!"); // NOVA FUNCIONALIDADE: Throw error se houver actions não utilizadas if (unusedActions > 0) { console.log(`\n\x1b[31m💥 ERRO: Encontradas ${unusedActions} actions não utilizadas!\x1b[0m`); console.log(`\x1b[33m🔧 AÇÃO NECESSÁRIA: Otimize as seguintes queries removendo ou implementando seu uso:\x1b[0m`); // Lista resumida para o erro result.unusedActions.forEach(actionName => { console.log(`\x1b[31m • ${actionName}${actionPatterns[actionName].join(', ')}\x1b[0m`); }); console.log(`\n\x1b[37m📖 DICA: Execute novamente após implementar o uso ou remover as actions desnecessárias.\x1b[0m`); // Throw com informações detalhadas const errorMessage = `🚨 OTIMIZAÇÃO NECESSÁRIA: ${unusedActions} actions da Clint não estão sendo utilizadas no código. ` + `Actions desperdiçadas: ${result.unusedActions.join(', ')}. ` + `Implemente o uso ou remova essas actions para otimizar o projeto.`; throw new Error(errorMessage); } // Exit com sucesso se não houver actions não utilizadas console.log("\n\x1b[32m✅ Todas as actions estão sendo utilizadas corretamente!\x1b[0m"); } catch (error) { console.error("❌ Erro na análise:", error); process.exit(1); } }); program.parse(); //# sourceMappingURL=cli.js.map