diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index fb82a17b965..8636b38d294 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -1,6 +1,6 @@ /// /// -/// import { deepEqual } from "assert";import { deepEqual } from "assert"; +/// diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index cf441017de9..291f2b9b871 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -19,7 +19,7 @@ namespace ts.server.typingsInstaller { writeLine: noop }; - const timestampsFile = "timestamps.json"; + const timestampsFileName = "timestamps.json"; function typingToFileName(cachePath: string, packageName: string, installTypingHost: InstallTypingHost, log: Log): string { try { @@ -44,60 +44,37 @@ namespace ts.server.typingsInstaller { } interface TypeDeclarationTimestampFile { + // entries maps from package names (e.g. "@types/node") to timestamp values (as produced by Date#getTime) entries: MapLike; } function loadTypeDeclarationTimestampFile(typeDeclarationTimestampFilePath: string, host: InstallTypingHost, log: Log): MapLike { - const fileExists = host.fileExists(typeDeclarationTimestampFilePath); - if (!fileExists) { - if (log.isEnabled()) { - log.writeLine(`Type declaration timestamp file '${typeDeclarationTimestampFilePath}' does not exist`); - } - } try { - if (fileExists) { - const content = JSON.parse(host.readFile(typeDeclarationTimestampFilePath)); - return content.entries || {}; - } - else { - host.writeFile(typeDeclarationTimestampFilePath, "{}"); - if (log.isEnabled()) { - log.writeLine("Type declaration timestamp file was created."); - } - return {}; + if (log.isEnabled()) { + log.writeLine("Loading type declaration timestamp file."); } + const content = JSON.parse(host.readFile(typeDeclarationTimestampFilePath)); + return content.entries || {}; } catch (e) { if (log.isEnabled()) { log.writeLine(`Error when loading type declaration timestamp file '${typeDeclarationTimestampFilePath}': ${(e).message}, ${(e).stack}`); } + // If file cannot be read, we update all requested type declarations. return {}; } } function writeTypeDeclarationTimestampFile(typeDeclarationTimestampFilePath: string, newContents: TypeDeclarationTimestampFile, host: InstallTypingHost, log: Log): void { - const fileExists = host.fileExists(typeDeclarationTimestampFilePath); - if (!fileExists) { - if (log.isEnabled()) { - log.writeLine(`Type declaration timestamp file '${typeDeclarationTimestampFilePath}' does not exist`); - } - } try { - if (fileExists) { - host.writeFile(typeDeclarationTimestampFilePath, JSON.stringify(newContents)); - return; - } - else { - host.writeFile(typeDeclarationTimestampFilePath, JSON.stringify(newContents)); - if (log.isEnabled()) { - log.writeLine("Type declaration time stamp file was created."); - } - return; + if (log.isEnabled()) { + log.writeLine("Writing type declaration timestamp file."); } + host.writeFile(typeDeclarationTimestampFilePath, JSON.stringify(newContents)); } catch (e) { if (log.isEnabled()) { - log.writeLine(`Error when writing new type declaration timestamp file '${typeDeclarationTimestampFilePath}': ${(e).message}, ${(e).stack}`); + log.writeLine(`Error when writing type declaration timestamp file '${typeDeclarationTimestampFilePath}': ${(e).message}, ${(e).stack}`); } return; } @@ -162,11 +139,12 @@ namespace ts.server.typingsInstaller { } // load existing typing information from the cache + const timestampsFilePath = combinePaths(req.cachePath || this.globalCachePath, timestampsFileName); if (req.cachePath) { if (this.log.isEnabled()) { this.log.writeLine(`Request specifies cache path '${req.cachePath}', loading cached information...`); } - this.processCacheLocation(req.cachePath); + this.processCacheLocation(req.cachePath, timestampsFilePath); } if (this.safeList === undefined) { @@ -191,7 +169,7 @@ namespace ts.server.typingsInstaller { // install typings if (discoverTypingsResult.newTypingNames.length) { - this.installTypings(req, req.cachePath || this.globalCachePath, discoverTypingsResult.cachedTypingPaths, discoverTypingsResult.newTypingNames); + this.installTypings(req, req.cachePath || this.globalCachePath, discoverTypingsResult.cachedTypingPaths, discoverTypingsResult.newTypingNames, timestampsFilePath); } else { this.sendResponse(this.createSetTypings(req, discoverTypingsResult.cachedTypingPaths)); @@ -215,7 +193,7 @@ namespace ts.server.typingsInstaller { this.safeList = JsTyping.loadSafeList(this.installTypingHost, this.safeListPath); } - private processCacheLocation(cacheLocation: string) { + private processCacheLocation(cacheLocation: string, timestampsFilePath?: string) { if (this.log.isEnabled()) { this.log.writeLine(`Processing cache location '${cacheLocation}'`); } @@ -225,8 +203,7 @@ namespace ts.server.typingsInstaller { } return; } - const timestampJson = combinePaths(cacheLocation, timestampsFile); - this.typeDeclarationTimestamps = loadTypeDeclarationTimestampFile(timestampJson, this.installTypingHost, this.log); + this.typeDeclarationTimestamps = loadTypeDeclarationTimestampFile(timestampsFilePath || combinePaths(cacheLocation, timestampsFileName), this.installTypingHost, this.log); const packageJson = combinePaths(cacheLocation, "package.json"); if (this.log.isEnabled()) { this.log.writeLine(`Trying to find '${packageJson}'...`); @@ -321,7 +298,7 @@ namespace ts.server.typingsInstaller { } } - private installTypings(req: DiscoverTypings, cachePath: string, currentlyCachedTypings: string[], typingsToInstall: string[]) { + private installTypings(req: DiscoverTypings, cachePath: string, currentlyCachedTypings: string[], typingsToInstall: string[], timestampsFilePath: string) { if (this.log.isEnabled()) { this.log.writeLine(`Installing typings ${JSON.stringify(typingsToInstall)}`); } @@ -384,8 +361,7 @@ namespace ts.server.typingsInstaller { } const newFileContents: TypeDeclarationTimestampFile = { entries: this.typeDeclarationTimestamps }; - const timestampJson = combinePaths(cachePath, timestampsFile); - writeTypeDeclarationTimestampFile(timestampJson, newFileContents, this.installTypingHost, this.log); + writeTypeDeclarationTimestampFile(timestampsFilePath, newFileContents, this.installTypingHost, this.log); this.sendResponse(this.createSetTypings(req, currentlyCachedTypings.concat(installedTypingFiles))); } diff --git a/src/services/jsTyping.ts b/src/services/jsTyping.ts index f636de25313..335b36952f6 100644 --- a/src/services/jsTyping.ts +++ b/src/services/jsTyping.ts @@ -32,16 +32,8 @@ namespace ts.JsTyping { } export function isTypingExpired(typing: JsTyping.CachedTyping | undefined) { - const comparisonDate = new Date(); - const currentMonth = comparisonDate.getMonth(); - if (currentMonth) { - comparisonDate.setMonth(11); - comparisonDate.setFullYear(comparisonDate.getFullYear() - 1); - } - else { - comparisonDate.setMonth(currentMonth - 1); - } - return !typing || typing.timestamp < comparisonDate.getTime(); + const msPerMonth = 1000 * 60 * 60 * 24 * 30; // ms/second * second/minute * minutes/hour * hours/day * days/month + return !typing || typing.timestamp < Date.now() - msPerMonth; } /* @internal */