mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
205 lines
6.9 KiB
TypeScript
205 lines
6.9 KiB
TypeScript
import * as fs from 'node:fs';
|
|
import * as path from 'node:path';
|
|
import { MediaReferenceSchema } from '../../../src/types/media-reference.js';
|
|
import {
|
|
generateComponentReferences,
|
|
generateFeatureReferences,
|
|
generateMediaElementReferences,
|
|
generatePresetReferences,
|
|
} from './pipeline.js';
|
|
import { ComponentReferenceSchema, FeatureReferenceSchema, PresetReferenceSchema } from './types.js';
|
|
import { generateUtilReferences } from './util-handler.js';
|
|
|
|
// Magenta prefix - visible on both light and dark terminals
|
|
const PREFIX = '\x1b[35m[api-docs-builder]\x1b[0m';
|
|
|
|
const log = {
|
|
info: (...args: unknown[]) => console.log(PREFIX, ...args),
|
|
warn: (...args: unknown[]) => console.warn(PREFIX, '\x1b[33mwarn:\x1b[0m', ...args),
|
|
error: (...args: unknown[]) => console.error(PREFIX, '\x1b[31merror:\x1b[0m', ...args),
|
|
success: (...args: unknown[]) => console.log(PREFIX, ...args),
|
|
};
|
|
|
|
// Paths relative to the monorepo root
|
|
const MONOREPO_ROOT = path.resolve(import.meta.dirname, '../../../../');
|
|
const COMPONENT_OUTPUT_PATH = path.join(MONOREPO_ROOT, 'site/src/content/generated-component-reference');
|
|
const UTIL_OUTPUT_PATH = path.join(MONOREPO_ROOT, 'site/src/content/generated-util-reference');
|
|
const FEATURE_OUTPUT_PATH = path.join(MONOREPO_ROOT, 'site/src/content/generated-feature-reference');
|
|
const MEDIA_OUTPUT_PATH = path.join(MONOREPO_ROOT, 'site/src/content/generated-media-reference');
|
|
const PRESET_OUTPUT_PATH = path.join(MONOREPO_ROOT, 'site/src/content/generated-preset-reference');
|
|
|
|
/**
|
|
* Main entry point.
|
|
*/
|
|
function main() {
|
|
// typescript-api-extractor doesn't handle the `never` TypeScript type flag
|
|
// (or a few others like ESSymbol, TemplateLiteral). It falls back to `any`
|
|
// and logs a warning for each occurrence. This is a known gap in the alpha
|
|
// library — not a bug in our types. Suppress the noise here.
|
|
const originalWarn = console.warn;
|
|
console.warn = (...args: unknown[]) => {
|
|
if (typeof args[0] === 'string' && args[0].startsWith('Unable to handle a type with flag')) return;
|
|
originalWarn.apply(console, args);
|
|
};
|
|
|
|
// Ensure output directories exist
|
|
for (const dir of [
|
|
COMPONENT_OUTPUT_PATH,
|
|
UTIL_OUTPUT_PATH,
|
|
FEATURE_OUTPUT_PATH,
|
|
MEDIA_OUTPUT_PATH,
|
|
PRESET_OUTPUT_PATH,
|
|
]) {
|
|
if (!fs.existsSync(dir)) {
|
|
fs.mkdirSync(dir, { recursive: true });
|
|
}
|
|
}
|
|
|
|
// Generate component references via pipeline
|
|
const componentResults = generateComponentReferences(MONOREPO_ROOT);
|
|
|
|
if (componentResults.length === 0) {
|
|
log.info('No components found.');
|
|
} else {
|
|
log.info(`Found ${componentResults.length} components. Processing...`);
|
|
}
|
|
|
|
let successCount = 0;
|
|
let errorCount = 0;
|
|
|
|
for (const result of componentResults) {
|
|
// Validate against schema before writing
|
|
const validated = ComponentReferenceSchema.safeParse(result.reference);
|
|
if (!validated.success) {
|
|
log.error(`Schema validation failed for ${result.name}:`);
|
|
for (const issue of validated.error.issues) {
|
|
log.error(` - ${issue.path.join('.')}: ${issue.message}`);
|
|
}
|
|
errorCount++;
|
|
continue;
|
|
}
|
|
|
|
// Write JSON file
|
|
const outputFile = path.join(COMPONENT_OUTPUT_PATH, `${result.kebab}.json`);
|
|
const json = `${JSON.stringify(validated.data, null, 2)}\n`;
|
|
fs.writeFileSync(outputFile, json);
|
|
|
|
log.success(`✅ Generated ${path.basename(outputFile)}`);
|
|
successCount++;
|
|
}
|
|
|
|
log.info(`Done! Generated ${successCount} component files.`);
|
|
|
|
// Generate util references
|
|
const utilResult = generateUtilReferences(UTIL_OUTPUT_PATH, MONOREPO_ROOT);
|
|
successCount += utilResult.success;
|
|
errorCount += utilResult.errors;
|
|
|
|
log.info(`Done! Generated ${utilResult.success} util files.`);
|
|
|
|
// Generate feature references
|
|
const featureResults = generateFeatureReferences(MONOREPO_ROOT);
|
|
|
|
if (featureResults.length === 0) {
|
|
log.info('No features found.');
|
|
} else {
|
|
log.info(`Found ${featureResults.length} features. Processing...`);
|
|
}
|
|
|
|
let featureSuccessCount = 0;
|
|
for (const result of featureResults) {
|
|
const validated = FeatureReferenceSchema.safeParse(result.reference);
|
|
if (!validated.success) {
|
|
log.error(`Schema validation failed for feature ${result.name}:`);
|
|
for (const issue of validated.error.issues) {
|
|
log.error(` - ${issue.path.join('.')}: ${issue.message}`);
|
|
}
|
|
errorCount++;
|
|
continue;
|
|
}
|
|
|
|
const outputFile = path.join(FEATURE_OUTPUT_PATH, `${result.slug}.json`);
|
|
const json = `${JSON.stringify(validated.data, null, 2)}\n`;
|
|
fs.writeFileSync(outputFile, json);
|
|
|
|
log.success(`✅ Generated ${path.basename(outputFile)}`);
|
|
featureSuccessCount++;
|
|
successCount++;
|
|
}
|
|
|
|
log.info(`Done! Generated ${featureSuccessCount} feature files.`);
|
|
|
|
// Generate media element references
|
|
const mediaResults = generateMediaElementReferences(MONOREPO_ROOT);
|
|
|
|
if (mediaResults.length === 0) {
|
|
log.info('No media elements found.');
|
|
} else {
|
|
log.info(`Found ${mediaResults.length} media elements. Processing...`);
|
|
}
|
|
|
|
let mediaSuccessCount = 0;
|
|
for (const result of mediaResults) {
|
|
const validated = MediaReferenceSchema.safeParse(result.reference);
|
|
if (!validated.success) {
|
|
log.error(`Schema validation failed for media element ${result.name}:`);
|
|
for (const issue of validated.error.issues) {
|
|
log.error(` - ${issue.path.join('.')}: ${issue.message}`);
|
|
}
|
|
errorCount++;
|
|
continue;
|
|
}
|
|
|
|
const outputFile = path.join(MEDIA_OUTPUT_PATH, `${validated.data.tagName}.json`);
|
|
const json = `${JSON.stringify(validated.data, null, 2)}\n`;
|
|
fs.writeFileSync(outputFile, json);
|
|
|
|
log.success(`✅ Generated ${path.basename(outputFile)}`);
|
|
mediaSuccessCount++;
|
|
successCount++;
|
|
}
|
|
|
|
log.info(`Done! Generated ${mediaSuccessCount} media element files.`);
|
|
|
|
// Generate preset references
|
|
const presetResults = generatePresetReferences(MONOREPO_ROOT);
|
|
|
|
if (presetResults.length === 0) {
|
|
log.info('No presets found.');
|
|
} else {
|
|
log.info(`Found ${presetResults.length} presets. Processing...`);
|
|
}
|
|
|
|
let presetSuccessCount = 0;
|
|
for (const result of presetResults) {
|
|
const validated = PresetReferenceSchema.safeParse(result.reference);
|
|
if (!validated.success) {
|
|
log.error(`Schema validation failed for preset ${result.name}:`);
|
|
for (const issue of validated.error.issues) {
|
|
log.error(` - ${issue.path.join('.')}: ${issue.message}`);
|
|
}
|
|
errorCount++;
|
|
continue;
|
|
}
|
|
|
|
const outputFile = path.join(PRESET_OUTPUT_PATH, `${result.name}.json`);
|
|
const json = `${JSON.stringify(validated.data, null, 2)}\n`;
|
|
fs.writeFileSync(outputFile, json);
|
|
|
|
log.success(`✅ Generated ${path.basename(outputFile)}`);
|
|
presetSuccessCount++;
|
|
successCount++;
|
|
}
|
|
|
|
log.info(`Done! Generated ${presetSuccessCount} preset files.`);
|
|
|
|
console.warn = originalWarn;
|
|
|
|
if (errorCount > 0) {
|
|
log.error(`${errorCount} errors occurred.`);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
main();
|