@eventcatalog/linter
Version:
A linter for EventCatalog to validate frontmatter and resource references
72 lines • 3.4 kB
JavaScript
;
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 chalk_1 = __importDefault(require("chalk"));
const ora_1 = __importDefault(require("ora"));
const path_1 = __importDefault(require("path"));
const scanner_1 = require("../scanner");
const parser_1 = require("../parser");
const validators_1 = require("../validators");
const reporters_1 = require("../reporters");
const config_1 = require("../config");
const program = new commander_1.Command();
program
.name('eventcatalog-linter')
.description('Lint your EventCatalog for frontmatter and reference validation')
.version('0.1.0')
.argument('[directory]', 'EventCatalog directory to lint', '.')
.option('-v, --verbose', 'Show verbose output', false)
.option('--fail-on-warning', 'Exit with non-zero code on warnings', false)
.action(async (directory, options) => {
const rootDir = path_1.default.resolve(directory);
const spinner = (0, ora_1.default)('Loading configuration...').start();
try {
// Load configuration
const config = (0, config_1.loadConfig)(rootDir);
spinner.text = 'Scanning EventCatalog files...';
const allFiles = await (0, scanner_1.scanCatalogFiles)(rootDir);
// Filter out ignored files
const files = allFiles.filter((file) => !(0, config_1.shouldIgnoreFile)(file.relativePath, config.ignorePatterns || []));
const ignoredCount = allFiles.length - files.length;
if (ignoredCount > 0) {
spinner.text = `Found ${files.length} catalog files (${ignoredCount} ignored)`;
}
else {
spinner.text = `Found ${files.length} catalog files`;
}
if (files.length === 0) {
spinner.warn('No EventCatalog files found');
process.exit(0);
}
spinner.text = 'Parsing frontmatter...';
const { parsed, errors: parseErrors } = await (0, parser_1.parseAllFiles)(files);
spinner.text = 'Validating catalog...';
const rawValidationErrors = (0, validators_1.validateCatalog)(parsed);
// Apply rule configuration to each file's errors
const validationErrors = parsed.flatMap((parsedFile) => {
const fileErrors = rawValidationErrors.filter((error) => error.file === parsedFile.file.relativePath);
const effectiveRules = (0, config_1.getEffectiveRules)(parsedFile.file.relativePath, config);
return (0, config_1.applyRuleSeverity)(fileErrors, effectiveRules);
});
spinner.stop();
const summary = (0, reporters_1.reportErrors)(validationErrors, parseErrors, options.verbose);
// Show scan summary
if (summary.totalErrors === 0) {
console.log(chalk_1.default.dim(`\n ${files.length} files checked`));
}
if (summary.totalErrors > 0 || (options.failOnWarning && summary.totalWarnings > 0)) {
process.exit(1);
}
}
catch (error) {
spinner.fail('An error occurred');
console.error(chalk_1.default.red(error instanceof Error ? error.message : String(error)));
process.exit(1);
}
});
program.parse();
//# sourceMappingURL=index.js.map