aeo-linter 0.1.0

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.
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { runCli } from '../dist/index.js';
4
+
5
+ runCli();
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @fileoverview CLI principal para aeo-linter
3
+ */
4
+ export declare function runCli(): Promise<void>;
package/dist/index.js ADDED
@@ -0,0 +1,99 @@
1
+ /**
2
+ * @fileoverview CLI principal para aeo-linter
3
+ */
4
+ import { Command } from 'commander';
5
+ import fs from 'node:fs/promises';
6
+ import path from 'node:path';
7
+ import { Runner, TerminalReporter, HtmlReporter, defaultConfig } from '@drowlink/aeo-linter-core';
8
+ export async function runCli() {
9
+ const program = new Command();
10
+ program
11
+ .name('aeo-linter')
12
+ .description('Answer Engine Optimization (AEO/GEO) Linter - Arquitectura Google Lighthouse')
13
+ .version('0.1.0')
14
+ .argument('<url>', 'URL de la página web a auditar')
15
+ .option('-j, --json', 'Muestra el resultado completo en formato JSON')
16
+ .option('--html', 'Genera un reporte visual interactivo en formato HTML')
17
+ .option('-o, --output <file>', 'Ruta de archivo para guardar el reporte (.html o .json)')
18
+ .option('-c, --categories <categories>', 'Lista separada por comas de categorías a auditar')
19
+ .action(async (url, options) => {
20
+ try {
21
+ // Validar formato de URL
22
+ let validUrl;
23
+ try {
24
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
25
+ validUrl = `https://${url}`;
26
+ }
27
+ else {
28
+ validUrl = url;
29
+ }
30
+ new URL(validUrl);
31
+ }
32
+ catch {
33
+ console.error(`\x1b[31mError: URL inválida '${url}'\x1b[0m`);
34
+ process.exit(1);
35
+ }
36
+ // Filtrar categorías si se especificaron
37
+ let customConfig = defaultConfig;
38
+ if (options.categories) {
39
+ const selected = options.categories.split(',').map((c) => c.trim().toLowerCase());
40
+ const filteredCategories = {};
41
+ for (const key of Object.keys(defaultConfig.categories)) {
42
+ if (selected.includes(key.toLowerCase())) {
43
+ filteredCategories[key] = defaultConfig.categories[key];
44
+ }
45
+ }
46
+ if (Object.keys(filteredCategories).length === 0) {
47
+ console.error(`\x1b[31mError: Ninguna categoría válida seleccionada. Disponibles: ${Object.keys(defaultConfig.categories).join(', ')}\x1b[0m`);
48
+ process.exit(1);
49
+ }
50
+ customConfig = {
51
+ ...defaultConfig,
52
+ categories: filteredCategories,
53
+ };
54
+ }
55
+ const isQuiet = Boolean(options.json && !options.output);
56
+ if (!isQuiet) {
57
+ console.log(`\x1b[36m⚡ Iniciando auditoría AEO para:\x1b[0m ${validUrl}`);
58
+ }
59
+ const report = await Runner.run(validUrl, {
60
+ config: customConfig,
61
+ onProgress: (phase, msg) => {
62
+ if (!isQuiet) {
63
+ console.log(` \x1b[90m[${phase.toUpperCase()}]\x1b[0m ${msg}`);
64
+ }
65
+ },
66
+ });
67
+ // Generar salida
68
+ if (options.output) {
69
+ const outPath = path.resolve(process.cwd(), options.output);
70
+ let content = '';
71
+ if (outPath.endsWith('.json') || options.json) {
72
+ content = JSON.stringify(report, null, 2);
73
+ }
74
+ else {
75
+ content = HtmlReporter.generate(report);
76
+ }
77
+ await fs.writeFile(outPath, content, 'utf-8');
78
+ console.log(`\n\x1b[32m✔ Reporte guardado con éxito en:\x1b[0m ${outPath}`);
79
+ }
80
+ else if (options.html) {
81
+ const defaultHtmlPath = path.resolve(process.cwd(), `aeo-report-${Date.now()}.html`);
82
+ const content = HtmlReporter.generate(report);
83
+ await fs.writeFile(defaultHtmlPath, content, 'utf-8');
84
+ console.log(`\n\x1b[32m✔ Reporte HTML interactivo generado en:\x1b[0m ${defaultHtmlPath}`);
85
+ }
86
+ else if (options.json) {
87
+ console.log(JSON.stringify(report, null, 2));
88
+ }
89
+ else {
90
+ console.log(TerminalReporter.generate(report));
91
+ }
92
+ }
93
+ catch (err) {
94
+ console.error(`\x1b[31mError durante la auditoría AEO:\x1b[0m`, err instanceof Error ? err.message : err);
95
+ process.exit(1);
96
+ }
97
+ });
98
+ await program.parseAsync(process.argv);
99
+ }
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "aeo-linter",
3
+ "version": "0.1.0",
4
+ "description": "Command-line interface for Answer Engine Optimization (AEO/GEO) Linter",
5
+ "bin": {
6
+ "aeo-linter": "./bin/aeo-linter.js"
7
+ },
8
+ "type": "module",
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "typecheck": "tsc --noEmit",
12
+ "prepublishOnly": "npm run build"
13
+ },
14
+ "files": [
15
+ "bin",
16
+ "dist"
17
+ ],
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/DrowLink/aeo-audit-linter.git",
21
+ "directory": "cli"
22
+ },
23
+ "keywords": [
24
+ "aeo",
25
+ "geo",
26
+ "linter",
27
+ "lighthouse",
28
+ "cli"
29
+ ],
30
+ "author": "DrowLink",
31
+ "license": "MIT",
32
+ "dependencies": {
33
+ "@drowlink/aeo-linter-core": "^0.1.0",
34
+ "commander": "^12.0.0"
35
+ },
36
+ "devDependencies": {
37
+ "@types/node": "^20.12.7",
38
+ "typescript": "^5.4.5"
39
+ }
40
+ }