Skip to content

Instantly share code, notes, and snippets.

@strothj
Last active August 27, 2021 03:18
Show Gist options
  • Save strothj/c863b603e00c1a8cfe1b0d426b9d8327 to your computer and use it in GitHub Desktop.
Save strothj/c863b603e00c1a8cfe1b0d426b9d8327 to your computer and use it in GitHub Desktop.
Yarn v3 patch: typescript@4.4.2
{
"resolutions": {
"typescript": "patch:typescript@4.4.2#./.yarn/patches/typescript.diff"
}
}
diff --git a/lib/tsc.js b/lib/tsc.js
index d425ad1b5..4c61f37c2 100644
semver exclusivity 4.4.2
--- a/lib/tsc.js
+++ b/lib/tsc.js
@@ -4758,6 +4758,9 @@ var ts;
: new Buffer(input, encoding);
}
function isFileSystemCaseSensitive() {
+ if (process.versions.pnp) {
+ return true;
+ }
if (platform === "win32" || platform === "win64") {
return false;
}
@@ -33390,21 +33393,52 @@ var ts;
}
}
ts.getEffectiveTypeRoots = getEffectiveTypeRoots;
- function getDefaultTypeRoots(currentDirectory, host) {
+ function getNodeModulesTypeRoots(currentDirectory, host) {
if (!host.directoryExists) {
return [ts.combinePaths(currentDirectory, nodeModulesAtTypes)];
}
- var typeRoots;
+ var typeRoots = [];
ts.forEachAncestorDirectory(ts.normalizePath(currentDirectory), function (directory) {
var atTypes = ts.combinePaths(directory, nodeModulesAtTypes);
if (host.directoryExists(atTypes)) {
- (typeRoots || (typeRoots = [])).push(atTypes);
+ typeRoots.push(atTypes);
}
return undefined;
});
return typeRoots;
}
var nodeModulesAtTypes = ts.combinePaths("node_modules", "@types");
+ function getPnpTypeRoots(currentDirectory) {
+ var pnpapi = getPnpApi(currentDirectory);
+ if (!pnpapi) {
+ return [];
+ }
+ currentDirectory = ts.sys.resolvePath(currentDirectory);
+ var currentPackage = pnpapi.findPackageLocator(currentDirectory + "/");
+ if (!currentPackage) {
+ return [];
+ }
+ var packageDependencies = pnpapi.getPackageInformation(currentPackage).packageDependencies;
+ var typeRoots = [];
+ for (var _i = 0, _a = Array.from(packageDependencies.entries()); _i < _a.length; _i++) {
+ var _b = _a[_i], name = _b[0], referencish = _b[1];
+ if (name.startsWith(typesPackagePrefix) && referencish !== null) {
+ var dependencyLocator = pnpapi.getLocator(name, referencish);
+ var packageLocation = pnpapi.getPackageInformation(dependencyLocator).packageLocation;
+ typeRoots.push(ts.getDirectoryPath(packageLocation));
+ }
+ }
+ return typeRoots;
+ }
+ ts.getPnpTypeRoots = getPnpTypeRoots;
+ var typesPackagePrefix = "@types/";
+ function getDefaultTypeRoots(currentDirectory, host) {
+ var nmTypes = getNodeModulesTypeRoots(currentDirectory, host);
+ var pnpTypes = getPnpTypeRoots(currentDirectory);
+ if (nmTypes.length > 0 || pnpTypes.length > 0) {
+ return __spreadArray(__spreadArray([], nmTypes, true), pnpTypes, true);
+ }
+ }
function resolveTypeReferenceDirective(typeReferenceDirectiveName, containingFile, options, host, redirectedReference, cache) {
var traceEnabled = isTraceEnabled(options, host);
if (redirectedReference) {
@@ -33511,7 +33545,9 @@ var ts;
}
var result_4;
if (!ts.isExternalModuleNameRelative(typeReferenceDirectiveName)) {
- var searchResult = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, undefined, undefined);
+ var searchResult = getPnpApi(initialLocationForSecondaryLookup)
+ ? tryLoadModuleUsingPnpResolution(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState)
+ : loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, undefined, undefined);
result_4 = searchResult && searchResult.value;
}
else {
@@ -33954,9 +33990,12 @@ var ts;
if (traceEnabled) {
trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]);
}
- var resolved_1 = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
- if (!resolved_1)
+ var resolved_1 = getPnpApi(containingDirectory)
+ ? tryLoadModuleUsingPnpResolution(extensions, moduleName, containingDirectory, state)
+ : loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
+ if (!resolved_1) {
return undefined;
+ }
var resolvedValue = resolved_1.value;
if (!compilerOptions.preserveSymlinks && resolvedValue && !resolvedValue.originalPath) {
var path = realPath(resolvedValue.path, host, traceEnabled);
@@ -34267,6 +34306,14 @@ var ts;
}
function loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state) {
var candidate = ts.normalizePath(ts.combinePaths(nodeModulesDirectory, moduleName));
+ return loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state, candidate, undefined, undefined);
+ }
+ function loadModuleFromPnpResolution(extensions, packageDirectory, rest, state) {
+ var candidate = ts.normalizePath(ts.combinePaths(packageDirectory, rest));
+ return loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, undefined, undefined, true, state, candidate, rest, packageDirectory);
+ }
+ function loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state, candidate, rest, packageDirectory) {
+ var _a;
var packageInfo = getPackageJsonInfo(candidate, !nodeModulesDirectoryExists, state);
if (packageInfo) {
var fromFile = loadModuleFromFile(extensions, candidate, !nodeModulesDirectoryExists, state);
@@ -34281,9 +34328,12 @@ var ts;
loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageInfo && packageInfo.packageJsonContent, packageInfo && packageInfo.versionPaths);
return withPackageId(packageInfo, pathAndExtension);
};
- var _a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
+ var packageName;
+ if (rest === undefined)
+ (_a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest);
if (rest !== "") {
- var packageDirectory = ts.combinePaths(nodeModulesDirectory, packageName);
+ if (packageDirectory === undefined)
+ packageDirectory = ts.combinePaths(nodeModulesDirectory, packageName);
packageInfo = getPackageJsonInfo(packageDirectory, !nodeModulesDirectoryExists, state);
if (packageInfo && packageInfo.versionPaths) {
if (state.traceEnabled) {
@@ -34421,6 +34471,47 @@ var ts;
function toSearchResult(value) {
return value !== undefined ? { value: value } : undefined;
}
+ function getPnpApi(path) {
+ var findPnpApi = require("module").findPnpApi;
+ if (findPnpApi === undefined) {
+ return undefined;
+ }
+ return findPnpApi(path + "/");
+ }
+ function loadPnpPackageResolution(packageName, containingDirectory) {
+ try {
+ var resolution = getPnpApi(containingDirectory).resolveToUnqualified(packageName, containingDirectory + "/", { considerBuiltins: false });
+ return ts.normalizeSlashes(resolution);
+ }
+ catch (_a) {
+ }
+ }
+ function loadPnpTypePackageResolution(packageName, containingDirectory) {
+ return loadPnpPackageResolution(getTypesPackageName(packageName), containingDirectory);
+ }
+ function tryLoadModuleUsingPnpResolution(extensions, moduleName, containingDirectory, state) {
+ var _a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
+ var packageResolution = loadPnpPackageResolution(packageName, containingDirectory);
+ var packageFullResolution = packageResolution
+ ? loadModuleFromPnpResolution(extensions, packageResolution, rest, state)
+ : undefined;
+ var resolved;
+ if (packageFullResolution) {
+ resolved = packageFullResolution;
+ }
+ else if (extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) {
+ var typePackageResolution = loadPnpTypePackageResolution(packageName, containingDirectory);
+ var typePackageFullResolution = typePackageResolution
+ ? loadModuleFromPnpResolution(Extensions.DtsOnly, typePackageResolution, rest, state)
+ : undefined;
+ if (typePackageFullResolution) {
+ resolved = typePackageFullResolution;
+ }
+ }
+ if (resolved) {
+ return toSearchResult(resolved);
+ }
+ }
})(ts || (ts = {}));
var ts;
(function (ts) {
@@ -91002,6 +91093,7 @@ var ts;
ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["None"] = 0] = "None";
ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Partial"] = 1] = "Partial";
ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Full"] = 2] = "Full";
+ ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Resolutions"] = 3] = "Resolutions";
})(ConfigFileProgramReloadLevel = ts.ConfigFileProgramReloadLevel || (ts.ConfigFileProgramReloadLevel = {}));
function updateSharedExtendedConfigFileWatcher(projectPath, options, extendedConfigFilesMap, createExtendedConfigFileWatch, toPath) {
var _a;
@@ -96668,6 +96760,25 @@ var ts;
return undefined;
}
var parts = getNodeModulePathParts(path);
+ var packageName;
+ if (!parts && typeof process.versions.pnp !== "undefined") {
+ var pnpApi = require("pnpapi");
+ var locator = pnpApi.findPackageLocator(path);
+ if (locator !== null) {
+ var sourceLocator = pnpApi.findPackageLocator(sourceDirectory + "/");
+ if (locator === sourceLocator) {
+ return undefined;
+ }
+ var information = pnpApi.getPackageInformation(locator);
+ packageName = locator.name;
+ parts = {
+ topLevelNodeModulesIndex: undefined,
+ topLevelPackageNameIndex: undefined,
+ packageRootIndex: information.packageLocation.length - 1,
+ fileNameIndex: path.lastIndexOf("/"),
+ };
+ }
+ }
if (!parts) {
return undefined;
}
@@ -96695,14 +96806,18 @@ var ts;
if (isRedirect && !isPackageRootPath) {
return undefined;
}
- var globalTypingsCacheLocation = host.getGlobalTypingsCacheLocation && host.getGlobalTypingsCacheLocation();
- var pathToTopLevelNodeModules = getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex));
- if (!(ts.startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && ts.startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) {
- return undefined;
+ if (typeof process.versions.pnp === "undefined") {
+ var globalTypingsCacheLocation = host.getGlobalTypingsCacheLocation && host.getGlobalTypingsCacheLocation();
+ var pathToTopLevelNodeModules = getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex));
+ if (!(ts.startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && ts.startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) {
+ return undefined;
+ }
}
- var nodeModulesDirectoryName = moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
- var packageName = ts.getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
- return ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs && packageName === nodeModulesDirectoryName ? undefined : packageName;
+ var nodeModulesDirectoryName = typeof packageName !== "undefined"
+ ? packageName + moduleSpecifier.substring(parts.packageRootIndex)
+ : moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
+ var packageNameFromPath = ts.getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
+ return ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs && packageNameFromPath === nodeModulesDirectoryName ? undefined : packageNameFromPath;
function tryDirectoryWithPackageJson(packageRootIndex) {
var packageRootPath = path.substring(0, packageRootIndex);
var packageJsonPath = ts.combinePaths(packageRootPath, "package.json");
@@ -97430,6 +97545,10 @@ var ts;
if (configFileName) {
configFileWatcher = watchFile(configFileName, scheduleProgramReload, ts.PollingInterval.High, watchOptions, ts.WatchType.ConfigFile);
}
+ var pnpFileWatcher;
+ if (typeof process.versions.pnp !== "undefined") {
+ pnpFileWatcher = watchFile(require.resolve("pnpapi"), scheduleResolutionReload, ts.PollingInterval.High, watchOptions, ts.WatchType.ConfigFile);
+ }
var compilerHost = ts.createCompilerHostFromProgramHost(host, function () { return compilerOptions; }, directoryStructureHost);
ts.setGetSourceFileAsHashVersioned(compilerHost, host);
var getNewSourceFile = compilerHost.getSourceFile;
@@ -97501,6 +97620,10 @@ var ts;
configFileWatcher.close();
configFileWatcher = undefined;
}
+ if (pnpFileWatcher) {
+ pnpFileWatcher.close();
+ pnpFileWatcher = undefined;
+ }
extendedConfigCache === null || extendedConfigCache === void 0 ? void 0 : extendedConfigCache.clear();
extendedConfigCache = undefined;
if (sharedExtendedConfigFileWatchers) {
@@ -97533,7 +97656,8 @@ var ts;
function getCurrentProgram() {
return builderProgram && builderProgram.getProgramOrUndefined();
}
- function synchronizeProgram() {
+ function synchronizeProgram(forceAllFilesAsInvalidated) {
+ if (forceAllFilesAsInvalidated === void 0) { forceAllFilesAsInvalidated = false; }
writeLog("Synchronizing program");
clearInvalidateResolutionsOfFailedLookupLocations();
var program = getCurrentBuilderProgram();
@@ -97543,7 +97667,7 @@ var ts;
resolutionCache.clear();
}
}
- var hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution || changesAffectResolution);
+ var hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution || forceAllFilesAsInvalidated);
if (ts.isProgramUptoDate(getCurrentProgram(), rootFileNames, compilerOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {
if (hasChangedConfigFileParsingErrors) {
builderProgram = createProgram(undefined, undefined, compilerHost, builderProgram, configFileParsingDiagnostics, projectReferences);
@@ -97727,6 +97851,12 @@ var ts;
reloadLevel = ts.ConfigFileProgramReloadLevel.Full;
scheduleProgramUpdate();
}
+ function scheduleResolutionReload() {
+ writeLog("Clearing resolutions");
+ resolutionCache.clear();
+ reloadLevel = ts.ConfigFileProgramReloadLevel.Resolutions;
+ scheduleProgramUpdate();
+ }
function updateProgramWithWatchStatus() {
timerToUpdateProgram = undefined;
reportWatchDiagnostic(ts.Diagnostics.File_change_detected_Starting_incremental_compilation);
@@ -97742,6 +97872,10 @@ var ts;
ts.perfLogger.logStartUpdateProgram("FullConfigReload");
reloadConfigFile();
break;
+ case ts.ConfigFileProgramReloadLevel.Resolutions:
+ ts.perfLogger.logStartUpdateProgram("SynchronizeProgramWithResolutions");
+ synchronizeProgram(true);
+ break;
default:
ts.perfLogger.logStartUpdateProgram("SynchronizeProgram");
synchronizeProgram();
diff --git a/lib/tsserver.js b/lib/tsserver.js
index 6e4ee30b7..a774c21dd 100644
semver exclusivity 4.4.2
--- a/lib/tsserver.js
+++ b/lib/tsserver.js
@@ -7458,6 +7458,11 @@ var ts;
: new Buffer(input, encoding);
}
function isFileSystemCaseSensitive() {
+ // The PnP runtime is always case-sensitive
+ // @ts-ignore
+ if (process.versions.pnp) {
+ return true;
+ }
// win32\win64 are case insensitive platforms
if (platform === "win32" || platform === "win64") {
return false;
@@ -40967,24 +40972,56 @@ var ts;
ts.getEffectiveTypeRoots = getEffectiveTypeRoots;
/**
* Returns the path to every node_modules/@types directory from some ancestor directory.
- * Returns undefined if there are none.
*/
- function getDefaultTypeRoots(currentDirectory, host) {
+ function getNodeModulesTypeRoots(currentDirectory, host) {
if (!host.directoryExists) {
return [ts.combinePaths(currentDirectory, nodeModulesAtTypes)];
// And if it doesn't exist, tough.
}
- var typeRoots;
+ var typeRoots = [];
ts.forEachAncestorDirectory(ts.normalizePath(currentDirectory), function (directory) {
var atTypes = ts.combinePaths(directory, nodeModulesAtTypes);
if (host.directoryExists(atTypes)) {
- (typeRoots || (typeRoots = [])).push(atTypes);
+ typeRoots.push(atTypes);
}
return undefined;
});
return typeRoots;
}
var nodeModulesAtTypes = ts.combinePaths("node_modules", "@types");
+ function getPnpTypeRoots(currentDirectory) {
+ var pnpapi = getPnpApi(currentDirectory);
+ if (!pnpapi) {
+ return [];
+ }
+ // Some TS consumers pass relative paths that aren't normalized
+ currentDirectory = ts.sys.resolvePath(currentDirectory);
+ var currentPackage = pnpapi.findPackageLocator(currentDirectory + "/");
+ if (!currentPackage) {
+ return [];
+ }
+ var packageDependencies = pnpapi.getPackageInformation(currentPackage).packageDependencies;
+ var typeRoots = [];
+ for (var _i = 0, _a = Array.from(packageDependencies.entries()); _i < _a.length; _i++) {
+ var _b = _a[_i], name = _b[0], referencish = _b[1];
+ // eslint-disable-next-line no-null/no-null
+ if (name.startsWith(typesPackagePrefix) && referencish !== null) {
+ var dependencyLocator = pnpapi.getLocator(name, referencish);
+ var packageLocation = pnpapi.getPackageInformation(dependencyLocator).packageLocation;
+ typeRoots.push(ts.getDirectoryPath(packageLocation));
+ }
+ }
+ return typeRoots;
+ }
+ ts.getPnpTypeRoots = getPnpTypeRoots;
+ var typesPackagePrefix = "@types/";
+ function getDefaultTypeRoots(currentDirectory, host) {
+ var nmTypes = getNodeModulesTypeRoots(currentDirectory, host);
+ var pnpTypes = getPnpTypeRoots(currentDirectory);
+ if (nmTypes.length > 0 || pnpTypes.length > 0) {
+ return __spreadArray(__spreadArray([], nmTypes, true), pnpTypes, true);
+ }
+ }
/**
* @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
@@ -41098,7 +41135,9 @@ var ts;
}
var result_4;
if (!ts.isExternalModuleNameRelative(typeReferenceDirectiveName)) {
- var searchResult = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
+ var searchResult = getPnpApi(initialLocationForSecondaryLookup)
+ ? tryLoadModuleUsingPnpResolution(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState)
+ : loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
result_4 = searchResult && searchResult.value;
}
else {
@@ -41653,9 +41692,12 @@ var ts;
if (traceEnabled) {
trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]);
}
- var resolved_1 = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
- if (!resolved_1)
+ var resolved_1 = getPnpApi(containingDirectory)
+ ? tryLoadModuleUsingPnpResolution(extensions, moduleName, containingDirectory, state)
+ : loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
+ if (!resolved_1) {
return undefined;
+ }
var resolvedValue = resolved_1.value;
if (!compilerOptions.preserveSymlinks && resolvedValue && !resolvedValue.originalPath) {
var path = realPath(resolvedValue.path, host, traceEnabled);
@@ -42000,6 +42042,14 @@ var ts;
}
function loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state) {
var candidate = ts.normalizePath(ts.combinePaths(nodeModulesDirectory, moduleName));
+ return loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state, candidate, undefined, undefined);
+ }
+ function loadModuleFromPnpResolution(extensions, packageDirectory, rest, state) {
+ var candidate = ts.normalizePath(ts.combinePaths(packageDirectory, rest));
+ return loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, undefined, undefined, true, state, candidate, rest, packageDirectory);
+ }
+ function loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state, candidate, rest, packageDirectory) {
+ var _a;
// First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
var packageInfo = getPackageJsonInfo(candidate, !nodeModulesDirectoryExists, state);
if (packageInfo) {
@@ -42015,9 +42065,12 @@ var ts;
loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageInfo && packageInfo.packageJsonContent, packageInfo && packageInfo.versionPaths);
return withPackageId(packageInfo, pathAndExtension);
};
- var _a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
+ var packageName;
+ if (rest === undefined)
+ (_a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest);
if (rest !== "") { // If "rest" is empty, we just did this search above.
- var packageDirectory = ts.combinePaths(nodeModulesDirectory, packageName);
+ if (packageDirectory === undefined)
+ packageDirectory = ts.combinePaths(nodeModulesDirectory, packageName);
// Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId and path mappings.
packageInfo = getPackageJsonInfo(packageDirectory, !nodeModulesDirectoryExists, state);
if (packageInfo && packageInfo.versionPaths) {
@@ -42176,6 +42229,58 @@ var ts;
function toSearchResult(value) {
return value !== undefined ? { value: value } : undefined;
}
+ /**
+ * We only allow PnP to be used as a resolution strategy if TypeScript
+ * itself is executed under a PnP runtime (and we only allow it to access
+ * the current PnP runtime, not any on the disk). This ensures that we
+ * don't execute potentially malicious code that didn't already have a
+ * chance to be executed (if we're running within the runtime, it means
+ * that the runtime has already been executed).
+ * @internal
+ */
+ function getPnpApi(path) {
+ var findPnpApi = require("module").findPnpApi;
+ if (findPnpApi === undefined) {
+ return undefined;
+ }
+ return findPnpApi(path + "/");
+ }
+ function loadPnpPackageResolution(packageName, containingDirectory) {
+ try {
+ var resolution = getPnpApi(containingDirectory).resolveToUnqualified(packageName, containingDirectory + "/", { considerBuiltins: false });
+ return ts.normalizeSlashes(resolution);
+ }
+ catch (_a) {
+ // Nothing to do
+ }
+ }
+ function loadPnpTypePackageResolution(packageName, containingDirectory) {
+ return loadPnpPackageResolution(getTypesPackageName(packageName), containingDirectory);
+ }
+ /* @internal */
+ function tryLoadModuleUsingPnpResolution(extensions, moduleName, containingDirectory, state) {
+ var _a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
+ var packageResolution = loadPnpPackageResolution(packageName, containingDirectory);
+ var packageFullResolution = packageResolution
+ ? loadModuleFromPnpResolution(extensions, packageResolution, rest, state)
+ : undefined;
+ var resolved;
+ if (packageFullResolution) {
+ resolved = packageFullResolution;
+ }
+ else if (extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) {
+ var typePackageResolution = loadPnpTypePackageResolution(packageName, containingDirectory);
+ var typePackageFullResolution = typePackageResolution
+ ? loadModuleFromPnpResolution(Extensions.DtsOnly, typePackageResolution, rest, state)
+ : undefined;
+ if (typePackageFullResolution) {
+ resolved = typePackageFullResolution;
+ }
+ }
+ if (resolved) {
+ return toSearchResult(resolved);
+ }
+ }
})(ts || (ts = {}));
/* @internal */
var ts;
@@ -110519,6 +110624,8 @@ var ts;
ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Partial"] = 1] = "Partial";
/** Reload completely by re-reading contents of config file from disk and updating program */
ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Full"] = 2] = "Full";
+ /** Reload the resolutions */
+ ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Resolutions"] = 3] = "Resolutions";
})(ConfigFileProgramReloadLevel = ts.ConfigFileProgramReloadLevel || (ts.ConfigFileProgramReloadLevel = {}));
/**
* Updates the map of shared extended config file watches with a new set of extended config files from a base config file of the project
@@ -117089,6 +117196,29 @@ var ts;
return undefined;
}
var parts = getNodeModulePathParts(path);
+ var packageName;
+ if (!parts && typeof process.versions.pnp !== "undefined") {
+ var pnpApi = require("pnpapi");
+ var locator = pnpApi.findPackageLocator(path);
+ // eslint-disable-next-line no-null/no-null
+ if (locator !== null) {
+ var sourceLocator = pnpApi.findPackageLocator(sourceDirectory + "/");
+ // Don't use the package name when the imported file is inside
+ // the source directory (prefer a relative path instead)
+ if (locator === sourceLocator) {
+ return undefined;
+ }
+ var information = pnpApi.getPackageInformation(locator);
+ packageName = locator.name;
+ parts = {
+ topLevelNodeModulesIndex: undefined,
+ topLevelPackageNameIndex: undefined,
+ // The last character from packageLocation is the trailing "/", we want to point to it
+ packageRootIndex: information.packageLocation.length - 1,
+ fileNameIndex: path.lastIndexOf("/"),
+ };
+ }
+ }
if (!parts) {
return undefined;
}
@@ -117119,18 +117249,24 @@ var ts;
if (isRedirect && !isPackageRootPath) {
return undefined;
}
- var globalTypingsCacheLocation = host.getGlobalTypingsCacheLocation && host.getGlobalTypingsCacheLocation();
- // Get a path that's relative to node_modules or the importing file's path
- // if node_modules folder is in this folder or any of its parent folders, no need to keep it.
- var pathToTopLevelNodeModules = getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex));
- if (!(ts.startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && ts.startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) {
- return undefined;
+ // If PnP is enabled the node_modules entries we'll get will always be relevant even if they
+ // are located in a weird path apparently outside of the source directory
+ if (typeof process.versions.pnp === "undefined") {
+ var globalTypingsCacheLocation = host.getGlobalTypingsCacheLocation && host.getGlobalTypingsCacheLocation();
+ // Get a path that's relative to node_modules or the importing file's path
+ // if node_modules folder is in this folder or any of its parent folders, no need to keep it.
+ var pathToTopLevelNodeModules = getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex));
+ if (!(ts.startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && ts.startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) {
+ return undefined;
+ }
}
// If the module was found in @types, get the actual Node package name
- var nodeModulesDirectoryName = moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
- var packageName = ts.getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
+ var nodeModulesDirectoryName = typeof packageName !== "undefined"
+ ? packageName + moduleSpecifier.substring(parts.packageRootIndex)
+ : moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
+ var packageNameFromPath = ts.getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
// For classic resolution, only allow importing from node_modules/@types, not other node_modules
- return ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs && packageName === nodeModulesDirectoryName ? undefined : packageName;
+ return ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs && packageNameFromPath === nodeModulesDirectoryName ? undefined : packageNameFromPath;
function tryDirectoryWithPackageJson(packageRootIndex) {
var packageRootPath = path.substring(0, packageRootIndex);
var packageJsonPath = ts.combinePaths(packageRootPath, "package.json");
@@ -117924,6 +118060,10 @@ var ts;
if (configFileName) {
configFileWatcher = watchFile(configFileName, scheduleProgramReload, ts.PollingInterval.High, watchOptions, ts.WatchType.ConfigFile);
}
+ var pnpFileWatcher;
+ if (typeof process.versions.pnp !== "undefined") {
+ pnpFileWatcher = watchFile(require.resolve("pnpapi"), scheduleResolutionReload, ts.PollingInterval.High, watchOptions, ts.WatchType.ConfigFile);
+ }
var compilerHost = ts.createCompilerHostFromProgramHost(host, function () { return compilerOptions; }, directoryStructureHost);
ts.setGetSourceFileAsHashVersioned(compilerHost, host);
// Members for CompilerHost
@@ -118002,6 +118142,10 @@ var ts;
configFileWatcher.close();
configFileWatcher = undefined;
}
+ if (pnpFileWatcher) {
+ pnpFileWatcher.close();
+ pnpFileWatcher = undefined;
+ }
extendedConfigCache === null || extendedConfigCache === void 0 ? void 0 : extendedConfigCache.clear();
extendedConfigCache = undefined;
if (sharedExtendedConfigFileWatchers) {
@@ -118034,7 +118178,8 @@ var ts;
function getCurrentProgram() {
return builderProgram && builderProgram.getProgramOrUndefined();
}
- function synchronizeProgram() {
+ function synchronizeProgram(forceAllFilesAsInvalidated) {
+ if (forceAllFilesAsInvalidated === void 0) { forceAllFilesAsInvalidated = false; }
writeLog("Synchronizing program");
clearInvalidateResolutionsOfFailedLookupLocations();
var program = getCurrentBuilderProgram();
@@ -118045,7 +118190,7 @@ var ts;
}
}
// All resolutions are invalid if user provided resolutions
- var hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution || changesAffectResolution);
+ var hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution || forceAllFilesAsInvalidated);
if (ts.isProgramUptoDate(getCurrentProgram(), rootFileNames, compilerOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {
if (hasChangedConfigFileParsingErrors) {
builderProgram = createProgram(/*rootNames*/ undefined, /*options*/ undefined, compilerHost, builderProgram, configFileParsingDiagnostics, projectReferences);
@@ -118252,6 +118397,12 @@ var ts;
reloadLevel = ts.ConfigFileProgramReloadLevel.Full;
scheduleProgramUpdate();
}
+ function scheduleResolutionReload() {
+ writeLog("Clearing resolutions");
+ resolutionCache.clear();
+ reloadLevel = ts.ConfigFileProgramReloadLevel.Resolutions;
+ scheduleProgramUpdate();
+ }
function updateProgramWithWatchStatus() {
timerToUpdateProgram = undefined;
reportWatchDiagnostic(ts.Diagnostics.File_change_detected_Starting_incremental_compilation);
@@ -118267,6 +118418,10 @@ var ts;
ts.perfLogger.logStartUpdateProgram("FullConfigReload");
reloadConfigFile();
break;
+ case ts.ConfigFileProgramReloadLevel.Resolutions:
+ ts.perfLogger.logStartUpdateProgram("SynchronizeProgramWithResolutions");
+ synchronizeProgram(/*forceAllFilesAsInvalidated*/ true);
+ break;
default:
ts.perfLogger.logStartUpdateProgram("SynchronizeProgram");
synchronizeProgram();
@@ -123684,11 +123839,27 @@ var ts;
return hasImportablePath;
}
ts.isImportableFile = isImportableFile;
+ /**
+ * We only allow PnP to be used as a resolution strategy if TypeScript
+ * itself is executed under a PnP runtime (and we only allow it to access
+ * the current PnP runtime, not any on the disk). This ensures that we
+ * don't execute potentially malicious code that didn't already have a
+ * chance to be executed (if we're running within the runtime, it means
+ * that the runtime has already been executed).
+ * @internal
+ */
+ function getPnpApi(path) {
+ var findPnpApi = require("module").findPnpApi;
+ if (findPnpApi === undefined) {
+ return undefined;
+ }
+ return findPnpApi(path + "/");
+ }
/**
* Don't include something from a `node_modules` that isn't actually reachable by a global import.
* A relative import to node_modules is usually a bad idea.
*/
- function isImportablePath(fromPath, toPath, getCanonicalFileName, globalCachePath) {
+ function isImportablePathNode(fromPath, toPath, getCanonicalFileName, globalCachePath) {
// If it's in a `node_modules` but is not reachable from here via a global import, don't bother.
var toNodeModules = ts.forEachAncestorDirectory(toPath, function (ancestor) { return ts.getBaseFileName(ancestor) === "node_modules" ? ancestor : undefined; });
var toNodeModulesParent = toNodeModules && ts.getDirectoryPath(getCanonicalFileName(toNodeModules));
@@ -123696,6 +123867,26 @@ var ts;
|| ts.startsWith(getCanonicalFileName(fromPath), toNodeModulesParent)
|| (!!globalCachePath && ts.startsWith(getCanonicalFileName(globalCachePath), toNodeModulesParent));
}
+ function isImportablePathPnp(fromPath, toPath) {
+ var pnpApi = getPnpApi(fromPath);
+ var fromLocator = pnpApi.findPackageLocator(fromPath);
+ var toLocator = pnpApi.findPackageLocator(toPath);
+ // eslint-disable-next-line no-null/no-null
+ if (toLocator === null) {
+ return false;
+ }
+ var fromInfo = pnpApi.getPackageInformation(fromLocator);
+ var toReference = fromInfo.packageDependencies.get(toLocator.name);
+ return toReference === toLocator.reference;
+ }
+ function isImportablePath(fromPath, toPath, getCanonicalFileName, globalCachePath) {
+ if (getPnpApi(fromPath)) {
+ return isImportablePathPnp(fromPath, toPath);
+ }
+ else {
+ return isImportablePathNode(fromPath, toPath, getCanonicalFileName, globalCachePath);
+ }
+ }
function forEachExternalModuleToImportFrom(program, host, useAutoImportProvider, cb) {
var _a, _b;
forEachExternalModule(program.getTypeChecker(), program.getSourceFiles(), function (module, file) { return cb(module, file, program, /*isFromPackageJson*/ false); });
@@ -125506,6 +125697,7 @@ var ts;
* This includes all files that are found in node_modules/moduleName/ with acceptable file extensions
*/
function getCompletionEntriesForNonRelativeModules(fragment, scriptPath, compilerOptions, host, typeChecker) {
+ var _a, _b;
var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths;
var result = [];
var extensionOptions = getExtensionOptions(compilerOptions);
@@ -125518,8 +125710,8 @@ var ts;
}
}
var fragmentDirectory = getFragmentDirectory(fragment);
- for (var _i = 0, _a = getAmbientModuleCompletions(fragment, fragmentDirectory, typeChecker); _i < _a.length; _i++) {
- var ambientName = _a[_i];
+ for (var _i = 0, _c = getAmbientModuleCompletions(fragment, fragmentDirectory, typeChecker); _i < _c.length; _i++) {
+ var ambientName = _c[_i];
result.push(nameAndKind(ambientName, "external module name" /* externalModuleName */, /*extension*/ undefined));
}
getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, fragmentDirectory, extensionOptions, result);
@@ -125534,18 +125726,36 @@ var ts;
result.push(nameAndKind(moduleName, "external module name" /* externalModuleName */, /*extension*/ undefined));
}
};
- for (var _b = 0, _c = enumerateNodeModulesVisibleToScript(host, scriptPath); _b < _c.length; _b++) {
- var moduleName = _c[_b];
+ for (var _d = 0, _e = enumerateNodeModulesVisibleToScript(host, scriptPath); _d < _e.length; _d++) {
+ var moduleName = _e[_d];
_loop_3(moduleName);
}
}
if (!foundGlobal) {
- ts.forEachAncestorDirectory(scriptPath, function (ancestor) {
- var nodeModules = ts.combinePaths(ancestor, "node_modules");
- if (ts.tryDirectoryExists(host, nodeModules)) {
- getCompletionEntriesForDirectoryFragment(fragment, nodeModules, extensionOptions, host, /*exclude*/ undefined, result);
+ var pnpapi = (_b = (_a = require("module")).findPnpApi) === null || _b === void 0 ? void 0 : _b.call(_a, scriptPath);
+ if (pnpapi) {
+ try {
+ // Splits a require request into its components, or return null if the request is a file path
+ var pathRegExp = /^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:@[^/]+\/)?[^/]+)\/*(.*|)$/;
+ var dependencyNameMatch = fragment.match(pathRegExp);
+ if (dependencyNameMatch) {
+ var dependencyName = dependencyNameMatch[1], subPath = dependencyNameMatch[2];
+ var unqualified = pnpapi.resolveToUnqualified(dependencyName, scriptPath, { considerBuiltins: false });
+ if (unqualified) {
+ getCompletionEntriesForDirectoryFragment(subPath, ts.normalizePath(unqualified), extensionOptions, host, /*exclude*/ undefined, result);
+ }
+ }
}
- });
+ catch (_f) { }
+ }
+ else {
+ ts.forEachAncestorDirectory(scriptPath, function (ancestor) {
+ var nodeModules = ts.combinePaths(ancestor, "node_modules");
+ if (ts.tryDirectoryExists(host, nodeModules)) {
+ getCompletionEntriesForDirectoryFragment(fragment, nodeModules, extensionOptions, host, /*exclude*/ undefined, result);
+ }
+ });
+ }
}
}
return result;
@@ -125646,6 +125856,7 @@ var ts;
return addReplacementSpans(toComplete, range.pos + prefix.length, names);
}
function getCompletionEntriesFromTypings(host, options, scriptPath, fragmentDirectory, extensionOptions, result) {
+ var _a, _b;
if (result === void 0) { result = []; }
// Check for typings specified in compiler options
var seen = new ts.Map();
@@ -125654,11 +125865,19 @@ var ts;
var root = typeRoots_1[_i];
getCompletionEntriesFromDirectories(root);
}
- // Also get all @types typings installed in visible node_modules directories
- for (var _a = 0, _b = ts.findPackageJsons(scriptPath, host); _a < _b.length; _a++) {
- var packageJson = _b[_a];
- var typesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules/@types");
- getCompletionEntriesFromDirectories(typesDir);
+ if ((_b = (_a = require("module")).findPnpApi) === null || _b === void 0 ? void 0 : _b.call(_a, scriptPath)) {
+ for (var _c = 0, _d = ts.getPnpTypeRoots(scriptPath); _c < _d.length; _c++) {
+ var root = _d[_c];
+ getCompletionEntriesFromDirectories(root);
+ }
+ }
+ else {
+ // Also get all @types typings installed in visible node_modules directories
+ for (var _e = 0, _f = ts.findPackageJsons(scriptPath, host); _e < _f.length; _e++) {
+ var packageJson = _f[_e];
+ var typesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules/@types");
+ getCompletionEntriesFromDirectories(typesDir);
+ }
}
return result;
function getCompletionEntriesFromDirectories(directory) {
@@ -153851,9 +154070,9 @@ var ts;
if (isTopLevelDeclarationStatement(statement) &&
!isExported(sourceFile, statement, useEs6Exports) &&
forEachTopLevelDeclaration(statement, function (d) { return needExport.has(ts.Debug.checkDefined(d.symbol)); })) {
- var exports = addExport(statement, useEs6Exports);
- if (exports)
- return exports;
+ var exports_1 = addExport(statement, useEs6Exports);
+ if (exports_1)
+ return exports_1;
}
return statement;
});
@@ -162652,6 +162871,37 @@ var ts;
return this.projectReferences;
};
ConfiguredProject.prototype.updateReferences = function (refs) {
+ // @ts-ignore
+ if (process.versions.pnp) {
+ // With Plug'n'Play, dependencies that list peer dependencies
+ // are "virtualized": they are resolved to a unique (virtual)
+ // path that the underlying filesystem layer then resolve back
+ // to the original location.
+ //
+ // When a workspace depends on another workspace with peer
+ // dependencies, this other workspace will thus be resolved to
+ // a unique path that won't match what the initial project has
+ // listed in its `references` field, and TS thus won't leverage
+ // the reference at all.
+ //
+ // To avoid that, we compute here the virtualized paths for the
+ // user-provided references in our references by directly querying
+ // the PnP API. This way users don't have to know the virtual paths,
+ // but we still support them just fine even through references.
+ var pnpApi_1 = require("pnpapi");
+ var basePath_1 = this.getCurrentDirectory();
+ var getPnpPath_1 = function (path) {
+ try {
+ var targetLocator = pnpApi_1.findPackageLocator(path + "/");
+ return pnpApi_1.resolveToUnqualified(targetLocator.name, basePath_1 + "/");
+ }
+ catch (_a) {
+ // something went wrong with the resolution, try not to fail
+ return path;
+ }
+ };
+ refs = refs === null || refs === void 0 ? void 0 : refs.map(function (r) { return (__assign(__assign({}, r), { path: getPnpPath_1(r.path) })); });
+ }
this.projectReferences = refs;
this.potentialProjectReferences = undefined;
};
@@ -163268,6 +163518,7 @@ var ts;
watchDirectory: ts.returnNoopFileWatcher,
} :
ts.getWatchFactory(this.host, watchLogLevel, log, getDetailWatchInfo);
+ this.pnpWatcher = this.watchPnpFile();
}
ProjectService.prototype.toPath = function (fileName) {
return ts.toPath(fileName, this.currentDirectory, this.toCanonicalFileName);
@@ -165120,7 +165371,7 @@ var ts;
};
ProjectService.prototype.setHostConfiguration = function (args) {
var _this = this;
- var _a;
+ var _a, _b;
if (args.file) {
var info = this.getScriptInfoForNormalizedPath(server.toNormalizedPath(args.file));
if (info) {
@@ -165138,7 +165389,7 @@ var ts;
this.logger.info("Format host information updated");
}
if (args.preferences) {
- var _b = this.hostConfiguration.preferences, lazyConfiguredProjectsFromExternalProject = _b.lazyConfiguredProjectsFromExternalProject, includePackageJsonAutoImports = _b.includePackageJsonAutoImports;
+ var _c = this.hostConfiguration.preferences, lazyConfiguredProjectsFromExternalProject = _c.lazyConfiguredProjectsFromExternalProject, includePackageJsonAutoImports = _c.includePackageJsonAutoImports;
this.hostConfiguration.preferences = __assign(__assign({}, this.hostConfiguration.preferences), args.preferences);
if (lazyConfiguredProjectsFromExternalProject && !this.hostConfiguration.preferences.lazyConfiguredProjectsFromExternalProject) {
// Load configured projects for external projects that are pending reload
@@ -165164,6 +165415,8 @@ var ts;
if (args.watchOptions) {
this.hostConfiguration.watchOptions = (_a = convertWatchOptions(args.watchOptions)) === null || _a === void 0 ? void 0 : _a.watchOptions;
this.logger.info("Host watch options changed to " + JSON.stringify(this.hostConfiguration.watchOptions) + ", it will be take effect for next watches.");
+ (_b = this.pnpWatcher) === null || _b === void 0 ? void 0 : _b.close();
+ this.watchPnpFile();
}
}
};
@@ -166158,6 +166411,25 @@ var ts;
});
};
/*@internal*/
+ ProjectService.prototype.watchPnpFile = function () {
+ var _this = this;
+ if (typeof process.versions.pnp === "undefined") {
+ return;
+ }
+ var pnpFileName = require.resolve("pnpapi");
+ return this.watchFactory.watchFile(pnpFileName, function () {
+ _this.forEachProject(function (project) {
+ for (var _i = 0, _a = project.getScriptInfos(); _i < _a.length; _i++) {
+ var info = _a[_i];
+ project.resolutionCache.invalidateResolutionOfFile(info.path);
+ }
+ project.markAsDirty();
+ updateProjectIfDirty(project);
+ });
+ _this.delayEnsureProjectForOpenFiles();
+ }, ts.PollingInterval.Low, this.hostConfiguration.watchOptions, ts.WatchType.ConfigFile);
+ };
+ /*@internal*/
ProjectService.prototype.watchPackageJsonFile = function (path) {
var _this = this;
var watchers = this.packageJsonFilesMap || (this.packageJsonFilesMap = new ts.Map());
@@ -171029,6 +171301,9 @@ var ts;
}
try {
var args = [ts.combinePaths(__dirname, "watchGuard.js"), path];
+ if (typeof process.versions.pnp !== "undefined") {
+ args.unshift('-r', require.resolve('pnpapi'));
+ }
if (logger.hasLevel(server.LogLevel.verbose)) {
logger.info("Starting " + process.execPath + " with args:" + server.stringifyIndented(args));
}
@@ -171289,6 +171564,9 @@ var ts;
break;
}
}
+ if (typeof process.versions.pnp !== "undefined") {
+ execArgv.unshift('-r', require.resolve('pnpapi'));
+ }
this.installer = childProcess.fork(ts.combinePaths(__dirname, "typingsInstaller.js"), args, { execArgv: execArgv });
this.installer.on("message", function (m) { return _this.handleMessage(m); });
// We have to schedule this event to the next tick
diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts
index 581d70b71..93b185e08 100644
semver exclusivity 4.4.2
--- a/lib/tsserverlibrary.d.ts
+++ b/lib/tsserverlibrary.d.ts
@@ -4759,6 +4759,7 @@ declare namespace ts {
}
declare namespace ts {
export function getEffectiveTypeRoots(options: CompilerOptions, host: GetEffectiveTypeRootsHost): string[] | undefined;
+ export function getPnpTypeRoots(currentDirectory: string): string[];
/**
* @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js
index 5fa1cd290..0c97c83ad 100644
semver exclusivity 4.4.2
--- a/lib/tsserverlibrary.js
+++ b/lib/tsserverlibrary.js
@@ -7652,6 +7652,11 @@ var ts;
: new Buffer(input, encoding);
}
function isFileSystemCaseSensitive() {
+ // The PnP runtime is always case-sensitive
+ // @ts-ignore
+ if (process.versions.pnp) {
+ return true;
+ }
// win32\win64 are case insensitive platforms
if (platform === "win32" || platform === "win64") {
return false;
@@ -41161,24 +41166,56 @@ var ts;
ts.getEffectiveTypeRoots = getEffectiveTypeRoots;
/**
* Returns the path to every node_modules/@types directory from some ancestor directory.
- * Returns undefined if there are none.
*/
- function getDefaultTypeRoots(currentDirectory, host) {
+ function getNodeModulesTypeRoots(currentDirectory, host) {
if (!host.directoryExists) {
return [ts.combinePaths(currentDirectory, nodeModulesAtTypes)];
// And if it doesn't exist, tough.
}
- var typeRoots;
+ var typeRoots = [];
ts.forEachAncestorDirectory(ts.normalizePath(currentDirectory), function (directory) {
var atTypes = ts.combinePaths(directory, nodeModulesAtTypes);
if (host.directoryExists(atTypes)) {
- (typeRoots || (typeRoots = [])).push(atTypes);
+ typeRoots.push(atTypes);
}
return undefined;
});
return typeRoots;
}
var nodeModulesAtTypes = ts.combinePaths("node_modules", "@types");
+ function getPnpTypeRoots(currentDirectory) {
+ var pnpapi = getPnpApi(currentDirectory);
+ if (!pnpapi) {
+ return [];
+ }
+ // Some TS consumers pass relative paths that aren't normalized
+ currentDirectory = ts.sys.resolvePath(currentDirectory);
+ var currentPackage = pnpapi.findPackageLocator(currentDirectory + "/");
+ if (!currentPackage) {
+ return [];
+ }
+ var packageDependencies = pnpapi.getPackageInformation(currentPackage).packageDependencies;
+ var typeRoots = [];
+ for (var _i = 0, _a = Array.from(packageDependencies.entries()); _i < _a.length; _i++) {
+ var _b = _a[_i], name = _b[0], referencish = _b[1];
+ // eslint-disable-next-line no-null/no-null
+ if (name.startsWith(typesPackagePrefix) && referencish !== null) {
+ var dependencyLocator = pnpapi.getLocator(name, referencish);
+ var packageLocation = pnpapi.getPackageInformation(dependencyLocator).packageLocation;
+ typeRoots.push(ts.getDirectoryPath(packageLocation));
+ }
+ }
+ return typeRoots;
+ }
+ ts.getPnpTypeRoots = getPnpTypeRoots;
+ var typesPackagePrefix = "@types/";
+ function getDefaultTypeRoots(currentDirectory, host) {
+ var nmTypes = getNodeModulesTypeRoots(currentDirectory, host);
+ var pnpTypes = getPnpTypeRoots(currentDirectory);
+ if (nmTypes.length > 0 || pnpTypes.length > 0) {
+ return __spreadArray(__spreadArray([], nmTypes, true), pnpTypes, true);
+ }
+ }
/**
* @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
@@ -41292,7 +41329,9 @@ var ts;
}
var result_4;
if (!ts.isExternalModuleNameRelative(typeReferenceDirectiveName)) {
- var searchResult = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
+ var searchResult = getPnpApi(initialLocationForSecondaryLookup)
+ ? tryLoadModuleUsingPnpResolution(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState)
+ : loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
result_4 = searchResult && searchResult.value;
}
else {
@@ -41847,9 +41886,12 @@ var ts;
if (traceEnabled) {
trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]);
}
- var resolved_1 = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
- if (!resolved_1)
+ var resolved_1 = getPnpApi(containingDirectory)
+ ? tryLoadModuleUsingPnpResolution(extensions, moduleName, containingDirectory, state)
+ : loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
+ if (!resolved_1) {
return undefined;
+ }
var resolvedValue = resolved_1.value;
if (!compilerOptions.preserveSymlinks && resolvedValue && !resolvedValue.originalPath) {
var path = realPath(resolvedValue.path, host, traceEnabled);
@@ -42194,6 +42236,14 @@ var ts;
}
function loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state) {
var candidate = ts.normalizePath(ts.combinePaths(nodeModulesDirectory, moduleName));
+ return loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state, candidate, undefined, undefined);
+ }
+ function loadModuleFromPnpResolution(extensions, packageDirectory, rest, state) {
+ var candidate = ts.normalizePath(ts.combinePaths(packageDirectory, rest));
+ return loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, undefined, undefined, true, state, candidate, rest, packageDirectory);
+ }
+ function loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state, candidate, rest, packageDirectory) {
+ var _a;
// First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
var packageInfo = getPackageJsonInfo(candidate, !nodeModulesDirectoryExists, state);
if (packageInfo) {
@@ -42209,9 +42259,12 @@ var ts;
loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageInfo && packageInfo.packageJsonContent, packageInfo && packageInfo.versionPaths);
return withPackageId(packageInfo, pathAndExtension);
};
- var _a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
+ var packageName;
+ if (rest === undefined)
+ (_a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest);
if (rest !== "") { // If "rest" is empty, we just did this search above.
- var packageDirectory = ts.combinePaths(nodeModulesDirectory, packageName);
+ if (packageDirectory === undefined)
+ packageDirectory = ts.combinePaths(nodeModulesDirectory, packageName);
// Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId and path mappings.
packageInfo = getPackageJsonInfo(packageDirectory, !nodeModulesDirectoryExists, state);
if (packageInfo && packageInfo.versionPaths) {
@@ -42370,6 +42423,58 @@ var ts;
function toSearchResult(value) {
return value !== undefined ? { value: value } : undefined;
}
+ /**
+ * We only allow PnP to be used as a resolution strategy if TypeScript
+ * itself is executed under a PnP runtime (and we only allow it to access
+ * the current PnP runtime, not any on the disk). This ensures that we
+ * don't execute potentially malicious code that didn't already have a
+ * chance to be executed (if we're running within the runtime, it means
+ * that the runtime has already been executed).
+ * @internal
+ */
+ function getPnpApi(path) {
+ var findPnpApi = require("module").findPnpApi;
+ if (findPnpApi === undefined) {
+ return undefined;
+ }
+ return findPnpApi(path + "/");
+ }
+ function loadPnpPackageResolution(packageName, containingDirectory) {
+ try {
+ var resolution = getPnpApi(containingDirectory).resolveToUnqualified(packageName, containingDirectory + "/", { considerBuiltins: false });
+ return ts.normalizeSlashes(resolution);
+ }
+ catch (_a) {
+ // Nothing to do
+ }
+ }
+ function loadPnpTypePackageResolution(packageName, containingDirectory) {
+ return loadPnpPackageResolution(getTypesPackageName(packageName), containingDirectory);
+ }
+ /* @internal */
+ function tryLoadModuleUsingPnpResolution(extensions, moduleName, containingDirectory, state) {
+ var _a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
+ var packageResolution = loadPnpPackageResolution(packageName, containingDirectory);
+ var packageFullResolution = packageResolution
+ ? loadModuleFromPnpResolution(extensions, packageResolution, rest, state)
+ : undefined;
+ var resolved;
+ if (packageFullResolution) {
+ resolved = packageFullResolution;
+ }
+ else if (extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) {
+ var typePackageResolution = loadPnpTypePackageResolution(packageName, containingDirectory);
+ var typePackageFullResolution = typePackageResolution
+ ? loadModuleFromPnpResolution(Extensions.DtsOnly, typePackageResolution, rest, state)
+ : undefined;
+ if (typePackageFullResolution) {
+ resolved = typePackageFullResolution;
+ }
+ }
+ if (resolved) {
+ return toSearchResult(resolved);
+ }
+ }
})(ts || (ts = {}));
/* @internal */
var ts;
@@ -110713,6 +110818,8 @@ var ts;
ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Partial"] = 1] = "Partial";
/** Reload completely by re-reading contents of config file from disk and updating program */
ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Full"] = 2] = "Full";
+ /** Reload the resolutions */
+ ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Resolutions"] = 3] = "Resolutions";
})(ConfigFileProgramReloadLevel = ts.ConfigFileProgramReloadLevel || (ts.ConfigFileProgramReloadLevel = {}));
/**
* Updates the map of shared extended config file watches with a new set of extended config files from a base config file of the project
@@ -117283,6 +117390,29 @@ var ts;
return undefined;
}
var parts = getNodeModulePathParts(path);
+ var packageName;
+ if (!parts && typeof process.versions.pnp !== "undefined") {
+ var pnpApi = require("pnpapi");
+ var locator = pnpApi.findPackageLocator(path);
+ // eslint-disable-next-line no-null/no-null
+ if (locator !== null) {
+ var sourceLocator = pnpApi.findPackageLocator(sourceDirectory + "/");
+ // Don't use the package name when the imported file is inside
+ // the source directory (prefer a relative path instead)
+ if (locator === sourceLocator) {
+ return undefined;
+ }
+ var information = pnpApi.getPackageInformation(locator);
+ packageName = locator.name;
+ parts = {
+ topLevelNodeModulesIndex: undefined,
+ topLevelPackageNameIndex: undefined,
+ // The last character from packageLocation is the trailing "/", we want to point to it
+ packageRootIndex: information.packageLocation.length - 1,
+ fileNameIndex: path.lastIndexOf("/"),
+ };
+ }
+ }
if (!parts) {
return undefined;
}
@@ -117313,18 +117443,24 @@ var ts;
if (isRedirect && !isPackageRootPath) {
return undefined;
}
- var globalTypingsCacheLocation = host.getGlobalTypingsCacheLocation && host.getGlobalTypingsCacheLocation();
- // Get a path that's relative to node_modules or the importing file's path
- // if node_modules folder is in this folder or any of its parent folders, no need to keep it.
- var pathToTopLevelNodeModules = getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex));
- if (!(ts.startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && ts.startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) {
- return undefined;
+ // If PnP is enabled the node_modules entries we'll get will always be relevant even if they
+ // are located in a weird path apparently outside of the source directory
+ if (typeof process.versions.pnp === "undefined") {
+ var globalTypingsCacheLocation = host.getGlobalTypingsCacheLocation && host.getGlobalTypingsCacheLocation();
+ // Get a path that's relative to node_modules or the importing file's path
+ // if node_modules folder is in this folder or any of its parent folders, no need to keep it.
+ var pathToTopLevelNodeModules = getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex));
+ if (!(ts.startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && ts.startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) {
+ return undefined;
+ }
}
// If the module was found in @types, get the actual Node package name
- var nodeModulesDirectoryName = moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
- var packageName = ts.getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
+ var nodeModulesDirectoryName = typeof packageName !== "undefined"
+ ? packageName + moduleSpecifier.substring(parts.packageRootIndex)
+ : moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
+ var packageNameFromPath = ts.getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
// For classic resolution, only allow importing from node_modules/@types, not other node_modules
- return ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs && packageName === nodeModulesDirectoryName ? undefined : packageName;
+ return ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs && packageNameFromPath === nodeModulesDirectoryName ? undefined : packageNameFromPath;
function tryDirectoryWithPackageJson(packageRootIndex) {
var packageRootPath = path.substring(0, packageRootIndex);
var packageJsonPath = ts.combinePaths(packageRootPath, "package.json");
@@ -118118,6 +118254,10 @@ var ts;
if (configFileName) {
configFileWatcher = watchFile(configFileName, scheduleProgramReload, ts.PollingInterval.High, watchOptions, ts.WatchType.ConfigFile);
}
+ var pnpFileWatcher;
+ if (typeof process.versions.pnp !== "undefined") {
+ pnpFileWatcher = watchFile(require.resolve("pnpapi"), scheduleResolutionReload, ts.PollingInterval.High, watchOptions, ts.WatchType.ConfigFile);
+ }
var compilerHost = ts.createCompilerHostFromProgramHost(host, function () { return compilerOptions; }, directoryStructureHost);
ts.setGetSourceFileAsHashVersioned(compilerHost, host);
// Members for CompilerHost
@@ -118196,6 +118336,10 @@ var ts;
configFileWatcher.close();
configFileWatcher = undefined;
}
+ if (pnpFileWatcher) {
+ pnpFileWatcher.close();
+ pnpFileWatcher = undefined;
+ }
extendedConfigCache === null || extendedConfigCache === void 0 ? void 0 : extendedConfigCache.clear();
extendedConfigCache = undefined;
if (sharedExtendedConfigFileWatchers) {
@@ -118228,7 +118372,8 @@ var ts;
function getCurrentProgram() {
return builderProgram && builderProgram.getProgramOrUndefined();
}
- function synchronizeProgram() {
+ function synchronizeProgram(forceAllFilesAsInvalidated) {
+ if (forceAllFilesAsInvalidated === void 0) { forceAllFilesAsInvalidated = false; }
writeLog("Synchronizing program");
clearInvalidateResolutionsOfFailedLookupLocations();
var program = getCurrentBuilderProgram();
@@ -118239,7 +118384,7 @@ var ts;
}
}
// All resolutions are invalid if user provided resolutions
- var hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution || changesAffectResolution);
+ var hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution || forceAllFilesAsInvalidated);
if (ts.isProgramUptoDate(getCurrentProgram(), rootFileNames, compilerOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {
if (hasChangedConfigFileParsingErrors) {
builderProgram = createProgram(/*rootNames*/ undefined, /*options*/ undefined, compilerHost, builderProgram, configFileParsingDiagnostics, projectReferences);
@@ -118446,6 +118591,12 @@ var ts;
reloadLevel = ts.ConfigFileProgramReloadLevel.Full;
scheduleProgramUpdate();
}
+ function scheduleResolutionReload() {
+ writeLog("Clearing resolutions");
+ resolutionCache.clear();
+ reloadLevel = ts.ConfigFileProgramReloadLevel.Resolutions;
+ scheduleProgramUpdate();
+ }
function updateProgramWithWatchStatus() {
timerToUpdateProgram = undefined;
reportWatchDiagnostic(ts.Diagnostics.File_change_detected_Starting_incremental_compilation);
@@ -118461,6 +118612,10 @@ var ts;
ts.perfLogger.logStartUpdateProgram("FullConfigReload");
reloadConfigFile();
break;
+ case ts.ConfigFileProgramReloadLevel.Resolutions:
+ ts.perfLogger.logStartUpdateProgram("SynchronizeProgramWithResolutions");
+ synchronizeProgram(/*forceAllFilesAsInvalidated*/ true);
+ break;
default:
ts.perfLogger.logStartUpdateProgram("SynchronizeProgram");
synchronizeProgram();
@@ -124266,11 +124421,27 @@ var ts;
return hasImportablePath;
}
ts.isImportableFile = isImportableFile;
+ /**
+ * We only allow PnP to be used as a resolution strategy if TypeScript
+ * itself is executed under a PnP runtime (and we only allow it to access
+ * the current PnP runtime, not any on the disk). This ensures that we
+ * don't execute potentially malicious code that didn't already have a
+ * chance to be executed (if we're running within the runtime, it means
+ * that the runtime has already been executed).
+ * @internal
+ */
+ function getPnpApi(path) {
+ var findPnpApi = require("module").findPnpApi;
+ if (findPnpApi === undefined) {
+ return undefined;
+ }
+ return findPnpApi(path + "/");
+ }
/**
* Don't include something from a `node_modules` that isn't actually reachable by a global import.
* A relative import to node_modules is usually a bad idea.
*/
- function isImportablePath(fromPath, toPath, getCanonicalFileName, globalCachePath) {
+ function isImportablePathNode(fromPath, toPath, getCanonicalFileName, globalCachePath) {
// If it's in a `node_modules` but is not reachable from here via a global import, don't bother.
var toNodeModules = ts.forEachAncestorDirectory(toPath, function (ancestor) { return ts.getBaseFileName(ancestor) === "node_modules" ? ancestor : undefined; });
var toNodeModulesParent = toNodeModules && ts.getDirectoryPath(getCanonicalFileName(toNodeModules));
@@ -124278,6 +124449,26 @@ var ts;
|| ts.startsWith(getCanonicalFileName(fromPath), toNodeModulesParent)
|| (!!globalCachePath && ts.startsWith(getCanonicalFileName(globalCachePath), toNodeModulesParent));
}
+ function isImportablePathPnp(fromPath, toPath) {
+ var pnpApi = getPnpApi(fromPath);
+ var fromLocator = pnpApi.findPackageLocator(fromPath);
+ var toLocator = pnpApi.findPackageLocator(toPath);
+ // eslint-disable-next-line no-null/no-null
+ if (toLocator === null) {
+ return false;
+ }
+ var fromInfo = pnpApi.getPackageInformation(fromLocator);
+ var toReference = fromInfo.packageDependencies.get(toLocator.name);
+ return toReference === toLocator.reference;
+ }
+ function isImportablePath(fromPath, toPath, getCanonicalFileName, globalCachePath) {
+ if (getPnpApi(fromPath)) {
+ return isImportablePathPnp(fromPath, toPath);
+ }
+ else {
+ return isImportablePathNode(fromPath, toPath, getCanonicalFileName, globalCachePath);
+ }
+ }
function forEachExternalModuleToImportFrom(program, host, useAutoImportProvider, cb) {
var _a, _b;
forEachExternalModule(program.getTypeChecker(), program.getSourceFiles(), function (module, file) { return cb(module, file, program, /*isFromPackageJson*/ false); });
@@ -126088,6 +126279,7 @@ var ts;
* This includes all files that are found in node_modules/moduleName/ with acceptable file extensions
*/
function getCompletionEntriesForNonRelativeModules(fragment, scriptPath, compilerOptions, host, typeChecker) {
+ var _a, _b;
var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths;
var result = [];
var extensionOptions = getExtensionOptions(compilerOptions);
@@ -126100,8 +126292,8 @@ var ts;
}
}
var fragmentDirectory = getFragmentDirectory(fragment);
- for (var _i = 0, _a = getAmbientModuleCompletions(fragment, fragmentDirectory, typeChecker); _i < _a.length; _i++) {
- var ambientName = _a[_i];
+ for (var _i = 0, _c = getAmbientModuleCompletions(fragment, fragmentDirectory, typeChecker); _i < _c.length; _i++) {
+ var ambientName = _c[_i];
result.push(nameAndKind(ambientName, "external module name" /* externalModuleName */, /*extension*/ undefined));
}
getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, fragmentDirectory, extensionOptions, result);
@@ -126116,18 +126308,36 @@ var ts;
result.push(nameAndKind(moduleName, "external module name" /* externalModuleName */, /*extension*/ undefined));
}
};
- for (var _b = 0, _c = enumerateNodeModulesVisibleToScript(host, scriptPath); _b < _c.length; _b++) {
- var moduleName = _c[_b];
+ for (var _d = 0, _e = enumerateNodeModulesVisibleToScript(host, scriptPath); _d < _e.length; _d++) {
+ var moduleName = _e[_d];
_loop_3(moduleName);
}
}
if (!foundGlobal) {
- ts.forEachAncestorDirectory(scriptPath, function (ancestor) {
- var nodeModules = ts.combinePaths(ancestor, "node_modules");
- if (ts.tryDirectoryExists(host, nodeModules)) {
- getCompletionEntriesForDirectoryFragment(fragment, nodeModules, extensionOptions, host, /*exclude*/ undefined, result);
+ var pnpapi = (_b = (_a = require("module")).findPnpApi) === null || _b === void 0 ? void 0 : _b.call(_a, scriptPath);
+ if (pnpapi) {
+ try {
+ // Splits a require request into its components, or return null if the request is a file path
+ var pathRegExp = /^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:@[^/]+\/)?[^/]+)\/*(.*|)$/;
+ var dependencyNameMatch = fragment.match(pathRegExp);
+ if (dependencyNameMatch) {
+ var dependencyName = dependencyNameMatch[1], subPath = dependencyNameMatch[2];
+ var unqualified = pnpapi.resolveToUnqualified(dependencyName, scriptPath, { considerBuiltins: false });
+ if (unqualified) {
+ getCompletionEntriesForDirectoryFragment(subPath, ts.normalizePath(unqualified), extensionOptions, host, /*exclude*/ undefined, result);
+ }
+ }
}
- });
+ catch (_f) { }
+ }
+ else {
+ ts.forEachAncestorDirectory(scriptPath, function (ancestor) {
+ var nodeModules = ts.combinePaths(ancestor, "node_modules");
+ if (ts.tryDirectoryExists(host, nodeModules)) {
+ getCompletionEntriesForDirectoryFragment(fragment, nodeModules, extensionOptions, host, /*exclude*/ undefined, result);
+ }
+ });
+ }
}
}
return result;
@@ -126228,6 +126438,7 @@ var ts;
return addReplacementSpans(toComplete, range.pos + prefix.length, names);
}
function getCompletionEntriesFromTypings(host, options, scriptPath, fragmentDirectory, extensionOptions, result) {
+ var _a, _b;
if (result === void 0) { result = []; }
// Check for typings specified in compiler options
var seen = new ts.Map();
@@ -126236,11 +126447,19 @@ var ts;
var root = typeRoots_1[_i];
getCompletionEntriesFromDirectories(root);
}
- // Also get all @types typings installed in visible node_modules directories
- for (var _a = 0, _b = ts.findPackageJsons(scriptPath, host); _a < _b.length; _a++) {
- var packageJson = _b[_a];
- var typesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules/@types");
- getCompletionEntriesFromDirectories(typesDir);
+ if ((_b = (_a = require("module")).findPnpApi) === null || _b === void 0 ? void 0 : _b.call(_a, scriptPath)) {
+ for (var _c = 0, _d = ts.getPnpTypeRoots(scriptPath); _c < _d.length; _c++) {
+ var root = _d[_c];
+ getCompletionEntriesFromDirectories(root);
+ }
+ }
+ else {
+ // Also get all @types typings installed in visible node_modules directories
+ for (var _e = 0, _f = ts.findPackageJsons(scriptPath, host); _e < _f.length; _e++) {
+ var packageJson = _f[_e];
+ var typesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules/@types");
+ getCompletionEntriesFromDirectories(typesDir);
+ }
}
return result;
function getCompletionEntriesFromDirectories(directory) {
@@ -154433,9 +154652,9 @@ var ts;
if (isTopLevelDeclarationStatement(statement) &&
!isExported(sourceFile, statement, useEs6Exports) &&
forEachTopLevelDeclaration(statement, function (d) { return needExport.has(ts.Debug.checkDefined(d.symbol)); })) {
- var exports = addExport(statement, useEs6Exports);
- if (exports)
- return exports;
+ var exports_1 = addExport(statement, useEs6Exports);
+ if (exports_1)
+ return exports_1;
}
return statement;
});
@@ -162846,6 +163065,37 @@ var ts;
return this.projectReferences;
};
ConfiguredProject.prototype.updateReferences = function (refs) {
+ // @ts-ignore
+ if (process.versions.pnp) {
+ // With Plug'n'Play, dependencies that list peer dependencies
+ // are "virtualized": they are resolved to a unique (virtual)
+ // path that the underlying filesystem layer then resolve back
+ // to the original location.
+ //
+ // When a workspace depends on another workspace with peer
+ // dependencies, this other workspace will thus be resolved to
+ // a unique path that won't match what the initial project has
+ // listed in its `references` field, and TS thus won't leverage
+ // the reference at all.
+ //
+ // To avoid that, we compute here the virtualized paths for the
+ // user-provided references in our references by directly querying
+ // the PnP API. This way users don't have to know the virtual paths,
+ // but we still support them just fine even through references.
+ var pnpApi_1 = require("pnpapi");
+ var basePath_1 = this.getCurrentDirectory();
+ var getPnpPath_1 = function (path) {
+ try {
+ var targetLocator = pnpApi_1.findPackageLocator(path + "/");
+ return pnpApi_1.resolveToUnqualified(targetLocator.name, basePath_1 + "/");
+ }
+ catch (_a) {
+ // something went wrong with the resolution, try not to fail
+ return path;
+ }
+ };
+ refs = refs === null || refs === void 0 ? void 0 : refs.map(function (r) { return (__assign(__assign({}, r), { path: getPnpPath_1(r.path) })); });
+ }
this.projectReferences = refs;
this.potentialProjectReferences = undefined;
};
@@ -163462,6 +163712,7 @@ var ts;
watchDirectory: ts.returnNoopFileWatcher,
} :
ts.getWatchFactory(this.host, watchLogLevel, log, getDetailWatchInfo);
+ this.pnpWatcher = this.watchPnpFile();
}
ProjectService.prototype.toPath = function (fileName) {
return ts.toPath(fileName, this.currentDirectory, this.toCanonicalFileName);
@@ -165314,7 +165565,7 @@ var ts;
};
ProjectService.prototype.setHostConfiguration = function (args) {
var _this = this;
- var _a;
+ var _a, _b;
if (args.file) {
var info = this.getScriptInfoForNormalizedPath(server.toNormalizedPath(args.file));
if (info) {
@@ -165332,7 +165583,7 @@ var ts;
this.logger.info("Format host information updated");
}
if (args.preferences) {
- var _b = this.hostConfiguration.preferences, lazyConfiguredProjectsFromExternalProject = _b.lazyConfiguredProjectsFromExternalProject, includePackageJsonAutoImports = _b.includePackageJsonAutoImports;
+ var _c = this.hostConfiguration.preferences, lazyConfiguredProjectsFromExternalProject = _c.lazyConfiguredProjectsFromExternalProject, includePackageJsonAutoImports = _c.includePackageJsonAutoImports;
this.hostConfiguration.preferences = __assign(__assign({}, this.hostConfiguration.preferences), args.preferences);
if (lazyConfiguredProjectsFromExternalProject && !this.hostConfiguration.preferences.lazyConfiguredProjectsFromExternalProject) {
// Load configured projects for external projects that are pending reload
@@ -165358,6 +165609,8 @@ var ts;
if (args.watchOptions) {
this.hostConfiguration.watchOptions = (_a = convertWatchOptions(args.watchOptions)) === null || _a === void 0 ? void 0 : _a.watchOptions;
this.logger.info("Host watch options changed to " + JSON.stringify(this.hostConfiguration.watchOptions) + ", it will be take effect for next watches.");
+ (_b = this.pnpWatcher) === null || _b === void 0 ? void 0 : _b.close();
+ this.watchPnpFile();
}
}
};
@@ -166352,6 +166605,25 @@ var ts;
});
};
/*@internal*/
+ ProjectService.prototype.watchPnpFile = function () {
+ var _this = this;
+ if (typeof process.versions.pnp === "undefined") {
+ return;
+ }
+ var pnpFileName = require.resolve("pnpapi");
+ return this.watchFactory.watchFile(pnpFileName, function () {
+ _this.forEachProject(function (project) {
+ for (var _i = 0, _a = project.getScriptInfos(); _i < _a.length; _i++) {
+ var info = _a[_i];
+ project.resolutionCache.invalidateResolutionOfFile(info.path);
+ }
+ project.markAsDirty();
+ updateProjectIfDirty(project);
+ });
+ _this.delayEnsureProjectForOpenFiles();
+ }, ts.PollingInterval.Low, this.hostConfiguration.watchOptions, ts.WatchType.ConfigFile);
+ };
+ /*@internal*/
ProjectService.prototype.watchPackageJsonFile = function (path) {
var _this = this;
var watchers = this.packageJsonFilesMap || (this.packageJsonFilesMap = new ts.Map());
diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts
index 4902d45ad..f512e9e8c 100644
semver exclusivity 4.4.2
--- a/lib/typescript.d.ts
+++ b/lib/typescript.d.ts
@@ -4759,6 +4759,7 @@ declare namespace ts {
}
declare namespace ts {
export function getEffectiveTypeRoots(options: CompilerOptions, host: GetEffectiveTypeRootsHost): string[] | undefined;
+ export function getPnpTypeRoots(currentDirectory: string): string[];
/**
* @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
diff --git a/lib/typescript.js b/lib/typescript.js
index 44462973f..07a9ef8fa 100644
semver exclusivity 4.4.2
--- a/lib/typescript.js
+++ b/lib/typescript.js
@@ -7652,6 +7652,11 @@ var ts;
: new Buffer(input, encoding);
}
function isFileSystemCaseSensitive() {
+ // The PnP runtime is always case-sensitive
+ // @ts-ignore
+ if (process.versions.pnp) {
+ return true;
+ }
// win32\win64 are case insensitive platforms
if (platform === "win32" || platform === "win64") {
return false;
@@ -41161,24 +41166,56 @@ var ts;
ts.getEffectiveTypeRoots = getEffectiveTypeRoots;
/**
* Returns the path to every node_modules/@types directory from some ancestor directory.
- * Returns undefined if there are none.
*/
- function getDefaultTypeRoots(currentDirectory, host) {
+ function getNodeModulesTypeRoots(currentDirectory, host) {
if (!host.directoryExists) {
return [ts.combinePaths(currentDirectory, nodeModulesAtTypes)];
// And if it doesn't exist, tough.
}
- var typeRoots;
+ var typeRoots = [];
ts.forEachAncestorDirectory(ts.normalizePath(currentDirectory), function (directory) {
var atTypes = ts.combinePaths(directory, nodeModulesAtTypes);
if (host.directoryExists(atTypes)) {
- (typeRoots || (typeRoots = [])).push(atTypes);
+ typeRoots.push(atTypes);
}
return undefined;
});
return typeRoots;
}
var nodeModulesAtTypes = ts.combinePaths("node_modules", "@types");
+ function getPnpTypeRoots(currentDirectory) {
+ var pnpapi = getPnpApi(currentDirectory);
+ if (!pnpapi) {
+ return [];
+ }
+ // Some TS consumers pass relative paths that aren't normalized
+ currentDirectory = ts.sys.resolvePath(currentDirectory);
+ var currentPackage = pnpapi.findPackageLocator(currentDirectory + "/");
+ if (!currentPackage) {
+ return [];
+ }
+ var packageDependencies = pnpapi.getPackageInformation(currentPackage).packageDependencies;
+ var typeRoots = [];
+ for (var _i = 0, _a = Array.from(packageDependencies.entries()); _i < _a.length; _i++) {
+ var _b = _a[_i], name = _b[0], referencish = _b[1];
+ // eslint-disable-next-line no-null/no-null
+ if (name.startsWith(typesPackagePrefix) && referencish !== null) {
+ var dependencyLocator = pnpapi.getLocator(name, referencish);
+ var packageLocation = pnpapi.getPackageInformation(dependencyLocator).packageLocation;
+ typeRoots.push(ts.getDirectoryPath(packageLocation));
+ }
+ }
+ return typeRoots;
+ }
+ ts.getPnpTypeRoots = getPnpTypeRoots;
+ var typesPackagePrefix = "@types/";
+ function getDefaultTypeRoots(currentDirectory, host) {
+ var nmTypes = getNodeModulesTypeRoots(currentDirectory, host);
+ var pnpTypes = getPnpTypeRoots(currentDirectory);
+ if (nmTypes.length > 0 || pnpTypes.length > 0) {
+ return __spreadArray(__spreadArray([], nmTypes, true), pnpTypes, true);
+ }
+ }
/**
* @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
@@ -41292,7 +41329,9 @@ var ts;
}
var result_4;
if (!ts.isExternalModuleNameRelative(typeReferenceDirectiveName)) {
- var searchResult = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
+ var searchResult = getPnpApi(initialLocationForSecondaryLookup)
+ ? tryLoadModuleUsingPnpResolution(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState)
+ : loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
result_4 = searchResult && searchResult.value;
}
else {
@@ -41847,9 +41886,12 @@ var ts;
if (traceEnabled) {
trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]);
}
- var resolved_1 = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
- if (!resolved_1)
+ var resolved_1 = getPnpApi(containingDirectory)
+ ? tryLoadModuleUsingPnpResolution(extensions, moduleName, containingDirectory, state)
+ : loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
+ if (!resolved_1) {
return undefined;
+ }
var resolvedValue = resolved_1.value;
if (!compilerOptions.preserveSymlinks && resolvedValue && !resolvedValue.originalPath) {
var path = realPath(resolvedValue.path, host, traceEnabled);
@@ -42194,6 +42236,14 @@ var ts;
}
function loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state) {
var candidate = ts.normalizePath(ts.combinePaths(nodeModulesDirectory, moduleName));
+ return loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state, candidate, undefined, undefined);
+ }
+ function loadModuleFromPnpResolution(extensions, packageDirectory, rest, state) {
+ var candidate = ts.normalizePath(ts.combinePaths(packageDirectory, rest));
+ return loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, undefined, undefined, true, state, candidate, rest, packageDirectory);
+ }
+ function loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state, candidate, rest, packageDirectory) {
+ var _a;
// First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
var packageInfo = getPackageJsonInfo(candidate, !nodeModulesDirectoryExists, state);
if (packageInfo) {
@@ -42209,9 +42259,12 @@ var ts;
loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageInfo && packageInfo.packageJsonContent, packageInfo && packageInfo.versionPaths);
return withPackageId(packageInfo, pathAndExtension);
};
- var _a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
+ var packageName;
+ if (rest === undefined)
+ (_a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest);
if (rest !== "") { // If "rest" is empty, we just did this search above.
- var packageDirectory = ts.combinePaths(nodeModulesDirectory, packageName);
+ if (packageDirectory === undefined)
+ packageDirectory = ts.combinePaths(nodeModulesDirectory, packageName);
// Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId and path mappings.
packageInfo = getPackageJsonInfo(packageDirectory, !nodeModulesDirectoryExists, state);
if (packageInfo && packageInfo.versionPaths) {
@@ -42370,6 +42423,58 @@ var ts;
function toSearchResult(value) {
return value !== undefined ? { value: value } : undefined;
}
+ /**
+ * We only allow PnP to be used as a resolution strategy if TypeScript
+ * itself is executed under a PnP runtime (and we only allow it to access
+ * the current PnP runtime, not any on the disk). This ensures that we
+ * don't execute potentially malicious code that didn't already have a
+ * chance to be executed (if we're running within the runtime, it means
+ * that the runtime has already been executed).
+ * @internal
+ */
+ function getPnpApi(path) {
+ var findPnpApi = require("module").findPnpApi;
+ if (findPnpApi === undefined) {
+ return undefined;
+ }
+ return findPnpApi(path + "/");
+ }
+ function loadPnpPackageResolution(packageName, containingDirectory) {
+ try {
+ var resolution = getPnpApi(containingDirectory).resolveToUnqualified(packageName, containingDirectory + "/", { considerBuiltins: false });
+ return ts.normalizeSlashes(resolution);
+ }
+ catch (_a) {
+ // Nothing to do
+ }
+ }
+ function loadPnpTypePackageResolution(packageName, containingDirectory) {
+ return loadPnpPackageResolution(getTypesPackageName(packageName), containingDirectory);
+ }
+ /* @internal */
+ function tryLoadModuleUsingPnpResolution(extensions, moduleName, containingDirectory, state) {
+ var _a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
+ var packageResolution = loadPnpPackageResolution(packageName, containingDirectory);
+ var packageFullResolution = packageResolution
+ ? loadModuleFromPnpResolution(extensions, packageResolution, rest, state)
+ : undefined;
+ var resolved;
+ if (packageFullResolution) {
+ resolved = packageFullResolution;
+ }
+ else if (extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) {
+ var typePackageResolution = loadPnpTypePackageResolution(packageName, containingDirectory);
+ var typePackageFullResolution = typePackageResolution
+ ? loadModuleFromPnpResolution(Extensions.DtsOnly, typePackageResolution, rest, state)
+ : undefined;
+ if (typePackageFullResolution) {
+ resolved = typePackageFullResolution;
+ }
+ }
+ if (resolved) {
+ return toSearchResult(resolved);
+ }
+ }
})(ts || (ts = {}));
/* @internal */
var ts;
@@ -110713,6 +110818,8 @@ var ts;
ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Partial"] = 1] = "Partial";
/** Reload completely by re-reading contents of config file from disk and updating program */
ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Full"] = 2] = "Full";
+ /** Reload the resolutions */
+ ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Resolutions"] = 3] = "Resolutions";
})(ConfigFileProgramReloadLevel = ts.ConfigFileProgramReloadLevel || (ts.ConfigFileProgramReloadLevel = {}));
/**
* Updates the map of shared extended config file watches with a new set of extended config files from a base config file of the project
@@ -117283,6 +117390,29 @@ var ts;
return undefined;
}
var parts = getNodeModulePathParts(path);
+ var packageName;
+ if (!parts && typeof process.versions.pnp !== "undefined") {
+ var pnpApi = require("pnpapi");
+ var locator = pnpApi.findPackageLocator(path);
+ // eslint-disable-next-line no-null/no-null
+ if (locator !== null) {
+ var sourceLocator = pnpApi.findPackageLocator(sourceDirectory + "/");
+ // Don't use the package name when the imported file is inside
+ // the source directory (prefer a relative path instead)
+ if (locator === sourceLocator) {
+ return undefined;
+ }
+ var information = pnpApi.getPackageInformation(locator);
+ packageName = locator.name;
+ parts = {
+ topLevelNodeModulesIndex: undefined,
+ topLevelPackageNameIndex: undefined,
+ // The last character from packageLocation is the trailing "/", we want to point to it
+ packageRootIndex: information.packageLocation.length - 1,
+ fileNameIndex: path.lastIndexOf("/"),
+ };
+ }
+ }
if (!parts) {
return undefined;
}
@@ -117313,18 +117443,24 @@ var ts;
if (isRedirect && !isPackageRootPath) {
return undefined;
}
- var globalTypingsCacheLocation = host.getGlobalTypingsCacheLocation && host.getGlobalTypingsCacheLocation();
- // Get a path that's relative to node_modules or the importing file's path
- // if node_modules folder is in this folder or any of its parent folders, no need to keep it.
- var pathToTopLevelNodeModules = getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex));
- if (!(ts.startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && ts.startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) {
- return undefined;
+ // If PnP is enabled the node_modules entries we'll get will always be relevant even if they
+ // are located in a weird path apparently outside of the source directory
+ if (typeof process.versions.pnp === "undefined") {
+ var globalTypingsCacheLocation = host.getGlobalTypingsCacheLocation && host.getGlobalTypingsCacheLocation();
+ // Get a path that's relative to node_modules or the importing file's path
+ // if node_modules folder is in this folder or any of its parent folders, no need to keep it.
+ var pathToTopLevelNodeModules = getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex));
+ if (!(ts.startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && ts.startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) {
+ return undefined;
+ }
}
// If the module was found in @types, get the actual Node package name
- var nodeModulesDirectoryName = moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
- var packageName = ts.getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
+ var nodeModulesDirectoryName = typeof packageName !== "undefined"
+ ? packageName + moduleSpecifier.substring(parts.packageRootIndex)
+ : moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
+ var packageNameFromPath = ts.getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
// For classic resolution, only allow importing from node_modules/@types, not other node_modules
- return ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs && packageName === nodeModulesDirectoryName ? undefined : packageName;
+ return ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs && packageNameFromPath === nodeModulesDirectoryName ? undefined : packageNameFromPath;
function tryDirectoryWithPackageJson(packageRootIndex) {
var packageRootPath = path.substring(0, packageRootIndex);
var packageJsonPath = ts.combinePaths(packageRootPath, "package.json");
@@ -118118,6 +118254,10 @@ var ts;
if (configFileName) {
configFileWatcher = watchFile(configFileName, scheduleProgramReload, ts.PollingInterval.High, watchOptions, ts.WatchType.ConfigFile);
}
+ var pnpFileWatcher;
+ if (typeof process.versions.pnp !== "undefined") {
+ pnpFileWatcher = watchFile(require.resolve("pnpapi"), scheduleResolutionReload, ts.PollingInterval.High, watchOptions, ts.WatchType.ConfigFile);
+ }
var compilerHost = ts.createCompilerHostFromProgramHost(host, function () { return compilerOptions; }, directoryStructureHost);
ts.setGetSourceFileAsHashVersioned(compilerHost, host);
// Members for CompilerHost
@@ -118196,6 +118336,10 @@ var ts;
configFileWatcher.close();
configFileWatcher = undefined;
}
+ if (pnpFileWatcher) {
+ pnpFileWatcher.close();
+ pnpFileWatcher = undefined;
+ }
extendedConfigCache === null || extendedConfigCache === void 0 ? void 0 : extendedConfigCache.clear();
extendedConfigCache = undefined;
if (sharedExtendedConfigFileWatchers) {
@@ -118228,7 +118372,8 @@ var ts;
function getCurrentProgram() {
return builderProgram && builderProgram.getProgramOrUndefined();
}
- function synchronizeProgram() {
+ function synchronizeProgram(forceAllFilesAsInvalidated) {
+ if (forceAllFilesAsInvalidated === void 0) { forceAllFilesAsInvalidated = false; }
writeLog("Synchronizing program");
clearInvalidateResolutionsOfFailedLookupLocations();
var program = getCurrentBuilderProgram();
@@ -118239,7 +118384,7 @@ var ts;
}
}
// All resolutions are invalid if user provided resolutions
- var hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution || changesAffectResolution);
+ var hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution || forceAllFilesAsInvalidated);
if (ts.isProgramUptoDate(getCurrentProgram(), rootFileNames, compilerOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {
if (hasChangedConfigFileParsingErrors) {
builderProgram = createProgram(/*rootNames*/ undefined, /*options*/ undefined, compilerHost, builderProgram, configFileParsingDiagnostics, projectReferences);
@@ -118446,6 +118591,12 @@ var ts;
reloadLevel = ts.ConfigFileProgramReloadLevel.Full;
scheduleProgramUpdate();
}
+ function scheduleResolutionReload() {
+ writeLog("Clearing resolutions");
+ resolutionCache.clear();
+ reloadLevel = ts.ConfigFileProgramReloadLevel.Resolutions;
+ scheduleProgramUpdate();
+ }
function updateProgramWithWatchStatus() {
timerToUpdateProgram = undefined;
reportWatchDiagnostic(ts.Diagnostics.File_change_detected_Starting_incremental_compilation);
@@ -118461,6 +118612,10 @@ var ts;
ts.perfLogger.logStartUpdateProgram("FullConfigReload");
reloadConfigFile();
break;
+ case ts.ConfigFileProgramReloadLevel.Resolutions:
+ ts.perfLogger.logStartUpdateProgram("SynchronizeProgramWithResolutions");
+ synchronizeProgram(/*forceAllFilesAsInvalidated*/ true);
+ break;
default:
ts.perfLogger.logStartUpdateProgram("SynchronizeProgram");
synchronizeProgram();
@@ -124266,11 +124421,27 @@ var ts;
return hasImportablePath;
}
ts.isImportableFile = isImportableFile;
+ /**
+ * We only allow PnP to be used as a resolution strategy if TypeScript
+ * itself is executed under a PnP runtime (and we only allow it to access
+ * the current PnP runtime, not any on the disk). This ensures that we
+ * don't execute potentially malicious code that didn't already have a
+ * chance to be executed (if we're running within the runtime, it means
+ * that the runtime has already been executed).
+ * @internal
+ */
+ function getPnpApi(path) {
+ var findPnpApi = require("module").findPnpApi;
+ if (findPnpApi === undefined) {
+ return undefined;
+ }
+ return findPnpApi(path + "/");
+ }
/**
* Don't include something from a `node_modules` that isn't actually reachable by a global import.
* A relative import to node_modules is usually a bad idea.
*/
- function isImportablePath(fromPath, toPath, getCanonicalFileName, globalCachePath) {
+ function isImportablePathNode(fromPath, toPath, getCanonicalFileName, globalCachePath) {
// If it's in a `node_modules` but is not reachable from here via a global import, don't bother.
var toNodeModules = ts.forEachAncestorDirectory(toPath, function (ancestor) { return ts.getBaseFileName(ancestor) === "node_modules" ? ancestor : undefined; });
var toNodeModulesParent = toNodeModules && ts.getDirectoryPath(getCanonicalFileName(toNodeModules));
@@ -124278,6 +124449,26 @@ var ts;
|| ts.startsWith(getCanonicalFileName(fromPath), toNodeModulesParent)
|| (!!globalCachePath && ts.startsWith(getCanonicalFileName(globalCachePath), toNodeModulesParent));
}
+ function isImportablePathPnp(fromPath, toPath) {
+ var pnpApi = getPnpApi(fromPath);
+ var fromLocator = pnpApi.findPackageLocator(fromPath);
+ var toLocator = pnpApi.findPackageLocator(toPath);
+ // eslint-disable-next-line no-null/no-null
+ if (toLocator === null) {
+ return false;
+ }
+ var fromInfo = pnpApi.getPackageInformation(fromLocator);
+ var toReference = fromInfo.packageDependencies.get(toLocator.name);
+ return toReference === toLocator.reference;
+ }
+ function isImportablePath(fromPath, toPath, getCanonicalFileName, globalCachePath) {
+ if (getPnpApi(fromPath)) {
+ return isImportablePathPnp(fromPath, toPath);
+ }
+ else {
+ return isImportablePathNode(fromPath, toPath, getCanonicalFileName, globalCachePath);
+ }
+ }
function forEachExternalModuleToImportFrom(program, host, useAutoImportProvider, cb) {
var _a, _b;
forEachExternalModule(program.getTypeChecker(), program.getSourceFiles(), function (module, file) { return cb(module, file, program, /*isFromPackageJson*/ false); });
@@ -126088,6 +126279,7 @@ var ts;
* This includes all files that are found in node_modules/moduleName/ with acceptable file extensions
*/
function getCompletionEntriesForNonRelativeModules(fragment, scriptPath, compilerOptions, host, typeChecker) {
+ var _a, _b;
var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths;
var result = [];
var extensionOptions = getExtensionOptions(compilerOptions);
@@ -126100,8 +126292,8 @@ var ts;
}
}
var fragmentDirectory = getFragmentDirectory(fragment);
- for (var _i = 0, _a = getAmbientModuleCompletions(fragment, fragmentDirectory, typeChecker); _i < _a.length; _i++) {
- var ambientName = _a[_i];
+ for (var _i = 0, _c = getAmbientModuleCompletions(fragment, fragmentDirectory, typeChecker); _i < _c.length; _i++) {
+ var ambientName = _c[_i];
result.push(nameAndKind(ambientName, "external module name" /* externalModuleName */, /*extension*/ undefined));
}
getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, fragmentDirectory, extensionOptions, result);
@@ -126116,18 +126308,36 @@ var ts;
result.push(nameAndKind(moduleName, "external module name" /* externalModuleName */, /*extension*/ undefined));
}
};
- for (var _b = 0, _c = enumerateNodeModulesVisibleToScript(host, scriptPath); _b < _c.length; _b++) {
- var moduleName = _c[_b];
+ for (var _d = 0, _e = enumerateNodeModulesVisibleToScript(host, scriptPath); _d < _e.length; _d++) {
+ var moduleName = _e[_d];
_loop_3(moduleName);
}
}
if (!foundGlobal) {
- ts.forEachAncestorDirectory(scriptPath, function (ancestor) {
- var nodeModules = ts.combinePaths(ancestor, "node_modules");
- if (ts.tryDirectoryExists(host, nodeModules)) {
- getCompletionEntriesForDirectoryFragment(fragment, nodeModules, extensionOptions, host, /*exclude*/ undefined, result);
+ var pnpapi = (_b = (_a = require("module")).findPnpApi) === null || _b === void 0 ? void 0 : _b.call(_a, scriptPath);
+ if (pnpapi) {
+ try {
+ // Splits a require request into its components, or return null if the request is a file path
+ var pathRegExp = /^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:@[^/]+\/)?[^/]+)\/*(.*|)$/;
+ var dependencyNameMatch = fragment.match(pathRegExp);
+ if (dependencyNameMatch) {
+ var dependencyName = dependencyNameMatch[1], subPath = dependencyNameMatch[2];
+ var unqualified = pnpapi.resolveToUnqualified(dependencyName, scriptPath, { considerBuiltins: false });
+ if (unqualified) {
+ getCompletionEntriesForDirectoryFragment(subPath, ts.normalizePath(unqualified), extensionOptions, host, /*exclude*/ undefined, result);
+ }
+ }
}
- });
+ catch (_f) { }
+ }
+ else {
+ ts.forEachAncestorDirectory(scriptPath, function (ancestor) {
+ var nodeModules = ts.combinePaths(ancestor, "node_modules");
+ if (ts.tryDirectoryExists(host, nodeModules)) {
+ getCompletionEntriesForDirectoryFragment(fragment, nodeModules, extensionOptions, host, /*exclude*/ undefined, result);
+ }
+ });
+ }
}
}
return result;
@@ -126228,6 +126438,7 @@ var ts;
return addReplacementSpans(toComplete, range.pos + prefix.length, names);
}
function getCompletionEntriesFromTypings(host, options, scriptPath, fragmentDirectory, extensionOptions, result) {
+ var _a, _b;
if (result === void 0) { result = []; }
// Check for typings specified in compiler options
var seen = new ts.Map();
@@ -126236,11 +126447,19 @@ var ts;
var root = typeRoots_1[_i];
getCompletionEntriesFromDirectories(root);
}
- // Also get all @types typings installed in visible node_modules directories
- for (var _a = 0, _b = ts.findPackageJsons(scriptPath, host); _a < _b.length; _a++) {
- var packageJson = _b[_a];
- var typesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules/@types");
- getCompletionEntriesFromDirectories(typesDir);
+ if ((_b = (_a = require("module")).findPnpApi) === null || _b === void 0 ? void 0 : _b.call(_a, scriptPath)) {
+ for (var _c = 0, _d = ts.getPnpTypeRoots(scriptPath); _c < _d.length; _c++) {
+ var root = _d[_c];
+ getCompletionEntriesFromDirectories(root);
+ }
+ }
+ else {
+ // Also get all @types typings installed in visible node_modules directories
+ for (var _e = 0, _f = ts.findPackageJsons(scriptPath, host); _e < _f.length; _e++) {
+ var packageJson = _f[_e];
+ var typesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules/@types");
+ getCompletionEntriesFromDirectories(typesDir);
+ }
}
return result;
function getCompletionEntriesFromDirectories(directory) {
@@ -154433,9 +154652,9 @@ var ts;
if (isTopLevelDeclarationStatement(statement) &&
!isExported(sourceFile, statement, useEs6Exports) &&
forEachTopLevelDeclaration(statement, function (d) { return needExport.has(ts.Debug.checkDefined(d.symbol)); })) {
- var exports = addExport(statement, useEs6Exports);
- if (exports)
- return exports;
+ var exports_1 = addExport(statement, useEs6Exports);
+ if (exports_1)
+ return exports_1;
}
return statement;
});
diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts
index c4e5e624c..1ff41ed4d 100644
semver exclusivity 4.4.2
--- a/lib/typescriptServices.d.ts
+++ b/lib/typescriptServices.d.ts
@@ -4759,6 +4759,7 @@ declare namespace ts {
}
declare namespace ts {
export function getEffectiveTypeRoots(options: CompilerOptions, host: GetEffectiveTypeRootsHost): string[] | undefined;
+ export function getPnpTypeRoots(currentDirectory: string): string[];
/**
* @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js
index 20a6fc52e..7c5460b03 100644
semver exclusivity 4.4.2
--- a/lib/typescriptServices.js
+++ b/lib/typescriptServices.js
@@ -7652,6 +7652,11 @@ var ts;
: new Buffer(input, encoding);
}
function isFileSystemCaseSensitive() {
+ // The PnP runtime is always case-sensitive
+ // @ts-ignore
+ if (process.versions.pnp) {
+ return true;
+ }
// win32\win64 are case insensitive platforms
if (platform === "win32" || platform === "win64") {
return false;
@@ -41161,24 +41166,56 @@ var ts;
ts.getEffectiveTypeRoots = getEffectiveTypeRoots;
/**
* Returns the path to every node_modules/@types directory from some ancestor directory.
- * Returns undefined if there are none.
*/
- function getDefaultTypeRoots(currentDirectory, host) {
+ function getNodeModulesTypeRoots(currentDirectory, host) {
if (!host.directoryExists) {
return [ts.combinePaths(currentDirectory, nodeModulesAtTypes)];
// And if it doesn't exist, tough.
}
- var typeRoots;
+ var typeRoots = [];
ts.forEachAncestorDirectory(ts.normalizePath(currentDirectory), function (directory) {
var atTypes = ts.combinePaths(directory, nodeModulesAtTypes);
if (host.directoryExists(atTypes)) {
- (typeRoots || (typeRoots = [])).push(atTypes);
+ typeRoots.push(atTypes);
}
return undefined;
});
return typeRoots;
}
var nodeModulesAtTypes = ts.combinePaths("node_modules", "@types");
+ function getPnpTypeRoots(currentDirectory) {
+ var pnpapi = getPnpApi(currentDirectory);
+ if (!pnpapi) {
+ return [];
+ }
+ // Some TS consumers pass relative paths that aren't normalized
+ currentDirectory = ts.sys.resolvePath(currentDirectory);
+ var currentPackage = pnpapi.findPackageLocator(currentDirectory + "/");
+ if (!currentPackage) {
+ return [];
+ }
+ var packageDependencies = pnpapi.getPackageInformation(currentPackage).packageDependencies;
+ var typeRoots = [];
+ for (var _i = 0, _a = Array.from(packageDependencies.entries()); _i < _a.length; _i++) {
+ var _b = _a[_i], name = _b[0], referencish = _b[1];
+ // eslint-disable-next-line no-null/no-null
+ if (name.startsWith(typesPackagePrefix) && referencish !== null) {
+ var dependencyLocator = pnpapi.getLocator(name, referencish);
+ var packageLocation = pnpapi.getPackageInformation(dependencyLocator).packageLocation;
+ typeRoots.push(ts.getDirectoryPath(packageLocation));
+ }
+ }
+ return typeRoots;
+ }
+ ts.getPnpTypeRoots = getPnpTypeRoots;
+ var typesPackagePrefix = "@types/";
+ function getDefaultTypeRoots(currentDirectory, host) {
+ var nmTypes = getNodeModulesTypeRoots(currentDirectory, host);
+ var pnpTypes = getPnpTypeRoots(currentDirectory);
+ if (nmTypes.length > 0 || pnpTypes.length > 0) {
+ return __spreadArray(__spreadArray([], nmTypes, true), pnpTypes, true);
+ }
+ }
/**
* @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
@@ -41292,7 +41329,9 @@ var ts;
}
var result_4;
if (!ts.isExternalModuleNameRelative(typeReferenceDirectiveName)) {
- var searchResult = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
+ var searchResult = getPnpApi(initialLocationForSecondaryLookup)
+ ? tryLoadModuleUsingPnpResolution(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState)
+ : loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
result_4 = searchResult && searchResult.value;
}
else {
@@ -41847,9 +41886,12 @@ var ts;
if (traceEnabled) {
trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]);
}
- var resolved_1 = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
- if (!resolved_1)
+ var resolved_1 = getPnpApi(containingDirectory)
+ ? tryLoadModuleUsingPnpResolution(extensions, moduleName, containingDirectory, state)
+ : loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
+ if (!resolved_1) {
return undefined;
+ }
var resolvedValue = resolved_1.value;
if (!compilerOptions.preserveSymlinks && resolvedValue && !resolvedValue.originalPath) {
var path = realPath(resolvedValue.path, host, traceEnabled);
@@ -42194,6 +42236,14 @@ var ts;
}
function loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state) {
var candidate = ts.normalizePath(ts.combinePaths(nodeModulesDirectory, moduleName));
+ return loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state, candidate, undefined, undefined);
+ }
+ function loadModuleFromPnpResolution(extensions, packageDirectory, rest, state) {
+ var candidate = ts.normalizePath(ts.combinePaths(packageDirectory, rest));
+ return loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, undefined, undefined, true, state, candidate, rest, packageDirectory);
+ }
+ function loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state, candidate, rest, packageDirectory) {
+ var _a;
// First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
var packageInfo = getPackageJsonInfo(candidate, !nodeModulesDirectoryExists, state);
if (packageInfo) {
@@ -42209,9 +42259,12 @@ var ts;
loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageInfo && packageInfo.packageJsonContent, packageInfo && packageInfo.versionPaths);
return withPackageId(packageInfo, pathAndExtension);
};
- var _a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
+ var packageName;
+ if (rest === undefined)
+ (_a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest);
if (rest !== "") { // If "rest" is empty, we just did this search above.
- var packageDirectory = ts.combinePaths(nodeModulesDirectory, packageName);
+ if (packageDirectory === undefined)
+ packageDirectory = ts.combinePaths(nodeModulesDirectory, packageName);
// Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId and path mappings.
packageInfo = getPackageJsonInfo(packageDirectory, !nodeModulesDirectoryExists, state);
if (packageInfo && packageInfo.versionPaths) {
@@ -42370,6 +42423,58 @@ var ts;
function toSearchResult(value) {
return value !== undefined ? { value: value } : undefined;
}
+ /**
+ * We only allow PnP to be used as a resolution strategy if TypeScript
+ * itself is executed under a PnP runtime (and we only allow it to access
+ * the current PnP runtime, not any on the disk). This ensures that we
+ * don't execute potentially malicious code that didn't already have a
+ * chance to be executed (if we're running within the runtime, it means
+ * that the runtime has already been executed).
+ * @internal
+ */
+ function getPnpApi(path) {
+ var findPnpApi = require("module").findPnpApi;
+ if (findPnpApi === undefined) {
+ return undefined;
+ }
+ return findPnpApi(path + "/");
+ }
+ function loadPnpPackageResolution(packageName, containingDirectory) {
+ try {
+ var resolution = getPnpApi(containingDirectory).resolveToUnqualified(packageName, containingDirectory + "/", { considerBuiltins: false });
+ return ts.normalizeSlashes(resolution);
+ }
+ catch (_a) {
+ // Nothing to do
+ }
+ }
+ function loadPnpTypePackageResolution(packageName, containingDirectory) {
+ return loadPnpPackageResolution(getTypesPackageName(packageName), containingDirectory);
+ }
+ /* @internal */
+ function tryLoadModuleUsingPnpResolution(extensions, moduleName, containingDirectory, state) {
+ var _a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
+ var packageResolution = loadPnpPackageResolution(packageName, containingDirectory);
+ var packageFullResolution = packageResolution
+ ? loadModuleFromPnpResolution(extensions, packageResolution, rest, state)
+ : undefined;
+ var resolved;
+ if (packageFullResolution) {
+ resolved = packageFullResolution;
+ }
+ else if (extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) {
+ var typePackageResolution = loadPnpTypePackageResolution(packageName, containingDirectory);
+ var typePackageFullResolution = typePackageResolution
+ ? loadModuleFromPnpResolution(Extensions.DtsOnly, typePackageResolution, rest, state)
+ : undefined;
+ if (typePackageFullResolution) {
+ resolved = typePackageFullResolution;
+ }
+ }
+ if (resolved) {
+ return toSearchResult(resolved);
+ }
+ }
})(ts || (ts = {}));
/* @internal */
var ts;
@@ -110713,6 +110818,8 @@ var ts;
ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Partial"] = 1] = "Partial";
/** Reload completely by re-reading contents of config file from disk and updating program */
ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Full"] = 2] = "Full";
+ /** Reload the resolutions */
+ ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Resolutions"] = 3] = "Resolutions";
})(ConfigFileProgramReloadLevel = ts.ConfigFileProgramReloadLevel || (ts.ConfigFileProgramReloadLevel = {}));
/**
* Updates the map of shared extended config file watches with a new set of extended config files from a base config file of the project
@@ -117283,6 +117390,29 @@ var ts;
return undefined;
}
var parts = getNodeModulePathParts(path);
+ var packageName;
+ if (!parts && typeof process.versions.pnp !== "undefined") {
+ var pnpApi = require("pnpapi");
+ var locator = pnpApi.findPackageLocator(path);
+ // eslint-disable-next-line no-null/no-null
+ if (locator !== null) {
+ var sourceLocator = pnpApi.findPackageLocator(sourceDirectory + "/");
+ // Don't use the package name when the imported file is inside
+ // the source directory (prefer a relative path instead)
+ if (locator === sourceLocator) {
+ return undefined;
+ }
+ var information = pnpApi.getPackageInformation(locator);
+ packageName = locator.name;
+ parts = {
+ topLevelNodeModulesIndex: undefined,
+ topLevelPackageNameIndex: undefined,
+ // The last character from packageLocation is the trailing "/", we want to point to it
+ packageRootIndex: information.packageLocation.length - 1,
+ fileNameIndex: path.lastIndexOf("/"),
+ };
+ }
+ }
if (!parts) {
return undefined;
}
@@ -117313,18 +117443,24 @@ var ts;
if (isRedirect && !isPackageRootPath) {
return undefined;
}
- var globalTypingsCacheLocation = host.getGlobalTypingsCacheLocation && host.getGlobalTypingsCacheLocation();
- // Get a path that's relative to node_modules or the importing file's path
- // if node_modules folder is in this folder or any of its parent folders, no need to keep it.
- var pathToTopLevelNodeModules = getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex));
- if (!(ts.startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && ts.startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) {
- return undefined;
+ // If PnP is enabled the node_modules entries we'll get will always be relevant even if they
+ // are located in a weird path apparently outside of the source directory
+ if (typeof process.versions.pnp === "undefined") {
+ var globalTypingsCacheLocation = host.getGlobalTypingsCacheLocation && host.getGlobalTypingsCacheLocation();
+ // Get a path that's relative to node_modules or the importing file's path
+ // if node_modules folder is in this folder or any of its parent folders, no need to keep it.
+ var pathToTopLevelNodeModules = getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex));
+ if (!(ts.startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && ts.startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) {
+ return undefined;
+ }
}
// If the module was found in @types, get the actual Node package name
- var nodeModulesDirectoryName = moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
- var packageName = ts.getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
+ var nodeModulesDirectoryName = typeof packageName !== "undefined"
+ ? packageName + moduleSpecifier.substring(parts.packageRootIndex)
+ : moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
+ var packageNameFromPath = ts.getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
// For classic resolution, only allow importing from node_modules/@types, not other node_modules
- return ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs && packageName === nodeModulesDirectoryName ? undefined : packageName;
+ return ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs && packageNameFromPath === nodeModulesDirectoryName ? undefined : packageNameFromPath;
function tryDirectoryWithPackageJson(packageRootIndex) {
var packageRootPath = path.substring(0, packageRootIndex);
var packageJsonPath = ts.combinePaths(packageRootPath, "package.json");
@@ -118118,6 +118254,10 @@ var ts;
if (configFileName) {
configFileWatcher = watchFile(configFileName, scheduleProgramReload, ts.PollingInterval.High, watchOptions, ts.WatchType.ConfigFile);
}
+ var pnpFileWatcher;
+ if (typeof process.versions.pnp !== "undefined") {
+ pnpFileWatcher = watchFile(require.resolve("pnpapi"), scheduleResolutionReload, ts.PollingInterval.High, watchOptions, ts.WatchType.ConfigFile);
+ }
var compilerHost = ts.createCompilerHostFromProgramHost(host, function () { return compilerOptions; }, directoryStructureHost);
ts.setGetSourceFileAsHashVersioned(compilerHost, host);
// Members for CompilerHost
@@ -118196,6 +118336,10 @@ var ts;
configFileWatcher.close();
configFileWatcher = undefined;
}
+ if (pnpFileWatcher) {
+ pnpFileWatcher.close();
+ pnpFileWatcher = undefined;
+ }
extendedConfigCache === null || extendedConfigCache === void 0 ? void 0 : extendedConfigCache.clear();
extendedConfigCache = undefined;
if (sharedExtendedConfigFileWatchers) {
@@ -118228,7 +118372,8 @@ var ts;
function getCurrentProgram() {
return builderProgram && builderProgram.getProgramOrUndefined();
}
- function synchronizeProgram() {
+ function synchronizeProgram(forceAllFilesAsInvalidated) {
+ if (forceAllFilesAsInvalidated === void 0) { forceAllFilesAsInvalidated = false; }
writeLog("Synchronizing program");
clearInvalidateResolutionsOfFailedLookupLocations();
var program = getCurrentBuilderProgram();
@@ -118239,7 +118384,7 @@ var ts;
}
}
// All resolutions are invalid if user provided resolutions
- var hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution || changesAffectResolution);
+ var hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution || forceAllFilesAsInvalidated);
if (ts.isProgramUptoDate(getCurrentProgram(), rootFileNames, compilerOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {
if (hasChangedConfigFileParsingErrors) {
builderProgram = createProgram(/*rootNames*/ undefined, /*options*/ undefined, compilerHost, builderProgram, configFileParsingDiagnostics, projectReferences);
@@ -118446,6 +118591,12 @@ var ts;
reloadLevel = ts.ConfigFileProgramReloadLevel.Full;
scheduleProgramUpdate();
}
+ function scheduleResolutionReload() {
+ writeLog("Clearing resolutions");
+ resolutionCache.clear();
+ reloadLevel = ts.ConfigFileProgramReloadLevel.Resolutions;
+ scheduleProgramUpdate();
+ }
function updateProgramWithWatchStatus() {
timerToUpdateProgram = undefined;
reportWatchDiagnostic(ts.Diagnostics.File_change_detected_Starting_incremental_compilation);
@@ -118461,6 +118612,10 @@ var ts;
ts.perfLogger.logStartUpdateProgram("FullConfigReload");
reloadConfigFile();
break;
+ case ts.ConfigFileProgramReloadLevel.Resolutions:
+ ts.perfLogger.logStartUpdateProgram("SynchronizeProgramWithResolutions");
+ synchronizeProgram(/*forceAllFilesAsInvalidated*/ true);
+ break;
default:
ts.perfLogger.logStartUpdateProgram("SynchronizeProgram");
synchronizeProgram();
@@ -124266,11 +124421,27 @@ var ts;
return hasImportablePath;
}
ts.isImportableFile = isImportableFile;
+ /**
+ * We only allow PnP to be used as a resolution strategy if TypeScript
+ * itself is executed under a PnP runtime (and we only allow it to access
+ * the current PnP runtime, not any on the disk). This ensures that we
+ * don't execute potentially malicious code that didn't already have a
+ * chance to be executed (if we're running within the runtime, it means
+ * that the runtime has already been executed).
+ * @internal
+ */
+ function getPnpApi(path) {
+ var findPnpApi = require("module").findPnpApi;
+ if (findPnpApi === undefined) {
+ return undefined;
+ }
+ return findPnpApi(path + "/");
+ }
/**
* Don't include something from a `node_modules` that isn't actually reachable by a global import.
* A relative import to node_modules is usually a bad idea.
*/
- function isImportablePath(fromPath, toPath, getCanonicalFileName, globalCachePath) {
+ function isImportablePathNode(fromPath, toPath, getCanonicalFileName, globalCachePath) {
// If it's in a `node_modules` but is not reachable from here via a global import, don't bother.
var toNodeModules = ts.forEachAncestorDirectory(toPath, function (ancestor) { return ts.getBaseFileName(ancestor) === "node_modules" ? ancestor : undefined; });
var toNodeModulesParent = toNodeModules && ts.getDirectoryPath(getCanonicalFileName(toNodeModules));
@@ -124278,6 +124449,26 @@ var ts;
|| ts.startsWith(getCanonicalFileName(fromPath), toNodeModulesParent)
|| (!!globalCachePath && ts.startsWith(getCanonicalFileName(globalCachePath), toNodeModulesParent));
}
+ function isImportablePathPnp(fromPath, toPath) {
+ var pnpApi = getPnpApi(fromPath);
+ var fromLocator = pnpApi.findPackageLocator(fromPath);
+ var toLocator = pnpApi.findPackageLocator(toPath);
+ // eslint-disable-next-line no-null/no-null
+ if (toLocator === null) {
+ return false;
+ }
+ var fromInfo = pnpApi.getPackageInformation(fromLocator);
+ var toReference = fromInfo.packageDependencies.get(toLocator.name);
+ return toReference === toLocator.reference;
+ }
+ function isImportablePath(fromPath, toPath, getCanonicalFileName, globalCachePath) {
+ if (getPnpApi(fromPath)) {
+ return isImportablePathPnp(fromPath, toPath);
+ }
+ else {
+ return isImportablePathNode(fromPath, toPath, getCanonicalFileName, globalCachePath);
+ }
+ }
function forEachExternalModuleToImportFrom(program, host, useAutoImportProvider, cb) {
var _a, _b;
forEachExternalModule(program.getTypeChecker(), program.getSourceFiles(), function (module, file) { return cb(module, file, program, /*isFromPackageJson*/ false); });
@@ -126088,6 +126279,7 @@ var ts;
* This includes all files that are found in node_modules/moduleName/ with acceptable file extensions
*/
function getCompletionEntriesForNonRelativeModules(fragment, scriptPath, compilerOptions, host, typeChecker) {
+ var _a, _b;
var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths;
var result = [];
var extensionOptions = getExtensionOptions(compilerOptions);
@@ -126100,8 +126292,8 @@ var ts;
}
}
var fragmentDirectory = getFragmentDirectory(fragment);
- for (var _i = 0, _a = getAmbientModuleCompletions(fragment, fragmentDirectory, typeChecker); _i < _a.length; _i++) {
- var ambientName = _a[_i];
+ for (var _i = 0, _c = getAmbientModuleCompletions(fragment, fragmentDirectory, typeChecker); _i < _c.length; _i++) {
+ var ambientName = _c[_i];
result.push(nameAndKind(ambientName, "external module name" /* externalModuleName */, /*extension*/ undefined));
}
getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, fragmentDirectory, extensionOptions, result);
@@ -126116,18 +126308,36 @@ var ts;
result.push(nameAndKind(moduleName, "external module name" /* externalModuleName */, /*extension*/ undefined));
}
};
- for (var _b = 0, _c = enumerateNodeModulesVisibleToScript(host, scriptPath); _b < _c.length; _b++) {
- var moduleName = _c[_b];
+ for (var _d = 0, _e = enumerateNodeModulesVisibleToScript(host, scriptPath); _d < _e.length; _d++) {
+ var moduleName = _e[_d];
_loop_3(moduleName);
}
}
if (!foundGlobal) {
- ts.forEachAncestorDirectory(scriptPath, function (ancestor) {
- var nodeModules = ts.combinePaths(ancestor, "node_modules");
- if (ts.tryDirectoryExists(host, nodeModules)) {
- getCompletionEntriesForDirectoryFragment(fragment, nodeModules, extensionOptions, host, /*exclude*/ undefined, result);
+ var pnpapi = (_b = (_a = require("module")).findPnpApi) === null || _b === void 0 ? void 0 : _b.call(_a, scriptPath);
+ if (pnpapi) {
+ try {
+ // Splits a require request into its components, or return null if the request is a file path
+ var pathRegExp = /^(?![a-zA-Z]:[\\/]|\\\\|\.{0,2}(?:\/|$))((?:@[^/]+\/)?[^/]+)\/*(.*|)$/;
+ var dependencyNameMatch = fragment.match(pathRegExp);
+ if (dependencyNameMatch) {
+ var dependencyName = dependencyNameMatch[1], subPath = dependencyNameMatch[2];
+ var unqualified = pnpapi.resolveToUnqualified(dependencyName, scriptPath, { considerBuiltins: false });
+ if (unqualified) {
+ getCompletionEntriesForDirectoryFragment(subPath, ts.normalizePath(unqualified), extensionOptions, host, /*exclude*/ undefined, result);
+ }
+ }
}
- });
+ catch (_f) { }
+ }
+ else {
+ ts.forEachAncestorDirectory(scriptPath, function (ancestor) {
+ var nodeModules = ts.combinePaths(ancestor, "node_modules");
+ if (ts.tryDirectoryExists(host, nodeModules)) {
+ getCompletionEntriesForDirectoryFragment(fragment, nodeModules, extensionOptions, host, /*exclude*/ undefined, result);
+ }
+ });
+ }
}
}
return result;
@@ -126228,6 +126438,7 @@ var ts;
return addReplacementSpans(toComplete, range.pos + prefix.length, names);
}
function getCompletionEntriesFromTypings(host, options, scriptPath, fragmentDirectory, extensionOptions, result) {
+ var _a, _b;
if (result === void 0) { result = []; }
// Check for typings specified in compiler options
var seen = new ts.Map();
@@ -126236,11 +126447,19 @@ var ts;
var root = typeRoots_1[_i];
getCompletionEntriesFromDirectories(root);
}
- // Also get all @types typings installed in visible node_modules directories
- for (var _a = 0, _b = ts.findPackageJsons(scriptPath, host); _a < _b.length; _a++) {
- var packageJson = _b[_a];
- var typesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules/@types");
- getCompletionEntriesFromDirectories(typesDir);
+ if ((_b = (_a = require("module")).findPnpApi) === null || _b === void 0 ? void 0 : _b.call(_a, scriptPath)) {
+ for (var _c = 0, _d = ts.getPnpTypeRoots(scriptPath); _c < _d.length; _c++) {
+ var root = _d[_c];
+ getCompletionEntriesFromDirectories(root);
+ }
+ }
+ else {
+ // Also get all @types typings installed in visible node_modules directories
+ for (var _e = 0, _f = ts.findPackageJsons(scriptPath, host); _e < _f.length; _e++) {
+ var packageJson = _f[_e];
+ var typesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules/@types");
+ getCompletionEntriesFromDirectories(typesDir);
+ }
}
return result;
function getCompletionEntriesFromDirectories(directory) {
@@ -154433,9 +154652,9 @@ var ts;
if (isTopLevelDeclarationStatement(statement) &&
!isExported(sourceFile, statement, useEs6Exports) &&
forEachTopLevelDeclaration(statement, function (d) { return needExport.has(ts.Debug.checkDefined(d.symbol)); })) {
- var exports = addExport(statement, useEs6Exports);
- if (exports)
- return exports;
+ var exports_1 = addExport(statement, useEs6Exports);
+ if (exports_1)
+ return exports_1;
}
return statement;
});
diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js
index a0e7177a1..05fe8eb42 100644
semver exclusivity 4.4.2
--- a/lib/typingsInstaller.js
+++ b/lib/typingsInstaller.js
@@ -7447,6 +7447,11 @@ var ts;
: new Buffer(input, encoding);
}
function isFileSystemCaseSensitive() {
+ // The PnP runtime is always case-sensitive
+ // @ts-ignore
+ if (process.versions.pnp) {
+ return true;
+ }
// win32\win64 are case insensitive platforms
if (platform === "win32" || platform === "win64") {
return false;
@@ -40956,24 +40961,56 @@ var ts;
ts.getEffectiveTypeRoots = getEffectiveTypeRoots;
/**
* Returns the path to every node_modules/@types directory from some ancestor directory.
- * Returns undefined if there are none.
*/
- function getDefaultTypeRoots(currentDirectory, host) {
+ function getNodeModulesTypeRoots(currentDirectory, host) {
if (!host.directoryExists) {
return [ts.combinePaths(currentDirectory, nodeModulesAtTypes)];
// And if it doesn't exist, tough.
}
- var typeRoots;
+ var typeRoots = [];
ts.forEachAncestorDirectory(ts.normalizePath(currentDirectory), function (directory) {
var atTypes = ts.combinePaths(directory, nodeModulesAtTypes);
if (host.directoryExists(atTypes)) {
- (typeRoots || (typeRoots = [])).push(atTypes);
+ typeRoots.push(atTypes);
}
return undefined;
});
return typeRoots;
}
var nodeModulesAtTypes = ts.combinePaths("node_modules", "@types");
+ function getPnpTypeRoots(currentDirectory) {
+ var pnpapi = getPnpApi(currentDirectory);
+ if (!pnpapi) {
+ return [];
+ }
+ // Some TS consumers pass relative paths that aren't normalized
+ currentDirectory = ts.sys.resolvePath(currentDirectory);
+ var currentPackage = pnpapi.findPackageLocator(currentDirectory + "/");
+ if (!currentPackage) {
+ return [];
+ }
+ var packageDependencies = pnpapi.getPackageInformation(currentPackage).packageDependencies;
+ var typeRoots = [];
+ for (var _i = 0, _a = Array.from(packageDependencies.entries()); _i < _a.length; _i++) {
+ var _b = _a[_i], name = _b[0], referencish = _b[1];
+ // eslint-disable-next-line no-null/no-null
+ if (name.startsWith(typesPackagePrefix) && referencish !== null) {
+ var dependencyLocator = pnpapi.getLocator(name, referencish);
+ var packageLocation = pnpapi.getPackageInformation(dependencyLocator).packageLocation;
+ typeRoots.push(ts.getDirectoryPath(packageLocation));
+ }
+ }
+ return typeRoots;
+ }
+ ts.getPnpTypeRoots = getPnpTypeRoots;
+ var typesPackagePrefix = "@types/";
+ function getDefaultTypeRoots(currentDirectory, host) {
+ var nmTypes = getNodeModulesTypeRoots(currentDirectory, host);
+ var pnpTypes = getPnpTypeRoots(currentDirectory);
+ if (nmTypes.length > 0 || pnpTypes.length > 0) {
+ return __spreadArray(__spreadArray([], nmTypes, true), pnpTypes, true);
+ }
+ }
/**
* @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
@@ -41087,7 +41124,9 @@ var ts;
}
var result_4;
if (!ts.isExternalModuleNameRelative(typeReferenceDirectiveName)) {
- var searchResult = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
+ var searchResult = getPnpApi(initialLocationForSecondaryLookup)
+ ? tryLoadModuleUsingPnpResolution(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState)
+ : loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
result_4 = searchResult && searchResult.value;
}
else {
@@ -41642,9 +41681,12 @@ var ts;
if (traceEnabled) {
trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]);
}
- var resolved_1 = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
- if (!resolved_1)
+ var resolved_1 = getPnpApi(containingDirectory)
+ ? tryLoadModuleUsingPnpResolution(extensions, moduleName, containingDirectory, state)
+ : loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
+ if (!resolved_1) {
return undefined;
+ }
var resolvedValue = resolved_1.value;
if (!compilerOptions.preserveSymlinks && resolvedValue && !resolvedValue.originalPath) {
var path = realPath(resolvedValue.path, host, traceEnabled);
@@ -41989,6 +42031,14 @@ var ts;
}
function loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state) {
var candidate = ts.normalizePath(ts.combinePaths(nodeModulesDirectory, moduleName));
+ return loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state, candidate, undefined, undefined);
+ }
+ function loadModuleFromPnpResolution(extensions, packageDirectory, rest, state) {
+ var candidate = ts.normalizePath(ts.combinePaths(packageDirectory, rest));
+ return loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, undefined, undefined, true, state, candidate, rest, packageDirectory);
+ }
+ function loadModuleFromSpecificNodeModulesDirectoryImpl(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state, candidate, rest, packageDirectory) {
+ var _a;
// First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
var packageInfo = getPackageJsonInfo(candidate, !nodeModulesDirectoryExists, state);
if (packageInfo) {
@@ -42004,9 +42054,12 @@ var ts;
loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageInfo && packageInfo.packageJsonContent, packageInfo && packageInfo.versionPaths);
return withPackageId(packageInfo, pathAndExtension);
};
- var _a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
+ var packageName;
+ if (rest === undefined)
+ (_a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest);
if (rest !== "") { // If "rest" is empty, we just did this search above.
- var packageDirectory = ts.combinePaths(nodeModulesDirectory, packageName);
+ if (packageDirectory === undefined)
+ packageDirectory = ts.combinePaths(nodeModulesDirectory, packageName);
// Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId and path mappings.
packageInfo = getPackageJsonInfo(packageDirectory, !nodeModulesDirectoryExists, state);
if (packageInfo && packageInfo.versionPaths) {
@@ -42165,6 +42218,58 @@ var ts;
function toSearchResult(value) {
return value !== undefined ? { value: value } : undefined;
}
+ /**
+ * We only allow PnP to be used as a resolution strategy if TypeScript
+ * itself is executed under a PnP runtime (and we only allow it to access
+ * the current PnP runtime, not any on the disk). This ensures that we
+ * don't execute potentially malicious code that didn't already have a
+ * chance to be executed (if we're running within the runtime, it means
+ * that the runtime has already been executed).
+ * @internal
+ */
+ function getPnpApi(path) {
+ var findPnpApi = require("module").findPnpApi;
+ if (findPnpApi === undefined) {
+ return undefined;
+ }
+ return findPnpApi(path + "/");
+ }
+ function loadPnpPackageResolution(packageName, containingDirectory) {
+ try {
+ var resolution = getPnpApi(containingDirectory).resolveToUnqualified(packageName, containingDirectory + "/", { considerBuiltins: false });
+ return ts.normalizeSlashes(resolution);
+ }
+ catch (_a) {
+ // Nothing to do
+ }
+ }
+ function loadPnpTypePackageResolution(packageName, containingDirectory) {
+ return loadPnpPackageResolution(getTypesPackageName(packageName), containingDirectory);
+ }
+ /* @internal */
+ function tryLoadModuleUsingPnpResolution(extensions, moduleName, containingDirectory, state) {
+ var _a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
+ var packageResolution = loadPnpPackageResolution(packageName, containingDirectory);
+ var packageFullResolution = packageResolution
+ ? loadModuleFromPnpResolution(extensions, packageResolution, rest, state)
+ : undefined;
+ var resolved;
+ if (packageFullResolution) {
+ resolved = packageFullResolution;
+ }
+ else if (extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) {
+ var typePackageResolution = loadPnpTypePackageResolution(packageName, containingDirectory);
+ var typePackageFullResolution = typePackageResolution
+ ? loadModuleFromPnpResolution(Extensions.DtsOnly, typePackageResolution, rest, state)
+ : undefined;
+ if (typePackageFullResolution) {
+ resolved = typePackageFullResolution;
+ }
+ }
+ if (resolved) {
+ return toSearchResult(resolved);
+ }
+ }
})(ts || (ts = {}));
/* @internal */
var ts;
@@ -110508,6 +110613,8 @@ var ts;
ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Partial"] = 1] = "Partial";
/** Reload completely by re-reading contents of config file from disk and updating program */
ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Full"] = 2] = "Full";
+ /** Reload the resolutions */
+ ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Resolutions"] = 3] = "Resolutions";
})(ConfigFileProgramReloadLevel = ts.ConfigFileProgramReloadLevel || (ts.ConfigFileProgramReloadLevel = {}));
/**
* Updates the map of shared extended config file watches with a new set of extended config files from a base config file of the project
@@ -117078,6 +117185,29 @@ var ts;
return undefined;
}
var parts = getNodeModulePathParts(path);
+ var packageName;
+ if (!parts && typeof process.versions.pnp !== "undefined") {
+ var pnpApi = require("pnpapi");
+ var locator = pnpApi.findPackageLocator(path);
+ // eslint-disable-next-line no-null/no-null
+ if (locator !== null) {
+ var sourceLocator = pnpApi.findPackageLocator(sourceDirectory + "/");
+ // Don't use the package name when the imported file is inside
+ // the source directory (prefer a relative path instead)
+ if (locator === sourceLocator) {
+ return undefined;
+ }
+ var information = pnpApi.getPackageInformation(locator);
+ packageName = locator.name;
+ parts = {
+ topLevelNodeModulesIndex: undefined,
+ topLevelPackageNameIndex: undefined,
+ // The last character from packageLocation is the trailing "/", we want to point to it
+ packageRootIndex: information.packageLocation.length - 1,
+ fileNameIndex: path.lastIndexOf("/"),
+ };
+ }
+ }
if (!parts) {
return undefined;
}
@@ -117108,18 +117238,24 @@ var ts;
if (isRedirect && !isPackageRootPath) {
return undefined;
}
- var globalTypingsCacheLocation = host.getGlobalTypingsCacheLocation && host.getGlobalTypingsCacheLocation();
- // Get a path that's relative to node_modules or the importing file's path
- // if node_modules folder is in this folder or any of its parent folders, no need to keep it.
- var pathToTopLevelNodeModules = getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex));
- if (!(ts.startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && ts.startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) {
- return undefined;
+ // If PnP is enabled the node_modules entries we'll get will always be relevant even if they
+ // are located in a weird path apparently outside of the source directory
+ if (typeof process.versions.pnp === "undefined") {
+ var globalTypingsCacheLocation = host.getGlobalTypingsCacheLocation && host.getGlobalTypingsCacheLocation();
+ // Get a path that's relative to node_modules or the importing file's path
+ // if node_modules folder is in this folder or any of its parent folders, no need to keep it.
+ var pathToTopLevelNodeModules = getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex));
+ if (!(ts.startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && ts.startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) {
+ return undefined;
+ }
}
// If the module was found in @types, get the actual Node package name
- var nodeModulesDirectoryName = moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
- var packageName = ts.getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
+ var nodeModulesDirectoryName = typeof packageName !== "undefined"
+ ? packageName + moduleSpecifier.substring(parts.packageRootIndex)
+ : moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
+ var packageNameFromPath = ts.getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
// For classic resolution, only allow importing from node_modules/@types, not other node_modules
- return ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs && packageName === nodeModulesDirectoryName ? undefined : packageName;
+ return ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs && packageNameFromPath === nodeModulesDirectoryName ? undefined : packageNameFromPath;
function tryDirectoryWithPackageJson(packageRootIndex) {
var packageRootPath = path.substring(0, packageRootIndex);
var packageJsonPath = ts.combinePaths(packageRootPath, "package.json");
@@ -117913,6 +118049,10 @@ var ts;
if (configFileName) {
configFileWatcher = watchFile(configFileName, scheduleProgramReload, ts.PollingInterval.High, watchOptions, ts.WatchType.ConfigFile);
}
+ var pnpFileWatcher;
+ if (typeof process.versions.pnp !== "undefined") {
+ pnpFileWatcher = watchFile(require.resolve("pnpapi"), scheduleResolutionReload, ts.PollingInterval.High, watchOptions, ts.WatchType.ConfigFile);
+ }
var compilerHost = ts.createCompilerHostFromProgramHost(host, function () { return compilerOptions; }, directoryStructureHost);
ts.setGetSourceFileAsHashVersioned(compilerHost, host);
// Members for CompilerHost
@@ -117991,6 +118131,10 @@ var ts;
configFileWatcher.close();
configFileWatcher = undefined;
}
+ if (pnpFileWatcher) {
+ pnpFileWatcher.close();
+ pnpFileWatcher = undefined;
+ }
extendedConfigCache === null || extendedConfigCache === void 0 ? void 0 : extendedConfigCache.clear();
extendedConfigCache = undefined;
if (sharedExtendedConfigFileWatchers) {
@@ -118023,7 +118167,8 @@ var ts;
function getCurrentProgram() {
return builderProgram && builderProgram.getProgramOrUndefined();
}
- function synchronizeProgram() {
+ function synchronizeProgram(forceAllFilesAsInvalidated) {
+ if (forceAllFilesAsInvalidated === void 0) { forceAllFilesAsInvalidated = false; }
writeLog("Synchronizing program");
clearInvalidateResolutionsOfFailedLookupLocations();
var program = getCurrentBuilderProgram();
@@ -118034,7 +118179,7 @@ var ts;
}
}
// All resolutions are invalid if user provided resolutions
- var hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution || changesAffectResolution);
+ var hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution || forceAllFilesAsInvalidated);
if (ts.isProgramUptoDate(getCurrentProgram(), rootFileNames, compilerOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {
if (hasChangedConfigFileParsingErrors) {
builderProgram = createProgram(/*rootNames*/ undefined, /*options*/ undefined, compilerHost, builderProgram, configFileParsingDiagnostics, projectReferences);
@@ -118241,6 +118386,12 @@ var ts;
reloadLevel = ts.ConfigFileProgramReloadLevel.Full;
scheduleProgramUpdate();
}
+ function scheduleResolutionReload() {
+ writeLog("Clearing resolutions");
+ resolutionCache.clear();
+ reloadLevel = ts.ConfigFileProgramReloadLevel.Resolutions;
+ scheduleProgramUpdate();
+ }
function updateProgramWithWatchStatus() {
timerToUpdateProgram = undefined;
reportWatchDiagnostic(ts.Diagnostics.File_change_detected_Starting_incremental_compilation);
@@ -118256,6 +118407,10 @@ var ts;
ts.perfLogger.logStartUpdateProgram("FullConfigReload");
reloadConfigFile();
break;
+ case ts.ConfigFileProgramReloadLevel.Resolutions:
+ ts.perfLogger.logStartUpdateProgram("SynchronizeProgramWithResolutions");
+ synchronizeProgram(/*forceAllFilesAsInvalidated*/ true);
+ break;
default:
ts.perfLogger.logStartUpdateProgram("SynchronizeProgram");
synchronizeProgram();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment