@@ -120,7 +120,7 @@ export function isTraceEnabled(compilerOptions: CompilerOptions, host: ModuleRes
120
120
return ! ! compilerOptions . traceResolution && host . trace !== undefined ;
121
121
}
122
122
123
- function withPackageId ( packageInfo : PackageJsonInfo | undefined , r : PathAndExtension | undefined ) : Resolved | undefined {
123
+ function withPackageId ( packageInfo : PackageJsonInfo | undefined , r : PathAndExtension | undefined , state : ModuleResolutionState ) : Resolved | undefined {
124
124
let packageId : PackageId | undefined ;
125
125
if ( r && packageInfo ) {
126
126
const packageJsonContent = packageInfo . contents . packageJsonContent as PackageJson ;
@@ -129,14 +129,15 @@ function withPackageId(packageInfo: PackageJsonInfo | undefined, r: PathAndExten
129
129
name : packageJsonContent . name ,
130
130
subModuleName : r . path . slice ( packageInfo . packageDirectory . length + directorySeparator . length ) ,
131
131
version : packageJsonContent . version ,
132
+ peerDependencies : getPeerDependenciesOfPackageJsonInfo ( packageInfo , state ) ,
132
133
} ;
133
134
}
134
135
}
135
136
return r && { path : r . path , extension : r . ext , packageId, resolvedUsingTsExtension : r . resolvedUsingTsExtension } ;
136
137
}
137
138
138
139
function noPackageId ( r : PathAndExtension | undefined ) : Resolved | undefined {
139
- return withPackageId ( /*packageInfo*/ undefined , r ) ;
140
+ return withPackageId ( /*packageInfo*/ undefined , r , /*state*/ undefined ! ) ; // State will not be used so no need to pass
140
141
}
141
142
142
143
function removeIgnoredPackageId ( r : Resolved | undefined ) : PathAndExtension | undefined {
@@ -346,6 +347,7 @@ export interface PackageJsonPathFields {
346
347
interface PackageJson extends PackageJsonPathFields {
347
348
name ?: string ;
348
349
version ?: string ;
350
+ peerDependencies ?: MapLike < string > ;
349
351
}
350
352
351
353
function readPackageJsonField < K extends MatchingKeys < PackageJson , string | undefined > > ( jsonContent : PackageJson , fieldName : K , typeOfTag : "string" , state : ModuleResolutionState ) : PackageJson [ K ] | undefined ;
@@ -669,7 +671,7 @@ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string
669
671
if ( resolvedFromFile ) {
670
672
const packageDirectory = parseNodeModuleFromPath ( resolvedFromFile . path ) ;
671
673
const packageInfo = packageDirectory ? getPackageJsonInfo ( packageDirectory , /*onlyRecordFailures*/ false , moduleResolutionState ) : undefined ;
672
- return resolvedTypeScriptOnly ( withPackageId ( packageInfo , resolvedFromFile ) ) ;
674
+ return resolvedTypeScriptOnly ( withPackageId ( packageInfo , resolvedFromFile , moduleResolutionState ) ) ;
673
675
}
674
676
}
675
677
return resolvedTypeScriptOnly (
@@ -1984,7 +1986,7 @@ function nodeLoadModuleByRelativeName(extensions: Extensions, candidate: string,
1984
1986
if ( resolvedFromFile ) {
1985
1987
const packageDirectory = considerPackageJson ? parseNodeModuleFromPath ( resolvedFromFile . path ) : undefined ;
1986
1988
const packageInfo = packageDirectory ? getPackageJsonInfo ( packageDirectory , /*onlyRecordFailures*/ false , state ) : undefined ;
1987
- return withPackageId ( packageInfo , resolvedFromFile ) ;
1989
+ return withPackageId ( packageInfo , resolvedFromFile , state ) ;
1988
1990
}
1989
1991
}
1990
1992
if ( ! onlyRecordFailures ) {
@@ -2200,7 +2202,7 @@ function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string,
2200
2202
const packageInfo = considerPackageJson ? getPackageJsonInfo ( candidate , onlyRecordFailures , state ) : undefined ;
2201
2203
const packageJsonContent = packageInfo && packageInfo . contents . packageJsonContent ;
2202
2204
const versionPaths = packageInfo && getVersionPathsOfPackageJsonInfo ( packageInfo , state ) ;
2203
- return withPackageId ( packageInfo , loadNodeModuleFromDirectoryWorker ( extensions , candidate , onlyRecordFailures , state , packageJsonContent , versionPaths ) ) ;
2205
+ return withPackageId ( packageInfo , loadNodeModuleFromDirectoryWorker ( extensions , candidate , onlyRecordFailures , state , packageJsonContent , versionPaths ) , state ) ;
2204
2206
}
2205
2207
2206
2208
/** @internal */
@@ -2372,6 +2374,8 @@ export interface PackageJsonInfoContents {
2372
2374
versionPaths : VersionPaths | false | undefined ;
2373
2375
/** false: resolved to nothing. undefined: not yet resolved */
2374
2376
resolvedEntrypoints : string [ ] | false | undefined ;
2377
+ /** false: peerDependencies are not present. undefined: not yet resolved */
2378
+ peerDependencies : string | false | undefined ;
2375
2379
}
2376
2380
2377
2381
/**
@@ -2399,6 +2403,37 @@ function getVersionPathsOfPackageJsonInfo(packageJsonInfo: PackageJsonInfo, stat
2399
2403
return packageJsonInfo . contents . versionPaths || undefined ;
2400
2404
}
2401
2405
2406
+ function getPeerDependenciesOfPackageJsonInfo ( packageJsonInfo : PackageJsonInfo , state : ModuleResolutionState ) : string | undefined {
2407
+ if ( packageJsonInfo . contents . peerDependencies === undefined ) {
2408
+ packageJsonInfo . contents . peerDependencies = readPackageJsonPeerDependencies ( packageJsonInfo , state ) || false ;
2409
+ }
2410
+ return packageJsonInfo . contents . peerDependencies || undefined ;
2411
+ }
2412
+
2413
+ function readPackageJsonPeerDependencies ( packageJsonInfo : PackageJsonInfo , state : ModuleResolutionState ) : string | undefined {
2414
+ const peerDependencies = readPackageJsonField ( packageJsonInfo . contents . packageJsonContent , "peerDependencies" , "object" , state ) ;
2415
+ if ( peerDependencies === undefined ) return undefined ;
2416
+ if ( state . traceEnabled ) trace ( state . host , Diagnostics . package_json_has_a_peerDependencies_field ) ;
2417
+ const packageDirectory = realPath ( packageJsonInfo . packageDirectory , state . host , state . traceEnabled ) ;
2418
+ const nodeModules = packageDirectory . substring ( 0 , packageDirectory . lastIndexOf ( "node_modules" ) + "node_modules" . length ) + directorySeparator ;
2419
+ let result = "" ;
2420
+ for ( const key in peerDependencies ) {
2421
+ if ( hasProperty ( peerDependencies , key ) ) {
2422
+ const peerPackageJson = getPackageJsonInfo ( nodeModules + key , /*onlyRecordFailures*/ false , state ) ;
2423
+ if ( peerPackageJson ) {
2424
+ const version = ( peerPackageJson . contents . packageJsonContent as PackageJson ) . version ;
2425
+ result += `+${ key } @${ version } ` ;
2426
+ if ( state . traceEnabled ) trace ( state . host , Diagnostics . Found_peerDependency_0_with_1_version , key , version ) ;
2427
+ }
2428
+ else {
2429
+ // Read the dependency version
2430
+ if ( state . traceEnabled ) trace ( state . host , Diagnostics . Failed_to_find_peerDependency_0 , key ) ;
2431
+ }
2432
+ }
2433
+ }
2434
+ return result ;
2435
+ }
2436
+
2402
2437
/** @internal */
2403
2438
export function getPackageJsonInfo ( packageDirectory : string , onlyRecordFailures : boolean , state : ModuleResolutionState ) : PackageJsonInfo | undefined {
2404
2439
const { host, traceEnabled } = state ;
@@ -2429,7 +2464,7 @@ export function getPackageJsonInfo(packageDirectory: string, onlyRecordFailures:
2429
2464
if ( traceEnabled ) {
2430
2465
trace ( host , Diagnostics . Found_package_json_at_0 , packageJsonPath ) ;
2431
2466
}
2432
- const result : PackageJsonInfo = { packageDirectory, contents : { packageJsonContent, versionPaths : undefined , resolvedEntrypoints : undefined } } ;
2467
+ const result : PackageJsonInfo = { packageDirectory, contents : { packageJsonContent, versionPaths : undefined , resolvedEntrypoints : undefined , peerDependencies : undefined } } ;
2433
2468
if ( state . packageJsonInfoCache && ! state . packageJsonInfoCache . isReadonly ) state . packageJsonInfoCache . setPackageJsonInfo ( packageJsonPath , result ) ;
2434
2469
state . affectingLocations ?. push ( packageJsonPath ) ;
2435
2470
return result ;
@@ -2755,7 +2790,7 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo
2755
2790
const finalPath = toAbsolutePath ( pattern ? resolvedTarget . replace ( / \* / g, subpath ) : resolvedTarget + subpath ) ;
2756
2791
const inputLink = tryLoadInputFileForPath ( finalPath , subpath , combinePaths ( scope . packageDirectory , "package.json" ) , isImports ) ;
2757
2792
if ( inputLink ) return inputLink ;
2758
- return toSearchResult ( withPackageId ( scope , loadFileNameFromPackageJsonField ( extensions , finalPath , /*onlyRecordFailures*/ false , state ) ) ) ;
2793
+ return toSearchResult ( withPackageId ( scope , loadFileNameFromPackageJsonField ( extensions , finalPath , /*onlyRecordFailures*/ false , state ) , state ) ) ;
2759
2794
}
2760
2795
else if ( typeof target === "object" && target !== null ) { // eslint-disable-line no-null/no-null
2761
2796
if ( ! Array . isArray ( target ) ) {
@@ -2901,7 +2936,7 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo
2901
2936
if ( ! extensionIsOk ( extensions , possibleExt ) ) continue ;
2902
2937
const possibleInputWithInputExtension = changeAnyExtension ( possibleInputBase , possibleExt , ext , ! useCaseSensitiveFileNames ( state ) ) ;
2903
2938
if ( state . host . fileExists ( possibleInputWithInputExtension ) ) {
2904
- return toSearchResult ( withPackageId ( scope , loadFileNameFromPackageJsonField ( extensions , possibleInputWithInputExtension , /*onlyRecordFailures*/ false , state ) ) ) ;
2939
+ return toSearchResult ( withPackageId ( scope , loadFileNameFromPackageJsonField ( extensions , possibleInputWithInputExtension , /*onlyRecordFailures*/ false , state ) , state ) ) ;
2905
2940
}
2906
2941
}
2907
2942
}
@@ -3037,7 +3072,7 @@ function loadModuleFromSpecificNodeModulesDirectory(extensions: Extensions, modu
3037
3072
packageInfo . contents . packageJsonContent ,
3038
3073
getVersionPathsOfPackageJsonInfo ( packageInfo , state ) ,
3039
3074
) ;
3040
- return withPackageId ( packageInfo , fromDirectory ) ;
3075
+ return withPackageId ( packageInfo , fromDirectory , state ) ;
3041
3076
}
3042
3077
3043
3078
const loader : ResolutionKindSpecificLoader = ( extensions , candidate , onlyRecordFailures , state ) => {
@@ -3060,7 +3095,7 @@ function loadModuleFromSpecificNodeModulesDirectory(extensions: Extensions, modu
3060
3095
// a default `index.js` entrypoint if no `main` or `exports` are present
3061
3096
pathAndExtension = loadModuleFromFile ( extensions , combinePaths ( candidate , "index.js" ) , onlyRecordFailures , state ) ;
3062
3097
}
3063
- return withPackageId ( packageInfo , pathAndExtension ) ;
3098
+ return withPackageId ( packageInfo , pathAndExtension , state ) ;
3064
3099
} ;
3065
3100
3066
3101
if ( rest !== "" ) {
@@ -3260,7 +3295,7 @@ function resolveFromTypeRoot(moduleName: string, state: ModuleResolutionState) {
3260
3295
if ( resolvedFromFile ) {
3261
3296
const packageDirectory = parseNodeModuleFromPath ( resolvedFromFile . path ) ;
3262
3297
const packageInfo = packageDirectory ? getPackageJsonInfo ( packageDirectory , /*onlyRecordFailures*/ false , state ) : undefined ;
3263
- return toSearchResult ( withPackageId ( packageInfo , resolvedFromFile ) ) ;
3298
+ return toSearchResult ( withPackageId ( packageInfo , resolvedFromFile , state ) ) ;
3264
3299
}
3265
3300
const resolved = loadNodeModuleFromDirectory ( Extensions . Declaration , candidate , ! directoryExists , state ) ;
3266
3301
if ( resolved ) return toSearchResult ( resolved ) ;
0 commit comments