Skip to content

Commit ed6fcd4

Browse files
feat: Added an action to update dependencies
It will help if the user has "missed" the notification bubble for some reason. This way, the balloon can be easily redisplayed and help you with `npm install`.
1 parent 301d093 commit ed6fcd4

File tree

4 files changed

+69
-13
lines changed

4 files changed

+69
-13
lines changed

locales/bundle.l10n.jsonc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"No fix available yet.": "", // The flaw is not yet known to be resolved in a future release.
3535
"If possible, downgrade to version {0}.": "", // But it is possible to downgrade to a version where the flaw does not exist.
3636
"Details": "", // Link where you can learn more about the flaw.
37+
"Start installing the package": "", // Forces the display of the notification suggesting to update the package.
3738

3839
// DocumentDecoration.ts related.
3940
"Install pending": "", // The package was never installed, but the version entered by the user is the latest available.

locales/bundle.l10n.pt-br.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"No fix available yet.": "Ainda não há uma correção disponível.",
2626
"If possible, downgrade to version {0}.": "Se possível, realize um downgrade para a versão {0}.",
2727
"Details": "Detalhes",
28+
"Start installing the package": "Iniciar a instalação da dependência",
2829

2930
"Install pending": "Instalação pendente",
3031
"Update available:": "Atualização disponível:",

src/CodeAction.ts

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,43 @@ export class PackageJsonCodeActionProvider implements CodeActionProvider {
2323
document: TextDocument,
2424
range: Range
2525
): Promise<CodeAction[]> {
26+
const diagnosticsAll = languages.getDiagnostics(document.uri)
27+
2628
// Get all diagnostics from this extension.
27-
const diagnostics = languages
28-
.getDiagnostics(document.uri)
29-
.filter(
30-
(diagnostic) =>
31-
typeof diagnostic.code === "object" &&
32-
diagnostic.code.value === DIAGNOSTIC_ACTION &&
33-
(!PackageRelatedDiagnostic.is(diagnostic) || diagnostic.isSelectable)
34-
) as PackageRelatedDiagnostic[]
29+
const diagnostics = diagnosticsAll.filter(
30+
(diagnostic) =>
31+
typeof diagnostic.code === "object" &&
32+
diagnostic.code.value === DIAGNOSTIC_ACTION &&
33+
(!PackageRelatedDiagnostic.is(diagnostic) || diagnostic.isSelectable)
34+
) as PackageRelatedDiagnostic[]
3535

3636
// Checks if an CodeAction comes through a diagnostic.
3737
const diagnosticsSelected = diagnostics.filter(
3838
(diagnostic) => diagnostic.range.intersection(range) !== undefined
3939
)
4040

41+
// Checks if there are any packages waiting to be installed.
42+
let requiresInstall = false
43+
44+
for (const diagnostic of diagnosticsAll) {
45+
if (
46+
PackageRelatedDiagnostic.is(diagnostic) &&
47+
(await diagnostic.packageRelated.requiresInstallCommand())
48+
) {
49+
requiresInstall = true
50+
break
51+
}
52+
}
53+
4154
if (!diagnosticsSelected.length) {
55+
if (requiresInstall) {
56+
return Promise.all([this.createInstallAction(document)])
57+
}
58+
4259
return Promise.resolve([])
4360
}
4461

45-
const diagnosticsPromises = []
62+
const diagnosticsPromises: Promise<CodeAction>[] = []
4663

4764
let diagnosticsSelectedFiltered = diagnosticsSelected
4865

@@ -144,6 +161,10 @@ export class PackageJsonCodeActionProvider implements CodeActionProvider {
144161
}
145162
}
146163

164+
if (requiresInstall) {
165+
diagnosticsPromises.push(this.createInstallAction(document))
166+
}
167+
147168
return Promise.all(diagnosticsPromises)
148169
}
149170

@@ -225,6 +246,23 @@ export class PackageJsonCodeActionProvider implements CodeActionProvider {
225246
return action
226247
}
227248

249+
private async createInstallAction(
250+
document: TextDocument
251+
): Promise<CodeAction> {
252+
const action = new CodeAction(
253+
l10n.t("Start installing the package"),
254+
CodeActionKind.QuickFix
255+
)
256+
257+
action.command = {
258+
arguments: [document],
259+
command: COMMAND_INSTALL_REQUEST,
260+
title: "update",
261+
}
262+
263+
return action
264+
}
265+
228266
private async updatePackageVersion(
229267
action: CodeAction,
230268
document: TextDocument,

src/extension.test.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,14 +297,26 @@ describe("code actions", () => {
297297
it("no package selected", async () => {
298298
const { actions } = await vscodeSimulator({
299299
packageJson: { dependencies: { "npm-outdated": "^1.0.1" } },
300-
packagesInstalled: { "npm-outdated": "1.0.0" },
300+
packagesInstalled: { "npm-outdated": "1.0.1" },
301301
packagesRepository: { "npm-outdated": ["1.0.0", "1.0.1"] },
302302
selectFirsts: 0,
303303
})
304304

305305
expect(actions).toHaveLength(0)
306306
})
307307

308+
it("no package selected, awaiting for installing packages", async () => {
309+
const { actions } = await vscodeSimulator({
310+
packageJson: { dependencies: { "npm-outdated": "^1.0.1" } },
311+
packagesInstalled: { "npm-outdated": "1.0.0" },
312+
packagesRepository: { "npm-outdated": ["1.0.0", "1.0.1"] },
313+
selectFirsts: 0,
314+
})
315+
316+
expect(actions[0]?.title).toBe("Start installing the package")
317+
expect(actions).toHaveLength(1)
318+
})
319+
308320
it("selected a specific package", async () => {
309321
const { actions } = await vscodeSimulator({
310322
packageJson: { dependencies: { "npm-outdated": "^1.0.0" } },
@@ -392,27 +404,31 @@ describe("code actions", () => {
392404
expect(actions).toHaveLength(2)
393405
})
394406

395-
it("selected all two packages", async () => {
407+
it("selected all two packages, with waiting for install another", async () => {
396408
const { actions } = await vscodeSimulator({
397409
packageJson: {
398410
dependencies: {
399411
"@types/jest": "^1.0.0",
412+
"node-fetch": "^1.0.1",
400413
"npm-outdated": "^1.0.0",
401414
},
402415
},
403416
packagesInstalled: {
404417
"@types/jest": "1.0.0",
418+
"node-fetch": "1.0.0",
405419
"npm-outdated": "1.0.0",
406420
},
407421
packagesRepository: {
408422
"@types/jest": ["1.0.0", "1.0.1"],
423+
"node-fetch": ["1.0.0", "1.0.1"],
409424
"npm-outdated": ["1.0.0", "1.0.1"],
410425
},
411-
selectFirsts: 2,
426+
selectFirsts: 3,
412427
})
413428

414429
expect(actions[0]?.title).toBe("Update 2 selected packages")
415-
expect(actions).toHaveLength(1)
430+
expect(actions[1]?.title).toBe("Start installing the package")
431+
expect(actions).toHaveLength(2)
416432
})
417433

418434
it("selected all two packages, but one is major update (protection enabled)", async () => {

0 commit comments

Comments
 (0)