graphql-lint-clint-platform
Version:
GraphQL unused fields linter for Clint platform - Custom patterns and actions.graphql support
149 lines • 7.81 kB
JavaScript
;
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