mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-19 01:33:15 -05:00
Update installed types if older than those listed in the registry
This commit is contained in:
@@ -252,7 +252,7 @@ namespace ts.server {
|
||||
private requestMap = createMap<QueuedOperation>(); // Maps operation ID to newest requestQueue entry with that ID
|
||||
/** We will lazily request the types registry on the first call to `isKnownTypesPackageName` and store it in `typesRegistryCache`. */
|
||||
private requestedRegistry: boolean;
|
||||
private typesRegistryCache: Map<void> | undefined;
|
||||
private typesRegistryCache: Map<MapLike<string>> | undefined;
|
||||
|
||||
// This number is essentially arbitrary. Processing more than one typings request
|
||||
// at a time makes sense, but having too many in the pipe results in a hang
|
||||
|
||||
@@ -77,7 +77,7 @@ declare namespace ts.server {
|
||||
/* @internal */
|
||||
export interface TypesRegistryResponse extends TypingInstallerResponse {
|
||||
readonly kind: EventTypesRegistry;
|
||||
readonly typesRegistry: MapLike<void>;
|
||||
readonly typesRegistry: MapLike<MapLike<string>>;
|
||||
}
|
||||
|
||||
export interface PackageInstalledResponse extends ProjectResponse {
|
||||
|
||||
@@ -41,15 +41,15 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
|
||||
interface TypesRegistryFile {
|
||||
entries: MapLike<void>;
|
||||
entries: MapLike<MapLike<string>>;
|
||||
}
|
||||
|
||||
function loadTypesRegistryFile(typesRegistryFilePath: string, host: InstallTypingHost, log: Log): Map<void> {
|
||||
function loadTypesRegistryFile(typesRegistryFilePath: string, host: InstallTypingHost, log: Log): Map<MapLike<string>> {
|
||||
if (!host.fileExists(typesRegistryFilePath)) {
|
||||
if (log.isEnabled()) {
|
||||
log.writeLine(`Types registry file '${typesRegistryFilePath}' does not exist`);
|
||||
}
|
||||
return createMap<void>();
|
||||
return createMap<MapLike<string>>();
|
||||
}
|
||||
try {
|
||||
const content = <TypesRegistryFile>JSON.parse(host.readFile(typesRegistryFilePath));
|
||||
@@ -59,7 +59,7 @@ namespace ts.server.typingsInstaller {
|
||||
if (log.isEnabled()) {
|
||||
log.writeLine(`Error when loading types registry file '${typesRegistryFilePath}': ${(<Error>e).message}, ${(<Error>e).stack}`);
|
||||
}
|
||||
return createMap<void>();
|
||||
return createMap<MapLike<string>>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace ts.server.typingsInstaller {
|
||||
export class NodeTypingsInstaller extends TypingsInstaller {
|
||||
private readonly nodeExecSync: ExecSync;
|
||||
private readonly npmPath: string;
|
||||
readonly typesRegistry: Map<void>;
|
||||
readonly typesRegistry: Map<MapLike<string>>;
|
||||
|
||||
private delayedInitializationError: InitializationFailedResponse | undefined;
|
||||
|
||||
@@ -141,7 +141,7 @@ namespace ts.server.typingsInstaller {
|
||||
this.closeProject(req);
|
||||
break;
|
||||
case "typesRegistry": {
|
||||
const typesRegistry: { [key: string]: void } = {};
|
||||
const typesRegistry: { [key: string]: MapLike<string> } = {};
|
||||
this.typesRegistry.forEach((value, key) => {
|
||||
typesRegistry[key] = value;
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/// <reference path="../../compiler/core.ts" />
|
||||
/// <reference path="../../compiler/moduleNameResolver.ts" />
|
||||
/// <reference path="../../services/jsTyping.ts"/>
|
||||
/// <reference path="../../services/semver.ts"/>
|
||||
/// <reference path="../types.ts"/>
|
||||
/// <reference path="../shared.ts"/>
|
||||
|
||||
@@ -9,6 +10,10 @@ namespace ts.server.typingsInstaller {
|
||||
devDependencies: MapLike<any>;
|
||||
}
|
||||
|
||||
interface NpmLock {
|
||||
dependencies: { [packageName: string]: { version: string } };
|
||||
}
|
||||
|
||||
export interface Log {
|
||||
isEnabled(): boolean;
|
||||
writeLine(text: string): void;
|
||||
@@ -104,7 +109,7 @@ namespace ts.server.typingsInstaller {
|
||||
private installRunCount = 1;
|
||||
private inFlightRequestCount = 0;
|
||||
|
||||
abstract readonly typesRegistry: Map<void>;
|
||||
abstract readonly typesRegistry: Map<MapLike<string>>;
|
||||
|
||||
constructor(
|
||||
protected readonly installTypingHost: InstallTypingHost,
|
||||
@@ -217,15 +222,18 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
const typeDeclarationTimestamps = loadTypeDeclarationTimestampFile(timestampsFilePath || combinePaths(cacheLocation, timestampsFileName), this.installTypingHost, this.log);
|
||||
const packageJson = combinePaths(cacheLocation, "package.json");
|
||||
const packageLockJson = combinePaths(cacheLocation, "package-lock.json");
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Trying to find '${packageJson}'...`);
|
||||
}
|
||||
if (this.installTypingHost.fileExists(packageJson)) {
|
||||
if (this.installTypingHost.fileExists(packageJson) && this.installTypingHost.fileExists(packageLockJson)) {
|
||||
const npmConfig = <NpmConfig>JSON.parse(this.installTypingHost.readFile(packageJson));
|
||||
const npmLock = <NpmLock>JSON.parse(this.installTypingHost.readFile(packageLockJson));
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Loaded content of '${packageJson}': ${JSON.stringify(npmConfig)}`);
|
||||
this.log.writeLine(`Loaded content of '${packageLockJson}'`);
|
||||
}
|
||||
if (npmConfig.devDependencies) {
|
||||
if (npmConfig.devDependencies && npmLock.dependencies) {
|
||||
for (const key in npmConfig.devDependencies) {
|
||||
// key is @types/<package name>
|
||||
const packageName = getBaseFileName(key);
|
||||
@@ -259,8 +267,11 @@ namespace ts.server.typingsInstaller {
|
||||
this.log.writeLine(`Adding entry into timestamp cache: '${key}' => '${timestamp}'`);
|
||||
}
|
||||
}
|
||||
const info = getProperty(npmLock.dependencies, key);
|
||||
const version = info && info.version;
|
||||
const semver = Semver.parse(version);
|
||||
// timestamp guaranteed to not be undefined by above check
|
||||
const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, timestamp: getProperty(typeDeclarationTimestamps, key) };
|
||||
const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, timestamp: getProperty(typeDeclarationTimestamps, key), version: semver };
|
||||
this.packageNameToTypingLocation.set(packageName, newTyping);
|
||||
}
|
||||
}
|
||||
@@ -277,10 +288,6 @@ namespace ts.server.typingsInstaller {
|
||||
if (this.log.isEnabled()) this.log.writeLine(`'${typing}' is in missingTypingsSet - skipping...`);
|
||||
return false;
|
||||
}
|
||||
if (this.packageNameToTypingLocation.get(typing) && !JsTyping.isTypingExpired(this.packageNameToTypingLocation.get(typing))) {
|
||||
if (this.log.isEnabled()) this.log.writeLine(`'${typing}' already has a typing - skipping...`);
|
||||
return false;
|
||||
}
|
||||
const validationResult = JsTyping.validatePackageName(typing);
|
||||
if (validationResult !== JsTyping.PackageNameValidationResult.Ok) {
|
||||
// add typing name to missing set so we won't process it again
|
||||
@@ -292,8 +299,17 @@ namespace ts.server.typingsInstaller {
|
||||
if (this.log.isEnabled()) this.log.writeLine(`Entry for package '${typing}' does not exist in local types registry - skipping...`);
|
||||
return false;
|
||||
}
|
||||
if (this.packageNameToTypingLocation.get(typing) && isTypingUpToDate(this.packageNameToTypingLocation.get(typing), this.typesRegistry.get(typing))) {
|
||||
if (this.log.isEnabled()) this.log.writeLine(`'${typing}' already has an up-to-date typing - skipping...`);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
function isTypingUpToDate(cachedTyping: JsTyping.CachedTyping, availableTypingVersions: MapLike<string>) {
|
||||
const availableVersion = Semver.parse(getProperty(availableTypingVersions, `ts${ts.version}`));
|
||||
return !availableVersion.greaterThan(cachedTyping.version);
|
||||
}
|
||||
}
|
||||
|
||||
protected ensurePackageDirectoryExists(directory: string) {
|
||||
@@ -364,7 +380,8 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
|
||||
const newTimestamp = Date.now();
|
||||
const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, timestamp: newTimestamp };
|
||||
const newVersion = Semver.parse(this.typesRegistry.get(packageName)[`ts${ts.versionMajorMinor}`]);
|
||||
const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, timestamp: newTimestamp, version: newVersion };
|
||||
this.packageNameToTypingLocation.set(packageName, newTyping);
|
||||
typeDeclarationTimestamps[typesPackageName(packageName)] = newTimestamp;
|
||||
installedTypingFiles.push(typingFile);
|
||||
|
||||
Reference in New Issue
Block a user