mirror of
https://github.com/awesome-opencode/awesome-opencode.git
synced 2026-04-28 12:29:29 +00:00
158 lines
3.7 KiB
JavaScript
158 lines
3.7 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Export registry data as a flat JSON list.
|
|
* Usage:
|
|
* node scripts/export-json.js --pretty --output dist/registry.json
|
|
* node scripts/export-json.js --pretty > dist/registry.json
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const { readYamlDir, slugify } = require('./utils/yaml');
|
|
const { validateEntry, formatValidationErrors } = require('./utils/validation');
|
|
|
|
const CATEGORIES = ['plugins', 'themes', 'agents', 'projects', 'resources'];
|
|
|
|
function parseArgs(args) {
|
|
const outputFlagIndex = args.findIndex((arg) => arg === '--output');
|
|
const outputPath = outputFlagIndex !== -1 && args[outputFlagIndex + 1]
|
|
? args[outputFlagIndex + 1]
|
|
: null;
|
|
const pretty = args.includes('--pretty');
|
|
return { outputPath, pretty };
|
|
}
|
|
|
|
function buildProductId(entry) {
|
|
if (entry._fileName) {
|
|
return entry._fileName;
|
|
}
|
|
if (entry.name) {
|
|
return slugify(entry.name);
|
|
}
|
|
return '';
|
|
}
|
|
|
|
function sanitizeArray(value, fallback) {
|
|
if (Array.isArray(value) && value.length > 0) {
|
|
return value;
|
|
}
|
|
return fallback;
|
|
}
|
|
|
|
function mapEntry(entry, category) {
|
|
const productId = buildProductId(entry);
|
|
if (!productId) {
|
|
return null;
|
|
}
|
|
|
|
const output = {
|
|
productId,
|
|
type: category,
|
|
displayName: entry.name,
|
|
repoUrl: entry.repo,
|
|
tagline: entry.tagline,
|
|
description: entry.description,
|
|
scope: sanitizeArray(entry.scope, ['global']),
|
|
tags: sanitizeArray(entry.tags, []),
|
|
homepageUrl: entry.homepage,
|
|
installation: entry.installation,
|
|
minVersion: entry.min_version
|
|
};
|
|
|
|
return output;
|
|
}
|
|
|
|
function stripUndefined(data) {
|
|
const cleaned = {};
|
|
for (const [key, value] of Object.entries(data)) {
|
|
if (value !== undefined) {
|
|
cleaned[key] = value;
|
|
}
|
|
}
|
|
return cleaned;
|
|
}
|
|
|
|
async function loadEntries() {
|
|
const results = [];
|
|
const errors = [];
|
|
|
|
for (const category of CATEGORIES) {
|
|
const categoryPath = path.join(__dirname, '../data', category);
|
|
let entries = [];
|
|
|
|
try {
|
|
entries = await readYamlDir(categoryPath);
|
|
} catch (err) {
|
|
if (err.code === 'ENOENT') {
|
|
continue;
|
|
}
|
|
throw err;
|
|
}
|
|
|
|
for (const entry of entries) {
|
|
const result = validateEntry(entry, entry._filePath || categoryPath);
|
|
if (!result.valid) {
|
|
errors.push(formatValidationErrors(result));
|
|
continue;
|
|
}
|
|
|
|
const mapped = mapEntry(entry, category);
|
|
if (mapped) {
|
|
results.push(stripUndefined(mapped));
|
|
}
|
|
}
|
|
}
|
|
|
|
return { results, errors };
|
|
}
|
|
|
|
async function main() {
|
|
const { outputPath, pretty } = parseArgs(process.argv.slice(2));
|
|
const writeToStdout = !outputPath;
|
|
const log = (...args) => {
|
|
if (writeToStdout) {
|
|
console.error(...args);
|
|
} else {
|
|
console.log(...args);
|
|
}
|
|
};
|
|
|
|
const { results, errors } = await loadEntries();
|
|
|
|
results.sort((a, b) => {
|
|
const typeCompare = a.type.localeCompare(b.type);
|
|
if (typeCompare !== 0) {
|
|
return typeCompare;
|
|
}
|
|
return a.productId.localeCompare(b.productId);
|
|
});
|
|
|
|
if (errors.length > 0) {
|
|
for (const error of errors) {
|
|
log(error);
|
|
}
|
|
log(`\n⚠️ Skipped ${errors.length} invalid entr${errors.length === 1 ? 'y' : 'ies'}.`);
|
|
}
|
|
|
|
const json = JSON.stringify(results, null, pretty ? 2 : 0);
|
|
|
|
if (outputPath) {
|
|
const outputDir = path.dirname(outputPath);
|
|
if (outputDir && outputDir !== '.') {
|
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
}
|
|
fs.writeFileSync(outputPath, json);
|
|
log(`Saved ${results.length} entries to ${outputPath}`);
|
|
} else {
|
|
process.stdout.write(json);
|
|
}
|
|
|
|
if (errors.length > 0) {
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error('Export failed:', err.message);
|
|
process.exit(1);
|
|
});
|