diff --git a/src/server/typingsInstaller/nodeTypingsInstaller.ts b/src/server/typingsInstaller/nodeTypingsInstaller.ts
index b9b5c7a40a..4e123fb360 100644
--- a/src/server/typingsInstaller/nodeTypingsInstaller.ts
+++ b/src/server/typingsInstaller/nodeTypingsInstaller.ts
@@ -3,9 +3,11 @@
namespace ts.server.typingsInstaller {
export class NodeTypingsInstaller extends TypingsInstaller {
private execSync: { (command: string, options: { stdio: "ignore" }): any };
+ private exec: { (command: string, options: {}, callback?: (error: Error, stdout: string, stderr: string) => void): any };
constructor() {
super();
this.execSync = require("child_process").execSync;
+ this.exec = require("child_process").exec;
}
init() {
@@ -35,13 +37,31 @@ namespace ts.server.typingsInstaller {
}
}
- protected getTypingResolutionHost() {
+ protected getInstallTypingHost() {
return sys;
}
protected sendResponse(response: InstallTypingsResponse) {
process.send(response);
}
+
+ protected runTsd(cachePath: string, typingsToInstall: string[], postInstallAction: (installedTypings: string[]) => void): void {
+ this.exec(`tsd install ${typingsToInstall.join(" ")} -ros`, {}, (err, stdout, stderr) => {
+ const i = stdout.indexOf("running install");
+ if (i < 0) {
+ return;
+ }
+ const installedTypings: string[] = [];
+
+ const expr = /^\s*-\s*(\S+)\s*$/gm;
+ expr.lastIndex = i;
+ let match: RegExpExecArray;
+ while (match = expr.exec(stdout)) {
+ installedTypings.push(match[1]);
+ }
+ postInstallAction(installedTypings);
+ })
+ }
}
const installer = new NodeTypingsInstaller();
diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts
index 4d1e49d233..7910e4363e 100644
--- a/src/server/typingsInstaller/typingsInstaller.ts
+++ b/src/server/typingsInstaller/typingsInstaller.ts
@@ -1,8 +1,6 @@
///
///
-
-
namespace ts.server.typingsInstaller {
const DefaultTsdSettings = JSON.stringify({
@@ -40,18 +38,30 @@ namespace ts.server.typingsInstaller {
// respond with whatever cached typings we have now
this.sendResponse(this.createResponse(req, discoverTypingsResult.cachedTypingPaths));
+ // start watching files
this.watchFiles(discoverTypingsResult.filesToWatch);
- this.installTypings(req, discoverTypingsResult.newTypingNames);
+ // install typings and
+ this.installTypings(req, discoverTypingsResult.cachedTypingPaths, discoverTypingsResult.newTypingNames);
}
- private installTypings(req: InstallTypingsRequest, typingsToInstall: string[]) {
+ private installTypings(req: InstallTypingsRequest, currentlyCachedTypings: string[], typingsToInstall: string[]) {
+ typingsToInstall = filter(typingsToInstall, x => !hasProperty(this.missingTypings, x));
+ if (typingsToInstall.length === 0) {
+ return;
+ }
+
// TODO: install typings and send response when they are ready
- const existingTypings = typingsToInstall.fi
const host = this.getInstallTypingHost();
const tsdPath = combinePaths(req.cachePath, "tsd.json");
if (!host.fileExists(tsdPath)) {
host.writeFile(tsdPath, DefaultTsdSettings);
}
+
+ this.runTsd(tsdPath, typingsToInstall, installedTypings => {
+ // TODO: record new missing package names
+ // TODO: watch project directory
+ this.sendResponse(this.createResponse(req, currentlyCachedTypings.concat(installedTypings)));
+ });
}
private watchFiles(files: string[]) {
@@ -71,5 +81,6 @@ namespace ts.server.typingsInstaller {
protected abstract installPackage(packageName: string): boolean;
protected abstract getInstallTypingHost(): InstallTypingHost;
protected abstract sendResponse(response: InstallTypingsResponse): void;
+ protected abstract runTsd(cachePath: string, typingsToInstall: string[], postInstallAction: (installedTypings: string[]) => void): void;
}
}
\ No newline at end of file