( metadata: PackageMetadata, filename: string )
| 686 | specificity: prefix.length + suffix.length, |
| 687 | prefixLength: prefix.length |
| 688 | }) |
| 689 | } |
| 690 | return matches.sort((a, b) => |
| 691 | b.specificity - a.specificity || b.prefixLength - a.prefixLength || b.key.length - a.key.length |
| 692 | )[0] |
| 693 | } |
| 694 | |
| 695 | function packageExportTargetMatches(value: unknown, star: string | null, expectedTarget: string): boolean { |
| 696 | if (typeof value === "string") { |
| 697 | const target = normalizePackagePath(star === null ? value : value.replaceAll("*", star)) |
| 698 | return target === expectedTarget |
| 699 | } |
| 700 | if (value === null || value === undefined) { |
| 701 | return false |
| 702 | } |
| 703 | if (Array.isArray(value)) { |
| 704 | return value.some((item) => packageExportTargetMatches(item, star, expectedTarget)) |
| 705 | } |
| 706 | if (isRecord(value)) { |
| 707 | return Object.values(value).some((item) => packageExportTargetMatches(item, star, expectedTarget)) |
| 708 | } |
| 709 | return false |
| 710 | } |
| 711 | |
| 712 | function isPackageSubpathExported( |
| 713 | packageExports: unknown, |
| 714 | subpath: string, |
| 715 | expectedTarget: string |
| 716 | ): boolean { |
| 717 | const match = getPackageExportMatch(packageExports, subpath) |
| 718 | return match !== undefined && packageExportTargetMatches(match.value, match.star, expectedTarget) |
| 719 | } |
| 720 | |
| 721 | function isPathInside(parent: string, child: string): boolean { |
| 722 | const relative = path.relative(parent, child) |
| 723 | return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative)) |
| 724 | } |
| 725 | |
| 726 | function packageSpecifier(packageName: string, subpath: string): string { |
| 727 | return subpath === "" ? packageName : `${packageName}/${subpath}` |
| 728 | } |
| 729 | |
| 730 | function resolveBarrelImport( |
| 731 | metadata: PackageMetadata, |
| 732 | filename: string |
| 733 | ): Result<{ readonly barrel: ParsedJSDocBarrelImport | null; readonly flatNames: ReadonlyArray<string> }, string> { |
| 734 | let directory = path.dirname(filename) |
| 735 | while (isPathInside(metadata.sourceRoot, directory)) { |
| 736 | const indexPath = path.join(directory, "index.ts") |
| 737 | if (indexPath !== filename && fs.existsSync(indexPath)) { |
no test coverage detected
searching dependent graphs…