99 CommandLineOption ,
1010 comparePaths ,
1111 Comparison ,
12+ CompilerHost ,
1213 CompilerOptions ,
1314 concatenate ,
1415 contains ,
@@ -36,10 +37,12 @@ import {
3637 forEachAncestorDirectory ,
3738 formatMessage ,
3839 getAllowJSCompilerOption ,
40+ getAnyExtensionFromPath ,
3941 getBaseFileName ,
4042 GetCanonicalFileName ,
4143 getCommonSourceDirectory ,
4244 getCompilerOptionValue ,
45+ getDeclarationEmitExtensionForPath ,
4346 getDirectoryPath ,
4447 GetEffectiveTypeRootsHost ,
4548 getEmitModuleKind ,
@@ -99,6 +102,7 @@ import {
99102 startsWith ,
100103 stringContains ,
101104 supportedDeclarationExtensions ,
105+ supportedJSExtensionsFlat ,
102106 supportedTSImplementationExtensions ,
103107 toPath ,
104108 tryExtractTSExtension ,
@@ -194,6 +198,15 @@ function formatExtensions(extensions: Extensions) {
194198 return result . join ( ", " ) ;
195199}
196200
201+ function extensionsToExtensionsArray ( extensions : Extensions ) {
202+ const result : Extension [ ] = [ ] ;
203+ if ( extensions & Extensions . TypeScript ) result . push ( ...supportedTSImplementationExtensions ) ;
204+ if ( extensions & Extensions . JavaScript ) result . push ( ...supportedJSExtensionsFlat ) ;
205+ if ( extensions & Extensions . Declaration ) result . push ( ...supportedDeclarationExtensions ) ;
206+ if ( extensions & Extensions . Json ) result . push ( Extension . Json ) ;
207+ return result ;
208+ }
209+
197210interface PathAndPackageId {
198211 readonly fileName : string ;
199212 readonly packageId : PackageId | undefined ;
@@ -2085,11 +2098,16 @@ function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string,
20852098 return withPackageId ( packageInfo , loadNodeModuleFromDirectoryWorker ( extensions , candidate , onlyRecordFailures , state , packageJsonContent , versionPaths ) ) ;
20862099}
20872100
2101+ /** @internal */
2102+ export interface GetPackageJsonEntrypointsHost extends ModuleResolutionHost {
2103+ readDirectory : CompilerHost [ "readDirectory" ] ;
2104+ }
2105+
20882106/** @internal */
20892107export function getEntrypointsFromPackageJsonInfo (
20902108 packageJsonInfo : PackageJsonInfo ,
20912109 options : CompilerOptions ,
2092- host : ModuleResolutionHost ,
2110+ host : GetPackageJsonEntrypointsHost ,
20932111 cache : ModuleResolutionCache | undefined ,
20942112 resolveJs ?: boolean ,
20952113) : string [ ] | false {
@@ -2120,7 +2138,7 @@ export function getEntrypointsFromPackageJsonInfo(
21202138 arrayIsEqualTo
21212139 ) ;
21222140 for ( const conditions of conditionSets ) {
2123- const loadPackageJsonExportsState = { ...loadPackageJsonMainState , failedLookupLocations : [ ] , conditions } ;
2141+ const loadPackageJsonExportsState = { ...loadPackageJsonMainState , failedLookupLocations : [ ] , conditions, host } ;
21242142 const exportResolutions = loadEntrypointsFromExportMap (
21252143 packageJsonInfo ,
21262144 packageJsonInfo . contents . packageJsonContent . exports ,
@@ -2140,7 +2158,7 @@ export function getEntrypointsFromPackageJsonInfo(
21402158function loadEntrypointsFromExportMap (
21412159 scope : PackageJsonInfo ,
21422160 exports : object ,
2143- state : ModuleResolutionState ,
2161+ state : ModuleResolutionState & { host : GetPackageJsonEntrypointsHost } ,
21442162 extensions : Extensions ,
21452163) : PathAndExtension [ ] | undefined {
21462164 let entrypoints : PathAndExtension [ ] | undefined ;
@@ -2161,17 +2179,37 @@ function loadEntrypointsFromExportMap(
21612179 return entrypoints ;
21622180
21632181 function loadEntrypointsFromTargetExports ( target : unknown ) : boolean | undefined {
2164- if ( typeof target === "string" && startsWith ( target , "./" ) && target . indexOf ( "*" ) === - 1 ) {
2165- const partsAfterFirst = getPathComponents ( target ) . slice ( 2 ) ;
2166- if ( partsAfterFirst . indexOf ( ".." ) >= 0 || partsAfterFirst . indexOf ( "." ) >= 0 || partsAfterFirst . indexOf ( "node_modules" ) >= 0 ) {
2167- return false ;
2182+ if ( typeof target === "string" && startsWith ( target , "./" ) ) {
2183+ if ( target . indexOf ( "*" ) >= 0 && state . host . readDirectory ) {
2184+ if ( target . indexOf ( "*" ) !== target . lastIndexOf ( "*" ) ) {
2185+ return false ;
2186+ }
2187+
2188+ state . host . readDirectory (
2189+ scope . packageDirectory ,
2190+ extensionsToExtensionsArray ( extensions ) ,
2191+ /*excludes*/ undefined ,
2192+ [ changeAnyExtension ( target . replace ( "*" , "**/*" ) , getDeclarationEmitExtensionForPath ( target ) ) ]
2193+ ) . forEach ( entry => {
2194+ entrypoints = appendIfUnique ( entrypoints , {
2195+ path : entry ,
2196+ ext : getAnyExtensionFromPath ( entry ) ,
2197+ resolvedUsingTsExtension : undefined
2198+ } ) ;
2199+ } ) ;
21682200 }
2169- const resolvedTarget = combinePaths ( scope . packageDirectory , target ) ;
2170- const finalPath = getNormalizedAbsolutePath ( resolvedTarget , state . host . getCurrentDirectory ?.( ) ) ;
2171- const result = loadFileNameFromPackageJsonField ( extensions , finalPath , /*onlyRecordFailures*/ false , state ) ;
2172- if ( result ) {
2173- entrypoints = appendIfUnique ( entrypoints , result , ( a , b ) => a . path === b . path ) ;
2174- return true ;
2201+ else {
2202+ const partsAfterFirst = getPathComponents ( target ) . slice ( 2 ) ;
2203+ if ( partsAfterFirst . indexOf ( ".." ) >= 0 || partsAfterFirst . indexOf ( "." ) >= 0 || partsAfterFirst . indexOf ( "node_modules" ) >= 0 ) {
2204+ return false ;
2205+ }
2206+ const resolvedTarget = combinePaths ( scope . packageDirectory , target ) ;
2207+ const finalPath = getNormalizedAbsolutePath ( resolvedTarget , state . host . getCurrentDirectory ?.( ) ) ;
2208+ const result = loadFileNameFromPackageJsonField ( extensions , finalPath , /*onlyRecordFailures*/ false , state ) ;
2209+ if ( result ) {
2210+ entrypoints = appendIfUnique ( entrypoints , result , ( a , b ) => a . path === b . path ) ;
2211+ return true ;
2212+ }
21752213 }
21762214 }
21772215 else if ( Array . isArray ( target ) ) {
@@ -2685,12 +2723,6 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo
26852723 return ensureTrailingDirectorySeparator ( combinePaths ( root , dir ) ) ;
26862724 }
26872725
2688- function useCaseSensitiveFileNames ( ) {
2689- return ! state . host . useCaseSensitiveFileNames ? true :
2690- typeof state . host . useCaseSensitiveFileNames === "boolean" ? state . host . useCaseSensitiveFileNames :
2691- state . host . useCaseSensitiveFileNames ( ) ;
2692- }
2693-
26942726 function tryLoadInputFileForPath ( finalPath : string , entry : string , packagePath : string , isImports : boolean ) {
26952727 // Replace any references to outputs for files in the program with the input files to support package self-names used with outDir
26962728 // PROBLEM: We don't know how to calculate the output paths yet, because the "common source directory" we use as the base of the file structure
@@ -2700,13 +2732,13 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo
27002732 if ( ! state . isConfigLookup
27012733 && ( state . compilerOptions . declarationDir || state . compilerOptions . outDir )
27022734 && finalPath . indexOf ( "/node_modules/" ) === - 1
2703- && ( state . compilerOptions . configFile ? containsPath ( scope . packageDirectory , toAbsolutePath ( state . compilerOptions . configFile . fileName ) , ! useCaseSensitiveFileNames ( ) ) : true )
2735+ && ( state . compilerOptions . configFile ? containsPath ( scope . packageDirectory , toAbsolutePath ( state . compilerOptions . configFile . fileName ) , ! useCaseSensitiveFileNames ( state ) ) : true )
27042736 ) {
27052737 // So that all means we'll only try these guesses for files outside `node_modules` in a directory where the `package.json` and `tsconfig.json` are siblings.
27062738 // Even with all that, we still don't know if the root of the output file structure will be (relative to the package file)
27072739 // `.`, `./src` or any other deeper directory structure. (If project references are used, it's definitely `.` by fiat, so that should be pretty common.)
27082740
2709- const getCanonicalFileName = hostGetCanonicalFileName ( { useCaseSensitiveFileNames } ) ;
2741+ const getCanonicalFileName = hostGetCanonicalFileName ( { useCaseSensitiveFileNames : ( ) => useCaseSensitiveFileNames ( state ) } ) ;
27102742 const commonSourceDirGuesses : string [ ] = [ ] ;
27112743 // A `rootDir` compiler option strongly indicates the root location
27122744 // A `composite` project is using project references and has it's common src dir set to `.`, so it shouldn't need to check any other locations
@@ -2761,7 +2793,7 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo
27612793 for ( const commonSourceDirGuess of commonSourceDirGuesses ) {
27622794 const candidateDirectories = getOutputDirectoriesForBaseDirectory ( commonSourceDirGuess ) ;
27632795 for ( const candidateDir of candidateDirectories ) {
2764- if ( containsPath ( candidateDir , finalPath , ! useCaseSensitiveFileNames ( ) ) ) {
2796+ if ( containsPath ( candidateDir , finalPath , ! useCaseSensitiveFileNames ( state ) ) ) {
27652797 // The matched export is looking up something in either the out declaration or js dir, now map the written path back into the source dir and source extension
27662798 const pathFragment = finalPath . slice ( candidateDir . length + 1 ) ; // +1 to also remove directory seperator
27672799 const possibleInputBase = combinePaths ( commonSourceDirGuess , pathFragment ) ;
@@ -2771,7 +2803,7 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo
27712803 const inputExts = getPossibleOriginalInputExtensionForExtension ( possibleInputBase ) ;
27722804 for ( const possibleExt of inputExts ) {
27732805 if ( ! extensionIsOk ( extensions , possibleExt ) ) continue ;
2774- const possibleInputWithInputExtension = changeAnyExtension ( possibleInputBase , possibleExt , ext , ! useCaseSensitiveFileNames ( ) ) ;
2806+ const possibleInputWithInputExtension = changeAnyExtension ( possibleInputBase , possibleExt , ext , ! useCaseSensitiveFileNames ( state ) ) ;
27752807 if ( state . host . fileExists ( possibleInputWithInputExtension ) ) {
27762808 return toSearchResult ( withPackageId ( scope , loadFileNameFromPackageJsonField ( extensions , possibleInputWithInputExtension , /*onlyRecordFailures*/ false , state ) ) ) ;
27772809 }
@@ -3203,3 +3235,9 @@ function traceIfEnabled(state: ModuleResolutionState, diagnostic: DiagnosticMess
32033235 trace ( state . host , diagnostic , ...args ) ;
32043236 }
32053237}
3238+
3239+ function useCaseSensitiveFileNames ( state : ModuleResolutionState ) {
3240+ return ! state . host . useCaseSensitiveFileNames ? true :
3241+ typeof state . host . useCaseSensitiveFileNames === "boolean" ? state . host . useCaseSensitiveFileNames :
3242+ state . host . useCaseSensitiveFileNames ( ) ;
3243+ }
0 commit comments