Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Jakefile.js
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ task("generate-spec", [specMd]);
// Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory
desc("Makes a new LKG out of the built js files");
task("LKG", ["clean", "release", "local"].concat(libraryTargets), function () {
var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile].concat(libraryTargets);
var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile].concat(libraryTargets);
var missingFiles = expectedFiles.filter(function (f) {
return !fs.existsSync(f);
});
Expand Down
92 changes: 92 additions & 0 deletions src/harness/unittests/typingsInstaller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -627,5 +627,97 @@ namespace ts.projectSystem {
checkProjectActualFiles(p1, [lodashJs.path, commanderJs.path, file3.path, commander.path, jquery.path, lodash.path, cordova.path]);
checkProjectActualFiles(p2, [file3.path, grunt.path, gulp.path ]);
});

it("configured projects discover from node_modules", () => {
const app = {
path: "/app.js",
content: ""
};
const jsconfig = {
path: "/jsconfig.json",
content: JSON.stringify({})
};
const jquery = {
path: "/node_modules/jquery/index.js",
content: ""
};
const jqueryPackage = {
path: "/node_modules/jquery/package.json",
content: JSON.stringify({ name: "jquery" })
};
const jqueryDTS = {
path: "/tmp/node_modules/@types/jquery/index.d.ts",
content: ""
};
const host = createServerHost([app, jsconfig, jquery, jqueryPackage]);
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation: "/tmp" });
}
runCommand(requestKind: TI.RequestKind, requestId: number, command: string, cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
const installedTypings = ["@types/jquery"];
const typingFiles = [jqueryDTS];
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
}
})();

const projectService = createProjectService(host, { useSingleInferredProject: true, typingsInstaller: installer });
projectService.openClientFile(app.path);

checkNumberOfProjects(projectService, { configuredProjects: 1 });
const p = projectService.configuredProjects[0];
checkProjectActualFiles(p, [app.path]);

installer.installAll([TI.NpmViewRequest], [TI.NpmInstallRequest]);

checkNumberOfProjects(projectService, { configuredProjects: 1 });
checkProjectActualFiles(p, [app.path, jqueryDTS.path]);
});

it("configured projects discover from bower.josn", () => {
const app = {
path: "/app.js",
content: ""
};
const jsconfig = {
path: "/jsconfig.json",
content: JSON.stringify({})
};
const bowerJson = {
path: "/bower.json",
content: JSON.stringify({
"dependencies": {
"jquery": "^3.1.0"
}
})
};
const jqueryDTS = {
path: "/tmp/node_modules/@types/jquery/index.d.ts",
content: ""
};
const host = createServerHost([app, jsconfig, bowerJson]);
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation: "/tmp" });
}
runCommand(requestKind: TI.RequestKind, requestId: number, command: string, cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
const installedTypings = ["@types/jquery"];
const typingFiles = [jqueryDTS];
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
}
})();

const projectService = createProjectService(host, { useSingleInferredProject: true, typingsInstaller: installer });
projectService.openClientFile(app.path);

checkNumberOfProjects(projectService, { configuredProjects: 1 });
const p = projectService.configuredProjects[0];
checkProjectActualFiles(p, [app.path]);

installer.installAll([TI.NpmViewRequest], [TI.NpmInstallRequest]);

checkNumberOfProjects(projectService, { configuredProjects: 1 });
checkProjectActualFiles(p, [app.path, jqueryDTS.path]);
});
});
}
12 changes: 11 additions & 1 deletion src/server/typingsInstaller/nodeTypingsInstaller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace ts.server.typingsInstaller {
const path: {
join(...parts: string[]): string;
dirname(path: string): string;
basename(path: string, extension?: string): string;
} = require("path");

class FileLog implements Log {
Expand All @@ -23,6 +24,15 @@ namespace ts.server.typingsInstaller {
}
}

function getNPMLocation(processName: string) {
if (path.basename(processName).indexOf("node") == 0) {
return `"${path.join(path.dirname(process.argv[0]), "npm")}"`;
}
else {
return "npm";
}
}

export class NodeTypingsInstaller extends TypingsInstaller {
private readonly exec: { (command: string, options: { cwd: string }, callback?: (error: Error, stdout: string, stderr: string) => void): any };

Expand All @@ -31,7 +41,7 @@ namespace ts.server.typingsInstaller {
constructor(globalTypingsCacheLocation: string, throttleLimit: number, log: Log) {
super(
globalTypingsCacheLocation,
/*npmPath*/ `"${path.join(path.dirname(process.argv[0]), "npm")}"`,
/*npmPath*/ getNPMLocation(process.argv[0]),
toPath("typingSafeList.json", __dirname, createGetCanonicalFileName(sys.useCaseSensitiveFileNames)),
throttleLimit,
log);
Expand Down
2 changes: 1 addition & 1 deletion src/server/typingsInstaller/typingsInstaller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ namespace ts.server.typingsInstaller {
if (this.installTypingHost.fileExists(packageJson)) {
const npmConfig = <NpmConfig>JSON.parse(this.installTypingHost.readFile(packageJson));
if (this.log.isEnabled()) {
this.log.writeLine(`Loaded content of '${npmConfig}': ${JSON.stringify(npmConfig)}`);
this.log.writeLine(`Loaded content of '${packageJson}': ${JSON.stringify(npmConfig)}`);
}
if (npmConfig.devDependencies) {
for (const key in npmConfig.devDependencies) {
Expand Down
2 changes: 1 addition & 1 deletion src/server/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace ts.server {
function getProjectRootPath(project: Project): Path {
switch (project.projectKind) {
case ProjectKind.Configured:
return <Path>project.getProjectName();
return <Path>getDirectoryPath(project.getProjectName());
case ProjectKind.Inferred:
// TODO: fixme
return <Path>"";
Expand Down
2 changes: 1 addition & 1 deletion src/services/jsTyping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ namespace ts.JsTyping {
}

const typingNames: string[] = [];
const fileNames = host.readDirectory(nodeModulesPath, ["*.json"], /*excludes*/ undefined, /*includes*/ undefined, /*depth*/ 2);
const fileNames = host.readDirectory(nodeModulesPath, [".json"], /*excludes*/ undefined, /*includes*/ undefined, /*depth*/ 2);
for (const fileName of fileNames) {
const normalizedFileName = normalizePath(fileName);
if (getBaseFileName(normalizedFileName) !== "package.json") {
Expand Down