@@ -110,6 +110,8 @@ import {
110
110
versionMajorMinor ,
111
111
VersionRange ,
112
112
} from "./_namespaces/ts.js" ;
113
+ import { getPnpTypeRoots } from "./pnp.js" ;
114
+ import { getPnpApi } from "./pnpapi.js" ;
113
115
114
116
/** @internal */
115
117
export function trace ( host : ModuleResolutionHost , message : DiagnosticMessage , ...args : any [ ] ) : void {
@@ -495,7 +497,7 @@ export function getEffectiveTypeRoots(options: CompilerOptions, host: GetEffecti
495
497
* Returns the path to every node_modules/@types directory from some ancestor directory.
496
498
* Returns undefined if there are none.
497
499
*/
498
- function getDefaultTypeRoots ( currentDirectory : string ) : string [ ] | undefined {
500
+ function getNodeModulesTypeRoots ( currentDirectory : string ) {
499
501
let typeRoots : string [ ] | undefined ;
500
502
forEachAncestorDirectory ( normalizePath ( currentDirectory ) , directory => {
501
503
const atTypes = combinePaths ( directory , nodeModulesAtTypes ) ;
@@ -510,6 +512,18 @@ function arePathsEqual(path1: string, path2: string, host: ModuleResolutionHost)
510
512
return comparePaths ( path1 , path2 , ! useCaseSensitiveFileNames ) === Comparison . EqualTo ;
511
513
}
512
514
515
+ function getDefaultTypeRoots ( currentDirectory : string ) : string [ ] | undefined {
516
+ const nmTypes = getNodeModulesTypeRoots ( currentDirectory ) ;
517
+ const pnpTypes = getPnpTypeRoots ( currentDirectory ) ;
518
+
519
+ if ( nmTypes ?. length ) {
520
+ return [ ...nmTypes , ...pnpTypes ] ;
521
+ }
522
+ else if ( pnpTypes . length ) {
523
+ return pnpTypes ;
524
+ }
525
+ }
526
+
513
527
function getOriginalAndResolvedFileName ( fileName : string , host : ModuleResolutionHost , traceEnabled : boolean ) {
514
528
const resolvedFileName = realPath ( fileName , host , traceEnabled ) ;
515
529
const pathsAreEqual = arePathsEqual ( fileName , resolvedFileName , host ) ;
@@ -790,6 +804,18 @@ export function resolvePackageNameToPackageJson(
790
804
) : PackageJsonInfo | undefined {
791
805
const moduleResolutionState = getTemporaryModuleResolutionState ( cache ?. getPackageJsonInfoCache ( ) , host , options ) ;
792
806
807
+ const pnpapi = getPnpApi ( containingDirectory ) ;
808
+ if ( pnpapi ) {
809
+ try {
810
+ const resolution = pnpapi . resolveToUnqualified ( packageName , `${ containingDirectory } /` , { considerBuiltins : false } ) ;
811
+ const candidate = normalizeSlashes ( resolution ) . replace ( / \/ $ / , "" ) ;
812
+ return getPackageJsonInfo ( candidate , /*onlyRecordFailures*/ false , moduleResolutionState ) ;
813
+ }
814
+ catch {
815
+ return ;
816
+ }
817
+ }
818
+
793
819
return forEachAncestorDirectoryStoppingAtGlobalCache ( host , containingDirectory , ancestorDirectory => {
794
820
if ( getBaseFileName ( ancestorDirectory ) !== "node_modules" ) {
795
821
const nodeModulesFolder = combinePaths ( ancestorDirectory , "node_modules" ) ;
@@ -3007,6 +3033,15 @@ function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions,
3007
3033
}
3008
3034
3009
3035
function lookup ( extensions : Extensions ) {
3036
+ const issuer = normalizeSlashes ( directory ) ;
3037
+ if ( getPnpApi ( issuer ) ) {
3038
+ const resolutionFromCache = tryFindNonRelativeModuleNameInCache ( cache , moduleName , mode , issuer , redirectedReference , state ) ;
3039
+ if ( resolutionFromCache ) {
3040
+ return resolutionFromCache ;
3041
+ }
3042
+ return toSearchResult ( loadModuleFromImmediateNodeModulesDirectoryPnP ( extensions , moduleName , issuer , state , typesScopeOnly , cache , redirectedReference ) ) ;
3043
+ }
3044
+
3010
3045
return forEachAncestorDirectoryStoppingAtGlobalCache (
3011
3046
state . host ,
3012
3047
normalizeSlashes ( directory ) ,
@@ -3069,11 +3104,34 @@ function loadModuleFromImmediateNodeModulesDirectory(extensions: Extensions, mod
3069
3104
}
3070
3105
}
3071
3106
3107
+ function loadModuleFromImmediateNodeModulesDirectoryPnP ( extensions : Extensions , moduleName : string , directory : string , state : ModuleResolutionState , typesScopeOnly : boolean , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) : Resolved | undefined {
3108
+ const issuer = normalizeSlashes ( directory ) ;
3109
+
3110
+ if ( ! typesScopeOnly ) {
3111
+ const packageResult = tryLoadModuleUsingPnpResolution ( extensions , moduleName , issuer , state , cache , redirectedReference ) ;
3112
+ if ( packageResult ) {
3113
+ return packageResult ;
3114
+ }
3115
+ }
3116
+
3117
+ if ( extensions & Extensions . Declaration ) {
3118
+ return tryLoadModuleUsingPnpResolution ( Extensions . Declaration , `@types/${ mangleScopedPackageNameWithTrace ( moduleName , state ) } ` , issuer , state , cache , redirectedReference ) ;
3119
+ }
3120
+ }
3121
+
3072
3122
function loadModuleFromSpecificNodeModulesDirectory ( extensions : Extensions , moduleName : string , nodeModulesDirectory : string , nodeModulesDirectoryExists : boolean , state : ModuleResolutionState , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) : Resolved | undefined {
3073
3123
const candidate = normalizePath ( combinePaths ( nodeModulesDirectory , moduleName ) ) ;
3074
3124
const { packageName, rest } = parsePackageName ( moduleName ) ;
3075
3125
const packageDirectory = combinePaths ( nodeModulesDirectory , packageName ) ;
3126
+ return loadModuleFromSpecificNodeModulesDirectoryImpl ( extensions , nodeModulesDirectoryExists , state , cache , redirectedReference , candidate , rest , packageDirectory ) ;
3127
+ }
3128
+
3129
+ function loadModuleFromPnpResolution ( extensions : Extensions , packageDirectory : string , rest : string , state : ModuleResolutionState , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) : Resolved | undefined {
3130
+ const candidate = normalizePath ( combinePaths ( packageDirectory , rest ) ) ;
3131
+ return loadModuleFromSpecificNodeModulesDirectoryImpl ( extensions , /*nodeModulesDirectoryExists*/ true , state , cache , redirectedReference , candidate , rest , packageDirectory ) ;
3132
+ }
3076
3133
3134
+ function loadModuleFromSpecificNodeModulesDirectoryImpl ( extensions : Extensions , nodeModulesDirectoryExists : boolean , state : ModuleResolutionState , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined , candidate : string , rest : string , packageDirectory : string ) : Resolved | undefined {
3077
3135
let rootPackageInfo : PackageJsonInfo | undefined ;
3078
3136
// First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
3079
3137
let packageInfo = getPackageJsonInfo ( candidate , ! nodeModulesDirectoryExists , state ) ;
@@ -3409,3 +3467,22 @@ function useCaseSensitiveFileNames(state: ModuleResolutionState) {
3409
3467
typeof state . host . useCaseSensitiveFileNames === "boolean" ? state . host . useCaseSensitiveFileNames :
3410
3468
state . host . useCaseSensitiveFileNames ( ) ;
3411
3469
}
3470
+
3471
+ function loadPnpPackageResolution ( packageName : string , containingDirectory : string ) {
3472
+ try {
3473
+ const resolution = getPnpApi ( containingDirectory ) . resolveToUnqualified ( packageName , `${ containingDirectory } /` , { considerBuiltins : false } ) ;
3474
+ return normalizeSlashes ( resolution ) . replace ( / \/ $ / , "" ) ;
3475
+ }
3476
+ catch {
3477
+ // Nothing to do
3478
+ }
3479
+ }
3480
+
3481
+ function tryLoadModuleUsingPnpResolution ( extensions : Extensions , moduleName : string , containingDirectory : string , state : ModuleResolutionState , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) {
3482
+ const { packageName, rest } = parsePackageName ( moduleName ) ;
3483
+
3484
+ const packageResolution = loadPnpPackageResolution ( packageName , containingDirectory ) ;
3485
+ return packageResolution
3486
+ ? loadModuleFromPnpResolution ( extensions , packageResolution , rest , state , cache , redirectedReference )
3487
+ : undefined ;
3488
+ }
0 commit comments