ai-seo
Version:
AI-native JSON-LD schema utility with automated URL-to-Schema generation, intelligent content analysis, caching, rate limiting, performance monitoring, and AI optimization (ChatGPT, Voice). Complete automation & scale features. Zero runtime dependencies.
141 lines (118 loc) ⢠4.28 kB
JavaScript
// CLI Command: generate-url-batch
// Generate schemas from multiple URLs - v1.12.0
import { URLSchemaGenerator } from '../../src/url-generator.js';
import { readFile, writeFile } from 'fs/promises';
import { existsSync } from 'fs';
const colorCodes = {
blue: '\x1b[34m',
gray: '\x1b[90m',
red: '\x1b[31m',
yellow: '\x1b[33m',
dim: '\x1b[2m',
green: '\x1b[32m',
bold: '\x1b[1m',
cyan: '\x1b[36m',
reset: '\x1b[0m'
};
function colorize(text, color) {
return `${colorCodes[color]}${text}${colorCodes.reset}`;
}
const colors = {
blue: (text) => colorize(text, 'blue'),
gray: (text) => colorize(text, 'gray'),
red: (text) => colorize(text, 'red'),
yellow: (text) => colorize(text, 'yellow'),
dim: (text) => colorize(text, 'dim'),
green: (text) => colorize(text, 'green'),
bold: (text) => colorize(text, 'bold'),
cyan: (text) => colorize(text, 'cyan')
};
export async function generateUrlBatchCommand(inputFile, options = {}) {
console.log(colors.blue('š Batch URL Schema Generator - v1.12.0\n'));
try {
// Read URLs from file
if (!existsSync(inputFile)) {
console.log(colors.red(`ā File not found: ${inputFile}`));
return;
}
const fileContent = await readFile(inputFile, 'utf-8');
const urls = fileContent
.split('\n')
.map(line => line.trim())
.filter(line => line && !line.startsWith('#')); // Filter empty and comments
if (urls.length === 0) {
console.log(colors.yellow('ā ļø No URLs found in file'));
return;
}
console.log(colors.gray(`Found ${urls.length} URLs to process`));
console.log(colors.gray(`Concurrency: ${options.concurrency || 3}\n`));
// Progress tracking
let completed = 0;
let successful = 0;
let failed = 0;
const progressCallback = (url, current, total) => {
const percentage = Math.round((current / total) * 100);
process.stdout.write(`\r${colors.cyan('Progress:')} ${current}/${total} (${percentage}%) - ${url.substring(0, 50)}...`);
};
// Process URLs
const results = await URLSchemaGenerator.generateFromURLs(urls, {
...options,
concurrency: options.concurrency || 3,
progressCallback
});
console.log('\n'); // New line after progress
// Count results
results.forEach(result => {
if (result.success) {
successful++;
} else {
failed++;
}
});
// Display summary
console.log(colors.green(`\nā
Batch processing complete!\n`));
console.log(colors.bold('Summary:'));
console.log(colors.green(` ā Successful: ${successful}`));
if (failed > 0) {
console.log(colors.red(` ā Failed: ${failed}`));
}
console.log(colors.gray(` Total: ${results.length}`));
// Save results
if (options.outputDir) {
const outputDir = options.outputDir;
const fs = await import('fs');
// Create directory if it doesn't exist
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
// Save each result
for (let i = 0; i < results.length; i++) {
const result = results[i];
if (result.success) {
const filename = `${outputDir}/schema-${i + 1}.json`;
await writeFile(filename, JSON.stringify(result, null, 2));
}
}
console.log(colors.green(`\nš Saved to: ${outputDir}/`));
} else if (options.output) {
// Save all results to single file
await writeFile(options.output, JSON.stringify(results, null, 2));
console.log(colors.green(`\nš Saved to: ${options.output}`));
}
// Show failed URLs
if (failed > 0 && !options.quiet) {
console.log(colors.red('\nā Failed URLs:'));
results.forEach((result, i) => {
if (!result.success) {
console.log(colors.dim(` ${i + 1}. ${result.url}`));
console.log(colors.dim(` Error: ${result.error}`));
}
});
}
} catch (error) {
console.log(colors.red('\nā Error:'), error.message);
if (options.debug) {
console.log(colors.dim(error.stack));
}
}
}