@@ -109,6 +109,10 @@ import {
109
109
versionMajorMinor ,
110
110
VersionRange ,
111
111
} from "./_namespaces/ts.js" ;
112
+ import {
113
+ getPnpApi ,
114
+ getPnpTypeRoots ,
115
+ } from "./pnp.js" ;
112
116
113
117
/** @internal */
114
118
export function trace ( host : ModuleResolutionHost , message : DiagnosticMessage , ...args : any [ ] ) : void {
@@ -494,7 +498,7 @@ export function getEffectiveTypeRoots(options: CompilerOptions, host: GetEffecti
494
498
* Returns the path to every node_modules/@types directory from some ancestor directory.
495
499
* Returns undefined if there are none.
496
500
*/
497
- function getDefaultTypeRoots ( currentDirectory : string ) : string [ ] | undefined {
501
+ function getNodeModulesTypeRoots ( currentDirectory : string ) {
498
502
let typeRoots : string [ ] | undefined ;
499
503
forEachAncestorDirectory ( normalizePath ( currentDirectory ) , directory => {
500
504
const atTypes = combinePaths ( directory , nodeModulesAtTypes ) ;
@@ -509,6 +513,18 @@ function arePathsEqual(path1: string, path2: string, host: ModuleResolutionHost)
509
513
return comparePaths ( path1 , path2 , ! useCaseSensitiveFileNames ) === Comparison . EqualTo ;
510
514
}
511
515
516
+ function getDefaultTypeRoots ( currentDirectory : string ) : string [ ] | undefined {
517
+ const nmTypes = getNodeModulesTypeRoots ( currentDirectory ) ;
518
+ const pnpTypes = getPnpTypeRoots ( currentDirectory ) ;
519
+
520
+ if ( nmTypes ?. length ) {
521
+ return [ ...nmTypes , ...pnpTypes ] ;
522
+ }
523
+ else if ( pnpTypes . length ) {
524
+ return pnpTypes ;
525
+ }
526
+ }
527
+
512
528
function getOriginalAndResolvedFileName ( fileName : string , host : ModuleResolutionHost , traceEnabled : boolean ) {
513
529
const resolvedFileName = realPath ( fileName , host , traceEnabled ) ;
514
530
const pathsAreEqual = arePathsEqual ( fileName , resolvedFileName , host ) ;
@@ -789,6 +805,18 @@ export function resolvePackageNameToPackageJson(
789
805
) : PackageJsonInfo | undefined {
790
806
const moduleResolutionState = getTemporaryModuleResolutionState ( cache ?. getPackageJsonInfoCache ( ) , host , options ) ;
791
807
808
+ const pnpapi = getPnpApi ( containingDirectory ) ;
809
+ if ( pnpapi ) {
810
+ try {
811
+ const resolution = pnpapi . resolveToUnqualified ( packageName , `${ containingDirectory } /` , { considerBuiltins : false } ) ;
812
+ const candidate = normalizeSlashes ( resolution ) . replace ( / \/ $ / , "" ) ;
813
+ return getPackageJsonInfo ( candidate , /*onlyRecordFailures*/ false , moduleResolutionState ) ;
814
+ }
815
+ catch {
816
+ return ;
817
+ }
818
+ }
819
+
792
820
return forEachAncestorDirectory ( containingDirectory , ancestorDirectory => {
793
821
if ( getBaseFileName ( ancestorDirectory ) !== "node_modules" ) {
794
822
const nodeModulesFolder = combinePaths ( ancestorDirectory , "node_modules" ) ;
@@ -3012,7 +3040,16 @@ function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions,
3012
3040
}
3013
3041
3014
3042
function lookup ( extensions : Extensions ) {
3015
- return forEachAncestorDirectory ( normalizeSlashes ( directory ) , ancestorDirectory => {
3043
+ const issuer = normalizeSlashes ( directory ) ;
3044
+ if ( getPnpApi ( issuer ) ) {
3045
+ const resolutionFromCache = tryFindNonRelativeModuleNameInCache ( cache , moduleName , mode , issuer , redirectedReference , state ) ;
3046
+ if ( resolutionFromCache ) {
3047
+ return resolutionFromCache ;
3048
+ }
3049
+ return toSearchResult ( loadModuleFromImmediateNodeModulesDirectoryPnP ( extensions , moduleName , issuer , state , typesScopeOnly , cache , redirectedReference ) ) ;
3050
+ }
3051
+
3052
+ return forEachAncestorDirectory ( issuer , ancestorDirectory => {
3016
3053
if ( getBaseFileName ( ancestorDirectory ) !== "node_modules" ) {
3017
3054
const resolutionFromCache = tryFindNonRelativeModuleNameInCache ( cache , moduleName , mode , ancestorDirectory , redirectedReference , state ) ;
3018
3055
if ( resolutionFromCache ) {
@@ -3051,11 +3088,34 @@ function loadModuleFromImmediateNodeModulesDirectory(extensions: Extensions, mod
3051
3088
}
3052
3089
}
3053
3090
3091
+ function loadModuleFromImmediateNodeModulesDirectoryPnP ( extensions : Extensions , moduleName : string , directory : string , state : ModuleResolutionState , typesScopeOnly : boolean , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) : Resolved | undefined {
3092
+ const issuer = normalizeSlashes ( directory ) ;
3093
+
3094
+ if ( ! typesScopeOnly ) {
3095
+ const packageResult = tryLoadModuleUsingPnpResolution ( extensions , moduleName , issuer , state , cache , redirectedReference ) ;
3096
+ if ( packageResult ) {
3097
+ return packageResult ;
3098
+ }
3099
+ }
3100
+
3101
+ if ( extensions & Extensions . Declaration ) {
3102
+ return tryLoadModuleUsingPnpResolution ( Extensions . Declaration , `@types/${ mangleScopedPackageNameWithTrace ( moduleName , state ) } ` , issuer , state , cache , redirectedReference ) ;
3103
+ }
3104
+ }
3105
+
3054
3106
function loadModuleFromSpecificNodeModulesDirectory ( extensions : Extensions , moduleName : string , nodeModulesDirectory : string , nodeModulesDirectoryExists : boolean , state : ModuleResolutionState , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) : Resolved | undefined {
3055
3107
const candidate = normalizePath ( combinePaths ( nodeModulesDirectory , moduleName ) ) ;
3056
3108
const { packageName, rest } = parsePackageName ( moduleName ) ;
3057
3109
const packageDirectory = combinePaths ( nodeModulesDirectory , packageName ) ;
3110
+ return loadModuleFromSpecificNodeModulesDirectoryImpl ( extensions , nodeModulesDirectoryExists , state , cache , redirectedReference , candidate , rest , packageDirectory ) ;
3111
+ }
3058
3112
3113
+ function loadModuleFromPnpResolution ( extensions : Extensions , packageDirectory : string , rest : string , state : ModuleResolutionState , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) : Resolved | undefined {
3114
+ const candidate = normalizePath ( combinePaths ( packageDirectory , rest ) ) ;
3115
+ return loadModuleFromSpecificNodeModulesDirectoryImpl ( extensions , /*nodeModulesDirectoryExists*/ true , state , cache , redirectedReference , candidate , rest , packageDirectory ) ;
3116
+ }
3117
+
3118
+ function loadModuleFromSpecificNodeModulesDirectoryImpl ( extensions : Extensions , nodeModulesDirectoryExists : boolean , state : ModuleResolutionState , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined , candidate : string , rest : string , packageDirectory : string ) : Resolved | undefined {
3059
3119
let rootPackageInfo : PackageJsonInfo | undefined ;
3060
3120
// First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
3061
3121
let packageInfo = getPackageJsonInfo ( candidate , ! nodeModulesDirectoryExists , state ) ;
@@ -3387,3 +3447,22 @@ function useCaseSensitiveFileNames(state: ModuleResolutionState) {
3387
3447
typeof state . host . useCaseSensitiveFileNames === "boolean" ? state . host . useCaseSensitiveFileNames :
3388
3448
state . host . useCaseSensitiveFileNames ( ) ;
3389
3449
}
3450
+
3451
+ function loadPnpPackageResolution ( packageName : string , containingDirectory : string ) {
3452
+ try {
3453
+ const resolution = getPnpApi ( containingDirectory ) . resolveToUnqualified ( packageName , `${ containingDirectory } /` , { considerBuiltins : false } ) ;
3454
+ return normalizeSlashes ( resolution ) . replace ( / \/ $ / , "" ) ;
3455
+ }
3456
+ catch {
3457
+ // Nothing to do
3458
+ }
3459
+ }
3460
+
3461
+ function tryLoadModuleUsingPnpResolution ( extensions : Extensions , moduleName : string , containingDirectory : string , state : ModuleResolutionState , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) {
3462
+ const { packageName, rest } = parsePackageName ( moduleName ) ;
3463
+
3464
+ const packageResolution = loadPnpPackageResolution ( packageName , containingDirectory ) ;
3465
+ return packageResolution
3466
+ ? loadModuleFromPnpResolution ( extensions , packageResolution , rest , state , cache , redirectedReference )
3467
+ : undefined ;
3468
+ }
0 commit comments