Skip to content

Commit 87a3b42

Browse files
authored
Handle empty package.json files (#39937)
1 parent e9f82e4 commit 87a3b42

File tree

4 files changed

+28
-16
lines changed

4 files changed

+28
-16
lines changed

src/server/editorServices.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3774,12 +3774,10 @@ namespace ts.server {
37743774
/*@internal*/
37753775
getPackageJsonsVisibleToFile(fileName: string, rootDir?: string): readonly PackageJsonInfo[] {
37763776
const packageJsonCache = this.packageJsonCache;
3777-
const watchPackageJsonFile = this.watchPackageJsonFile.bind(this);
3778-
const toPath = this.toPath.bind(this);
3779-
const rootPath = rootDir && toPath(rootDir);
3780-
const filePath = toPath(fileName);
3777+
const rootPath = rootDir && this.toPath(rootDir);
3778+
const filePath = this.toPath(fileName);
37813779
const result: PackageJsonInfo[] = [];
3782-
forEachAncestorDirectory(getDirectoryPath(filePath), function processDirectory(directory): boolean | undefined {
3780+
const processDirectory = (directory: Path): boolean | undefined => {
37833781
switch (packageJsonCache.directoryHasPackageJson(directory)) {
37843782
// Sync and check same directory again
37853783
case Ternary.Maybe:
@@ -3788,15 +3786,16 @@ namespace ts.server {
37883786
// Check package.json
37893787
case Ternary.True:
37903788
const packageJsonFileName = combinePaths(directory, "package.json");
3791-
watchPackageJsonFile(packageJsonFileName);
3789+
this.watchPackageJsonFile(packageJsonFileName as Path);
37923790
const info = packageJsonCache.getInDirectory(directory);
37933791
if (info) result.push(info);
37943792
}
3795-
if (rootPath && rootPath === toPath(directory)) {
3793+
if (rootPath && rootPath === this.toPath(directory)) {
37963794
return true;
37973795
}
3798-
});
3796+
};
37993797

3798+
forEachAncestorDirectory(getDirectoryPath(filePath), processDirectory);
38003799
return result;
38013800
}
38023801

src/server/packageJsonCache.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,9 @@ namespace ts.server {
4242
};
4343

4444
function addOrUpdate(fileName: Path) {
45-
const packageJsonInfo = createPackageJsonInfo(fileName, host.host);
46-
if (packageJsonInfo !== undefined) {
47-
packageJsons.set(fileName, packageJsonInfo);
48-
directoriesWithoutPackageJson.delete(getDirectoryPath(fileName));
49-
}
45+
const packageJsonInfo = Debug.checkDefined(createPackageJsonInfo(fileName, host.host));
46+
packageJsons.set(fileName, packageJsonInfo);
47+
directoriesWithoutPackageJson.delete(getDirectoryPath(fileName));
5048
}
5149

5250
function directoryHasPackageJson(directory: Path) {

src/services/utilities.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2739,9 +2739,7 @@ namespace ts {
27392739

27402740
type PackageJsonRaw = Record<typeof dependencyKeys[number], Record<string, string> | undefined>;
27412741
const dependencyKeys = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"] as const;
2742-
const stringContent = host.readFile(fileName);
2743-
if (!stringContent) return undefined;
2744-
2742+
const stringContent = host.readFile(fileName) || "";
27452743
const content = tryParseJson(stringContent) as PackageJsonRaw | undefined;
27462744
const info: Pick<PackageJsonInfo, typeof dependencyKeys[number]> = {};
27472745
if (content) {

src/testRunner/unittests/tsserver/packageJsonInfo.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,23 @@ namespace ts.projectSystem {
8282
assert.ok(packageJsonInfo2.peerDependencies);
8383
assert.ok(packageJsonInfo2.optionalDependencies);
8484
});
85+
86+
it("handles empty package.json", () => {
87+
const packageJsonContent = "";
88+
const { projectService, host } = setup([tsConfig, { path: packageJson.path, content: packageJsonContent }]);
89+
projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path);
90+
const packageJsonInfo = projectService.packageJsonCache.getInDirectory("/" as Path)!;
91+
assert.isFalse(packageJsonInfo.parseable);
92+
93+
host.writeFile(packageJson.path, packageJson.content);
94+
projectService.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path);
95+
const packageJsonInfo2 = projectService.packageJsonCache.getInDirectory("/" as Path)!;
96+
assert.ok(packageJsonInfo2);
97+
assert.ok(packageJsonInfo2.dependencies);
98+
assert.ok(packageJsonInfo2.devDependencies);
99+
assert.ok(packageJsonInfo2.peerDependencies);
100+
assert.ok(packageJsonInfo2.optionalDependencies);
101+
});
85102
});
86103

87104
function setup(files: readonly File[] = [tsConfig, packageJson]) {

0 commit comments

Comments
 (0)