@@ -669,11 +669,30 @@ namespace ts.codefix {
669
669
}
670
670
}
671
671
672
+ /**
673
+ * We only allow PnP to be used as a resolution strategy if TypeScript
674
+ * itself is executed under a PnP runtime (and we only allow it to access
675
+ * the current PnP runtime, not any on the disk). This ensures that we
676
+ * don't execute potentially malicious code that didn't already have a
677
+ * chance to be executed (if we're running within the runtime, it means
678
+ * that the runtime has already been executed).
679
+ * @internal
680
+ */
681
+ function isPnpAvailable ( ) {
682
+ // @ts -ignore
683
+ return process . versions . pnp ;
684
+ }
685
+
686
+ function getPnpApi ( ) {
687
+ // @ts -ignore
688
+ return require ( "pnpapi" ) ;
689
+ }
690
+
672
691
/**
673
692
* Don't include something from a `node_modules` that isn't actually reachable by a global import.
674
693
* A relative import to node_modules is usually a bad idea.
675
694
*/
676
- function isImportablePath ( fromPath : string , toPath : string , getCanonicalFileName : GetCanonicalFileName , globalCachePath ?: string ) : boolean {
695
+ function isImportablePathNode ( fromPath : string , toPath : string , getCanonicalFileName : GetCanonicalFileName , globalCachePath ?: string ) : boolean {
677
696
// If it's in a `node_modules` but is not reachable from here via a global import, don't bother.
678
697
const toNodeModules = forEachAncestorDirectory ( toPath , ancestor => getBaseFileName ( ancestor ) === "node_modules" ? ancestor : undefined ) ;
679
698
const toNodeModulesParent = toNodeModules && getDirectoryPath ( getCanonicalFileName ( toNodeModules ) ) ;
@@ -682,6 +701,30 @@ namespace ts.codefix {
682
701
|| ( ! ! globalCachePath && startsWith ( getCanonicalFileName ( globalCachePath ) , toNodeModulesParent ) ) ;
683
702
}
684
703
704
+ function isImportablePathPnp ( fromPath : string , toPath : string ) : boolean {
705
+ const pnpApi = getPnpApi ( ) ;
706
+
707
+ const fromLocator = pnpApi . findPackageLocator ( fromPath ) ;
708
+ const toLocator = pnpApi . findPackageLocator ( toPath ) ;
709
+
710
+ if ( toLocator === null ) {
711
+ return false ;
712
+ }
713
+
714
+ const fromInfo = pnpApi . getPackageInformation ( fromLocator ) ;
715
+ const toReference = fromInfo . packageDependencies . get ( toLocator . name ) ;
716
+
717
+ return toReference === toLocator . reference ;
718
+ }
719
+
720
+ function isImportablePath ( fromPath : string , toPath : string , getCanonicalFileName : GetCanonicalFileName , globalCachePath ?: string ) : boolean {
721
+ if ( isPnpAvailable ( ) ) {
722
+ return isImportablePathPnp ( fromPath , toPath ) ;
723
+ } else {
724
+ return isImportablePathNode ( fromPath , toPath , getCanonicalFileName , globalCachePath ) ;
725
+ }
726
+ }
727
+
685
728
export function moduleSymbolToValidIdentifier ( moduleSymbol : Symbol , target : ScriptTarget ) : string {
686
729
return moduleSpecifierToValidIdentifier ( removeFileExtension ( stripQuotes ( moduleSymbol . name ) ) , target ) ;
687
730
}
0 commit comments