TypeScript/src/server/typingsInstaller/typingsInstaller.ts

97 lines
4 KiB
TypeScript
Raw Normal View History

/// <reference path="../../services/JsTyping.ts"/>
/// <reference path="../types.d.ts"/>
2016-08-12 20:04:43 +02:00
namespace ts.server.typingsInstaller {
const DefaultTsdSettings = JSON.stringify({
version: "v4",
repo: "DefinitelyTyped/DefinitelyTyped",
ref: "master",
path: "typings"
}, /*replacer*/undefined, /*space*/4);
export abstract class TypingsInstaller {
private isTsdInstalled: boolean;
private missingTypings: Map<string> = {};
init() {
this.isTsdInstalled = this.isPackageInstalled("tsd");
if (!this.isTsdInstalled) {
this.isTsdInstalled = this.installPackage("tsd");
}
}
install(req: InstallTypingsRequest) {
if (!this.isTsdInstalled) {
return;
}
const discoverTypingsResult = JsTyping.discoverTypings(
this.getInstallTypingHost(),
req.fileNames,
req.projectRootPath,
req.safeListPath,
req.packageNameToTypingLocation,
req.typingOptions,
req.compilerOptions);
// respond with whatever cached typings we have now
this.sendResponse(this.createResponse(req, discoverTypingsResult.cachedTypingPaths));
2016-08-12 21:14:25 +02:00
// start watching files
2016-08-12 20:04:43 +02:00
this.watchFiles(discoverTypingsResult.filesToWatch);
2016-08-12 21:14:25 +02:00
// install typings and
this.installTypings(req, discoverTypingsResult.cachedTypingPaths, discoverTypingsResult.newTypingNames);
2016-08-12 20:04:43 +02:00
}
2016-08-12 21:14:25 +02:00
private installTypings(req: InstallTypingsRequest, currentlyCachedTypings: string[], typingsToInstall: string[]) {
typingsToInstall = filter(typingsToInstall, x => !hasProperty(this.missingTypings, x));
if (typingsToInstall.length === 0) {
return;
}
2016-08-12 20:04:43 +02:00
// TODO: install typings and send response when they are ready
const host = this.getInstallTypingHost();
const tsdPath = combinePaths(req.cachePath, "tsd.json");
if (!host.fileExists(tsdPath)) {
2016-08-13 08:04:17 +02:00
this.ensureDirectoryExists(req.cachePath, host);
2016-08-12 20:04:43 +02:00
host.writeFile(tsdPath, DefaultTsdSettings);
}
2016-08-12 21:14:25 +02:00
this.runTsd(req.cachePath, typingsToInstall, installedTypings => {
2016-08-12 21:14:25 +02:00
// TODO: record new missing package names
// TODO: watch project directory
installedTypings = installedTypings.map(x => getNormalizedAbsolutePath(x, req.cachePath));
2016-08-12 21:14:25 +02:00
this.sendResponse(this.createResponse(req, currentlyCachedTypings.concat(installedTypings)));
});
2016-08-12 20:04:43 +02:00
}
2016-08-13 08:04:17 +02:00
private ensureDirectoryExists(directory: string, host: InstallTypingHost): void {
const directoryName = getDirectoryPath(directory);
if (!host.directoryExists(directoryName)) {
this.ensureDirectoryExists(directoryName, host);
}
if (!host.directoryExists(directory)) {
host.createDirectory(directory);
}
}
2016-08-12 20:04:43 +02:00
private watchFiles(files: string[]) {
// TODO: start watching files
}
private createResponse(request: InstallTypingsRequest, typings: string[]) {
return {
projectName: request.projectName,
typingOptions: request.typingOptions,
compilerOptions: request.compilerOptions,
typings
};
}
protected abstract isPackageInstalled(packageName: string): boolean;
protected abstract installPackage(packageName: string): boolean;
protected abstract getInstallTypingHost(): InstallTypingHost;
protected abstract sendResponse(response: InstallTypingsResponse): void;
2016-08-12 21:14:25 +02:00
protected abstract runTsd(cachePath: string, typingsToInstall: string[], postInstallAction: (installedTypings: string[]) => void): void;
2016-08-12 20:04:43 +02:00
}
}