blob: 7de6cefe36bfce030bfb9a7650a5e2b6b2a35da9 [file]
const fs = require('fs');
const path = require('path');
const { execFileSync } = require('child_process');
const PUBLIC_DIR = 'public';
const CAMEL_REPO = 'apache/camel';
const CATALOG_BASE = 'catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog';
const YAML_SCHEMA_PATH = 'dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json';
const CATALOG_DIRS = ['components', 'dataformats', 'languages', 'models', 'others'];
const VERSION_DIRS = [
'components'
];
const SHARED_DIRS = [
'manual'
];
function fetchCatalogAndSchema(version) {
const branch = `camel-${version}.x`;
const catalogDir = path.join(PUBLIC_DIR, 'catalog');
console.log(`\nFetching catalog and YAML DSL schema from ${CAMEL_REPO}@${branch}...`);
// fetch YAML DSL canonical schema
const schemaDir = path.join(catalogDir, 'schema');
fs.mkdirSync(schemaDir, { recursive: true });
try {
const schema = execFileSync('gh', [
'api', `repos/${CAMEL_REPO}/contents/${YAML_SCHEMA_PATH}?ref=${branch}`,
'--jq', '.content'
], { encoding: 'utf8' });
fs.writeFileSync(
path.join(schemaDir, 'camelYamlDsl-canonical.json'),
Buffer.from(schema.trim(), 'base64').toString('utf8')
);
console.log(' Fetched schema/camelYamlDsl-canonical.json');
} catch (error) {
console.warn(` Could not fetch YAML DSL schema: ${error.message}`);
}
// fetch catalog JSON files for each category
for (const dir of CATALOG_DIRS) {
const targetDir = path.join(catalogDir, dir);
fs.mkdirSync(targetDir, { recursive: true });
try {
const files = execFileSync('gh', [
'api', `repos/${CAMEL_REPO}/contents/${CATALOG_BASE}/${dir}?ref=${branch}`,
'--jq', '.[].name'
], { encoding: 'utf8' }).trim().split('\n').filter(f => f.endsWith('.json'));
console.log(` Fetching catalog/${dir}/ (${files.length} files)...`);
for (const file of files) {
try {
const content = execFileSync('gh', [
'api', `repos/${CAMEL_REPO}/contents/${CATALOG_BASE}/${dir}/${file}?ref=${branch}`,
'--jq', '.content'
], { encoding: 'utf8' });
fs.writeFileSync(
path.join(targetDir, file),
Buffer.from(content.trim(), 'base64').toString('utf8')
);
} catch {
// skip individual file failures silently
}
}
} catch (error) {
console.warn(` Could not fetch catalog/${dir}: ${error.message}`);
}
}
return fs.existsSync(catalogDir);
}
function main() {
const version = process.argv[2];
if (!version) {
console.error('Usage: node scripts/generate-offline-bundle.js <version>');
console.error('Example: node scripts/generate-offline-bundle.js 4.18');
process.exit(1);
}
const versionDir = `${version}.x`;
const bundleName = `camel-docs-${version}.zip`;
const bundlePath = path.join(PUBLIC_DIR, bundleName);
if (!fs.existsSync(PUBLIC_DIR)) {
console.error(`Cannot generate ${bundleName}: '${PUBLIC_DIR}' directory not found`);
process.exit(1);
}
// collect paths to include (relative to public/)
const includePaths = [];
for (const dir of VERSION_DIRS) {
const fullPath = path.join(PUBLIC_DIR, dir, versionDir);
if (fs.existsSync(fullPath)) {
includePaths.push(`${dir}/${versionDir}/*`);
console.log(` Including ${dir}/${versionDir}/`);
} else {
console.warn(` Skipping ${dir}/${versionDir}/ (not found)`);
}
}
for (const dir of SHARED_DIRS) {
const fullPath = path.join(PUBLIC_DIR, dir);
if (fs.existsSync(fullPath)) {
includePaths.push(`${dir}/*`);
console.log(` Including ${dir}/`);
}
}
if (includePaths.length === 0) {
console.error(`No documentation directories found for version ${version}`);
process.exit(1);
}
// always include llms.txt if present
if (fs.existsSync(path.join(PUBLIC_DIR, 'llms.txt'))) {
includePaths.push('llms.txt');
}
// fetch catalog and YAML DSL schema from the camel repo
if (fetchCatalogAndSchema(version)) {
includePaths.push('catalog/*');
}
// remove stale bundle
if (fs.existsSync(bundlePath)) {
fs.unlinkSync(bundlePath);
}
// build zip: include .md files from doc dirs, plus .json from catalog, plus llms.txt
const zipArgs = ['-r', '-q', bundleName, '.'];
for (const p of includePaths) {
if (p === 'llms.txt') {
zipArgs.push('-i', 'llms.txt');
} else if (p.startsWith('catalog/')) {
zipArgs.push('-i', `${p}.json`);
} else {
zipArgs.push('-i', `${p}.md`);
}
}
try {
execFileSync('zip', zipArgs, { cwd: PUBLIC_DIR, stdio: 'inherit' });
const sizeMb = (fs.statSync(bundlePath).size / (1024 * 1024)).toFixed(1);
console.log(`\nGenerated ${bundleName} (${sizeMb} MB)`);
} catch (error) {
console.error(`Failed to generate ${bundleName}:`, error.message);
process.exit(1);
}
}
main();