(version, sourceDir)
| 492 | const { lint: lintUniversalDocParity } = require('./lint-universal-storyboard-doc-parity.cjs'); |
| 493 | |
| 494 | function generateIndex(version, sourceDir) { |
| 495 | const specialisms = discoverSpecialisms(sourceDir); |
| 496 | const protocols = discoverProtocols(sourceDir, specialisms); |
| 497 | verifyEnumParity(specialisms, protocols); |
| 498 | const docParityErrors = lintUniversalDocParity({ sourceDir }); |
| 499 | if (docParityErrors.length) { |
| 500 | throw new Error('Universal-storyboard doc parity drift:\n - ' + docParityErrors.join('\n - ')); |
| 501 | } |
| 502 | lintStoryboardIdempotency(sourceDir, SCHEMAS_DIR); |
| 503 | const universalDir = path.join(sourceDir, 'universal'); |
| 504 | const universal = fs.existsSync(universalDir) |
| 505 | ? fs.readdirSync(universalDir) |
| 506 | .filter(f => f.endsWith('.yaml')) |
| 507 | .map(f => f.replace(/\.yaml$/, '')) |
| 508 | .sort() |
| 509 | : []; |
| 510 | |
| 511 | const protocolEntries = protocols.map(d => ({ |
| 512 | id: d.id, |
| 513 | title: d.title, |
| 514 | has_baseline: d.has_baseline, |
| 515 | path: d.path, |
| 516 | })); |
| 517 | // Transitional alias for @adcp/client consumers that read `domains` and expect |
| 518 | // `domains/{id}/` on-disk paths. Drop after v6 ships and all consumers upgrade. |
| 519 | const domainAliasEntries = protocols.map(d => ({ |
| 520 | id: d.id, |
| 521 | title: d.title, |
| 522 | has_baseline: d.has_baseline, |
| 523 | path: d.path.replace(/^protocols\//, 'domains/'), |
| 524 | })); |
| 525 | |
| 526 | // published_version: full semver of this compliance bundle. |
| 527 | // adcp_version: legacy alias kept through 3.x for @adcp/client compatibility |
| 528 | // (ComplianceIndex.adcp_version). Both carry full semver; distinct from the |
| 529 | // wire field in core/version-envelope.json (release-precision). |
| 530 | return { |
| 531 | published_version: version, |
| 532 | adcp_version: version, |
| 533 | generated_at: new Date().toISOString(), |
| 534 | universal, |
| 535 | protocols: protocolEntries, |
| 536 | domains: domainAliasEntries, |
| 537 | specialisms: specialisms.map(s => ({ |
| 538 | id: s.id, |
| 539 | protocol: s.protocol, |
| 540 | domain: s.protocol, |
| 541 | title: s.title, |
| 542 | status: s.status, |
| 543 | required_tools: s.required_tools, |
| 544 | ...(s.required_any_of_tools ? { required_any_of_tools: s.required_any_of_tools } : {}), |
| 545 | path: s.path |
| 546 | })) |
| 547 | }; |
| 548 | } |
| 549 | |
| 550 | function mirrorProtocolsToDomains(targetDir) { |
| 551 | const protocolsDir = path.join(targetDir, 'protocols'); |
no test coverage detected