import * as path from "path" ; import { MappingEntry } from "./mapping-entry" ; import { dirname } from "path" ; import { removeExtension } from "./filesystem" ; export interface TryPath { readonly type : "file" | "extension" | "index" | "package" ; readonly path : string ; } /**
 * Builds a list of all physical paths to try by:
 * 1. Check for file named exactly as request.
 * 2. Check for files named as request ending in any of the extensions.
 * 3. Check for file specified in package.json's main property.
 * 4. Check for files named as request ending in "index" with any of the extensions.
 */ export function getPathsToTry ( extensions , absolutePathMappings , requestedModule ) { if ( ! absolutePathMappings || ! requestedModule || requestedModule [ 0 ] === "." || requestedModule [ 0 ] === path . sep ) { return undefined ; } const pathsToTry = [ ] ; for ( const entry of absolutePathMappings ) { const starMatch = entry . pattern === requestedModule ? "" : matchStar ( entry . pattern , requestedModule ) ; if ( starMatch !== undefined ) { for ( const physicalPathPattern of entry . paths ) { const physicalPath = physicalPathPattern . replace ( "*" , starMatch ) ; pathsToTry . push ( { type : "file" , path : physicalPath } ) ; pathsToTry . push ( ... extensions . map ( ( e ) => ( { type : "extension" , path : physicalPath + e } as TryPath ) ) ) ; pathsToTry . push ( { type : "package" , path : path . join ( physicalPath , "/package.json" ) , } ) ; const indexPath = path . join ( physicalPath , "/index" ) ; pathsToTry . push ( ... extensions . map ( ( e ) => ( { type : "index" , path : indexPath + e } as TryPath ) ) ) ; } } } return pathsToTry . length === 0 ? undefined : pathsToTry ; } export function getStrippedPath ( tryPath ) { return tryPath . type === "index" ? dirname ( tryPath . path ) : tryPath . type === "file" ? tryPath . path : tryPath . type === "extension" ? removeExtension ( tryPath . path ) : tryPath . type === "package" ? tryPath . path : exhaustiveTypeException ( tryPath . type ) ; } export function exhaustiveTypeException ( check ) { throw new Error ( `Unknown type ${ check }` ) ; } param patttern param search returns function matchStar ( pattern , search ) { if ( search . length < pattern . length ) { return undefined ; } if ( pattern === "*" ) { return search ; } const star = pattern . indexOf ( "*" ) ; if ( star === - 1 ) { return undefined ; } const part1 = pattern . substring ( 0 , star ) ; const part2 = pattern . substring ( star + 1 ) ; if ( search . substr ( 0 , star ) !== part1 ) { return undefined ; } if ( search . substr ( search . length - part2 . length ) !== part2 ) { return undefined ; } return search . substr ( star , search . length - part2 . length ) ; }