( options: ExtractSnapshotOptions, discovered: DiscoveryResult, path: Path.Path )
| 720 | }) |
| 721 | |
| 722 | const extractSnapshot = ( |
| 723 | options: ExtractSnapshotOptions, |
| 724 | discovered: DiscoveryResult, |
| 725 | path: Path.Path |
| 726 | ): ApiSnapshot => { |
| 727 | const diagnostics: Array<SnapshotDiagnostic> = discovered.missing.map((module) => ({ |
| 728 | code: "missing-entrypoint", |
| 729 | message: `Consumer-visible declaration entrypoint not found: ${module}`, |
| 730 | module |
| 731 | })) |
| 732 | if (diagnostics.length > 0) { |
| 733 | throw snapshotExtractionError(diagnostics) |
| 734 | } |
| 735 | const program = ts.createProgram({ |
| 736 | rootNames: discovered.entrypoints.map((entrypoint) => entrypoint.declarationFile), |
| 737 | options: { |
| 738 | module: ts.ModuleKind.NodeNext, |
| 739 | moduleResolution: ts.ModuleResolutionKind.NodeNext, |
| 740 | target: ts.ScriptTarget.ESNext, |
| 741 | skipLibCheck: true, |
| 742 | types: [], |
| 743 | noEmit: true |
| 744 | } |
| 745 | }) |
| 746 | // The declarations were already checked by the branch-native build. Re-checking |
| 747 | // them with the pinned extractor compiler would introduce lib-version drift. |
| 748 | const compilerDiagnostics = program.getSyntacticDiagnostics() |
| 749 | .filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error) |
| 750 | if (compilerDiagnostics.length > 0) { |
| 751 | throw snapshotExtractionError(compilerDiagnostics.map((diagnostic) => ({ |
| 752 | code: `typescript-${diagnostic.code}`, |
| 753 | message: ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"), |
| 754 | source: diagnostic.file === undefined |
| 755 | ? undefined |
| 756 | : sourceLocation(path, options.repoRoot, diagnostic.file) |
| 757 | }))) |
| 758 | } |
| 759 | const checker = program.getTypeChecker() |
| 760 | const pending = new Map<string, PendingEntity>() |
| 761 | for (const entrypoint of discovered.entrypoints) { |
| 762 | const source = program.getSourceFile(entrypoint.declarationFile) |
| 763 | const symbol = source === undefined ? undefined : checker.getSymbolAtLocation(source) |
| 764 | if (source === undefined || symbol === undefined) { |
| 765 | diagnostics.push({ |
| 766 | code: "missing-module-symbol", |
| 767 | message: `Could not load module symbol for ${entrypoint.module}`, |
| 768 | module: entrypoint.module |
| 769 | }) |
| 770 | continue |
| 771 | } |
| 772 | collectExports(checker, symbol, entrypoint, pending) |
| 773 | } |
| 774 | |
| 775 | const entities: Array<ApiEntity> = [] |
| 776 | const publicSymbols = new Map<string, string>() |
| 777 | for (const [key, pendingEntity] of pending) { |
| 778 | const route = canonicalRoute(pendingEntity.routes) |
| 779 | publicSymbols.set(key, `${route.module}#${route.path.join(".")}#${pendingEntity.bucket}`) |
no test coverage detected