123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- import * as path from "path";
- import * as Filesystem from "./filesystem";
- import * as MappingEntry from "./mapping-entry";
- import * as TryPath from "./try-path";
- /**
- * Function that can match a path
- */
- export interface MatchPath {
- (
- requestedModule: string,
- readJson?: Filesystem.ReadJsonSync,
- fileExists?: (name: string) => boolean,
- extensions?: ReadonlyArray<string>
- ): string | undefined;
- }
- /**
- * Creates a function that can resolve paths according to tsconfig paths property.
- * @param absoluteBaseUrl Absolute version of baseUrl as specified in tsconfig.
- * @param paths The paths as specified in tsconfig.
- * @param mainFields A list of package.json field names to try when resolving module files.
- * @param addMatchAll Add a match-all "*" rule if none is present
- * @returns a function that can resolve paths.
- */
- export function createMatchPath(
- absoluteBaseUrl: string,
- paths: { [key: string]: Array<string> },
- mainFields: string[] = ["main"],
- addMatchAll: boolean = true
- ): MatchPath {
- const absolutePaths = MappingEntry.getAbsoluteMappingEntries(
- absoluteBaseUrl,
- paths,
- addMatchAll
- );
- return (
- requestedModule: string,
- readJson?: Filesystem.ReadJsonSync,
- fileExists?: Filesystem.FileExistsSync,
- extensions?: Array<string>
- ) =>
- matchFromAbsolutePaths(
- absolutePaths,
- requestedModule,
- readJson,
- fileExists,
- extensions,
- mainFields
- );
- }
- /**
- * Finds a path from tsconfig that matches a module load request.
- * @param absolutePathMappings The paths to try as specified in tsconfig but resolved to absolute form.
- * @param requestedModule The required module name.
- * @param readJson Function that can read json from a path (useful for testing).
- * @param fileExists Function that checks for existence of a file at a path (useful for testing).
- * @param extensions File extensions to probe for (useful for testing).
- * @param mainFields A list of package.json field names to try when resolving module files.
- * @returns the found path, or undefined if no path was found.
- */
- export function matchFromAbsolutePaths(
- absolutePathMappings: ReadonlyArray<MappingEntry.MappingEntry>,
- requestedModule: string,
- readJson: Filesystem.ReadJsonSync = Filesystem.readJsonFromDiskSync,
- fileExists: Filesystem.FileExistsSync = Filesystem.fileExistsSync,
- extensions: Array<string> = Object.keys(require.extensions),
- mainFields: string[] = ["main"]
- ): string | undefined {
- const tryPaths = TryPath.getPathsToTry(
- extensions,
- absolutePathMappings,
- requestedModule
- );
- if (!tryPaths) {
- return undefined;
- }
- return findFirstExistingPath(tryPaths, readJson, fileExists, mainFields);
- }
- function findFirstExistingMainFieldMappedFile(
- packageJson: Filesystem.PackageJson,
- mainFields: string[],
- packageJsonPath: string,
- fileExists: Filesystem.FileExistsSync
- ): string | undefined {
- for (let index = 0; index < mainFields.length; index++) {
- const mainFieldName = mainFields[index];
- const candidateMapping = packageJson[mainFieldName];
- if (candidateMapping && typeof candidateMapping === "string") {
- const candidateFilePath = path.join(
- path.dirname(packageJsonPath),
- candidateMapping
- );
- if (fileExists(candidateFilePath)) {
- return candidateFilePath;
- }
- }
- }
- return undefined;
- }
- function findFirstExistingPath(
- tryPaths: ReadonlyArray<TryPath.TryPath>,
- readJson: Filesystem.ReadJsonSync = Filesystem.readJsonFromDiskSync,
- fileExists: Filesystem.FileExistsSync,
- mainFields: string[] = ["main"]
- ): string | undefined {
- for (const tryPath of tryPaths) {
- if (
- tryPath.type === "file" ||
- tryPath.type === "extension" ||
- tryPath.type === "index"
- ) {
- if (fileExists(tryPath.path)) {
- return TryPath.getStrippedPath(tryPath);
- }
- } else if (tryPath.type === "package") {
- const packageJson: Filesystem.PackageJson = readJson(tryPath.path);
- if (packageJson) {
- const mainFieldMappedFile = findFirstExistingMainFieldMappedFile(
- packageJson,
- mainFields,
- tryPath.path,
- fileExists
- );
- if (mainFieldMappedFile) {
- return mainFieldMappedFile;
- }
- }
- } else {
- TryPath.exhaustiveTypeException(tryPath.type);
- }
- }
- return undefined;
- }
|