@@ -121,7 +121,7 @@ export function isTraceEnabled(compilerOptions: CompilerOptions, host: ModuleRes
121
121
return ! ! compilerOptions . traceResolution && host . trace !== undefined ;
122
122
}
123
123
124
- function withPackageId ( packageInfo : PackageJsonInfo | undefined , r : PathAndExtension | undefined ) : Resolved | undefined {
124
+ function withPackageId ( packageInfo : PackageJsonInfo | undefined , r : PathAndExtension | undefined , state : ModuleResolutionState ) : Resolved | undefined {
125
125
let packageId : PackageId | undefined ;
126
126
if ( r && packageInfo ) {
127
127
const packageJsonContent = packageInfo . contents . packageJsonContent as PackageJson ;
@@ -130,14 +130,15 @@ function withPackageId(packageInfo: PackageJsonInfo | undefined, r: PathAndExten
130
130
name : packageJsonContent . name ,
131
131
subModuleName : r . path . slice ( packageInfo . packageDirectory . length + directorySeparator . length ) ,
132
132
version : packageJsonContent . version ,
133
+ peerDependencies : getPeerDependenciesOfPackageJsonInfo ( packageInfo , state ) ,
133
134
} ;
134
135
}
135
136
}
136
137
return r && { path : r . path , extension : r . ext , packageId, resolvedUsingTsExtension : r . resolvedUsingTsExtension } ;
137
138
}
138
139
139
140
function noPackageId ( r : PathAndExtension | undefined ) : Resolved | undefined {
140
- return withPackageId ( /*packageInfo*/ undefined , r ) ;
141
+ return withPackageId ( /*packageInfo*/ undefined , r , /*state*/ undefined ! ) ; // State will not be used so no need to pass
141
142
}
142
143
143
144
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 < TMatch , K extends MatchingKeys < PackageJson , string | undefined > > ( jsonContent : PackageJson , fieldName : K , typeOfTag : "string" , state : ModuleResolutionState ) : PackageJson [ K ] | undefined ;
@@ -668,7 +670,7 @@ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string
668
670
if ( resolvedFromFile ) {
669
671
const packageDirectory = parseNodeModuleFromPath ( resolvedFromFile . path ) ;
670
672
const packageInfo = packageDirectory ? getPackageJsonInfo ( packageDirectory , /*onlyRecordFailures*/ false , moduleResolutionState ) : undefined ;
671
- return resolvedTypeScriptOnly ( withPackageId ( packageInfo , resolvedFromFile ) ) ;
673
+ return resolvedTypeScriptOnly ( withPackageId ( packageInfo , resolvedFromFile , moduleResolutionState ) ) ;
672
674
}
673
675
}
674
676
return resolvedTypeScriptOnly (
@@ -1977,7 +1979,7 @@ function nodeLoadModuleByRelativeName(extensions: Extensions, candidate: string,
1977
1979
if ( resolvedFromFile ) {
1978
1980
const packageDirectory = considerPackageJson ? parseNodeModuleFromPath ( resolvedFromFile . path ) : undefined ;
1979
1981
const packageInfo = packageDirectory ? getPackageJsonInfo ( packageDirectory , /*onlyRecordFailures*/ false , state ) : undefined ;
1980
- return withPackageId ( packageInfo , resolvedFromFile ) ;
1982
+ return withPackageId ( packageInfo , resolvedFromFile , state ) ;
1981
1983
}
1982
1984
}
1983
1985
if ( ! onlyRecordFailures ) {
@@ -2194,7 +2196,7 @@ function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string,
2194
2196
const packageInfo = considerPackageJson ? getPackageJsonInfo ( candidate , onlyRecordFailures , state ) : undefined ;
2195
2197
const packageJsonContent = packageInfo && packageInfo . contents . packageJsonContent ;
2196
2198
const versionPaths = packageInfo && getVersionPathsOfPackageJsonInfo ( packageInfo , state ) ;
2197
- return withPackageId ( packageInfo , loadNodeModuleFromDirectoryWorker ( extensions , candidate , onlyRecordFailures , state , packageJsonContent , versionPaths ) ) ;
2199
+ return withPackageId ( packageInfo , loadNodeModuleFromDirectoryWorker ( extensions , candidate , onlyRecordFailures , state , packageJsonContent , versionPaths ) , state ) ;
2198
2200
}
2199
2201
2200
2202
/** @internal */
@@ -2365,6 +2367,8 @@ export interface PackageJsonInfoContents {
2365
2367
versionPaths : VersionPaths | false | undefined ;
2366
2368
/** false: resolved to nothing. undefined: not yet resolved */
2367
2369
resolvedEntrypoints : string [ ] | false | undefined ;
2370
+ /** false: peerDependencies are not present. undefined: not yet resolved */
2371
+ peerDependencies : string | false | undefined ;
2368
2372
}
2369
2373
2370
2374
/**
@@ -2392,6 +2396,44 @@ function getVersionPathsOfPackageJsonInfo(packageJsonInfo: PackageJsonInfo, stat
2392
2396
return packageJsonInfo . contents . versionPaths || undefined ;
2393
2397
}
2394
2398
2399
+ function getPeerDependenciesOfPackageJsonInfo ( packageJsonInfo : PackageJsonInfo , state : ModuleResolutionState ) : string | undefined {
2400
+ if ( packageJsonInfo . contents . peerDependencies === undefined ) {
2401
+ packageJsonInfo . contents . peerDependencies = readPackageJsonPeerDependencies ( packageJsonInfo , state ) || false ;
2402
+ }
2403
+ return packageJsonInfo . contents . peerDependencies || undefined ;
2404
+ }
2405
+
2406
+ function readPackageJsonPeerDependencies ( packageJsonInfo : PackageJsonInfo , state : ModuleResolutionState ) : string | undefined {
2407
+ const peerDependencies = readPackageJsonField ( packageJsonInfo . contents . packageJsonContent , "peerDependencies" , "object" , state ) ;
2408
+ if ( peerDependencies === undefined ) return undefined ;
2409
+ if ( state . traceEnabled ) trace ( state . host , Diagnostics . package_json_has_a_peerDependencies_field ) ;
2410
+ const packageDirectory = realPath ( packageJsonInfo . packageDirectory , state . host , state . traceEnabled ) ;
2411
+ if ( packageDirectory . indexOf ( ".pnpm" ) === - 1 ) {
2412
+ // For now skip extra work for anything else
2413
+ if ( state . traceEnabled ) trace ( state . host , Diagnostics . Package_is_not_installed_using_pnpm_skipping_peerDependencies_version_resolution ) ;
2414
+ return undefined ;
2415
+ }
2416
+ const nodeModules = packageDirectory . substring ( 0 , packageDirectory . lastIndexOf ( "node_modules" ) + "node_modules" . length ) + directorySeparator ;
2417
+ let result = "" ;
2418
+ if ( state . traceEnabled ) {
2419
+ for ( const key in peerDependencies ) {
2420
+ if ( hasProperty ( peerDependencies , key ) ) {
2421
+ const peerPackageJson = getPackageJsonInfo ( nodeModules + key , /*onlyRecordFailures*/ false , state ) ;
2422
+ if ( peerPackageJson ) {
2423
+ const version = ( peerPackageJson . contents . packageJsonContent as PackageJson ) . version ;
2424
+ result += `+${ key } @${ version } ` ;
2425
+ if ( state . traceEnabled ) trace ( state . host , Diagnostics . Found_peerDependency_0_with_1_version , key , version ) ;
2426
+ }
2427
+ else {
2428
+ // Read the dependency version
2429
+ if ( state . traceEnabled ) trace ( state . host , Diagnostics . Failed_to_find_peerDependency_0 , key ) ;
2430
+ }
2431
+ }
2432
+ }
2433
+ }
2434
+ return result ;
2435
+ }
2436
+
2395
2437
/** @internal */
2396
2438
export function getPackageJsonInfo ( packageDirectory : string , onlyRecordFailures : boolean , state : ModuleResolutionState ) : PackageJsonInfo | undefined {
2397
2439
const { host, traceEnabled } = state ;
@@ -2422,7 +2464,7 @@ export function getPackageJsonInfo(packageDirectory: string, onlyRecordFailures:
2422
2464
if ( traceEnabled ) {
2423
2465
trace ( host , Diagnostics . Found_package_json_at_0 , packageJsonPath ) ;
2424
2466
}
2425
- const result : PackageJsonInfo = { packageDirectory, contents : { packageJsonContent, versionPaths : undefined , resolvedEntrypoints : undefined } } ;
2467
+ const result : PackageJsonInfo = { packageDirectory, contents : { packageJsonContent, versionPaths : undefined , resolvedEntrypoints : undefined , peerDependencies : undefined } } ;
2426
2468
if ( state . packageJsonInfoCache && ! state . packageJsonInfoCache . isReadonly ) state . packageJsonInfoCache . setPackageJsonInfo ( packageJsonPath , result ) ;
2427
2469
state . affectingLocations ?. push ( packageJsonPath ) ;
2428
2470
return result ;
@@ -2760,7 +2802,7 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo
2760
2802
const finalPath = toAbsolutePath ( pattern ? resolvedTarget . replace ( / \* / g, subpath ) : resolvedTarget + subpath ) ;
2761
2803
const inputLink = tryLoadInputFileForPath ( finalPath , subpath , combinePaths ( scope . packageDirectory , "package.json" ) , isImports ) ;
2762
2804
if ( inputLink ) return inputLink ;
2763
- return toSearchResult ( withPackageId ( scope , loadFileNameFromPackageJsonField ( extensions , finalPath , /*onlyRecordFailures*/ false , state ) ) ) ;
2805
+ return toSearchResult ( withPackageId ( scope , loadFileNameFromPackageJsonField ( extensions , finalPath , /*onlyRecordFailures*/ false , state ) , state ) ) ;
2764
2806
}
2765
2807
else if ( typeof target === "object" && target !== null ) { // eslint-disable-line no-null/no-null
2766
2808
if ( ! Array . isArray ( target ) ) {
@@ -2906,7 +2948,7 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo
2906
2948
if ( ! extensionIsOk ( extensions , possibleExt ) ) continue ;
2907
2949
const possibleInputWithInputExtension = changeAnyExtension ( possibleInputBase , possibleExt , ext , ! useCaseSensitiveFileNames ( state ) ) ;
2908
2950
if ( state . host . fileExists ( possibleInputWithInputExtension ) ) {
2909
- return toSearchResult ( withPackageId ( scope , loadFileNameFromPackageJsonField ( extensions , possibleInputWithInputExtension , /*onlyRecordFailures*/ false , state ) ) ) ;
2951
+ return toSearchResult ( withPackageId ( scope , loadFileNameFromPackageJsonField ( extensions , possibleInputWithInputExtension , /*onlyRecordFailures*/ false , state ) , state ) ) ;
2910
2952
}
2911
2953
}
2912
2954
}
@@ -3042,7 +3084,7 @@ function loadModuleFromSpecificNodeModulesDirectory(extensions: Extensions, modu
3042
3084
packageInfo . contents . packageJsonContent ,
3043
3085
getVersionPathsOfPackageJsonInfo ( packageInfo , state ) ,
3044
3086
) ;
3045
- return withPackageId ( packageInfo , fromDirectory ) ;
3087
+ return withPackageId ( packageInfo , fromDirectory , state ) ;
3046
3088
}
3047
3089
3048
3090
const loader : ResolutionKindSpecificLoader = ( extensions , candidate , onlyRecordFailures , state ) => {
@@ -3065,7 +3107,7 @@ function loadModuleFromSpecificNodeModulesDirectory(extensions: Extensions, modu
3065
3107
// a default `index.js` entrypoint if no `main` or `exports` are present
3066
3108
pathAndExtension = loadModuleFromFile ( extensions , combinePaths ( candidate , "index.js" ) , onlyRecordFailures , state ) ;
3067
3109
}
3068
- return withPackageId ( packageInfo , pathAndExtension ) ;
3110
+ return withPackageId ( packageInfo , pathAndExtension , state ) ;
3069
3111
} ;
3070
3112
3071
3113
if ( rest !== "" ) {
@@ -3261,7 +3303,7 @@ function resolveFromTypeRoot(moduleName: string, state: ModuleResolutionState) {
3261
3303
if ( resolvedFromFile ) {
3262
3304
const packageDirectory = parseNodeModuleFromPath ( resolvedFromFile . path ) ;
3263
3305
const packageInfo = packageDirectory ? getPackageJsonInfo ( packageDirectory , /*onlyRecordFailures*/ false , state ) : undefined ;
3264
- return toSearchResult ( withPackageId ( packageInfo , resolvedFromFile ) ) ;
3306
+ return toSearchResult ( withPackageId ( packageInfo , resolvedFromFile , state ) ) ;
3265
3307
}
3266
3308
const resolved = loadNodeModuleFromDirectory ( Extensions . Declaration , candidate , ! directoryExists , state ) ;
3267
3309
if ( resolved ) return toSearchResult ( resolved ) ;
0 commit comments