From ad31c96405847000f67a7ba30e803227dcf69179 Mon Sep 17 00:00:00 2001 From: Timothy Johnson Date: Fri, 27 Dec 2024 16:22:52 -0500 Subject: [PATCH] Port fix for duplicate config watcher events Signed-off-by: Timothy Johnson --- package.json | 2 +- packages/zowe-explorer-api/package.json | 2 +- packages/zowe-explorer/CHANGELOG.md | 1 + .../__mocks__/@zowe/imperative.ts | 4 + .../ZoweExplorerExtender.unit.test.ts | 2 +- .../__unit__/shared/init.unit.test.ts | 2 + .../__unit__/shared/utils.unit.test.ts | 30 ++++ .../__unit__/utils/ProfilesUtils.unit.test.ts | 149 +++++++----------- .../sample/src/utils/ProfilesUtils.i18n.json | 2 +- packages/zowe-explorer/src/Profiles.ts | 1 - .../zowe-explorer/src/ZoweExplorerExtender.ts | 2 +- packages/zowe-explorer/src/shared/init.ts | 47 +++--- packages/zowe-explorer/src/shared/utils.ts | 15 ++ .../zowe-explorer/src/utils/ProfilesUtils.ts | 94 ++++++----- yarn.lock | 126 +++++++-------- 15 files changed, 249 insertions(+), 230 deletions(-) diff --git a/package.json b/package.json index 303ee0aabf..d3653d6086 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "vscode": "^1.53.2" }, "dependencies": { - "@zowe/cli": "^7.29.7", + "@zowe/cli": "^7.29.8", "vscode-nls": "^4.1.2" }, "devDependencies": { diff --git a/packages/zowe-explorer-api/package.json b/packages/zowe-explorer-api/package.json index e922fc1ffe..6912d62301 100644 --- a/packages/zowe-explorer-api/package.json +++ b/packages/zowe-explorer-api/package.json @@ -22,7 +22,7 @@ }, "dependencies": { "@types/vscode": "^1.53.2", - "@zowe/cli": "^7.29.7", + "@zowe/cli": "^7.29.8", "@zowe/secrets-for-zowe-sdk": "^7.18.6", "mustache": "^4.2.0", "semver": "^7.5.3" diff --git a/packages/zowe-explorer/CHANGELOG.md b/packages/zowe-explorer/CHANGELOG.md index 8e9441547c..0455c00057 100644 --- a/packages/zowe-explorer/CHANGELOG.md +++ b/packages/zowe-explorer/CHANGELOG.md @@ -20,6 +20,7 @@ All notable changes to the "vscode-extension-for-zowe" extension will be documen - Fixed an issue where clicking on a file in the Unix System Services tree caused the tree to abruptly change focus to the selected item. [#2486](https://github.com/zowe/zowe-explorer-vscode/issues/2486) - Fixed an issue where binary USS files were not fetched using the "Pull from Mainframe" context menu option. [#3355](https://github.com/zowe/zowe-explorer-vscode/issues/3355) - Fixed an issue with Auto Save where a failed UNIX file or data set save operation caused an infinite loop of save requests. [#2406](https://github.com/zowe/zowe-explorer-vscode/issues/2406), [#2627](https://github.com/zowe/zowe-explorer-vscode/issues/2627) +- Fixed an issue where editing a team config file or updating credentials in OS vault could trigger multiple events for a single action. [#3296](https://github.com/zowe/zowe-explorer-vscode/pull/3296) ## `2.18.0` diff --git a/packages/zowe-explorer/__mocks__/@zowe/imperative.ts b/packages/zowe-explorer/__mocks__/@zowe/imperative.ts index b892c0cde8..67c75d9405 100644 --- a/packages/zowe-explorer/__mocks__/@zowe/imperative.ts +++ b/packages/zowe-explorer/__mocks__/@zowe/imperative.ts @@ -256,6 +256,10 @@ export class ProfileInfo { return; } + public profileManagerWillLoad(): boolean { + return true; + } + public addProfileTypeToSchema( profileType: string, typeInfo: { diff --git a/packages/zowe-explorer/__tests__/__unit__/ZoweExplorerExtender.unit.test.ts b/packages/zowe-explorer/__tests__/__unit__/ZoweExplorerExtender.unit.test.ts index d81f948e75..7dfc3b972a 100644 --- a/packages/zowe-explorer/__tests__/__unit__/ZoweExplorerExtender.unit.test.ts +++ b/packages/zowe-explorer/__tests__/__unit__/ZoweExplorerExtender.unit.test.ts @@ -242,7 +242,7 @@ describe("ZoweExplorerExtender unit tests", () => { const readProfilesFromDiskSpy = jest.fn(); const refreshProfilesQueueAddSpy = jest.spyOn((ZoweExplorerExtender as any).refreshProfilesQueue, "add"); - jest.spyOn(ProfilesUtils, "getProfileInfo").mockReturnValueOnce({ + jest.spyOn(ProfilesUtils, "setupProfileInfo").mockReturnValueOnce({ readProfilesFromDisk: readProfilesFromDiskSpy, } as any); await expect(blockMocks.instTest.initForZowe("USS", ["" as any])).resolves.not.toThrow(); diff --git a/packages/zowe-explorer/__tests__/__unit__/shared/init.unit.test.ts b/packages/zowe-explorer/__tests__/__unit__/shared/init.unit.test.ts index 85acd51746..7e5f12c9ca 100644 --- a/packages/zowe-explorer/__tests__/__unit__/shared/init.unit.test.ts +++ b/packages/zowe-explorer/__tests__/__unit__/shared/init.unit.test.ts @@ -28,6 +28,7 @@ import { ZoweSaveQueue } from "../../../src/abstract/ZoweSaveQueue"; import { ZoweExplorerApiRegister } from "../../../src/ZoweExplorerApiRegister"; import * as HistoryView from "../../../src/shared/HistoryView"; import * as certWizard from "../../../src/utils/CertificateWizard"; +import * as sharedUtils from "../../../src/shared/utils"; describe("Test src/shared/extension", () => { describe("registerCommonCommands", () => { @@ -326,6 +327,7 @@ describe("Test src/shared/extension", () => { Object.defineProperty(globals, "SAVED_PROFILE_CONTENTS", { value: "test", configurable: true }); jest.spyOn(vscode.workspace, "createFileSystemWatcher").mockReturnValue(watcher); jest.spyOn(ZoweExplorerApiRegister.getInstance().onProfilesUpdateEmitter, "fire").mockImplementation(mockEmitter); + jest.spyOn(sharedUtils, "debounce").mockImplementation((cb: any) => cb); }); afterAll(() => { diff --git a/packages/zowe-explorer/__tests__/__unit__/shared/utils.unit.test.ts b/packages/zowe-explorer/__tests__/__unit__/shared/utils.unit.test.ts index 3a86769159..4dedba82b3 100644 --- a/packages/zowe-explorer/__tests__/__unit__/shared/utils.unit.test.ts +++ b/packages/zowe-explorer/__tests__/__unit__/shared/utils.unit.test.ts @@ -1355,3 +1355,33 @@ describe("Shared utils unit tests - function initializeFileOpening", () => { expect(globalMocks.mockShowTextDocument).toBeCalledWith(globalMocks.mockTextDocument, { preview: false }); }); }); + +describe("Shared utils unit tests - function debounce", () => { + beforeAll(() => { + jest.useFakeTimers(); + }); + + afterAll(() => { + jest.useRealTimers(); + }); + + it("executes a function twice when time between calls is long", () => { + const mockEventHandler = jest.fn(); + const debouncedFn = sharedUtils.debounce(mockEventHandler, 100); + debouncedFn(); + jest.runAllTimers(); + debouncedFn(); + jest.runAllTimers(); + expect(mockEventHandler).toHaveBeenCalledTimes(2); + }); + + it("executes a function only once when time between calls is short", () => { + const mockEventHandler = jest.fn(); + const debouncedFn = sharedUtils.debounce(mockEventHandler, 100); + debouncedFn(); + jest.advanceTimersByTime(10); + debouncedFn(); + jest.runAllTimers(); + expect(mockEventHandler).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/zowe-explorer/__tests__/__unit__/utils/ProfilesUtils.unit.test.ts b/packages/zowe-explorer/__tests__/__unit__/utils/ProfilesUtils.unit.test.ts index 34d55863bb..f71de095e4 100644 --- a/packages/zowe-explorer/__tests__/__unit__/utils/ProfilesUtils.unit.test.ts +++ b/packages/zowe-explorer/__tests__/__unit__/utils/ProfilesUtils.unit.test.ts @@ -277,19 +277,20 @@ describe("ProfilesUtils unit tests", () => { }); describe("readConfigFromDisk", () => { - it("should readConfigFromDisk and log 'Not Available'", async () => { - Object.defineProperty(vscode.workspace, "workspaceFolders", { - value: [ - { - uri: { - fsPath: "./test", - }, + Object.defineProperty(vscode.workspace, "workspaceFolders", { + value: [ + { + uri: { + fsPath: "./test", }, - ], - configurable: true, - }); + }, + ], + configurable: true, + }); + + it("should readConfigFromDisk and find default profiles", async () => { const mockReadProfilesFromDisk = jest.fn(); - const profInfoSpy = jest.spyOn(profUtils.ProfilesUtils, "getProfileInfo").mockReturnValue({ + jest.spyOn(profUtils.ProfilesUtils, "setupProfileInfo").mockReturnValueOnce({ readProfilesFromDisk: mockReadProfilesFromDisk, usingTeamConfig: true, getTeamConfig: () => ({ @@ -309,66 +310,48 @@ describe("ProfilesUtils unit tests", () => { ], }), } as never); - Object.defineProperty(globals.LOG, "debug", { - value: jest.fn(), - configurable: true, - }); + const loggerSpy = jest.spyOn(ZoweLogger, "debug"); await expect(profUtils.ProfilesUtils.readConfigFromDisk()).resolves.not.toThrow(); expect(mockReadProfilesFromDisk).toHaveBeenCalledTimes(1); - profInfoSpy.mockRestore(); + expect(loggerSpy).toHaveBeenLastCalledWith(expect.stringContaining(`Path: test, Found with the following defaults: "test"`)); }); - it("should readConfigFromDisk and find with defaults", async () => { - Object.defineProperty(vscode.workspace, "workspaceFolders", { - value: [ - { - uri: { - fsPath: "./test", - }, - }, - ], - configurable: true, - }); + it("should readConfigFromDisk and log 'Not Available'", async () => { const mockReadProfilesFromDisk = jest.fn(); - const profInfoSpy = jest.spyOn(profUtils.ProfilesUtils, "getProfileInfo").mockReturnValue({ + jest.spyOn(profUtils.ProfilesUtils, "setupProfileInfo").mockResolvedValueOnce({ readProfilesFromDisk: mockReadProfilesFromDisk, usingTeamConfig: true, - getTeamConfig: () => [], + getTeamConfig: () => ({ + exists: true, + layers: [ + { + path: "test", + exists: false, + properties: {}, + }, + ], + }), } as never); - Object.defineProperty(globals.LOG, "debug", { - value: jest.fn(), - configurable: true, - }); + const loggerSpy = jest.spyOn(ZoweLogger, "debug"); await expect(profUtils.ProfilesUtils.readConfigFromDisk()).resolves.not.toThrow(); expect(mockReadProfilesFromDisk).toHaveBeenCalledTimes(1); - profInfoSpy.mockRestore(); + expect(loggerSpy).toHaveBeenLastCalledWith(expect.stringContaining("Path: test, Not available")); }); it("should keep Imperative error details if readConfigFromDisk fails", async () => { - Object.defineProperty(vscode.workspace, "workspaceFolders", { - value: [ - { - uri: { - fsPath: "./test", - }, - }, - ], - configurable: true, - }); const impErr = new zowe.imperative.ImperativeError({ msg: "Unexpected Imperative error" }); const mockReadProfilesFromDisk = jest.fn().mockRejectedValue(impErr); - const profInfoSpy = jest.spyOn(profUtils.ProfilesUtils, "getProfileInfo").mockReturnValue({ + jest.spyOn(profUtils.ProfilesUtils, "setupProfileInfo").mockResolvedValueOnce({ readProfilesFromDisk: mockReadProfilesFromDisk, usingTeamConfig: true, getTeamConfig: () => [], } as never); await expect(profUtils.ProfilesUtils.readConfigFromDisk()).rejects.toBe(impErr); expect(mockReadProfilesFromDisk).toHaveBeenCalledTimes(1); - profInfoSpy.mockRestore(); }); it("should warn the user when using team config with a missing schema", async () => { - const profInfoSpy = jest.spyOn(profUtils.ProfilesUtils, "getProfileInfo").mockReturnValueOnce({ + jest.spyOn(profUtils.ProfilesUtils, "setupProfileInfo").mockResolvedValueOnce({ readProfilesFromDisk: jest.fn(), usingTeamConfig: true, hasValidSchema: false, @@ -394,7 +377,6 @@ describe("ProfilesUtils unit tests", () => { expect(warnMsgSpy).toHaveBeenCalledWith( "No valid schema was found for the active team configuration. This may introduce issues with profiles in Zowe Explorer." ); - profInfoSpy.mockRestore(); }); }); @@ -736,14 +718,14 @@ describe("ProfilesUtils unit tests", () => { }); }); - describe("getProfilesInfo", () => { + describe("setupProfileInfo", () => { let isVSCodeCredentialPluginInstalledSpy: jest.SpyInstance; let getDirectValueSpy: jest.SpyInstance; let fetchRegisteredPluginsSpy: jest.SpyInstance; let getCredentialManagerOverrideSpy: jest.SpyInstance; let getCredentialManagerMapSpy: jest.SpyInstance; let setupCustomCredentialManagerSpy: jest.SpyInstance; - let readProfilesFromDiskSpy: jest.SpyInstance; + let profileManagerWillLoadSpy: jest.SpyInstance; let promptAndDisableCredentialManagementSpy: jest.SpyInstance; beforeEach(() => { @@ -756,7 +738,7 @@ describe("ProfilesUtils unit tests", () => { getCredentialManagerOverrideSpy = jest.spyOn(profUtils.ProfilesUtils, "getCredentialManagerOverride"); getCredentialManagerMapSpy = jest.spyOn(profUtils.ProfilesUtils, "getCredentialManagerMap"); setupCustomCredentialManagerSpy = jest.spyOn((profUtils as any).ProfilesUtils, "setupCustomCredentialManager"); - readProfilesFromDiskSpy = jest.spyOn(zowe.imperative.ProfileInfo.prototype, "readProfilesFromDisk"); + profileManagerWillLoadSpy = jest.spyOn(zowe.imperative.ProfileInfo.prototype, "profileManagerWillLoad"); promptAndDisableCredentialManagementSpy = jest.spyOn(profUtils.ProfilesUtils, "promptAndDisableCredentialManagement"); }); @@ -772,7 +754,7 @@ describe("ProfilesUtils unit tests", () => { credMgrZEName: "test", }); setupCustomCredentialManagerSpy.mockReturnValueOnce({}); - await expect(profUtils.ProfilesUtils.getProfileInfo(false)).resolves.toEqual({}); + await expect(profUtils.ProfilesUtils.setupProfileInfo(false)).resolves.toBeInstanceOf(zowe.imperative.ProfileInfo); expect(isVSCodeCredentialPluginInstalledSpy).toBeCalledTimes(1); }); @@ -788,57 +770,31 @@ describe("ProfilesUtils unit tests", () => { credMgrZEName: "test", }); setupCustomCredentialManagerSpy.mockReturnValueOnce({}); - await expect(profUtils.ProfilesUtils.getProfileInfo(false)).resolves.toEqual({}); + await expect(profUtils.ProfilesUtils.setupProfileInfo(false)).resolves.toBeInstanceOf(zowe.imperative.ProfileInfo); }); it("should retrieve the default credential manager if no custom credential manager is found", async () => { - getDirectValueSpy.mockReturnValueOnce(false); + getDirectValueSpy.mockReturnValueOnce(true).mockReturnValueOnce(false); getCredentialManagerOverrideSpy.mockReturnValue("@zowe/cli"); isVSCodeCredentialPluginInstalledSpy.mockReturnValueOnce(false); getDirectValueSpy.mockReturnValueOnce(true); getCredentialManagerMapSpy.mockReturnValueOnce(undefined); setupCustomCredentialManagerSpy.mockReturnValueOnce({}); - await expect(profUtils.ProfilesUtils.getProfileInfo(false)).resolves.toEqual({}); + await expect(profUtils.ProfilesUtils.setupProfileInfo(false)).resolves.toBeInstanceOf(zowe.imperative.ProfileInfo); }); it("should retrieve the default credential manager and prompt to disable credential management if environment not supported", async () => { - const expectedErrMsg = - // eslint-disable-next-line max-len - "Failed to load credential manager. This may be related to Zowe Explorer being unable to use the default credential manager in a browser based environment."; - getDirectValueSpy.mockReturnValueOnce(false); + getDirectValueSpy.mockReturnValueOnce(true).mockReturnValueOnce(false); getCredentialManagerOverrideSpy.mockReturnValue("@zowe/cli"); isVSCodeCredentialPluginInstalledSpy.mockReturnValueOnce(false); getDirectValueSpy.mockReturnValueOnce(true); getCredentialManagerMapSpy.mockReturnValueOnce(undefined); setupCustomCredentialManagerSpy.mockReturnValueOnce({}); - readProfilesFromDiskSpy.mockImplementation(() => { - const err = new zowe.imperative.ProfInfoErr({ - msg: expectedErrMsg, - }); - Object.defineProperty(err, "errorCode", { - value: zowe.imperative.ProfInfoErr.LOAD_CRED_MGR_FAILED, - configurable: true, - }); - throw err; - }); - await expect(profUtils.ProfilesUtils.getProfileInfo(false)).rejects.toThrow(expectedErrMsg); + profileManagerWillLoadSpy.mockReturnValueOnce(false); + promptAndDisableCredentialManagementSpy.mockResolvedValueOnce(undefined); + await expect(profUtils.ProfilesUtils.setupProfileInfo(false)).resolves.toBeInstanceOf(zowe.imperative.ProfileInfo); expect(promptAndDisableCredentialManagementSpy).toHaveBeenCalledTimes(1); }); - - it("should ignore error if it is not an instance of ProfInfoErr", async () => { - const expectedErrorMsg = "Another error unrelated to credential management"; - getDirectValueSpy.mockReturnValueOnce(false); - getCredentialManagerOverrideSpy.mockReturnValue("@zowe/cli"); - isVSCodeCredentialPluginInstalledSpy.mockReturnValueOnce(false); - getDirectValueSpy.mockReturnValueOnce(true); - getCredentialManagerMapSpy.mockReturnValueOnce(undefined); - setupCustomCredentialManagerSpy.mockReturnValueOnce({}); - readProfilesFromDiskSpy.mockImplementation(() => { - throw new Error(expectedErrorMsg); - }); - await expect(profUtils.ProfilesUtils.getProfileInfo(false)).resolves.not.toThrow(); - expect(promptAndDisableCredentialManagementSpy).toHaveBeenCalledTimes(0); - }); }); describe("isVSCodeCredentialPluginInstalled", () => { @@ -916,7 +872,7 @@ describe("ProfilesUtils unit tests", () => { jest.restoreAllMocks(); }); - it("should return the profileInfo object with the custom credential manager constructor", async () => { + it("should return the credential manager override with the custom credential manager constructor", async () => { const zoweLoggerTraceSpy = jest.spyOn(ZoweLogger, "trace"); const zoweLoggerInfoSpy = jest.spyOn(ZoweLogger, "info"); @@ -929,7 +885,7 @@ describe("ProfilesUtils unit tests", () => { credMgrPluginName: "test", credMgrZEName: "test", }) - ).resolves.toEqual({} as zowe.imperative.ProfileInfo); + ).resolves.toMatchObject({ service: "test" }); expect(zoweLoggerTraceSpy).toBeCalledTimes(2); expect(zoweLoggerInfoSpy).toBeCalledTimes(1); }); @@ -1079,13 +1035,20 @@ describe("ProfilesUtils unit tests", () => { }); describe("setupDefaultCredentialManager", () => { - it("calls readProfilesFromDisk with homeDir and projectDir", async () => { - const readProfilesFromDiskMock = jest.spyOn(zowe.imperative.ProfileInfo.prototype, "readProfilesFromDisk").mockImplementation(); + it("calls profileManagerWillLoad to load default credential manager", async () => { + const profileManagerWillLoadSpy = jest.spyOn(zowe.imperative.ProfileInfo.prototype, "profileManagerWillLoad"); await profUtils.ProfilesUtils.setupDefaultCredentialManager(); - expect(readProfilesFromDiskMock).toHaveBeenCalledWith({ - homeDir: zowe.getZoweDir(), - projectDir: vscode.workspace.workspaceFolders?.[0].uri.fsPath, - }); + expect(profileManagerWillLoadSpy).toHaveBeenCalled(); + }); + + it("prompts user to disable credential manager if default fails to load", async () => { + const profileManagerWillLoadSpy = jest + .spyOn(zowe.imperative.ProfileInfo.prototype, "profileManagerWillLoad") + .mockResolvedValueOnce(false); + const disableCredMgmtSpy = jest.spyOn(profUtils.ProfilesUtils, "promptAndDisableCredentialManagement").mockImplementation(); + await profUtils.ProfilesUtils.setupDefaultCredentialManager(); + expect(profileManagerWillLoadSpy).toHaveBeenCalled(); + expect(disableCredMgmtSpy).toHaveBeenCalled(); }); }); }); diff --git a/packages/zowe-explorer/i18n/sample/src/utils/ProfilesUtils.i18n.json b/packages/zowe-explorer/i18n/sample/src/utils/ProfilesUtils.i18n.json index 99e1b0bad5..3c674bbc9b 100644 --- a/packages/zowe-explorer/i18n/sample/src/utils/ProfilesUtils.i18n.json +++ b/packages/zowe-explorer/i18n/sample/src/utils/ProfilesUtils.i18n.json @@ -36,7 +36,7 @@ "writeOverridesFile.jsonParse.error": "Failed to parse JSON file {0}. Will try to re-create the file.", "writeOverridesFile.updateFile": "Updating imperative.json Credential Manager to {0}.\n{1}", "initializeZoweFolder.error": "Failed to initialize Zowe folder: {0}", - "initializeZoweProfiles.success": "Zowe Profiles initialized successfully.", + "initializeZoweProfiles.success": "Zowe profiles initialized successfully.", "initializeZoweTempFolder.success": "Zowe Temp folder initialized successfully.", "getProfile.notTreeItem": "Tree Item is not a Zowe Explorer item." } diff --git a/packages/zowe-explorer/src/Profiles.ts b/packages/zowe-explorer/src/Profiles.ts index 1b3058c31b..22e2121bff 100644 --- a/packages/zowe-explorer/src/Profiles.ts +++ b/packages/zowe-explorer/src/Profiles.ts @@ -57,7 +57,6 @@ export class Profiles extends ProfilesCache { await Profiles.loader.refresh(ZoweExplorerApiRegister.getInstance()); } catch (err) { ZoweLogger.error(err); - ZoweExplorerExtender.showZoweConfigError(err.message); } return Profiles.loader; } diff --git a/packages/zowe-explorer/src/ZoweExplorerExtender.ts b/packages/zowe-explorer/src/ZoweExplorerExtender.ts index 659b3f96e9..2bdf380140 100644 --- a/packages/zowe-explorer/src/ZoweExplorerExtender.ts +++ b/packages/zowe-explorer/src/ZoweExplorerExtender.ts @@ -175,7 +175,7 @@ export class ZoweExplorerExtender implements ZoweExplorerApi.IApiExplorerExtende let usingTeamConfig: boolean; let profileInfo: zowe.imperative.ProfileInfo; try { - profileInfo = await ProfilesUtils.getProfileInfo(globals.ISTHEIA); + profileInfo = await ProfilesUtils.setupProfileInfo(globals.ISTHEIA); await profileInfo.readProfilesFromDisk({ homeDir: zoweDir, projectDir }); usingTeamConfig = profileInfo.usingTeamConfig; } catch (error) { diff --git a/packages/zowe-explorer/src/shared/init.ts b/packages/zowe-explorer/src/shared/init.ts index e59de77dcb..3f5a9c73f8 100644 --- a/packages/zowe-explorer/src/shared/init.ts +++ b/packages/zowe-explorer/src/shared/init.ts @@ -34,6 +34,7 @@ import { USSTree } from "../uss/USSTree"; import { ZosJobsProvider } from "../job/ZosJobsProvider"; import { CertificateWizard } from "../utils/CertificateWizard"; import { ZosConsoleViewProvider } from "../zosconsole/ZosConsolePanel"; +import * as sharedUtils from "./utils"; // Set up localization nls.config({ @@ -243,26 +244,32 @@ export function watchConfigProfile(context: vscode.ExtensionContext): void { context.subscriptions.push(...watchers); watchers.forEach((watcher) => { - watcher.onDidCreate(() => { - ZoweLogger.info(localize("watchConfigProfile.create", "Team config file created, refreshing Zowe Explorer.")); - void refreshActions.refreshAll(); - ZoweExplorerApiRegister.getInstance().onProfilesUpdateEmitter.fire(EventTypes.CREATE); - }); - watcher.onDidDelete(() => { - ZoweLogger.info(localize("watchConfigProfile.delete", "Team config file deleted, refreshing Zowe Explorer.")); - void refreshActions.refreshAll(); - ZoweExplorerApiRegister.getInstance().onProfilesUpdateEmitter.fire(EventTypes.DELETE); - }); - watcher.onDidChange(async (uri: vscode.Uri) => { - ZoweLogger.info(localize("watchConfigProfile.update", "Team config file updated.")); - const newProfileContents = await vscode.workspace.fs.readFile(uri); - if (newProfileContents.toString() === globals.SAVED_PROFILE_CONTENTS.toString()) { - return; - } - globals.setSavedProfileContents(newProfileContents); - void refreshActions.refreshAll(); - ZoweExplorerApiRegister.getInstance().onProfilesUpdateEmitter.fire(EventTypes.UPDATE); - }); + watcher.onDidCreate( + sharedUtils.debounce(() => { + ZoweLogger.info(localize("watchConfigProfile.create", "Team config file created, refreshing Zowe Explorer.")); + void refreshActions.refreshAll(); + ZoweExplorerApiRegister.getInstance().onProfilesUpdateEmitter.fire(EventTypes.CREATE); + }, 100) // eslint-disable-line no-magic-numbers + ); + watcher.onDidDelete( + sharedUtils.debounce(() => { + ZoweLogger.info(localize("watchConfigProfile.delete", "Team config file deleted, refreshing Zowe Explorer.")); + void refreshActions.refreshAll(); + ZoweExplorerApiRegister.getInstance().onProfilesUpdateEmitter.fire(EventTypes.DELETE); + }, 100) // eslint-disable-line no-magic-numbers + ); + watcher.onDidChange( + sharedUtils.debounce(async (uri: vscode.Uri) => { + ZoweLogger.info(localize("watchConfigProfile.update", "Team config file updated.")); + const newProfileContents = await vscode.workspace.fs.readFile(uri); + if (newProfileContents.toString() === globals.SAVED_PROFILE_CONTENTS.toString()) { + return; + } + globals.setSavedProfileContents(newProfileContents); + void refreshActions.refreshAll(); + ZoweExplorerApiRegister.getInstance().onProfilesUpdateEmitter.fire(EventTypes.UPDATE); + }, 100) // eslint-disable-line no-magic-numbers + ); }); } diff --git a/packages/zowe-explorer/src/shared/utils.ts b/packages/zowe-explorer/src/shared/utils.ts index e1ba2a0ccf..c59efccee5 100644 --- a/packages/zowe-explorer/src/shared/utils.ts +++ b/packages/zowe-explorer/src/shared/utils.ts @@ -640,3 +640,18 @@ export async function initializeFileOpening( await vscode.commands.executeCommand("vscode.open", uriPath); } } + +/** + * Debounces an event handler to prevent duplicate triggers. + * @param callback Event handler callback + * @param delay Number of milliseconds to delay + */ +export function debounce void | Promise>(callback: T, delay: number): (...args: Parameters) => void { + let timeoutId: ReturnType; + return (...args: Parameters): void => { + if (timeoutId) { + clearTimeout(timeoutId); + } + timeoutId = setTimeout(() => void callback(...args), delay); + }; +} diff --git a/packages/zowe-explorer/src/utils/ProfilesUtils.ts b/packages/zowe-explorer/src/utils/ProfilesUtils.ts index 4a7dee995e..c9b9e80566 100644 --- a/packages/zowe-explorer/src/utils/ProfilesUtils.ts +++ b/packages/zowe-explorer/src/utils/ProfilesUtils.ts @@ -286,7 +286,9 @@ export class ProfilesUtils { * @param credentialManagerMap The map with associated names of the custom credential manager * @returns Promise the object of profileInfo using the custom credential manager */ - public static async setupCustomCredentialManager(credentialManagerMap: imperative.ICredentialManagerNameMap): Promise { + public static async setupCustomCredentialManager( + credentialManagerMap: imperative.ICredentialManagerNameMap + ): Promise { ZoweLogger.trace("ProfilesUtils.setupCustomCredentialManager called."); ZoweLogger.info( localize( @@ -301,12 +303,10 @@ export class ProfilesUtils { if (credentialManager) { Object.setPrototypeOf(credentialManager.prototype, imperative.AbstractCredentialManager.prototype); await ProfilesUtils.updateCredentialManagerSetting(credentialManagerMap.credMgrDisplayName); - return new imperative.ProfileInfo("zowe", { - credMgrOverride: { - Manager: credentialManager, - service: credentialManagerMap.credMgrDisplayName, - }, - }); + return { + Manager: credentialManager, + service: credentialManagerMap.credMgrDisplayName, + }; } } @@ -357,32 +357,21 @@ export class ProfilesUtils { * Use the default credential manager in Zowe Explorer and setup before use * @returns Promise the object of profileInfo using the default credential manager */ - public static async setupDefaultCredentialManager(): Promise { - try { - ZoweLogger.trace("ProfilesUtils.setupDefaultCredentialManager called."); - ZoweLogger.info( - localize( - "ProfilesUtils.setupDefaultCredentialManager.usingDefault", - "No custom credential managers found, using the default instead." - ) - ); - await ProfilesUtils.updateCredentialManagerSetting(globals.ZOWE_CLI_SCM); - const defaultCredentialManager = imperative.ProfileCredentials.defaultCredMgrWithKeytar(ProfilesCache.requireKeyring); - const profileInfo = new imperative.ProfileInfo("zowe", { - credMgrOverride: defaultCredentialManager, - }); - const workspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; - // Trigger initialize() function of credential manager to throw an error early if failed to load - await profileInfo.readProfilesFromDisk({ - homeDir: getZoweDir(), - projectDir: workspaceFolder ? getFullPath(workspaceFolder) : undefined, - }); - return profileInfo; - } catch (err) { - if (err instanceof imperative.ProfInfoErr && err.errorCode === imperative.ProfInfoErr.LOAD_CRED_MGR_FAILED) { - await ProfilesUtils.promptAndDisableCredentialManagement(); - } - // Ignore other types of errors since they will be handled later + public static async setupDefaultCredentialManager(): Promise { + ZoweLogger.trace("ProfilesUtils.setupDefaultCredentialManager called."); + ZoweLogger.info( + localize("ProfilesUtils.setupDefaultCredentialManager.usingDefault", "No custom credential managers found, using the default instead.") + ); + await ProfilesUtils.updateCredentialManagerSetting(globals.ZOWE_CLI_SCM); + const defaultCredentialManager = imperative.ProfileCredentials.defaultCredMgrWithKeytar(ProfilesCache.requireKeyring); + const profileInfo = new imperative.ProfileInfo("zowe", { + credMgrOverride: defaultCredentialManager, + }); + + if (await profileInfo.profileManagerWillLoad()) { + return defaultCredentialManager; + } else { + await ProfilesUtils.promptAndDisableCredentialManagement(); } } @@ -417,7 +406,7 @@ export class ProfilesUtils { await Gui.infoMessage(header, { items: [optionYes, optionDontAskAgain], vsCodeOpts: { modal: true, detail: message } }).then( async (selection) => { if (selection === optionYes) { - await this.updateCredentialManagerSetting(credentialManager.credMgrDisplayName); + await ProfilesUtils.updateCredentialManagerSetting(credentialManager.credMgrDisplayName); SettingsConfig.setDirectValue( globals.SETTINGS_CHECK_FOR_CUSTOM_CREDENTIAL_MANAGERS, false, @@ -477,36 +466,44 @@ export class ProfilesUtils { ); } - public static async getProfileInfo(envTheia: boolean): Promise { - ZoweLogger.trace("ProfilesUtils.getProfileInfo called."); + /** + * Creates an instance of ProfileInfo with the configured credential manager override. + * @returns An instance of `ProfileInfo`, or `undefined` if there was an error. + */ + public static async setupProfileInfo(_envTheia: boolean): Promise { + ZoweLogger.trace("ProfilesUtils.setupProfileInfo called."); const hasSecureCredentialManagerEnabled: boolean = SettingsConfig.getDirectValue(globals.SETTINGS_SECURE_CREDENTIALS_ENABLED); if (hasSecureCredentialManagerEnabled) { const shouldCheckForCustomCredentialManagers = SettingsConfig.getDirectValue(globals.SETTINGS_CHECK_FOR_CUSTOM_CREDENTIAL_MANAGERS); if (shouldCheckForCustomCredentialManagers) { - await this.fetchRegisteredPlugins(); + await ProfilesUtils.fetchRegisteredPlugins(); } - const credentialManagerOverride = this.getCredentialManagerOverride(); - const isVSCodeCredentialPluginInstalled = this.isVSCodeCredentialPluginInstalled(credentialManagerOverride); + const credentialManagerOverride = ProfilesUtils.getCredentialManagerOverride(); + const isVSCodeCredentialPluginInstalled = ProfilesUtils.isVSCodeCredentialPluginInstalled(credentialManagerOverride); const isCustomCredentialPluginDefined = credentialManagerOverride !== imperative.CredentialManagerOverride.DEFAULT_CRED_MGR_NAME; const credentialManagerMap = ProfilesUtils.getCredentialManagerMap(credentialManagerOverride); if (isCustomCredentialPluginDefined && !isVSCodeCredentialPluginInstalled && credentialManagerMap) { - await this.promptAndHandleMissingCredentialManager(credentialManagerMap); + await ProfilesUtils.promptAndHandleMissingCredentialManager(credentialManagerMap); } if (credentialManagerMap && isVSCodeCredentialPluginInstalled) { - return this.setupCustomCredentialManager(credentialManagerMap); + return new imperative.ProfileInfo("zowe", { + credMgrOverride: await ProfilesUtils.setupCustomCredentialManager(credentialManagerMap), + }); } } - return this.setupDefaultCredentialManager(); + return new imperative.ProfileInfo("zowe", { + credMgrOverride: hasSecureCredentialManagerEnabled ? await ProfilesUtils.setupDefaultCredentialManager() : undefined, + }); } public static async readConfigFromDisk(warnForMissingSchema?: boolean): Promise { ZoweLogger.trace("ProfilesUtils.readConfigFromDisk called."); let rootPath: string; - const mProfileInfo = await ProfilesUtils.getProfileInfo(globals.ISTHEIA); + const mProfileInfo = await ProfilesUtils.setupProfileInfo(globals.ISTHEIA); if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders[0]) { rootPath = vscode.workspace.workspaceFolders[0].uri.fsPath; await mProfileInfo.readProfilesFromDisk({ homeDir: getZoweDir(), projectDir: getFullPath(rootPath) }); @@ -527,13 +524,13 @@ export class ProfilesUtils { const layers = mProfileInfo.getTeamConfig().layers || []; const layerSummary = layers.map( (config: imperative.IConfigLayer) => - `Path: ${config.path}: ${ + `Path: ${config.path}, ${ config.exists - ? "Found, with the following defaults:" + JSON.stringify(config.properties?.defaults || "Undefined default") + ? "Found with the following defaults: " + JSON.stringify(config.properties?.defaults || "Undefined default") : "Not available" } ` ); - ZoweLogger.debug(`Summary of team configuration files considered for Zowe Explorer: ${JSON.stringify(layerSummary)}`); + ZoweLogger.debug(["Summary of team configuration files considered for Zowe Explorer:", ...layerSummary].join("\t\n")); } } @@ -701,9 +698,10 @@ export class ProfilesUtils { try { await ProfilesUtils.readConfigFromDisk(true); - ZoweLogger.info(localize("initializeZoweProfiles.success", "Zowe Profiles initialized successfully.")); + ZoweLogger.info(localize("initializeZoweProfiles.success", "Zowe profiles initialized successfully.")); } catch (err) { - if (err instanceof imperative.ImperativeError) { + // JSON parsing errors in team config files will have suppressDump=true + if (err instanceof imperative.ImperativeError && !err.mDetails.suppressDump) { await errorHandling(err, undefined, err.mDetails.causeErrors); } else { ZoweLogger.error(err); diff --git a/yarn.lock b/yarn.lock index 2de31ba288..368db2acbc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3012,22 +3012,22 @@ resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== -"@zowe/cli@^7.29.7": - version "7.29.7" - resolved "https://registry.npmjs.org/@zowe/cli/-/cli-7.29.7.tgz#820d6952e8e791bec8a034ebcefa6c5b4cdcd6d0" - integrity sha512-9mgYlIDhjqaw5NOGsjMoWXhOe2AGhVLga+UhgfzYxdZb1+I70UWPpc4mgxQcX9cJiI3fRD/Fsc6rkKMq7K/DrQ== - dependencies: - "@zowe/core-for-zowe-sdk" "7.29.7" - "@zowe/imperative" "5.27.4" - "@zowe/provisioning-for-zowe-sdk" "7.29.7" - "@zowe/zos-console-for-zowe-sdk" "7.29.7" - "@zowe/zos-files-for-zowe-sdk" "7.29.7" - "@zowe/zos-jobs-for-zowe-sdk" "7.29.7" - "@zowe/zos-logs-for-zowe-sdk" "7.29.7" - "@zowe/zos-tso-for-zowe-sdk" "7.29.7" - "@zowe/zos-uss-for-zowe-sdk" "7.29.7" - "@zowe/zos-workflows-for-zowe-sdk" "7.29.7" - "@zowe/zosmf-for-zowe-sdk" "7.29.7" +"@zowe/cli@^7.29.8": + version "7.29.8" + resolved "https://registry.npmjs.org/@zowe/cli/-/cli-7.29.8.tgz#c3cb50c7c83b26ceda11c13ab285539563cfba39" + integrity sha512-EjYiFKkQ0xcnBIMm59IJkQHlYfh8UJhT6tkZaNzl8gFu8ESqJCfY4psb86nYc5ua0au5BwURMj02wAawYaoYaw== + dependencies: + "@zowe/core-for-zowe-sdk" "7.29.8" + "@zowe/imperative" "5.27.5" + "@zowe/provisioning-for-zowe-sdk" "7.29.8" + "@zowe/zos-console-for-zowe-sdk" "7.29.8" + "@zowe/zos-files-for-zowe-sdk" "7.29.8" + "@zowe/zos-jobs-for-zowe-sdk" "7.29.8" + "@zowe/zos-logs-for-zowe-sdk" "7.29.8" + "@zowe/zos-tso-for-zowe-sdk" "7.29.8" + "@zowe/zos-uss-for-zowe-sdk" "7.29.8" + "@zowe/zos-workflows-for-zowe-sdk" "7.29.8" + "@zowe/zosmf-for-zowe-sdk" "7.29.8" find-process "1.4.7" get-stream "6.0.1" lodash "4.17.21" @@ -3036,18 +3036,18 @@ optionalDependencies: "@zowe/secrets-for-zowe-sdk" "7.18.6" -"@zowe/core-for-zowe-sdk@7.29.7": - version "7.29.7" - resolved "https://registry.npmjs.org/@zowe/core-for-zowe-sdk/-/core-for-zowe-sdk-7.29.7.tgz#80822ceffccf8d8caaa80d4a95942eba3c9c11ab" - integrity sha512-QR1vhYzLcQz8bwswjuyHBxcbeekS55jx+CAx9vMXKDbw/9BV/S1Rj9mn6QA64zBw6ZJ5H3lZJkRcpWUfdfTyKw== +"@zowe/core-for-zowe-sdk@7.29.8": + version "7.29.8" + resolved "https://registry.npmjs.org/@zowe/core-for-zowe-sdk/-/core-for-zowe-sdk-7.29.8.tgz#6fc22c6c85e8cc51a6969654907b9d14f272544d" + integrity sha512-6BYYFiQJlJIs5OUR3KzdMtgRMeqSSYBfaIT0Ztzvk5+bWQ7Y6B5150amnMMIK+r1zZZMMs7vCWjI1D803Z4hZw== dependencies: comment-json "4.1.1" string-width "4.2.3" -"@zowe/imperative@5.27.4": - version "5.27.4" - resolved "https://registry.npmjs.org/@zowe/imperative/-/imperative-5.27.4.tgz#2e7872590ac062e705291d33ba6942efaadd9c2b" - integrity sha512-gwxr5U+y6tcypOIDAV1nhTYKqnyq5SvDJaKWbPPHkBb9TgcIy/HiqIH9UACOUBmVPWdCxJeJN4J9BvrYOlWSJg== +"@zowe/imperative@5.27.5": + version "5.27.5" + resolved "https://registry.npmjs.org/@zowe/imperative/-/imperative-5.27.5.tgz#958ac8c97d2524c1d011b2d5b37f6ce6d0e3ee80" + integrity sha512-D9e1uZCEM3USTfHMXetmirL6lynw7vfxwjsMWzxgMjsjDdD+xjN+kJFVK7N0Cub0UbxmBvWPn5ceEk3Cg4Bd9w== dependencies: "@types/yargs" "13.0.4" chalk "2.4.2" @@ -3088,10 +3088,10 @@ yamljs "0.3.0" yargs "15.3.1" -"@zowe/provisioning-for-zowe-sdk@7.29.7": - version "7.29.7" - resolved "https://registry.npmjs.org/@zowe/provisioning-for-zowe-sdk/-/provisioning-for-zowe-sdk-7.29.7.tgz#46cc5f150216d6507b2cea42f185166b98eff934" - integrity sha512-VnMrxewkeEulqyBUYlO8Ga4j546i1tV7hv7/7M8nthZIV1Wv12oUzZi25I5MFibm8utvM7v2SYTKMPtOWqPM5A== +"@zowe/provisioning-for-zowe-sdk@7.29.8": + version "7.29.8" + resolved "https://registry.npmjs.org/@zowe/provisioning-for-zowe-sdk/-/provisioning-for-zowe-sdk-7.29.8.tgz#4afc964e6e06594755d82f55d70e60badbb50b09" + integrity sha512-s+/NC1CjIQk9ke5IfzDhafLlUzLv9l6jML5umr1YRD+CkVFVDXNQz61jF0tEMnArRFrQJteKrY5wl5i3CzIGDw== dependencies: js-yaml "4.1.0" @@ -3100,15 +3100,15 @@ resolved "https://registry.npmjs.org/@zowe/secrets-for-zowe-sdk/-/secrets-for-zowe-sdk-7.18.6.tgz#6b854b344babb291c26d19d82633099a46e08452" integrity sha512-YyS1NoXddb147mBQpu5/dTfo1gdwGa/xdg85U8KCngA+RHCmNct3n2rbK3tHx9C9H6rlgjeS+Mrux5Q+PHJUgQ== -"@zowe/zos-console-for-zowe-sdk@7.29.7": - version "7.29.7" - resolved "https://registry.npmjs.org/@zowe/zos-console-for-zowe-sdk/-/zos-console-for-zowe-sdk-7.29.7.tgz#7d5c8ce415eef9b2ca76f0bc1feab08c70c39c9a" - integrity sha512-+XqEaZHTkw+c+RzlaHOeuzecMTvWqjj6fHAQ/bFj/Yh+Ziqpzw/QvZdCaOEb/aqBTcaxLYxFSOE4apuEjtTsKA== +"@zowe/zos-console-for-zowe-sdk@7.29.8": + version "7.29.8" + resolved "https://registry.npmjs.org/@zowe/zos-console-for-zowe-sdk/-/zos-console-for-zowe-sdk-7.29.8.tgz#5ecc484ccf2b28a38d2229c70a32fd1a2fefd025" + integrity sha512-pY9dLV+Oi0IYUic+GpM/xz1iv8gUEZkXxIwJDqHtgMRpK4cdiDUcOZJUYAKqOcUm1zrcwsl/rPn/z3jIwiRqFQ== -"@zowe/zos-files-for-zowe-sdk@7.29.7": - version "7.29.7" - resolved "https://registry.npmjs.org/@zowe/zos-files-for-zowe-sdk/-/zos-files-for-zowe-sdk-7.29.7.tgz#febc4ddb9510dc38e77fc5a96ec818e491931d27" - integrity sha512-VdhCRv6bzQeoiIQDk4fCTZO1mNLDWUZ+26P06QsRAON2IZ2sZYFKsHafVa6stqKz+YUEEaTJpG41EthfRp+H1A== +"@zowe/zos-files-for-zowe-sdk@7.29.8": + version "7.29.8" + resolved "https://registry.npmjs.org/@zowe/zos-files-for-zowe-sdk/-/zos-files-for-zowe-sdk-7.29.8.tgz#aeb7800eb2c91a44ad5a30aee4dc9bcca2df7fd2" + integrity sha512-XpIQXbzbfJPW3Z3jRbJ7DTvjZXeBgiqtbtBUyq5GB178XDz5+5rLqs6AiEcujVxop7NonT1lUcqjNHl72wddYw== dependencies: minimatch "5.0.1" @@ -3119,43 +3119,43 @@ dependencies: zos-node-accessor "1.0.16" -"@zowe/zos-jobs-for-zowe-sdk@7.29.7": - version "7.29.7" - resolved "https://registry.npmjs.org/@zowe/zos-jobs-for-zowe-sdk/-/zos-jobs-for-zowe-sdk-7.29.7.tgz#4d116650538d3fa142c439aaa37c9b2ed634a81e" - integrity sha512-MDy4BiLjYaD9v62YUMfqgfGDgoLPORhHvG8y3D++J4D4lAFTbFCt5yASmc7G4K+ElQGkn+JGzNlRx0yUdHQ03Q== +"@zowe/zos-jobs-for-zowe-sdk@7.29.8": + version "7.29.8" + resolved "https://registry.npmjs.org/@zowe/zos-jobs-for-zowe-sdk/-/zos-jobs-for-zowe-sdk-7.29.8.tgz#05c404b818335fd1f80bdd7aef1e45602a9b919f" + integrity sha512-vgEZK3STpSRgFwP5CLXJCK7fF0mbtGkLBqSYmtxGMJwacQSyu7GBTWWWSjeqmKhEIfcJrb0RKDItJGBblWshvA== dependencies: - "@zowe/zos-files-for-zowe-sdk" "7.29.7" + "@zowe/zos-files-for-zowe-sdk" "7.29.8" -"@zowe/zos-logs-for-zowe-sdk@7.29.7": - version "7.29.7" - resolved "https://registry.npmjs.org/@zowe/zos-logs-for-zowe-sdk/-/zos-logs-for-zowe-sdk-7.29.7.tgz#8f92ab44c6927ff9d9dc075e7fb84d39c4b3e1e2" - integrity sha512-8dz/17TeWhbP3gG7Gmk+kr1aQW7PHW4ETCBAZmvuAYceuLXCH39LbZBWo5QXI0liX7GaEN9WZDRcMVyq2ghn6A== +"@zowe/zos-logs-for-zowe-sdk@7.29.8": + version "7.29.8" + resolved "https://registry.npmjs.org/@zowe/zos-logs-for-zowe-sdk/-/zos-logs-for-zowe-sdk-7.29.8.tgz#b8b429c6032df222f306460b68403633fc140f0f" + integrity sha512-BprM+dtyNjxwDywEJs3SfTRv5Xg03tgLekc2r4c2Unj+05L4raBB3qvJceTd9itlos0qBZa0SEVZwMp3hLT6gQ== -"@zowe/zos-tso-for-zowe-sdk@7.29.7": - version "7.29.7" - resolved "https://registry.npmjs.org/@zowe/zos-tso-for-zowe-sdk/-/zos-tso-for-zowe-sdk-7.29.7.tgz#d6bc3bf0c79c930af9d116217c5fdb4a20e7208a" - integrity sha512-Xs1o/0Z4CUrks7J9o4VQtrBwwyD9qWOYE9LiC0fIbQ94V2+IR9jkKn6yuOsOfzLnKcv3TW/fGyAvJF3NdrQiOw== +"@zowe/zos-tso-for-zowe-sdk@7.29.8": + version "7.29.8" + resolved "https://registry.npmjs.org/@zowe/zos-tso-for-zowe-sdk/-/zos-tso-for-zowe-sdk-7.29.8.tgz#2389861857fde720cacfea720acabae4dc075ff0" + integrity sha512-+VYF+B6S/Waks3XLzylSRcYrCytcEjWOAeC2QW+npTI5izRnmwdAcCaIClMLNfMXibJA73soblhraU+qzKHSEw== dependencies: - "@zowe/zosmf-for-zowe-sdk" "7.29.7" + "@zowe/zosmf-for-zowe-sdk" "7.29.8" -"@zowe/zos-uss-for-zowe-sdk@7.29.7": - version "7.29.7" - resolved "https://registry.npmjs.org/@zowe/zos-uss-for-zowe-sdk/-/zos-uss-for-zowe-sdk-7.29.7.tgz#0d19c9c4a044c27081d2a8c08aa68f318b0f00b6" - integrity sha512-TNuK1xK2tnFVz58vay2cFvwPKi9fowcofi8yQfy+JnrDbKioYTvfUAPUdLLpMtPtjRV39qf3dGaxmnez5oMpIQ== +"@zowe/zos-uss-for-zowe-sdk@7.29.8": + version "7.29.8" + resolved "https://registry.npmjs.org/@zowe/zos-uss-for-zowe-sdk/-/zos-uss-for-zowe-sdk-7.29.8.tgz#2680469c6db1eb15671e64763f032eb1ad3e111a" + integrity sha512-AfBgQ6UWWnH81v79FtxuREByejGIwuVXMUxHN9hhf2U73TmWciap/CBpSfFN16ePVAbmx1UEc1qJoBE928x3Fg== dependencies: ssh2 "1.15.0" -"@zowe/zos-workflows-for-zowe-sdk@7.29.7": - version "7.29.7" - resolved "https://registry.npmjs.org/@zowe/zos-workflows-for-zowe-sdk/-/zos-workflows-for-zowe-sdk-7.29.7.tgz#32645f4348103229575e384ed85d35fd4c3ad805" - integrity sha512-BOYmpdcflx2RVQ099tQrtqqjfIzOsM+2M4b8dKiH5t5UsL4FwlHzSXXtfpYQTqgLZ5gJl+n5tzbBFpAFRPEMUQ== +"@zowe/zos-workflows-for-zowe-sdk@7.29.8": + version "7.29.8" + resolved "https://registry.npmjs.org/@zowe/zos-workflows-for-zowe-sdk/-/zos-workflows-for-zowe-sdk-7.29.8.tgz#4bbc85c0f72281a4921a8a013b079572dba2885e" + integrity sha512-eqJdSdV8DwA54jrgen/2BEltkGCqhmX7kkOVCq5cA/aYPYYYDvzTsN4R96Uy/lbkw/xHr7Q183SOUS2UnKGZbQ== dependencies: - "@zowe/zos-files-for-zowe-sdk" "7.29.7" + "@zowe/zos-files-for-zowe-sdk" "7.29.8" -"@zowe/zosmf-for-zowe-sdk@7.29.7": - version "7.29.7" - resolved "https://registry.npmjs.org/@zowe/zosmf-for-zowe-sdk/-/zosmf-for-zowe-sdk-7.29.7.tgz#cd6628b89a8b2b30472e89f61eb062112a1ccaf1" - integrity sha512-9JAI72LsFmBelYmzOSQCHhOJywKCqdAqJy/LMQ1IgSllrVRLOAh08VY8nUvQGR+BarG+EticdqOvItuAdjdvIA== +"@zowe/zosmf-for-zowe-sdk@7.29.8": + version "7.29.8" + resolved "https://registry.npmjs.org/@zowe/zosmf-for-zowe-sdk/-/zosmf-for-zowe-sdk-7.29.8.tgz#9659efb212bcfd0f873b9656f16af997850e8407" + integrity sha512-rCqka/lopFaGvxCaY02ZiqxtrVhAgbxSOHdhETJm5DuwZ+Hp5Ilieq+SOhuMYt6AXgu391LO6PCUsnSxkboANw== abbrev@1: version "1.1.1"