@@ -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" ) ;
@@ -3013,6 +3039,15 @@ function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions,
3013
3039
}
3014
3040
3015
3041
function lookup ( extensions : Extensions ) {
3042
+ const issuer = normalizeSlashes ( directory ) ;
3043
+ if ( getPnpApi ( issuer ) ) {
3044
+ const resolutionFromCache = tryFindNonRelativeModuleNameInCache ( cache , moduleName , mode , issuer , redirectedReference , state ) ;
3045
+ if ( resolutionFromCache ) {
3046
+ return resolutionFromCache ;
3047
+ }
3048
+ return toSearchResult ( loadModuleFromImmediateNodeModulesDirectoryPnP ( extensions , moduleName , issuer , state , typesScopeOnly , cache , redirectedReference ) ) ;
3049
+ }
3050
+
3016
3051
return forEachAncestorDirectoryStoppingAtGlobalCache (
3017
3052
state . host ,
3018
3053
normalizeSlashes ( directory ) ,
@@ -3075,11 +3110,34 @@ function loadModuleFromImmediateNodeModulesDirectory(extensions: Extensions, mod
3075
3110
}
3076
3111
}
3077
3112
3113
+ function loadModuleFromImmediateNodeModulesDirectoryPnP ( extensions : Extensions , moduleName : string , directory : string , state : ModuleResolutionState , typesScopeOnly : boolean , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) : Resolved | undefined {
3114
+ const issuer = normalizeSlashes ( directory ) ;
3115
+
3116
+ if ( ! typesScopeOnly ) {
3117
+ const packageResult = tryLoadModuleUsingPnpResolution ( extensions , moduleName , issuer , state , cache , redirectedReference ) ;
3118
+ if ( packageResult ) {
3119
+ return packageResult ;
3120
+ }
3121
+ }
3122
+
3123
+ if ( extensions & Extensions . Declaration ) {
3124
+ return tryLoadModuleUsingPnpResolution ( Extensions . Declaration , `@types/${ mangleScopedPackageNameWithTrace ( moduleName , state ) } ` , issuer , state , cache , redirectedReference ) ;
3125
+ }
3126
+ }
3127
+
3078
3128
function loadModuleFromSpecificNodeModulesDirectory ( extensions : Extensions , moduleName : string , nodeModulesDirectory : string , nodeModulesDirectoryExists : boolean , state : ModuleResolutionState , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) : Resolved | undefined {
3079
3129
const candidate = normalizePath ( combinePaths ( nodeModulesDirectory , moduleName ) ) ;
3080
3130
const { packageName, rest } = parsePackageName ( moduleName ) ;
3081
3131
const packageDirectory = combinePaths ( nodeModulesDirectory , packageName ) ;
3132
+ return loadModuleFromSpecificNodeModulesDirectoryImpl ( extensions , nodeModulesDirectoryExists , state , cache , redirectedReference , candidate , rest , packageDirectory ) ;
3133
+ }
3134
+
3135
+ function loadModuleFromPnpResolution ( extensions : Extensions , packageDirectory : string , rest : string , state : ModuleResolutionState , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) : Resolved | undefined {
3136
+ const candidate = normalizePath ( combinePaths ( packageDirectory , rest ) ) ;
3137
+ return loadModuleFromSpecificNodeModulesDirectoryImpl ( extensions , /*nodeModulesDirectoryExists*/ true , state , cache , redirectedReference , candidate , rest , packageDirectory ) ;
3138
+ }
3082
3139
3140
+ function loadModuleFromSpecificNodeModulesDirectoryImpl ( extensions : Extensions , nodeModulesDirectoryExists : boolean , state : ModuleResolutionState , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined , candidate : string , rest : string , packageDirectory : string ) : Resolved | undefined {
3083
3141
let rootPackageInfo : PackageJsonInfo | undefined ;
3084
3142
// First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
3085
3143
let packageInfo = getPackageJsonInfo ( candidate , ! nodeModulesDirectoryExists , state ) ;
@@ -3415,3 +3473,22 @@ function useCaseSensitiveFileNames(state: ModuleResolutionState) {
3415
3473
typeof state . host . useCaseSensitiveFileNames === "boolean" ? state . host . useCaseSensitiveFileNames :
3416
3474
state . host . useCaseSensitiveFileNames ( ) ;
3417
3475
}
3476
+
3477
+ function loadPnpPackageResolution ( packageName : string , containingDirectory : string ) {
3478
+ try {
3479
+ const resolution = getPnpApi ( containingDirectory ) . resolveToUnqualified ( packageName , `${ containingDirectory } /` , { considerBuiltins : false } ) ;
3480
+ return normalizeSlashes ( resolution ) . replace ( / \/ $ / , "" ) ;
3481
+ }
3482
+ catch {
3483
+ // Nothing to do
3484
+ }
3485
+ }
3486
+
3487
+ function tryLoadModuleUsingPnpResolution ( extensions : Extensions , moduleName : string , containingDirectory : string , state : ModuleResolutionState , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) {
3488
+ const { packageName, rest } = parsePackageName ( moduleName ) ;
3489
+
3490
+ const packageResolution = loadPnpPackageResolution ( packageName , containingDirectory ) ;
3491
+ return packageResolution
3492
+ ? loadModuleFromPnpResolution ( extensions , packageResolution , rest , state , cache , redirectedReference )
3493
+ : undefined ;
3494
+ }
0 commit comments