Skip to content

Commit b504a1e

Browse files
authored
Handle lock file 3 version when caching the typings ensuring we can reuse already installed packages (#61730)
1 parent 81c9518 commit b504a1e

File tree

4 files changed

+1074
-4
lines changed

4 files changed

+1074
-4
lines changed

src/testRunner/unittests/tsserver/typingsInstaller.ts

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,6 +1372,113 @@ describe("unittests:: tsserver:: typingsInstaller:: General functionality", () =
13721372
host.runPendingInstalls();
13731373
baselineTsserverLogs("typingsInstaller", "non expired cache entry", session);
13741374
});
1375+
1376+
it("expired cache entry (inferred project, should install typings) lockFile3", () => {
1377+
const file1 = {
1378+
path: "/home/src/projects/project/app.js",
1379+
content: "",
1380+
};
1381+
const packageJson = {
1382+
path: "/home/src/projects/project/package.json",
1383+
content: jsonToReadableText({
1384+
name: "test",
1385+
dependencies: {
1386+
jquery: "^3.1.0",
1387+
},
1388+
}),
1389+
};
1390+
const jquery = {
1391+
path: getPathForTypeScriptTypingInstallerCacheTest("node_modules/@types/jquery/index.d.ts"),
1392+
content: "declare const $: { x: number }",
1393+
};
1394+
const cacheConfig = {
1395+
path: getPathForTypeScriptTypingInstallerCacheTest("package.json"),
1396+
content: jsonToReadableText({
1397+
dependencies: {
1398+
"types-registry": "^0.1.317",
1399+
},
1400+
devDependencies: {
1401+
"@types/jquery": "^1.0.0",
1402+
},
1403+
}),
1404+
};
1405+
const cacheLockConfig = {
1406+
path: getPathForTypeScriptTypingInstallerCacheTest("package-lock.json"),
1407+
content: jsonToReadableText({
1408+
packages: {
1409+
"node_modules/@types/jquery": {
1410+
version: "1.0.0",
1411+
},
1412+
},
1413+
}),
1414+
};
1415+
const host = TestServerHost.createServerHost(
1416+
[file1, packageJson, jquery, cacheConfig, cacheLockConfig],
1417+
{ typingsInstallerTypesRegistry: "jquery" },
1418+
);
1419+
const session = new TestSession({
1420+
host,
1421+
useSingleInferredProject: true,
1422+
installAction: [jquery],
1423+
});
1424+
openFilesForSession([file1], session);
1425+
host.runPendingInstalls();
1426+
host.runQueuedTimeoutCallbacks();
1427+
baselineTsserverLogs("typingsInstaller", "expired cache entry lockFile3", session);
1428+
});
1429+
1430+
it("non-expired cache entry (inferred project, should not install typings) lockFile3", () => {
1431+
const file1 = {
1432+
path: "/home/src/projects/project/app.js",
1433+
content: "",
1434+
};
1435+
const packageJson = {
1436+
path: "/home/src/projects/project/package.json",
1437+
content: jsonToReadableText({
1438+
name: "test",
1439+
dependencies: {
1440+
jquery: "^3.1.0",
1441+
},
1442+
}),
1443+
};
1444+
const cacheConfig = {
1445+
path: getPathForTypeScriptTypingInstallerCacheTest("package.json"),
1446+
content: jsonToReadableText({
1447+
dependencies: {
1448+
"types-registry": "^0.1.317",
1449+
},
1450+
devDependencies: {
1451+
"@types/jquery": "^1.3.0",
1452+
},
1453+
}),
1454+
};
1455+
const cacheLockConfig = {
1456+
path: getPathForTypeScriptTypingInstallerCacheTest("package-lock.json"),
1457+
content: jsonToReadableText({
1458+
packages: {
1459+
"node_modules/@types/jquery": {
1460+
version: "1.3.0",
1461+
},
1462+
},
1463+
}),
1464+
};
1465+
const jquery = {
1466+
path: getPathForTypeScriptTypingInstallerCacheTest("node_modules/@types/jquery/index.d.ts"),
1467+
content: "declare const $: { x: number }",
1468+
};
1469+
const host = TestServerHost.createServerHost(
1470+
[file1, packageJson, cacheConfig, cacheLockConfig, jquery],
1471+
{ typingsInstallerTypesRegistry: "jquery" },
1472+
);
1473+
const session = new TestSession({
1474+
host,
1475+
useSingleInferredProject: true,
1476+
installAction: true,
1477+
});
1478+
openFilesForSession([file1], session);
1479+
host.runPendingInstalls();
1480+
baselineTsserverLogs("typingsInstaller", "non expired cache entry lockFile3", session);
1481+
});
13751482
});
13761483

13771484
describe("unittests:: tsserver:: typingsInstaller:: Validate package name:", () => {

src/typingsInstallerCore/typingsInstaller.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ interface NpmConfig {
4646
}
4747

4848
interface NpmLock {
49-
dependencies: { [packageName: string]: { version: string; }; };
49+
dependencies?: { [packageName: string]: { version: string; }; };
50+
packages?: {
51+
[nodeModulesAtTypesPackage: string]: { version: string; };
52+
};
5053
}
5154

5255
export interface Log {
@@ -304,9 +307,13 @@ export abstract class TypingsInstaller {
304307
this.log.writeLine(`Loaded content of '${packageJson}':${stringifyIndented(npmConfig)}`);
305308
this.log.writeLine(`Loaded content of '${packageLockJson}':${stringifyIndented(npmLock)}`);
306309
}
307-
if (npmConfig.devDependencies && npmLock.dependencies) {
310+
// Packages is present in lock file 3 vs lockfile 2 has dependencies field for already installed types package
311+
if (npmConfig.devDependencies && (npmLock.packages || npmLock.dependencies)) {
308312
for (const key in npmConfig.devDependencies) {
309-
if (!hasProperty(npmLock.dependencies, key)) {
313+
if (
314+
(npmLock.packages && !hasProperty(npmLock.packages, `node_modules/${key}`)) ||
315+
(npmLock.dependencies && !hasProperty(npmLock.dependencies, key))
316+
) {
310317
// if package in package.json but not package-lock.json, skip adding to cache so it is reinstalled on next use
311318
continue;
312319
}
@@ -333,7 +340,8 @@ export abstract class TypingsInstaller {
333340
if (this.log.isEnabled()) {
334341
this.log.writeLine(`Adding entry into typings cache: '${packageName}' => '${typingFile}'`);
335342
}
336-
const info = getProperty(npmLock.dependencies, key);
343+
const info = npmLock.packages && getProperty(npmLock.packages, `node_modules/${key}`) ||
344+
getProperty(npmLock.dependencies!, key);
337345
const version = info && info.version;
338346
if (!version) {
339347
continue;

0 commit comments

Comments
 (0)