@@ -51,13 +51,17 @@ namespace ts {
5151 DtsOnly /** Only '.d.ts' */
5252 }
5353
54+ interface PathAndPackageId {
55+ readonly fileName : string ;
56+ readonly packageId : PackageId ;
57+ }
5458 /** Used with `Extensions.DtsOnly` to extract the path from TypeScript results. */
55- function resolvedTypeScriptOnly ( resolved : Resolved | undefined ) : string | undefined {
59+ function resolvedTypeScriptOnly ( resolved : Resolved | undefined ) : PathAndPackageId | undefined {
5660 if ( ! resolved ) {
5761 return undefined ;
5862 }
5963 Debug . assert ( extensionIsTypeScript ( resolved . extension ) ) ;
60- return resolved . path ;
64+ return { fileName : resolved . path , packageId : resolved . packageId } ;
6165 }
6266
6367 function createResolvedModuleWithFailedLookupLocations ( resolved : Resolved | undefined , isExternalLibraryImport : boolean , failedLookupLocations : string [ ] ) : ResolvedModuleWithFailedLookupLocations {
@@ -201,18 +205,18 @@ namespace ts {
201205 let resolvedTypeReferenceDirective : ResolvedTypeReferenceDirective | undefined ;
202206 if ( resolved ) {
203207 if ( ! options . preserveSymlinks ) {
204- resolved = realPath ( resolved , host , traceEnabled ) ;
208+ resolved = { ... resolved , fileName : realPath ( resolved . fileName , host , traceEnabled ) } ;
205209 }
206210
207211 if ( traceEnabled ) {
208- trace ( host , Diagnostics . Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2 , typeReferenceDirectiveName , resolved , primary ) ;
212+ trace ( host , Diagnostics . Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2 , typeReferenceDirectiveName , resolved . fileName , primary ) ;
209213 }
210- resolvedTypeReferenceDirective = { primary, resolvedFileName : resolved } ;
214+ resolvedTypeReferenceDirective = { primary, resolvedFileName : resolved . fileName , packageId : resolved . packageId } ;
211215 }
212216
213217 return { resolvedTypeReferenceDirective, failedLookupLocations } ;
214218
215- function primaryLookup ( ) : string | undefined {
219+ function primaryLookup ( ) : PathAndPackageId | undefined {
216220 // Check primary library paths
217221 if ( typeRoots && typeRoots . length ) {
218222 if ( traceEnabled ) {
@@ -237,8 +241,8 @@ namespace ts {
237241 }
238242 }
239243
240- function secondaryLookup ( ) : string | undefined {
241- let resolvedFile : string ;
244+ function secondaryLookup ( ) : PathAndPackageId | undefined {
245+ let resolvedFile : PathAndPackageId ;
242246 const initialLocationForSecondaryLookup = containingFile && getDirectoryPath ( containingFile ) ;
243247
244248 if ( initialLocationForSecondaryLookup !== undefined ) {
@@ -675,7 +679,7 @@ namespace ts {
675679 if ( extension !== undefined ) {
676680 const path = tryFile ( candidate , failedLookupLocations , /*onlyRecordFailures*/ false , state ) ;
677681 if ( path !== undefined ) {
678- return { path, extension , packageId : undefined } ;
682+ return noPackageId ( { path, ext : extension } ) ;
679683 }
680684 }
681685
@@ -875,38 +879,49 @@ namespace ts {
875879 return undefined ;
876880 }
877881
878- function loadNodeModuleFromDirectory ( extensions : Extensions , candidate : string , failedLookupLocations : Push < string > , onlyRecordFailures : boolean , state : ModuleResolutionState , considerPackageJson = true ) : Resolved | undefined {
879- const directoryExists = ! onlyRecordFailures && directoryProbablyExists ( candidate , state . host ) ;
880-
881- let packageId : PackageId | undefined ;
882-
883- if ( considerPackageJson ) {
884- const packageJsonPath = pathToPackageJson ( candidate ) ;
885- if ( directoryExists && state . host . fileExists ( packageJsonPath ) ) {
886- if ( state . traceEnabled ) {
887- trace ( state . host , Diagnostics . Found_package_json_at_0 , packageJsonPath ) ;
888- }
889- const jsonContent = readJson ( packageJsonPath , state . host ) ;
882+ function loadNodeModuleFromDirectory ( extensions : Extensions , candidate : string , failedLookupLocations : Push < string > , onlyRecordFailures : boolean , state : ModuleResolutionState , considerPackageJson = true ) {
883+ const { packageJsonContent, packageId } = considerPackageJson
884+ ? getPackageJsonInfo ( candidate , "" , failedLookupLocations , onlyRecordFailures , state )
885+ : { packageJsonContent : undefined , packageId : undefined } ;
886+ return withPackageId ( packageId , loadNodeModuleFromDirectoryWorker ( extensions , candidate , failedLookupLocations , onlyRecordFailures , state , packageJsonContent ) ) ;
887+ }
890888
891- if ( typeof jsonContent . name === "string" && typeof jsonContent . version === "string" ) {
892- packageId = { name : jsonContent . name , version : jsonContent . version } ;
893- }
889+ function loadNodeModuleFromDirectoryWorker ( extensions : Extensions , candidate : string , failedLookupLocations : Push < string > , onlyRecordFailures : boolean , state : ModuleResolutionState , packageJsonContent : PackageJson | undefined ) : PathAndExtension | undefined {
890+ const fromPackageJson = packageJsonContent && loadModuleFromPackageJson ( packageJsonContent , extensions , candidate , failedLookupLocations , state ) ;
891+ if ( fromPackageJson ) {
892+ return fromPackageJson ;
893+ }
894+ const directoryExists = ! onlyRecordFailures && directoryProbablyExists ( candidate , state . host ) ;
895+ return loadModuleFromFile ( extensions , combinePaths ( candidate , "index" ) , failedLookupLocations , ! directoryExists , state ) ;
896+ }
894897
895- const fromPackageJson = loadModuleFromPackageJson ( jsonContent , extensions , candidate , failedLookupLocations , state ) ;
896- if ( fromPackageJson ) {
897- return withPackageId ( packageId , fromPackageJson ) ;
898- }
898+ function getPackageJsonInfo (
899+ nodeModuleDirectory : string ,
900+ subModuleName : string ,
901+ failedLookupLocations : Push < string > ,
902+ onlyRecordFailures : boolean ,
903+ { host, traceEnabled } : ModuleResolutionState ,
904+ ) : { packageJsonContent : PackageJson | undefined , packageId : PackageId | undefined } {
905+ const directoryExists = ! onlyRecordFailures && directoryProbablyExists ( nodeModuleDirectory , host ) ;
906+ const packageJsonPath = pathToPackageJson ( nodeModuleDirectory ) ;
907+ if ( directoryExists && host . fileExists ( packageJsonPath ) ) {
908+ if ( traceEnabled ) {
909+ trace ( host , Diagnostics . Found_package_json_at_0 , packageJsonPath ) ;
899910 }
900- else {
901- if ( directoryExists && state . traceEnabled ) {
902- trace ( state . host , Diagnostics . File_0_does_not_exist , packageJsonPath ) ;
903- }
904- // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
905- failedLookupLocations . push ( packageJsonPath ) ;
911+ const packageJsonContent = readJson ( packageJsonPath , host ) ;
912+ const packageId : PackageId = typeof packageJsonContent . name === "string" && typeof packageJsonContent . version === "string"
913+ ? { name : packageJsonContent . name , subModuleName, version : packageJsonContent . version }
914+ : undefined ;
915+ return { packageJsonContent, packageId } ;
916+ }
917+ else {
918+ if ( directoryExists && traceEnabled ) {
919+ trace ( host , Diagnostics . File_0_does_not_exist , packageJsonPath ) ;
906920 }
921+ // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
922+ failedLookupLocations . push ( packageJsonPath ) ;
923+ return { packageJsonContent : undefined , packageId : undefined } ;
907924 }
908-
909- return withPackageId ( packageId , loadModuleFromFile ( extensions , combinePaths ( candidate , "index" ) , failedLookupLocations , ! directoryExists , state ) ) ;
910925 }
911926
912927 function loadModuleFromPackageJson ( jsonContent : PackageJson , extensions : Extensions , candidate : string , failedLookupLocations : Push < string > , state : ModuleResolutionState ) : PathAndExtension | undefined {
@@ -961,10 +976,18 @@ namespace ts {
961976 }
962977
963978 function loadModuleFromNodeModulesFolder ( extensions : Extensions , moduleName : string , nodeModulesFolder : string , nodeModulesFolderExists : boolean , failedLookupLocations : Push < string > , state : ModuleResolutionState ) : Resolved | undefined {
979+ const { top, rest } = getNameOfTopDirectory ( moduleName ) ;
980+ const packageRootPath = combinePaths ( nodeModulesFolder , top ) ;
981+ const { packageJsonContent, packageId } = getPackageJsonInfo ( packageRootPath , rest , failedLookupLocations , ! nodeModulesFolderExists , state ) ;
964982 const candidate = normalizePath ( combinePaths ( nodeModulesFolder , moduleName ) ) ;
983+ const pathAndExtension = loadModuleFromFile ( extensions , candidate , failedLookupLocations , ! nodeModulesFolderExists , state ) ||
984+ loadNodeModuleFromDirectoryWorker ( extensions , candidate , failedLookupLocations , ! nodeModulesFolderExists , state , packageJsonContent ) ;
985+ return withPackageId ( packageId , pathAndExtension ) ;
986+ }
965987
966- return loadModuleFromFileNoPackageId ( extensions , candidate , failedLookupLocations , ! nodeModulesFolderExists , state ) ||
967- loadNodeModuleFromDirectory ( extensions , candidate , failedLookupLocations , ! nodeModulesFolderExists , state ) ;
988+ function getNameOfTopDirectory ( name : string ) : { top : string , rest : string } {
989+ const idx = name . indexOf ( directorySeparator ) ;
990+ return idx === - 1 ? { top : name , rest : "" } : { top : name . slice ( 0 , idx ) , rest : name . slice ( idx + 1 ) } ;
968991 }
969992
970993 function loadModuleFromNodeModules ( extensions : Extensions , moduleName : string , directory : string , failedLookupLocations : Push < string > , state : ModuleResolutionState , cache : NonRelativeModuleNameResolutionCache ) : SearchResult < Resolved > {
0 commit comments