@@ -51,13 +51,17 @@ namespace ts {
51
51
DtsOnly /** Only '.d.ts' */
52
52
}
53
53
54
+ interface PathAndPackageId {
55
+ readonly fileName : string ;
56
+ readonly packageId : PackageId ;
57
+ }
54
58
/** 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 {
56
60
if ( ! resolved ) {
57
61
return undefined ;
58
62
}
59
63
Debug . assert ( extensionIsTypeScript ( resolved . extension ) ) ;
60
- return resolved . path ;
64
+ return { fileName : resolved . path , packageId : resolved . packageId } ;
61
65
}
62
66
63
67
function createResolvedModuleWithFailedLookupLocations ( resolved : Resolved | undefined , isExternalLibraryImport : boolean , failedLookupLocations : string [ ] ) : ResolvedModuleWithFailedLookupLocations {
@@ -201,18 +205,18 @@ namespace ts {
201
205
let resolvedTypeReferenceDirective : ResolvedTypeReferenceDirective | undefined ;
202
206
if ( resolved ) {
203
207
if ( ! options . preserveSymlinks ) {
204
- resolved = realpath ( resolved , host , traceEnabled ) ;
208
+ resolved = { ... resolved , fileName : realpath ( resolved . fileName , host , traceEnabled ) } ;
205
209
}
206
210
207
211
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 ) ;
209
213
}
210
- resolvedTypeReferenceDirective = { primary, resolvedFileName : resolved } ;
214
+ resolvedTypeReferenceDirective = { primary, resolvedFileName : resolved . fileName , packageId : resolved . packageId } ;
211
215
}
212
216
213
217
return { resolvedTypeReferenceDirective, failedLookupLocations } ;
214
218
215
- function primaryLookup ( ) : string | undefined {
219
+ function primaryLookup ( ) : PathAndPackageId | undefined {
216
220
// Check primary library paths
217
221
if ( typeRoots && typeRoots . length ) {
218
222
if ( traceEnabled ) {
@@ -237,8 +241,8 @@ namespace ts {
237
241
}
238
242
}
239
243
240
- function secondaryLookup ( ) : string | undefined {
241
- let resolvedFile : string ;
244
+ function secondaryLookup ( ) : PathAndPackageId | undefined {
245
+ let resolvedFile : PathAndPackageId ;
242
246
const initialLocationForSecondaryLookup = containingFile && getDirectoryPath ( containingFile ) ;
243
247
244
248
if ( initialLocationForSecondaryLookup !== undefined ) {
@@ -675,7 +679,7 @@ namespace ts {
675
679
if ( extension !== undefined ) {
676
680
const path = tryFile ( candidate , failedLookupLocations , /*onlyRecordFailures*/ false , state ) ;
677
681
if ( path !== undefined ) {
678
- return { path, extension , packageId : undefined } ;
682
+ return noPackageId ( { path, ext : extension } ) ;
679
683
}
680
684
}
681
685
@@ -874,38 +878,49 @@ namespace ts {
874
878
return undefined ;
875
879
}
876
880
877
- function loadNodeModuleFromDirectory ( extensions : Extensions , candidate : string , failedLookupLocations : Push < string > , onlyRecordFailures : boolean , state : ModuleResolutionState , considerPackageJson = true ) : Resolved | undefined {
878
- const directoryExists = ! onlyRecordFailures && directoryProbablyExists ( candidate , state . host ) ;
879
-
880
- let packageId : PackageId | undefined ;
881
-
882
- if ( considerPackageJson ) {
883
- const packageJsonPath = pathToPackageJson ( candidate ) ;
884
- if ( directoryExists && state . host . fileExists ( packageJsonPath ) ) {
885
- if ( state . traceEnabled ) {
886
- trace ( state . host , Diagnostics . Found_package_json_at_0 , packageJsonPath ) ;
887
- }
888
- const jsonContent = readJson ( packageJsonPath , state . host ) ;
881
+ function loadNodeModuleFromDirectory ( extensions : Extensions , candidate : string , failedLookupLocations : Push < string > , onlyRecordFailures : boolean , state : ModuleResolutionState , considerPackageJson = true ) {
882
+ const { packageJsonContent, packageId } = considerPackageJson
883
+ ? getPackageJsonInfo ( candidate , "" , failedLookupLocations , onlyRecordFailures , state )
884
+ : { packageJsonContent : undefined , packageId : undefined } ;
885
+ return withPackageId ( packageId , loadNodeModuleFromDirectoryWorker ( extensions , candidate , failedLookupLocations , onlyRecordFailures , state , packageJsonContent ) ) ;
886
+ }
889
887
890
- if ( typeof jsonContent . name === "string" && typeof jsonContent . version === "string" ) {
891
- packageId = { name : jsonContent . name , version : jsonContent . version } ;
892
- }
888
+ function loadNodeModuleFromDirectoryWorker ( extensions : Extensions , candidate : string , failedLookupLocations : Push < string > , onlyRecordFailures : boolean , state : ModuleResolutionState , packageJsonContent : PackageJson | undefined ) : PathAndExtension | undefined {
889
+ const fromPackageJson = packageJsonContent && loadModuleFromPackageJson ( packageJsonContent , extensions , candidate , failedLookupLocations , state ) ;
890
+ if ( fromPackageJson ) {
891
+ return fromPackageJson ;
892
+ }
893
+ const directoryExists = ! onlyRecordFailures && directoryProbablyExists ( candidate , state . host ) ;
894
+ return loadModuleFromFile ( extensions , combinePaths ( candidate , "index" ) , failedLookupLocations , ! directoryExists , state ) ;
895
+ }
893
896
894
- const fromPackageJson = loadModuleFromPackageJson ( jsonContent , extensions , candidate , failedLookupLocations , state ) ;
895
- if ( fromPackageJson ) {
896
- return withPackageId ( packageId , fromPackageJson ) ;
897
- }
897
+ function getPackageJsonInfo (
898
+ nodeModuleDirectory : string ,
899
+ subModuleName : string ,
900
+ failedLookupLocations : Push < string > ,
901
+ onlyRecordFailures : boolean ,
902
+ { host, traceEnabled } : ModuleResolutionState ,
903
+ ) : { packageJsonContent : PackageJson | undefined , packageId : PackageId | undefined } {
904
+ const directoryExists = ! onlyRecordFailures && directoryProbablyExists ( nodeModuleDirectory , host ) ;
905
+ const packageJsonPath = pathToPackageJson ( nodeModuleDirectory ) ;
906
+ if ( directoryExists && host . fileExists ( packageJsonPath ) ) {
907
+ if ( traceEnabled ) {
908
+ trace ( host , Diagnostics . Found_package_json_at_0 , packageJsonPath ) ;
898
909
}
899
- else {
900
- if ( directoryExists && state . traceEnabled ) {
901
- trace ( state . host , Diagnostics . File_0_does_not_exist , packageJsonPath ) ;
902
- }
903
- // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
904
- failedLookupLocations . push ( packageJsonPath ) ;
910
+ const packageJsonContent = readJson ( packageJsonPath , host ) ;
911
+ const packageId : PackageId = typeof packageJsonContent . name === "string" && typeof packageJsonContent . version === "string"
912
+ ? { name : packageJsonContent . name , subModuleName, version : packageJsonContent . version }
913
+ : undefined ;
914
+ return { packageJsonContent, packageId } ;
915
+ }
916
+ else {
917
+ if ( directoryExists && traceEnabled ) {
918
+ trace ( host , Diagnostics . File_0_does_not_exist , packageJsonPath ) ;
905
919
}
920
+ // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
921
+ failedLookupLocations . push ( packageJsonPath ) ;
922
+ return { packageJsonContent : undefined , packageId : undefined } ;
906
923
}
907
-
908
- return withPackageId ( packageId , loadModuleFromFile ( extensions , combinePaths ( candidate , "index" ) , failedLookupLocations , ! directoryExists , state ) ) ;
909
924
}
910
925
911
926
function loadModuleFromPackageJson ( jsonContent : PackageJson , extensions : Extensions , candidate : string , failedLookupLocations : Push < string > , state : ModuleResolutionState ) : PathAndExtension | undefined {
@@ -960,10 +975,18 @@ namespace ts {
960
975
}
961
976
962
977
function loadModuleFromNodeModulesFolder ( extensions : Extensions , moduleName : string , nodeModulesFolder : string , nodeModulesFolderExists : boolean , failedLookupLocations : Push < string > , state : ModuleResolutionState ) : Resolved | undefined {
978
+ const { top, rest } = getNameOfTopDirectory ( moduleName ) ;
979
+ const packageRootPath = combinePaths ( nodeModulesFolder , top ) ;
980
+ const { packageJsonContent, packageId } = getPackageJsonInfo ( packageRootPath , rest , failedLookupLocations , ! nodeModulesFolderExists , state ) ;
963
981
const candidate = normalizePath ( combinePaths ( nodeModulesFolder , moduleName ) ) ;
982
+ const pathAndExtension = loadModuleFromFile ( extensions , candidate , failedLookupLocations , ! nodeModulesFolderExists , state ) ||
983
+ loadNodeModuleFromDirectoryWorker ( extensions , candidate , failedLookupLocations , ! nodeModulesFolderExists , state , packageJsonContent ) ;
984
+ return withPackageId ( packageId , pathAndExtension ) ;
985
+ }
964
986
965
- return loadModuleFromFileNoPackageId ( extensions , candidate , failedLookupLocations , ! nodeModulesFolderExists , state ) ||
966
- loadNodeModuleFromDirectory ( extensions , candidate , failedLookupLocations , ! nodeModulesFolderExists , state ) ;
987
+ function getNameOfTopDirectory ( name : string ) : { top : string , rest : string } {
988
+ const idx = name . indexOf ( directorySeparator ) ;
989
+ return idx === - 1 ? { top : name , rest : "" } : { top : name . slice ( 0 , idx ) , rest : name . slice ( idx + 1 ) } ;
967
990
}
968
991
969
992
function loadModuleFromNodeModules ( extensions : Extensions , moduleName : string , directory : string , failedLookupLocations : Push < string > , state : ModuleResolutionState , cache : NonRelativeModuleNameResolutionCache ) : SearchResult < Resolved > {
0 commit comments