/** * Generador de documentación de contratos data-* * * Este script lee el registro CONTRACTS y genera un markdown * con la documentación de todos los data-attrs de cada componente. * * Uso: * npm run generate:contracts-docs * o * node scripts/generate-contracts-docs.js */ import { CONTRACTS } from '../src/uix/terra/utils/contracts.ts'; import { existsSync, writeFileSync } from 'node:fs'; import { resolve, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // ──────────────────────────────────────────────────────────────────────────────── // Helpers de formateo // ──────────────────────────────────────────────────────────────────────────────── function toKebabCase(str: string): string { return str .replace(/([a-z])([A-Z])/g, '$1-$2') .replace(/[\s_]+/g, '-') .toLowerCase(); } function formatComponentName(name: string): string { return `\`${name}\``; } function formatAttrValue(values?: readonly string[]): string { if (!values) return '(flag)'; return values.map((v) => `\`${v}\``).join(' \\| '); } // ──────────────────────────────────────────────────────────────────────────────── // Generación de markdown // ──────────────────────────────────────────────────────────────────────────────── let markdown = `# Terra Data Attributes Contracts `; markdown += `> Contrato formal de atributos \`data-*\` entre Terra y Air. > Generado automáticamente desde \`src/uix/terra/utils/contracts.ts\`. > > ⚠️ **Estos attrs son API PÚBLICA.** Cambiarlos es un breaking change. > `; markdown += `--- `; markdown += `\n`; markdown += `## Índice `; markdown += `\n`; // Tabla de contenidos for (const [name, contract] of Object.entries(CONTRACTS)) { markdown += `- [${name}](#${toKebabCase(name)})\n`; } markdown += `\n`; markdown += `---\n`; markdown += `\n`; // Generar documentación por componente for (const [name, contract] of Object.entries(CONTRACTS)) { markdown += `## ${name}\n\n`; markdown += `**Versión del contrato:** ${contract.version}\n\n`; if (Object.keys(contract.parts).length === 0) { markdown += `*Sin partes documentadas*\n\n`; continue; } for (const [partName, attrs] of Object.entries(contract.parts)) { markdown += `### ${partName === 'root' ? 'Root' : partName.charAt(0).toUpperCase() + partName.slice(1)}\n\n`; markdown += `| Attr | Valores | Descripción |\n`; markdown += `|-----|---------|-------------|\n`; for (const attr of attrs) { const values = formatAttrValue(attr.values); const description = attr.description || ''; markdown += `| \`${attr.attr}\` | ${values} | ${description} |\n`; } markdown += `\n`; } markdown += `---\n\n`; } // ──────────────────────────────────────────────────────────────────────────────── // Escribir archivo // ──────────────────────────────────────────────────────────────────────────────── const outputPath = resolve(__dirname, '..', 'DATA_ATTRS.md'); writeFileSync(outputPath, markdown); console.log(`✅ Documentación generada: ${outputPath}`); console.log(` ${Object.keys(CONTRACTS).length} componentes documentados`);