From 7a46f29e646dd148143c0cf247ef4b2b0c54a94d Mon Sep 17 00:00:00 2001 From: Joshua Feingold Date: Mon, 28 Oct 2024 11:34:20 -0500 Subject: [PATCH 01/35] FIX @W-17014756@ Smoke tests can be invoked manually. --- .github/workflows/daily-smoke-tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/daily-smoke-tests.yml b/.github/workflows/daily-smoke-tests.yml index cb534e345..9a0f0099d 100644 --- a/.github/workflows/daily-smoke-tests.yml +++ b/.github/workflows/daily-smoke-tests.yml @@ -12,4 +12,3 @@ jobs: uses: ./.github/workflows/run-tests.yml with: node-matrix: "[{version: 'lts/*', artifact: 'lts'}, {version: 'latest', artifact: 'latest'}]" - java-matrix: "['11']" From ee09e28efe843538546e0d517eba0d4a5340260d Mon Sep 17 00:00:00 2001 From: Joshua Feingold Date: Wed, 30 Oct 2024 14:49:54 -0500 Subject: [PATCH 02/35] CHANGE @W-17052870@ Polished config output --- src/lib/actions/ConfigAction.ts | 5 +++- src/lib/viewers/ActionSummaryViewer.ts | 4 +--- .../no-outfile-created.txt.goldfile | 2 -- test/lib/actions/ConfigAction.test.ts | 24 ++++++++++++++++++- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/lib/actions/ConfigAction.ts b/src/lib/actions/ConfigAction.ts index e588334ae..c997b5031 100644 --- a/src/lib/actions/ConfigAction.ts +++ b/src/lib/actions/ConfigAction.ts @@ -121,10 +121,13 @@ export class ConfigAction { }; const configModel: ConfigModel = this.dependencies.modelGenerator(relevantEngines, userConfigContext, defaultConfigContext); - this.dependencies.viewer.view(configModel); const fileWritten: boolean = this.dependencies.writer ? await this.dependencies.writer.write(configModel) : false; + if (!fileWritten) { + this.dependencies.viewer.view(configModel); + } + this.dependencies.actionSummaryViewer.view(logFileWriter.getLogDestination(), fileWritten ? input['output-file'] : undefined); return Promise.resolve(); } diff --git a/src/lib/viewers/ActionSummaryViewer.ts b/src/lib/viewers/ActionSummaryViewer.ts index 0754696d2..59377b028 100644 --- a/src/lib/viewers/ActionSummaryViewer.ts +++ b/src/lib/viewers/ActionSummaryViewer.ts @@ -34,10 +34,8 @@ export class ConfigActionSummaryViewer extends AbstractActionSummaryViewer { if (outfile) { this.displayOutfile(outfile); - } else { - this.display.displayLog(getMessage(BundleName.ActionSummaryViewer, 'config-action.no-outfiles')); + this.displayLineSeparator(); } - this.displayLineSeparator(); this.displayLogFileInfo(logFile); } diff --git a/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/action-summaries/no-outfile-created.txt.goldfile b/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/action-summaries/no-outfile-created.txt.goldfile index 3bcdbe5f2..86522fd7c 100644 --- a/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/action-summaries/no-outfile-created.txt.goldfile +++ b/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/action-summaries/no-outfile-created.txt.goldfile @@ -1,5 +1,3 @@ === Summary -No output file was specified. - Additional log information written to: \ No newline at end of file diff --git a/test/lib/actions/ConfigAction.test.ts b/test/lib/actions/ConfigAction.test.ts index 10edee0ab..84c536c08 100644 --- a/test/lib/actions/ConfigAction.test.ts +++ b/test/lib/actions/ConfigAction.test.ts @@ -13,6 +13,7 @@ import {ConfigStyledYamlViewer} from '../../../src/lib/viewers/ConfigViewer'; import {ConfigActionSummaryViewer} from '../../../src/lib/viewers/ActionSummaryViewer'; import {SpyConfigWriter} from '../../stubs/SpyConfigWriter'; +import {SpyConfigViewer} from '../../stubs/SpyConfigViewer'; import {DisplayEventType, SpyDisplay} from '../../stubs/SpyDisplay'; const PATH_TO_FIXTURES = path.join(__dirname, '..', '..', 'fixtures'); @@ -403,17 +404,38 @@ describe('ConfigAction tests', () => { }; }); - it('If a ConfigWriter is provided, it is used along with the ConfigViewer', async () => { + it('If a file is created, then the ConfigViewer is unused', async () => { // ==== SETUP ==== // We need to add a Writer to the dependencies. const spyWriter = new SpyConfigWriter(); dependencies.writer = spyWriter; + // Replace the viewer with a Spy. + const spyViewer = new SpyConfigViewer(); + dependencies.viewer = spyViewer; // ==== TESTED BEHAVIOR ==== await runActionAndGetDisplayedConfig(dependencies, ['all']); // ==== ASSERTIONS ==== expect(spyWriter.getCallHistory()).toHaveLength(1); + expect(spyViewer.getCallHistory()).toHaveLength(0); + }); + + it('If a file is specified by not created, then the ConfigViewer is used', async () => { + // ==== SETUP ==== + // We need to add a Writer to the dependencies. + const spyWriter = new SpyConfigWriter(false); + dependencies.writer = spyWriter; + // Replace the viewer with a Spy. + const spyViewer = new SpyConfigViewer(); + dependencies.viewer = spyViewer; + + // ==== TESTED BEHAVIOR ==== + await runActionAndGetDisplayedConfig(dependencies, ['all']); + + // ==== ASSERTIONS ==== + expect(spyWriter.getCallHistory()).toHaveLength(1); + expect(spyViewer.getCallHistory()).toHaveLength(1); }); }); From cbcf4a6356f68a88f77716acbb3dd5ad6e6858e3 Mon Sep 17 00:00:00 2001 From: Joshua Feingold Date: Wed, 30 Oct 2024 15:42:22 -0500 Subject: [PATCH 03/35] CHANGE @W-17052870@ Removed orphaned message --- messages/action-summary-viewer.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/messages/action-summary-viewer.md b/messages/action-summary-viewer.md index 2fe72f796..c29822674 100644 --- a/messages/action-summary-viewer.md +++ b/messages/action-summary-viewer.md @@ -6,10 +6,6 @@ Summary Additional log information written to: -# config-action.no-outfiles - -No output file was specified. - # config-action.outfile-location Configuration written to: From f755f6742a861b8a726b0035b005c99f5da41cb2 Mon Sep 17 00:00:00 2001 From: Joshua Feingold Date: Fri, 1 Nov 2024 10:49:19 -0500 Subject: [PATCH 04/35] CHANGE @W-17052953@ Polished output for rules command. --- messages/action-summary-viewer.md | 12 ++++ messages/progress-event-listener.md | 2 +- src/commands/code-analyzer/rules.ts | 2 + src/lib/actions/RulesAction.ts | 3 + src/lib/listeners/ProgressEventListener.ts | 3 +- src/lib/viewers/ActionSummaryViewer.ts | 33 +++++++++++ .../action-summaries/no-rules.txt.goldfile | 6 ++ .../action-summaries/some-rules.txt.goldfile | 8 +++ test/lib/actions/RulesAction.test.ts | 55 +++++++++++++++++++ .../listeners/ProgressEventListener.test.ts | 6 +- 10 files changed, 124 insertions(+), 6 deletions(-) create mode 100644 test/fixtures/comparison-files/lib/actions/RulesAction.test.ts/action-summaries/no-rules.txt.goldfile create mode 100644 test/fixtures/comparison-files/lib/actions/RulesAction.test.ts/action-summaries/some-rules.txt.goldfile diff --git a/messages/action-summary-viewer.md b/messages/action-summary-viewer.md index c29822674..bf7fa37ce 100644 --- a/messages/action-summary-viewer.md +++ b/messages/action-summary-viewer.md @@ -9,3 +9,15 @@ Additional log information written to: # config-action.outfile-location Configuration written to: + +# rules-action.found-no-rules + +Found 0 rules. + +# rules-action.rules-total + +Found %d rule(s) from %d engine(s): + +# rules-action.rules-item + +%d %s rule(s) found. diff --git a/messages/progress-event-listener.md b/messages/progress-event-listener.md index e8f383b91..b98fa90d0 100644 --- a/messages/progress-event-listener.md +++ b/messages/progress-event-listener.md @@ -5,7 +5,7 @@ Selecting rules Eligible engines: %s; Completion: %d%; Elapsed time: %ds # selection-spinner.finished-status -done. Selected rules from %s. +done. # execution-spinner.action Executing rules diff --git a/src/commands/code-analyzer/rules.ts b/src/commands/code-analyzer/rules.ts index 6181b38a5..398a24b80 100644 --- a/src/commands/code-analyzer/rules.ts +++ b/src/commands/code-analyzer/rules.ts @@ -3,6 +3,7 @@ import {View} from '../../Constants'; import {CodeAnalyzerConfigFactoryImpl} from '../../lib/factories/CodeAnalyzerConfigFactory'; import {EnginePluginsFactoryImpl} from '../../lib/factories/EnginePluginsFactory'; import {RuleDetailDisplayer, RuleTableDisplayer} from '../../lib/viewers/RuleViewer'; +import {RulesActionSummaryViewer} from '../../lib/viewers/ActionSummaryViewer'; import {RulesAction, RulesDependencies} from '../../lib/actions/RulesAction'; import {BundleName, getMessage, getMessages} from '../../lib/messages'; import {Displayable, UxDisplay} from '../../lib/Display'; @@ -67,6 +68,7 @@ export default class RulesCommand extends SfCommand implements Displayable pluginsFactory: new EnginePluginsFactoryImpl(), logEventListeners: [new LogEventDisplayer(uxDisplay)], progressListeners: [new RuleSelectionProgressSpinner(uxDisplay)], + actionSummaryViewer: new RulesActionSummaryViewer(uxDisplay), viewer: view === View.TABLE ? new RuleTableDisplayer(uxDisplay) : new RuleDetailDisplayer(uxDisplay) }; } diff --git a/src/lib/actions/RulesAction.ts b/src/lib/actions/RulesAction.ts index d4a934316..dd6cab0fe 100644 --- a/src/lib/actions/RulesAction.ts +++ b/src/lib/actions/RulesAction.ts @@ -6,12 +6,14 @@ import {ProgressEventListener} from '../listeners/ProgressEventListener'; import {LogFileWriter} from '../writers/LogWriter'; import {LogEventListener, LogEventLogger} from '../listeners/LogEventListener'; import {RuleViewer} from '../viewers/RuleViewer'; +import {RulesActionSummaryViewer} from '../viewers/ActionSummaryViewer'; export type RulesDependencies = { configFactory: CodeAnalyzerConfigFactory; pluginsFactory: EnginePluginsFactory; logEventListeners: LogEventListener[]; progressListeners: ProgressEventListener[]; + actionSummaryViewer: RulesActionSummaryViewer, viewer: RuleViewer; } @@ -58,6 +60,7 @@ export class RulesAction { const rules: Rule[] = core.getEngineNames().flatMap(name => ruleSelection.getRulesFor(name)); this.dependencies.viewer.view(rules); + this.dependencies.actionSummaryViewer.view(ruleSelection, logWriter.getLogDestination()); } public static createAction(dependencies: RulesDependencies): RulesAction { diff --git a/src/lib/listeners/ProgressEventListener.ts b/src/lib/listeners/ProgressEventListener.ts index a23c7e6c2..06dce3656 100644 --- a/src/lib/listeners/ProgressEventListener.ts +++ b/src/lib/listeners/ProgressEventListener.ts @@ -138,8 +138,7 @@ export class RuleSelectionProgressSpinner extends ProgressSpinner implements Pro } protected createFinishedSpinnerStatus(): string { - return getMessage(BundleName.ProgressEventListener, 'selection-spinner.finished-status', - [[...this.engineNames.keys()].join(', ')]); + return getMessage(BundleName.ProgressEventListener, 'selection-spinner.finished-status'); } } diff --git a/src/lib/viewers/ActionSummaryViewer.ts b/src/lib/viewers/ActionSummaryViewer.ts index 59377b028..fb0515400 100644 --- a/src/lib/viewers/ActionSummaryViewer.ts +++ b/src/lib/viewers/ActionSummaryViewer.ts @@ -1,4 +1,5 @@ import {Display} from '../Display'; +import {RuleSelection} from '@salesforce/code-analyzer-core'; import {toStyledHeader, indent} from '../utils/StylingUtil'; import {BundleName, getMessage} from '../messages'; @@ -45,3 +46,35 @@ export class ConfigActionSummaryViewer extends AbstractActionSummaryViewer { this.display.displayLog(indent(outfile)); } } + +export class RulesActionSummaryViewer extends AbstractActionSummaryViewer { + public constructor(display: Display) { + super(display); + } + + public view(ruleSelection: RuleSelection, logFile: string): void { + // Start with separator to cleanly break from anything that's already been logged. + this.displayLineSeparator(); + this.displaySummaryHeader(); + this.displayLineSeparator(); + + if (ruleSelection.getCount() === 0) { + this.display.displayLog(getMessage(BundleName.ActionSummaryViewer, 'rules-action.found-no-rules')); + } else { + this.displayRuleSelection(ruleSelection); + } + this.displayLineSeparator(); + + this.displayLogFileInfo(logFile); + } + + private displayRuleSelection(ruleSelection: RuleSelection): void { + this.display.displayLog(getMessage(BundleName.ActionSummaryViewer, 'rules-action.rules-total', [ruleSelection.getCount(), ruleSelection.getEngineNames().length])); + for (const engineName of ruleSelection.getEngineNames()) { + const ruleCountForEngine: number = ruleSelection.getRulesFor(engineName).length; + this.display.displayLog(indent(getMessage(BundleName.ActionSummaryViewer, 'rules-action.rules-item', [ruleCountForEngine, engineName]))); + } + } + + +} diff --git a/test/fixtures/comparison-files/lib/actions/RulesAction.test.ts/action-summaries/no-rules.txt.goldfile b/test/fixtures/comparison-files/lib/actions/RulesAction.test.ts/action-summaries/no-rules.txt.goldfile new file mode 100644 index 000000000..197b47c89 --- /dev/null +++ b/test/fixtures/comparison-files/lib/actions/RulesAction.test.ts/action-summaries/no-rules.txt.goldfile @@ -0,0 +1,6 @@ + +=== Summary + +Found 0 rules. + +Additional log information written to: \ No newline at end of file diff --git a/test/fixtures/comparison-files/lib/actions/RulesAction.test.ts/action-summaries/some-rules.txt.goldfile b/test/fixtures/comparison-files/lib/actions/RulesAction.test.ts/action-summaries/some-rules.txt.goldfile new file mode 100644 index 000000000..88cc080c1 --- /dev/null +++ b/test/fixtures/comparison-files/lib/actions/RulesAction.test.ts/action-summaries/some-rules.txt.goldfile @@ -0,0 +1,8 @@ + +=== Summary + +Found 5 rule(s) from 2 engine(s): + 3 stubEngine1 rule(s) found. + 2 stubEngine2 rule(s) found. + +Additional log information written to: \ No newline at end of file diff --git a/test/lib/actions/RulesAction.test.ts b/test/lib/actions/RulesAction.test.ts index 94c13b563..912573cf6 100644 --- a/test/lib/actions/RulesAction.test.ts +++ b/test/lib/actions/RulesAction.test.ts @@ -1,8 +1,14 @@ import * as path from 'node:path'; +import * as fsp from 'node:fs/promises'; +import ansis from 'ansis'; import {RulesAction, RulesDependencies, RulesInput} from '../../../src/lib/actions/RulesAction'; +import {RulesActionSummaryViewer} from '../../../src/lib/viewers/ActionSummaryViewer'; import {StubDefaultConfigFactory} from '../../stubs/StubCodeAnalyzerConfigFactories'; import * as StubEnginePluginFactories from '../../stubs/StubEnginePluginsFactories'; import {SpyRuleViewer} from '../../stubs/SpyRuleViewer'; +import {DisplayEventType, SpyDisplay} from '../../stubs/SpyDisplay'; + +const PATH_TO_GOLDFILES = path.join(__dirname, '..', '..', 'fixtures', 'comparison-files', 'lib', 'actions', 'RulesAction.test.ts'); describe('RulesAction tests', () => { let viewer: SpyRuleViewer; @@ -12,11 +18,14 @@ describe('RulesAction tests', () => { }) it('Submitting the all-selector returns all rules', async () => { + const spyDisplay: SpyDisplay = new SpyDisplay(); + const actionSummaryViewer: RulesActionSummaryViewer = new RulesActionSummaryViewer(spyDisplay); const dependencies: RulesDependencies = { configFactory: new StubDefaultConfigFactory(), pluginsFactory: new StubEnginePluginFactories.StubEnginePluginsFactory_withFunctionalStubEngine(), logEventListeners: [], progressListeners: [], + actionSummaryViewer, viewer }; const action = RulesAction.createAction(dependencies); @@ -41,11 +50,14 @@ describe('RulesAction tests', () => { }); it('Submitting a filtering selector returns only matching rules', async () => { + const spyDisplay: SpyDisplay = new SpyDisplay(); + const actionSummaryViewer: RulesActionSummaryViewer = new RulesActionSummaryViewer(spyDisplay); const dependencies: RulesDependencies = { configFactory: new StubDefaultConfigFactory(), pluginsFactory: new StubEnginePluginFactories.StubEnginePluginsFactory_withFunctionalStubEngine(), logEventListeners: [], progressListeners: [], + actionSummaryViewer, viewer }; const action = RulesAction.createAction(dependencies); @@ -64,12 +76,15 @@ describe('RulesAction tests', () => { }); it('Engines with target-dependent rules return the right rules', async () => { + const spyDisplay: SpyDisplay = new SpyDisplay(); + const actionSummaryViewer: RulesActionSummaryViewer = new RulesActionSummaryViewer(spyDisplay); const dependencies: RulesDependencies = { configFactory: new StubDefaultConfigFactory(), // The engine we're using here will synthesize one rule per target. pluginsFactory: new StubEnginePluginFactories.StubEnginePluginsFactory_withTargetDependentStubEngine(), logEventListeners: [], progressListeners: [], + actionSummaryViewer, viewer }; const targetedFilesAndFolders = ['package.json', 'src', 'README.md']; @@ -98,11 +113,14 @@ describe('RulesAction tests', () => { * test will help us do that. */ it('When no engines are registered, empty results are displayed', async () => { + const spyDisplay: SpyDisplay = new SpyDisplay(); + const actionSummaryViewer: RulesActionSummaryViewer = new RulesActionSummaryViewer(spyDisplay); const dependencies: RulesDependencies = { configFactory: new StubDefaultConfigFactory(), pluginsFactory: new StubEnginePluginFactories.StubEnginePluginsFactory_withNoPlugins(), logEventListeners: [], progressListeners: [], + actionSummaryViewer, viewer }; const action = RulesAction.createAction(dependencies); @@ -118,11 +136,14 @@ describe('RulesAction tests', () => { }); it('Throws an error when an engine throws an error', async () => { + const spyDisplay: SpyDisplay = new SpyDisplay(); + const actionSummaryViewer: RulesActionSummaryViewer = new RulesActionSummaryViewer(spyDisplay); const dependencies: RulesDependencies = { configFactory: new StubDefaultConfigFactory(), pluginsFactory: new StubEnginePluginFactories.StubEnginePluginsFactory_withThrowingStubPlugin(), logEventListeners: [], progressListeners: [], + actionSummaryViewer, viewer }; const action = RulesAction.createAction(dependencies); @@ -133,6 +154,40 @@ describe('RulesAction tests', () => { await expect(executionPromise).rejects.toThrow('SomeErrorFromGetAvailableEngineNames'); }); + + describe('Summary generation', () => { + it.each([ + {quantifier: 'no', expectation: 'Summary indicates absence of rules', selector: 'NonsensicalTag', goldfile: 'no-rules.txt.goldfile'}, + {quantifier: 'some', expectation: 'Summary provides breakdown by engine', selector: 'Recommended', goldfile: 'some-rules.txt.goldfile'} + ])('When $quantifier rules are returned, $expectation', async ({selector, goldfile}) => { + const goldfilePath: string = path.join(PATH_TO_GOLDFILES, 'action-summaries', goldfile); + const spyDisplay: SpyDisplay = new SpyDisplay(); + const actionSummaryViewer: RulesActionSummaryViewer = new RulesActionSummaryViewer(spyDisplay); + const dependencies: RulesDependencies = { + configFactory: new StubDefaultConfigFactory(), + pluginsFactory: new StubEnginePluginFactories.StubEnginePluginsFactory_withFunctionalStubEngine(), + logEventListeners: [], + progressListeners: [], + actionSummaryViewer, + viewer + }; + const action = RulesAction.createAction(dependencies); + const input: RulesInput = { + 'rule-selector': [selector] + }; + + await action.execute(input); + + const displayEvents = spyDisplay.getDisplayEvents(); + const displayedLogEvents = ansis.strip(displayEvents + .filter(e => e.type === DisplayEventType.LOG) + .map(e => e.data) + .join('\n')); + + const goldfileContents: string = await fsp.readFile(goldfilePath, 'utf-8'); + expect(displayedLogEvents).toContain(goldfileContents); + }); + }); }); // TODO: Whenever we decide to document the custom_engine_plugin_modules flag in our configuration file, then we'll want diff --git a/test/lib/listeners/ProgressEventListener.test.ts b/test/lib/listeners/ProgressEventListener.test.ts index b4e48127a..f875cd087 100644 --- a/test/lib/listeners/ProgressEventListener.test.ts +++ b/test/lib/listeners/ProgressEventListener.test.ts @@ -87,7 +87,7 @@ describe('ProgressEventListener implementations', () => { expect(percentagesInOrder).toEqual([0, 25, 50, 100]); const endEvent = displayEvents[displayEvents.length - 1]; expect(endEvent).toHaveProperty('type', DisplayEventType.SPINNER_STOP); - expect(endEvent.data).toContain(`done. Selected rules from stubEngine1, stubEngine2.`); + expect(endEvent.data).toEqual(`done.`); }); it('Properly aggregates percentages across multiple Cores', async () => { @@ -123,7 +123,7 @@ describe('ProgressEventListener implementations', () => { expect(percentagesInOrder).toEqual([0, 12, 25, 50, 62, 75, 100]); const endEvent = displayEvents[displayEvents.length - 1]; expect(endEvent).toHaveProperty('type', DisplayEventType.SPINNER_STOP); - expect(endEvent.data).toContain('done. Selected rules from stubEngine1, stubEngine2.'); + expect(endEvent.data).toEqual('done.'); }); it('Properly interleaves progress updates with ticking', async () => { @@ -159,7 +159,7 @@ describe('ProgressEventListener implementations', () => { expect(percentagesInOrder).toEqual([0, 20, 40, 50, 60, 80, 100]); const endEvent = displayEvents[displayEvents.length - 1]; expect(endEvent).toHaveProperty('type', DisplayEventType.SPINNER_STOP); - expect(endEvent.data).toContain('done. Selected rules from timeableEngine1, timeableEngine2.'); + expect(endEvent.data).toEqual('done.'); }); }); From 8a26778be1e31b22aaca706fe7ffc12db9acb4f5 Mon Sep 17 00:00:00 2001 From: Joshua Feingold Date: Mon, 4 Nov 2024 12:55:45 -0600 Subject: [PATCH 05/35] CHANGE @W-17052953@ Removed redundant information from rules output --- messages/rule-viewer.md | 8 ------- src/lib/viewers/RuleViewer.ts | 11 +++++---- .../RuleViewer.test.ts/one-rule-details.txt | 4 ++-- .../RuleViewer.test.ts/two-rules-details.txt | 4 ++-- test/lib/viewers/RuleViewer.test.ts | 24 ++++++++++++------- 5 files changed, 26 insertions(+), 25 deletions(-) diff --git a/messages/rule-viewer.md b/messages/rule-viewer.md index b6bcf2726..7f150c7de 100644 --- a/messages/rule-viewer.md +++ b/messages/rule-viewer.md @@ -1,11 +1,3 @@ -# summary.found-no-rules - -Found 0 rules. - -# summary.found-rules - -Found %d rule(s): - # summary.detail.header %d. %s diff --git a/src/lib/viewers/RuleViewer.ts b/src/lib/viewers/RuleViewer.ts index 1e1c82b57..ed7246f52 100644 --- a/src/lib/viewers/RuleViewer.ts +++ b/src/lib/viewers/RuleViewer.ts @@ -17,14 +17,17 @@ abstract class AbstractRuleDisplayer implements RuleViewer { } public view(rules: Rule[]): void { - if (rules.length === 0) { - this.display.displayLog(getMessage(BundleName.RuleViewer, 'summary.found-no-rules')); - } else { - this.display.displayLog(getMessage(BundleName.RuleViewer, 'summary.found-rules', [rules.length])); + this.displayLineSeparator(); + if (rules.length > 0) { this._view(rules); + this.displayLineSeparator(); } } + protected displayLineSeparator(): void { + this.display.displayLog(""); + } + protected abstract _view(rules: Rule[]): void; } diff --git a/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/one-rule-details.txt b/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/one-rule-details.txt index 12bad3fb1..c6d3e4d86 100644 --- a/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/one-rule-details.txt +++ b/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/one-rule-details.txt @@ -1,8 +1,8 @@ -Found 1 rule(s): + === 1. StubRule1 severity: 2 (High) engine: FakeEngine1 type: Standard tags: Recommended, Security resources: www.google.com - description: This is the description for a stub rule. Blah blah blah. \ No newline at end of file + description: This is the description for a stub rule. Blah blah blah. diff --git a/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/two-rules-details.txt b/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/two-rules-details.txt index 272c472fa..9eaea142b 100644 --- a/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/two-rules-details.txt +++ b/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/two-rules-details.txt @@ -1,4 +1,4 @@ -Found 2 rule(s): + === 1. StubRule1 severity: 2 (High) engine: FakeEngine1 @@ -13,4 +13,4 @@ Found 2 rule(s): type: Flow tags: CodeStyle, Performance resources: www.bing.com, www.salesforce.com - description: This is the description for a second stub rule. Blah blah blah. \ No newline at end of file + description: This is the description for a second stub rule. Blah blah blah. diff --git a/test/lib/viewers/RuleViewer.test.ts b/test/lib/viewers/RuleViewer.test.ts index 2c5eb7f7f..51c718dc6 100644 --- a/test/lib/viewers/RuleViewer.test.ts +++ b/test/lib/viewers/RuleViewer.test.ts @@ -10,7 +10,7 @@ const PATH_TO_COMPARISON_FILES = path.resolve(__dirname, '..', '..', '..', 'test describe('RuleViewer implementations', () => { describe('RuleDetailDisplayer', () => { - it('When given no rules, outputs summary and nothing else', () => { + it('When given no rules, outputs a line separator and nothing else', () => { const display = new SpyDisplay(); const viewer = new RuleDetailDisplayer(display); @@ -20,7 +20,7 @@ describe('RuleViewer implementations', () => { expect(displayEvents).toHaveLength(1); expect(displayEvents).toEqual([{ type: DisplayEventType.LOG, - data: 'Found 0 rules.' + data: '' }]); }); @@ -34,7 +34,7 @@ describe('RuleViewer implementations', () => { ]); const actualDisplayEvents = display.getDisplayEvents(); - expect(actualDisplayEvents).toHaveLength(2); + expect(actualDisplayEvents).toHaveLength(3); for (const displayEvent of actualDisplayEvents) { expect(displayEvent.type).toEqual(DisplayEventType.LOG); } @@ -57,7 +57,7 @@ describe('RuleViewer implementations', () => { ]); const actualDisplayEvents = display.getDisplayEvents(); - expect(actualDisplayEvents).toHaveLength(2); + expect(actualDisplayEvents).toHaveLength(3); for (const displayEvent of actualDisplayEvents) { expect(displayEvent.type).toEqual(DisplayEventType.LOG); } @@ -80,7 +80,7 @@ describe('RuleViewer implementations', () => { expect(displayEvents).toHaveLength(1); expect(displayEvents).toEqual([{ type: DisplayEventType.LOG, - data: 'Found 0 rules.' + data: '' }]); }); @@ -94,10 +94,10 @@ describe('RuleViewer implementations', () => { ]); const displayEvents = display.getDisplayEvents(); - expect(displayEvents).toHaveLength(2); + expect(displayEvents).toHaveLength(3); expect(displayEvents).toEqual([{ type: DisplayEventType.LOG, - data: 'Found 1 rule(s):' + data: '' }, { type: DisplayEventType.TABLE, data: JSON.stringify({ @@ -110,6 +110,9 @@ describe('RuleViewer implementations', () => { tag: rule.getFormattedTags() }] }) + }, { + type: DisplayEventType.LOG, + data: '' }]) }); @@ -125,10 +128,10 @@ describe('RuleViewer implementations', () => { ]); const displayEvents = display.getDisplayEvents(); - expect(displayEvents).toHaveLength(2); + expect(displayEvents).toHaveLength(3); expect(displayEvents).toEqual([{ type: DisplayEventType.LOG, - data: 'Found 2 rule(s):' + data: '' }, { type: DisplayEventType.TABLE, data: JSON.stringify({ @@ -147,6 +150,9 @@ describe('RuleViewer implementations', () => { tag: rule2.getFormattedTags() }] }) + }, { + type: DisplayEventType.LOG, + data: '' }]); }); }); From 4981ee11369f25144a0c723cb64a0a99e486a475 Mon Sep 17 00:00:00 2001 From: Josh Feingold Date: Fri, 15 Nov 2024 09:20:28 -0600 Subject: [PATCH 06/35] NEW @W-17042397@ Detail output now has multilocation support (#1673) --- package.json | 12 ++-- src/lib/utils/StylingUtil.ts | 13 ++-- src/lib/viewers/ResultsViewer.ts | 44 ++++++++++--- .../one-multilocation-violation-details.txt | 10 +++ .../factories/EnginePluginsFactory.test.ts | 2 +- test/lib/viewers/ResultsViewer.test.ts | 47 ++++++++++++++ yarn.lock | 64 ++++++++++--------- 7 files changed, 142 insertions(+), 50 deletions(-) create mode 100644 test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/one-multilocation-violation-details.txt diff --git a/package.json b/package.json index b7f6f06bd..0b54578b8 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,12 @@ "bugs": "https://github.com/forcedotcom/sfdx-scanner/issues", "dependencies": { "@oclif/core": "^3.3.2", - "@salesforce/code-analyzer-core": "0.14.1", - "@salesforce/code-analyzer-engine-api": "0.11.1", - "@salesforce/code-analyzer-eslint-engine": "0.11.1", - "@salesforce/code-analyzer-pmd-engine": "0.11.1", - "@salesforce/code-analyzer-regex-engine": "0.11.1", - "@salesforce/code-analyzer-retirejs-engine": "0.11.1", + "@salesforce/code-analyzer-core": "0.16.0", + "@salesforce/code-analyzer-engine-api": "0.13.0", + "@salesforce/code-analyzer-eslint-engine": "0.13.0", + "@salesforce/code-analyzer-pmd-engine": "0.13.0", + "@salesforce/code-analyzer-regex-engine": "0.13.0", + "@salesforce/code-analyzer-retirejs-engine": "0.13.0", "@salesforce/core": "^5", "@salesforce/sf-plugins-core": "^5.0.4", "@salesforce/ts-types": "^2.0.9", diff --git a/src/lib/utils/StylingUtil.ts b/src/lib/utils/StylingUtil.ts index 85478e9ba..cb3f43788 100644 --- a/src/lib/utils/StylingUtil.ts +++ b/src/lib/utils/StylingUtil.ts @@ -4,7 +4,7 @@ import ansis from 'ansis'; * For now, the styling methods only accept objects if all of their keys correspond to string values. This puts the * burden of formatting non-string properties on the caller. */ -type Styleable = null | undefined | {[key: string]: string}; +type Styleable = null | undefined | {[key: string]: string|string[]}; export function toStyledHeaderAndBody(header: string, body: Styleable, keys?: string[]): string { const styledHeader: string = toStyledHeader(header); @@ -27,11 +27,16 @@ export function toStyledPropertyList(body: Styleable, selectedKeys?: string[]): const keysToPrint = selectedKeys || [...Object.keys(body)]; const longestKeyLength = Math.max(...keysToPrint.map(k => k.length)); - const styleProperty = (key: string, value: string): string => { + const styleProperty = (key: string, value: string|string[]): string => { const keyPortion = `${ansis.blue(key)}:`; const keyValueGap = ' '.repeat(longestKeyLength - key.length + 1); - const valuePortion = value.replace('\n', `\n${' '.repeat(longestKeyLength + 2)}`); - return `${keyPortion}${keyValueGap}${valuePortion}`; + if (typeof value === 'string') { + const valuePortion = value.replace('\n', `\n${' '.repeat(longestKeyLength + 2)}`); + return `${keyPortion}${keyValueGap}${valuePortion}`; + } else { + const valuePortion: string = value.map(v => `${indent(v, 4)}`).join('\n'); + return `${keyPortion}\n${valuePortion}`; + } } const output = keysToPrint.map(key => styleProperty(key, body[key] || '')); diff --git a/src/lib/viewers/ResultsViewer.ts b/src/lib/viewers/ResultsViewer.ts index 34d795467..f5e107f6c 100644 --- a/src/lib/viewers/ResultsViewer.ts +++ b/src/lib/viewers/ResultsViewer.ts @@ -58,25 +58,49 @@ export class ResultsDetailDisplayer extends AbstractResultsDisplayer { private styleViolation(violation: Violation, idx: number): string { const rule = violation.getRule(); const sev = rule.getSeverityLevel(); - const primaryLocation = violation.getCodeLocations()[violation.getPrimaryLocationIndex()]; const header = getMessage( BundleName.ResultsViewer, 'summary.detail.violation-header', [idx + 1, rule.getName()] ); - const body = { - severity: `${sev.valueOf()} (${SeverityLevel[sev]})`, - engine: rule.getEngineName(), - message: violation.getMessage(), - location: `${primaryLocation.getFile()}:${primaryLocation.getStartLine()}:${primaryLocation.getStartColumn()}`, - resources: violation.getResourceUrls().join(',') - }; - const keys = ['severity', 'engine', 'message', 'location', 'resources']; - return toStyledHeaderAndBody(header, body, keys); + if (violation.getCodeLocations().length > 1) { + const body = { + severity: `${sev.valueOf()} (${SeverityLevel[sev]})`, + engine: rule.getEngineName(), + message: violation.getMessage(), + locations: stringifyLocations(violation.getCodeLocations(), violation.getPrimaryLocationIndex()), + resources: violation.getResourceUrls().join(',') + }; + const keys = ['severity', 'engine', 'message', 'locations', 'resources']; + return toStyledHeaderAndBody(header, body, keys); + } else { + const body = { + severity: `${sev.valueOf()} (${SeverityLevel[sev]})`, + engine: rule.getEngineName(), + message: violation.getMessage(), + location: stringifyLocations(violation.getCodeLocations())[0], + resources: violation.getResourceUrls().join(',') + }; + const keys = ['severity', 'engine', 'message', 'location', 'resources']; + return toStyledHeaderAndBody(header, body, keys); + } } } +function stringifyLocations(codeLocations: CodeLocation[], primaryIndex?: number): string[] { + const locationStrings: string[] = []; + + codeLocations.forEach((loc, idx) => { + const commentPortion: string = loc.getComment() ? ` ${loc.getComment()}` : ''; + const locationString: string = `${loc.getFile()}:${loc.getStartLine()}:${loc.getStartColumn()}${commentPortion}`; + const mainPortion: string = primaryIndex != null && primaryIndex === idx ? '(main) ' : ''; + locationStrings.push(`${mainPortion}${locationString}`); + }); + + return locationStrings; +} + type ResultRow = { num: number; location: string; diff --git a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/one-multilocation-violation-details.txt b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/one-multilocation-violation-details.txt new file mode 100644 index 000000000..76806161e --- /dev/null +++ b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/one-multilocation-violation-details.txt @@ -0,0 +1,10 @@ +Found 1 violation(s) across 1 file(s): +=== 1. stub1RuleA + severity: 4 (Low) + engine: stubEngine1 + message: This is a message + locations: + __PATH_TO_FILE_A__:20:1 + (main) __PATH_TO_FILE_Z__:2:1 This is a comment at Location 2 + __PATH_TO_FILE_A__:1:1 This is a comment at Location 3 + resources: https://example.com/stub1RuleA diff --git a/test/lib/factories/EnginePluginsFactory.test.ts b/test/lib/factories/EnginePluginsFactory.test.ts index 72559c364..7b645c793 100644 --- a/test/lib/factories/EnginePluginsFactory.test.ts +++ b/test/lib/factories/EnginePluginsFactory.test.ts @@ -8,7 +8,7 @@ describe('EnginePluginsFactoryImpl', () => { expect(enginePlugins).toHaveLength(4); expect(enginePlugins[0].getAvailableEngineNames()).toEqual(['eslint']); - expect(enginePlugins[1].getAvailableEngineNames()).toEqual(['pmd']); + expect(enginePlugins[1].getAvailableEngineNames()).toEqual(['pmd', 'cpd']); expect(enginePlugins[2].getAvailableEngineNames()).toEqual(['retire-js']); expect(enginePlugins[3].getAvailableEngineNames()).toEqual(['regex']); }); diff --git a/test/lib/viewers/ResultsViewer.test.ts b/test/lib/viewers/ResultsViewer.test.ts index cb4c74ce9..fa0044a4c 100644 --- a/test/lib/viewers/ResultsViewer.test.ts +++ b/test/lib/viewers/ResultsViewer.test.ts @@ -132,6 +132,53 @@ describe('ResultsViewer implementations', () => { .replace(/__PATH_TO_FILE_Z__/g, PATH_TO_FILE_Z); expect(actualEventText).toContain(expectedViolationDetails); }); + + it('Multi-location violations are correctly displayed', async () => { + // ==== TEST SETUP ==== + // Populate the engine with: + const violations: Violation[] = [ + // A violation. + createViolation(rule1.name, PATH_TO_FILE_A, 20, 1), + ]; + + // Add some additional locations to the violation. + violations[0].codeLocations.push({ + file: PATH_TO_FILE_Z, + startLine: 2, + startColumn: 1, + comment: 'This is a comment at Location 2' + }, { + file: PATH_TO_FILE_A, + startLine: 1, + startColumn: 1, + comment: 'This is a comment at Location 3' + }); + // Declare the second location to be the primary. + violations[0].primaryLocationIndex = 1; + engine1.resultsToReturn = {violations}; + + // "Run" the plugin. + const workspace = await codeAnalyzerCore.createWorkspace(['package.json']); + const rules = await codeAnalyzerCore.selectRules(['all'], {workspace}); + const results = await codeAnalyzerCore.run(rules, {workspace}); + + // ==== TESTED METHOD ==== + // Pass the result object into the viewer. + viewer.view(results); + + // ==== ASSERTIONS ==== + // Compare the text in the events with the text in our comparison file. + const actualDisplayEvents: DisplayEvent[] = spyDisplay.getDisplayEvents(); + for (const event of actualDisplayEvents) { + expect(event.type).toEqual(DisplayEventType.LOG); + } + // Rip off all of ansis's styling, so we're just comparing plain text. + const actualEventText = ansis.strip(actualDisplayEvents.map(e => e.data).join('\n')); + const expectedViolationDetails = (await readComparisonFile('one-multilocation-violation-details.txt')) + .replace(/__PATH_TO_FILE_A__/g, PATH_TO_FILE_A) + .replace(/__PATH_TO_FILE_Z__/g, PATH_TO_FILE_Z); + expect(actualEventText).toContain(expectedViolationDetails); + }) }); describe('ResultsTableDisplayer', () => { diff --git a/yarn.lock b/yarn.lock index 6843b37dc..4cfc410ae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1569,35 +1569,36 @@ strip-ansi "6.0.1" ts-retry-promise "^0.8.1" -"@salesforce/code-analyzer-core@0.14.1": - version "0.14.1" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-core/-/code-analyzer-core-0.14.1.tgz#6b14e12b1bbfc32ea4401b03f86117330431c952" - integrity sha512-kTgrGAsDxpeV4FU+V0i91h9byvD6tECJHfX0lKv/6bTfDwNJEuLFypb1t/g+w8qfIymRLq7IYvJ+wFjYAJTdDA== +"@salesforce/code-analyzer-core@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-core/-/code-analyzer-core-0.16.0.tgz#e9aec49c7e3835d29f22b715388a16267c632afd" + integrity sha512-hqOUF4dFNjY9w6pMlw8eIDN1jnm8aypLH3KEdPMI2asmLjOI1C1EOZ6IYrlsclYX6Czr9f5LzShaa0l5CJabaQ== dependencies: - "@salesforce/code-analyzer-engine-api" "0.11.1" + "@salesforce/code-analyzer-engine-api" "0.13.0" "@types/js-yaml" "^4.0.9" "@types/node" "^20.0.0" + "@types/sarif" "^2.1.7" csv-stringify "^6.5.0" js-yaml "^4.1.0" xmlbuilder "^15.1.1" -"@salesforce/code-analyzer-engine-api@0.11.1": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-engine-api/-/code-analyzer-engine-api-0.11.1.tgz#c4e1ad9375263d1daf70cfef2118b11013ce4b4a" - integrity sha512-RW2OU3dHNL+ecYQ5B1TSmKCOFXlruT1M4ATG0pTp3E9wYvz0oah8wWeaFPRT37HNn+Sf7SNYpkbIVDZYwV46iw== +"@salesforce/code-analyzer-engine-api@0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-engine-api/-/code-analyzer-engine-api-0.13.0.tgz#dbaba9102d34ea12472f4115298da8d617a0492d" + integrity sha512-dcVuoYUbzEXcW1+l0tjoOquu6VSgr41ti+tOKE/569Wb+hf4Yu7LhXFGq4Gq5tueZDuODjDYDWuFnmmgcAwBJw== dependencies: "@types/node" "^20.0.0" -"@salesforce/code-analyzer-eslint-engine@0.11.1": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-eslint-engine/-/code-analyzer-eslint-engine-0.11.1.tgz#f640324b05411404c6907e224ca482d3b57564e0" - integrity sha512-wOuY8nAtBnnkH2Bi8kz3PlJr97Mc6fQgKzOnUJR6fC3AcdLTz8rZ9YWR8yQdi9ASEPfGQq9ZyA20PDEzJMWezQ== +"@salesforce/code-analyzer-eslint-engine@0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-eslint-engine/-/code-analyzer-eslint-engine-0.13.0.tgz#1bb3688e94a63f4b6c0db941e0ce6fc84ca2b0de" + integrity sha512-UnEQB+5KiZIcQJYIVrAB1XzJnymyRAm6NXy2naETOdqXwVxjXo1jvSNuw68BfKQXs36GXf+EfjF/H+CnXurvHQ== dependencies: "@babel/core" "^7.24.7" "@babel/eslint-parser" "^7.24.7" "@eslint/js" "^8.57.0" "@lwc/eslint-plugin-lwc" "^1.8.0" - "@salesforce/code-analyzer-engine-api" "0.11.1" + "@salesforce/code-analyzer-engine-api" "0.13.0" "@salesforce/eslint-config-lwc" "^3.5.3" "@salesforce/eslint-plugin-lightning" "^1.0.0" "@types/eslint" "^8.56.10" @@ -1608,33 +1609,33 @@ eslint-plugin-import "^2.29.1" eslint-plugin-jest "^28.6.0" -"@salesforce/code-analyzer-pmd-engine@0.11.1": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-pmd-engine/-/code-analyzer-pmd-engine-0.11.1.tgz#8c6be62ad172ed1650149fc55840bac7490bd4df" - integrity sha512-hIbqT+PBhNiRu0NbYs66aNw8ML+PtvB0wneQ7IvOErvFhznL6RY7AokXix3FxMkCk4xyBdAC1s080m+QmojCug== +"@salesforce/code-analyzer-pmd-engine@0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-pmd-engine/-/code-analyzer-pmd-engine-0.13.0.tgz#c3db9ee1cd73d46bdb940aea1c6888e64bea51b1" + integrity sha512-5TMiTL520jNfVcewX7IlsScNoxh5CDyQI5lrilZEa+LkgR9wvFI8b0N+uzz82Iz9xPp+tzmgnW9QVODaCLwdwQ== dependencies: - "@salesforce/code-analyzer-engine-api" "0.11.1" + "@salesforce/code-analyzer-engine-api" "0.13.0" "@types/node" "^20.0.0" "@types/semver" "^7.5.8" "@types/tmp" "^0.2.6" semver "^7.6.3" tmp "^0.2.3" -"@salesforce/code-analyzer-regex-engine@0.11.1": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-regex-engine/-/code-analyzer-regex-engine-0.11.1.tgz#e34974f356bc20c1afd8c9d6834fb4dcdc461fc7" - integrity sha512-KVdg44ENoIfripHIqVwmf2UemlAtQGQOw4Kn0fuqrjOXFbKATjKrJsawZZhyoKtSdejWt58ni1bjCvYesej93g== +"@salesforce/code-analyzer-regex-engine@0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-regex-engine/-/code-analyzer-regex-engine-0.13.0.tgz#0bff0037483663d2707a01d05a9b4d8f5951e1fc" + integrity sha512-6eDG9muy74jHw46rVE+W3MOzuKPpbxvmE+DK6i/JB3qh00OIv7JmVysuAuXV9mvGhO1jj+FBHfug2ZexKEhGUw== dependencies: - "@salesforce/code-analyzer-engine-api" "0.11.1" + "@salesforce/code-analyzer-engine-api" "0.13.0" "@types/node" "^20.0.0" isbinaryfile "^5.0.2" -"@salesforce/code-analyzer-retirejs-engine@0.11.1": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-retirejs-engine/-/code-analyzer-retirejs-engine-0.11.1.tgz#2a12a97626f32ff4841182f4969361ac570d9f81" - integrity sha512-nCaU7Sg24EZ/l8RljCjQEHccs7FgM5+t5oXVYrVU0/UoOuMHjgZvELsit02WD63K65J0vAQkBEsgRO4s7mLtlQ== +"@salesforce/code-analyzer-retirejs-engine@0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-retirejs-engine/-/code-analyzer-retirejs-engine-0.13.0.tgz#943c6be8f1cd4607a34044e33114bd5834e4e015" + integrity sha512-1AN9vTKifDR2QsR56VCr4Xuy5EzxmsL95gmfYoxJwo4brf6QzW3/5XgaaanCEfWAdLbONYkEnJMsT45RE30uJA== dependencies: - "@salesforce/code-analyzer-engine-api" "0.11.1" + "@salesforce/code-analyzer-engine-api" "0.13.0" "@types/node" "^20.0.0" "@types/tmp" "^0.2.6" isbinaryfile "^5.0.2" @@ -2495,6 +2496,11 @@ dependencies: undici-types "~6.19.2" +"@types/sarif@^2.1.7": + version "2.1.7" + resolved "https://registry.yarnpkg.com/@types/sarif/-/sarif-2.1.7.tgz#dab4d16ba7568e9846c454a8764f33c5d98e5524" + integrity sha512-kRz0VEkJqWLf1LLVN4pT1cg1Z9wAuvI6L97V3m2f5B76Tg8d413ddvLBPTEHAZJlnn4XSvu0FkZtViCQGVyrXQ== + "@types/semver@^7.5.4", "@types/semver@^7.5.8": version "7.5.8" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" From 2bbb76f8a593c52ab9c4d29033465aeb007740f5 Mon Sep 17 00:00:00 2001 From: Josh Feingold Date: Fri, 15 Nov 2024 10:40:59 -0600 Subject: [PATCH 07/35] CHANGE @W-17053004@ Polished run command output (#1669) --- messages/action-summary-viewer.md | 16 ++ messages/progress-event-listener.md | 2 +- messages/results-viewer.md | 8 +- messages/run-summary-viewer.md | 27 ---- src/commands/code-analyzer/config.ts | 2 +- src/commands/code-analyzer/run.ts | 4 +- src/lib/actions/RunAction.ts | 6 +- src/lib/listeners/ProgressEventListener.ts | 2 +- src/lib/messages.ts | 2 +- src/lib/viewers/ActionSummaryViewer.ts | 60 ++++++- src/lib/viewers/ResultsViewer.ts | 33 ++-- src/lib/viewers/RunSummaryViewer.ts | 62 -------- .../no-violations.txt.goldfile | 6 + .../some-outfiles.txt.goldfile | 11 ++ .../some-violations.txt.goldfile | 8 + .../four-identical-violations-details.txt | 2 +- .../four-unique-violations-details.txt | 2 +- .../one-multilocation-violation-details.txt | 2 +- .../four-unique-violations-summary.txt | 3 - test/lib/actions/RunAction.test.ts | 128 ++++++++++++++- .../listeners/ProgressEventListener.test.ts | 2 +- test/lib/viewers/ResultsViewer.test.ts | 20 ++- test/lib/viewers/RunSummaryViewer.test.ts | 150 ------------------ 23 files changed, 262 insertions(+), 296 deletions(-) delete mode 100644 messages/run-summary-viewer.md delete mode 100644 src/lib/viewers/RunSummaryViewer.ts create mode 100644 test/fixtures/comparison-files/lib/actions/RunAction.test.ts/action-summaries/no-violations.txt.goldfile create mode 100644 test/fixtures/comparison-files/lib/actions/RunAction.test.ts/action-summaries/some-outfiles.txt.goldfile create mode 100644 test/fixtures/comparison-files/lib/actions/RunAction.test.ts/action-summaries/some-violations.txt.goldfile delete mode 100644 test/fixtures/comparison-files/lib/viewers/RunSummaryViewer.test.ts/four-unique-violations-summary.txt delete mode 100644 test/lib/viewers/RunSummaryViewer.test.ts diff --git a/messages/action-summary-viewer.md b/messages/action-summary-viewer.md index bf7fa37ce..ad5f1be66 100644 --- a/messages/action-summary-viewer.md +++ b/messages/action-summary-viewer.md @@ -21,3 +21,19 @@ Found %d rule(s) from %d engine(s): # rules-action.rules-item %d %s rule(s) found. + +# run-action.found-no-violations + +Found 0 violations. + +# run-action.violations-total + +Found %d violation(s) across %d file(s): + +# run-action.violations-item + +%d %s severity violation(s) found. + +# run-action.outfiles-total + +Results written to: diff --git a/messages/progress-event-listener.md b/messages/progress-event-listener.md index b98fa90d0..fee84255f 100644 --- a/messages/progress-event-listener.md +++ b/messages/progress-event-listener.md @@ -11,7 +11,7 @@ done. Executing rules # execution-spinner.progress-summary -%d of %d engines still executing after %ds. +%d of %d engines finished after %ds. # execution-spinner.engine-status - %s at %d% completion. diff --git a/messages/results-viewer.md b/messages/results-viewer.md index 4d85513f3..8ed4253fe 100644 --- a/messages/results-viewer.md +++ b/messages/results-viewer.md @@ -1,11 +1,11 @@ -# summary.detail.found-results - -Found %d violation(s) across %d file(s): - # summary.detail.violation-header %d. %s +# summary.table.results-relative-to + +Violation file paths relative to '%s'. + # summary.table.found-results Found %d violation(s) across %d file(s) relative to '%s': diff --git a/messages/run-summary-viewer.md b/messages/run-summary-viewer.md deleted file mode 100644 index ab712ae84..000000000 --- a/messages/run-summary-viewer.md +++ /dev/null @@ -1,27 +0,0 @@ -# summary.header - -Summary - -# summary.found-no-violations - -Found 0 violations. - -# summary.violations-total - -Found %d violation(s): - -# summary.violations-item - -%d %s severity violation(s) found. - -# summary.no-outfiles - -No results files were specified. - -# summary.outfiles-total - -Results written to: - -# summary.log-file-location - -Additional log information written to: diff --git a/src/commands/code-analyzer/config.ts b/src/commands/code-analyzer/config.ts index 04459fdeb..951ebdf7d 100644 --- a/src/commands/code-analyzer/config.ts +++ b/src/commands/code-analyzer/config.ts @@ -62,7 +62,7 @@ export default class ConfigCommand extends SfCommand implements Displayabl protected createDependencies(outputFile?: string): ConfigDependencies { const uxDisplay: UxDisplay = new UxDisplay(this, this.spinner); - const modelGeneratorFunction = (relevantEngines: Set, userContext: ConfigContext, defaultContext: ConfigContext) => { + const modelGeneratorFunction = /* istanbul ignore next - Model tested separately */ (relevantEngines: Set, userContext: ConfigContext, defaultContext: ConfigContext) => { return AnnotatedConfigModel.fromSelection(relevantEngines, userContext, defaultContext); }; const dependencies: ConfigDependencies = { diff --git a/src/commands/code-analyzer/run.ts b/src/commands/code-analyzer/run.ts index b2cd008ca..247cab9ff 100644 --- a/src/commands/code-analyzer/run.ts +++ b/src/commands/code-analyzer/run.ts @@ -6,7 +6,7 @@ import {CodeAnalyzerConfigFactoryImpl} from '../../lib/factories/CodeAnalyzerCon import {EnginePluginsFactoryImpl} from '../../lib/factories/EnginePluginsFactory'; import {CompositeResultsWriter} from '../../lib/writers/ResultsWriter'; import {ResultsDetailDisplayer, ResultsTableDisplayer} from '../../lib/viewers/ResultsViewer'; -import {RunSummaryDisplayer} from '../../lib/viewers/RunSummaryViewer'; +import {RunActionSummaryViewer} from '../../lib/viewers/ActionSummaryViewer'; import {BundleName, getMessage, getMessages} from '../../lib/messages'; import {LogEventDisplayer} from '../../lib/listeners/LogEventListener'; import {EngineRunProgressSpinner, RuleSelectionProgressSpinner} from '../../lib/listeners/ProgressEventListener'; @@ -108,7 +108,7 @@ export default class RunCommand extends SfCommand implements Displayable { resultsViewer: view === View.TABLE ? new ResultsTableDisplayer(uxDisplay) : new ResultsDetailDisplayer(uxDisplay), - runSummaryViewer: new RunSummaryDisplayer(uxDisplay) + actionSummaryViewer: new RunActionSummaryViewer(uxDisplay) }; } } diff --git a/src/lib/actions/RunAction.ts b/src/lib/actions/RunAction.ts index 43780761c..b23691c1f 100644 --- a/src/lib/actions/RunAction.ts +++ b/src/lib/actions/RunAction.ts @@ -13,7 +13,7 @@ import {EnginePluginsFactory} from '../factories/EnginePluginsFactory'; import {createPathStarts} from '../utils/PathStartUtil'; import {createWorkspace} from '../utils/WorkspaceUtil'; import {ResultsViewer} from '../viewers/ResultsViewer'; -import {RunSummaryViewer} from '../viewers/RunSummaryViewer'; +import {RunActionSummaryViewer} from '../viewers/ActionSummaryViewer'; import {ResultsWriter} from '../writers/ResultsWriter'; import {LogFileWriter} from '../writers/LogWriter'; import {LogEventListener, LogEventLogger} from '../listeners/LogEventListener'; @@ -27,7 +27,7 @@ export type RunDependencies = { progressListeners: ProgressEventListener[]; writer: ResultsWriter; resultsViewer: ResultsViewer; - runSummaryViewer: RunSummaryViewer; + actionSummaryViewer: RunActionSummaryViewer; } export type RunInput = { @@ -80,7 +80,7 @@ export class RunAction { this.dependencies.logEventListeners.forEach(listener => listener.stopListening()); this.dependencies.writer.write(results); this.dependencies.resultsViewer.view(results); - this.dependencies.runSummaryViewer.view(results, logWriter.getLogDestination(), input['output-file']); + this.dependencies.actionSummaryViewer.view(results, logWriter.getLogDestination(), input['output-file']); const thresholdValue = input['severity-threshold']; if (thresholdValue) { diff --git a/src/lib/listeners/ProgressEventListener.ts b/src/lib/listeners/ProgressEventListener.ts index 06dce3656..55a5a7f7a 100644 --- a/src/lib/listeners/ProgressEventListener.ts +++ b/src/lib/listeners/ProgressEventListener.ts @@ -207,7 +207,7 @@ export class EngineRunProgressSpinner extends ProgressSpinner implements Progres engineLines.push(getMessage(BundleName.ProgressEventListener, 'execution-spinner.engine-status', [name, progress])); } return [ - getMessage(BundleName.ProgressEventListener, 'execution-spinner.progress-summary', [unfinishedEngines, totalEngines, secondsRunning]), + getMessage(BundleName.ProgressEventListener, 'execution-spinner.progress-summary', [totalEngines - unfinishedEngines, totalEngines, secondsRunning]), ...engineLines ].join('\n'); } diff --git a/src/lib/messages.ts b/src/lib/messages.ts index 218091880..a73b71b1a 100644 --- a/src/lib/messages.ts +++ b/src/lib/messages.ts @@ -50,6 +50,6 @@ export function getMessage(bundle: BundleName, messageKey: string, tokens?: Toke } export function getMessages(bundle: BundleName, messageKey: string, tokens?: Tokens): string[] { - INSTANCE = INSTANCE || new MessageCatalog(); + INSTANCE = INSTANCE || /* istanbul ignore next */ new MessageCatalog(); return INSTANCE.getMessages(bundle, messageKey, tokens); } diff --git a/src/lib/viewers/ActionSummaryViewer.ts b/src/lib/viewers/ActionSummaryViewer.ts index fb0515400..7325533e5 100644 --- a/src/lib/viewers/ActionSummaryViewer.ts +++ b/src/lib/viewers/ActionSummaryViewer.ts @@ -1,5 +1,5 @@ import {Display} from '../Display'; -import {RuleSelection} from '@salesforce/code-analyzer-core'; +import {RuleSelection, RunResults, SeverityLevel, Violation} from '@salesforce/code-analyzer-core'; import {toStyledHeader, indent} from '../utils/StylingUtil'; import {BundleName, getMessage} from '../messages'; @@ -75,6 +75,64 @@ export class RulesActionSummaryViewer extends AbstractActionSummaryViewer { this.display.displayLog(indent(getMessage(BundleName.ActionSummaryViewer, 'rules-action.rules-item', [ruleCountForEngine, engineName]))); } } +} + +export class RunActionSummaryViewer extends AbstractActionSummaryViewer { + public constructor(display: Display) { + super(display); + } + + public view(results: RunResults, logFile: string, outfiles: string[]): void { + // Start with separator to cleanly break from anything that's already been logged. + this.displayLineSeparator(); + this.displaySummaryHeader(); + this.displayLineSeparator(); + + if (results.getViolationCount() === 0) { + this.display.displayLog(getMessage(BundleName.ActionSummaryViewer, 'run-action.found-no-violations')); + } else { + this.displayResultsSummary(results); + } + this.displayLineSeparator(); + if (outfiles.length > 0) { + this.displayOutfiles(outfiles); + this.displayLineSeparator(); + } + this.displayLogFileInfo(logFile); + } + + private displayResultsSummary(results: RunResults): void { + this.display.displayLog(getMessage(BundleName.ActionSummaryViewer, 'run-action.violations-total', [results.getViolationCount(), this.countUniqueFiles(results.getViolations())])); + for (const sev of Object.values(SeverityLevel)) { + // Some of the keys will be numbers, since the enum is numerical. Skip those. + if (typeof sev !== 'string') { + continue; + } + const sevCount = results.getViolationCountOfSeverity(SeverityLevel[sev] as SeverityLevel); + if (sevCount > 0) { + this.display.displayLog(indent(getMessage(BundleName.ActionSummaryViewer, 'run-action.violations-item', [sevCount, sev]))); + } + } + } + + private countUniqueFiles(violations: Violation[]): number { + const fileSet: Set = new Set(); + violations.forEach(v => { + const primaryLocation = v.getCodeLocations()[v.getPrimaryLocationIndex()]; + const file = primaryLocation.getFile(); + if (file) { + fileSet.add(file); + } + }); + return fileSet.size; + } + + private displayOutfiles(outfiles: string[]): void { + this.display.displayLog(getMessage(BundleName.ActionSummaryViewer, 'run-action.outfiles-total')); + for (const outfile of outfiles) { + this.display.displayLog(indent(outfile)); + } + } } diff --git a/src/lib/viewers/ResultsViewer.ts b/src/lib/viewers/ResultsViewer.ts index f5e107f6c..1c06b3950 100644 --- a/src/lib/viewers/ResultsViewer.ts +++ b/src/lib/viewers/ResultsViewer.ts @@ -20,21 +20,14 @@ abstract class AbstractResultsDisplayer implements ResultsViewer { if (results.getViolationCount() === 0) { return; } else { + this.displayLineSeparator(); this._view(results); - this.display.displayLog('\n'); + this.displayLineSeparator(); } } - protected countUniqueFiles(violations: Violation[]): number { - const fileSet: Set = new Set(); - violations.forEach(v => { - const primaryLocation = v.getCodeLocations()[v.getPrimaryLocationIndex()]; - const file = primaryLocation.getFile(); - if (file) { - fileSet.add(file); - } - }); - return fileSet.size; + protected displayLineSeparator(): void { + this.display.displayLog(''); } protected abstract _view(results: RunResults): void; @@ -44,8 +37,6 @@ export class ResultsDetailDisplayer extends AbstractResultsDisplayer { protected _view(results: RunResults): void { const violations = sortViolations(results.getViolations()); - this.display.displayLog(getMessage(BundleName.ResultsViewer, 'summary.detail.found-results', [ - violations.length, this.countUniqueFiles(violations)])); this.displayDetails(violations); } @@ -147,8 +138,7 @@ export class ResultsTableDisplayer extends AbstractResultsDisplayer { } }); - this.display.displayLog(getMessage(BundleName.ResultsViewer, 'summary.table.found-results', [ - violations.length, this.countUniqueFiles(violations), parentFolder])); + this.display.displayLog(getMessage(BundleName.ResultsViewer, 'summary.table.results-relative-to', [parentFolder])); this.display.displayTable(resultRows, TABLE_COLUMNS); } } @@ -164,22 +154,22 @@ function sortViolations(violations: Violation[]): Violation[] { // Next, compare file names. const v1PrimaryLocation = v1.getCodeLocations()[v1.getPrimaryLocationIndex()]; const v2PrimaryLocation = v2.getCodeLocations()[v2.getPrimaryLocationIndex()]; - const v1File = v1PrimaryLocation.getFile() || ''; - const v2File = v2PrimaryLocation.getFile() || ''; + const v1File = v1PrimaryLocation.getFile() || /* istanbul ignore next */ ''; + const v2File = v2PrimaryLocation.getFile() || /* istanbul ignore next */ ''; if (v1File !== v2File) { return v1File.localeCompare(v2File); } // Next, compare start lines. - const v1StartLine = v1PrimaryLocation.getStartLine() || 0; - const v2StartLine = v2PrimaryLocation.getStartLine() || 0; + const v1StartLine = v1PrimaryLocation.getStartLine() || /* istanbul ignore next */ 0; + const v2StartLine = v2PrimaryLocation.getStartLine() || /* istanbul ignore next */ 0; if (v1StartLine !== v2StartLine) { return v1StartLine - v2StartLine; } // Next, compare start columns. - const v1StartColumn = v1PrimaryLocation.getStartColumn() || 0; - const v2StartColumn = v2PrimaryLocation.getStartColumn() || 0; + const v1StartColumn = v1PrimaryLocation.getStartColumn() || /* istanbul ignore next */ 0; + const v2StartColumn = v2PrimaryLocation.getStartColumn() || /* istanbul ignore next */ 0; return v1StartColumn - v2StartColumn; }); } @@ -196,6 +186,7 @@ function getPrimaryLocation(violation: Violation): CodeLocation { export function findLongestCommonParentFolderOf(filePaths: string[]): string { const roots: string[] = filePaths.map(filePath => path.parse(filePath).root); const commonRoot: string = (new Set(roots)).size === 1 ? roots[0] : ''; + // istanbul ignore next - Hard to test outside of Windows if (!commonRoot) { return ''; } diff --git a/src/lib/viewers/RunSummaryViewer.ts b/src/lib/viewers/RunSummaryViewer.ts deleted file mode 100644 index 290c464fb..000000000 --- a/src/lib/viewers/RunSummaryViewer.ts +++ /dev/null @@ -1,62 +0,0 @@ -import {RunResults, SeverityLevel} from '@salesforce/code-analyzer-core'; -import {Display} from '../Display'; -import {indent, toStyledHeader} from '../utils/StylingUtil'; -import {BundleName, getMessage} from '../messages'; - -export interface RunSummaryViewer { - view(results: RunResults, logFile: string, outfiles: string[]): void; -} - -export class RunSummaryDisplayer implements RunSummaryViewer { - protected display: Display; - - public constructor(display: Display) { - this.display = display; - } - - public view(results: RunResults, logFile: string, outfiles: string[]): void { - this.display.displayLog(toStyledHeader(getMessage(BundleName.RunSummaryViewer, 'summary.header'))); - // Use empty line as a visual separator - this.display.displayLog(''); - - if (results.getViolationCount() === 0) { - this.display.displayLog(getMessage(BundleName.RunSummaryViewer, 'summary.found-no-violations')); - } else { - this.displayResultsSummary(results); - } - // Use empty line as a visual separator - this.display.displayLog(''); - - if (outfiles.length === 0) { - this.display.displayLog(getMessage(BundleName.RunSummaryViewer, 'summary.no-outfiles')); - } else { - this.displayOutfiles(outfiles); - } - // Use empty line as a visual separator - this.display.displayLog(''); - - this.display.displayLog(getMessage(BundleName.RunSummaryViewer, 'summary.log-file-location')); - this.display.displayLog(indent(logFile)); - } - - private displayResultsSummary(results: RunResults): void { - this.display.displayLog(getMessage(BundleName.RunSummaryViewer, 'summary.violations-total', [results.getViolationCount()])); - for (const sev of Object.values(SeverityLevel)) { - // Some of the keys will be numbers, since the enum is numerical. Skip those. - if (typeof sev !== 'string') { - continue; - } - const sevCount = results.getViolationCountOfSeverity(SeverityLevel[sev] as SeverityLevel); - if (sevCount > 0) { - this.display.displayLog(indent(getMessage(BundleName.RunSummaryViewer, 'summary.violations-item', [sevCount, sev]))); - } - } - } - - private displayOutfiles(outfiles: string[]): void { - this.display.displayLog(getMessage(BundleName.RunSummaryViewer, 'summary.outfiles-total')); - for (const outfile of outfiles) { - this.display.displayLog(indent(outfile)); - } - } -} diff --git a/test/fixtures/comparison-files/lib/actions/RunAction.test.ts/action-summaries/no-violations.txt.goldfile b/test/fixtures/comparison-files/lib/actions/RunAction.test.ts/action-summaries/no-violations.txt.goldfile new file mode 100644 index 000000000..9b02dca8f --- /dev/null +++ b/test/fixtures/comparison-files/lib/actions/RunAction.test.ts/action-summaries/no-violations.txt.goldfile @@ -0,0 +1,6 @@ + +=== Summary + +Found 0 violations. + +Additional log information written to: \ No newline at end of file diff --git a/test/fixtures/comparison-files/lib/actions/RunAction.test.ts/action-summaries/some-outfiles.txt.goldfile b/test/fixtures/comparison-files/lib/actions/RunAction.test.ts/action-summaries/some-outfiles.txt.goldfile new file mode 100644 index 000000000..f0f45442b --- /dev/null +++ b/test/fixtures/comparison-files/lib/actions/RunAction.test.ts/action-summaries/some-outfiles.txt.goldfile @@ -0,0 +1,11 @@ + +=== Summary + +Found 1 violation(s) across 1 file(s): + 1 Low severity violation(s) found. + +Results written to: + {{PATH_TO_FILE1}} + {{PATH_TO_FILE2}} + +Additional log information written to: \ No newline at end of file diff --git a/test/fixtures/comparison-files/lib/actions/RunAction.test.ts/action-summaries/some-violations.txt.goldfile b/test/fixtures/comparison-files/lib/actions/RunAction.test.ts/action-summaries/some-violations.txt.goldfile new file mode 100644 index 000000000..7b04ba246 --- /dev/null +++ b/test/fixtures/comparison-files/lib/actions/RunAction.test.ts/action-summaries/some-violations.txt.goldfile @@ -0,0 +1,8 @@ + +=== Summary + +Found 2 violation(s) across 1 file(s): + 1 High severity violation(s) found. + 1 Low severity violation(s) found. + +Additional log information written to: \ No newline at end of file diff --git a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-identical-violations-details.txt b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-identical-violations-details.txt index b180c09b8..adb9b67b1 100644 --- a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-identical-violations-details.txt +++ b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-identical-violations-details.txt @@ -1,4 +1,4 @@ -Found 4 violation(s) across 1 file(s): + === 1. stub1RuleA severity: 4 (Low) engine: stubEngine1 diff --git a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-unique-violations-details.txt b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-unique-violations-details.txt index 35080fcf8..63f537b94 100644 --- a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-unique-violations-details.txt +++ b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-unique-violations-details.txt @@ -1,4 +1,4 @@ -Found 4 violation(s) across 2 file(s): + === 1. stub1RuleB severity: 2 (High) engine: stubEngine1 diff --git a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/one-multilocation-violation-details.txt b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/one-multilocation-violation-details.txt index 76806161e..d7fe30fca 100644 --- a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/one-multilocation-violation-details.txt +++ b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/one-multilocation-violation-details.txt @@ -1,4 +1,4 @@ -Found 1 violation(s) across 1 file(s): + === 1. stub1RuleA severity: 4 (Low) engine: stubEngine1 diff --git a/test/fixtures/comparison-files/lib/viewers/RunSummaryViewer.test.ts/four-unique-violations-summary.txt b/test/fixtures/comparison-files/lib/viewers/RunSummaryViewer.test.ts/four-unique-violations-summary.txt deleted file mode 100644 index fdfd3a17d..000000000 --- a/test/fixtures/comparison-files/lib/viewers/RunSummaryViewer.test.ts/four-unique-violations-summary.txt +++ /dev/null @@ -1,3 +0,0 @@ -Found 4 violation(s): - 1 High severity violation(s) found. - 3 Low severity violation(s) found. diff --git a/test/lib/actions/RunAction.test.ts b/test/lib/actions/RunAction.test.ts index 70a6cefa3..00f49487c 100644 --- a/test/lib/actions/RunAction.test.ts +++ b/test/lib/actions/RunAction.test.ts @@ -1,26 +1,31 @@ import path from 'node:path'; +import * as fsp from 'node:fs/promises'; import {SfError} from '@salesforce/core'; +import ansis from 'ansis'; import {SeverityLevel} from '@salesforce/code-analyzer-core'; import {SpyResultsViewer} from '../../stubs/SpyResultsViewer'; -import {SpyRunSummaryViewer} from '../../stubs/SpyRunSummaryViewer'; import {SpyResultsWriter} from '../../stubs/SpyResultsWriter'; +import {SpyDisplay, DisplayEventType} from '../../stubs/SpyDisplay'; import {StubDefaultConfigFactory} from '../../stubs/StubCodeAnalyzerConfigFactories'; import {ConfigurableStubEnginePlugin1, StubEngine1, TargetDependentEngine1} from '../../stubs/StubEnginePlugins'; import {RunAction, RunInput, RunDependencies} from '../../../src/lib/actions/RunAction'; +import {RunActionSummaryViewer} from '../../../src/lib/viewers/ActionSummaryViewer'; import { StubEnginePluginsFactory_withPreconfiguredStubEngines, StubEnginePluginsFactory_withThrowingStubPlugin } from '../../stubs/StubEnginePluginsFactories'; const PATH_TO_FILE_A = path.resolve('test', 'sample-code', 'fileA.cls'); +const PATH_TO_GOLDFILES = path.join(__dirname, '..', '..', 'fixtures', 'comparison-files', 'lib', 'actions', 'RunAction.test.ts'); describe('RunAction tests', () => { + let spyDisplay: SpyDisplay; let engine1: StubEngine1; let stubEnginePlugin: ConfigurableStubEnginePlugin1; let pluginsFactory: StubEnginePluginsFactory_withPreconfiguredStubEngines; let writer: SpyResultsWriter; let resultsViewer: SpyResultsViewer; - let runSummaryViewer: SpyRunSummaryViewer; + let actionSummaryViewer: RunActionSummaryViewer; let dependencies: RunDependencies; let action: RunAction; @@ -33,9 +38,10 @@ describe('RunAction tests', () => { pluginsFactory.addPreconfiguredEnginePlugin(stubEnginePlugin); // Set up the writer and viewers. + spyDisplay = new SpyDisplay(); writer = new SpyResultsWriter(); resultsViewer = new SpyResultsViewer(); - runSummaryViewer = new SpyRunSummaryViewer(); + actionSummaryViewer = new RunActionSummaryViewer(spyDisplay); // Initialize our dependency object. dependencies = { @@ -45,7 +51,7 @@ describe('RunAction tests', () => { progressListeners: [], writer, resultsViewer, - runSummaryViewer + actionSummaryViewer }; // Create the action. action = RunAction.createAction(dependencies); @@ -94,8 +100,6 @@ describe('RunAction tests', () => { expect(writer.getCallHistory()[0].getViolations()[0].getMessage()).toEqual('Fake message'); expect(resultsViewer.getCallHistory()[0].getViolationCount()).toEqual(1); expect(resultsViewer.getCallHistory()[0].getViolations()[0].getMessage()).toEqual('Fake message'); - expect(runSummaryViewer.getCallHistory()[0].results.getViolationCount()).toEqual(1); - expect(runSummaryViewer.getCallHistory()[0].results.getViolations()[0].getMessage()).toEqual('Fake message'); }); it('Engines with target-dependent rules run the right rules', async () => { @@ -217,7 +221,7 @@ describe('RunAction tests', () => { progressListeners: [], writer, resultsViewer, - runSummaryViewer + actionSummaryViewer }; // Instantiate our action, intentionally using a different instance than the one set up in // the before-each. @@ -234,6 +238,116 @@ describe('RunAction tests', () => { // ==== ASSERTIONS ==== await expect(executionPromise).rejects.toThrow('SomeErrorFromGetAvailableEngineNames'); }); + + describe('Summary generation', () => { + it.each([ + {quantifier: 'no', expectation: 'Summarizer reflects this fact', goldfile: 'no-violations.txt.goldfile', resultsToReturn: []}, + {quantifier: 'some', expectation: 'Summarizer breaks them down by severity', goldfile: 'some-violations.txt.goldfile', + resultsToReturn: [{ + ruleName: 'stub1RuleA', + message: 'Fake message', + codeLocations: [{ + file: PATH_TO_FILE_A, + startLine: 5, + startColumn: 1 + }], + primaryLocationIndex: 0 + }, { + ruleName: 'stub1RuleB', + message: 'Fake message', + codeLocations: [{ + file: PATH_TO_FILE_A, + startLine: 5, + startColumn: 1 + }], + primaryLocationIndex: 0 + }] + } + ])('When $quantifier violations are found, $expectation', async ({resultsToReturn, goldfile}) => { + // ==== SETUP ==== + const expectedRules = ['stub1RuleA', 'stub1RuleB', 'stub1RuleC', 'stub1RuleD', 'stub1RuleE'] + // Create the input. + const input: RunInput = { + // Use the selector provided by the test + 'rule-selector': ['all'], + // Use the current directory, for convenience. + 'workspace': ['.'], + // Outfile is just an empty list + 'output-file': [] + }; + // Configure the engine to return a violation for the first expected rule. + engine1.resultsToReturn = { + violations: resultsToReturn + }; + + // ==== TESTED BEHAVIOR ==== + await action.execute(input); + + // ==== ASSERTIONS ==== + // Verify that the expected rules were executed on the right files. + const actualExecutedRules = engine1.runRulesCallHistory[0].ruleNames; + expect(actualExecutedRules).toEqual(expectedRules); + const actualTargetFiles = engine1.runRulesCallHistory[0].runOptions.workspace.getFilesAndFolders(); + expect(actualTargetFiles).toEqual([path.resolve('.')]); + // Verify that the summary output matches the expectation. + const goldfileContents: string = await fsp.readFile(path.join(PATH_TO_GOLDFILES, 'action-summaries', goldfile), 'utf-8'); + const displayEvents = spyDisplay.getDisplayEvents(); + const displayedLogEvents = ansis.strip(displayEvents + .filter(e => e.type === DisplayEventType.LOG) + .map(e => e.data) + .join('\n')); + expect(displayedLogEvents).toContain(goldfileContents); + }); + + it('When Outfiles are provided, they are mentioned', async () => { + // ==== SETUP ==== + const expectedRules = ['stub1RuleA', 'stub1RuleB', 'stub1RuleC', 'stub1RuleD', 'stub1RuleE'] + const outfilePath1 = path.join('the', 'specifics', 'of', 'this', 'path', 'do', 'not', 'matter.csv'); + const outfilePath2 = path.join('neither', 'do', 'the', 'specifics', 'of', 'this', 'one.json'); + // Create the input. + const input: RunInput = { + // Use the selector provided by the test + 'rule-selector': ['all'], + // Use the current directory, for convenience. + 'workspace': ['.'], + // Outfiles are provided + 'output-file': [outfilePath1, outfilePath2] + }; + // Configure the engine to return a violation for the first expected rule. + engine1.resultsToReturn = { + violations: [{ + ruleName: 'stub1RuleA', + message: 'Fake message', + codeLocations: [{ + file: PATH_TO_FILE_A, + startLine: 5, + startColumn: 1 + }], + primaryLocationIndex: 0 + }] + }; + + // ==== TESTED BEHAVIOR ==== + await action.execute(input); + + // ==== ASSERTIONS ==== + // Verify that the expected rules were executed on the right files. + const actualExecutedRules = engine1.runRulesCallHistory[0].ruleNames; + expect(actualExecutedRules).toEqual(expectedRules); + const actualTargetFiles = engine1.runRulesCallHistory[0].runOptions.workspace.getFilesAndFolders(); + expect(actualTargetFiles).toEqual([path.resolve('.')]); + // Verify that the summary output matches the expectation. + const goldfileContents: string = (await fsp.readFile(path.join(PATH_TO_GOLDFILES, 'action-summaries', 'some-outfiles.txt.goldfile'), 'utf-8')) + .replace(`{{PATH_TO_FILE1}}`, outfilePath1) + .replace(`{{PATH_TO_FILE2}}`, outfilePath2); + const displayEvents = spyDisplay.getDisplayEvents(); + const displayedLogEvents = ansis.strip(displayEvents + .filter(e => e.type === DisplayEventType.LOG) + .map(e => e.data) + .join('\n')); + expect(displayedLogEvents).toContain(goldfileContents); + }); + }); }); // TODO: Whenever we decide to document the custom_engine_plugin_modules flag in our configuration file, then we'll want diff --git a/test/lib/listeners/ProgressEventListener.test.ts b/test/lib/listeners/ProgressEventListener.test.ts index f875cd087..e2b85be67 100644 --- a/test/lib/listeners/ProgressEventListener.test.ts +++ b/test/lib/listeners/ProgressEventListener.test.ts @@ -247,7 +247,7 @@ describe('ProgressEventListener implementations', () => { const startEvent = displayEvents[0]; expect(startEvent).toHaveProperty('type', DisplayEventType.SPINNER_START); // The start event should always start with at least 1 known engine, to prevent "0 of 0 engines" scenarios. - expect(startEvent.data).toContain("1 of 1 engines"); + expect(startEvent.data).toContain("0 of 1 engines"); const percentagesInOrder = getDedupedCompletionPercentages(displayEvents.slice(1, displayEvents.length - 1)); expect(percentagesInOrder).toEqual([0, 50, 100]); const endEvent = displayEvents[displayEvents.length - 1]; diff --git a/test/lib/viewers/ResultsViewer.test.ts b/test/lib/viewers/ResultsViewer.test.ts index fa0044a4c..6e642ce87 100644 --- a/test/lib/viewers/ResultsViewer.test.ts +++ b/test/lib/viewers/ResultsViewer.test.ts @@ -223,11 +223,13 @@ describe('ResultsViewer implementations', () => { // ==== ASSERTIONS ==== const displayEvents = spyDisplay.getDisplayEvents(); - expect(displayEvents).toHaveLength(3); + expect(displayEvents).toHaveLength(4); expect(displayEvents[0].type).toEqual(DisplayEventType.LOG); - expect(displayEvents[0].data).toEqual(getMessage(BundleName.ResultsViewer, 'summary.table.found-results', [4, 1, PATH_TO_SAMPLE_CODE])); - expect(displayEvents[1].type).toEqual(DisplayEventType.TABLE); - expect(displayEvents[1].data).toEqual(`{"columns":["#","Severity","Rule","Location","Message"],"rows":[{"num":1,"location":"someFile.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"},{"num":2,"location":"someFile.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"},{"num":3,"location":"someFile.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"},{"num":4,"location":"someFile.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"}]}`); + expect(displayEvents[0].data).toEqual(''); + expect(displayEvents[1].type).toEqual(DisplayEventType.LOG); + expect(displayEvents[1].data).toEqual(getMessage(BundleName.ResultsViewer, 'summary.table.results-relative-to', [PATH_TO_SAMPLE_CODE])); + expect(displayEvents[2].type).toEqual(DisplayEventType.TABLE); + expect(displayEvents[2].data).toEqual(`{"columns":["#","Severity","Rule","Location","Message"],"rows":[{"num":1,"location":"someFile.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"},{"num":2,"location":"someFile.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"},{"num":3,"location":"someFile.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"},{"num":4,"location":"someFile.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"}]}`); }); // The reasoning behind this sorting order is so that the Table view can function as a "show me all the violations @@ -255,11 +257,13 @@ describe('ResultsViewer implementations', () => { // ==== ASSERTIONS ==== const displayEvents = spyDisplay.getDisplayEvents(); - expect(displayEvents).toHaveLength(3); + expect(displayEvents).toHaveLength(4); expect(displayEvents[0].type).toEqual(DisplayEventType.LOG); - expect(displayEvents[0].data).toEqual(getMessage(BundleName.ResultsViewer, 'summary.table.found-results', [4, 2, PATH_TO_SAMPLE_CODE])); - expect(displayEvents[1].type).toEqual(DisplayEventType.TABLE); - expect(displayEvents[1].data).toEqual(`{"columns":["#","Severity","Rule","Location","Message"],"rows":[{"num":1,"location":"fileZ.cls:20:1","rule":"stubEngine1:stub1RuleB","severity":"2 (High)","message":"This is a message"},{"num":2,"location":"fileA.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"},{"num":3,"location":"fileA.cls:20:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"},{"num":4,"location":"fileZ.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"}]}`); + expect(displayEvents[0].data).toEqual(''); + expect(displayEvents[1].type).toEqual(DisplayEventType.LOG); + expect(displayEvents[1].data).toEqual(getMessage(BundleName.ResultsViewer, 'summary.table.results-relative-to', [PATH_TO_SAMPLE_CODE])); + expect(displayEvents[2].type).toEqual(DisplayEventType.TABLE); + expect(displayEvents[2].data).toEqual(`{"columns":["#","Severity","Rule","Location","Message"],"rows":[{"num":1,"location":"fileZ.cls:20:1","rule":"stubEngine1:stub1RuleB","severity":"2 (High)","message":"This is a message"},{"num":2,"location":"fileA.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"},{"num":3,"location":"fileA.cls:20:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"},{"num":4,"location":"fileZ.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"}]}`); }); }); }); diff --git a/test/lib/viewers/RunSummaryViewer.test.ts b/test/lib/viewers/RunSummaryViewer.test.ts deleted file mode 100644 index 7a06b8d4f..000000000 --- a/test/lib/viewers/RunSummaryViewer.test.ts +++ /dev/null @@ -1,150 +0,0 @@ -import fs from "node:fs/promises"; -import path from "node:path"; -import ansis from 'ansis'; -import {CodeAnalyzer, CodeAnalyzerConfig, RunResults} from '@salesforce/code-analyzer-core'; -import {Violation} from "@salesforce/code-analyzer-engine-api"; - -import {RunSummaryDisplayer} from '../../../src/lib/viewers/RunSummaryViewer'; - -import {DisplayEvent, DisplayEventType, SpyDisplay} from "../../stubs/SpyDisplay"; -import {FunctionalStubEnginePlugin1, StubEngine1} from '../../stubs/StubEnginePlugins'; - -const PATH_TO_COMPARISON_FILES = path.resolve(__dirname, '..', '..', '..', 'test', 'fixtures', 'comparison-files', 'lib', - 'viewers', 'RunSummaryViewer.test.ts'); -const PATH_TO_SAMPLE_CODE = path.resolve(__dirname, '..', '..', '..', 'test', 'sample-code'); -const PATH_TO_OUTFILE1 = path.join('the', 'specifics', 'of', 'this', 'path', 'do', 'not', 'matter.csv'); -const PATH_TO_OUTFILE2 = path.join('neither', 'do', 'the', 'specifics', 'of', 'this', 'one.json'); -const PATH_TO_FILE_A = path.resolve(PATH_TO_SAMPLE_CODE, 'fileA.cls'); -const PATH_TO_FILE_Z = path.resolve(PATH_TO_SAMPLE_CODE, 'fileZ.cls'); - -describe('RunSummaryViewer implementations', () => { - // We need SpyDisplays for the cases where inputs are empty and non-empty. - const emptyInputsSpyDisplay: SpyDisplay = new SpyDisplay(); - const nonEmptyInputsSpyDisplay: SpyDisplay = new SpyDisplay(); - - // We need a config, core, and plugin. - const config: CodeAnalyzerConfig = CodeAnalyzerConfig.withDefaults(); - const codeAnalyzerCore: CodeAnalyzer = new CodeAnalyzer(config); - const stubEnginePlugin: FunctionalStubEnginePlugin1 = new FunctionalStubEnginePlugin1(); - - let emptyResults: RunResults; - let nonEmptyResults: RunResults; - - // The tests are similar enough that we can do all of the setup in the `beforeAll()` functions. - beforeAll(async () => { - // Add the stub plugin to the core. - await codeAnalyzerCore.addEnginePlugin(stubEnginePlugin); - - // Run the core once without assigning any violations. - const workspace = await codeAnalyzerCore.createWorkspace(['package.json']); - const rules = await codeAnalyzerCore.selectRules(['all'], {workspace}); - emptyResults = await codeAnalyzerCore.run(rules, {workspace}); - - // Assign some violations and then run the core again. - const engine1 = stubEnginePlugin.getCreatedEngine(`stubEngine1`) as StubEngine1; - const rule1 = (await engine1.describeRules())[0]; - const rule2 = (await engine1.describeRules())[1]; - const violations: Violation[] = [ - // A low-severity violation late in a high-alphabetical file. - createViolation(rule1.name, PATH_TO_FILE_A, 20, 1), - // A low-severity violation early in the same high-alphabetical file. - createViolation(rule1.name, PATH_TO_FILE_A, 1, 1), - // A low-severity violation early in a low-alphabetical file. - createViolation(rule1.name, PATH_TO_FILE_Z, 1, 1), - // A high-severity violation later in the same low-alphabetical file. - createViolation(rule2.name, PATH_TO_FILE_Z, 20, 1) - ]; - engine1.resultsToReturn = {violations}; - - nonEmptyResults = await codeAnalyzerCore.run(rules, {workspace}); - }); - - describe('RunSummaryDisplayer', () => { - // Create Displayers for the empty-input and non-empty-input cases. - const emptyInputsDisplayer: RunSummaryDisplayer = new RunSummaryDisplayer(emptyInputsSpyDisplay); - const nonEmptyInputsDisplayer: RunSummaryDisplayer = new RunSummaryDisplayer(nonEmptyInputsSpyDisplay); - const fakeLogFile: string = path.join('path', 'to', 'fakelogfile.log'); - - let emptyInputsDisplayEvents: DisplayEvent[]; - let nonEmptyInputsDisplayEvents: DisplayEvent[]; - - beforeAll(() => { - emptyInputsDisplayer.view(emptyResults, fakeLogFile, []); - emptyInputsDisplayEvents = emptyInputsSpyDisplay.getDisplayEvents(); - nonEmptyInputsDisplayer.view(nonEmptyResults, fakeLogFile, [PATH_TO_OUTFILE1, PATH_TO_OUTFILE2]) - nonEmptyInputsDisplayEvents = nonEmptyInputsSpyDisplay.getDisplayEvents(); - }); - - describe('Formatting', () => { - it('Output has correct header', () => { - expect(ansis.strip(emptyInputsDisplayEvents[0].data)).toEqual('=== Summary'); - expect(ansis.strip(nonEmptyInputsDisplayEvents[0].data)).toEqual('=== Summary'); - }); - - it('Output has correct log level', () => { - for (const event of emptyInputsDisplayEvents) { - expect(event.type).toEqual(DisplayEventType.LOG); - } - for (const event of nonEmptyInputsDisplayEvents) { - expect(event.type).toEqual(DisplayEventType.LOG); - } - }); - }); - - describe('Results breakdown', () => { - it('When no violations exist, correctly outputs this fact', () => { - const contents = emptyInputsDisplayEvents.map(e => e.data).join('\n'); - expect(contents).toContain('Found 0 violations.\n'); - }); - - it('When violations exist, they are broken down by severity', async () => { - const contents = nonEmptyInputsDisplayEvents.map(e => e.data).join('\n'); - const expectedViolationSummary = await readComparisonFile('four-unique-violations-summary.txt'); - expect(contents).toContain(expectedViolationSummary); - }); - }); - - describe('Outfile breakdown', () => { - it('When no outfiles were provided, correctly outputs this fact', () => { - const contents = emptyInputsDisplayEvents.map(e => e.data).join('\n'); - expect(contents).toContain('No results files were specified.\n'); - }); - - it('When outfiles were provided, they are properly listed', () => { - const contents = nonEmptyInputsDisplayEvents.map(e => e.data).join('\n'); - const expectation = `Results written to:\n` + - ` ${PATH_TO_OUTFILE1}\n` + - ` ${PATH_TO_OUTFILE2}\n`; - expect(contents).toContain(expectation); - }); - }); - - describe('Logging breakdown', () => { - it('Logfile is correctly displayed', () => { - const expectation = `Additional log information written to:\n` + - ` ${fakeLogFile}`; - const emptyContents = emptyInputsDisplayEvents.map(e => e.data).join('\n'); - const nonEmptyContents = nonEmptyInputsDisplayEvents.map(e => e.data).join('\n'); - expect(emptyContents).toContain(expectation); - expect(nonEmptyContents).toContain(expectation); - }); - }); - }); -}); - -function createViolation(ruleName: string, file: string, startLine: number, startColumn: number): Violation { - return { - ruleName, - message: 'This is a message', - codeLocations: [{ - file, - startLine, - startColumn - }], - primaryLocationIndex: 0 - }; -} - -function readComparisonFile(fileName: string): Promise { - return fs.readFile(path.join(PATH_TO_COMPARISON_FILES, fileName), {encoding: 'utf-8'}); -} From c11ca621688ba27041d117518c17a591bb8396bf Mon Sep 17 00:00:00 2001 From: Stephen Carter Date: Fri, 15 Nov 2024 11:48:24 -0500 Subject: [PATCH 08/35] NEW: @W-17100389@: Add in feedback url to help text and log --- messages/config-command.md | 2 ++ messages/path-start-util.md | 4 ++-- messages/rules-command.md | 2 ++ messages/run-command.md | 2 ++ messages/shared.md | 4 ++++ messages/workspace-util.md | 2 +- src/lib/listeners/LogEventListener.ts | 2 ++ 7 files changed, 15 insertions(+), 3 deletions(-) diff --git a/messages/config-command.md b/messages/config-command.md index a7d73693f..1339fa37f 100644 --- a/messages/config-command.md +++ b/messages/config-command.md @@ -8,6 +8,8 @@ Code Analyzer gives you the ability to configure settings that modify Code Analy To apply a custom configuration with Code Analyzer, either keep your custom configuration settings in a `code-analyzer.yml` file located in the current folder from which you are executing commands, or specify the location of your custom configuration file to the Code Analyzer commands with the --config-file flag. +We're continually improving Salesforce Code Analyzer. Tell us what you think! Give feedback at http://sfdc.co/CodeAnalyzerFeedback. + # command.examples - Display the current state of the Code Analyzer configuration using the default behavior: display top level configuration, display the engine and rule override settings associated with all the rules that have a "Recommended" tag; and automatically apply any existing custom configuration settings found in a `code-analyzer.yml` or `code-analyzer.yaml` file in the current folder: diff --git a/messages/path-start-util.md b/messages/path-start-util.md index 8c8415903..832162d91 100644 --- a/messages/path-start-util.md +++ b/messages/path-start-util.md @@ -1,7 +1,7 @@ # error.glob-method-conflict -*DRAFT*: Path start point %s is invalid: When specifying a method with the #methodName syntax, glob patterns cannot be used. +Path start point %s is invalid: When specifying a method with the #methodName syntax, glob patterns cannot be used. # error.negative-globs-unsupported -*DRAFT*: Path start point %s is invalid: Negative globs are unsupported. +Path start point %s is invalid: Negative globs are unsupported. diff --git a/messages/rules-command.md b/messages/rules-command.md index d225950b3..7e2e243d3 100644 --- a/messages/rules-command.md +++ b/messages/rules-command.md @@ -8,6 +8,8 @@ You can also view details about the rules, such as the engine it's associated wi Use this command to determine the exact set of rules to analyze your code. The `code-analyzer run` command has similar flags as this command, so once you've determined the flag values for this command that list the rules you want to run, you specify the same values to the `code-analyzer run` command. +We're continually improving Salesforce Code Analyzer. Tell us what you think! Give feedback at http://sfdc.co/CodeAnalyzerFeedback. + # command.examples - List rules using the default behavior: include rules from all engines that have a "Recommended" tag; display the rules using concise table format; and automatically apply rule or engine overrides if a "code-analyzer.yml" or "code-analyzer.yaml" file exists in the current folder: diff --git a/messages/run-command.md b/messages/run-command.md index 154d493b7..ee74f6edf 100644 --- a/messages/run-command.md +++ b/messages/run-command.md @@ -8,6 +8,8 @@ You can scan your codebase with the recommended rules. Or use flags to filter th If you want to preview the list of rules before you actually run them, use the `code-analyzer rules` command, which also has the "--rules-selector", "--workspace", and "--config-file" flags that together define the list of rules to be run. +We're continually improving Salesforce Code Analyzer. Tell us what you think! Give feedback at http://sfdc.co/CodeAnalyzerFeedback. + # command.examples - Analyze code using the default behavior: analyze the files in the current folder (default workspace) using the Recommended rules; display the output in the terminal with the concise table view; and automatically apply rule or engine overrides if a "code-analyzer.yml" or "code-analyzer.yaml" file exists in the current folder: diff --git a/messages/shared.md b/messages/shared.md index c39149101..039af4710 100644 --- a/messages/shared.md +++ b/messages/shared.md @@ -5,3 +5,7 @@ Developer Preview # warning.command-state This command is in %s. + +# log.give-us-feedback + +We're continually improving Salesforce Code Analyzer. Tell us what you think! Give feedback at http://sfdc.co/CodeAnalyzerFeedback. diff --git a/messages/workspace-util.md b/messages/workspace-util.md index c9b61fa7f..57b4ac1fe 100644 --- a/messages/workspace-util.md +++ b/messages/workspace-util.md @@ -1,3 +1,3 @@ # error.negative-globs-unsupported -*DRAFT*: Workspace path %s is invalid: Negative globs are unsupported. +Workspace path %s is invalid: Negative globs are unsupported. diff --git a/src/lib/listeners/LogEventListener.ts b/src/lib/listeners/LogEventListener.ts index f717f5d59..41e8a0379 100644 --- a/src/lib/listeners/LogEventListener.ts +++ b/src/lib/listeners/LogEventListener.ts @@ -1,6 +1,7 @@ import {CodeAnalyzer, EngineLogEvent, EventType, LogEvent, LogLevel} from '@salesforce/code-analyzer-core'; import {Display} from '../Display'; import {LogWriter} from '../writers/LogWriter'; +import {BundleName, getMessage} from "../messages"; export interface LogEventListener { listen(codeAnalyzer: CodeAnalyzer): void; @@ -58,6 +59,7 @@ export class LogEventLogger implements LogEventListener { } public stopListening(): void { + this.logWriter.writeToLog('\n' + getMessage(BundleName.Shared, 'log.give-us-feedback')); this.logWriter.closeLog(); } From 812864d8ce920e9ae9d2487644e209bbfdb28601 Mon Sep 17 00:00:00 2001 From: Stephen Carter Date: Fri, 15 Nov 2024 12:03:43 -0500 Subject: [PATCH 09/35] Implement review feedback --- messages/path-start-util.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messages/path-start-util.md b/messages/path-start-util.md index 832162d91..e40d93bcf 100644 --- a/messages/path-start-util.md +++ b/messages/path-start-util.md @@ -1,6 +1,6 @@ # error.glob-method-conflict -Path start point %s is invalid: When specifying a method with the #methodName syntax, glob patterns cannot be used. +Path start point %s is invalid: You can't use glob patterns when specifying a method with the #methodName syntax. # error.negative-globs-unsupported From 676a2b8e1ca9fcea9eab784ebf3fd14de2078158 Mon Sep 17 00:00:00 2001 From: Josh Feingold Date: Mon, 18 Nov 2024 13:35:44 -0600 Subject: [PATCH 10/35] CHANGE @W-17100347@ Removed mentions of JUnit from CLI (#1675) --- messages/results-writer.md | 2 +- messages/run-command.md | 1 - src/lib/writers/ResultsWriter.ts | 3 --- test/lib/writers/ResultsWriter.test.ts | 4 ---- 4 files changed, 1 insertion(+), 9 deletions(-) diff --git a/messages/results-writer.md b/messages/results-writer.md index b29c1060c..03076e48e 100644 --- a/messages/results-writer.md +++ b/messages/results-writer.md @@ -1,3 +1,3 @@ # error.unrecognized-file-format -The output file %s has an unsupported extension. Valid extensions include: .csv; .html/.htm; .json; .junit/.junit.xml; .sarif/.sarif.json; .xml. +The output file %s has an unsupported extension. Valid extensions include: .csv; .html/.htm; .json; .sarif/.sarif.json; .xml. diff --git a/messages/run-command.md b/messages/run-command.md index ee74f6edf..d001a3cc7 100644 --- a/messages/run-command.md +++ b/messages/run-command.md @@ -133,7 +133,6 @@ If you don't specify this flag, the command outputs the results in the terminal. - .csv - .html or .htm - .json -- .junit or .junit.xml - .sarif or .sarif.json - .xml diff --git a/src/lib/writers/ResultsWriter.ts b/src/lib/writers/ResultsWriter.ts index 4fcae8a7c..0f6acf073 100644 --- a/src/lib/writers/ResultsWriter.ts +++ b/src/lib/writers/ResultsWriter.ts @@ -39,9 +39,6 @@ export class ResultsFileWriter implements ResultsWriter { // Check for `.json` AFTER checking for `.sarif.json`! } else if (ext === '.json') { this.format = OutputFormat.JSON; - } else if (ext === '.junit' || file.toLowerCase().endsWith('.junit.xml')) { - throw new Error('TODO: Support JUNIT-type output'); - // Check for `.xml` AFTER checking for `.junit.xml`! } else if (ext === '.xml') { this.format = OutputFormat.XML; } else { diff --git a/test/lib/writers/ResultsWriter.test.ts b/test/lib/writers/ResultsWriter.test.ts index 9fc6a6c02..b8f2ca632 100644 --- a/test/lib/writers/ResultsWriter.test.ts +++ b/test/lib/writers/ResultsWriter.test.ts @@ -23,8 +23,6 @@ describe('ResultsWriter implementations', () => { {ext: '.html', expectedOutput: `Results formatted as ${OutputFormat.HTML}`}, {ext: '.htm', expectedOutput: `Results formatted as ${OutputFormat.HTML}`}, {ext: '.json', expectedOutput: `Results formatted as ${OutputFormat.JSON}`}, - //{ext: '.junit', expectedOutput: `Results formatted as ${OutputFormat.JUNIT}`}, - //{ext: '.junit.xml', expectedOutput: `Results formatted as ${OutputFormat.JUNIT}`}, //{ext: '.sarif', expectedOutput: `Results formatted as ${OutputFormat.SARIF}`}, //{ext: '.sarif.json', expectedOutput: `Results formatted as ${OutputFormat.SARIF}`}, {ext: '.xml', expectedOutput: `Results formatted as ${OutputFormat.XML}`} @@ -48,8 +46,6 @@ describe('ResultsWriter implementations', () => { * in the case array for the valid format tests. */ it.each([ - {ext: '.junit'}, - {ext: '.junit.xml'}, {ext: '.sarif'}, {ext: '.sarif.json'} ])('Throws TODO error for not-yet-supported format: *$ext', ({ext}) => { From d4daca7477289d13e94b58cb4fbb81acc9acd738 Mon Sep 17 00:00:00 2001 From: Josh Feingold Date: Wed, 20 Nov 2024 11:18:28 -0600 Subject: [PATCH 11/35] @W-17281128@ Reworked interaction between -v and -f (#1676) --- messages/run-command.md | 2 + src/commands/code-analyzer/run.ts | 24 ++++++++--- src/lib/viewers/ResultsViewer.ts | 7 +++ test/commands/code-analyzer/run.test.ts | 57 +++++++++++++++++-------- 4 files changed, 66 insertions(+), 24 deletions(-) diff --git a/messages/run-command.md b/messages/run-command.md index d001a3cc7..bb2ee25d9 100644 --- a/messages/run-command.md +++ b/messages/run-command.md @@ -122,6 +122,8 @@ Format to display the command results in the terminal. The format `table` is concise and shows minimal output, the format `detail` shows all available information. +If you specify neither --view nor --output-file, then the default table view is shown. If you specify --output-file but not --view, only summary information is shown. + # flags.output-file.summary Output file that contains the analysis results. The file format depends on the extension you specify, such as .csv, .html, .xml, and so on. diff --git a/src/commands/code-analyzer/run.ts b/src/commands/code-analyzer/run.ts index 247cab9ff..16fa2b2e5 100644 --- a/src/commands/code-analyzer/run.ts +++ b/src/commands/code-analyzer/run.ts @@ -5,7 +5,7 @@ import {View} from '../../Constants'; import {CodeAnalyzerConfigFactoryImpl} from '../../lib/factories/CodeAnalyzerConfigFactory'; import {EnginePluginsFactoryImpl} from '../../lib/factories/EnginePluginsFactory'; import {CompositeResultsWriter} from '../../lib/writers/ResultsWriter'; -import {ResultsDetailDisplayer, ResultsTableDisplayer} from '../../lib/viewers/ResultsViewer'; +import {ResultsDetailDisplayer, ResultsNoOpDisplayer, ResultsTableDisplayer, ResultsViewer} from '../../lib/viewers/ResultsViewer'; import {RunActionSummaryViewer} from '../../lib/viewers/ActionSummaryViewer'; import {BundleName, getMessage, getMessages} from '../../lib/messages'; import {LogEventDisplayer} from '../../lib/listeners/LogEventListener'; @@ -59,7 +59,6 @@ export default class RunCommand extends SfCommand implements Displayable { summary: getMessage(BundleName.RunCommand, 'flags.view.summary'), description: getMessage(BundleName.RunCommand, 'flags.view.description'), char: 'v', - default: View.TABLE, options: Object.values(View) }), 'output-file': Flags.string({ @@ -83,7 +82,7 @@ export default class RunCommand extends SfCommand implements Displayable { this.warn(getMessage(BundleName.Shared, "warning.command-state", [getMessage(BundleName.Shared, 'label.command-state')])); const parsedFlags = (await this.parse(RunCommand)).flags; - const dependencies: RunDependencies = this.createDependencies(parsedFlags.view as View, parsedFlags['output-file']); + const dependencies: RunDependencies = this.createDependencies(parsedFlags.view as View|undefined, parsedFlags['output-file']); const action: RunAction = RunAction.createAction(dependencies); const runInput: RunInput = { 'config-file': parsedFlags['config-file'], @@ -97,17 +96,16 @@ export default class RunCommand extends SfCommand implements Displayable { await action.execute(runInput); } - protected createDependencies(view: View, outputFiles: string[] = []): RunDependencies { + protected createDependencies(view: View|undefined, outputFiles: string[] = []): RunDependencies { const uxDisplay: UxDisplay = new UxDisplay(this, this.spinner); + const resultsViewer: ResultsViewer = createResultsViewer(view, outputFiles, uxDisplay); return { configFactory: new CodeAnalyzerConfigFactoryImpl(), pluginsFactory: new EnginePluginsFactoryImpl(), writer: CompositeResultsWriter.fromFiles(outputFiles), logEventListeners: [new LogEventDisplayer(uxDisplay)], progressListeners: [new EngineRunProgressSpinner(uxDisplay), new RuleSelectionProgressSpinner(uxDisplay)], - resultsViewer: view === View.TABLE - ? new ResultsTableDisplayer(uxDisplay) - : new ResultsDetailDisplayer(uxDisplay), + resultsViewer, actionSummaryViewer: new RunActionSummaryViewer(uxDisplay) }; } @@ -138,3 +136,15 @@ function convertThresholdToEnum(threshold: string): SeverityLevel { } } +function createResultsViewer(view: View|undefined, outputFiles: string[], uxDisplay: UxDisplay): ResultsViewer { + switch (view) { + case View.DETAIL: + return new ResultsDetailDisplayer(uxDisplay); + case View.TABLE: + return new ResultsTableDisplayer(uxDisplay); + default: + return outputFiles.length === 0 + ? new ResultsTableDisplayer(uxDisplay) + : new ResultsNoOpDisplayer(); + } +} diff --git a/src/lib/viewers/ResultsViewer.ts b/src/lib/viewers/ResultsViewer.ts index 1c06b3950..d4ed113a5 100644 --- a/src/lib/viewers/ResultsViewer.ts +++ b/src/lib/viewers/ResultsViewer.ts @@ -9,6 +9,13 @@ export interface ResultsViewer { view(results: RunResults): void; } +export class ResultsNoOpDisplayer implements ResultsViewer { + public view(_results: RunResults): void { + // istanbul ignore next - No need to cover deliberate no-op + return; + } +} + abstract class AbstractResultsDisplayer implements ResultsViewer { protected display: Display; diff --git a/test/commands/code-analyzer/run.test.ts b/test/commands/code-analyzer/run.test.ts index 094ece083..74bb6c6ad 100644 --- a/test/commands/code-analyzer/run.test.ts +++ b/test/commands/code-analyzer/run.test.ts @@ -11,6 +11,8 @@ describe('`code-analyzer run` tests', () => { let createActionSpy: jest.SpyInstance; let receivedActionInput: RunInput; let receivedActionDependencies: RunDependencies; + let fromFilesSpy: jest.SpyInstance; + let receivedFiles: string[]; beforeEach(() => { stubSfCommandUx($$.SANDBOX); executeSpy = jest.spyOn(RunAction.prototype, 'execute').mockImplementation((input) => { @@ -22,6 +24,11 @@ describe('`code-analyzer run` tests', () => { receivedActionDependencies = dependencies; return originalCreateAction(dependencies); }); + const originalFromFiles = CompositeResultsWriter.fromFiles; + fromFilesSpy = jest.spyOn(CompositeResultsWriter, 'fromFiles').mockImplementation(files => { + receivedFiles = files; + return originalFromFiles(files); + }) }); afterEach(() => { @@ -231,17 +238,6 @@ describe('`code-analyzer run` tests', () => { }); describe('--output-file', () => { - let fromFilesSpy: jest.SpyInstance; - let receivedFiles: string[]; - - beforeEach(() => { - const originalFromFiles = CompositeResultsWriter.fromFiles; - fromFilesSpy = jest.spyOn(CompositeResultsWriter, 'fromFiles').mockImplementation(files => { - receivedFiles = files; - return originalFromFiles(files); - }) - }); - it('Can be supplied once with a single value', async () => { const inputValue = './somefile.json'; await RunCommand.run(['--output-file', inputValue]); @@ -312,12 +308,6 @@ describe('`code-analyzer run` tests', () => { expect(executeSpy).not.toHaveBeenCalled(); }); - it('Defaults to value of "table"', async () => { - await RunCommand.run([]); - expect(createActionSpy).toHaveBeenCalled(); - expect(receivedActionDependencies.resultsViewer.constructor.name).toEqual('ResultsTableDisplayer'); - }); - it('Can be supplied only once', async () => { const inputValue1 = 'detail'; const inputValue2 = 'table'; @@ -334,5 +324,38 @@ describe('`code-analyzer run` tests', () => { expect(receivedActionDependencies.resultsViewer.constructor.name).toEqual('ResultsDetailDisplayer'); }); }); + + describe('Flag interactions', () => { + describe('--output-file and --view', () => { + it('When --output-file and --view are both present, both are used', async () => { + const outfileInput = 'beep.json'; + const viewInput = 'detail'; + await RunCommand.run(['--output-file', outfileInput, '--view', viewInput]); + expect(executeSpy).toHaveBeenCalled(); + expect(createActionSpy).toHaveBeenCalled(); + expect(fromFilesSpy).toHaveBeenCalled(); + expect(receivedFiles).toEqual([outfileInput]); + expect(receivedActionDependencies.resultsViewer.constructor.name).toEqual('ResultsDetailDisplayer'); + }); + + it('When --output-file is present and --view is not, --view is a no-op', async () => { + const outfileInput= 'beep.json'; + await RunCommand.run(['--output-file', outfileInput]); + expect(executeSpy).toHaveBeenCalled(); + expect(createActionSpy).toHaveBeenCalled(); + expect(fromFilesSpy).toHaveBeenCalled(); + expect(receivedFiles).toEqual([outfileInput]); + expect(receivedActionDependencies.resultsViewer.constructor.name).toEqual('ResultsNoOpDisplayer'); + }); + + it('When --output-file and --view are both absent, --view defaults to "table"', async () => { + await RunCommand.run([]); + expect(createActionSpy).toHaveBeenCalled(); + expect(fromFilesSpy).toHaveBeenCalled(); + expect(receivedFiles).toEqual([]); + expect(receivedActionDependencies.resultsViewer.constructor.name).toEqual('ResultsTableDisplayer'); + }); + }); + }); }); From 6028a4d4ae3cad8bfc66976fa73b48e5192c2f3b Mon Sep 17 00:00:00 2001 From: Stephen Carter Date: Wed, 20 Nov 2024 14:09:59 -0500 Subject: [PATCH 12/35] CHANGE: @W-17272495@: Remove usage of RuleType and update dependencies --- package.json | 12 +- src/lib/viewers/RuleViewer.ts | 5 +- .../RuleViewer.test.ts/one-rule-details.txt | 1 - .../RuleViewer.test.ts/two-rules-details.txt | 2 - test/lib/actions/ConfigAction.test.ts | 10 - test/stubs/StubEnginePlugins.ts | 19 +- test/stubs/StubRules.ts | 10 +- yarn.lock | 1984 +++++++++-------- 8 files changed, 1061 insertions(+), 982 deletions(-) diff --git a/package.json b/package.json index 0b54578b8..361060367 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,12 @@ "bugs": "https://github.com/forcedotcom/sfdx-scanner/issues", "dependencies": { "@oclif/core": "^3.3.2", - "@salesforce/code-analyzer-core": "0.16.0", - "@salesforce/code-analyzer-engine-api": "0.13.0", - "@salesforce/code-analyzer-eslint-engine": "0.13.0", - "@salesforce/code-analyzer-pmd-engine": "0.13.0", - "@salesforce/code-analyzer-regex-engine": "0.13.0", - "@salesforce/code-analyzer-retirejs-engine": "0.13.0", + "@salesforce/code-analyzer-core": "0.17.0", + "@salesforce/code-analyzer-engine-api": "0.14.0", + "@salesforce/code-analyzer-eslint-engine": "0.14.0", + "@salesforce/code-analyzer-pmd-engine": "0.14.0", + "@salesforce/code-analyzer-regex-engine": "0.14.0", + "@salesforce/code-analyzer-retirejs-engine": "0.14.0", "@salesforce/core": "^5", "@salesforce/sf-plugins-core": "^5.0.4", "@salesforce/ts-types": "^2.0.9", diff --git a/src/lib/viewers/RuleViewer.ts b/src/lib/viewers/RuleViewer.ts index ed7246f52..d8519cae5 100644 --- a/src/lib/viewers/RuleViewer.ts +++ b/src/lib/viewers/RuleViewer.ts @@ -1,5 +1,5 @@ import {Ux} from '@salesforce/sf-plugins-core'; -import {Rule, RuleType, SeverityLevel} from '@salesforce/code-analyzer-core'; +import {Rule, SeverityLevel} from '@salesforce/code-analyzer-core'; import {Display} from '../Display'; import {toStyledHeaderAndBody} from '../utils/StylingUtil'; import {BundleName, getMessage} from '../messages'; @@ -41,12 +41,11 @@ export class RuleDetailDisplayer extends AbstractRuleDisplayer { const body = { engine: rule.getEngineName(), severity: `${severity.valueOf()} (${SeverityLevel[severity]})`, - type: RuleType[rule.getType()], tags: rule.getTags().join(', '), resources: rule.getResourceUrls().join(', '), description: rule.getDescription() }; - const keys = ['severity', 'engine', 'type', 'tags', 'resources', 'description']; + const keys = ['severity', 'engine', 'tags', 'resources', 'description']; styledRules.push(toStyledHeaderAndBody(header, body, keys)); } this.display.displayLog(styledRules.join('\n\n')); diff --git a/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/one-rule-details.txt b/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/one-rule-details.txt index c6d3e4d86..1a406a4a4 100644 --- a/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/one-rule-details.txt +++ b/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/one-rule-details.txt @@ -2,7 +2,6 @@ === 1. StubRule1 severity: 2 (High) engine: FakeEngine1 - type: Standard tags: Recommended, Security resources: www.google.com description: This is the description for a stub rule. Blah blah blah. diff --git a/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/two-rules-details.txt b/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/two-rules-details.txt index 9eaea142b..32f56f881 100644 --- a/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/two-rules-details.txt +++ b/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/two-rules-details.txt @@ -2,7 +2,6 @@ === 1. StubRule1 severity: 2 (High) engine: FakeEngine1 - type: Standard tags: Recommended, Security resources: www.google.com description: This is the description for a stub rule. Blah blah blah. @@ -10,7 +9,6 @@ === 2. StubRule2 severity: 4 (Low) engine: FakeEngine1 - type: Flow tags: CodeStyle, Performance resources: www.bing.com, www.salesforce.com description: This is the description for a second stub rule. Blah blah blah. diff --git a/test/lib/actions/ConfigAction.test.ts b/test/lib/actions/ConfigAction.test.ts index 84c536c08..ed9c0ae2c 100644 --- a/test/lib/actions/ConfigAction.test.ts +++ b/test/lib/actions/ConfigAction.test.ts @@ -655,56 +655,48 @@ class StubEngine1 extends EngineApi.Engine { return Promise.resolve([{ name: 'Stub1Rule1', severityLevel: EngineApi.SeverityLevel.Info, - type: EngineApi.RuleType.Standard, tags: ["Recommended", "CodeStyle"], description: 'Generic description', resourceUrls: [] }, { name: 'Stub1Rule2', severityLevel: EngineApi.SeverityLevel.Moderate, - type: EngineApi.RuleType.Standard, tags: ["CodeStyle"], description: 'Generic description', resourceUrls: [] }, { name: 'Stub1Rule3', severityLevel: EngineApi.SeverityLevel.Low, - type: EngineApi.RuleType.Standard, tags: ["BestPractices"], description: 'Generic description', resourceUrls: [] }, { name: 'Stub1Rule4', severityLevel: EngineApi.SeverityLevel.High, - type: EngineApi.RuleType.Standard, tags: ["CodeStyle"], description: 'Generic description', resourceUrls: [] }, { name: 'Stub1Rule5', severityLevel: EngineApi.SeverityLevel.High, - type: EngineApi.RuleType.Standard, tags: ["Recommended", "CodeStyle"], description: 'Generic description', resourceUrls: [] }, { name: 'Stub1Rule6', severityLevel: EngineApi.SeverityLevel.Low, - type: EngineApi.RuleType.Standard, tags: ["Recommended"], description: 'Generic description', resourceUrls: [] }, { name: 'Stub1Rule7', severityLevel: EngineApi.SeverityLevel.Moderate, - type: EngineApi.RuleType.Standard, tags: [], description: 'Generic description', resourceUrls: [] }, { name: 'Stub1Rule8', severityLevel: EngineApi.SeverityLevel.Moderate, - type: EngineApi.RuleType.Standard, tags: ['Recommended'], description: 'Generic description', resourceUrls: [] @@ -731,7 +723,6 @@ class StubEngine2 extends EngineApi.Engine { return Promise.resolve([{ name: 'Stub2Rule1', severityLevel: EngineApi.SeverityLevel.Moderate, - type: EngineApi.RuleType.Standard, tags: ['Security'], description: 'Generic description', resourceUrls: [] @@ -758,7 +749,6 @@ class StubEngine3 extends EngineApi.Engine { return Promise.resolve([{ name: 'Stub3Rule1', severityLevel: EngineApi.SeverityLevel.Moderate, - type: EngineApi.RuleType.Standard, tags: ['CodeStyle'], description: 'Generic description', resourceUrls: [] diff --git a/test/stubs/StubEnginePlugins.ts b/test/stubs/StubEnginePlugins.ts index 9a7cea070..42ce59450 100644 --- a/test/stubs/StubEnginePlugins.ts +++ b/test/stubs/StubEnginePlugins.ts @@ -93,7 +93,6 @@ export class StubEngine1 extends EngineApi.Engine { { name: "stub1RuleA", severityLevel: EngineApi.SeverityLevel.Low, - type: EngineApi.RuleType.Standard, tags: ["Recommended", "CodeStyle"], description: "Some description for stub1RuleA", resourceUrls: ["https://example.com/stub1RuleA"] @@ -101,7 +100,6 @@ export class StubEngine1 extends EngineApi.Engine { { name: "stub1RuleB", severityLevel: EngineApi.SeverityLevel.High, - type: EngineApi.RuleType.Standard, tags: ["Recommended", "Security"], description: "Some description for stub1RuleB", resourceUrls: ["https://example.com/stub1RuleB"] @@ -109,7 +107,6 @@ export class StubEngine1 extends EngineApi.Engine { { name: "stub1RuleC", severityLevel: EngineApi.SeverityLevel.Moderate, - type: EngineApi.RuleType.Standard, tags: ["Recommended", "Performance", "Custom"], description: "Some description for stub1RuleC", resourceUrls: ["https://example.com/stub1RuleC"] @@ -117,7 +114,6 @@ export class StubEngine1 extends EngineApi.Engine { { name: "stub1RuleD", severityLevel: EngineApi.SeverityLevel.Low, - type: EngineApi.RuleType.Standard, tags: ["CodeStyle"], description: "Some description for stub1RuleD", resourceUrls: ["https://example.com/stub1RuleD"] @@ -125,7 +121,6 @@ export class StubEngine1 extends EngineApi.Engine { { name: "stub1RuleE", severityLevel: EngineApi.SeverityLevel.Moderate, - type: EngineApi.RuleType.Standard, tags: ["Performance"], description: "Some description for stub1RuleE", resourceUrls: ["https://example.com/stub1RuleE", "https://example.com/stub1RuleE_2"] @@ -178,7 +173,6 @@ export class StubEngine2 extends EngineApi.Engine { { name: "stub2RuleA", severityLevel: EngineApi.SeverityLevel.Moderate, - type: EngineApi.RuleType.DataFlow, tags: ["Recommended", "Security"], description: "Some description for stub2RuleA", resourceUrls: ["https://example.com/stub2RuleA"] @@ -186,7 +180,6 @@ export class StubEngine2 extends EngineApi.Engine { { name: "stub2RuleB", severityLevel: EngineApi.SeverityLevel.Low, - type: EngineApi.RuleType.DataFlow, tags: ["Performance", "Custom"], description: "Some description for stub2RuleB", resourceUrls: ["https://example.com/stub2RuleB"] @@ -194,7 +187,6 @@ export class StubEngine2 extends EngineApi.Engine { { name: "stub2RuleC", severityLevel: EngineApi.SeverityLevel.High, - type: EngineApi.RuleType.DataFlow, tags: ["Recommended", "BestPractice"], description: "Some description for stub2RuleC", resourceUrls: [] // Purposely putting in nothing here @@ -267,7 +259,7 @@ abstract class BaseTimeableEngine extends EngineApi.Engine { private selectionWaitTime: number; private executionWaitTime: number; - constructor(config: EngineApi.ConfigObject) { + constructor(_config: EngineApi.ConfigObject) { super(); this.selectionWaitTime = 0; this.executionWaitTime = 0; @@ -306,7 +298,6 @@ abstract class BaseTimeableEngine extends EngineApi.Engine { { name: "stub1RuleA", severityLevel: EngineApi.SeverityLevel.Low, - type: EngineApi.RuleType.Standard, tags: ["Recommended", "CodeStyle"], description: "Some description for stub1RuleA", resourceUrls: ["https://example.com/stub1RuleA"] @@ -314,7 +305,7 @@ abstract class BaseTimeableEngine extends EngineApi.Engine { ]; } - async runRules(ruleNames: string[], runOptions: EngineApi.RunOptions): Promise { + async runRules(_ruleNames: string[], _runOptions: EngineApi.RunOptions): Promise { await new Promise(res => setTimeout(res, this.executionWaitTime)); this.emitEvent({ type: EngineApi.EventType.RunRulesProgressEvent, @@ -367,7 +358,7 @@ export class TimeableEngine2 extends BaseTimeableEngine { export class EventConfigurableEngine1 extends EngineApi.Engine { private events: {logLevel: LogLevel, message: string}[] = []; - constructor(config: EngineApi.ConfigObject) { + constructor(_config: EngineApi.ConfigObject) { super(); } @@ -384,7 +375,6 @@ export class EventConfigurableEngine1 extends EngineApi.Engine { { name: "stub1RuleA", severityLevel: EngineApi.SeverityLevel.Low, - type: EngineApi.RuleType.Standard, tags: ["Recommended", "CodeStyle"], description: "Some description for stub1RuleA", resourceUrls: ["https://example.com/stub1RuleA"] @@ -392,7 +382,7 @@ export class EventConfigurableEngine1 extends EngineApi.Engine { ]); } - async runRules(ruleNames: string[], runOptions: EngineApi.RunOptions): Promise { + async runRules(_ruleNames: string[], _runOptions: EngineApi.RunOptions): Promise { for (const {logLevel, message} of this.events) { this.emitEvent({ type: EngineApi.EventType.LogEvent, @@ -447,7 +437,6 @@ export class TargetDependentEngine1 extends EngineApi.Engine { return { name: `ruleFor${fileOrFolder}`, severityLevel: EngineApi.SeverityLevel.Low, - type: EngineApi.RuleType.Standard, tags: ["Recommended"], description: `Rule synthesized for target "${fileOrFolder}`, resourceUrls: [`https://example.com/${fileOrFolder}`] diff --git a/test/stubs/StubRules.ts b/test/stubs/StubRules.ts index e0959514a..6f9eb8b77 100644 --- a/test/stubs/StubRules.ts +++ b/test/stubs/StubRules.ts @@ -1,4 +1,4 @@ -import {Rule, RuleType, SeverityLevel} from '@salesforce/code-analyzer-core'; +import {Rule, SeverityLevel} from '@salesforce/code-analyzer-core'; export class StubRule1 implements Rule { public getName(): string { @@ -17,10 +17,6 @@ export class StubRule1 implements Rule { return `2 (High)`; } - public getType(): RuleType { - return RuleType.Standard; - } - public getFormattedType(): string { return "Standard"; } @@ -63,10 +59,6 @@ export class StubRule2 implements Rule { return `4 (Low)`; } - public getType(): RuleType { - return RuleType.Flow; - } - public getFormattedType(): string { return "Flow"; } diff --git a/yarn.lock b/yarn.lock index 4cfc410ae..cc7aff676 100644 --- a/yarn.lock +++ b/yarn.lock @@ -69,7 +69,7 @@ dependencies: tslib "^2.6.2" -"@aws-crypto/util@^5.2.0": +"@aws-crypto/util@5.2.0", "@aws-crypto/util@^5.2.0": version "5.2.0" resolved "https://registry.yarnpkg.com/@aws-crypto/util/-/util-5.2.0.tgz#71284c9cffe7927ddadac793c14f14886d3876da" integrity sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ== @@ -78,601 +78,603 @@ "@smithy/util-utf8" "^2.0.0" tslib "^2.6.2" -"@aws-sdk/client-cloudfront@^3.675.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-cloudfront/-/client-cloudfront-3.679.0.tgz#8062cc1cf25897306478ff7f44cb050bfd8cc283" - integrity sha512-C/k3ZP+K47CAWICCkaXleUJGdJCiEJRB+5XvbEpoCabrrRJDCa+x/qbgS0KfTuioS5gYb9V1DWeUfXD+iWaoCw== +"@aws-sdk/client-cloudfront@^3.687.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-cloudfront/-/client-cloudfront-3.696.0.tgz#47ad5b16780959f28df7056aac8b346025f1eb24" + integrity sha512-8lhDJF29RrCD56HQTdaamTB4WBVsoU8BuSJJvl8CC3wE1jnF8dLIBAjVUnDhU/dGQINMb0bC7MWQ9Mnafxy8OQ== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/client-sso-oidc" "3.679.0" - "@aws-sdk/client-sts" "3.679.0" - "@aws-sdk/core" "3.679.0" - "@aws-sdk/credential-provider-node" "3.679.0" - "@aws-sdk/middleware-host-header" "3.679.0" - "@aws-sdk/middleware-logger" "3.679.0" - "@aws-sdk/middleware-recursion-detection" "3.679.0" - "@aws-sdk/middleware-user-agent" "3.679.0" - "@aws-sdk/region-config-resolver" "3.679.0" - "@aws-sdk/types" "3.679.0" - "@aws-sdk/util-endpoints" "3.679.0" - "@aws-sdk/util-user-agent-browser" "3.679.0" - "@aws-sdk/util-user-agent-node" "3.679.0" - "@aws-sdk/xml-builder" "3.679.0" - "@smithy/config-resolver" "^3.0.9" - "@smithy/core" "^2.4.8" - "@smithy/fetch-http-handler" "^3.2.9" - "@smithy/hash-node" "^3.0.7" - "@smithy/invalid-dependency" "^3.0.7" - "@smithy/middleware-content-length" "^3.0.9" - "@smithy/middleware-endpoint" "^3.1.4" - "@smithy/middleware-retry" "^3.0.23" - "@smithy/middleware-serde" "^3.0.7" - "@smithy/middleware-stack" "^3.0.7" - "@smithy/node-config-provider" "^3.1.8" - "@smithy/node-http-handler" "^3.2.4" - "@smithy/protocol-http" "^4.1.4" - "@smithy/smithy-client" "^3.4.0" - "@smithy/types" "^3.5.0" - "@smithy/url-parser" "^3.0.7" + "@aws-sdk/client-sso-oidc" "3.696.0" + "@aws-sdk/client-sts" "3.696.0" + "@aws-sdk/core" "3.696.0" + "@aws-sdk/credential-provider-node" "3.696.0" + "@aws-sdk/middleware-host-header" "3.696.0" + "@aws-sdk/middleware-logger" "3.696.0" + "@aws-sdk/middleware-recursion-detection" "3.696.0" + "@aws-sdk/middleware-user-agent" "3.696.0" + "@aws-sdk/region-config-resolver" "3.696.0" + "@aws-sdk/types" "3.696.0" + "@aws-sdk/util-endpoints" "3.696.0" + "@aws-sdk/util-user-agent-browser" "3.696.0" + "@aws-sdk/util-user-agent-node" "3.696.0" + "@aws-sdk/xml-builder" "3.696.0" + "@smithy/config-resolver" "^3.0.12" + "@smithy/core" "^2.5.3" + "@smithy/fetch-http-handler" "^4.1.1" + "@smithy/hash-node" "^3.0.10" + "@smithy/invalid-dependency" "^3.0.10" + "@smithy/middleware-content-length" "^3.0.12" + "@smithy/middleware-endpoint" "^3.2.3" + "@smithy/middleware-retry" "^3.0.27" + "@smithy/middleware-serde" "^3.0.10" + "@smithy/middleware-stack" "^3.0.10" + "@smithy/node-config-provider" "^3.1.11" + "@smithy/node-http-handler" "^3.3.1" + "@smithy/protocol-http" "^4.1.7" + "@smithy/smithy-client" "^3.4.4" + "@smithy/types" "^3.7.1" + "@smithy/url-parser" "^3.0.10" "@smithy/util-base64" "^3.0.0" "@smithy/util-body-length-browser" "^3.0.0" "@smithy/util-body-length-node" "^3.0.0" - "@smithy/util-defaults-mode-browser" "^3.0.23" - "@smithy/util-defaults-mode-node" "^3.0.23" - "@smithy/util-endpoints" "^2.1.3" - "@smithy/util-middleware" "^3.0.7" - "@smithy/util-retry" "^3.0.7" - "@smithy/util-stream" "^3.1.9" + "@smithy/util-defaults-mode-browser" "^3.0.27" + "@smithy/util-defaults-mode-node" "^3.0.27" + "@smithy/util-endpoints" "^2.1.6" + "@smithy/util-middleware" "^3.0.10" + "@smithy/util-retry" "^3.0.10" + "@smithy/util-stream" "^3.3.1" "@smithy/util-utf8" "^3.0.0" - "@smithy/util-waiter" "^3.1.6" + "@smithy/util-waiter" "^3.1.9" tslib "^2.6.2" -"@aws-sdk/client-s3@^3.676.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.679.0.tgz#862088ffa9388488ab3217144d3dd3a95219a92b" - integrity sha512-P93tUbJXiDtSPgBfFpnjaijLV38hyPlE3g0XybsPTmSYNV6A9Jt1TUIF6vX+o6LdFuq3FerCiagUjhfDANWkAw== +"@aws-sdk/client-s3@^3.693.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.696.0.tgz#498f2716658a7092c896c07be8e9bce2401ab9ce" + integrity sha512-kJw6J8QqxKLd2yNACPt2Y9J0vzi7Q25DHOrBkz6SX3nPLp5Qtzxm4rjKbHs9gKhX7ijUoVkOpzZ/4ufz6/RJmA== dependencies: "@aws-crypto/sha1-browser" "5.2.0" "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/client-sso-oidc" "3.679.0" - "@aws-sdk/client-sts" "3.679.0" - "@aws-sdk/core" "3.679.0" - "@aws-sdk/credential-provider-node" "3.679.0" - "@aws-sdk/middleware-bucket-endpoint" "3.679.0" - "@aws-sdk/middleware-expect-continue" "3.679.0" - "@aws-sdk/middleware-flexible-checksums" "3.679.0" - "@aws-sdk/middleware-host-header" "3.679.0" - "@aws-sdk/middleware-location-constraint" "3.679.0" - "@aws-sdk/middleware-logger" "3.679.0" - "@aws-sdk/middleware-recursion-detection" "3.679.0" - "@aws-sdk/middleware-sdk-s3" "3.679.0" - "@aws-sdk/middleware-ssec" "3.679.0" - "@aws-sdk/middleware-user-agent" "3.679.0" - "@aws-sdk/region-config-resolver" "3.679.0" - "@aws-sdk/signature-v4-multi-region" "3.679.0" - "@aws-sdk/types" "3.679.0" - "@aws-sdk/util-endpoints" "3.679.0" - "@aws-sdk/util-user-agent-browser" "3.679.0" - "@aws-sdk/util-user-agent-node" "3.679.0" - "@aws-sdk/xml-builder" "3.679.0" - "@smithy/config-resolver" "^3.0.9" - "@smithy/core" "^2.4.8" - "@smithy/eventstream-serde-browser" "^3.0.10" - "@smithy/eventstream-serde-config-resolver" "^3.0.7" - "@smithy/eventstream-serde-node" "^3.0.9" - "@smithy/fetch-http-handler" "^3.2.9" - "@smithy/hash-blob-browser" "^3.1.6" - "@smithy/hash-node" "^3.0.7" - "@smithy/hash-stream-node" "^3.1.6" - "@smithy/invalid-dependency" "^3.0.7" - "@smithy/md5-js" "^3.0.7" - "@smithy/middleware-content-length" "^3.0.9" - "@smithy/middleware-endpoint" "^3.1.4" - "@smithy/middleware-retry" "^3.0.23" - "@smithy/middleware-serde" "^3.0.7" - "@smithy/middleware-stack" "^3.0.7" - "@smithy/node-config-provider" "^3.1.8" - "@smithy/node-http-handler" "^3.2.4" - "@smithy/protocol-http" "^4.1.4" - "@smithy/smithy-client" "^3.4.0" - "@smithy/types" "^3.5.0" - "@smithy/url-parser" "^3.0.7" + "@aws-sdk/client-sso-oidc" "3.696.0" + "@aws-sdk/client-sts" "3.696.0" + "@aws-sdk/core" "3.696.0" + "@aws-sdk/credential-provider-node" "3.696.0" + "@aws-sdk/middleware-bucket-endpoint" "3.696.0" + "@aws-sdk/middleware-expect-continue" "3.696.0" + "@aws-sdk/middleware-flexible-checksums" "3.696.0" + "@aws-sdk/middleware-host-header" "3.696.0" + "@aws-sdk/middleware-location-constraint" "3.696.0" + "@aws-sdk/middleware-logger" "3.696.0" + "@aws-sdk/middleware-recursion-detection" "3.696.0" + "@aws-sdk/middleware-sdk-s3" "3.696.0" + "@aws-sdk/middleware-ssec" "3.696.0" + "@aws-sdk/middleware-user-agent" "3.696.0" + "@aws-sdk/region-config-resolver" "3.696.0" + "@aws-sdk/signature-v4-multi-region" "3.696.0" + "@aws-sdk/types" "3.696.0" + "@aws-sdk/util-endpoints" "3.696.0" + "@aws-sdk/util-user-agent-browser" "3.696.0" + "@aws-sdk/util-user-agent-node" "3.696.0" + "@aws-sdk/xml-builder" "3.696.0" + "@smithy/config-resolver" "^3.0.12" + "@smithy/core" "^2.5.3" + "@smithy/eventstream-serde-browser" "^3.0.13" + "@smithy/eventstream-serde-config-resolver" "^3.0.10" + "@smithy/eventstream-serde-node" "^3.0.12" + "@smithy/fetch-http-handler" "^4.1.1" + "@smithy/hash-blob-browser" "^3.1.9" + "@smithy/hash-node" "^3.0.10" + "@smithy/hash-stream-node" "^3.1.9" + "@smithy/invalid-dependency" "^3.0.10" + "@smithy/md5-js" "^3.0.10" + "@smithy/middleware-content-length" "^3.0.12" + "@smithy/middleware-endpoint" "^3.2.3" + "@smithy/middleware-retry" "^3.0.27" + "@smithy/middleware-serde" "^3.0.10" + "@smithy/middleware-stack" "^3.0.10" + "@smithy/node-config-provider" "^3.1.11" + "@smithy/node-http-handler" "^3.3.1" + "@smithy/protocol-http" "^4.1.7" + "@smithy/smithy-client" "^3.4.4" + "@smithy/types" "^3.7.1" + "@smithy/url-parser" "^3.0.10" "@smithy/util-base64" "^3.0.0" "@smithy/util-body-length-browser" "^3.0.0" "@smithy/util-body-length-node" "^3.0.0" - "@smithy/util-defaults-mode-browser" "^3.0.23" - "@smithy/util-defaults-mode-node" "^3.0.23" - "@smithy/util-endpoints" "^2.1.3" - "@smithy/util-middleware" "^3.0.7" - "@smithy/util-retry" "^3.0.7" - "@smithy/util-stream" "^3.1.9" + "@smithy/util-defaults-mode-browser" "^3.0.27" + "@smithy/util-defaults-mode-node" "^3.0.27" + "@smithy/util-endpoints" "^2.1.6" + "@smithy/util-middleware" "^3.0.10" + "@smithy/util-retry" "^3.0.10" + "@smithy/util-stream" "^3.3.1" "@smithy/util-utf8" "^3.0.0" - "@smithy/util-waiter" "^3.1.6" + "@smithy/util-waiter" "^3.1.9" tslib "^2.6.2" -"@aws-sdk/client-sso-oidc@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.679.0.tgz#00de670c9ea31c5073f6eed6842795e70bc63fca" - integrity sha512-/dBYWcCwbA/id4sFCIVZvf0UsvzHCC68SryxeNQk/PDkY9N4n5yRcMUkZDaEyQCjowc3kY4JOXp2AdUP037nhA== +"@aws-sdk/client-sso-oidc@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.696.0.tgz#b6a92ae876d3fdaa986bd70bbb329dcbcd12ea2b" + integrity sha512-ikxQ3mo86d1mAq5zTaQAh8rLBERwL+I4MUYu/IVYW2hhl9J2SDsl0SgnKeXQG6S8zWuHcBO587zsZaRta1MQ/g== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/core" "3.679.0" - "@aws-sdk/credential-provider-node" "3.679.0" - "@aws-sdk/middleware-host-header" "3.679.0" - "@aws-sdk/middleware-logger" "3.679.0" - "@aws-sdk/middleware-recursion-detection" "3.679.0" - "@aws-sdk/middleware-user-agent" "3.679.0" - "@aws-sdk/region-config-resolver" "3.679.0" - "@aws-sdk/types" "3.679.0" - "@aws-sdk/util-endpoints" "3.679.0" - "@aws-sdk/util-user-agent-browser" "3.679.0" - "@aws-sdk/util-user-agent-node" "3.679.0" - "@smithy/config-resolver" "^3.0.9" - "@smithy/core" "^2.4.8" - "@smithy/fetch-http-handler" "^3.2.9" - "@smithy/hash-node" "^3.0.7" - "@smithy/invalid-dependency" "^3.0.7" - "@smithy/middleware-content-length" "^3.0.9" - "@smithy/middleware-endpoint" "^3.1.4" - "@smithy/middleware-retry" "^3.0.23" - "@smithy/middleware-serde" "^3.0.7" - "@smithy/middleware-stack" "^3.0.7" - "@smithy/node-config-provider" "^3.1.8" - "@smithy/node-http-handler" "^3.2.4" - "@smithy/protocol-http" "^4.1.4" - "@smithy/smithy-client" "^3.4.0" - "@smithy/types" "^3.5.0" - "@smithy/url-parser" "^3.0.7" + "@aws-sdk/core" "3.696.0" + "@aws-sdk/credential-provider-node" "3.696.0" + "@aws-sdk/middleware-host-header" "3.696.0" + "@aws-sdk/middleware-logger" "3.696.0" + "@aws-sdk/middleware-recursion-detection" "3.696.0" + "@aws-sdk/middleware-user-agent" "3.696.0" + "@aws-sdk/region-config-resolver" "3.696.0" + "@aws-sdk/types" "3.696.0" + "@aws-sdk/util-endpoints" "3.696.0" + "@aws-sdk/util-user-agent-browser" "3.696.0" + "@aws-sdk/util-user-agent-node" "3.696.0" + "@smithy/config-resolver" "^3.0.12" + "@smithy/core" "^2.5.3" + "@smithy/fetch-http-handler" "^4.1.1" + "@smithy/hash-node" "^3.0.10" + "@smithy/invalid-dependency" "^3.0.10" + "@smithy/middleware-content-length" "^3.0.12" + "@smithy/middleware-endpoint" "^3.2.3" + "@smithy/middleware-retry" "^3.0.27" + "@smithy/middleware-serde" "^3.0.10" + "@smithy/middleware-stack" "^3.0.10" + "@smithy/node-config-provider" "^3.1.11" + "@smithy/node-http-handler" "^3.3.1" + "@smithy/protocol-http" "^4.1.7" + "@smithy/smithy-client" "^3.4.4" + "@smithy/types" "^3.7.1" + "@smithy/url-parser" "^3.0.10" "@smithy/util-base64" "^3.0.0" "@smithy/util-body-length-browser" "^3.0.0" "@smithy/util-body-length-node" "^3.0.0" - "@smithy/util-defaults-mode-browser" "^3.0.23" - "@smithy/util-defaults-mode-node" "^3.0.23" - "@smithy/util-endpoints" "^2.1.3" - "@smithy/util-middleware" "^3.0.7" - "@smithy/util-retry" "^3.0.7" + "@smithy/util-defaults-mode-browser" "^3.0.27" + "@smithy/util-defaults-mode-node" "^3.0.27" + "@smithy/util-endpoints" "^2.1.6" + "@smithy/util-middleware" "^3.0.10" + "@smithy/util-retry" "^3.0.10" "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@aws-sdk/client-sso@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.679.0.tgz#6d6e96ae4e8c3258793e26bcd127b9f9a621dd1b" - integrity sha512-/0cAvYnpOZTo/Y961F1kx2fhDDLUYZ0SQQ5/75gh3xVImLj7Zw+vp74ieqFbqWLYGMaq8z1Arr9A8zG95mbLdg== +"@aws-sdk/client-sso@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.696.0.tgz#a9251e88cdfc91fb14191f760f68baa835e88f1c" + integrity sha512-q5TTkd08JS0DOkHfUL853tuArf7NrPeqoS5UOvqJho8ibV9Ak/a/HO4kNvy9Nj3cib/toHYHsQIEtecUPSUUrQ== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/core" "3.679.0" - "@aws-sdk/middleware-host-header" "3.679.0" - "@aws-sdk/middleware-logger" "3.679.0" - "@aws-sdk/middleware-recursion-detection" "3.679.0" - "@aws-sdk/middleware-user-agent" "3.679.0" - "@aws-sdk/region-config-resolver" "3.679.0" - "@aws-sdk/types" "3.679.0" - "@aws-sdk/util-endpoints" "3.679.0" - "@aws-sdk/util-user-agent-browser" "3.679.0" - "@aws-sdk/util-user-agent-node" "3.679.0" - "@smithy/config-resolver" "^3.0.9" - "@smithy/core" "^2.4.8" - "@smithy/fetch-http-handler" "^3.2.9" - "@smithy/hash-node" "^3.0.7" - "@smithy/invalid-dependency" "^3.0.7" - "@smithy/middleware-content-length" "^3.0.9" - "@smithy/middleware-endpoint" "^3.1.4" - "@smithy/middleware-retry" "^3.0.23" - "@smithy/middleware-serde" "^3.0.7" - "@smithy/middleware-stack" "^3.0.7" - "@smithy/node-config-provider" "^3.1.8" - "@smithy/node-http-handler" "^3.2.4" - "@smithy/protocol-http" "^4.1.4" - "@smithy/smithy-client" "^3.4.0" - "@smithy/types" "^3.5.0" - "@smithy/url-parser" "^3.0.7" + "@aws-sdk/core" "3.696.0" + "@aws-sdk/middleware-host-header" "3.696.0" + "@aws-sdk/middleware-logger" "3.696.0" + "@aws-sdk/middleware-recursion-detection" "3.696.0" + "@aws-sdk/middleware-user-agent" "3.696.0" + "@aws-sdk/region-config-resolver" "3.696.0" + "@aws-sdk/types" "3.696.0" + "@aws-sdk/util-endpoints" "3.696.0" + "@aws-sdk/util-user-agent-browser" "3.696.0" + "@aws-sdk/util-user-agent-node" "3.696.0" + "@smithy/config-resolver" "^3.0.12" + "@smithy/core" "^2.5.3" + "@smithy/fetch-http-handler" "^4.1.1" + "@smithy/hash-node" "^3.0.10" + "@smithy/invalid-dependency" "^3.0.10" + "@smithy/middleware-content-length" "^3.0.12" + "@smithy/middleware-endpoint" "^3.2.3" + "@smithy/middleware-retry" "^3.0.27" + "@smithy/middleware-serde" "^3.0.10" + "@smithy/middleware-stack" "^3.0.10" + "@smithy/node-config-provider" "^3.1.11" + "@smithy/node-http-handler" "^3.3.1" + "@smithy/protocol-http" "^4.1.7" + "@smithy/smithy-client" "^3.4.4" + "@smithy/types" "^3.7.1" + "@smithy/url-parser" "^3.0.10" "@smithy/util-base64" "^3.0.0" "@smithy/util-body-length-browser" "^3.0.0" "@smithy/util-body-length-node" "^3.0.0" - "@smithy/util-defaults-mode-browser" "^3.0.23" - "@smithy/util-defaults-mode-node" "^3.0.23" - "@smithy/util-endpoints" "^2.1.3" - "@smithy/util-middleware" "^3.0.7" - "@smithy/util-retry" "^3.0.7" + "@smithy/util-defaults-mode-browser" "^3.0.27" + "@smithy/util-defaults-mode-node" "^3.0.27" + "@smithy/util-endpoints" "^2.1.6" + "@smithy/util-middleware" "^3.0.10" + "@smithy/util-retry" "^3.0.10" "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@aws-sdk/client-sts@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.679.0.tgz#4641c24032ebd69a6e0e4eb28477749e21e69884" - integrity sha512-3CvrT8w1RjFu1g8vKA5Azfr5V83r2/b68Ock43WE003Bq/5Y38mwmYX7vk0fPHzC3qejt4YMAWk/C3fSKOy25g== +"@aws-sdk/client-sts@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sts/-/client-sts-3.696.0.tgz#58d820a6d6f62626fd3177e7c0dc90027f0c6c3c" + integrity sha512-eJOxR8/UyI7kGSRyE751Ea7MKEzllQs7eNveDJy9OP4t/jsN/P19HJ1YHeA1np40JRTUBfqa6WLAAiIXsk8rkg== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/client-sso-oidc" "3.679.0" - "@aws-sdk/core" "3.679.0" - "@aws-sdk/credential-provider-node" "3.679.0" - "@aws-sdk/middleware-host-header" "3.679.0" - "@aws-sdk/middleware-logger" "3.679.0" - "@aws-sdk/middleware-recursion-detection" "3.679.0" - "@aws-sdk/middleware-user-agent" "3.679.0" - "@aws-sdk/region-config-resolver" "3.679.0" - "@aws-sdk/types" "3.679.0" - "@aws-sdk/util-endpoints" "3.679.0" - "@aws-sdk/util-user-agent-browser" "3.679.0" - "@aws-sdk/util-user-agent-node" "3.679.0" - "@smithy/config-resolver" "^3.0.9" - "@smithy/core" "^2.4.8" - "@smithy/fetch-http-handler" "^3.2.9" - "@smithy/hash-node" "^3.0.7" - "@smithy/invalid-dependency" "^3.0.7" - "@smithy/middleware-content-length" "^3.0.9" - "@smithy/middleware-endpoint" "^3.1.4" - "@smithy/middleware-retry" "^3.0.23" - "@smithy/middleware-serde" "^3.0.7" - "@smithy/middleware-stack" "^3.0.7" - "@smithy/node-config-provider" "^3.1.8" - "@smithy/node-http-handler" "^3.2.4" - "@smithy/protocol-http" "^4.1.4" - "@smithy/smithy-client" "^3.4.0" - "@smithy/types" "^3.5.0" - "@smithy/url-parser" "^3.0.7" + "@aws-sdk/client-sso-oidc" "3.696.0" + "@aws-sdk/core" "3.696.0" + "@aws-sdk/credential-provider-node" "3.696.0" + "@aws-sdk/middleware-host-header" "3.696.0" + "@aws-sdk/middleware-logger" "3.696.0" + "@aws-sdk/middleware-recursion-detection" "3.696.0" + "@aws-sdk/middleware-user-agent" "3.696.0" + "@aws-sdk/region-config-resolver" "3.696.0" + "@aws-sdk/types" "3.696.0" + "@aws-sdk/util-endpoints" "3.696.0" + "@aws-sdk/util-user-agent-browser" "3.696.0" + "@aws-sdk/util-user-agent-node" "3.696.0" + "@smithy/config-resolver" "^3.0.12" + "@smithy/core" "^2.5.3" + "@smithy/fetch-http-handler" "^4.1.1" + "@smithy/hash-node" "^3.0.10" + "@smithy/invalid-dependency" "^3.0.10" + "@smithy/middleware-content-length" "^3.0.12" + "@smithy/middleware-endpoint" "^3.2.3" + "@smithy/middleware-retry" "^3.0.27" + "@smithy/middleware-serde" "^3.0.10" + "@smithy/middleware-stack" "^3.0.10" + "@smithy/node-config-provider" "^3.1.11" + "@smithy/node-http-handler" "^3.3.1" + "@smithy/protocol-http" "^4.1.7" + "@smithy/smithy-client" "^3.4.4" + "@smithy/types" "^3.7.1" + "@smithy/url-parser" "^3.0.10" "@smithy/util-base64" "^3.0.0" "@smithy/util-body-length-browser" "^3.0.0" "@smithy/util-body-length-node" "^3.0.0" - "@smithy/util-defaults-mode-browser" "^3.0.23" - "@smithy/util-defaults-mode-node" "^3.0.23" - "@smithy/util-endpoints" "^2.1.3" - "@smithy/util-middleware" "^3.0.7" - "@smithy/util-retry" "^3.0.7" + "@smithy/util-defaults-mode-browser" "^3.0.27" + "@smithy/util-defaults-mode-node" "^3.0.27" + "@smithy/util-endpoints" "^2.1.6" + "@smithy/util-middleware" "^3.0.10" + "@smithy/util-retry" "^3.0.10" "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@aws-sdk/core@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.679.0.tgz#102aa1d19db5bdcabefc2dcd044f2fb5d0771568" - integrity sha512-CS6PWGX8l4v/xyvX8RtXnBisdCa5+URzKd0L6GvHChype9qKUVxO/Gg6N/y43Hvg7MNWJt9FBPNWIxUB+byJwg== - dependencies: - "@aws-sdk/types" "3.679.0" - "@smithy/core" "^2.4.8" - "@smithy/node-config-provider" "^3.1.8" - "@smithy/property-provider" "^3.1.7" - "@smithy/protocol-http" "^4.1.4" - "@smithy/signature-v4" "^4.2.0" - "@smithy/smithy-client" "^3.4.0" - "@smithy/types" "^3.5.0" - "@smithy/util-middleware" "^3.0.7" +"@aws-sdk/core@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.696.0.tgz#bdf306bdc019f485738d91d8838eec877861dd26" + integrity sha512-3c9III1k03DgvRZWg8vhVmfIXPG6hAciN9MzQTzqGngzWAELZF/WONRTRQuDFixVtarQatmLHYVw/atGeA2Byw== + dependencies: + "@aws-sdk/types" "3.696.0" + "@smithy/core" "^2.5.3" + "@smithy/node-config-provider" "^3.1.11" + "@smithy/property-provider" "^3.1.9" + "@smithy/protocol-http" "^4.1.7" + "@smithy/signature-v4" "^4.2.2" + "@smithy/smithy-client" "^3.4.4" + "@smithy/types" "^3.7.1" + "@smithy/util-middleware" "^3.0.10" fast-xml-parser "4.4.1" tslib "^2.6.2" -"@aws-sdk/credential-provider-env@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.679.0.tgz#abf297714b77197a9da0d3d95a0f5687ae28e5b3" - integrity sha512-EdlTYbzMm3G7VUNAMxr9S1nC1qUNqhKlAxFU8E7cKsAe8Bp29CD5HAs3POc56AVo9GC4yRIS+/mtlZSmrckzUA== +"@aws-sdk/credential-provider-env@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.696.0.tgz#afad9e61cd03da404bb03e5bce83c49736b85271" + integrity sha512-T9iMFnJL7YTlESLpVFT3fg1Lkb1lD+oiaIC8KMpepb01gDUBIpj9+Y+pA/cgRWW0yRxmkDXNazAE2qQTVFGJzA== dependencies: - "@aws-sdk/core" "3.679.0" - "@aws-sdk/types" "3.679.0" - "@smithy/property-provider" "^3.1.7" - "@smithy/types" "^3.5.0" + "@aws-sdk/core" "3.696.0" + "@aws-sdk/types" "3.696.0" + "@smithy/property-provider" "^3.1.9" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/credential-provider-http@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.679.0.tgz#9fc29f4ec7ab52ecf394288c05295823e818d812" - integrity sha512-ZoKLubW5DqqV1/2a3TSn+9sSKg0T8SsYMt1JeirnuLJF0mCoYFUaWMyvxxKuxPoqvUsaycxKru4GkpJ10ltNBw== - dependencies: - "@aws-sdk/core" "3.679.0" - "@aws-sdk/types" "3.679.0" - "@smithy/fetch-http-handler" "^3.2.9" - "@smithy/node-http-handler" "^3.2.4" - "@smithy/property-provider" "^3.1.7" - "@smithy/protocol-http" "^4.1.4" - "@smithy/smithy-client" "^3.4.0" - "@smithy/types" "^3.5.0" - "@smithy/util-stream" "^3.1.9" +"@aws-sdk/credential-provider-http@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.696.0.tgz#535756f9f427fbe851a8c1db7b0e3aaaf7790ba2" + integrity sha512-GV6EbvPi2eq1+WgY/o2RFA3P7HGmnkIzCNmhwtALFlqMroLYWKE7PSeHw66Uh1dFQeVESn0/+hiUNhu1mB0emA== + dependencies: + "@aws-sdk/core" "3.696.0" + "@aws-sdk/types" "3.696.0" + "@smithy/fetch-http-handler" "^4.1.1" + "@smithy/node-http-handler" "^3.3.1" + "@smithy/property-provider" "^3.1.9" + "@smithy/protocol-http" "^4.1.7" + "@smithy/smithy-client" "^3.4.4" + "@smithy/types" "^3.7.1" + "@smithy/util-stream" "^3.3.1" tslib "^2.6.2" -"@aws-sdk/credential-provider-ini@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.679.0.tgz#0115c9e4813de3fcf0bf20f6156b6bf4b62d8431" - integrity sha512-Rg7t8RwUzKcumpipG4neZqaeJ6DF+Bco1+FHn5BZB68jpvwvjBjcQUuWkxj18B6ctYHr1fkunnzeKEn/+vy7+w== - dependencies: - "@aws-sdk/core" "3.679.0" - "@aws-sdk/credential-provider-env" "3.679.0" - "@aws-sdk/credential-provider-http" "3.679.0" - "@aws-sdk/credential-provider-process" "3.679.0" - "@aws-sdk/credential-provider-sso" "3.679.0" - "@aws-sdk/credential-provider-web-identity" "3.679.0" - "@aws-sdk/types" "3.679.0" - "@smithy/credential-provider-imds" "^3.2.4" - "@smithy/property-provider" "^3.1.7" - "@smithy/shared-ini-file-loader" "^3.1.8" - "@smithy/types" "^3.5.0" +"@aws-sdk/credential-provider-ini@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.696.0.tgz#8b162db836c81582f249e24adff48f01cacca402" + integrity sha512-9WsZZofjPjNAAZhIh7c7FOhLK8CR3RnGgUm1tdZzV6ZSM1BuS2m6rdwIilRxAh3fxxKDkmW/r/aYmmCYwA+AYA== + dependencies: + "@aws-sdk/core" "3.696.0" + "@aws-sdk/credential-provider-env" "3.696.0" + "@aws-sdk/credential-provider-http" "3.696.0" + "@aws-sdk/credential-provider-process" "3.696.0" + "@aws-sdk/credential-provider-sso" "3.696.0" + "@aws-sdk/credential-provider-web-identity" "3.696.0" + "@aws-sdk/types" "3.696.0" + "@smithy/credential-provider-imds" "^3.2.6" + "@smithy/property-provider" "^3.1.9" + "@smithy/shared-ini-file-loader" "^3.1.10" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/credential-provider-node@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.679.0.tgz#f3012b7e305aa1151c1472ece3f422f66666bc7c" - integrity sha512-E3lBtaqCte8tWs6Rkssc8sLzvGoJ10TLGvpkijOlz43wPd6xCRh1YLwg6zolf9fVFtEyUs/GsgymiASOyxhFtw== - dependencies: - "@aws-sdk/credential-provider-env" "3.679.0" - "@aws-sdk/credential-provider-http" "3.679.0" - "@aws-sdk/credential-provider-ini" "3.679.0" - "@aws-sdk/credential-provider-process" "3.679.0" - "@aws-sdk/credential-provider-sso" "3.679.0" - "@aws-sdk/credential-provider-web-identity" "3.679.0" - "@aws-sdk/types" "3.679.0" - "@smithy/credential-provider-imds" "^3.2.4" - "@smithy/property-provider" "^3.1.7" - "@smithy/shared-ini-file-loader" "^3.1.8" - "@smithy/types" "^3.5.0" +"@aws-sdk/credential-provider-node@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.696.0.tgz#6d8d97a85444bfd3c5a1aded9ce894f68e6d3547" + integrity sha512-8F6y5FcfRuMJouC5s207Ko1mcVvOXReBOlJmhIwE4QH1CnO/CliIyepnAZrRQ659mo5wIuquz6gXnpYbitEVMg== + dependencies: + "@aws-sdk/credential-provider-env" "3.696.0" + "@aws-sdk/credential-provider-http" "3.696.0" + "@aws-sdk/credential-provider-ini" "3.696.0" + "@aws-sdk/credential-provider-process" "3.696.0" + "@aws-sdk/credential-provider-sso" "3.696.0" + "@aws-sdk/credential-provider-web-identity" "3.696.0" + "@aws-sdk/types" "3.696.0" + "@smithy/credential-provider-imds" "^3.2.6" + "@smithy/property-provider" "^3.1.9" + "@smithy/shared-ini-file-loader" "^3.1.10" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/credential-provider-process@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.679.0.tgz#a06b5193cdad2c14382708bcd44d487af52b11dc" - integrity sha512-u/p4TV8kQ0zJWDdZD4+vdQFTMhkDEJFws040Gm113VHa/Xo1SYOjbpvqeuFoz6VmM0bLvoOWjxB9MxnSQbwKpQ== +"@aws-sdk/credential-provider-process@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.696.0.tgz#45da7b948aa40987b413c7c0d4a8125bf1433651" + integrity sha512-mL1RcFDe9sfmyU5K1nuFkO8UiJXXxLX4JO1gVaDIOvPqwStpUAwi3A1BoeZhWZZNQsiKI810RnYGo0E0WB/hUA== dependencies: - "@aws-sdk/core" "3.679.0" - "@aws-sdk/types" "3.679.0" - "@smithy/property-provider" "^3.1.7" - "@smithy/shared-ini-file-loader" "^3.1.8" - "@smithy/types" "^3.5.0" + "@aws-sdk/core" "3.696.0" + "@aws-sdk/types" "3.696.0" + "@smithy/property-provider" "^3.1.9" + "@smithy/shared-ini-file-loader" "^3.1.10" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/credential-provider-sso@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.679.0.tgz#ad07de8f9a0c3e5fe7bd660e1847867643ab480e" - integrity sha512-SAtWonhi9asxn0ukEbcE81jkyanKgqpsrtskvYPpO9Z9KOednM4Cqt6h1bfcS9zaHjN2zu815Gv8O7WiV+F/DQ== - dependencies: - "@aws-sdk/client-sso" "3.679.0" - "@aws-sdk/core" "3.679.0" - "@aws-sdk/token-providers" "3.679.0" - "@aws-sdk/types" "3.679.0" - "@smithy/property-provider" "^3.1.7" - "@smithy/shared-ini-file-loader" "^3.1.8" - "@smithy/types" "^3.5.0" +"@aws-sdk/credential-provider-sso@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.696.0.tgz#3e58608e7c330e08206af496a14764f82a776acf" + integrity sha512-4SSZ9Nk08JSu4/rX1a+dEac/Ims1HCXfV7YLUe5LGdtRLSKRoQQUy+hkFaGYoSugP/p1UfUPl3BuTO9Vv8z1pA== + dependencies: + "@aws-sdk/client-sso" "3.696.0" + "@aws-sdk/core" "3.696.0" + "@aws-sdk/token-providers" "3.696.0" + "@aws-sdk/types" "3.696.0" + "@smithy/property-provider" "^3.1.9" + "@smithy/shared-ini-file-loader" "^3.1.10" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/credential-provider-web-identity@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.679.0.tgz#5871c44e5846e7c93810fd033224c00493db65a3" - integrity sha512-a74tLccVznXCaBefWPSysUcLXYJiSkeUmQGtalNgJ1vGkE36W5l/8czFiiowdWdKWz7+x6xf0w+Kjkjlj42Ung== +"@aws-sdk/credential-provider-web-identity@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.696.0.tgz#3f97c00bd3bc7cfd988e098af67ff7c8392ce188" + integrity sha512-XJ/CVlWChM0VCoc259vWguFUjJDn/QwDqHwbx+K9cg3v6yrqXfK5ai+p/6lx0nQpnk4JzPVeYYxWRpaTsGC9rg== dependencies: - "@aws-sdk/core" "3.679.0" - "@aws-sdk/types" "3.679.0" - "@smithy/property-provider" "^3.1.7" - "@smithy/types" "^3.5.0" + "@aws-sdk/core" "3.696.0" + "@aws-sdk/types" "3.696.0" + "@smithy/property-provider" "^3.1.9" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/middleware-bucket-endpoint@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.679.0.tgz#cc5acad018d3b1646340fa2d0d0d412436b95e04" - integrity sha512-5EpiPhhGgnF+uJR4DzWUk6Lx3pOn9oM6JGXxeHsiynfoBfq7vHMleq+uABHHSQS+y7XzbyZ7x8tXNQlliMwOsg== +"@aws-sdk/middleware-bucket-endpoint@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.696.0.tgz#5c4e6c75855e94a8d7160812b63cb911373a4811" + integrity sha512-V07jishKHUS5heRNGFpCWCSTjRJyQLynS/ncUeE8ZYtG66StOOQWftTwDfFOSoXlIqrXgb4oT9atryzXq7Z4LQ== dependencies: - "@aws-sdk/types" "3.679.0" - "@aws-sdk/util-arn-parser" "3.679.0" - "@smithy/node-config-provider" "^3.1.8" - "@smithy/protocol-http" "^4.1.4" - "@smithy/types" "^3.5.0" + "@aws-sdk/types" "3.696.0" + "@aws-sdk/util-arn-parser" "3.693.0" + "@smithy/node-config-provider" "^3.1.11" + "@smithy/protocol-http" "^4.1.7" + "@smithy/types" "^3.7.1" "@smithy/util-config-provider" "^3.0.0" tslib "^2.6.2" -"@aws-sdk/middleware-expect-continue@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.679.0.tgz#6b22403fa6d7a7b9b0312c4453cfef69da66334b" - integrity sha512-nYsh9PdWrF4EahTRdXHGlNud82RPc508CNGdh1lAGfPU3tNveGfMBX3PcGBtPOse3p9ebNKRWVmUc9eXSjGvHA== +"@aws-sdk/middleware-expect-continue@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.696.0.tgz#9c8e56d45bc99899f0ed054ea67d0f9703b76356" + integrity sha512-vpVukqY3U2pb+ULeX0shs6L0aadNep6kKzjme/MyulPjtUDJpD3AekHsXRrCCGLmOqSKqRgQn5zhV9pQhHsb6Q== dependencies: - "@aws-sdk/types" "3.679.0" - "@smithy/protocol-http" "^4.1.4" - "@smithy/types" "^3.5.0" + "@aws-sdk/types" "3.696.0" + "@smithy/protocol-http" "^4.1.7" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/middleware-flexible-checksums@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.679.0.tgz#ccf5b58f4ad3056076877898d94f2473b667083c" - integrity sha512-2Nf3rnrcog3GRRdXxc623wkQPH3WXhz8oZ+KHuXBeBKX01zbp7bz22QAZKqw3Oo2lv+LQNEDzIfQYn7leXLZGQ== +"@aws-sdk/middleware-flexible-checksums@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.696.0.tgz#4c6db8aa9216fa847c744f42ae5b7674e86ab5ee" + integrity sha512-EF+iHcLluuRPashlrRa2Sjf2fjUU6h+FB9CpALv9hq2XgDziseWbs+fJcP3QUnJ1tSdW+3WXtMQFvyMyVYpQKw== dependencies: "@aws-crypto/crc32" "5.2.0" "@aws-crypto/crc32c" "5.2.0" - "@aws-sdk/core" "3.679.0" - "@aws-sdk/types" "3.679.0" + "@aws-crypto/util" "5.2.0" + "@aws-sdk/core" "3.696.0" + "@aws-sdk/types" "3.696.0" "@smithy/is-array-buffer" "^3.0.0" - "@smithy/node-config-provider" "^3.1.8" - "@smithy/protocol-http" "^4.1.4" - "@smithy/types" "^3.5.0" - "@smithy/util-middleware" "^3.0.7" + "@smithy/node-config-provider" "^3.1.11" + "@smithy/protocol-http" "^4.1.7" + "@smithy/types" "^3.7.1" + "@smithy/util-middleware" "^3.0.10" + "@smithy/util-stream" "^3.3.1" "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@aws-sdk/middleware-host-header@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.679.0.tgz#1eabe42250c57a9e28742dd04786781573faad1a" - integrity sha512-y176HuQ8JRY3hGX8rQzHDSbCl9P5Ny9l16z4xmaiLo+Qfte7ee4Yr3yaAKd7GFoJ3/Mhud2XZ37fR015MfYl2w== +"@aws-sdk/middleware-host-header@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.696.0.tgz#20aae0efeb973ca1a6db1b1014acbcdd06ad472e" + integrity sha512-zELJp9Ta2zkX7ELggMN9qMCgekqZhFC5V2rOr4hJDEb/Tte7gpfKSObAnw/3AYiVqt36sjHKfdkoTsuwGdEoDg== dependencies: - "@aws-sdk/types" "3.679.0" - "@smithy/protocol-http" "^4.1.4" - "@smithy/types" "^3.5.0" + "@aws-sdk/types" "3.696.0" + "@smithy/protocol-http" "^4.1.7" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/middleware-location-constraint@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.679.0.tgz#99ed75f1bf5ec005656af1c9efdb35aa2ddc7216" - integrity sha512-SA1C1D3XgoKTGxyNsOqd016ONpk46xJLWDgJUd00Zb21Ox5wYCoY6aDRKiaMRW+1VfCJdezs1Do3XLyIU9KxyA== +"@aws-sdk/middleware-location-constraint@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.696.0.tgz#21edf9fab1b29cb5f819c3be57e1286a86ae8be2" + integrity sha512-FgH12OB0q+DtTrP2aiDBddDKwL4BPOrm7w3VV9BJrSdkqQCNBPz8S1lb0y5eVH4tBG+2j7gKPlOv1wde4jF/iw== dependencies: - "@aws-sdk/types" "3.679.0" - "@smithy/types" "^3.5.0" + "@aws-sdk/types" "3.696.0" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/middleware-logger@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.679.0.tgz#cb0f205ddb5341d8327fc9ca1897bf06526c1896" - integrity sha512-0vet8InEj7nvIvGKk+ch7bEF5SyZ7Us9U7YTEgXPrBNStKeRUsgwRm0ijPWWd0a3oz2okaEwXsFl7G/vI0XiEA== +"@aws-sdk/middleware-logger@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.696.0.tgz#79d68b7e5ba181511ade769b11165bfb7527181e" + integrity sha512-KhkHt+8AjCxcR/5Zp3++YPJPpFQzxpr+jmONiT/Jw2yqnSngZ0Yspm5wGoRx2hS1HJbyZNuaOWEGuJoxLeBKfA== dependencies: - "@aws-sdk/types" "3.679.0" - "@smithy/types" "^3.5.0" + "@aws-sdk/types" "3.696.0" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/middleware-recursion-detection@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.679.0.tgz#3542de5baa466abffbfe5ee485fd87f60d5f917e" - integrity sha512-sQoAZFsQiW/LL3DfKMYwBoGjYDEnMbA9WslWN8xneCmBAwKo6IcSksvYs23PP8XMIoBGe2I2J9BSr654XWygTQ== +"@aws-sdk/middleware-recursion-detection@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.696.0.tgz#aa437d645d74cb785905162266741125c18f182a" + integrity sha512-si/maV3Z0hH7qa99f9ru2xpS5HlfSVcasRlNUXKSDm611i7jFMWwGNLUOXFAOLhXotPX5G3Z6BLwL34oDeBMug== dependencies: - "@aws-sdk/types" "3.679.0" - "@smithy/protocol-http" "^4.1.4" - "@smithy/types" "^3.5.0" + "@aws-sdk/types" "3.696.0" + "@smithy/protocol-http" "^4.1.7" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/middleware-sdk-s3@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.679.0.tgz#bc3ce2cf5de927f8cb75a0086ad8431a37434b7f" - integrity sha512-4zcT193F7RkEfqlS6ZdwyNQ0UUp9s66msNXgItugasTbjf7oqfWDas7N+BG8ADB/Ql3wvRUh9I+zdrVkxxw3BQ== - dependencies: - "@aws-sdk/core" "3.679.0" - "@aws-sdk/types" "3.679.0" - "@aws-sdk/util-arn-parser" "3.679.0" - "@smithy/core" "^2.4.8" - "@smithy/node-config-provider" "^3.1.8" - "@smithy/protocol-http" "^4.1.4" - "@smithy/signature-v4" "^4.2.0" - "@smithy/smithy-client" "^3.4.0" - "@smithy/types" "^3.5.0" +"@aws-sdk/middleware-sdk-s3@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.696.0.tgz#63199a2df26e097122c07edf2e178f6d407b0ba7" + integrity sha512-M7fEiAiN7DBMHflzOFzh1I2MNSlLpbiH2ubs87bdRc2wZsDPSbs4l3v6h3WLhxoQK0bq6vcfroudrLBgvCuX3Q== + dependencies: + "@aws-sdk/core" "3.696.0" + "@aws-sdk/types" "3.696.0" + "@aws-sdk/util-arn-parser" "3.693.0" + "@smithy/core" "^2.5.3" + "@smithy/node-config-provider" "^3.1.11" + "@smithy/protocol-http" "^4.1.7" + "@smithy/signature-v4" "^4.2.2" + "@smithy/smithy-client" "^3.4.4" + "@smithy/types" "^3.7.1" "@smithy/util-config-provider" "^3.0.0" - "@smithy/util-middleware" "^3.0.7" - "@smithy/util-stream" "^3.1.9" + "@smithy/util-middleware" "^3.0.10" + "@smithy/util-stream" "^3.3.1" "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@aws-sdk/middleware-ssec@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-ssec/-/middleware-ssec-3.679.0.tgz#72c68c46073d1e93654b9b47be61cbcf852d7804" - integrity sha512-4GNUxXbs1M71uFHRiCAZtN0/g23ogI9YjMe5isAuYMHXwDB3MhqF7usKf954mBP6tplvN44vYlbJ84faaLrTtg== +"@aws-sdk/middleware-ssec@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-ssec/-/middleware-ssec-3.696.0.tgz#b809692109f02722b90a74ca3593d4b6906ddc18" + integrity sha512-w/d6O7AOZ7Pg3w2d3BxnX5RmGNWb5X4RNxF19rJqcgu/xqxxE/QwZTNd5a7eTsqLXAUIfbbR8hh0czVfC1pJLA== dependencies: - "@aws-sdk/types" "3.679.0" - "@smithy/types" "^3.5.0" + "@aws-sdk/types" "3.696.0" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/middleware-user-agent@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.679.0.tgz#11e410967405139dee2bf69ca728be76f4e617ef" - integrity sha512-4hdeXhPDURPqQLPd9jCpUEo9fQITXl3NM3W1MwcJpE0gdUM36uXkQOYsTPeeU/IRCLVjK8Htlh2oCaM9iJrLCA== - dependencies: - "@aws-sdk/core" "3.679.0" - "@aws-sdk/types" "3.679.0" - "@aws-sdk/util-endpoints" "3.679.0" - "@smithy/core" "^2.4.8" - "@smithy/protocol-http" "^4.1.4" - "@smithy/types" "^3.5.0" +"@aws-sdk/middleware-user-agent@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.696.0.tgz#626c89300f6b3af5aefc1cb6d9ac19eebf8bc97d" + integrity sha512-Lvyj8CTyxrHI6GHd2YVZKIRI5Fmnugt3cpJo0VrKKEgK5zMySwEZ1n4dqPK6czYRWKd5+WnYHYAuU+Wdk6Jsjw== + dependencies: + "@aws-sdk/core" "3.696.0" + "@aws-sdk/types" "3.696.0" + "@aws-sdk/util-endpoints" "3.696.0" + "@smithy/core" "^2.5.3" + "@smithy/protocol-http" "^4.1.7" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/region-config-resolver@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.679.0.tgz#d205dbaea8385aaf05e637fb7cb095c60bc708be" - integrity sha512-Ybx54P8Tg6KKq5ck7uwdjiKif7n/8g1x+V0V9uTjBjRWqaIgiqzXwKWoPj6NCNkE7tJNtqI4JrNxp/3S3HvmRw== +"@aws-sdk/region-config-resolver@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.696.0.tgz#146c428702c09db75df5234b5d40ce49d147d0cf" + integrity sha512-7EuH142lBXjI8yH6dVS/CZeiK/WZsmb/8zP6bQbVYpMrppSTgB3MzZZdxVZGzL5r8zPQOU10wLC4kIMy0qdBVQ== dependencies: - "@aws-sdk/types" "3.679.0" - "@smithy/node-config-provider" "^3.1.8" - "@smithy/types" "^3.5.0" + "@aws-sdk/types" "3.696.0" + "@smithy/node-config-provider" "^3.1.11" + "@smithy/types" "^3.7.1" "@smithy/util-config-provider" "^3.0.0" - "@smithy/util-middleware" "^3.0.7" + "@smithy/util-middleware" "^3.0.10" tslib "^2.6.2" -"@aws-sdk/signature-v4-multi-region@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.679.0.tgz#174ed23967d70513345a446cb12cb9cd13026141" - integrity sha512-g1D57e7YBhgXihCWIRBcTUvKquS3FS27xuA24EynY9teiTIq7vHkASxxDnMMMcmKHnCKLI5pkznjk0PuDJ4uJw== +"@aws-sdk/signature-v4-multi-region@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.696.0.tgz#3a110c24a659818df665857e4e894e40eb59762b" + integrity sha512-ijPkoLjXuPtgxAYlDoYls8UaG/VKigROn9ebbvPL/orEY5umedd3iZTcS9T+uAf4Ur3GELLxMQiERZpfDKaz3g== dependencies: - "@aws-sdk/middleware-sdk-s3" "3.679.0" - "@aws-sdk/types" "3.679.0" - "@smithy/protocol-http" "^4.1.4" - "@smithy/signature-v4" "^4.2.0" - "@smithy/types" "^3.5.0" + "@aws-sdk/middleware-sdk-s3" "3.696.0" + "@aws-sdk/types" "3.696.0" + "@smithy/protocol-http" "^4.1.7" + "@smithy/signature-v4" "^4.2.2" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/token-providers@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.679.0.tgz#7ec462d93941dd3cfdc245104ad32971f6ebc4f6" - integrity sha512-1/+Zso/x2jqgutKixYFQEGli0FELTgah6bm7aB+m2FAWH4Hz7+iMUsazg6nSWm714sG9G3h5u42Dmpvi9X6/hA== +"@aws-sdk/token-providers@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.696.0.tgz#22ca7cf0901885d2f01aed6fe664e5162ae58108" + integrity sha512-fvTcMADrkwRdNwVmJXi2pSPf1iizmUqczrR1KusH4XehI/KybS4U6ViskRT0v07vpxwL7x+iaD/8fR0PUu5L/g== dependencies: - "@aws-sdk/types" "3.679.0" - "@smithy/property-provider" "^3.1.7" - "@smithy/shared-ini-file-loader" "^3.1.8" - "@smithy/types" "^3.5.0" + "@aws-sdk/types" "3.696.0" + "@smithy/property-provider" "^3.1.9" + "@smithy/shared-ini-file-loader" "^3.1.10" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/types@3.679.0", "@aws-sdk/types@^3.222.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.679.0.tgz#3737bb0f190add9e788b838a24cd5d8106dbed4f" - integrity sha512-NwVq8YvInxQdJ47+zz4fH3BRRLC6lL+WLkvr242PVBbUOLRyK/lkwHlfiKUoeVIMyK5NF+up6TRg71t/8Bny6Q== +"@aws-sdk/types@3.696.0", "@aws-sdk/types@^3.222.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.696.0.tgz#559c3df74dc389b6f40ba6ec6daffeab155330cd" + integrity sha512-9rTvUJIAj5d3//U5FDPWGJ1nFJLuWb30vugGOrWk7aNZ6y9tuA3PI7Cc9dP8WEXKVyK1vuuk8rSFP2iqXnlgrw== dependencies: - "@smithy/types" "^3.5.0" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/util-arn-parser@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-arn-parser/-/util-arn-parser-3.679.0.tgz#1b7793c8ae31305ca6c6f7497066f3e74ad69716" - integrity sha512-CwzEbU8R8rq9bqUFryO50RFBlkfufV9UfMArHPWlo+lmsC+NlSluHQALoj6Jkq3zf5ppn1CN0c1DDLrEqdQUXg== +"@aws-sdk/util-arn-parser@3.693.0": + version "3.693.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-arn-parser/-/util-arn-parser-3.693.0.tgz#8dae27eb822ab4f88be28bb3c0fc11f1f13d3948" + integrity sha512-WC8x6ca+NRrtpAH64rWu+ryDZI3HuLwlEr8EU6/dbC/pt+r/zC0PBoC15VEygUaBA+isppCikQpGyEDu0Yj7gQ== dependencies: tslib "^2.6.2" -"@aws-sdk/util-endpoints@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.679.0.tgz#b249ad8b4289e634cb5dfb3873a70b7aecbf323f" - integrity sha512-YL6s4Y/1zC45OvddvgE139fjeWSKKPgLlnfrvhVL7alNyY9n7beR4uhoDpNrt5mI6sn9qiBF17790o+xLAXjjg== +"@aws-sdk/util-endpoints@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.696.0.tgz#79e18714419a423a64094381b849214499f00577" + integrity sha512-T5s0IlBVX+gkb9g/I6CLt4yAZVzMSiGnbUqWihWsHvQR1WOoIcndQy/Oz/IJXT9T2ipoy7a80gzV6a5mglrioA== dependencies: - "@aws-sdk/types" "3.679.0" - "@smithy/types" "^3.5.0" - "@smithy/util-endpoints" "^2.1.3" + "@aws-sdk/types" "3.696.0" + "@smithy/types" "^3.7.1" + "@smithy/util-endpoints" "^2.1.6" tslib "^2.6.2" "@aws-sdk/util-locate-window@^3.0.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.679.0.tgz#8d5898624691e12ccbad839e103562002bbec85e" - integrity sha512-zKTd48/ZWrCplkXpYDABI74rQlbR0DNHs8nH95htfSLj9/mWRSwaGptoxwcihaq/77vi/fl2X3y0a1Bo8bt7RA== + version "3.693.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.693.0.tgz#1160f6d055cf074ca198eb8ecf89b6311537ad6c" + integrity sha512-ttrag6haJLWABhLqtg1Uf+4LgHWIMOVSYL+VYZmAp2v4PUGOwWmWQH0Zk8RM7YuQcLfH/EoR72/Yxz6A4FKcuw== dependencies: tslib "^2.6.2" -"@aws-sdk/util-user-agent-browser@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.679.0.tgz#bbaa5a8771c8a16388cd3cd934bb84a641ce907d" - integrity sha512-CusSm2bTBG1kFypcsqU8COhnYc6zltobsqs3nRrvYqYaOqtMnuE46K4XTWpnzKgwDejgZGOE+WYyprtAxrPvmQ== +"@aws-sdk/util-user-agent-browser@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.696.0.tgz#2034765c81313d5e50783662332d35ec041755a0" + integrity sha512-Z5rVNDdmPOe6ELoM5AhF/ja5tSjbe6ctSctDPb0JdDf4dT0v2MfwhJKzXju2RzX8Es/77Glh7MlaXLE0kCB9+Q== dependencies: - "@aws-sdk/types" "3.679.0" - "@smithy/types" "^3.5.0" + "@aws-sdk/types" "3.696.0" + "@smithy/types" "^3.7.1" bowser "^2.11.0" tslib "^2.6.2" -"@aws-sdk/util-user-agent-node@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.679.0.tgz#0d1cd6eba18bfe6d0106d78fc7aa9b74889c462b" - integrity sha512-Bw4uXZ+NU5ed6TNfo4tBbhBSW+2eQxXYjYBGl5gLUNUpg2pDFToQAP6rXBFiwcG52V2ny5oLGiD82SoYuYkAVg== +"@aws-sdk/util-user-agent-node@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.696.0.tgz#3267119e2be02185f3b4e0beb0cc495d392260b4" + integrity sha512-KhKqcfyXIB0SCCt+qsu4eJjsfiOrNzK5dCV7RAW2YIpp+msxGUUX0NdRE9rkzjiv+3EMktgJm3eEIS+yxtlVdQ== dependencies: - "@aws-sdk/middleware-user-agent" "3.679.0" - "@aws-sdk/types" "3.679.0" - "@smithy/node-config-provider" "^3.1.8" - "@smithy/types" "^3.5.0" + "@aws-sdk/middleware-user-agent" "3.696.0" + "@aws-sdk/types" "3.696.0" + "@smithy/node-config-provider" "^3.1.11" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@aws-sdk/xml-builder@3.679.0": - version "3.679.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/xml-builder/-/xml-builder-3.679.0.tgz#96ccb7a4a4d4faa881d1fec5fc0554dc726843b5" - integrity sha512-nPmhVZb39ty5bcQ7mAwtjezBcsBqTYZ9A2D9v/lE92KCLdu5RhSkPH7O71ZqbZx1mUSg9fAOxHPiG79U5VlpLQ== +"@aws-sdk/xml-builder@3.696.0": + version "3.696.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/xml-builder/-/xml-builder-3.696.0.tgz#ff3e37ee23208f9986f20d326cc278c0ee341164" + integrity sha512-dn1mX+EeqivoLYnY7p2qLrir0waPnCgS/0YdRCAVU2x14FgfUYCH6Im3w3oi2dMwhxfKY5lYVB5NKvZu7uI9lQ== dependencies: - "@smithy/types" "^3.5.0" + "@smithy/types" "^3.7.1" tslib "^2.6.2" "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.24.7", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.0.tgz#9374b5cd068d128dac0b94ff482594273b1c2815" - integrity sha512-INCKxTtbXtcNbUZ3YXutwMpEleqttcswhAdee7dhuoVrD2cnuc3PqtERBtxkX5nziX9vnBL8WXmSGwv8CuPV6g== + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" + integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== dependencies: "@babel/helper-validator-identifier" "^7.25.9" js-tokens "^4.0.0" picocolors "^1.0.0" "@babel/compat-data@^7.25.9": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.0.tgz#f02ba6d34e88fadd5e8861e8b38902f43cc1c819" - integrity sha512-qETICbZSLe7uXv9VE8T/RWOdIE5qqyTucOt4zLYMafj2MRO271VGgLd4RACJMeBO37UPWhXiKMBk7YlJ0fOzQA== + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.2.tgz#278b6b13664557de95b8f35b90d96785850bb56e" + integrity sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg== "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9", "@babel/core@^7.24.7": version "7.26.0" @@ -735,11 +737,11 @@ semver "^6.3.1" "@babel/generator@^7.24.9", "@babel/generator@^7.25.9", "@babel/generator@^7.26.0", "@babel/generator@^7.7.2": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.0.tgz#505cc7c90d92513f458a477e5ef0703e7c91b8d7" - integrity sha512-/AIkAmInnWwgEAJGQr9vY0c66Mj6kjkE2ZPB1PurTRaRAh3U+J45sAQMjQDJdh4WbR3l0x5xkimXBKyBXXAu2w== + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.2.tgz#87b75813bec87916210e5e01939a4c823d6bb74f" + integrity sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw== dependencies: - "@babel/parser" "^7.26.0" + "@babel/parser" "^7.26.2" "@babel/types" "^7.26.0" "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" @@ -801,10 +803,10 @@ "@babel/template" "^7.25.9" "@babel/types" "^7.26.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.24.8", "@babel/parser@^7.25.9", "@babel/parser@^7.26.0": - version "7.26.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.0.tgz#710a75a7d805a8f72753154e451474e9795b121c" - integrity sha512-aP8x5pIw3xvYr/sXT+SEUwyhrXT8rUJRZltK/qN3Db80dcKpTett8cJxHyjk+xYSVXvNnl2SfcJVjbwxpOSscA== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.24.8", "@babel/parser@^7.25.9", "@babel/parser@^7.26.0", "@babel/parser@^7.26.2": + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.2.tgz#fd7b6f487cfea09889557ef5d4eeb9ff9a5abd11" + integrity sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ== dependencies: "@babel/types" "^7.26.0" @@ -985,16 +987,16 @@ "@jridgewell/trace-mapping" "0.3.9" "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": - version "4.4.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + version "4.4.1" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz#d1145bf2c20132d6400495d6df4bf59362fd9d56" + integrity sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA== dependencies: - eslint-visitor-keys "^3.3.0" + eslint-visitor-keys "^3.4.3" "@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.6.1": - version "4.11.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.1.tgz#a547badfc719eb3e5f4b556325e542fbe9d7a18f" - integrity sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q== + version "4.12.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" + integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== "@eslint/eslintrc@^2.1.4": version "2.1.4" @@ -1035,7 +1037,18 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== -"@inquirer/confirm@^3.1.22", "@inquirer/confirm@^3.2.0": +"@inquirer/checkbox@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@inquirer/checkbox/-/checkbox-4.0.2.tgz#e45e0ad2611f2cb2d337ba36c7d955b53f195914" + integrity sha512-+gznPl8ip8P8HYHYecDtUtdsh1t2jvb+sWCD72GAiZ9m45RqwrLmReDaqdC0umQfamtFXVRoMVJ2/qINKGm9Tg== + dependencies: + "@inquirer/core" "^10.1.0" + "@inquirer/figures" "^1.0.8" + "@inquirer/type" "^3.0.1" + ansi-escapes "^4.3.2" + yoctocolors-cjs "^2.1.2" + +"@inquirer/confirm@^3.1.22": version "3.2.0" resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-3.2.0.tgz#6af1284670ea7c7d95e3f1253684cfbd7228ad6a" integrity sha512-oOIwPs0Dvq5220Z8lGL/6LHRTEr9TgLHmiI99Rj1PJ1p1czTys+olrgBqZk4E2qC0YTzeHprxSQmoHioVdJ7Lw== @@ -1043,6 +1056,29 @@ "@inquirer/core" "^9.1.0" "@inquirer/type" "^1.5.3" +"@inquirer/confirm@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-5.0.2.tgz#2b9dcf6b7da5f518c74abe4aeaf3173253d83c93" + integrity sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA== + dependencies: + "@inquirer/core" "^10.1.0" + "@inquirer/type" "^3.0.1" + +"@inquirer/core@^10.1.0": + version "10.1.0" + resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-10.1.0.tgz#c5fdc34c4cafd7248da29a3c3b3120fe6e1c45be" + integrity sha512-I+ETk2AL+yAVbvuKx5AJpQmoaWhpiTFOg/UJb7ZkMAK4blmtG8ATh5ct+T/8xNld0CZG/2UhtkdMwpgvld92XQ== + dependencies: + "@inquirer/figures" "^1.0.8" + "@inquirer/type" "^3.0.1" + ansi-escapes "^4.3.2" + cli-width "^4.1.0" + mute-stream "^2.0.0" + signal-exit "^4.1.0" + strip-ansi "^6.0.1" + wrap-ansi "^6.2.0" + yoctocolors-cjs "^2.1.2" + "@inquirer/core@^9.1.0": version "9.2.1" resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-9.2.1.tgz#677c49dee399c9063f31e0c93f0f37bddc67add1" @@ -1061,10 +1097,28 @@ wrap-ansi "^6.2.0" yoctocolors-cjs "^2.1.2" -"@inquirer/figures@^1.0.5", "@inquirer/figures@^1.0.6": - version "1.0.7" - resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.7.tgz#d050ccc0eabfacc0248c4ff647a9dfba1b01594b" - integrity sha512-m+Trk77mp54Zma6xLkLuY+mvanPxlE4A7yNKs2HBiyZ4UkVs28Mv5c/pgWrHeInx+USHeX/WEPzjrWrcJiQgjw== +"@inquirer/editor@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@inquirer/editor/-/editor-4.1.0.tgz#bc1a8bebe5897d4b44b0bfab1aeb1b5172f8d812" + integrity sha512-K1gGWsxEqO23tVdp5MT3H799OZ4ER1za7Dlc8F4um0W7lwSv0KGR/YyrUEyimj0g7dXZd8XknM/5QA2/Uy+TbA== + dependencies: + "@inquirer/core" "^10.1.0" + "@inquirer/type" "^3.0.1" + external-editor "^3.1.0" + +"@inquirer/expand@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@inquirer/expand/-/expand-4.0.2.tgz#7b5c332ad604d7d076e7052b8e5006a3b61c3274" + integrity sha512-WdgCX1cUtinz+syKyZdJomovULYlKUWZbVYZzhf+ZeeYf4htAQ3jLymoNs3koIAKfZZl3HUBb819ClCBfyznaw== + dependencies: + "@inquirer/core" "^10.1.0" + "@inquirer/type" "^3.0.1" + yoctocolors-cjs "^2.1.2" + +"@inquirer/figures@^1.0.5", "@inquirer/figures@^1.0.6", "@inquirer/figures@^1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.8.tgz#d9e414a1376a331a0e71b151fea27c48845788b0" + integrity sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg== "@inquirer/input@^2.2.4": version "2.3.0" @@ -1074,6 +1128,66 @@ "@inquirer/core" "^9.1.0" "@inquirer/type" "^1.5.3" +"@inquirer/input@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@inquirer/input/-/input-4.0.2.tgz#be77b79a1ed182444a6eef2d850309639aa9df22" + integrity sha512-yCLCraigU085EcdpIVEDgyfGv4vBiE4I+k1qRkc9C5dMjWF42ADMGy1RFU94+eZlz4YlkmFsiyHZy0W1wdhaNg== + dependencies: + "@inquirer/core" "^10.1.0" + "@inquirer/type" "^3.0.1" + +"@inquirer/number@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@inquirer/number/-/number-3.0.2.tgz#7e8315b41601d377cc09802b66f32b481e14fd68" + integrity sha512-MKQhYofdUNk7eqJtz52KvM1dH6R93OMrqHduXCvuefKrsiMjHiMwjc3NZw5Imm2nqY7gWd9xdhYrtcHMJQZUxA== + dependencies: + "@inquirer/core" "^10.1.0" + "@inquirer/type" "^3.0.1" + +"@inquirer/password@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@inquirer/password/-/password-4.0.2.tgz#5913e2818b3de1ee6f63ec1b0891a43c1d4bdca9" + integrity sha512-tQXGSu7IO07gsYlGy3VgXRVsbOWqFBMbqAUrJSc1PDTQQ5Qdm+QVwkP0OC0jnUZ62D19iPgXOMO+tnWG+HhjNQ== + dependencies: + "@inquirer/core" "^10.1.0" + "@inquirer/type" "^3.0.1" + ansi-escapes "^4.3.2" + +"@inquirer/prompts@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@inquirer/prompts/-/prompts-7.1.0.tgz#a55ee589c0eed0ca2ee0fbc7fc63f42f4c31a24e" + integrity sha512-5U/XiVRH2pp1X6gpNAjWOglMf38/Ys522ncEHIKT1voRUvSj/DQnR22OVxHnwu5S+rCFaUiPQ57JOtMFQayqYA== + dependencies: + "@inquirer/checkbox" "^4.0.2" + "@inquirer/confirm" "^5.0.2" + "@inquirer/editor" "^4.1.0" + "@inquirer/expand" "^4.0.2" + "@inquirer/input" "^4.0.2" + "@inquirer/number" "^3.0.2" + "@inquirer/password" "^4.0.2" + "@inquirer/rawlist" "^4.0.2" + "@inquirer/search" "^3.0.2" + "@inquirer/select" "^4.0.2" + +"@inquirer/rawlist@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@inquirer/rawlist/-/rawlist-4.0.2.tgz#78a58294505bed2a5e133153340f187967916702" + integrity sha512-3XGcskMoVF8H0Dl1S5TSZ3rMPPBWXRcM0VeNVsS4ByWeWjSeb0lPqfnBg6N7T0608I1B2bSVnbi2cwCrmOD1Yw== + dependencies: + "@inquirer/core" "^10.1.0" + "@inquirer/type" "^3.0.1" + yoctocolors-cjs "^2.1.2" + +"@inquirer/search@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@inquirer/search/-/search-3.0.2.tgz#71fccc766045f2ec37afc402d72ce31838768281" + integrity sha512-Zv4FC7w4dJ13BOJfKRQCICQfShinGjb1bCEIHxTSnjj2telu3+3RHwHubPG9HyD4aix5s+lyAMEK/wSFD75HLA== + dependencies: + "@inquirer/core" "^10.1.0" + "@inquirer/figures" "^1.0.8" + "@inquirer/type" "^3.0.1" + yoctocolors-cjs "^2.1.2" + "@inquirer/select@^2.5.0": version "2.5.0" resolved "https://registry.yarnpkg.com/@inquirer/select/-/select-2.5.0.tgz#345c6908ecfaeef3d84ddd2f9feb2f487c558efb" @@ -1085,6 +1199,17 @@ ansi-escapes "^4.3.2" yoctocolors-cjs "^2.1.2" +"@inquirer/select@^4.0.2": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@inquirer/select/-/select-4.0.2.tgz#c38ef154524a6859de4a1af11a90ad3f9638c9f2" + integrity sha512-uSWUzaSYAEj0hlzxa1mUB6VqrKaYx0QxGBLZzU4xWFxaSyGaXxsSE4OSOwdU24j0xl8OajgayqFXW0l2bkl2kg== + dependencies: + "@inquirer/core" "^10.1.0" + "@inquirer/figures" "^1.0.8" + "@inquirer/type" "^3.0.1" + ansi-escapes "^4.3.2" + yoctocolors-cjs "^2.1.2" + "@inquirer/type@^1.5.3": version "1.5.5" resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-1.5.5.tgz#303ea04ce7ad2e585b921b662b3be36ef7b4f09b" @@ -1099,6 +1224,11 @@ dependencies: mute-stream "^1.0.0" +"@inquirer/type@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-3.0.1.tgz#619ce9f65c3e114d8e39c41822bed3440d20b478" + integrity sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A== + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -1348,9 +1478,9 @@ "@jridgewell/sourcemap-codec" "^1.4.14" "@jsforce/jsforce-node@^3.6.1": - version "3.6.1" - resolved "https://registry.yarnpkg.com/@jsforce/jsforce-node/-/jsforce-node-3.6.1.tgz#cdd112a33b8139ca798dd4eef91d3dc2a5a0f291" - integrity sha512-N294vrCY7bIdHzTNAHe0t20riTxozEyvCmYPM4rp/C7uGdBX3AYrPDBdojw7rsXOBsRtoFqr7L/tUwMbw1hRTg== + version "3.6.2" + resolved "https://registry.yarnpkg.com/@jsforce/jsforce-node/-/jsforce-node-3.6.2.tgz#5d8509aaeb161f1d6658e4ce737948a04d3ce3a6" + integrity sha512-bBWRCZl4kVRnYLHRSzl4piqowM3GeTW2yBoKo+WnMGAw36uGjyMq/9z9yAaA+0AmpHFaI4po7/0PrAMdEU/AGA== dependencies: "@sindresorhus/is" "^4" base64url "^3.0.1" @@ -1467,10 +1597,10 @@ wordwrap "^1.0.0" wrap-ansi "^7.0.0" -"@oclif/core@^4", "@oclif/core@^4.0.29": - version "4.0.30" - resolved "https://registry.yarnpkg.com/@oclif/core/-/core-4.0.30.tgz#65672282756bf19fde3830cab6d8031bf6236064" - integrity sha512-Ak3OUdOcoovIRWZOT6oC5JhZgyJD90uWX/7HjSofn+C4LEmHxxfiyu04a73dwnezfzqDu9jEXfd2mQOOC54KZw== +"@oclif/core@^4", "@oclif/core@^4.0.32": + version "4.0.33" + resolved "https://registry.yarnpkg.com/@oclif/core/-/core-4.0.33.tgz#fcaf3dd2850c5999de20459a1445d31a230cd24b" + integrity sha512-NoTDwJ2L/ywpsSjcN7jAAHf3m70Px4Yim2SJrm16r70XpnfbNOdlj1x0HEJ0t95gfD+p/y5uy+qPT/VXTh/1gw== dependencies: ansi-escapes "^4.3.2" ansis "^3.3.2" @@ -1481,7 +1611,7 @@ get-package-type "^0.1.0" globby "^11.1.0" indent-string "^4.0.0" - is-wsl "^3" + is-wsl "^2.2.0" lilconfig "^3.1.2" minimatch "^9.0.5" semver "^7.6.3" @@ -1498,27 +1628,27 @@ dependencies: "@oclif/core" "^2.15.0" -"@oclif/plugin-help@^6.2.14": - version "6.2.16" - resolved "https://registry.yarnpkg.com/@oclif/plugin-help/-/plugin-help-6.2.16.tgz#3cb6c068739bc934159dc430d4f8ca7f9effa22a" - integrity sha512-1x/Bm0LebDouDOfsjkOz+6AXqY6gIZ6JmmU/KuF/GnUmowDvj5i3MFlP9uBTiN8UsOUeT9cdLwnc1kmitHWFTg== +"@oclif/plugin-help@^6.2.17": + version "6.2.18" + resolved "https://registry.yarnpkg.com/@oclif/plugin-help/-/plugin-help-6.2.18.tgz#fab8173773bb0afcc7a8e459187021fe65c461df" + integrity sha512-mDYOl8RmldLkOg9i9YKgyBlpcyi/bNySoIVHJ2EJd2qCmZaXRKQKRW2Zkx92bwjik8jfs/A3EFI+p4DsrXi57g== dependencies: "@oclif/core" "^4" -"@oclif/plugin-not-found@^3.2.21": - version "3.2.22" - resolved "https://registry.yarnpkg.com/@oclif/plugin-not-found/-/plugin-not-found-3.2.22.tgz#f217622cfc61ae047c53059fa7990d982d1e6aff" - integrity sha512-snd/gmYjTYIa8vr5rPLNus0ymKhhITRTFWLlYCJvAZTs2kX+vUMMdpKId9pEPSzoVGmyddNVshWSCJ2FSgR0mg== +"@oclif/plugin-not-found@^3.2.25": + version "3.2.28" + resolved "https://registry.yarnpkg.com/@oclif/plugin-not-found/-/plugin-not-found-3.2.28.tgz#c0cb47b4482e604b51fe270d6f757bb78c5c68a7" + integrity sha512-ObkesXE8F4Hj/AzOCQGI39hqDqm+MfaqY5ByG77uhSkMI4dMaDcPjXZSj1Ftn2mkhZiRk70YN3wTCG4HO/8gqw== dependencies: - "@inquirer/confirm" "^3.2.0" + "@inquirer/prompts" "^7.1.0" "@oclif/core" "^4" ansis "^3.3.1" fast-levenshtein "^3.0.0" -"@oclif/plugin-warn-if-update-available@^3.1.11": - version "3.1.20" - resolved "https://registry.yarnpkg.com/@oclif/plugin-warn-if-update-available/-/plugin-warn-if-update-available-3.1.20.tgz#2ac90286a0b59860c66956c37a74b27f2a4e78d0" - integrity sha512-gvovUQXwWkQZzHG7WknLq+yoSe61Cbv45rEUooKbzo7tfRDChFnCyLQ+OCCldQOsSYvS/KTsiawyyCetSaCR1g== +"@oclif/plugin-warn-if-update-available@^3.1.21": + version "3.1.23" + resolved "https://registry.yarnpkg.com/@oclif/plugin-warn-if-update-available/-/plugin-warn-if-update-available-3.1.23.tgz#443b8d1d6f9303fadad1241815167f4e0c706ff9" + integrity sha512-0R15OCkpWktUsEdfVNvOIY078rE92Dkor2mB/F2/xW0/VEe3NQEVtiXMatpwYsjc4KKIiWtAVm2P0oQhEbodkg== dependencies: "@oclif/core" "^4" ansis "^3.3.1" @@ -1554,11 +1684,11 @@ integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== "@salesforce/cli-plugins-testkit@^5.3.8": - version "5.3.34" - resolved "https://registry.yarnpkg.com/@salesforce/cli-plugins-testkit/-/cli-plugins-testkit-5.3.34.tgz#456503a30dade3459e1736a77a362fce2b41947b" - integrity sha512-OiXjWiLM1euGNr+DRK8iaOYAhp1gnhkD9oxbk+TZC2gQ/RYQ39dd/FEIGqyleCmeeFQMWupKXXni1dEighgoCw== + version "5.3.38" + resolved "https://registry.yarnpkg.com/@salesforce/cli-plugins-testkit/-/cli-plugins-testkit-5.3.38.tgz#ab34836662cf5aa1cb4d53e4b994fc750df206e5" + integrity sha512-wNLEEk5SCeTsNhd0RM8zxTv8sEuuSLowjVN9jlP8H50/unGHKAsfsc/7ZJpi78U3T4tgxbGXdneOo8WpaZe4zg== dependencies: - "@salesforce/core" "^8.6.2" + "@salesforce/core" "^8.8.0" "@salesforce/kit" "^3.2.3" "@salesforce/ts-types" "^2.0.11" "@types/shelljs" "^0.8.15" @@ -1569,12 +1699,12 @@ strip-ansi "6.0.1" ts-retry-promise "^0.8.1" -"@salesforce/code-analyzer-core@0.16.0": - version "0.16.0" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-core/-/code-analyzer-core-0.16.0.tgz#e9aec49c7e3835d29f22b715388a16267c632afd" - integrity sha512-hqOUF4dFNjY9w6pMlw8eIDN1jnm8aypLH3KEdPMI2asmLjOI1C1EOZ6IYrlsclYX6Czr9f5LzShaa0l5CJabaQ== +"@salesforce/code-analyzer-core@0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-core/-/code-analyzer-core-0.17.0.tgz#4e2c753b2a08525b1952f08f40b416460ffe7181" + integrity sha512-uLAk5q/YdDxqkWfWO0iZBYuZ68DSwsj+HxHVYqtWy+xrBZBpm6JFW06l3wzrtKopAOO4l/CVdVxrR5lXEqgHWQ== dependencies: - "@salesforce/code-analyzer-engine-api" "0.13.0" + "@salesforce/code-analyzer-engine-api" "0.14.0" "@types/js-yaml" "^4.0.9" "@types/node" "^20.0.0" "@types/sarif" "^2.1.7" @@ -1582,23 +1712,23 @@ js-yaml "^4.1.0" xmlbuilder "^15.1.1" -"@salesforce/code-analyzer-engine-api@0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-engine-api/-/code-analyzer-engine-api-0.13.0.tgz#dbaba9102d34ea12472f4115298da8d617a0492d" - integrity sha512-dcVuoYUbzEXcW1+l0tjoOquu6VSgr41ti+tOKE/569Wb+hf4Yu7LhXFGq4Gq5tueZDuODjDYDWuFnmmgcAwBJw== +"@salesforce/code-analyzer-engine-api@0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-engine-api/-/code-analyzer-engine-api-0.14.0.tgz#5cefeafbcd88850342759ad68f0e79e595667630" + integrity sha512-SKqiHKtARSzA3NOaR/hXENt6Z+LmSIozhu2LEBGSq0tlqYtw/89pLXBUv2rozh/wfsyEERAQcxgpPT3v4cVqnQ== dependencies: "@types/node" "^20.0.0" -"@salesforce/code-analyzer-eslint-engine@0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-eslint-engine/-/code-analyzer-eslint-engine-0.13.0.tgz#1bb3688e94a63f4b6c0db941e0ce6fc84ca2b0de" - integrity sha512-UnEQB+5KiZIcQJYIVrAB1XzJnymyRAm6NXy2naETOdqXwVxjXo1jvSNuw68BfKQXs36GXf+EfjF/H+CnXurvHQ== +"@salesforce/code-analyzer-eslint-engine@0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-eslint-engine/-/code-analyzer-eslint-engine-0.14.0.tgz#5735f440ed312f58d70b9b5032fffdb0d98c55d7" + integrity sha512-9WzeB8MXATi+YxKKfbwnkc5vueTMFnJQSQU7kBudtCmEqHB2gIEJsgjQsEKOgT3OSmBW1Vt7mMBY/VcpySBABw== dependencies: "@babel/core" "^7.24.7" "@babel/eslint-parser" "^7.24.7" "@eslint/js" "^8.57.0" "@lwc/eslint-plugin-lwc" "^1.8.0" - "@salesforce/code-analyzer-engine-api" "0.13.0" + "@salesforce/code-analyzer-engine-api" "0.14.0" "@salesforce/eslint-config-lwc" "^3.5.3" "@salesforce/eslint-plugin-lightning" "^1.0.0" "@types/eslint" "^8.56.10" @@ -1609,33 +1739,33 @@ eslint-plugin-import "^2.29.1" eslint-plugin-jest "^28.6.0" -"@salesforce/code-analyzer-pmd-engine@0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-pmd-engine/-/code-analyzer-pmd-engine-0.13.0.tgz#c3db9ee1cd73d46bdb940aea1c6888e64bea51b1" - integrity sha512-5TMiTL520jNfVcewX7IlsScNoxh5CDyQI5lrilZEa+LkgR9wvFI8b0N+uzz82Iz9xPp+tzmgnW9QVODaCLwdwQ== +"@salesforce/code-analyzer-pmd-engine@0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-pmd-engine/-/code-analyzer-pmd-engine-0.14.0.tgz#580a4b038a9f6468689e35a0e8e2867e71b5d75c" + integrity sha512-+fHZU1CnweU9ZD0sEF/TezWsQfUspA/FiLg7itilosjF+BICtc0MMGlDLjsxcHkKFWubfLfcPGZHK9Zn4Fhr+Q== dependencies: - "@salesforce/code-analyzer-engine-api" "0.13.0" + "@salesforce/code-analyzer-engine-api" "0.14.0" "@types/node" "^20.0.0" "@types/semver" "^7.5.8" "@types/tmp" "^0.2.6" semver "^7.6.3" tmp "^0.2.3" -"@salesforce/code-analyzer-regex-engine@0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-regex-engine/-/code-analyzer-regex-engine-0.13.0.tgz#0bff0037483663d2707a01d05a9b4d8f5951e1fc" - integrity sha512-6eDG9muy74jHw46rVE+W3MOzuKPpbxvmE+DK6i/JB3qh00OIv7JmVysuAuXV9mvGhO1jj+FBHfug2ZexKEhGUw== +"@salesforce/code-analyzer-regex-engine@0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-regex-engine/-/code-analyzer-regex-engine-0.14.0.tgz#0157910c8c43124cb9c9fb4acfef43c593c51ce8" + integrity sha512-yNef0gfFF7yfXmyLVDEUfCqpKTtaZgw7YlJ/qsyIiMxwou1CTtfKcPOSG3I71vgoc0syQ1ssAUIFFNhkk5kKjw== dependencies: - "@salesforce/code-analyzer-engine-api" "0.13.0" + "@salesforce/code-analyzer-engine-api" "0.14.0" "@types/node" "^20.0.0" isbinaryfile "^5.0.2" -"@salesforce/code-analyzer-retirejs-engine@0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-retirejs-engine/-/code-analyzer-retirejs-engine-0.13.0.tgz#943c6be8f1cd4607a34044e33114bd5834e4e015" - integrity sha512-1AN9vTKifDR2QsR56VCr4Xuy5EzxmsL95gmfYoxJwo4brf6QzW3/5XgaaanCEfWAdLbONYkEnJMsT45RE30uJA== +"@salesforce/code-analyzer-retirejs-engine@0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-retirejs-engine/-/code-analyzer-retirejs-engine-0.14.0.tgz#48a9cde0010153688a49caff7145e99c1331dde7" + integrity sha512-ZxzfHakDF/5lseuPvq/0TeRM0NrUfGI/waW2Oz2NuHd3FDvyFSnAZ/QlZvedd0UdGqQhe/U4PVHj/tSdFOh5TQ== dependencies: - "@salesforce/code-analyzer-engine-api" "0.13.0" + "@salesforce/code-analyzer-engine-api" "0.14.0" "@types/node" "^20.0.0" "@types/tmp" "^0.2.6" isbinaryfile "^5.0.2" @@ -1690,10 +1820,10 @@ semver "^7.6.0" ts-retry-promise "^0.7.1" -"@salesforce/core@^8.6.2": - version "8.6.3" - resolved "https://registry.yarnpkg.com/@salesforce/core/-/core-8.6.3.tgz#1a4d50eaa2b731c1e480986cef96b414ccafd347" - integrity sha512-fxY3J9AttGztTY45AYH4QP1cKB3OD1fJMDd1j/ALGCI6EMb2iMPp52awKVKHxrd/eTbZhn1OV5Jr0r6nJx5Hhw== +"@salesforce/core@^8.8.0": + version "8.8.0" + resolved "https://registry.yarnpkg.com/@salesforce/core/-/core-8.8.0.tgz#849c07ea3a2548ca201fc0fe8baef9b36a462194" + integrity sha512-HWGdRiy/MPCJ2KHz+W+cnqx0O9xhx9+QYvwP8bn9PE27wj0A/NjTi4xrqIWk1M+fE4dXHycE+8qPf4b540euvg== dependencies: "@jsforce/jsforce-node" "^3.6.1" "@salesforce/kit" "^3.2.2" @@ -1809,12 +1939,12 @@ resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz#282046f03e886e352b2d5f5da5eb755e01457f3f" integrity sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA== -"@smithy/abort-controller@^3.1.6": - version "3.1.6" - resolved "https://registry.yarnpkg.com/@smithy/abort-controller/-/abort-controller-3.1.6.tgz#d9de97b85ca277df6ffb9ee7cd83d5da793ee6de" - integrity sha512-0XuhuHQlEqbNQZp7QxxrFTdVWdwxch4vjxYgfInF91hZFkPxf9QDrdQka0KfxFMPqLNzSw0b95uGTrLliQUavQ== +"@smithy/abort-controller@^3.1.8": + version "3.1.8" + resolved "https://registry.yarnpkg.com/@smithy/abort-controller/-/abort-controller-3.1.8.tgz#ce0c10ddb2b39107d70b06bbb8e4f6e368bc551d" + integrity sha512-+3DOBcUn5/rVjlxGvUPKc416SExarAQ+Qe0bqk30YSUjbepwpS7QN0cyKUSifvLJhdMZ0WPzPP5ymut0oonrpQ== dependencies: - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" tslib "^2.6.2" "@smithy/chunked-blob-reader-native@^3.0.1": @@ -1832,144 +1962,133 @@ dependencies: tslib "^2.6.2" -"@smithy/config-resolver@^3.0.10", "@smithy/config-resolver@^3.0.9": - version "3.0.10" - resolved "https://registry.yarnpkg.com/@smithy/config-resolver/-/config-resolver-3.0.10.tgz#d9529d9893e5fae1f14cb1ffd55517feb6d7e50f" - integrity sha512-Uh0Sz9gdUuz538nvkPiyv1DZRX9+D15EKDtnQP5rYVAzM/dnYk3P8cg73jcxyOitPgT3mE3OVj7ky7sibzHWkw== +"@smithy/config-resolver@^3.0.12": + version "3.0.12" + resolved "https://registry.yarnpkg.com/@smithy/config-resolver/-/config-resolver-3.0.12.tgz#f355f95fcb5ee932a90871a488a4f2128e8ad3ac" + integrity sha512-YAJP9UJFZRZ8N+UruTeq78zkdjUHmzsY62J4qKWZ4SXB4QXJ/+680EfXXgkYA2xj77ooMqtUY9m406zGNqwivQ== dependencies: - "@smithy/node-config-provider" "^3.1.9" - "@smithy/types" "^3.6.0" + "@smithy/node-config-provider" "^3.1.11" + "@smithy/types" "^3.7.1" "@smithy/util-config-provider" "^3.0.0" - "@smithy/util-middleware" "^3.0.8" + "@smithy/util-middleware" "^3.0.10" tslib "^2.6.2" -"@smithy/core@^2.4.8", "@smithy/core@^2.5.1": - version "2.5.1" - resolved "https://registry.yarnpkg.com/@smithy/core/-/core-2.5.1.tgz#7f635b76778afca845bcb401d36f22fa37712f15" - integrity sha512-DujtuDA7BGEKExJ05W5OdxCoyekcKT3Rhg1ZGeiUWaz2BJIWXjZmsG/DIP4W48GHno7AQwRsaCb8NcBgH3QZpg== +"@smithy/core@^2.5.3": + version "2.5.3" + resolved "https://registry.yarnpkg.com/@smithy/core/-/core-2.5.3.tgz#1d5723f676b0d6ec08c515272f0ac03aa59fac72" + integrity sha512-96uW8maifUSmehaeW7uydWn7wBc98NEeNI3zN8vqakGpyCQgzyJaA64Z4FCOUmAdCJkhppd/7SZ798Fo4Xx37g== dependencies: - "@smithy/middleware-serde" "^3.0.8" - "@smithy/protocol-http" "^4.1.5" - "@smithy/types" "^3.6.0" + "@smithy/middleware-serde" "^3.0.10" + "@smithy/protocol-http" "^4.1.7" + "@smithy/types" "^3.7.1" "@smithy/util-body-length-browser" "^3.0.0" - "@smithy/util-middleware" "^3.0.8" - "@smithy/util-stream" "^3.2.1" + "@smithy/util-middleware" "^3.0.10" + "@smithy/util-stream" "^3.3.1" "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@smithy/credential-provider-imds@^3.2.4", "@smithy/credential-provider-imds@^3.2.5": - version "3.2.5" - resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.5.tgz#dbfd849a4a7ebd68519cd9fc35f78d091e126d0a" - integrity sha512-4FTQGAsuwqTzVMmiRVTn0RR9GrbRfkP0wfu/tXWVHd2LgNpTY0uglQpIScXK4NaEyXbB3JmZt8gfVqO50lP8wg== +"@smithy/credential-provider-imds@^3.2.6", "@smithy/credential-provider-imds@^3.2.7": + version "3.2.7" + resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.7.tgz#6eedf87ba0238723ec46d8ce0f18e276685a702d" + integrity sha512-cEfbau+rrWF8ylkmmVAObOmjbTIzKyUC5TkBL58SbLywD0RCBC4JAUKbmtSm2w5KUJNRPGgpGFMvE2FKnuNlWQ== dependencies: - "@smithy/node-config-provider" "^3.1.9" - "@smithy/property-provider" "^3.1.8" - "@smithy/types" "^3.6.0" - "@smithy/url-parser" "^3.0.8" + "@smithy/node-config-provider" "^3.1.11" + "@smithy/property-provider" "^3.1.10" + "@smithy/types" "^3.7.1" + "@smithy/url-parser" "^3.0.10" tslib "^2.6.2" -"@smithy/eventstream-codec@^3.1.7": - version "3.1.7" - resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-3.1.7.tgz#5bfaffbc83ae374ffd85a755a8200ba3c7aed016" - integrity sha512-kVSXScIiRN7q+s1x7BrQtZ1Aa9hvvP9FeCqCdBxv37GimIHgBCOnZ5Ip80HLt0DhnAKpiobFdGqTFgbaJNrazA== +"@smithy/eventstream-codec@^3.1.9": + version "3.1.9" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-codec/-/eventstream-codec-3.1.9.tgz#4271354e75e57d30771fca307da403896c657430" + integrity sha512-F574nX0hhlNOjBnP+noLtsPFqXnWh2L0+nZKCwcu7P7J8k+k+rdIDs+RMnrMwrzhUE4mwMgyN0cYnEn0G8yrnQ== dependencies: "@aws-crypto/crc32" "5.2.0" - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" "@smithy/util-hex-encoding" "^3.0.0" tslib "^2.6.2" -"@smithy/eventstream-serde-browser@^3.0.10": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.11.tgz#019f3d1016d893b65ef6efec8c5e2fa925d0ac3d" - integrity sha512-Pd1Wnq3CQ/v2SxRifDUihvpXzirJYbbtXfEnnLV/z0OGCTx/btVX74P86IgrZkjOydOASBGXdPpupYQI+iO/6A== +"@smithy/eventstream-serde-browser@^3.0.13": + version "3.0.13" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.13.tgz#191dcf9181e7ab0914ec43d51518d471b9d466ae" + integrity sha512-Nee9m+97o9Qj6/XeLz2g2vANS2SZgAxV4rDBMKGHvFJHU/xz88x2RwCkwsvEwYjSX4BV1NG1JXmxEaDUzZTAtw== dependencies: - "@smithy/eventstream-serde-universal" "^3.0.10" - "@smithy/types" "^3.6.0" + "@smithy/eventstream-serde-universal" "^3.0.12" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/eventstream-serde-config-resolver@^3.0.7": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.8.tgz#bba17a358818e61993aaa73e36ea4023c5805556" - integrity sha512-zkFIG2i1BLbfoGQnf1qEeMqX0h5qAznzaZmMVNnvPZz9J5AWBPkOMckZWPedGUPcVITacwIdQXoPcdIQq5FRcg== - dependencies: - "@smithy/types" "^3.6.0" - tslib "^2.6.2" - -"@smithy/eventstream-serde-node@^3.0.9": +"@smithy/eventstream-serde-config-resolver@^3.0.10": version "3.0.10" - resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.10.tgz#da40b872001390bb47807186855faba8172b3b5b" - integrity sha512-hjpU1tIsJ9qpcoZq9zGHBJPBOeBGYt+n8vfhDwnITPhEre6APrvqq/y3XMDEGUT2cWQ4ramNqBPRbx3qn55rhw== + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.10.tgz#5c0b2ae0bb8e11cfa77851098e46f7350047ec8d" + integrity sha512-K1M0x7P7qbBUKB0UWIL5KOcyi6zqV5mPJoL0/o01HPJr0CSq3A9FYuJC6e11EX6hR8QTIR++DBiGrYveOu6trw== dependencies: - "@smithy/eventstream-serde-universal" "^3.0.10" - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/eventstream-serde-universal@^3.0.10": - version "3.0.10" - resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.10.tgz#b24e66fec9ec003eb0a1d6733fa22ded43129281" - integrity sha512-ewG1GHbbqsFZ4asaq40KmxCmXO+AFSM1b+DcO2C03dyJj/ZH71CiTg853FSE/3SHK9q3jiYQIFjlGSwfxQ9kww== +"@smithy/eventstream-serde-node@^3.0.12": + version "3.0.12" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.12.tgz#7312383e821b5807abf2fe12316c2a8967d022f0" + integrity sha512-kiZymxXvZ4tnuYsPSMUHe+MMfc4FTeFWJIc0Q5wygJoUQM4rVHNghvd48y7ppuulNMbuYt95ah71pYc2+o4JOA== dependencies: - "@smithy/eventstream-codec" "^3.1.7" - "@smithy/types" "^3.6.0" + "@smithy/eventstream-serde-universal" "^3.0.12" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/fetch-http-handler@^3.2.9": - version "3.2.9" - resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.9.tgz#8d5199c162a37caa37a8b6848eefa9ca58221a0b" - integrity sha512-hYNVQOqhFQ6vOpenifFME546f0GfJn2OiQ3M0FDmuUu8V/Uiwy2wej7ZXxFBNqdx0R5DZAqWM1l6VRhGz8oE6A== +"@smithy/eventstream-serde-universal@^3.0.12": + version "3.0.12" + resolved "https://registry.yarnpkg.com/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.12.tgz#803d7beb29a3de4a64e91af97331a4654741c35f" + integrity sha512-1i8ifhLJrOZ+pEifTlF0EfZzMLUGQggYQ6WmZ4d5g77zEKf7oZ0kvh1yKWHPjofvOwqrkwRDVuxuYC8wVd662A== dependencies: - "@smithy/protocol-http" "^4.1.4" - "@smithy/querystring-builder" "^3.0.7" - "@smithy/types" "^3.5.0" - "@smithy/util-base64" "^3.0.0" + "@smithy/eventstream-codec" "^3.1.9" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/fetch-http-handler@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-4.0.0.tgz#3763cb5178745ed630ed5bc3beb6328abdc31f36" - integrity sha512-MLb1f5tbBO2X6K4lMEKJvxeLooyg7guq48C2zKr4qM7F2Gpkz4dc+hdSgu77pCJ76jVqFBjZczHYAs6dp15N+g== +"@smithy/fetch-http-handler@^4.1.1": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.1.tgz#cead80762af4cdea11e7eeb627ea1c4835265dfa" + integrity sha512-bH7QW0+JdX0bPBadXt8GwMof/jz0H28I84hU1Uet9ISpzUqXqRQ3fEZJ+ANPOhzSEczYvANNl3uDQDYArSFDtA== dependencies: - "@smithy/protocol-http" "^4.1.5" - "@smithy/querystring-builder" "^3.0.8" - "@smithy/types" "^3.6.0" + "@smithy/protocol-http" "^4.1.7" + "@smithy/querystring-builder" "^3.0.10" + "@smithy/types" "^3.7.1" "@smithy/util-base64" "^3.0.0" tslib "^2.6.2" -"@smithy/hash-blob-browser@^3.1.6": - version "3.1.7" - resolved "https://registry.yarnpkg.com/@smithy/hash-blob-browser/-/hash-blob-browser-3.1.7.tgz#717a75129f3587e78c3cac74727448257a59dcc3" - integrity sha512-4yNlxVNJifPM5ThaA5HKnHkn7JhctFUHvcaz6YXxHlYOSIrzI6VKQPTN8Gs1iN5nqq9iFcwIR9THqchUCouIfg== +"@smithy/hash-blob-browser@^3.1.9": + version "3.1.9" + resolved "https://registry.yarnpkg.com/@smithy/hash-blob-browser/-/hash-blob-browser-3.1.9.tgz#1f2c3ef6afbb0ce3e58a0129753850bb9267aae8" + integrity sha512-wOu78omaUuW5DE+PVWXiRKWRZLecARyP3xcq5SmkXUw9+utgN8HnSnBfrjL2B/4ZxgqPjaAJQkC/+JHf1ITVaQ== dependencies: "@smithy/chunked-blob-reader" "^4.0.0" "@smithy/chunked-blob-reader-native" "^3.0.1" - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/hash-node@^3.0.7": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-3.0.8.tgz#f451cc342f74830466b0b39bf985dc3022634065" - integrity sha512-tlNQYbfpWXHimHqrvgo14DrMAgUBua/cNoz9fMYcDmYej7MAmUcjav/QKQbFc3NrcPxeJ7QClER4tWZmfwoPng== +"@smithy/hash-node@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-3.0.10.tgz#93c857b4bff3a48884886440fd9772924887e592" + integrity sha512-3zWGWCHI+FlJ5WJwx73Mw2llYR8aflVyZN5JhoqLxbdPZi6UyKSdCeXAWJw9ja22m6S6Tzz1KZ+kAaSwvydi0g== dependencies: - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" "@smithy/util-buffer-from" "^3.0.0" "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@smithy/hash-stream-node@^3.1.6": - version "3.1.7" - resolved "https://registry.yarnpkg.com/@smithy/hash-stream-node/-/hash-stream-node-3.1.7.tgz#df5c3b7aa8dbe9c389ff7857ce9145694f550b7e" - integrity sha512-xMAsvJ3hLG63lsBVi1Hl6BBSfhd8/Qnp8fC06kjOpJvyyCEXdwHITa5Kvdsk6gaAXLhbZMhQMIGvgUbfnJDP6Q== +"@smithy/hash-stream-node@^3.1.9": + version "3.1.9" + resolved "https://registry.yarnpkg.com/@smithy/hash-stream-node/-/hash-stream-node-3.1.9.tgz#97eb416811b7e7b9d036f0271588151b619759e9" + integrity sha512-3XfHBjSP3oDWxLmlxnt+F+FqXpL3WlXs+XXaB6bV9Wo8BBu87fK1dSEsyH7Z4ZHRmwZ4g9lFMdf08m9hoX1iRA== dependencies: - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@smithy/invalid-dependency@^3.0.7": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-3.0.8.tgz#4d381a4c24832371ade79e904a72c173c9851e5f" - integrity sha512-7Qynk6NWtTQhnGTTZwks++nJhQ1O54Mzi7fz4PqZOiYXb4Z1Flpb2yRvdALoggTS8xjtohWUM+RygOtB30YL3Q== +"@smithy/invalid-dependency@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-3.0.10.tgz#8616dee555916c24dec3e33b1e046c525efbfee3" + integrity sha512-Lp2L65vFi+cj0vFMu2obpPW69DU+6O5g3086lmI4XcnRCG8PxvpWC7XyaVwJCxsZFzueHjXnrOH/E0pl0zikfA== dependencies: - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" tslib "^2.6.2" "@smithy/is-array-buffer@^2.2.0": @@ -1986,179 +2105,179 @@ dependencies: tslib "^2.6.2" -"@smithy/md5-js@^3.0.7": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@smithy/md5-js/-/md5-js-3.0.8.tgz#837e54094007e87bf5196e11eca453d1c1e83a26" - integrity sha512-LwApfTK0OJ/tCyNUXqnWCKoE2b4rDSr4BJlDAVCkiWYeHESr+y+d5zlAanuLW6fnitVJRD/7d9/kN/ZM9Su4mA== +"@smithy/md5-js@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@smithy/md5-js/-/md5-js-3.0.10.tgz#52ab927cf03cd1d24fed82d8ba936faf5632436e" + integrity sha512-m3bv6dApflt3fS2Y1PyWPUtRP7iuBlvikEOGwu0HsCZ0vE7zcIX+dBoh3e+31/rddagw8nj92j0kJg2TfV+SJA== dependencies: - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@smithy/middleware-content-length@^3.0.9": - version "3.0.10" - resolved "https://registry.yarnpkg.com/@smithy/middleware-content-length/-/middleware-content-length-3.0.10.tgz#738266f6d81436d7e3a86bea931bc64e04ae7dbf" - integrity sha512-T4dIdCs1d/+/qMpwhJ1DzOhxCZjZHbHazEPJWdB4GDi2HjIZllVzeBEcdJUN0fomV8DURsgOyrbEUzg3vzTaOg== +"@smithy/middleware-content-length@^3.0.12": + version "3.0.12" + resolved "https://registry.yarnpkg.com/@smithy/middleware-content-length/-/middleware-content-length-3.0.12.tgz#3b248ed1e8f1e0ae67171abb8eae9da7ab7ca613" + integrity sha512-1mDEXqzM20yywaMDuf5o9ue8OkJ373lSPbaSjyEvkWdqELhFMyNNgKGWL/rCSf4KME8B+HlHKuR8u9kRj8HzEQ== dependencies: - "@smithy/protocol-http" "^4.1.5" - "@smithy/types" "^3.6.0" + "@smithy/protocol-http" "^4.1.7" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/middleware-endpoint@^3.1.4", "@smithy/middleware-endpoint@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.1.tgz#b9ee42d29d8f3a266883d293c4d6a586f7b60979" - integrity sha512-wWO3xYmFm6WRW8VsEJ5oU6h7aosFXfszlz3Dj176pTij6o21oZnzkCLzShfmRaaCHDkBXWBdO0c4sQAvLFP6zA== - dependencies: - "@smithy/core" "^2.5.1" - "@smithy/middleware-serde" "^3.0.8" - "@smithy/node-config-provider" "^3.1.9" - "@smithy/shared-ini-file-loader" "^3.1.9" - "@smithy/types" "^3.6.0" - "@smithy/url-parser" "^3.0.8" - "@smithy/util-middleware" "^3.0.8" +"@smithy/middleware-endpoint@^3.2.3": + version "3.2.3" + resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.3.tgz#7dd3df0052fc55891522631a7751e613b6efd68a" + integrity sha512-Hdl9296i/EMptaX7agrSzJZDiz5Y8XPUeBbctTmMtnCguGpqfU3jVsTUan0VLaOhsnquqWLL8Bl5HrlbVGT1og== + dependencies: + "@smithy/core" "^2.5.3" + "@smithy/middleware-serde" "^3.0.10" + "@smithy/node-config-provider" "^3.1.11" + "@smithy/shared-ini-file-loader" "^3.1.11" + "@smithy/types" "^3.7.1" + "@smithy/url-parser" "^3.0.10" + "@smithy/util-middleware" "^3.0.10" tslib "^2.6.2" -"@smithy/middleware-retry@^3.0.23": - version "3.0.25" - resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-3.0.25.tgz#a6b1081fc1a0991ffe1d15e567e76198af01f37c" - integrity sha512-m1F70cPaMBML4HiTgCw5I+jFNtjgz5z5UdGnUbG37vw6kh4UvizFYjqJGHvicfgKMkDL6mXwyPp5mhZg02g5sg== - dependencies: - "@smithy/node-config-provider" "^3.1.9" - "@smithy/protocol-http" "^4.1.5" - "@smithy/service-error-classification" "^3.0.8" - "@smithy/smithy-client" "^3.4.2" - "@smithy/types" "^3.6.0" - "@smithy/util-middleware" "^3.0.8" - "@smithy/util-retry" "^3.0.8" +"@smithy/middleware-retry@^3.0.27": + version "3.0.27" + resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-3.0.27.tgz#2e4dda420178835cd2d416479505d313b601ba21" + integrity sha512-H3J/PjJpLL7Tt+fxDKiOD25sMc94YetlQhCnYeNmina2LZscAdu0ZEZPas/kwePHABaEtqp7hqa5S4UJgMs1Tg== + dependencies: + "@smithy/node-config-provider" "^3.1.11" + "@smithy/protocol-http" "^4.1.7" + "@smithy/service-error-classification" "^3.0.10" + "@smithy/smithy-client" "^3.4.4" + "@smithy/types" "^3.7.1" + "@smithy/util-middleware" "^3.0.10" + "@smithy/util-retry" "^3.0.10" tslib "^2.6.2" uuid "^9.0.1" -"@smithy/middleware-serde@^3.0.7", "@smithy/middleware-serde@^3.0.8": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-3.0.8.tgz#a46d10dba3c395be0d28610d55c89ff8c07c0cd3" - integrity sha512-Xg2jK9Wc/1g/MBMP/EUn2DLspN8LNt+GMe7cgF+Ty3vl+Zvu+VeZU5nmhveU+H8pxyTsjrAkci8NqY6OuvZnjA== +"@smithy/middleware-serde@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-3.0.10.tgz#5f6c0b57b10089a21d355bd95e9b7d40378454d7" + integrity sha512-MnAuhh+dD14F428ubSJuRnmRsfOpxSzvRhaGVTvd/lrUDE3kxzCCmH8lnVTvoNQnV2BbJ4c15QwZ3UdQBtFNZA== dependencies: - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/middleware-stack@^3.0.7", "@smithy/middleware-stack@^3.0.8": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-3.0.8.tgz#f1c7d9c7fe8280c6081141c88f4a76875da1fc43" - integrity sha512-d7ZuwvYgp1+3682Nx0MD3D/HtkmZd49N3JUndYWQXfRZrYEnCWYc8BHcNmVsPAp9gKvlurdg/mubE6b/rPS9MA== +"@smithy/middleware-stack@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-3.0.10.tgz#73e2fde5d151440844161773a17ee13375502baf" + integrity sha512-grCHyoiARDBBGPyw2BeicpjgpsDFWZZxptbVKb3CRd/ZA15F/T6rZjCCuBUjJwdck1nwUuIxYtsS4H9DDpbP5w== dependencies: - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/node-config-provider@^3.1.8", "@smithy/node-config-provider@^3.1.9": - version "3.1.9" - resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-3.1.9.tgz#d27ba8e4753f1941c24ed0af824dbc6c492f510a" - integrity sha512-qRHoah49QJ71eemjuS/WhUXB+mpNtwHRWQr77J/m40ewBVVwvo52kYAmb7iuaECgGTTcYxHS4Wmewfwy++ueew== +"@smithy/node-config-provider@^3.1.11": + version "3.1.11" + resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-3.1.11.tgz#95feba85a5cb3de3fe9adfff1060b35fd556d023" + integrity sha512-URq3gT3RpDikh/8MBJUB+QGZzfS7Bm6TQTqoh4CqE8NBuyPkWa5eUXj0XFcFfeZVgg3WMh1u19iaXn8FvvXxZw== dependencies: - "@smithy/property-provider" "^3.1.8" - "@smithy/shared-ini-file-loader" "^3.1.9" - "@smithy/types" "^3.6.0" + "@smithy/property-provider" "^3.1.10" + "@smithy/shared-ini-file-loader" "^3.1.11" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/node-http-handler@^3.2.4", "@smithy/node-http-handler@^3.2.5": - version "3.2.5" - resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-3.2.5.tgz#ad9d9ba1528bf0d4a655135e978ecc14b3df26a2" - integrity sha512-PkOwPNeKdvX/jCpn0A8n9/TyoxjGZB8WVoJmm9YzsnAgggTj4CrjpRHlTQw7dlLZ320n1mY1y+nTRUDViKi/3w== +"@smithy/node-http-handler@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-3.3.1.tgz#788fc1c22c21a0cf982f4025ccf9f64217f3164f" + integrity sha512-fr+UAOMGWh6bn4YSEezBCpJn9Ukp9oR4D32sCjCo7U81evE11YePOQ58ogzyfgmjIO79YeOdfXXqr0jyhPQeMg== dependencies: - "@smithy/abort-controller" "^3.1.6" - "@smithy/protocol-http" "^4.1.5" - "@smithy/querystring-builder" "^3.0.8" - "@smithy/types" "^3.6.0" + "@smithy/abort-controller" "^3.1.8" + "@smithy/protocol-http" "^4.1.7" + "@smithy/querystring-builder" "^3.0.10" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/property-provider@^3.1.7", "@smithy/property-provider@^3.1.8": - version "3.1.8" - resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-3.1.8.tgz#b1c5a3949effbb9772785ad7ddc5b4b235b10fbe" - integrity sha512-ukNUyo6rHmusG64lmkjFeXemwYuKge1BJ8CtpVKmrxQxc6rhUX0vebcptFA9MmrGsnLhwnnqeH83VTU9hwOpjA== +"@smithy/property-provider@^3.1.10", "@smithy/property-provider@^3.1.9": + version "3.1.10" + resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-3.1.10.tgz#ae00447c1060c194c3e1b9475f7c8548a70f8486" + integrity sha512-n1MJZGTorTH2DvyTVj+3wXnd4CzjJxyXeOgnTlgNVFxaaMeT4OteEp4QrzF8p9ee2yg42nvyVK6R/awLCakjeQ== dependencies: - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/protocol-http@^4.1.4", "@smithy/protocol-http@^4.1.5": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-4.1.5.tgz#a1f397440f299b6a5abeed6866957fecb1bf5013" - integrity sha512-hsjtwpIemmCkm3ZV5fd/T0bPIugW1gJXwZ/hpuVubt2hEUApIoUTrf6qIdh9MAWlw0vjMrA1ztJLAwtNaZogvg== +"@smithy/protocol-http@^4.1.7": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-4.1.7.tgz#5c67e62beb5deacdb94f2127f9a344bdf1b2ed6e" + integrity sha512-FP2LepWD0eJeOTm0SjssPcgqAlDFzOmRXqXmGhfIM52G7Lrox/pcpQf6RP4F21k0+O12zaqQt5fCDOeBtqY6Cg== dependencies: - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/querystring-builder@^3.0.7", "@smithy/querystring-builder@^3.0.8": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@smithy/querystring-builder/-/querystring-builder-3.0.8.tgz#0d845be53aa624771c518d1412881236ce12ed4f" - integrity sha512-btYxGVqFUARbUrN6VhL9c3dnSviIwBYD9Rz1jHuN1hgh28Fpv2xjU1HeCeDJX68xctz7r4l1PBnFhGg1WBBPuA== +"@smithy/querystring-builder@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@smithy/querystring-builder/-/querystring-builder-3.0.10.tgz#db8773af85ee3977c82b8e35a5cdd178c621306d" + integrity sha512-nT9CQF3EIJtIUepXQuBFb8dxJi3WVZS3XfuDksxSCSn+/CzZowRLdhDn+2acbBv8R6eaJqPupoI/aRFIImNVPQ== dependencies: - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" "@smithy/util-uri-escape" "^3.0.0" tslib "^2.6.2" -"@smithy/querystring-parser@^3.0.8": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@smithy/querystring-parser/-/querystring-parser-3.0.8.tgz#057a8e2d301eea8eac7071923100ba38a824d7df" - integrity sha512-BtEk3FG7Ks64GAbt+JnKqwuobJNX8VmFLBsKIwWr1D60T426fGrV2L3YS5siOcUhhp6/Y6yhBw1PSPxA5p7qGg== +"@smithy/querystring-parser@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@smithy/querystring-parser/-/querystring-parser-3.0.10.tgz#62db744a1ed2cf90f4c08d2c73d365e033b4a11c" + integrity sha512-Oa0XDcpo9SmjhiDD9ua2UyM3uU01ZTuIrNdZvzwUTykW1PM8o2yJvMh1Do1rY5sUQg4NDV70dMi0JhDx4GyxuQ== dependencies: - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/service-error-classification@^3.0.8": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-3.0.8.tgz#265ad2573b972f6c7bdd1ad6c5155a88aeeea1c4" - integrity sha512-uEC/kCCFto83bz5ZzapcrgGqHOh/0r69sZ2ZuHlgoD5kYgXJEThCoTuw/y1Ub3cE7aaKdznb+jD9xRPIfIwD7g== +"@smithy/service-error-classification@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-3.0.10.tgz#941c549daf0e9abb84d3def1d9e1e3f0f74f5ba6" + integrity sha512-zHe642KCqDxXLuhs6xmHVgRwy078RfqxP2wRDpIyiF8EmsWXptMwnMwbVa50lw+WOGNrYm9zbaEg0oDe3PTtvQ== dependencies: - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" -"@smithy/shared-ini-file-loader@^3.1.8", "@smithy/shared-ini-file-loader@^3.1.9": - version "3.1.9" - resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.9.tgz#1b77852b5bb176445e1d80333fa3f739313a4928" - integrity sha512-/+OsJRNtoRbtsX0UpSgWVxFZLsJHo/4sTr+kBg/J78sr7iC+tHeOvOJrS5hCpVQ6sWBbhWLp1UNiuMyZhE6pmA== +"@smithy/shared-ini-file-loader@^3.1.10", "@smithy/shared-ini-file-loader@^3.1.11": + version "3.1.11" + resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.11.tgz#0b4f98c4a66480956fbbefc4627c5dc09d891aea" + integrity sha512-AUdrIZHFtUgmfSN4Gq9nHu3IkHMa1YDcN+s061Nfm+6pQ0mJy85YQDB0tZBCmls0Vuj22pLwDPmL92+Hvfwwlg== dependencies: - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/signature-v4@^4.2.0": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-4.2.1.tgz#a918fd7d99af9f60aa07617506fa54be408126ee" - integrity sha512-NsV1jF4EvmO5wqmaSzlnTVetemBS3FZHdyc5CExbDljcyJCEEkJr8ANu2JvtNbVg/9MvKAWV44kTrGS+Pi4INg== +"@smithy/signature-v4@^4.2.2": + version "4.2.3" + resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-4.2.3.tgz#abbca5e5fe9158422b3125b2956791a325a27f22" + integrity sha512-pPSQQ2v2vu9vc8iew7sszLd0O09I5TRc5zhY71KA+Ao0xYazIG+uLeHbTJfIWGO3BGVLiXjUr3EEeCcEQLjpWQ== dependencies: "@smithy/is-array-buffer" "^3.0.0" - "@smithy/protocol-http" "^4.1.5" - "@smithy/types" "^3.6.0" + "@smithy/protocol-http" "^4.1.7" + "@smithy/types" "^3.7.1" "@smithy/util-hex-encoding" "^3.0.0" - "@smithy/util-middleware" "^3.0.8" + "@smithy/util-middleware" "^3.0.10" "@smithy/util-uri-escape" "^3.0.0" "@smithy/util-utf8" "^3.0.0" tslib "^2.6.2" -"@smithy/smithy-client@^3.4.0", "@smithy/smithy-client@^3.4.2": - version "3.4.2" - resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-3.4.2.tgz#a6e3ed98330ce170cf482e765bd0c21e0fde8ae4" - integrity sha512-dxw1BDxJiY9/zI3cBqfVrInij6ShjpV4fmGHesGZZUiP9OSE/EVfdwdRz0PgvkEvrZHpsj2htRaHJfftE8giBA== - dependencies: - "@smithy/core" "^2.5.1" - "@smithy/middleware-endpoint" "^3.2.1" - "@smithy/middleware-stack" "^3.0.8" - "@smithy/protocol-http" "^4.1.5" - "@smithy/types" "^3.6.0" - "@smithy/util-stream" "^3.2.1" +"@smithy/smithy-client@^3.4.4": + version "3.4.4" + resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-3.4.4.tgz#460870dc97d945fa2f390890359cf09d01131e0f" + integrity sha512-dPGoJuSZqvirBq+yROapBcHHvFjChoAQT8YPWJ820aPHHiowBlB3RL1Q4kPT1hx0qKgJuf+HhyzKi5Gbof4fNA== + dependencies: + "@smithy/core" "^2.5.3" + "@smithy/middleware-endpoint" "^3.2.3" + "@smithy/middleware-stack" "^3.0.10" + "@smithy/protocol-http" "^4.1.7" + "@smithy/types" "^3.7.1" + "@smithy/util-stream" "^3.3.1" tslib "^2.6.2" -"@smithy/types@^3.5.0", "@smithy/types@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@smithy/types/-/types-3.6.0.tgz#03a52bfd62ee4b7b2a1842c8ae3ada7a0a5ff3a4" - integrity sha512-8VXK/KzOHefoC65yRgCn5vG1cysPJjHnOVt9d0ybFQSmJgQj152vMn4EkYhGuaOmnnZvCPav/KnYyE6/KsNZ2w== +"@smithy/types@^3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-3.7.1.tgz#4af54c4e28351e9101996785a33f2fdbf93debe7" + integrity sha512-XKLcLXZY7sUQgvvWyeaL/qwNPp6V3dWcUjqrQKjSb+tzYiCy340R/c64LV5j+Tnb2GhmunEX0eou+L+m2hJNYA== dependencies: tslib "^2.6.2" -"@smithy/url-parser@^3.0.7", "@smithy/url-parser@^3.0.8": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-3.0.8.tgz#8057d91d55ba8df97d74576e000f927b42da9e18" - integrity sha512-4FdOhwpTW7jtSFWm7SpfLGKIBC9ZaTKG5nBF0wK24aoQKQyDIKUw3+KFWCQ9maMzrgTJIuOvOnsV2lLGW5XjTg== +"@smithy/url-parser@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-3.0.10.tgz#f389985a79766cff4a99af14979f01a17ce318da" + integrity sha512-j90NUalTSBR2NaZTuruEgavSdh8MLirf58LoGSk4AtQfyIymogIhgnGUU2Mga2bkMkpSoC9gxb74xBXL5afKAQ== dependencies: - "@smithy/querystring-parser" "^3.0.8" - "@smithy/types" "^3.6.0" + "@smithy/querystring-parser" "^3.0.10" + "@smithy/types" "^3.7.1" tslib "^2.6.2" "@smithy/util-base64@^3.0.0": @@ -2207,37 +2326,37 @@ dependencies: tslib "^2.6.2" -"@smithy/util-defaults-mode-browser@^3.0.23": - version "3.0.25" - resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.25.tgz#ef9b84272d1db23503ff155f9075a4543ab6dab7" - integrity sha512-fRw7zymjIDt6XxIsLwfJfYUfbGoO9CmCJk6rjJ/X5cd20+d2Is7xjU5Kt/AiDt6hX8DAf5dztmfP5O82gR9emA== +"@smithy/util-defaults-mode-browser@^3.0.27": + version "3.0.27" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.27.tgz#d5df39faee8ad4bb5a6920b208469caa9dda2ccb" + integrity sha512-GV8NvPy1vAGp7u5iD/xNKUxCorE4nQzlyl057qRac+KwpH5zq8wVq6rE3lPPeuFLyQXofPN6JwxL1N9ojGapiQ== dependencies: - "@smithy/property-provider" "^3.1.8" - "@smithy/smithy-client" "^3.4.2" - "@smithy/types" "^3.6.0" + "@smithy/property-provider" "^3.1.10" + "@smithy/smithy-client" "^3.4.4" + "@smithy/types" "^3.7.1" bowser "^2.11.0" tslib "^2.6.2" -"@smithy/util-defaults-mode-node@^3.0.23": - version "3.0.25" - resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.25.tgz#c16fe3995c8e90ae318e336178392173aebe1e37" - integrity sha512-H3BSZdBDiVZGzt8TG51Pd2FvFO0PAx/A0mJ0EH8a13KJ6iUCdYnw/Dk/MdC1kTd0eUuUGisDFaxXVXo4HHFL1g== - dependencies: - "@smithy/config-resolver" "^3.0.10" - "@smithy/credential-provider-imds" "^3.2.5" - "@smithy/node-config-provider" "^3.1.9" - "@smithy/property-provider" "^3.1.8" - "@smithy/smithy-client" "^3.4.2" - "@smithy/types" "^3.6.0" +"@smithy/util-defaults-mode-node@^3.0.27": + version "3.0.27" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.27.tgz#a7248c9d9cb620827ab57ef9d1867bfe8aef42d0" + integrity sha512-7+4wjWfZqZxZVJvDutO+i1GvL6bgOajEkop4FuR6wudFlqBiqwxw3HoH6M9NgeCd37km8ga8NPp2JacQEtAMPg== + dependencies: + "@smithy/config-resolver" "^3.0.12" + "@smithy/credential-provider-imds" "^3.2.7" + "@smithy/node-config-provider" "^3.1.11" + "@smithy/property-provider" "^3.1.10" + "@smithy/smithy-client" "^3.4.4" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/util-endpoints@^2.1.3": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@smithy/util-endpoints/-/util-endpoints-2.1.4.tgz#a29134c2b1982442c5fc3be18d9b22796e8eb964" - integrity sha512-kPt8j4emm7rdMWQyL0F89o92q10gvCUa6sBkBtDJ7nV2+P7wpXczzOfoDJ49CKXe5CCqb8dc1W+ZdLlrKzSAnQ== +"@smithy/util-endpoints@^2.1.6": + version "2.1.6" + resolved "https://registry.yarnpkg.com/@smithy/util-endpoints/-/util-endpoints-2.1.6.tgz#720cbd1a616ad7c099b77780f0cb0f1f9fc5d2df" + integrity sha512-mFV1t3ndBh0yZOJgWxO9J/4cHZVn5UG1D8DeCc6/echfNkeEJWu9LD7mgGH5fHrEdR7LDoWw7PQO6QiGpHXhgA== dependencies: - "@smithy/node-config-provider" "^3.1.9" - "@smithy/types" "^3.6.0" + "@smithy/node-config-provider" "^3.1.11" + "@smithy/types" "^3.7.1" tslib "^2.6.2" "@smithy/util-hex-encoding@^3.0.0": @@ -2247,31 +2366,31 @@ dependencies: tslib "^2.6.2" -"@smithy/util-middleware@^3.0.7", "@smithy/util-middleware@^3.0.8": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@smithy/util-middleware/-/util-middleware-3.0.8.tgz#372bc7a2845408ad69da039d277fc23c2734d0c6" - integrity sha512-p7iYAPaQjoeM+AKABpYWeDdtwQNxasr4aXQEA/OmbOaug9V0odRVDy3Wx4ci8soljE/JXQo+abV0qZpW8NX0yA== +"@smithy/util-middleware@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@smithy/util-middleware/-/util-middleware-3.0.10.tgz#ab8be99f1aaafe5a5490c344f27a264b72b7592f" + integrity sha512-eJO+/+RsrG2RpmY68jZdwQtnfsxjmPxzMlQpnHKjFPwrYqvlcT+fHdT+ZVwcjlWSrByOhGr9Ff2GG17efc192A== dependencies: - "@smithy/types" "^3.6.0" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/util-retry@^3.0.7", "@smithy/util-retry@^3.0.8": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-3.0.8.tgz#9c607c175a4d8a87b5d8ebaf308f6b849e4dc4d0" - integrity sha512-TCEhLnY581YJ+g1x0hapPz13JFqzmh/pMWL2KEFASC51qCfw3+Y47MrTmea4bUE5vsdxQ4F6/KFbUeSz22Q1ow== +"@smithy/util-retry@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-3.0.10.tgz#fc13e1b30e87af0cbecadf29ca83b171e2040440" + integrity sha512-1l4qatFp4PiU6j7UsbasUHL2VU023NRB/gfaa1M0rDqVrRN4g3mCArLRyH3OuktApA4ye+yjWQHjdziunw2eWA== dependencies: - "@smithy/service-error-classification" "^3.0.8" - "@smithy/types" "^3.6.0" + "@smithy/service-error-classification" "^3.0.10" + "@smithy/types" "^3.7.1" tslib "^2.6.2" -"@smithy/util-stream@^3.1.9", "@smithy/util-stream@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-3.2.1.tgz#f3055dc4c8caba8af4e47191ea7e773d0e5a429d" - integrity sha512-R3ufuzJRxSJbE58K9AEnL/uSZyVdHzud9wLS8tIbXclxKzoe09CRohj2xV8wpx5tj7ZbiJaKYcutMm1eYgz/0A== +"@smithy/util-stream@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-3.3.1.tgz#a2636f435637ef90d64df2bb8e71cd63236be112" + integrity sha512-Ff68R5lJh2zj+AUTvbAU/4yx+6QPRzg7+pI7M1FbtQHcRIp7xvguxVsQBKyB3fwiOwhAKu0lnNyYBaQfSW6TNw== dependencies: - "@smithy/fetch-http-handler" "^4.0.0" - "@smithy/node-http-handler" "^3.2.5" - "@smithy/types" "^3.6.0" + "@smithy/fetch-http-handler" "^4.1.1" + "@smithy/node-http-handler" "^3.3.1" + "@smithy/types" "^3.7.1" "@smithy/util-base64" "^3.0.0" "@smithy/util-buffer-from" "^3.0.0" "@smithy/util-hex-encoding" "^3.0.0" @@ -2301,13 +2420,13 @@ "@smithy/util-buffer-from" "^3.0.0" tslib "^2.6.2" -"@smithy/util-waiter@^3.1.6": - version "3.1.7" - resolved "https://registry.yarnpkg.com/@smithy/util-waiter/-/util-waiter-3.1.7.tgz#e94f7b9fb8e3b627d78f8886918c76030cf41815" - integrity sha512-d5yGlQtmN/z5eoTtIYgkvOw27US2Ous4VycnXatyoImIF9tzlcpnKqQ/V7qhvJmb2p6xZne1NopCLakdTnkBBQ== +"@smithy/util-waiter@^3.1.9": + version "3.1.9" + resolved "https://registry.yarnpkg.com/@smithy/util-waiter/-/util-waiter-3.1.9.tgz#1330ce2e79b58419d67755d25bce7a226e32dc6d" + integrity sha512-/aMXPANhMOlMPjfPtSrDfPeVP8l56SJlz93xeiLmhLe5xvlXA5T3abZ2ilEsDEPeY9T/wnN/vNGn9wa1SbufWA== dependencies: - "@smithy/abort-controller" "^3.1.6" - "@smithy/types" "^3.6.0" + "@smithy/abort-controller" "^3.1.8" + "@smithy/types" "^3.7.1" tslib "^2.6.2" "@szmarczak/http-timer@^5.0.1": @@ -2478,9 +2597,9 @@ "@types/node" "*" "@types/node@*", "@types/node@^22.5.5": - version "22.8.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.8.0.tgz#193c6f82f9356ce0e6bba86b59f2ffe06e7e320b" - integrity sha512-84rafSBHC/z1i1E3p0cJwKA+CfYDNSXX9WSZBRopjIzLET8oNt6ht2tei4C7izwDeEiLLfdeSVBv1egOH916hg== + version "22.9.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.9.1.tgz#bdf91c36e0e7ecfb7257b2d75bf1b206b308ca71" + integrity sha512-p8Yy/8sw1caA8CdRIQBG5tiLHmxtQKObCijiAa9Ez+d4+PRffM4054xbju0msf+cvhJpnFEeNjxmVT/0ipktrg== dependencies: undici-types "~6.19.8" @@ -2490,9 +2609,9 @@ integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== "@types/node@^20.0.0": - version "20.17.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.1.tgz#2b968e060dfb04b7f9550fe3db5f552721c14566" - integrity sha512-j2VlPv1NnwPJbaCNv69FO/1z4lId0QmGvpT41YxitRtWlg96g/j8qcv2RKsLKe2F6OJgyXhupN1Xo17b2m139Q== + version "20.17.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.6.tgz#6e4073230c180d3579e8c60141f99efdf5df0081" + integrity sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ== dependencies: undici-types "~6.19.2" @@ -2582,13 +2701,13 @@ "@typescript-eslint/types" "7.18.0" "@typescript-eslint/visitor-keys" "7.18.0" -"@typescript-eslint/scope-manager@8.11.0": - version "8.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.11.0.tgz#9d399ce624118966732824878bc9a83593a30405" - integrity sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ== +"@typescript-eslint/scope-manager@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.15.0.tgz#28a1a0f13038f382424f45a988961acaca38f7c6" + integrity sha512-QRGy8ADi4J7ii95xz4UoiymmmMd/zuy9azCaamnZ3FM8T5fZcex8UfJcjkiEZjJSztKfEBe3dZ5T/5RHAmw2mA== dependencies: - "@typescript-eslint/types" "8.11.0" - "@typescript-eslint/visitor-keys" "8.11.0" + "@typescript-eslint/types" "8.15.0" + "@typescript-eslint/visitor-keys" "8.15.0" "@typescript-eslint/type-utils@7.18.0": version "7.18.0" @@ -2605,10 +2724,10 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.18.0.tgz#b90a57ccdea71797ffffa0321e744f379ec838c9" integrity sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ== -"@typescript-eslint/types@8.11.0": - version "8.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.11.0.tgz#7c766250502097f49bbc2e651132e6bf489e20b8" - integrity sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw== +"@typescript-eslint/types@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.15.0.tgz#4958edf3d83e97f77005f794452e595aaf6430fc" + integrity sha512-n3Gt8Y/KyJNe0S3yDCD2RVKrHBC4gTUcLTebVBXacPy091E6tNspFLKRXlk3hwT4G55nfr1n2AdFqi/XMxzmPQ== "@typescript-eslint/typescript-estree@7.18.0": version "7.18.0" @@ -2624,13 +2743,13 @@ semver "^7.6.0" ts-api-utils "^1.3.0" -"@typescript-eslint/typescript-estree@8.11.0": - version "8.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.11.0.tgz#35fe5d3636fc5727c52429393415412e552e222b" - integrity sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg== +"@typescript-eslint/typescript-estree@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.15.0.tgz#915c94e387892b114a2a2cc0df2d7f19412c8ba7" + integrity sha512-1eMp2JgNec/niZsR7ioFBlsh/Fk0oJbhaqO0jRyQBMgkz7RrFfkqF9lYYmBoGBaSiLnu8TAPQTwoTUiSTUW9dg== dependencies: - "@typescript-eslint/types" "8.11.0" - "@typescript-eslint/visitor-keys" "8.11.0" + "@typescript-eslint/types" "8.15.0" + "@typescript-eslint/visitor-keys" "8.15.0" debug "^4.3.4" fast-glob "^3.3.2" is-glob "^4.0.3" @@ -2649,14 +2768,14 @@ "@typescript-eslint/typescript-estree" "7.18.0" "@typescript-eslint/utils@^6.0.0 || ^7.0.0 || ^8.0.0": - version "8.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.11.0.tgz#4480d1e9f2bb18ea3510c79f870a1aefc118103d" - integrity sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g== + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.15.0.tgz#ac04679ad19252776b38b81954b8e5a65567cef6" + integrity sha512-k82RI9yGhr0QM3Dnq+egEpz9qB6Un+WLYhmoNcvl8ltMEededhh7otBVVIDDsEEttauwdY/hQoSsOv13lxrFzQ== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@typescript-eslint/scope-manager" "8.11.0" - "@typescript-eslint/types" "8.11.0" - "@typescript-eslint/typescript-estree" "8.11.0" + "@typescript-eslint/scope-manager" "8.15.0" + "@typescript-eslint/types" "8.15.0" + "@typescript-eslint/typescript-estree" "8.15.0" "@typescript-eslint/visitor-keys@7.18.0": version "7.18.0" @@ -2666,13 +2785,13 @@ "@typescript-eslint/types" "7.18.0" eslint-visitor-keys "^3.4.3" -"@typescript-eslint/visitor-keys@8.11.0": - version "8.11.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.11.0.tgz#273de1cbffe63d9f9cd7dfc20b5a5af66310cb92" - integrity sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw== +"@typescript-eslint/visitor-keys@8.15.0": + version "8.15.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.15.0.tgz#9ea5a85eb25401d2aa74ec8a478af4e97899ea12" + integrity sha512-h8vYOulWec9LhpwfAdZf2bjr8xIp0KNKnpgqSz0qqYYKAW/QZKw3ktRndbiAtUz4acH4QLQavwZBYCc0wulA/Q== dependencies: - "@typescript-eslint/types" "8.11.0" - eslint-visitor-keys "^3.4.3" + "@typescript-eslint/types" "8.15.0" + eslint-visitor-keys "^4.2.0" "@ungap/structured-clone@^1.2.0": version "1.2.0" @@ -2699,9 +2818,9 @@ acorn-walk@^8.1.1: acorn "^8.11.0" acorn@^8.11.0, acorn@^8.4.1, acorn@^8.9.0: - version "8.13.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.13.0.tgz#2a30d670818ad16ddd6a35d3842dacec9e5d7ca3" - integrity sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w== + version "8.14.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" + integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== agent-base@6: version "6.0.2" @@ -3147,9 +3266,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001669: - version "1.0.30001669" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz#fda8f1d29a8bfdc42de0c170d7f34a9cf19ed7a3" - integrity sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w== + version "1.0.30001680" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz#5380ede637a33b9f9f1fc6045ea99bd142f3da5e" + integrity sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA== capital-case@^1.0.4: version "1.0.4" @@ -3357,14 +3476,14 @@ convert-source-map@^2.0.0: integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== core-js-pure@^3.30.2: - version "3.38.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.38.1.tgz#e8534062a54b7221344884ba9b52474be495ada3" - integrity sha512-BY8Etc1FZqdw1glX0XNOq2FDwfrg/VGqoZOZCdaL+UmdaqDwQwYXkMJT4t6In+zfEfOJDcM9T0KdbBeJg8KKCQ== + version "3.39.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.39.0.tgz#aa0d54d70a15bdc13e7c853db87c10abc30d68f3" + integrity sha512-7fEcWwKI4rJinnK+wLTezeg2smbFFdSBP6E2kQZNbnzM2s1rpKQ6aaRteZSSg7FLU3P0HGGVo/gbpfanU36urg== core-js@^3.6.4: - version "3.38.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.38.1.tgz#aa375b79a286a670388a1a363363d53677c0383e" - integrity sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw== + version "3.39.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.39.0.tgz#57f7647f4d2d030c32a72ea23a0555b2eaa30f83" + integrity sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g== core-util-is@~1.0.0: version "1.0.3" @@ -3390,9 +3509,9 @@ create-require@^1.1.0: integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" @@ -3616,9 +3735,9 @@ ejs@^3.1.10, ejs@^3.1.8: jake "^10.8.5" electron-to-chromium@^1.5.41: - version "1.5.46" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.46.tgz#69c98f809a3ea669386263d672f4d920be71da3a" - integrity sha512-1XDk0Z8/YRgB2t5GeEg8DPK592DLjVmd/5uwAu6c/S4Z0CUwV/RwYqe5GWxQqcoN3bJ5U7hYMiMRPZzpCzSBhQ== + version "1.5.63" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.63.tgz#69444d592fbbe628d129866c2355691ea93eda3e" + integrity sha512-ddeXKuY9BHo/mw145axlyWjlJ1UBt4WK3AlvkT7W2AbqfRQoacVoRUCF6wL3uIx/8wT9oLKXzI+rFqHHscByaA== emittery@^0.13.1: version "0.13.1" @@ -3645,9 +3764,9 @@ error-ex@^1.3.1: is-arrayish "^0.2.1" es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.2: - version "1.23.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0" - integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A== + version "1.23.5" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.5.tgz#f4599a4946d57ed467515ed10e4f157289cd52fb" + integrity sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ== dependencies: array-buffer-byte-length "^1.0.1" arraybuffer.prototype.slice "^1.0.3" @@ -3664,7 +3783,7 @@ es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23 function.prototype.name "^1.1.6" get-intrinsic "^1.2.4" get-symbol-description "^1.0.2" - globalthis "^1.0.3" + globalthis "^1.0.4" gopd "^1.0.1" has-property-descriptors "^1.0.2" has-proto "^1.0.3" @@ -3680,10 +3799,10 @@ es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23 is-string "^1.0.7" is-typed-array "^1.1.13" is-weakref "^1.0.2" - object-inspect "^1.13.1" + object-inspect "^1.13.3" object-keys "^1.1.1" object.assign "^4.1.5" - regexp.prototype.flags "^1.5.2" + regexp.prototype.flags "^1.5.3" safe-array-concat "^1.1.2" safe-regex-test "^1.0.3" string.prototype.trim "^1.2.9" @@ -3813,18 +3932,18 @@ eslint-plugin-import@^2.29.1: tsconfig-paths "^3.15.0" eslint-plugin-jest@^28.6.0: - version "28.8.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-28.8.3.tgz#c5699bba0ad06090ad613535e4f1572f4c2567c0" - integrity sha512-HIQ3t9hASLKm2IhIOqnu+ifw7uLZkIlR7RYNv7fMcEi/p0CIiJmfriStQS2LDkgtY4nyLbIZAD+JL347Yc2ETQ== + version "28.9.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-28.9.0.tgz#19168dfaed124339cd2252c4c4d1ac3688aeb243" + integrity sha512-rLu1s1Wf96TgUUxSw6loVIkNtUjq1Re7A9QdCCHSohnvXEBAjuL420h0T/fMmkQlNsQP2GhQzEUpYHPfxBkvYQ== dependencies: "@typescript-eslint/utils" "^6.0.0 || ^7.0.0 || ^8.0.0" eslint-plugin-sf-plugin@^1.17.4: - version "1.20.9" - resolved "https://registry.yarnpkg.com/eslint-plugin-sf-plugin/-/eslint-plugin-sf-plugin-1.20.9.tgz#87d17902f696ac242a1b7c6ccbb43f271d883e7e" - integrity sha512-9lqHOVTO2y9MpdaXiHGHPWP3hf8pcn3SWy6osLxK2J+jm4r2cJsx9mK0WdS4Grlfoou7Xm5P71fwgf+htrtdow== + version "1.20.13" + resolved "https://registry.yarnpkg.com/eslint-plugin-sf-plugin/-/eslint-plugin-sf-plugin-1.20.13.tgz#cebe116f1c8c44595ae67e0e1c9dc61f86f69652" + integrity sha512-jGiQn55k7TDPgpz9Wr2heNbyjGkFvpy+rgBMj7zDWSSJPLLePsLYF2CI4twF9lufQDzLxnO+BNUr+ZkChy+/TQ== dependencies: - "@salesforce/core" "^8.6.2" + "@salesforce/core" "^8.8.0" "@typescript-eslint/utils" "^7.18.0" eslint-restricted-globals@~0.2.0: @@ -3853,11 +3972,16 @@ eslint-visitor-keys@^2.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: +eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== +eslint-visitor-keys@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" + integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== + eslint@^8.57, eslint@^8.57.0: version "8.57.1" resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" @@ -3986,7 +4110,7 @@ expect@^29.0.0, expect@^29.7.0: jest-message-util "^29.7.0" jest-util "^29.7.0" -external-editor@^3.0.3: +external-editor@^3.0.3, external-editor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== @@ -4005,7 +4129,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.2: +fast-glob@^3.2.9, fast-glob@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== @@ -4093,6 +4217,11 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +fdir@^6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.2.tgz#ddaa7ce1831b161bc3657bb99cb36e1622702689" + integrity sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ== + figures@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" @@ -4154,9 +4283,9 @@ flat-cache@^3.0.4: rimraf "^3.0.2" flatted@^3.2.9: - version "3.3.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" - integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== + version "3.3.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.2.tgz#adba1448a9841bec72b42c532ea23dbbedef1a27" + integrity sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA== for-each@^0.3.3: version "0.3.3" @@ -4330,7 +4459,7 @@ globals@^13.19.0, globals@^13.24.0: dependencies: type-fest "^0.20.2" -globalthis@^1.0.3: +globalthis@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== @@ -4350,17 +4479,6 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -globby@^13.1.2: - version "13.2.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-13.2.2.tgz#63b90b1bf68619c2135475cbd4e71e66aa090592" - integrity sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w== - dependencies: - dir-glob "^3.0.1" - fast-glob "^3.3.0" - ignore "^5.2.4" - merge2 "^1.4.1" - slash "^4.0.0" - gopd@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" @@ -4542,7 +4660,7 @@ ieee754@^1.1.13, ieee754@^1.2.1: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -ignore@^5.2.0, ignore@^5.2.4, ignore@^5.3.1: +ignore@^5.2.0, ignore@^5.3.1: version "5.3.2" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== @@ -4722,11 +4840,6 @@ is-docker@^2.0.0: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== -is-docker@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" - integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -4749,13 +4862,6 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: dependencies: is-extglob "^2.1.1" -is-inside-container@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" - integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== - dependencies: - is-docker "^3.0.0" - is-interactive@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" @@ -4853,13 +4959,6 @@ is-wsl@^2.1.1, is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" -is-wsl@^3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-3.1.0.tgz#e1c657e39c10090afcbedec61720f6b924c3cbd2" - integrity sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw== - dependencies: - is-inside-container "^1.0.0" - isarray@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" @@ -5756,6 +5855,11 @@ mute-stream@^1.0.0: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== +mute-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-2.0.0.tgz#a5446fc0c512b71c83c44d908d5c7b7b4c493b2b" + integrity sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -5838,10 +5942,10 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -object-inspect@^1.13.1: - version "1.13.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" - integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== +object-inspect@^1.13.1, object-inspect@^1.13.3: + version "1.13.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.3.tgz#f14c183de51130243d6d18ae149375ff50ea488a" + integrity sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA== object-keys@^1.1.1: version "1.1.1" @@ -5892,19 +5996,19 @@ object.values@^1.2.0: es-object-atoms "^1.0.0" oclif@^4.0.3: - version "4.15.12" - resolved "https://registry.yarnpkg.com/oclif/-/oclif-4.15.12.tgz#3af53ffba0989741da32118585c2c4e0629147d1" - integrity sha512-L1D7dM6nEA+6QZSm+h7qfN7jLF19eOopCE8bs5V4Hmj002c2i4vw41rSL95yaUaLYM6kDlCEsJhgs+gC2wVsiA== + version "4.15.28" + resolved "https://registry.yarnpkg.com/oclif/-/oclif-4.15.28.tgz#d05613be10494baf727b7eb212ab661435696ed2" + integrity sha512-iyc3ISmnyX20Y8fY6E3U0SCZLIaPiaiI++yIxHXnm5903PAndjVrCK/kkseXZOQ9yRer9e0iLTpBoMMwdBQrnA== dependencies: - "@aws-sdk/client-cloudfront" "^3.675.0" - "@aws-sdk/client-s3" "^3.676.0" + "@aws-sdk/client-cloudfront" "^3.687.0" + "@aws-sdk/client-s3" "^3.693.0" "@inquirer/confirm" "^3.1.22" "@inquirer/input" "^2.2.4" "@inquirer/select" "^2.5.0" - "@oclif/core" "^4.0.29" - "@oclif/plugin-help" "^6.2.14" - "@oclif/plugin-not-found" "^3.2.21" - "@oclif/plugin-warn-if-update-available" "^3.1.11" + "@oclif/core" "^4.0.32" + "@oclif/plugin-help" "^6.2.17" + "@oclif/plugin-not-found" "^3.2.25" + "@oclif/plugin-warn-if-update-available" "^3.1.21" async-retry "^1.3.3" chalk "^4" change-case "^4" @@ -6142,6 +6246,11 @@ picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +picomatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab" + integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== + pino-abstract-transport@^1.0.0, pino-abstract-transport@^1.1.0, pino-abstract-transport@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz#97f9f2631931e242da531b5c66d3079c12c9d1b5" @@ -6433,7 +6542,7 @@ regenerator-runtime@^0.14.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== -regexp.prototype.flags@^1.5.2: +regexp.prototype.flags@^1.5.3: version "1.5.3" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz#b3ae40b1d2499b8350ab2c3fe6ef3845d3a96f42" integrity sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ== @@ -6512,9 +6621,9 @@ restore-cursor@^3.1.0: signal-exit "^3.0.2" retire@^5.0.1: - version "5.2.4" - resolved "https://registry.yarnpkg.com/retire/-/retire-5.2.4.tgz#8d6dd5ff9eec21ff853493c974be3e69f341898f" - integrity sha512-iutStQwG3svZQBvy79ZEG/7463GbVg8IKG/05SUPUdocQoCKl7e2mnvA/X3XlJqMQj0yV4mcKbZeeM1mAU374A== + version "5.2.5" + resolved "https://registry.yarnpkg.com/retire/-/retire-5.2.5.tgz#7a7b3126aff4068368053a51b7c05d116130520f" + integrity sha512-tPVphjnkTotC35HdiaqaZIyV81ASbebsug0anoWVxfQDHfV0bocXMezJiaR95P+b2nqfwxmhbKdg1WK9XKFlMA== dependencies: ansi-colors "^4.1.1" astronomical "^1.0.0" @@ -6742,11 +6851,6 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slash@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" - integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== - slice-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" @@ -6806,18 +6910,18 @@ sort-object-keys@^1.1.3: integrity sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg== sort-package-json@^2.10.1: - version "2.10.1" - resolved "https://registry.yarnpkg.com/sort-package-json/-/sort-package-json-2.10.1.tgz#18e7fa0172233cb2d4d926f7c99e6bfcf4d1d25c" - integrity sha512-d76wfhgUuGypKqY72Unm5LFnMpACbdxXsLPcL27pOsSrmVqH3PztFp1uq+Z22suk15h7vXmTesuh2aEjdCqb5w== + version "2.11.0" + resolved "https://registry.yarnpkg.com/sort-package-json/-/sort-package-json-2.11.0.tgz#51d02a1dd739ce42f4274612d1a2e32a8742c1d4" + integrity sha512-pBs3n/wcsbnMSiO5EYV4AVnZVtyQslfZ/0v6VbrRRVApqyNf0Uqo4MOXJsBmIplGY1hYZ4bq5qjO9xTgY+K8xw== dependencies: detect-indent "^7.0.1" detect-newline "^4.0.0" get-stdin "^9.0.0" git-hooks-list "^3.0.0" - globby "^13.1.2" is-plain-obj "^4.1.0" semver "^7.6.0" sort-object-keys "^1.1.3" + tinyglobby "^0.2.9" source-map-support@0.5.13: version "0.5.13" @@ -7036,17 +7140,25 @@ tiny-jsonc@^1.0.1: resolved "https://registry.yarnpkg.com/tiny-jsonc/-/tiny-jsonc-1.0.1.tgz#71de47c9d812b411e87a9f3ab4a5fe42cd8d8f9c" integrity sha512-ik6BCxzva9DoiEfDX/li0L2cWKPPENYvixUprFdl3YPi4bZZUhDnNI9YUkacrv+uIG90dnxR5mNqaoD6UhD6Bw== -tldts-core@^6.1.55: - version "6.1.55" - resolved "https://registry.yarnpkg.com/tldts-core/-/tldts-core-6.1.55.tgz#cab0d412672fca9c77d3c51312c69bb5b5ee95c2" - integrity sha512-BL+BuKHHaOpntE5BGI6naXjULU6aRlgaYdfDHR3T/hdbNTWkWUZ9yuc11wGnwgpvRwlyUiIK+QohYK3olaVU6Q== +tinyglobby@^0.2.9: + version "0.2.10" + resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.10.tgz#e712cf2dc9b95a1f5c5bbd159720e15833977a0f" + integrity sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew== + dependencies: + fdir "^6.4.2" + picomatch "^4.0.2" + +tldts-core@^6.1.61: + version "6.1.61" + resolved "https://registry.yarnpkg.com/tldts-core/-/tldts-core-6.1.61.tgz#5cd6507535ef5f5027ac9a1f52b9b60ecb9edfbd" + integrity sha512-In7VffkDWUPgwa+c9picLUxvb0RltVwTkSgMNFgvlGSWveCzGBemBqTsgJCL4EDFWZ6WH0fKTsot6yNhzy3ZzQ== tldts@^6.1.32: - version "6.1.55" - resolved "https://registry.yarnpkg.com/tldts/-/tldts-6.1.55.tgz#9a27d1708652bbae93d4b842dc2f8554fdabffc6" - integrity sha512-HxQR/9roQ07Pwc8RyyrJMAxRz5/ssoF3qIPPUiIo3zUt6yMdmYZjM2OZIFMiZ3jHyz9jrGHEHuQZrUhoc1LkDw== + version "6.1.61" + resolved "https://registry.yarnpkg.com/tldts/-/tldts-6.1.61.tgz#85df9810aa4c24bff281bf1fd0b838e087beef9c" + integrity sha512-rv8LUyez4Ygkopqn+M6OLItAOT9FF3REpPQDkdMx5ix8w4qkuE7Vo2o/vw1nxKQYmJDV8JpAMJQr1b+lTKf0FA== dependencies: - tldts-core "^6.1.55" + tldts-core "^6.1.61" tmp@^0.0.33: version "0.0.33" @@ -7085,9 +7197,9 @@ tr46@~0.0.3: integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== ts-api-utils@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" - integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== + version "1.4.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.0.tgz#709c6f2076e511a81557f3d07a0cbd566ae8195c" + integrity sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ== ts-jest@^29.1.4: version "29.2.5" @@ -7149,9 +7261,9 @@ tslib@^1.9.0: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.5.0, tslib@^2.6.2: - version "2.8.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.0.tgz#d124c86c3c05a40a91e6fdea4021bd31d377971b" - integrity sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA== + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== tunnel-agent@*, tunnel-agent@^0.6.0: version "0.6.0" From d4e8d9a1070201ef38799bfa1abf8d1429a3a8e3 Mon Sep 17 00:00:00 2001 From: Stephen Carter Date: Wed, 20 Nov 2024 14:16:02 -0500 Subject: [PATCH 13/35] Add in .npmrc file so that registry stays fixed --- .npmrc | 1 + 1 file changed, 1 insertion(+) create mode 100644 .npmrc diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..d263b35ba --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +registry=https://registry.yarnpkg.com \ No newline at end of file From 065608ae8d6d89cc0141674e53965987522091b3 Mon Sep 17 00:00:00 2001 From: Stephen Carter Date: Wed, 20 Nov 2024 16:19:32 -0500 Subject: [PATCH 14/35] CHANGE: @W-17272495@: Polish detail view output --- src/lib/viewers/ResultsViewer.ts | 66 ++++++++++--------- .../four-identical-violations-details.txt | 24 ++++--- .../four-unique-violations-details.txt | 40 +++++------ .../one-multilocation-violation-details.txt | 8 +-- test/lib/viewers/ResultsViewer.test.ts | 13 ++-- 5 files changed, 84 insertions(+), 67 deletions(-) diff --git a/src/lib/viewers/ResultsViewer.ts b/src/lib/viewers/ResultsViewer.ts index d4ed113a5..daa81f739 100644 --- a/src/lib/viewers/ResultsViewer.ts +++ b/src/lib/viewers/ResultsViewer.ts @@ -62,41 +62,47 @@ export class ResultsDetailDisplayer extends AbstractResultsDisplayer { 'summary.detail.violation-header', [idx + 1, rule.getName()] ); - if (violation.getCodeLocations().length > 1) { - const body = { - severity: `${sev.valueOf()} (${SeverityLevel[sev]})`, - engine: rule.getEngineName(), - message: violation.getMessage(), - locations: stringifyLocations(violation.getCodeLocations(), violation.getPrimaryLocationIndex()), - resources: violation.getResourceUrls().join(',') - }; - const keys = ['severity', 'engine', 'message', 'locations', 'resources']; - return toStyledHeaderAndBody(header, body, keys); - } else { - const body = { - severity: `${sev.valueOf()} (${SeverityLevel[sev]})`, - engine: rule.getEngineName(), - message: violation.getMessage(), - location: stringifyLocations(violation.getCodeLocations())[0], - resources: violation.getResourceUrls().join(',') - }; - const keys = ['severity', 'engine', 'message', 'location', 'resources']; - return toStyledHeaderAndBody(header, body, keys); + const body = { + severity: `${sev.valueOf()} (${SeverityLevel[sev]})`, + engine: rule.getEngineName(), + message: violation.getMessage() + } + const keys: string[] = ['severity', 'engine', 'message']; + if (violation.getCodeLocations().length == 1) { + body['location'] = stringifyLocation(violation.getCodeLocations()[0], false); + keys.push('location'); + } else if (violation.getCodeLocations().length > 1) { + body['locations'] = stringifyLocations(violation.getCodeLocations(), violation.getPrimaryLocationIndex()); + keys.push('locations'); } + if (violation.getResourceUrls().length == 1) { + body['resource'] = violation.getResourceUrls()[0]; + keys.push('resource'); + } else if (violation.getResourceUrls().length > 1) { + body['resources'] = violation.getResourceUrls(); + keys.push('resources'); + } + return toStyledHeaderAndBody(header, body, keys); } } -function stringifyLocations(codeLocations: CodeLocation[], primaryIndex?: number): string[] { - const locationStrings: string[] = []; - - codeLocations.forEach((loc, idx) => { - const commentPortion: string = loc.getComment() ? ` ${loc.getComment()}` : ''; - const locationString: string = `${loc.getFile()}:${loc.getStartLine()}:${loc.getStartColumn()}${commentPortion}`; - const mainPortion: string = primaryIndex != null && primaryIndex === idx ? '(main) ' : ''; - locationStrings.push(`${mainPortion}${locationString}`); - }); +function stringifyLocations(codeLocations: CodeLocation[], primaryIndex: number): string[] { + return codeLocations.map((loc, idx) => + stringifyLocation(loc, codeLocations.length > 1 && primaryIndex === idx)); +} - return locationStrings; +function stringifyLocation(loc: CodeLocation, displayMain: boolean): string { + const mainPortion: string = displayMain ? '(main) ' : ''; + const commentPortion: string = loc.getComment() ? ` "${loc.getComment()}"` : ''; + let rangePortion: string = ''; + if (loc.getStartLine()) { + rangePortion += ` (${loc.getStartLine()}:${loc.getStartColumn() || 1}`; + if (loc.getEndLine()) { + rangePortion += `-${loc.getEndLine()}:${loc.getEndColumn() || 1}`; + } + rangePortion += ')'; + } + return `${mainPortion}${loc.getFile()}${rangePortion}${commentPortion}`; } type ResultRow = { diff --git a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-identical-violations-details.txt b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-identical-violations-details.txt index adb9b67b1..d35c56933 100644 --- a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-identical-violations-details.txt +++ b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-identical-violations-details.txt @@ -3,26 +3,34 @@ severity: 4 (Low) engine: stubEngine1 message: This is a message - location: __PATH_TO_SOME_FILE__:1:1 - resources: https://example.com/stub1RuleA + location: __PATH_TO_SOME_FILE__ (1:1) + resources: + https://example.com/stub1RuleA + https://violation_specific.url === 2. stub1RuleA severity: 4 (Low) engine: stubEngine1 message: This is a message - location: __PATH_TO_SOME_FILE__:1:1 - resources: https://example.com/stub1RuleA + location: __PATH_TO_SOME_FILE__ (1:1) + resources: + https://example.com/stub1RuleA + https://violation_specific.url === 3. stub1RuleA severity: 4 (Low) engine: stubEngine1 message: This is a message - location: __PATH_TO_SOME_FILE__:1:1 - resources: https://example.com/stub1RuleA + location: __PATH_TO_SOME_FILE__ (1:1) + resources: + https://example.com/stub1RuleA + https://violation_specific.url === 4. stub1RuleA severity: 4 (Low) engine: stubEngine1 message: This is a message - location: __PATH_TO_SOME_FILE__:1:1 - resources: https://example.com/stub1RuleA + location: __PATH_TO_SOME_FILE__ (1:1) + resources: + https://example.com/stub1RuleA + https://violation_specific.url diff --git a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-unique-violations-details.txt b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-unique-violations-details.txt index 63f537b94..c0ff38a99 100644 --- a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-unique-violations-details.txt +++ b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-unique-violations-details.txt @@ -1,28 +1,28 @@ === 1. stub1RuleB - severity: 2 (High) - engine: stubEngine1 - message: This is a message - location: __PATH_TO_FILE_Z__:20:1 - resources: https://example.com/stub1RuleB + severity: 2 (High) + engine: stubEngine1 + message: This is a message + location: __PATH_TO_FILE_Z__ (20:1) + resource: https://example.com/stub1RuleB === 2. stub1RuleA - severity: 4 (Low) - engine: stubEngine1 - message: This is a message - location: __PATH_TO_FILE_A__:1:1 - resources: https://example.com/stub1RuleA + severity: 4 (Low) + engine: stubEngine1 + message: This is a message + location: __PATH_TO_FILE_A__ (1:1) + resource: https://example.com/stub1RuleA === 3. stub1RuleA - severity: 4 (Low) - engine: stubEngine1 - message: This is a message - location: __PATH_TO_FILE_A__:20:1 - resources: https://example.com/stub1RuleA + severity: 4 (Low) + engine: stubEngine1 + message: This is a message + location: __PATH_TO_FILE_A__ (20:1) + resource: https://example.com/stub1RuleA === 4. stub1RuleA - severity: 4 (Low) - engine: stubEngine1 - message: This is a message - location: __PATH_TO_FILE_Z__:1:1 - resources: https://example.com/stub1RuleA + severity: 4 (Low) + engine: stubEngine1 + message: This is a message + location: __PATH_TO_FILE_Z__ (1:1) + resource: https://example.com/stub1RuleA diff --git a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/one-multilocation-violation-details.txt b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/one-multilocation-violation-details.txt index d7fe30fca..2f67e5936 100644 --- a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/one-multilocation-violation-details.txt +++ b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/one-multilocation-violation-details.txt @@ -4,7 +4,7 @@ engine: stubEngine1 message: This is a message locations: - __PATH_TO_FILE_A__:20:1 - (main) __PATH_TO_FILE_Z__:2:1 This is a comment at Location 2 - __PATH_TO_FILE_A__:1:1 This is a comment at Location 3 - resources: https://example.com/stub1RuleA + __PATH_TO_FILE_A__ (20:1) + (main) __PATH_TO_FILE_Z__ (2:1) "This is a comment at Location 2" + __PATH_TO_FILE_A__ (1:1-3:1) "This is a comment at Location 3" + resource: https://example.com/stub1RuleA diff --git a/test/lib/viewers/ResultsViewer.test.ts b/test/lib/viewers/ResultsViewer.test.ts index 6e642ce87..876ab59ee 100644 --- a/test/lib/viewers/ResultsViewer.test.ts +++ b/test/lib/viewers/ResultsViewer.test.ts @@ -69,7 +69,7 @@ describe('ResultsViewer implementations', () => { // ==== TEST SETUP ==== // This test doesn't care about sorting, so just assign our engine several copies of the same violation. const violations: Violation[] = repeatViolation( - createViolation(rule1.name, PATH_TO_SOME_FILE, 1, 1), + createViolation(rule1.name, PATH_TO_SOME_FILE, 1, 1, ['https://violation_specific.url']), 4); engine1.resultsToReturn = {violations}; const workspace = await codeAnalyzerCore.createWorkspace([PATH_TO_SOME_FILE]); @@ -146,11 +146,13 @@ describe('ResultsViewer implementations', () => { file: PATH_TO_FILE_Z, startLine: 2, startColumn: 1, - comment: 'This is a comment at Location 2' + endColumn: 7, + comment: 'This is a comment at Location 2', }, { file: PATH_TO_FILE_A, startLine: 1, startColumn: 1, + endLine: 3, comment: 'This is a comment at Location 3' }); // Declare the second location to be the primary. @@ -177,7 +179,7 @@ describe('ResultsViewer implementations', () => { const expectedViolationDetails = (await readComparisonFile('one-multilocation-violation-details.txt')) .replace(/__PATH_TO_FILE_A__/g, PATH_TO_FILE_A) .replace(/__PATH_TO_FILE_Z__/g, PATH_TO_FILE_Z); - expect(actualEventText).toContain(expectedViolationDetails); + expect(actualEventText).toEqual(expectedViolationDetails); }) }); @@ -301,7 +303,7 @@ describe('Tests for the findLongestCommonParentFolderOf helper function', () => } }); -function createViolation(ruleName: string, file: string, startLine: number, startColumn: number): Violation { +function createViolation(ruleName: string, file: string, startLine: number, startColumn: number, resourceUrls: string[] = []): Violation { return { ruleName, message: 'This is a message', @@ -310,7 +312,8 @@ function createViolation(ruleName: string, file: string, startLine: number, star startLine, startColumn }], - primaryLocationIndex: 0 + primaryLocationIndex: 0, + resourceUrls: resourceUrls }; } From c294715a6de54e43de5f794c1ef196c9a590a8a5 Mon Sep 17 00:00:00 2001 From: Stephen Carter Date: Wed, 20 Nov 2024 17:00:34 -0500 Subject: [PATCH 15/35] Make detail view have relative paths to runDir --- messages/results-viewer.md | 2 +- src/lib/viewers/ResultsViewer.ts | 32 +++++++++++-------- .../four-identical-violations-details.txt | 10 +++--- .../four-unique-violations-details.txt | 10 +++--- .../one-multilocation-violation-details.txt | 8 +++-- test/lib/viewers/ResultsViewer.test.ts | 19 +++++------ 6 files changed, 47 insertions(+), 34 deletions(-) diff --git a/messages/results-viewer.md b/messages/results-viewer.md index 8ed4253fe..e9e526005 100644 --- a/messages/results-viewer.md +++ b/messages/results-viewer.md @@ -2,7 +2,7 @@ %d. %s -# summary.table.results-relative-to +# summary.shared.results-relative-to Violation file paths relative to '%s'. diff --git a/src/lib/viewers/ResultsViewer.ts b/src/lib/viewers/ResultsViewer.ts index daa81f739..1034533d8 100644 --- a/src/lib/viewers/ResultsViewer.ts +++ b/src/lib/viewers/ResultsViewer.ts @@ -43,17 +43,18 @@ abstract class AbstractResultsDisplayer implements ResultsViewer { export class ResultsDetailDisplayer extends AbstractResultsDisplayer { protected _view(results: RunResults): void { const violations = sortViolations(results.getViolations()); - - this.displayDetails(violations); + const runDir: string = results.getRunDirectory(); + this.display.displayLog(getMessage(BundleName.ResultsViewer, 'summary.shared.results-relative-to', [runDir]) + "\n"); + this.displayDetails(violations, runDir); } - private displayDetails(violations: Violation[]): void { + private displayDetails(violations: Violation[], runDir: string): void { const styledViolations: string[] = violations - .map((violation, idx) => this.styleViolation(violation, idx)); + .map((violation, idx) => this.styleViolation(violation, idx, runDir)); this.display.displayLog(styledViolations.join('\n\n')); } - private styleViolation(violation: Violation, idx: number): string { + private styleViolation(violation: Violation, idx: number, runDir: string): string { const rule = violation.getRule(); const sev = rule.getSeverityLevel(); @@ -69,10 +70,10 @@ export class ResultsDetailDisplayer extends AbstractResultsDisplayer { } const keys: string[] = ['severity', 'engine', 'message']; if (violation.getCodeLocations().length == 1) { - body['location'] = stringifyLocation(violation.getCodeLocations()[0], false); + body['location'] = stringifyLocation(violation.getCodeLocations()[0], false, runDir); keys.push('location'); } else if (violation.getCodeLocations().length > 1) { - body['locations'] = stringifyLocations(violation.getCodeLocations(), violation.getPrimaryLocationIndex()); + body['locations'] = stringifyLocations(violation.getCodeLocations(), violation.getPrimaryLocationIndex(), runDir); keys.push('locations'); } if (violation.getResourceUrls().length == 1) { @@ -86,14 +87,17 @@ export class ResultsDetailDisplayer extends AbstractResultsDisplayer { } } -function stringifyLocations(codeLocations: CodeLocation[], primaryIndex: number): string[] { +function stringifyLocations(codeLocations: CodeLocation[], primaryIndex: number, runDir: string): string[] { return codeLocations.map((loc, idx) => - stringifyLocation(loc, codeLocations.length > 1 && primaryIndex === idx)); + stringifyLocation(loc, codeLocations.length > 1 && primaryIndex === idx, runDir)); } -function stringifyLocation(loc: CodeLocation, displayMain: boolean): string { +function stringifyLocation(loc: CodeLocation, displayMain: boolean, runDir: string): string { const mainPortion: string = displayMain ? '(main) ' : ''; - const commentPortion: string = loc.getComment() ? ` "${loc.getComment()}"` : ''; + let filePortion: string | undefined = loc.getFile(); + if (filePortion && filePortion.startsWith(runDir)) { + filePortion = filePortion.slice(runDir.length); + } let rangePortion: string = ''; if (loc.getStartLine()) { rangePortion += ` (${loc.getStartLine()}:${loc.getStartColumn() || 1}`; @@ -102,7 +106,9 @@ function stringifyLocation(loc: CodeLocation, displayMain: boolean): string { } rangePortion += ')'; } - return `${mainPortion}${loc.getFile()}${rangePortion}${commentPortion}`; + const commentPortion: string = loc.getComment() ? ` "${loc.getComment()}"` : ''; + + return `${mainPortion}${filePortion}${rangePortion}${commentPortion}`; } type ResultRow = { @@ -151,7 +157,7 @@ export class ResultsTableDisplayer extends AbstractResultsDisplayer { } }); - this.display.displayLog(getMessage(BundleName.ResultsViewer, 'summary.table.results-relative-to', [parentFolder])); + this.display.displayLog(getMessage(BundleName.ResultsViewer, 'summary.shared.results-relative-to', [parentFolder])); this.display.displayTable(resultRows, TABLE_COLUMNS); } } diff --git a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-identical-violations-details.txt b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-identical-violations-details.txt index d35c56933..a31e21211 100644 --- a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-identical-violations-details.txt +++ b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-identical-violations-details.txt @@ -1,9 +1,11 @@ +Violation file paths relative to '{{RUNDIR}}'. + === 1. stub1RuleA severity: 4 (Low) engine: stubEngine1 message: This is a message - location: __PATH_TO_SOME_FILE__ (1:1) + location: test{{PATHSEP}}sample-code{{PATHSEP}}someFile.cls (1:1) resources: https://example.com/stub1RuleA https://violation_specific.url @@ -12,7 +14,7 @@ severity: 4 (Low) engine: stubEngine1 message: This is a message - location: __PATH_TO_SOME_FILE__ (1:1) + location: test{{PATHSEP}}sample-code{{PATHSEP}}someFile.cls (1:1) resources: https://example.com/stub1RuleA https://violation_specific.url @@ -21,7 +23,7 @@ severity: 4 (Low) engine: stubEngine1 message: This is a message - location: __PATH_TO_SOME_FILE__ (1:1) + location: test{{PATHSEP}}sample-code{{PATHSEP}}someFile.cls (1:1) resources: https://example.com/stub1RuleA https://violation_specific.url @@ -30,7 +32,7 @@ severity: 4 (Low) engine: stubEngine1 message: This is a message - location: __PATH_TO_SOME_FILE__ (1:1) + location: test{{PATHSEP}}sample-code{{PATHSEP}}someFile.cls (1:1) resources: https://example.com/stub1RuleA https://violation_specific.url diff --git a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-unique-violations-details.txt b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-unique-violations-details.txt index c0ff38a99..1bf2b5575 100644 --- a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-unique-violations-details.txt +++ b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/four-unique-violations-details.txt @@ -1,28 +1,30 @@ +Violation file paths relative to '{{RUNDIR}}'. + === 1. stub1RuleB severity: 2 (High) engine: stubEngine1 message: This is a message - location: __PATH_TO_FILE_Z__ (20:1) + location: test{{PATHSEP}}sample-code{{PATHSEP}}fileZ.cls (20:1) resource: https://example.com/stub1RuleB === 2. stub1RuleA severity: 4 (Low) engine: stubEngine1 message: This is a message - location: __PATH_TO_FILE_A__ (1:1) + location: test{{PATHSEP}}sample-code{{PATHSEP}}fileA.cls (1:1) resource: https://example.com/stub1RuleA === 3. stub1RuleA severity: 4 (Low) engine: stubEngine1 message: This is a message - location: __PATH_TO_FILE_A__ (20:1) + location: test{{PATHSEP}}sample-code{{PATHSEP}}fileA.cls (20:1) resource: https://example.com/stub1RuleA === 4. stub1RuleA severity: 4 (Low) engine: stubEngine1 message: This is a message - location: __PATH_TO_FILE_Z__ (1:1) + location: test{{PATHSEP}}sample-code{{PATHSEP}}fileZ.cls (1:1) resource: https://example.com/stub1RuleA diff --git a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/one-multilocation-violation-details.txt b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/one-multilocation-violation-details.txt index 2f67e5936..fce989c28 100644 --- a/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/one-multilocation-violation-details.txt +++ b/test/fixtures/comparison-files/lib/viewers/ResultsViewer.test.ts/one-multilocation-violation-details.txt @@ -1,10 +1,12 @@ +Violation file paths relative to '{{RUNDIR}}'. + === 1. stub1RuleA severity: 4 (Low) engine: stubEngine1 message: This is a message locations: - __PATH_TO_FILE_A__ (20:1) - (main) __PATH_TO_FILE_Z__ (2:1) "This is a comment at Location 2" - __PATH_TO_FILE_A__ (1:1-3:1) "This is a comment at Location 3" + test{{PATHSEP}}sample-code{{PATHSEP}}fileA.cls (20:1) + (main) test{{PATHSEP}}sample-code{{PATHSEP}}fileZ.cls (2:1) "This is a comment at Location 2" + test{{PATHSEP}}sample-code{{PATHSEP}}fileA.cls (1:1-3:1) "This is a comment at Location 3" resource: https://example.com/stub1RuleA diff --git a/test/lib/viewers/ResultsViewer.test.ts b/test/lib/viewers/ResultsViewer.test.ts index 876ab59ee..83ac512e6 100644 --- a/test/lib/viewers/ResultsViewer.test.ts +++ b/test/lib/viewers/ResultsViewer.test.ts @@ -90,8 +90,9 @@ describe('ResultsViewer implementations', () => { // Rip off all of ansis's styling, so we're just comparing plain text. const actualEventText = ansis.strip(actualDisplayEvents.map(e => e.data).join('\n')); const expectedViolationDetails = (await readComparisonFile('four-identical-violations-details.txt')) - .replace(/__PATH_TO_SOME_FILE__/g, PATH_TO_SOME_FILE); - expect(actualEventText).toContain(expectedViolationDetails); + .replaceAll("{{PATHSEP}}", path.sep) + .replace("{{RUNDIR}}", results.getRunDirectory()); + expect(actualEventText).toEqual(expectedViolationDetails); }); // The reasoning behind this sorting order is so that the Detail view can function as a "show me the N most @@ -128,9 +129,9 @@ describe('ResultsViewer implementations', () => { // Rip off all of ansis's styling, so we're just comparing plain text. const actualEventText = ansis.strip(actualDisplayEvents.map(e => e.data).join('\n')); const expectedViolationDetails = (await readComparisonFile('four-unique-violations-details.txt')) - .replace(/__PATH_TO_FILE_A__/g, PATH_TO_FILE_A) - .replace(/__PATH_TO_FILE_Z__/g, PATH_TO_FILE_Z); - expect(actualEventText).toContain(expectedViolationDetails); + .replaceAll("{{PATHSEP}}", path.sep) + .replace("{{RUNDIR}}", results.getRunDirectory()); + expect(actualEventText).toEqual(expectedViolationDetails); }); it('Multi-location violations are correctly displayed', async () => { @@ -177,8 +178,8 @@ describe('ResultsViewer implementations', () => { // Rip off all of ansis's styling, so we're just comparing plain text. const actualEventText = ansis.strip(actualDisplayEvents.map(e => e.data).join('\n')); const expectedViolationDetails = (await readComparisonFile('one-multilocation-violation-details.txt')) - .replace(/__PATH_TO_FILE_A__/g, PATH_TO_FILE_A) - .replace(/__PATH_TO_FILE_Z__/g, PATH_TO_FILE_Z); + .replaceAll("{{PATHSEP}}", path.sep) + .replace("{{RUNDIR}}", results.getRunDirectory()); expect(actualEventText).toEqual(expectedViolationDetails); }) }); @@ -229,7 +230,7 @@ describe('ResultsViewer implementations', () => { expect(displayEvents[0].type).toEqual(DisplayEventType.LOG); expect(displayEvents[0].data).toEqual(''); expect(displayEvents[1].type).toEqual(DisplayEventType.LOG); - expect(displayEvents[1].data).toEqual(getMessage(BundleName.ResultsViewer, 'summary.table.results-relative-to', [PATH_TO_SAMPLE_CODE])); + expect(displayEvents[1].data).toEqual(getMessage(BundleName.ResultsViewer, 'summary.shared.results-relative-to', [PATH_TO_SAMPLE_CODE])); expect(displayEvents[2].type).toEqual(DisplayEventType.TABLE); expect(displayEvents[2].data).toEqual(`{"columns":["#","Severity","Rule","Location","Message"],"rows":[{"num":1,"location":"someFile.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"},{"num":2,"location":"someFile.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"},{"num":3,"location":"someFile.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"},{"num":4,"location":"someFile.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"}]}`); }); @@ -263,7 +264,7 @@ describe('ResultsViewer implementations', () => { expect(displayEvents[0].type).toEqual(DisplayEventType.LOG); expect(displayEvents[0].data).toEqual(''); expect(displayEvents[1].type).toEqual(DisplayEventType.LOG); - expect(displayEvents[1].data).toEqual(getMessage(BundleName.ResultsViewer, 'summary.table.results-relative-to', [PATH_TO_SAMPLE_CODE])); + expect(displayEvents[1].data).toEqual(getMessage(BundleName.ResultsViewer, 'summary.shared.results-relative-to', [PATH_TO_SAMPLE_CODE])); expect(displayEvents[2].type).toEqual(DisplayEventType.TABLE); expect(displayEvents[2].data).toEqual(`{"columns":["#","Severity","Rule","Location","Message"],"rows":[{"num":1,"location":"fileZ.cls:20:1","rule":"stubEngine1:stub1RuleB","severity":"2 (High)","message":"This is a message"},{"num":2,"location":"fileA.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"},{"num":3,"location":"fileA.cls:20:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"},{"num":4,"location":"fileZ.cls:1:1","rule":"stubEngine1:stub1RuleA","severity":"4 (Low)","message":"This is a message"}]}`); }); From 5df9dae02d5a68ef68f97e7017cb1602a55f0817 Mon Sep 17 00:00:00 2001 From: Josh Feingold Date: Thu, 21 Nov 2024 15:26:43 -0600 Subject: [PATCH 16/35] NEW @W-17100664@ Integrated FlowTest engine (#1679) --- .github/workflows/run-tests.yml | 3 +++ package.json | 1 + src/lib/factories/EnginePluginsFactory.ts | 4 +++- test/lib/factories/EnginePluginsFactory.test.ts | 3 ++- yarn.lock | 12 ++++++++++++ 5 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 21c6a9bdd..4c00e3153 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -96,6 +96,9 @@ jobs: with: distribution: 'temurin' java-version: '11' + - uses: actions/setup-python@v5 + with: + python-version: '3.12' # Install SF CLI via NPM - run: npm install -g @salesforce/cli # Download and install the Tarball artifact diff --git a/package.json b/package.json index 361060367..de752cb2f 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "@salesforce/code-analyzer-core": "0.17.0", "@salesforce/code-analyzer-engine-api": "0.14.0", "@salesforce/code-analyzer-eslint-engine": "0.14.0", + "@salesforce/code-analyzer-flowtest-engine": "0.14.0", "@salesforce/code-analyzer-pmd-engine": "0.14.0", "@salesforce/code-analyzer-regex-engine": "0.14.0", "@salesforce/code-analyzer-retirejs-engine": "0.14.0", diff --git a/src/lib/factories/EnginePluginsFactory.ts b/src/lib/factories/EnginePluginsFactory.ts index accc6ce7c..e390bf337 100644 --- a/src/lib/factories/EnginePluginsFactory.ts +++ b/src/lib/factories/EnginePluginsFactory.ts @@ -3,6 +3,7 @@ import * as ESLintEngineModule from '@salesforce/code-analyzer-eslint-engine'; import * as PmdCpdEnginesModule from '@salesforce/code-analyzer-pmd-engine'; import * as RetireJSEngineModule from '@salesforce/code-analyzer-retirejs-engine'; import * as RegexEngineModule from '@salesforce/code-analyzer-regex-engine'; +import * as FlowTestEngineModule from '@salesforce/code-analyzer-flowtest-engine'; export interface EnginePluginsFactory { create(): EnginePlugin[]; @@ -14,7 +15,8 @@ export class EnginePluginsFactoryImpl implements EnginePluginsFactory { ESLintEngineModule.createEnginePlugin(), PmdCpdEnginesModule.createEnginePlugin(), RetireJSEngineModule.createEnginePlugin(), - RegexEngineModule.createEnginePlugin() + RegexEngineModule.createEnginePlugin(), + FlowTestEngineModule.createEnginePlugin() ]; } } diff --git a/test/lib/factories/EnginePluginsFactory.test.ts b/test/lib/factories/EnginePluginsFactory.test.ts index 7b645c793..9e00e08e3 100644 --- a/test/lib/factories/EnginePluginsFactory.test.ts +++ b/test/lib/factories/EnginePluginsFactory.test.ts @@ -6,10 +6,11 @@ describe('EnginePluginsFactoryImpl', () => { const pluginsFactory = new EnginePluginsFactoryImpl(); const enginePlugins = pluginsFactory.create(); - expect(enginePlugins).toHaveLength(4); + expect(enginePlugins).toHaveLength(5); expect(enginePlugins[0].getAvailableEngineNames()).toEqual(['eslint']); expect(enginePlugins[1].getAvailableEngineNames()).toEqual(['pmd', 'cpd']); expect(enginePlugins[2].getAvailableEngineNames()).toEqual(['retire-js']); expect(enginePlugins[3].getAvailableEngineNames()).toEqual(['regex']); + expect(enginePlugins[4].getAvailableEngineNames()).toEqual(['flowtest']); }); }); diff --git a/yarn.lock b/yarn.lock index cc7aff676..f1424a3f1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1739,6 +1739,18 @@ eslint-plugin-import "^2.29.1" eslint-plugin-jest "^28.6.0" +"@salesforce/code-analyzer-flowtest-engine@0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-flowtest-engine/-/code-analyzer-flowtest-engine-0.14.0.tgz#2e7fd02c4f71d0a0a4dd96460a16f261f2ae0434" + integrity sha512-SKcwtdB7h7GagowUsfZYoQYM5HSoTyQI5SNsGnwXxaJ7VCLBbxG8Ag1811cvqMAbk1DUb/44nHNBeb5XqUN3nA== + dependencies: + "@salesforce/code-analyzer-engine-api" "0.14.0" + "@types/node" "^20.0.0" + "@types/semver" "^7.5.8" + "@types/tmp" "^0.2.6" + semver "^7.6.3" + tmp "^0.2.3" + "@salesforce/code-analyzer-pmd-engine@0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-pmd-engine/-/code-analyzer-pmd-engine-0.14.0.tgz#580a4b038a9f6468689e35a0e8e2867e71b5d75c" From e1e84f2d82b289740610023ac6aac7edc578c3b5 Mon Sep 17 00:00:00 2001 From: Josh Feingold Date: Thu, 21 Nov 2024 15:57:29 -0600 Subject: [PATCH 17/35] CHANGE @W-17100664@ Updating to latest version (#1680) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index de752cb2f..eb5d52725 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "@salesforce/code-analyzer-core": "0.17.0", "@salesforce/code-analyzer-engine-api": "0.14.0", "@salesforce/code-analyzer-eslint-engine": "0.14.0", - "@salesforce/code-analyzer-flowtest-engine": "0.14.0", + "@salesforce/code-analyzer-flowtest-engine": "0.14.1", "@salesforce/code-analyzer-pmd-engine": "0.14.0", "@salesforce/code-analyzer-regex-engine": "0.14.0", "@salesforce/code-analyzer-retirejs-engine": "0.14.0", diff --git a/yarn.lock b/yarn.lock index f1424a3f1..f9b5c3582 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1739,10 +1739,10 @@ eslint-plugin-import "^2.29.1" eslint-plugin-jest "^28.6.0" -"@salesforce/code-analyzer-flowtest-engine@0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-flowtest-engine/-/code-analyzer-flowtest-engine-0.14.0.tgz#2e7fd02c4f71d0a0a4dd96460a16f261f2ae0434" - integrity sha512-SKcwtdB7h7GagowUsfZYoQYM5HSoTyQI5SNsGnwXxaJ7VCLBbxG8Ag1811cvqMAbk1DUb/44nHNBeb5XqUN3nA== +"@salesforce/code-analyzer-flowtest-engine@0.14.1": + version "0.14.1" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-flowtest-engine/-/code-analyzer-flowtest-engine-0.14.1.tgz#1cc374a2a02d9cc503c6abc9c5d5a1f06005bf2c" + integrity sha512-05cc4DV47IXA/n3mjrhwPjBubev8bmXL4AkOkRyPpbQKCkVoLitORHUAJiIk5DBB7nffnvjh8WDDgrAmwtk0cw== dependencies: "@salesforce/code-analyzer-engine-api" "0.14.0" "@types/node" "^20.0.0" From 2c59eb7957637cbf9a5ab9e8e6463a01805abb84 Mon Sep 17 00:00:00 2001 From: Stephen Carter Date: Tue, 26 Nov 2024 16:14:47 -0500 Subject: [PATCH 18/35] CHANGE: @W-17321151@: Only show fields in --detail view of rules command if they are non-empty --- src/lib/viewers/RuleViewer.ts | 27 +++++++++++++++---- .../RuleViewer.test.ts/one-rule-details.txt | 2 +- .../RuleViewer.test.ts/two-rules-details.txt | 6 +++-- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/lib/viewers/RuleViewer.ts b/src/lib/viewers/RuleViewer.ts index d8519cae5..9aa2fa6e2 100644 --- a/src/lib/viewers/RuleViewer.ts +++ b/src/lib/viewers/RuleViewer.ts @@ -38,14 +38,31 @@ export class RuleDetailDisplayer extends AbstractRuleDisplayer { const rule = rules[i]; const header = getMessage(BundleName.RuleViewer, 'summary.detail.header', [i + 1, rule.getName()]); const severity = rule.getSeverityLevel(); + const body = { - engine: rule.getEngineName(), severity: `${severity.valueOf()} (${SeverityLevel[severity]})`, - tags: rule.getTags().join(', '), - resources: rule.getResourceUrls().join(', '), - description: rule.getDescription() + engine: rule.getEngineName(), }; - const keys = ['severity', 'engine', 'tags', 'resources', 'description']; + const keys: string[] = ['severity', 'engine']; + + if (rule.getTags().length > 0) { + body['tags'] = rule.getTags().join(', '); + keys.push('tags'); + } + + if (rule.getResourceUrls().length == 1) { + body['resource'] = rule.getResourceUrls()[0]; + keys.push('resource'); + } else if (rule.getResourceUrls().length > 1) { + body['resources'] = rule.getResourceUrls(); + keys.push('resources'); + } + + if (rule.getDescription().length > 0) { + body['description'] = rule.getDescription(); + keys.push('description'); + } + styledRules.push(toStyledHeaderAndBody(header, body, keys)); } this.display.displayLog(styledRules.join('\n\n')); diff --git a/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/one-rule-details.txt b/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/one-rule-details.txt index 1a406a4a4..b3fa7bc4f 100644 --- a/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/one-rule-details.txt +++ b/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/one-rule-details.txt @@ -3,5 +3,5 @@ severity: 2 (High) engine: FakeEngine1 tags: Recommended, Security - resources: www.google.com + resource: www.google.com description: This is the description for a stub rule. Blah blah blah. diff --git a/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/two-rules-details.txt b/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/two-rules-details.txt index 32f56f881..eb1cf8d34 100644 --- a/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/two-rules-details.txt +++ b/test/fixtures/comparison-files/lib/viewers/RuleViewer.test.ts/two-rules-details.txt @@ -3,12 +3,14 @@ severity: 2 (High) engine: FakeEngine1 tags: Recommended, Security - resources: www.google.com + resource: www.google.com description: This is the description for a stub rule. Blah blah blah. === 2. StubRule2 severity: 4 (Low) engine: FakeEngine1 tags: CodeStyle, Performance - resources: www.bing.com, www.salesforce.com + resources: + www.bing.com + www.salesforce.com description: This is the description for a second stub rule. Blah blah blah. From 3ae4cd64ee93bf5ac390de5230d3964a0b54058e Mon Sep 17 00:00:00 2001 From: Stephen Carter Date: Thu, 5 Dec 2024 12:34:56 -0500 Subject: [PATCH 19/35] CHANGE: @W-17293079@: Update dependencies, refactor config command that fixes python_command issue --- package.json | 14 +- src/lib/messages.ts | 1 - src/lib/models/ConfigModel.ts | 79 ++++--- ...onfigWithRelativePathScenario.yml.goldfile | 2 +- test/lib/actions/ConfigAction.test.ts | 61 ++++- test/lib/writers/ConfigWriter.test.ts | 2 +- test/stubs/SpyRunSummaryViewer.ts | 14 -- test/stubs/StubEnginePlugins.ts | 20 ++ yarn.lock | 220 ++++++++++++------ 9 files changed, 277 insertions(+), 136 deletions(-) delete mode 100644 test/stubs/SpyRunSummaryViewer.ts diff --git a/package.json b/package.json index eb5d52725..7c3e59b06 100644 --- a/package.json +++ b/package.json @@ -6,13 +6,13 @@ "bugs": "https://github.com/forcedotcom/sfdx-scanner/issues", "dependencies": { "@oclif/core": "^3.3.2", - "@salesforce/code-analyzer-core": "0.17.0", - "@salesforce/code-analyzer-engine-api": "0.14.0", - "@salesforce/code-analyzer-eslint-engine": "0.14.0", - "@salesforce/code-analyzer-flowtest-engine": "0.14.1", - "@salesforce/code-analyzer-pmd-engine": "0.14.0", - "@salesforce/code-analyzer-regex-engine": "0.14.0", - "@salesforce/code-analyzer-retirejs-engine": "0.14.0", + "@salesforce/code-analyzer-core": "0.18.0", + "@salesforce/code-analyzer-engine-api": "0.15.0", + "@salesforce/code-analyzer-eslint-engine": "0.15.0", + "@salesforce/code-analyzer-flowtest-engine": "0.15.0", + "@salesforce/code-analyzer-pmd-engine": "0.15.0", + "@salesforce/code-analyzer-regex-engine": "0.15.0", + "@salesforce/code-analyzer-retirejs-engine": "0.15.0", "@salesforce/core": "^5", "@salesforce/sf-plugins-core": "^5.0.4", "@salesforce/ts-types": "^2.0.9", diff --git a/src/lib/messages.ts b/src/lib/messages.ts index a73b71b1a..4a8d0e661 100644 --- a/src/lib/messages.ts +++ b/src/lib/messages.ts @@ -17,7 +17,6 @@ export enum BundleName { ResultsWriter = 'results-writer', RunAction = 'run-action', RunCommand = 'run-command', - RunSummaryViewer = 'run-summary-viewer', Shared = 'shared', WorkspaceUtil = 'workspace-util' } diff --git a/src/lib/models/ConfigModel.ts b/src/lib/models/ConfigModel.ts index 479526d8e..d9465574f 100644 --- a/src/lib/models/ConfigModel.ts +++ b/src/lib/models/ConfigModel.ts @@ -2,7 +2,8 @@ import {dump as yamlDump} from 'js-yaml'; import { CodeAnalyzer, CodeAnalyzerConfig, - ConfigDescription, + ConfigDescription, ConfigFieldDescription, + EngineConfig, Rule, RuleSelection, SeverityLevel @@ -83,37 +84,51 @@ abstract class YamlFormatter { return yamlCode.replace(/(\r?\n|$)/, ` ${comment}$1`); } - private toYamlField(fieldName: string, userValue: unknown, defaultValue: unknown): string { - if (looksLikeAPathValue(userValue) && userValue === defaultValue) { - // We special handle a path value when it is equal to the default value, making it equal null because - // chances are it is a derived file or folder value based on the specific environment that we do not want to - // actually want to hard code since checking in the config to CI/CD system may create a different value - const commentText: string = getMessage(BundleName.ConfigModel, 'template.last-calculated-as', [JSON.stringify(userValue)]); - return this.toYamlUncheckedFieldWithInlineComment(fieldName, null, commentText); - } else if (JSON.stringify(userValue) === JSON.stringify(defaultValue)) { - return this.toYamlUncheckedField(fieldName, userValue); + private toYamlFieldUsingFieldDescription(fieldName: string, resolvedValue: unknown, fieldDescription: ConfigFieldDescription): string { + const resolvedValueJson: string = JSON.stringify(resolvedValue); + const defaultValueJson: string = JSON.stringify(fieldDescription.defaultValue); + + if (!fieldDescription.wasSuppliedByUser && resolvedValueJson !== defaultValueJson) { + // Whenever the user did not supply the value themselves but the resolved value is different from the + // default value, this means the value was not a "fixed" value but a value "calculated" at runtime. + // Since "calculated" values often depend on the specific environment, we do not want to actually hard code + // this value into the config since checking in the config to CI/CD system may create a different value. + const commentText: string = getMessage(BundleName.ConfigModel, 'template.last-calculated-as', [resolvedValueJson]); + return this.toYamlUncheckedFieldWithInlineComment(fieldName, fieldDescription.defaultValue, commentText); } - userValue = replaceAbsolutePathsWithRelativePathsWherePossible(userValue, this.userContext.config.getConfigRoot() + path.sep); + return this.toYamlField(fieldName, resolvedValue, fieldDescription.defaultValue); + } + + private toYamlField(fieldName: string, resolvedValue: unknown, defaultValue: unknown): string { + const resolvedValueJson: string = JSON.stringify(resolvedValue); + const defaultValueJson: string = JSON.stringify(defaultValue); - const commentText: string = getMessage(BundleName.ConfigModel, 'template.modified-from', [JSON.stringify(defaultValue)]); - return this.toYamlUncheckedFieldWithInlineComment(fieldName, userValue, commentText); + if (resolvedValueJson === defaultValueJson) { + return this.toYamlUncheckedField(fieldName, resolvedValue); + } + + const commentText: string = getMessage(BundleName.ConfigModel, 'template.modified-from', [defaultValueJson]); + resolvedValue = replaceAbsolutePathsWithRelativePathsWherePossible(resolvedValue, this.userContext.config.getConfigRoot() + path.sep); + return this.toYamlUncheckedFieldWithInlineComment(fieldName, resolvedValue, commentText); } toYaml(): string { - const topLevelDescription: ConfigDescription = CodeAnalyzerConfig.getConfigDescription(); - return this.toYamlSectionHeadingComment(topLevelDescription.overview!) + '\n' + + const topLevelDescription: ConfigDescription = this.userContext.config.getConfigDescription(); + return this.toYamlSectionHeadingComment(topLevelDescription.overview) + '\n' + '\n' + - this.toYamlComment(topLevelDescription.fieldDescriptions!.config_root) + '\n' + - this.toYamlField('config_root', this.userContext.config.getConfigRoot(), this.defaultContext.config.getConfigRoot()) + '\n' + + this.toYamlComment(topLevelDescription.fieldDescriptions.config_root.descriptionText) + '\n' + + this.toYamlFieldUsingFieldDescription('config_root', this.userContext.config.getConfigRoot(), + topLevelDescription.fieldDescriptions.config_root) + '\n' + '\n' + - this.toYamlComment(topLevelDescription.fieldDescriptions!.log_folder) + '\n' + - this.toYamlField('log_folder', this.userContext.config.getLogFolder(), this.defaultContext.config.getLogFolder()) + '\n' + + this.toYamlComment(topLevelDescription.fieldDescriptions.log_folder.descriptionText) + '\n' + + this.toYamlFieldUsingFieldDescription('log_folder', this.userContext.config.getLogFolder(), + topLevelDescription.fieldDescriptions.log_folder) + '\n' + '\n' + - this.toYamlComment(topLevelDescription.fieldDescriptions!.rules) + '\n' + + this.toYamlComment(topLevelDescription.fieldDescriptions.rules.descriptionText) + '\n' + this.toYamlRuleOverrides() + '\n' + '\n' + - this.toYamlComment(topLevelDescription.fieldDescriptions!.engines) + '\n' + + this.toYamlComment(topLevelDescription.fieldDescriptions.engines.descriptionText) + '\n' + this.toYamlEngineOverrides() + '\n' + '\n' + this.toYamlSectionHeadingComment(getMessage(BundleName.ConfigModel, 'template.common.end-of-config')) + '\n'; @@ -176,23 +191,21 @@ abstract class YamlFormatter { } private toYamlEngineOverridesForEngine(engineName: string): string { - const engineConfigDescriptor = this.userContext.core.getEngineConfigDescription(engineName); - const userEngineConfig = this.userContext.core.getEngineConfig(engineName); - const defaultEngineConfig = this.defaultContext.core.getEngineConfig(engineName); + const engineConfigDescriptor: ConfigDescription = this.userContext.core.getEngineConfigDescription(engineName); + const userEngineConfig: EngineConfig = this.userContext.core.getEngineConfig(engineName); let yamlCode: string = '\n' + - this.toYamlSectionHeadingComment(engineConfigDescriptor.overview!) + '\n' + + this.toYamlSectionHeadingComment(engineConfigDescriptor.overview) + '\n' + `${engineName}:\n`; // By fiat, the field description will always include, at minimum, an entry for "disable_engine", so we can // assume that the object is not undefined. - for (const configField of Object.keys(engineConfigDescriptor.fieldDescriptions!)) { - const fieldDescription = engineConfigDescriptor.fieldDescriptions![configField]; - const defaultValue = defaultEngineConfig[configField] ?? null; - const userValue = userEngineConfig[configField] ?? defaultValue; + for (const configField of Object.keys(engineConfigDescriptor.fieldDescriptions)) { + const fieldDescription: ConfigFieldDescription = engineConfigDescriptor.fieldDescriptions[configField]; + const userValue = userEngineConfig[configField] ?? fieldDescription.defaultValue; // Add a leading newline to visually break up the property from the previous one. yamlCode += '\n' + - indent(this.toYamlComment(fieldDescription), 2) + '\n' + - indent(this.toYamlField(configField, userValue, defaultValue), 2) + '\n'; + indent(this.toYamlComment(fieldDescription.descriptionText), 2) + '\n' + + indent(this.toYamlFieldUsingFieldDescription(configField, userValue, fieldDescription), 2) + '\n'; } return yamlCode.trimEnd(); } @@ -218,10 +231,6 @@ class StyledYamlFormatter extends YamlFormatter { } } -function looksLikeAPathValue(value: unknown) { - return typeof(value) === 'string' && !value.includes('\n') && value.includes(path.sep); -} - function replaceAbsolutePathsWithRelativePathsWherePossible(value: unknown, parentFolder: string): unknown { if (typeof value === 'string') { // Check if the string starts with the parent folder diff --git a/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/override-configurations/StubEngine2_forConfigWithRelativePathScenario.yml.goldfile b/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/override-configurations/StubEngine2_forConfigWithRelativePathScenario.yml.goldfile index 37775d47a..7e13e7a01 100644 --- a/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/override-configurations/StubEngine2_forConfigWithRelativePathScenario.yml.goldfile +++ b/test/fixtures/comparison-files/lib/actions/ConfigAction.test.ts/override-configurations/StubEngine2_forConfigWithRelativePathScenario.yml.goldfile @@ -7,6 +7,6 @@ disable_engine: false # Some description for top_field - top_field: # Modified from: null + top_field: # Modified from: {} sub_field: - optional-input-config.yml \ No newline at end of file diff --git a/test/lib/actions/ConfigAction.test.ts b/test/lib/actions/ConfigAction.test.ts index ed9c0ae2c..bf9bd36e2 100644 --- a/test/lib/actions/ConfigAction.test.ts +++ b/test/lib/actions/ConfigAction.test.ts @@ -252,7 +252,7 @@ describe('ConfigAction tests', () => { it.each([ {prop: 'config_root'}, {prop: 'log_folder'} - ])(`When derivable property $prop input is non-null and non-default, it is rendered as-is with no comment`, async ({prop}) => { + ])(`When derivable property $prop input is non-null and non-default, it is rendered as-is`, async ({prop}) => { // ==== SETUP ==== // Make the config root and log folder both be the folder above this one. const parentOfCurrentDirectory = path.resolve(__dirname, '..'); @@ -264,12 +264,11 @@ describe('ConfigAction tests', () => { const output = await runActionAndGetDisplayedConfig(dependencies, ['all']); // ==== ASSERTIONS ==== - const defaultConfig = CodeAnalyzerConfig.withDefaults(); const goldFileContents = (await readGoldFile(path.join(PATH_TO_COMPARISON_DIR, 'derivables-as-non-defaults', `${prop}.yml.goldfile`))) .replace('__DUMMY_CONFIG_ROOT__', parentOfCurrentDirectory) .replace('__DUMMY_LOG_FOLDER__', parentOfCurrentDirectory) - .replace('__DUMMY_DEFAULT_CONFIG_ROOT__', JSON.stringify(defaultConfig.getConfigRoot())) - .replace('__DUMMY_DEFAULT_LOG_FOLDER__', JSON.stringify(defaultConfig.getLogFolder())) + .replace('__DUMMY_DEFAULT_CONFIG_ROOT__', JSON.stringify(null)) + .replace('__DUMMY_DEFAULT_LOG_FOLDER__', JSON.stringify(null)) expect(output).toContain(goldFileContents); }); @@ -573,22 +572,52 @@ class StubEnginePlugin extends EngineApi.EnginePluginV1 { private readonly createdEngines: Map = new Map(); + /* + descriptionText: string; + valueType: string; + defaultValue: ConfigValue; + */ + private readonly descriptionsByEngine: {[key: string]: EngineApi.ConfigDescription} = { StubEngine1: { overview: 'This is a generic overview for StubEngine1\nIt has multiple lines of text\nWhee!', fieldDescriptions: { - 'Property1': 'This is the description for Property1', + 'Property1': { + descriptionText: 'This is the description for Property1', + valueType: 'string', + defaultValue: 'default1' + }, // Property2 is undocumented - 'Property3': 'This is the description for Property3', - 'Property4': 'This is the description for Property4', - 'Property5': 'This is the description for Property5', - 'Property6': 'This is the description for Property6' + 'Property3': { + descriptionText: 'This is the description for Property3', + valueType: 'string', + defaultValue: 'default3' + }, + 'Property4': { + descriptionText: 'This is the description for Property4', + valueType: 'object', + defaultValue: {SubProperty1: 10, SubProperty2: true} + }, + 'Property5': { + descriptionText: 'This is the description for Property5', + valueType: 'array', + defaultValue: ['arr1', 'arr2'] + }, + 'Property6': { + descriptionText: 'This is the description for Property6', + valueType: 'string', + defaultValue: null + }, } }, StubEngine2: { overview: 'Some overview for StubEngine2', fieldDescriptions: { - 'top_field': 'Some description for top_field' + 'top_field': { + descriptionText: 'Some description for top_field', + valueType: 'object', + defaultValue: {} + } } } // StubEngine3 also has no overview or documented properties. @@ -651,6 +680,10 @@ class StubEngine1 extends EngineApi.Engine { return 'StubEngine1'; } + getEngineVersion(): Promise { + return Promise.resolve("1.0.0"); + } + public describeRules(): Promise { return Promise.resolve([{ name: 'Stub1Rule1', @@ -719,6 +752,10 @@ class StubEngine2 extends EngineApi.Engine { return 'StubEngine2'; } + getEngineVersion(): Promise { + return Promise.resolve("1.0.2"); + } + public describeRules(): Promise { return Promise.resolve([{ name: 'Stub2Rule1', @@ -745,6 +782,10 @@ class StubEngine3 extends EngineApi.Engine { return 'StubEngine3'; } + getEngineVersion(): Promise { + return Promise.resolve("1.0.3"); + } + public describeRules(): Promise { return Promise.resolve([{ name: 'Stub3Rule1', diff --git a/test/lib/writers/ConfigWriter.test.ts b/test/lib/writers/ConfigWriter.test.ts index 367f42526..b794898cc 100644 --- a/test/lib/writers/ConfigWriter.test.ts +++ b/test/lib/writers/ConfigWriter.test.ts @@ -9,7 +9,7 @@ describe('ConfigWriter implementations', () => { describe('ConfigWriterImpl', () => { let writeFileSpy: jest.SpyInstance; - let writeFileInvocations: {file: fs.PathOrFileDescriptor, contents: String|ArrayBufferView}[]; + let writeFileInvocations: {file: fs.PathOrFileDescriptor, contents: string|ArrayBufferView}[]; beforeEach(() => { writeFileInvocations = []; writeFileSpy = jest.spyOn(fs, 'writeFileSync').mockImplementation((file, contents) => { diff --git a/test/stubs/SpyRunSummaryViewer.ts b/test/stubs/SpyRunSummaryViewer.ts deleted file mode 100644 index 54870a40e..000000000 --- a/test/stubs/SpyRunSummaryViewer.ts +++ /dev/null @@ -1,14 +0,0 @@ -import {RunResults} from '@salesforce/code-analyzer-core'; -import {RunSummaryViewer} from '../../src/lib/viewers/RunSummaryViewer' - -export class SpyRunSummaryViewer implements RunSummaryViewer { - private callHistory: {results: RunResults, logFile: string, outfiles: string[]}[] = []; - - public view(results: RunResults, logFile: string, outfiles: string[]): void { - this.callHistory.push({results, logFile, outfiles}); - } - - public getCallHistory(): {results: RunResults, logFile: string, outfiles: string[]}[] { - return this.callHistory; - } -} diff --git a/test/stubs/StubEnginePlugins.ts b/test/stubs/StubEnginePlugins.ts index 42ce59450..d027e529e 100644 --- a/test/stubs/StubEnginePlugins.ts +++ b/test/stubs/StubEnginePlugins.ts @@ -71,6 +71,10 @@ export class StubEngine1 extends EngineApi.Engine { return "stubEngine1"; } + getEngineVersion(): Promise { + return Promise.resolve("1.0.0"); + } + describeRules(): Promise { this.emitEvent({ type: EngineApi.EventType.DescribeRulesProgressEvent, @@ -168,6 +172,10 @@ export class StubEngine2 extends EngineApi.Engine { return "stubEngine2"; } + getEngineVersion(): Promise { + return Promise.resolve("1.2.3"); + } + describeRules(): Promise { return Promise.resolve([ { @@ -265,6 +273,10 @@ abstract class BaseTimeableEngine extends EngineApi.Engine { this.executionWaitTime = 0; } + getEngineVersion(): Promise { + return Promise.resolve("1.0.1"); + } + setRuleSelectionWaitTime(waitTime: number): void { this.selectionWaitTime = waitTime; } @@ -366,6 +378,10 @@ export class EventConfigurableEngine1 extends EngineApi.Engine { return "eventConfigurableEngine1"; } + getEngineVersion(): Promise { + return Promise.resolve("1.0.5"); + } + addEvents(...events: {logLevel: LogLevel, message: string}[]): void { this.events = [...this.events, ...events]; } @@ -428,6 +444,10 @@ export class TargetDependentEngine1 extends EngineApi.Engine { return 'targetDependentEngine1'; } + getEngineVersion(): Promise { + return Promise.resolve("1.3.0"); + } + describeRules(describeOptions: EngineApi.DescribeOptions): Promise { if (!describeOptions.workspace) { return Promise.resolve([]); diff --git a/yarn.lock b/yarn.lock index f9b5c3582..69e57cde2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -676,7 +676,7 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.2.tgz#278b6b13664557de95b8f35b90d96785850bb56e" integrity sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg== -"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9", "@babel/core@^7.24.7": +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9", "@babel/core@^7.26.0": version "7.26.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.0.tgz#d78b6023cc8f3114ccf049eb219613f74a747b40" integrity sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg== @@ -718,7 +718,7 @@ json5 "^2.2.3" semver "^6.3.1" -"@babel/eslint-parser@^7.24.7": +"@babel/eslint-parser@^7.25.9": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.25.9.tgz#603c68a63078796527bc9d0833f5e52dd5f9224c" integrity sha512-5UXfgpK0j0Xr/xIdgdLEhOFxaDZ0bRPWJJchRpqOSur/3rZoPbqqki5mm0p4NE2cs28krBEiSM2MB7//afRSQQ== @@ -1013,7 +1013,7 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.57.1", "@eslint/js@^8.57", "@eslint/js@^8.57.0": +"@eslint/js@8.57.1", "@eslint/js@^8.57", "@eslint/js@^8.57.1": version "8.57.1" resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2" integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== @@ -1493,10 +1493,10 @@ node-fetch "^2.6.1" xml2js "^0.6.2" -"@lwc/eslint-plugin-lwc@^1.8.0": - version "1.8.2" - resolved "https://registry.yarnpkg.com/@lwc/eslint-plugin-lwc/-/eslint-plugin-lwc-1.8.2.tgz#9268123d33d47a6d89a2eb7f205b019fdafc654b" - integrity sha512-kPlOq6G2BPo3x56qkGOgwas1SJWZYeQR6uXLMFzFrjb/Lisb24VeABNQd1i7JgoQXQzad0F12pfU0BLgIhhR7g== +"@lwc/eslint-plugin-lwc@^1.8.2": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@lwc/eslint-plugin-lwc/-/eslint-plugin-lwc-1.9.0.tgz#09ddc05e05c0d827cb40c27021c9c3868e519e33" + integrity sha512-z2wEUvLanstSl9o7VT/HAI7uFWHkTApz8N1ZpRQtyh8Hg6UbBZKLrg+vMxDED1vZVLu256i2KgYUWysVQyO4tg== dependencies: globals "^13.24.0" minimatch "^9.0.4" @@ -1699,90 +1699,90 @@ strip-ansi "6.0.1" ts-retry-promise "^0.8.1" -"@salesforce/code-analyzer-core@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-core/-/code-analyzer-core-0.17.0.tgz#4e2c753b2a08525b1952f08f40b416460ffe7181" - integrity sha512-uLAk5q/YdDxqkWfWO0iZBYuZ68DSwsj+HxHVYqtWy+xrBZBpm6JFW06l3wzrtKopAOO4l/CVdVxrR5lXEqgHWQ== +"@salesforce/code-analyzer-core@0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-core/-/code-analyzer-core-0.18.0.tgz#2f309da29564e5b7fc96f50142d4f42bf36d5a61" + integrity sha512-CazelPt8l5BYF6teuEy8v2ELjpOss7xnLeodeE2WIMMG9zlmbwiIIbnXx2shoVLsGUoU/UmOnkE8l7ea8kCnhA== dependencies: - "@salesforce/code-analyzer-engine-api" "0.14.0" + "@salesforce/code-analyzer-engine-api" "0.15.0" "@types/js-yaml" "^4.0.9" "@types/node" "^20.0.0" "@types/sarif" "^2.1.7" - csv-stringify "^6.5.0" + csv-stringify "^6.5.2" js-yaml "^4.1.0" xmlbuilder "^15.1.1" -"@salesforce/code-analyzer-engine-api@0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-engine-api/-/code-analyzer-engine-api-0.14.0.tgz#5cefeafbcd88850342759ad68f0e79e595667630" - integrity sha512-SKqiHKtARSzA3NOaR/hXENt6Z+LmSIozhu2LEBGSq0tlqYtw/89pLXBUv2rozh/wfsyEERAQcxgpPT3v4cVqnQ== +"@salesforce/code-analyzer-engine-api@0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-engine-api/-/code-analyzer-engine-api-0.15.0.tgz#a95b42430f28312441e674ae08d6be55a342d16b" + integrity sha512-6Gw4Qb3YhMVcWcdNmIajjhyTrQ/HmWy9zjgVIjAF2qEmwt6g9qsMDWI3wCwlIjs7xgeUUvwtSd88aDl6I7ZfsQ== dependencies: "@types/node" "^20.0.0" -"@salesforce/code-analyzer-eslint-engine@0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-eslint-engine/-/code-analyzer-eslint-engine-0.14.0.tgz#5735f440ed312f58d70b9b5032fffdb0d98c55d7" - integrity sha512-9WzeB8MXATi+YxKKfbwnkc5vueTMFnJQSQU7kBudtCmEqHB2gIEJsgjQsEKOgT3OSmBW1Vt7mMBY/VcpySBABw== - dependencies: - "@babel/core" "^7.24.7" - "@babel/eslint-parser" "^7.24.7" - "@eslint/js" "^8.57.0" - "@lwc/eslint-plugin-lwc" "^1.8.0" - "@salesforce/code-analyzer-engine-api" "0.14.0" - "@salesforce/eslint-config-lwc" "^3.5.3" +"@salesforce/code-analyzer-eslint-engine@0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-eslint-engine/-/code-analyzer-eslint-engine-0.15.0.tgz#c651e1b0a5d0bc3d4d81062be167b4b2af5c72f6" + integrity sha512-zwMOBzbVHk9adz2Rrb0h3TTaYxm66QU1Fqul88Abf2OoGVYHGfdeuNio7+vV6Md2hZkaXnBStudO5y9+eWlEYw== + dependencies: + "@babel/core" "^7.26.0" + "@babel/eslint-parser" "^7.25.9" + "@eslint/js" "^8.57.1" + "@lwc/eslint-plugin-lwc" "^1.8.2" + "@salesforce/code-analyzer-engine-api" "0.15.0" + "@salesforce/eslint-config-lwc" "^3.6.0" "@salesforce/eslint-plugin-lightning" "^1.0.0" "@types/eslint" "^8.56.10" "@types/node" "^20.0.0" - "@typescript-eslint/eslint-plugin" "^7.13.1" - "@typescript-eslint/parser" "^7.13.1" - eslint "^8.57.0" - eslint-plugin-import "^2.29.1" - eslint-plugin-jest "^28.6.0" - -"@salesforce/code-analyzer-flowtest-engine@0.14.1": - version "0.14.1" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-flowtest-engine/-/code-analyzer-flowtest-engine-0.14.1.tgz#1cc374a2a02d9cc503c6abc9c5d5a1f06005bf2c" - integrity sha512-05cc4DV47IXA/n3mjrhwPjBubev8bmXL4AkOkRyPpbQKCkVoLitORHUAJiIk5DBB7nffnvjh8WDDgrAmwtk0cw== - dependencies: - "@salesforce/code-analyzer-engine-api" "0.14.0" + "@typescript-eslint/eslint-plugin" "^8.17.0" + "@typescript-eslint/parser" "^8.17.0" + eslint "^8.57.1" + eslint-plugin-import "^2.31.0" + eslint-plugin-jest "^28.9.0" + +"@salesforce/code-analyzer-flowtest-engine@0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-flowtest-engine/-/code-analyzer-flowtest-engine-0.15.0.tgz#ceab51555365e50df63983861d35197bd104e16f" + integrity sha512-sb13so0Z1x1xO4CeE2x/t9QR6k6cAX/5cEW4edYLXNE7TH7gC8qpIR5qy55Kdl2zdGEWesUBHEIOFxgHklGIvQ== + dependencies: + "@salesforce/code-analyzer-engine-api" "0.15.0" "@types/node" "^20.0.0" "@types/semver" "^7.5.8" "@types/tmp" "^0.2.6" semver "^7.6.3" tmp "^0.2.3" -"@salesforce/code-analyzer-pmd-engine@0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-pmd-engine/-/code-analyzer-pmd-engine-0.14.0.tgz#580a4b038a9f6468689e35a0e8e2867e71b5d75c" - integrity sha512-+fHZU1CnweU9ZD0sEF/TezWsQfUspA/FiLg7itilosjF+BICtc0MMGlDLjsxcHkKFWubfLfcPGZHK9Zn4Fhr+Q== +"@salesforce/code-analyzer-pmd-engine@0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-pmd-engine/-/code-analyzer-pmd-engine-0.15.0.tgz#ce2bb427486c1869c021c5938d6592d1f6f85291" + integrity sha512-Tw6BNfOct40gsD5onrd08lv/qUQbJYEsLpCZT+GRVhZW6tYyp0R+PucHdyC9mZAT2D70TvGuyijjnbI/7F/3ag== dependencies: - "@salesforce/code-analyzer-engine-api" "0.14.0" + "@salesforce/code-analyzer-engine-api" "0.15.0" "@types/node" "^20.0.0" "@types/semver" "^7.5.8" "@types/tmp" "^0.2.6" semver "^7.6.3" tmp "^0.2.3" -"@salesforce/code-analyzer-regex-engine@0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-regex-engine/-/code-analyzer-regex-engine-0.14.0.tgz#0157910c8c43124cb9c9fb4acfef43c593c51ce8" - integrity sha512-yNef0gfFF7yfXmyLVDEUfCqpKTtaZgw7YlJ/qsyIiMxwou1CTtfKcPOSG3I71vgoc0syQ1ssAUIFFNhkk5kKjw== +"@salesforce/code-analyzer-regex-engine@0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-regex-engine/-/code-analyzer-regex-engine-0.15.0.tgz#7a010c0d6dcd27f46d68fb1f0dc05e7f11e5ef1c" + integrity sha512-1dj4G9WEA80PRankOqWvrckaVU7hjuhdKN3MlSbEJ+Kc9APALfsFS54DhkQX7dnWezGRtHO97NA7tGAgEWayeg== dependencies: - "@salesforce/code-analyzer-engine-api" "0.14.0" + "@salesforce/code-analyzer-engine-api" "0.15.0" "@types/node" "^20.0.0" - isbinaryfile "^5.0.2" + isbinaryfile "^5.0.4" -"@salesforce/code-analyzer-retirejs-engine@0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-retirejs-engine/-/code-analyzer-retirejs-engine-0.14.0.tgz#48a9cde0010153688a49caff7145e99c1331dde7" - integrity sha512-ZxzfHakDF/5lseuPvq/0TeRM0NrUfGI/waW2Oz2NuHd3FDvyFSnAZ/QlZvedd0UdGqQhe/U4PVHj/tSdFOh5TQ== +"@salesforce/code-analyzer-retirejs-engine@0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@salesforce/code-analyzer-retirejs-engine/-/code-analyzer-retirejs-engine-0.15.0.tgz#23dbb66eb8311cc495be341ea54191861c1b1d81" + integrity sha512-HihReOKFWLQzS8dJIUADtNX16ecfnsycw/RYW2dFRSW0fIkV+S191rrLCpwuhFA8dCPwXTW4e338O2+Jc0M0gA== dependencies: - "@salesforce/code-analyzer-engine-api" "0.14.0" + "@salesforce/code-analyzer-engine-api" "0.15.0" "@types/node" "^20.0.0" "@types/tmp" "^0.2.6" - isbinaryfile "^5.0.2" + isbinaryfile "^5.0.4" node-stream-zip "^1.15.0" - retire "^5.0.1" + retire "^5.2.5" tmp "^0.2.3" "@salesforce/core@^5": @@ -1856,7 +1856,7 @@ semver "^7.6.3" ts-retry-promise "^0.8.1" -"@salesforce/eslint-config-lwc@^3.5.3": +"@salesforce/eslint-config-lwc@^3.6.0": version "3.6.0" resolved "https://registry.yarnpkg.com/@salesforce/eslint-config-lwc/-/eslint-config-lwc-3.6.0.tgz#a7af99aff1607cfba65e511e823330308d306520" integrity sha512-k6F3LFKl6wvAmK31B/jn8aHtqo+kwl5q96DzhIcmL1qnCZj+AzH5gw9034j+c8279d8u8dC5QIUDU1iE3aCNCg== @@ -2679,7 +2679,7 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^7.13.1", "@typescript-eslint/eslint-plugin@^7.2.0": +"@typescript-eslint/eslint-plugin@^7.2.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz#b16d3cf3ee76bf572fdf511e79c248bdec619ea3" integrity sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw== @@ -2694,7 +2694,22 @@ natural-compare "^1.4.0" ts-api-utils "^1.3.0" -"@typescript-eslint/parser@^7.13.1", "@typescript-eslint/parser@^7.2.0": +"@typescript-eslint/eslint-plugin@^8.17.0": + version "8.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.17.0.tgz#2ee073c421f4e81e02d10e731241664b6253b23c" + integrity sha512-HU1KAdW3Tt8zQkdvNoIijfWDMvdSweFYm4hWh+KwhPstv+sCmWb89hCIP8msFm9N1R/ooh9honpSuvqKWlYy3w== + dependencies: + "@eslint-community/regexpp" "^4.10.0" + "@typescript-eslint/scope-manager" "8.17.0" + "@typescript-eslint/type-utils" "8.17.0" + "@typescript-eslint/utils" "8.17.0" + "@typescript-eslint/visitor-keys" "8.17.0" + graphemer "^1.4.0" + ignore "^5.3.1" + natural-compare "^1.4.0" + ts-api-utils "^1.3.0" + +"@typescript-eslint/parser@^7.2.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.18.0.tgz#83928d0f1b7f4afa974098c64b5ce6f9051f96a0" integrity sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg== @@ -2705,6 +2720,17 @@ "@typescript-eslint/visitor-keys" "7.18.0" debug "^4.3.4" +"@typescript-eslint/parser@^8.17.0": + version "8.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.17.0.tgz#2ee972bb12fa69ac625b85813dc8d9a5a053ff52" + integrity sha512-Drp39TXuUlD49F7ilHHCG7TTg8IkA+hxCuULdmzWYICxGXvDXmDmWEjJYZQYgf6l/TFfYNE167m7isnc3xlIEg== + dependencies: + "@typescript-eslint/scope-manager" "8.17.0" + "@typescript-eslint/types" "8.17.0" + "@typescript-eslint/typescript-estree" "8.17.0" + "@typescript-eslint/visitor-keys" "8.17.0" + debug "^4.3.4" + "@typescript-eslint/scope-manager@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz#c928e7a9fc2c0b3ed92ab3112c614d6bd9951c83" @@ -2721,6 +2747,14 @@ "@typescript-eslint/types" "8.15.0" "@typescript-eslint/visitor-keys" "8.15.0" +"@typescript-eslint/scope-manager@8.17.0": + version "8.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.17.0.tgz#a3f49bf3d4d27ff8d6b2ea099ba465ef4dbcaa3a" + integrity sha512-/ewp4XjvnxaREtqsZjF4Mfn078RD/9GmiEAtTeLQ7yFdKnqwTOgRMSvFz4et9U5RiJQ15WTGXPLj89zGusvxBg== + dependencies: + "@typescript-eslint/types" "8.17.0" + "@typescript-eslint/visitor-keys" "8.17.0" + "@typescript-eslint/type-utils@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz#2165ffaee00b1fbbdd2d40aa85232dab6998f53b" @@ -2731,6 +2765,16 @@ debug "^4.3.4" ts-api-utils "^1.3.0" +"@typescript-eslint/type-utils@8.17.0": + version "8.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.17.0.tgz#d326569f498cdd0edf58d5bb6030b4ad914e63d3" + integrity sha512-q38llWJYPd63rRnJ6wY/ZQqIzPrBCkPdpIsaCfkR3Q4t3p6sb422zougfad4TFW9+ElIFLVDzWGiGAfbb/v2qw== + dependencies: + "@typescript-eslint/typescript-estree" "8.17.0" + "@typescript-eslint/utils" "8.17.0" + debug "^4.3.4" + ts-api-utils "^1.3.0" + "@typescript-eslint/types@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.18.0.tgz#b90a57ccdea71797ffffa0321e744f379ec838c9" @@ -2741,6 +2785,11 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.15.0.tgz#4958edf3d83e97f77005f794452e595aaf6430fc" integrity sha512-n3Gt8Y/KyJNe0S3yDCD2RVKrHBC4gTUcLTebVBXacPy091E6tNspFLKRXlk3hwT4G55nfr1n2AdFqi/XMxzmPQ== +"@typescript-eslint/types@8.17.0": + version "8.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.17.0.tgz#ef84c709ef8324e766878834970bea9a7e3b72cf" + integrity sha512-gY2TVzeve3z6crqh2Ic7Cr+CAv6pfb0Egee7J5UAVWCpVvDI/F71wNfolIim4FE6hT15EbpZFVUj9j5i38jYXA== + "@typescript-eslint/typescript-estree@7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz#b5868d486c51ce8f312309ba79bdb9f331b37931" @@ -2769,6 +2818,20 @@ semver "^7.6.0" ts-api-utils "^1.3.0" +"@typescript-eslint/typescript-estree@8.17.0": + version "8.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.17.0.tgz#40b5903bc929b1e8dd9c77db3cb52cfb199a2a34" + integrity sha512-JqkOopc1nRKZpX+opvKqnM3XUlM7LpFMD0lYxTqOTKQfCWAmxw45e3qlOCsEqEB2yuacujivudOFpCnqkBDNMw== + dependencies: + "@typescript-eslint/types" "8.17.0" + "@typescript-eslint/visitor-keys" "8.17.0" + debug "^4.3.4" + fast-glob "^3.3.2" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" + "@typescript-eslint/utils@7.18.0", "@typescript-eslint/utils@^7.18.0": version "7.18.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.18.0.tgz#bca01cde77f95fc6a8d5b0dbcbfb3d6ca4be451f" @@ -2779,6 +2842,16 @@ "@typescript-eslint/types" "7.18.0" "@typescript-eslint/typescript-estree" "7.18.0" +"@typescript-eslint/utils@8.17.0": + version "8.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.17.0.tgz#41c05105a2b6ab7592f513d2eeb2c2c0236d8908" + integrity sha512-bQC8BnEkxqG8HBGKwG9wXlZqg37RKSMY7v/X8VEWD8JG2JuTHuNK0VFvMPMUKQcbk6B+tf05k+4AShAEtCtJ/w== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@typescript-eslint/scope-manager" "8.17.0" + "@typescript-eslint/types" "8.17.0" + "@typescript-eslint/typescript-estree" "8.17.0" + "@typescript-eslint/utils@^6.0.0 || ^7.0.0 || ^8.0.0": version "8.15.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.15.0.tgz#ac04679ad19252776b38b81954b8e5a65567cef6" @@ -2805,6 +2878,14 @@ "@typescript-eslint/types" "8.15.0" eslint-visitor-keys "^4.2.0" +"@typescript-eslint/visitor-keys@8.17.0": + version "8.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.17.0.tgz#4dbcd0e28b9bf951f4293805bf34f98df45e1aa8" + integrity sha512-1Hm7THLpO6ww5QU6H/Qp+AusUUl+z/CAm3cNZZ0jQvon9yicgO7Rwd+/WWRpMKLYV6p2UvdbR27c86rzCPpreg== + dependencies: + "@typescript-eslint/types" "8.17.0" + eslint-visitor-keys "^4.2.0" + "@ungap/structured-clone@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" @@ -3551,11 +3632,16 @@ csv-stringify@^5.3.4: resolved "https://registry.yarnpkg.com/csv-stringify/-/csv-stringify-5.6.5.tgz#c6d74badda4b49a79bf4e72f91cce1e33b94de00" integrity sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A== -csv-stringify@^6.4.4, csv-stringify@^6.5.0: +csv-stringify@^6.4.4: version "6.5.1" resolved "https://registry.yarnpkg.com/csv-stringify/-/csv-stringify-6.5.1.tgz#a31837dd35e34787e3c248159c982a21af964d94" integrity sha512-+9lpZfwpLntpTIEpFbwQyWuW/hmI/eHuJZD1XzeZpfZTqkf1fyvBbBLXTJJMsBuuS11uTShMqPwzx4A6ffXgRQ== +csv-stringify@^6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/csv-stringify/-/csv-stringify-6.5.2.tgz#b51d61cd949906d5b5b790463f3055d95915193e" + integrity sha512-RFPahj0sXcmUyjrObAK+DOWtMvMIFV328n4qZJhgX3x2RqkQgOTU2mCUmiFR0CzM6AzChlRSUErjiJeEt8BaQA== + data-uri-to-buffer@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz#8a58bb67384b261a38ef18bea1810cb01badd28b" @@ -3918,7 +4004,7 @@ eslint-module-utils@^2.12.0: dependencies: debug "^3.2.7" -eslint-plugin-import@^2.29.1: +eslint-plugin-import@^2.31.0: version "2.31.0" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz#310ce7e720ca1d9c0bb3f69adfd1c6bdd7d9e0e7" integrity sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A== @@ -3943,7 +4029,7 @@ eslint-plugin-import@^2.29.1: string.prototype.trimend "^1.0.8" tsconfig-paths "^3.15.0" -eslint-plugin-jest@^28.6.0: +eslint-plugin-jest@^28.9.0: version "28.9.0" resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-28.9.0.tgz#19168dfaed124339cd2252c4c4d1ac3688aeb243" integrity sha512-rLu1s1Wf96TgUUxSw6loVIkNtUjq1Re7A9QdCCHSohnvXEBAjuL420h0T/fMmkQlNsQP2GhQzEUpYHPfxBkvYQ== @@ -3994,7 +4080,7 @@ eslint-visitor-keys@^4.2.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== -eslint@^8.57, eslint@^8.57.0: +eslint@^8.57, eslint@^8.57.1: version "8.57.1" resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA== @@ -4981,7 +5067,7 @@ isarray@~1.0.0: resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== -isbinaryfile@^5.0.2: +isbinaryfile@^5.0.4: version "5.0.4" resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-5.0.4.tgz#2a2edefa76cafa66613fe4c1ea52f7f031017bdf" integrity sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ== @@ -6632,7 +6718,7 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" -retire@^5.0.1: +retire@^5.2.5: version "5.2.5" resolved "https://registry.yarnpkg.com/retire/-/retire-5.2.5.tgz#7a7b3126aff4068368053a51b7c05d116130520f" integrity sha512-tPVphjnkTotC35HdiaqaZIyV81ASbebsug0anoWVxfQDHfV0bocXMezJiaR95P+b2nqfwxmhbKdg1WK9XKFlMA== From f3cb27f109d22f74b3e28cd1b01d366c9020b494 Mon Sep 17 00:00:00 2001 From: Stephen Carter Date: Thu, 5 Dec 2024 15:14:11 -0500 Subject: [PATCH 20/35] Some refactoring --- src/commands/code-analyzer/config.ts | 7 +-- src/lib/actions/ConfigAction.ts | 16 ++---- src/lib/models/ConfigModel.ts | 76 +++++++++++++-------------- test/lib/actions/ConfigAction.test.ts | 8 +-- 4 files changed, 46 insertions(+), 61 deletions(-) diff --git a/src/commands/code-analyzer/config.ts b/src/commands/code-analyzer/config.ts index 951ebdf7d..e5249cc88 100644 --- a/src/commands/code-analyzer/config.ts +++ b/src/commands/code-analyzer/config.ts @@ -8,7 +8,7 @@ import {EnginePluginsFactoryImpl} from '../../lib/factories/EnginePluginsFactory import {BundleName, getMessage, getMessages} from '../../lib/messages'; import {LogEventDisplayer} from '../../lib/listeners/LogEventListener'; import {RuleSelectionProgressSpinner} from '../../lib/listeners/ProgressEventListener'; -import {AnnotatedConfigModel, ConfigContext} from '../../lib/models/ConfigModel'; +import {AnnotatedConfigModel} from '../../lib/models/ConfigModel'; import {Displayable, UxDisplay} from '../../lib/Display'; export default class ConfigCommand extends SfCommand implements Displayable { @@ -62,15 +62,12 @@ export default class ConfigCommand extends SfCommand implements Displayabl protected createDependencies(outputFile?: string): ConfigDependencies { const uxDisplay: UxDisplay = new UxDisplay(this, this.spinner); - const modelGeneratorFunction = /* istanbul ignore next - Model tested separately */ (relevantEngines: Set, userContext: ConfigContext, defaultContext: ConfigContext) => { - return AnnotatedConfigModel.fromSelection(relevantEngines, userContext, defaultContext); - }; const dependencies: ConfigDependencies = { configFactory: new CodeAnalyzerConfigFactoryImpl(), pluginsFactory: new EnginePluginsFactoryImpl(), logEventListeners: [new LogEventDisplayer(uxDisplay)], progressEventListeners: [new RuleSelectionProgressSpinner(uxDisplay)], - modelGenerator: modelGeneratorFunction, + modelGenerator: AnnotatedConfigModel, actionSummaryViewer: new ConfigActionSummaryViewer(uxDisplay), viewer: new ConfigStyledYamlViewer(uxDisplay) }; diff --git a/src/lib/actions/ConfigAction.ts b/src/lib/actions/ConfigAction.ts index c997b5031..81ea17f6c 100644 --- a/src/lib/actions/ConfigAction.ts +++ b/src/lib/actions/ConfigAction.ts @@ -8,12 +8,12 @@ import {createWorkspace} from '../utils/WorkspaceUtil'; import {LogEventListener, LogEventLogger} from '../listeners/LogEventListener'; import {ProgressEventListener} from '../listeners/ProgressEventListener'; import {ConfigActionSummaryViewer} from '../viewers/ActionSummaryViewer'; -import {ConfigModel, ConfigModelGeneratorFunction, ConfigContext} from '../models/ConfigModel'; +import {ConfigModel, ConfigModelConstructor} from '../models/ConfigModel'; export type ConfigDependencies = { configFactory: CodeAnalyzerConfigFactory; pluginsFactory: EnginePluginsFactory; - modelGenerator: ConfigModelGeneratorFunction; + modelGenerator: ConfigModelConstructor; logEventListeners: LogEventListener[]; progressEventListeners: ProgressEventListener[]; writer?: ConfigWriter; @@ -109,17 +109,7 @@ export class ConfigAction { // We need the Set of all Engines that returned rules for the user's selection on both the Default and User Cores. const relevantEngines: Set = new Set([...userRules.getEngineNames(), ...selectedDefaultRules.getEngineNames()]); - const userConfigContext: ConfigContext = { - config: userConfig, - core: userCore, - rules: userRules - }; - const defaultConfigContext: ConfigContext = { - config: defaultConfig, - core: defaultCoreForAllRules, - rules: allDefaultRules - }; - const configModel: ConfigModel = this.dependencies.modelGenerator(relevantEngines, userConfigContext, defaultConfigContext); + const configModel: ConfigModel = new this.dependencies.modelGenerator(userConfig, userCore, userRules, allDefaultRules, relevantEngines); const fileWritten: boolean = this.dependencies.writer ? await this.dependencies.writer.write(configModel) diff --git a/src/lib/models/ConfigModel.ts b/src/lib/models/ConfigModel.ts index d9465574f..0893e3635 100644 --- a/src/lib/models/ConfigModel.ts +++ b/src/lib/models/ConfigModel.ts @@ -21,50 +21,48 @@ export interface ConfigModel { toFormattedOutput(format: OutputFormat): string; } -export type ConfigContext = { - config: CodeAnalyzerConfig; - core: CodeAnalyzer; - rules: RuleSelection; -} - -export type ConfigModelGeneratorFunction = (relevantEngines: Set, userContext: ConfigContext, defaultContext: ConfigContext) => ConfigModel; +export type ConfigModelConstructor = new (config: CodeAnalyzerConfig, codeAnalyzer: CodeAnalyzer, userRules: RuleSelection, allDefaultRules: RuleSelection, relevantEngines: Set) => ConfigModel; export class AnnotatedConfigModel implements ConfigModel { - private readonly relevantEngines: Set; - private readonly userContext: ConfigContext; - private readonly defaultContext: ConfigContext; - - private constructor(relevantEngines: Set, userContext: ConfigContext, defaultContext: ConfigContext) { + private readonly config: CodeAnalyzerConfig; // TODO: It would be nice if we updated the CodeAnalyzer (in our core module) to just return its CodeAnalyzerConfig with a getter so we didn't need to pass it around + private readonly codeAnalyzer: CodeAnalyzer; + private readonly userRules: RuleSelection; + private readonly allDefaultRules: RuleSelection; + private readonly relevantEngines: Set; + + constructor(config: CodeAnalyzerConfig, codeAnalyzer: CodeAnalyzer, userRules: RuleSelection, allDefaultRules: RuleSelection, relevantEngines: Set) { + this.config = config; + this.codeAnalyzer = codeAnalyzer; + this.userRules = userRules; + this.allDefaultRules = allDefaultRules; this.relevantEngines = relevantEngines; - this.userContext = userContext; - this.defaultContext = defaultContext; } toFormattedOutput(format: OutputFormat): string { // istanbul ignore else: Should be impossible if (format === OutputFormat.STYLED_YAML) { - return new StyledYamlFormatter(this.relevantEngines, this.userContext, this.defaultContext).toYaml(); + return new StyledYamlFormatter(this.config, this.codeAnalyzer, this.userRules, this.allDefaultRules, this.relevantEngines).toYaml(); } else if (format === OutputFormat.RAW_YAML) { - return new PlainYamlFormatter(this.relevantEngines, this.userContext, this.defaultContext).toYaml(); + return new PlainYamlFormatter(this.config, this.codeAnalyzer, this.userRules, this.allDefaultRules, this.relevantEngines).toYaml(); } else { throw new Error(`Unsupported`) } } - - public static fromSelection(relevantEngines: Set, userContext: ConfigContext, defaultContext: ConfigContext): AnnotatedConfigModel { - return new AnnotatedConfigModel(relevantEngines, userContext, defaultContext); - } } abstract class YamlFormatter { + private readonly config: CodeAnalyzerConfig; + private readonly codeAnalyzer: CodeAnalyzer; + private readonly userRules: RuleSelection; + private readonly allDefaultRules: RuleSelection; private readonly relevantEngines: Set; - private readonly userContext: ConfigContext; - private readonly defaultContext: ConfigContext; - protected constructor(relevantEngines: Set, userContext: ConfigContext, defaultContext: ConfigContext) { + protected constructor(config: CodeAnalyzerConfig, codeAnalyzer: CodeAnalyzer, userRules: RuleSelection, allDefaultRules: RuleSelection, relevantEngines: Set) { + this.config = config; + this.codeAnalyzer = codeAnalyzer; + this.userRules = userRules; + this.allDefaultRules = allDefaultRules; this.relevantEngines = relevantEngines; - this.userContext = userContext; - this.defaultContext = defaultContext; } protected abstract toYamlComment(commentText: string): string @@ -109,20 +107,20 @@ abstract class YamlFormatter { } const commentText: string = getMessage(BundleName.ConfigModel, 'template.modified-from', [defaultValueJson]); - resolvedValue = replaceAbsolutePathsWithRelativePathsWherePossible(resolvedValue, this.userContext.config.getConfigRoot() + path.sep); + resolvedValue = replaceAbsolutePathsWithRelativePathsWherePossible(resolvedValue, this.config.getConfigRoot() + path.sep); return this.toYamlUncheckedFieldWithInlineComment(fieldName, resolvedValue, commentText); } toYaml(): string { - const topLevelDescription: ConfigDescription = this.userContext.config.getConfigDescription(); + const topLevelDescription: ConfigDescription = this.config.getConfigDescription(); return this.toYamlSectionHeadingComment(topLevelDescription.overview) + '\n' + '\n' + this.toYamlComment(topLevelDescription.fieldDescriptions.config_root.descriptionText) + '\n' + - this.toYamlFieldUsingFieldDescription('config_root', this.userContext.config.getConfigRoot(), + this.toYamlFieldUsingFieldDescription('config_root', this.config.getConfigRoot(), topLevelDescription.fieldDescriptions.config_root) + '\n' + '\n' + this.toYamlComment(topLevelDescription.fieldDescriptions.log_folder.descriptionText) + '\n' + - this.toYamlFieldUsingFieldDescription('log_folder', this.userContext.config.getLogFolder(), + this.toYamlFieldUsingFieldDescription('log_folder', this.config.getLogFolder(), topLevelDescription.fieldDescriptions.log_folder) + '\n' + '\n' + this.toYamlComment(topLevelDescription.fieldDescriptions.rules.descriptionText) + '\n' + @@ -135,13 +133,13 @@ abstract class YamlFormatter { } private toYamlRuleOverrides(): string { - if (this.userContext.rules.getCount() === 0) { + if (this.userRules.getCount() === 0) { const commentText: string = getMessage(BundleName.ConfigModel, 'template.yaml.no-rules-selected'); return `rules: {} ${this.toYamlComment(commentText)}`; } let yamlCode: string = 'rules:\n'; - for (const engineName of this.userContext.rules.getEngineNames()) { + for (const engineName of this.userRules.getEngineNames()) { yamlCode += '\n'; yamlCode += indent(this.toYamlRuleOverridesForEngine(engineName), 2) + '\n'; } @@ -153,7 +151,7 @@ abstract class YamlFormatter { [engineName.toUpperCase()]); let yamlCode: string = this.toYamlSectionHeadingComment(engineConfigHeader) + '\n'; yamlCode += `${engineName}:\n`; - for (const userRule of this.userContext.rules.getRulesFor(engineName)) { + for (const userRule of this.userRules.getRulesFor(engineName)) { const defaultRule: Rule|null = this.getDefaultRuleFor(engineName, userRule.getName()); yamlCode += indent(this.toYamlRuleOverridesForRule(userRule, defaultRule), 2) + '\n'; } @@ -162,7 +160,7 @@ abstract class YamlFormatter { private getDefaultRuleFor(engineName: string, ruleName: string): Rule|null { try { - return this.defaultContext.rules.getRule(engineName, ruleName); + return this.allDefaultRules.getRule(engineName, ruleName); } catch (e) { // istanbul ignore next return null; @@ -191,8 +189,8 @@ abstract class YamlFormatter { } private toYamlEngineOverridesForEngine(engineName: string): string { - const engineConfigDescriptor: ConfigDescription = this.userContext.core.getEngineConfigDescription(engineName); - const userEngineConfig: EngineConfig = this.userContext.core.getEngineConfig(engineName); + const engineConfigDescriptor: ConfigDescription = this.codeAnalyzer.getEngineConfigDescription(engineName); + const userEngineConfig: EngineConfig = this.codeAnalyzer.getEngineConfig(engineName); let yamlCode: string = '\n' + this.toYamlSectionHeadingComment(engineConfigDescriptor.overview) + '\n' + @@ -212,8 +210,8 @@ abstract class YamlFormatter { } class PlainYamlFormatter extends YamlFormatter { - constructor(relevantEngines: Set, userContext: ConfigContext, defaultContext: ConfigContext) { - super(relevantEngines, userContext, defaultContext); + constructor(config: CodeAnalyzerConfig, codeAnalyzer: CodeAnalyzer, userRules: RuleSelection, allDefaultRules: RuleSelection, relevantEngines: Set) { + super(config, codeAnalyzer, userRules, allDefaultRules, relevantEngines); } protected toYamlComment(commentText: string): string { @@ -222,8 +220,8 @@ class PlainYamlFormatter extends YamlFormatter { } class StyledYamlFormatter extends YamlFormatter { - constructor(relevantEngines: Set, userContext: ConfigContext, defaultContext: ConfigContext) { - super(relevantEngines, userContext, defaultContext); + constructor(config: CodeAnalyzerConfig, codeAnalyzer: CodeAnalyzer, userRules: RuleSelection, allDefaultRules: RuleSelection, relevantEngines: Set) { + super(config, codeAnalyzer, userRules, allDefaultRules, relevantEngines); } protected toYamlComment(commentText: string): string { diff --git a/test/lib/actions/ConfigAction.test.ts b/test/lib/actions/ConfigAction.test.ts index bf9bd36e2..b173b8387 100644 --- a/test/lib/actions/ConfigAction.test.ts +++ b/test/lib/actions/ConfigAction.test.ts @@ -37,7 +37,7 @@ describe('ConfigAction tests', () => { progressEventListeners: [], viewer: new ConfigStyledYamlViewer(spyDisplay), configFactory: new DefaultStubCodeAnalyzerConfigFactory(), - modelGenerator: AnnotatedConfigModel.fromSelection, + modelGenerator: AnnotatedConfigModel, actionSummaryViewer: new ConfigActionSummaryViewer(spyDisplay), pluginsFactory: new StubEnginePluginFactory() }; @@ -164,7 +164,7 @@ describe('ConfigAction tests', () => { progressEventListeners: [], viewer: new ConfigStyledYamlViewer(spyDisplay), configFactory: stubConfigFactory, - modelGenerator: AnnotatedConfigModel.fromSelection, + modelGenerator: AnnotatedConfigModel, actionSummaryViewer: new ConfigActionSummaryViewer(spyDisplay), pluginsFactory: new StubEnginePluginFactory() }; @@ -397,7 +397,7 @@ describe('ConfigAction tests', () => { progressEventListeners: [], viewer: new ConfigStyledYamlViewer(spyDisplay), configFactory: new DefaultStubCodeAnalyzerConfigFactory(), - modelGenerator: AnnotatedConfigModel.fromSelection, + modelGenerator: AnnotatedConfigModel, actionSummaryViewer: new ConfigActionSummaryViewer(spyDisplay), pluginsFactory: new StubEnginePluginFactory() }; @@ -446,7 +446,7 @@ describe('ConfigAction tests', () => { progressEventListeners: [], viewer: new ConfigStyledYamlViewer(spyDisplay), configFactory: new DefaultStubCodeAnalyzerConfigFactory(), - modelGenerator: AnnotatedConfigModel.fromSelection, + modelGenerator: AnnotatedConfigModel, actionSummaryViewer: new ConfigActionSummaryViewer(spyDisplay), pluginsFactory: new StubEnginePluginFactory() } From 219e83a03b122d31cb28f47e753ebe99c394cbd7 Mon Sep 17 00:00:00 2001 From: Stephen Carter Date: Thu, 5 Dec 2024 15:24:55 -0500 Subject: [PATCH 21/35] Final polish --- src/commands/code-analyzer/config.ts | 2 -- src/lib/actions/ConfigAction.ts | 5 ++--- src/lib/models/ConfigModel.ts | 14 +++++++++----- test/lib/actions/ConfigAction.test.ts | 5 ----- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/commands/code-analyzer/config.ts b/src/commands/code-analyzer/config.ts index e5249cc88..e53bf4cd2 100644 --- a/src/commands/code-analyzer/config.ts +++ b/src/commands/code-analyzer/config.ts @@ -8,7 +8,6 @@ import {EnginePluginsFactoryImpl} from '../../lib/factories/EnginePluginsFactory import {BundleName, getMessage, getMessages} from '../../lib/messages'; import {LogEventDisplayer} from '../../lib/listeners/LogEventListener'; import {RuleSelectionProgressSpinner} from '../../lib/listeners/ProgressEventListener'; -import {AnnotatedConfigModel} from '../../lib/models/ConfigModel'; import {Displayable, UxDisplay} from '../../lib/Display'; export default class ConfigCommand extends SfCommand implements Displayable { @@ -67,7 +66,6 @@ export default class ConfigCommand extends SfCommand implements Displayabl pluginsFactory: new EnginePluginsFactoryImpl(), logEventListeners: [new LogEventDisplayer(uxDisplay)], progressEventListeners: [new RuleSelectionProgressSpinner(uxDisplay)], - modelGenerator: AnnotatedConfigModel, actionSummaryViewer: new ConfigActionSummaryViewer(uxDisplay), viewer: new ConfigStyledYamlViewer(uxDisplay) }; diff --git a/src/lib/actions/ConfigAction.ts b/src/lib/actions/ConfigAction.ts index 81ea17f6c..f52bf24f2 100644 --- a/src/lib/actions/ConfigAction.ts +++ b/src/lib/actions/ConfigAction.ts @@ -8,12 +8,11 @@ import {createWorkspace} from '../utils/WorkspaceUtil'; import {LogEventListener, LogEventLogger} from '../listeners/LogEventListener'; import {ProgressEventListener} from '../listeners/ProgressEventListener'; import {ConfigActionSummaryViewer} from '../viewers/ActionSummaryViewer'; -import {ConfigModel, ConfigModelConstructor} from '../models/ConfigModel'; +import {AnnotatedConfigModel, ConfigModel} from '../models/ConfigModel'; export type ConfigDependencies = { configFactory: CodeAnalyzerConfigFactory; pluginsFactory: EnginePluginsFactory; - modelGenerator: ConfigModelConstructor; logEventListeners: LogEventListener[]; progressEventListeners: ProgressEventListener[]; writer?: ConfigWriter; @@ -109,7 +108,7 @@ export class ConfigAction { // We need the Set of all Engines that returned rules for the user's selection on both the Default and User Cores. const relevantEngines: Set = new Set([...userRules.getEngineNames(), ...selectedDefaultRules.getEngineNames()]); - const configModel: ConfigModel = new this.dependencies.modelGenerator(userConfig, userCore, userRules, allDefaultRules, relevantEngines); + const configModel: ConfigModel = new AnnotatedConfigModel(userConfig, userCore, userRules, allDefaultRules, relevantEngines); const fileWritten: boolean = this.dependencies.writer ? await this.dependencies.writer.write(configModel) diff --git a/src/lib/models/ConfigModel.ts b/src/lib/models/ConfigModel.ts index 0893e3635..a8557893f 100644 --- a/src/lib/models/ConfigModel.ts +++ b/src/lib/models/ConfigModel.ts @@ -2,7 +2,8 @@ import {dump as yamlDump} from 'js-yaml'; import { CodeAnalyzer, CodeAnalyzerConfig, - ConfigDescription, ConfigFieldDescription, + ConfigDescription, + ConfigFieldDescription, EngineConfig, Rule, RuleSelection, @@ -21,13 +22,16 @@ export interface ConfigModel { toFormattedOutput(format: OutputFormat): string; } -export type ConfigModelConstructor = new (config: CodeAnalyzerConfig, codeAnalyzer: CodeAnalyzer, userRules: RuleSelection, allDefaultRules: RuleSelection, relevantEngines: Set) => ConfigModel; - export class AnnotatedConfigModel implements ConfigModel { private readonly config: CodeAnalyzerConfig; // TODO: It would be nice if we updated the CodeAnalyzer (in our core module) to just return its CodeAnalyzerConfig with a getter so we didn't need to pass it around private readonly codeAnalyzer: CodeAnalyzer; private readonly userRules: RuleSelection; private readonly allDefaultRules: RuleSelection; + + // Note that it is important that we calculate the relevant engines list based on (the user rule selection with no + // config) plus (user rule selection with user config) since we still want to show the "disable_engine" config value + // in the output if a user even if selects an engine that is currently disabled. But we don't want to the engine + // configs not associated with the user's rule selection, thus we can't use the engines from allDefaultRules. private readonly relevantEngines: Set; constructor(config: CodeAnalyzerConfig, codeAnalyzer: CodeAnalyzer, userRules: RuleSelection, allDefaultRules: RuleSelection, relevantEngines: Set) { @@ -199,11 +203,11 @@ abstract class YamlFormatter { // assume that the object is not undefined. for (const configField of Object.keys(engineConfigDescriptor.fieldDescriptions)) { const fieldDescription: ConfigFieldDescription = engineConfigDescriptor.fieldDescriptions[configField]; - const userValue = userEngineConfig[configField] ?? fieldDescription.defaultValue; + const resolvedValue = userEngineConfig[configField] ?? fieldDescription.defaultValue; // Add a leading newline to visually break up the property from the previous one. yamlCode += '\n' + indent(this.toYamlComment(fieldDescription.descriptionText), 2) + '\n' + - indent(this.toYamlFieldUsingFieldDescription(configField, userValue, fieldDescription), 2) + '\n'; + indent(this.toYamlFieldUsingFieldDescription(configField, resolvedValue, fieldDescription), 2) + '\n'; } return yamlCode.trimEnd(); } diff --git a/test/lib/actions/ConfigAction.test.ts b/test/lib/actions/ConfigAction.test.ts index b173b8387..4381b03e2 100644 --- a/test/lib/actions/ConfigAction.test.ts +++ b/test/lib/actions/ConfigAction.test.ts @@ -8,7 +8,6 @@ import * as EngineApi from "@salesforce/code-analyzer-engine-api"; import {CodeAnalyzerConfigFactory} from "../../../src/lib/factories/CodeAnalyzerConfigFactory"; import {EnginePluginsFactory} from '../../../src/lib/factories/EnginePluginsFactory'; import {ConfigAction, ConfigDependencies, ConfigInput} from '../../../src/lib/actions/ConfigAction'; -import {AnnotatedConfigModel} from '../../../src/lib/models/ConfigModel'; import {ConfigStyledYamlViewer} from '../../../src/lib/viewers/ConfigViewer'; import {ConfigActionSummaryViewer} from '../../../src/lib/viewers/ActionSummaryViewer'; @@ -37,7 +36,6 @@ describe('ConfigAction tests', () => { progressEventListeners: [], viewer: new ConfigStyledYamlViewer(spyDisplay), configFactory: new DefaultStubCodeAnalyzerConfigFactory(), - modelGenerator: AnnotatedConfigModel, actionSummaryViewer: new ConfigActionSummaryViewer(spyDisplay), pluginsFactory: new StubEnginePluginFactory() }; @@ -164,7 +162,6 @@ describe('ConfigAction tests', () => { progressEventListeners: [], viewer: new ConfigStyledYamlViewer(spyDisplay), configFactory: stubConfigFactory, - modelGenerator: AnnotatedConfigModel, actionSummaryViewer: new ConfigActionSummaryViewer(spyDisplay), pluginsFactory: new StubEnginePluginFactory() }; @@ -397,7 +394,6 @@ describe('ConfigAction tests', () => { progressEventListeners: [], viewer: new ConfigStyledYamlViewer(spyDisplay), configFactory: new DefaultStubCodeAnalyzerConfigFactory(), - modelGenerator: AnnotatedConfigModel, actionSummaryViewer: new ConfigActionSummaryViewer(spyDisplay), pluginsFactory: new StubEnginePluginFactory() }; @@ -446,7 +442,6 @@ describe('ConfigAction tests', () => { progressEventListeners: [], viewer: new ConfigStyledYamlViewer(spyDisplay), configFactory: new DefaultStubCodeAnalyzerConfigFactory(), - modelGenerator: AnnotatedConfigModel, actionSummaryViewer: new ConfigActionSummaryViewer(spyDisplay), pluginsFactory: new StubEnginePluginFactory() } From a8be7472204857bb75a3151c1fd0dac0dbee3cd3 Mon Sep 17 00:00:00 2001 From: Stephen Carter Date: Thu, 5 Dec 2024 15:59:22 -0500 Subject: [PATCH 22/35] Simplify comments for config based fields --- src/lib/models/ConfigModel.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib/models/ConfigModel.ts b/src/lib/models/ConfigModel.ts index a8557893f..90f3b45c3 100644 --- a/src/lib/models/ConfigModel.ts +++ b/src/lib/models/ConfigModel.ts @@ -86,20 +86,23 @@ abstract class YamlFormatter { return yamlCode.replace(/(\r?\n|$)/, ` ${comment}$1`); } - private toYamlFieldUsingFieldDescription(fieldName: string, resolvedValue: unknown, fieldDescription: ConfigFieldDescription): string { + private toYamlFieldWithFieldDescription(fieldName: string, resolvedValue: unknown, fieldDescription: ConfigFieldDescription): string { const resolvedValueJson: string = JSON.stringify(resolvedValue); const defaultValueJson: string = JSON.stringify(fieldDescription.defaultValue); + let yamlField: string; if (!fieldDescription.wasSuppliedByUser && resolvedValueJson !== defaultValueJson) { // Whenever the user did not supply the value themselves but the resolved value is different from the // default value, this means the value was not a "fixed" value but a value "calculated" at runtime. // Since "calculated" values often depend on the specific environment, we do not want to actually hard code // this value into the config since checking in the config to CI/CD system may create a different value. const commentText: string = getMessage(BundleName.ConfigModel, 'template.last-calculated-as', [resolvedValueJson]); - return this.toYamlUncheckedFieldWithInlineComment(fieldName, fieldDescription.defaultValue, commentText); + yamlField = this.toYamlUncheckedFieldWithInlineComment(fieldName, fieldDescription.defaultValue, commentText); + } else { + yamlField = this.toYamlField(fieldName, resolvedValue, fieldDescription.defaultValue); } - return this.toYamlField(fieldName, resolvedValue, fieldDescription.defaultValue); + return this.toYamlComment(fieldDescription.descriptionText) + "\n" + yamlField } private toYamlField(fieldName: string, resolvedValue: unknown, defaultValue: unknown): string { @@ -119,12 +122,10 @@ abstract class YamlFormatter { const topLevelDescription: ConfigDescription = this.config.getConfigDescription(); return this.toYamlSectionHeadingComment(topLevelDescription.overview) + '\n' + '\n' + - this.toYamlComment(topLevelDescription.fieldDescriptions.config_root.descriptionText) + '\n' + - this.toYamlFieldUsingFieldDescription('config_root', this.config.getConfigRoot(), + this.toYamlFieldWithFieldDescription('config_root', this.config.getConfigRoot(), topLevelDescription.fieldDescriptions.config_root) + '\n' + '\n' + - this.toYamlComment(topLevelDescription.fieldDescriptions.log_folder.descriptionText) + '\n' + - this.toYamlFieldUsingFieldDescription('log_folder', this.config.getLogFolder(), + this.toYamlFieldWithFieldDescription('log_folder', this.config.getLogFolder(), topLevelDescription.fieldDescriptions.log_folder) + '\n' + '\n' + this.toYamlComment(topLevelDescription.fieldDescriptions.rules.descriptionText) + '\n' + @@ -206,8 +207,7 @@ abstract class YamlFormatter { const resolvedValue = userEngineConfig[configField] ?? fieldDescription.defaultValue; // Add a leading newline to visually break up the property from the previous one. yamlCode += '\n' + - indent(this.toYamlComment(fieldDescription.descriptionText), 2) + '\n' + - indent(this.toYamlFieldUsingFieldDescription(configField, resolvedValue, fieldDescription), 2) + '\n'; + indent(this.toYamlFieldWithFieldDescription(configField, resolvedValue, fieldDescription), 2) + '\n'; } return yamlCode.trimEnd(); } From abbf92688340023ea66cd8b22b87a2dbfae229f7 Mon Sep 17 00:00:00 2001 From: Stephen Carter Date: Thu, 5 Dec 2024 16:05:58 -0500 Subject: [PATCH 23/35] FIX --- test/lib/actions/ConfigAction.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/lib/actions/ConfigAction.test.ts b/test/lib/actions/ConfigAction.test.ts index 4381b03e2..d3074951e 100644 --- a/test/lib/actions/ConfigAction.test.ts +++ b/test/lib/actions/ConfigAction.test.ts @@ -264,8 +264,8 @@ describe('ConfigAction tests', () => { const goldFileContents = (await readGoldFile(path.join(PATH_TO_COMPARISON_DIR, 'derivables-as-non-defaults', `${prop}.yml.goldfile`))) .replace('__DUMMY_CONFIG_ROOT__', parentOfCurrentDirectory) .replace('__DUMMY_LOG_FOLDER__', parentOfCurrentDirectory) - .replace('__DUMMY_DEFAULT_CONFIG_ROOT__', JSON.stringify(null)) - .replace('__DUMMY_DEFAULT_LOG_FOLDER__', JSON.stringify(null)) + .replace('__DUMMY_DEFAULT_CONFIG_ROOT__', 'null') + .replace('__DUMMY_DEFAULT_LOG_FOLDER__', 'null') expect(output).toContain(goldFileContents); }); From d06b633c2b2b58f4cece45cd327789e528061331 Mon Sep 17 00:00:00 2001 From: Josh Feingold Date: Thu, 5 Dec 2024 15:28:30 -0600 Subject: [PATCH 24/35] @W-17159591@ Enabled SARIF output format (#1690) --- src/lib/writers/ResultsWriter.ts | 2 +- test/lib/writers/ResultsWriter.test.ts | 18 ++---------------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/lib/writers/ResultsWriter.ts b/src/lib/writers/ResultsWriter.ts index 0f6acf073..3d3685977 100644 --- a/src/lib/writers/ResultsWriter.ts +++ b/src/lib/writers/ResultsWriter.ts @@ -35,7 +35,7 @@ export class ResultsFileWriter implements ResultsWriter { } else if (['.html', '.htm'].includes(ext)) { this.format = OutputFormat.HTML; } else if (ext === '.sarif' || file.toLowerCase().endsWith('.sarif.json')) { - throw new Error('TODO: Support SARIF-type output'); + this.format = OutputFormat.SARIF; // Check for `.json` AFTER checking for `.sarif.json`! } else if (ext === '.json') { this.format = OutputFormat.JSON; diff --git a/test/lib/writers/ResultsWriter.test.ts b/test/lib/writers/ResultsWriter.test.ts index b8f2ca632..c85380bf2 100644 --- a/test/lib/writers/ResultsWriter.test.ts +++ b/test/lib/writers/ResultsWriter.test.ts @@ -23,8 +23,8 @@ describe('ResultsWriter implementations', () => { {ext: '.html', expectedOutput: `Results formatted as ${OutputFormat.HTML}`}, {ext: '.htm', expectedOutput: `Results formatted as ${OutputFormat.HTML}`}, {ext: '.json', expectedOutput: `Results formatted as ${OutputFormat.JSON}`}, - //{ext: '.sarif', expectedOutput: `Results formatted as ${OutputFormat.SARIF}`}, - //{ext: '.sarif.json', expectedOutput: `Results formatted as ${OutputFormat.SARIF}`}, + {ext: '.sarif', expectedOutput: `Results formatted as ${OutputFormat.SARIF}`}, + {ext: '.sarif.json', expectedOutput: `Results formatted as ${OutputFormat.SARIF}`}, {ext: '.xml', expectedOutput: `Results formatted as ${OutputFormat.XML}`} ])('Accepts and outputs valid file format: *$ext', ({ext, expectedOutput}) => { const validFile = `beep${ext}`; @@ -40,20 +40,6 @@ describe('ResultsWriter implementations', () => { }]); }); - /** - * All of these extensions are ones we intend to support long-term, but don't yet. When we add support for one of - * these extensions, we should remove it from the cases array here and uncomment the corresponding line - * in the case array for the valid format tests. - */ - it.each([ - {ext: '.sarif'}, - {ext: '.sarif.json'} - ])('Throws TODO error for not-yet-supported format: *$ext', ({ext}) => { - const notYetSupportedFile = `beep${ext}`; - // Expect the error message to include an indication that the functionality will be implemented eventually. - expect(() => new ResultsFileWriter(notYetSupportedFile)).toThrow('TODO'); - }); - it('Writes file even when results are empty', () => { const expectations = { file: 'beep.csv', From c4b9e645c728b1586cb6645c0e1522cdfea731ed Mon Sep 17 00:00:00 2001 From: Josh Feingold Date: Thu, 12 Dec 2024 13:21:06 -0600 Subject: [PATCH 25/35] @W-17312010@ Preparing dev-5 to replace dev as v5 home branch (#1696) --- .github/workflows/automated-release-tasks.yml | 63 ++++++++ .github/workflows/create-github-release.yml | 10 +- .github/workflows/create-release-branch.yml | 6 +- .github/workflows/daily-smoke-tests.yml | 14 ++ .github/workflows/production-heartbeat.yml | 145 ++---------------- .github/workflows/publish-to-npm.yml | 36 ++--- .github/workflows/validate-pr.yml | 8 +- github-actions/verify-pr-title/dist/index.js | 2 +- github-actions/verify-pr-title/src/index.ts | 2 +- 9 files changed, 120 insertions(+), 166 deletions(-) create mode 100644 .github/workflows/automated-release-tasks.yml diff --git a/.github/workflows/automated-release-tasks.yml b/.github/workflows/automated-release-tasks.yml new file mode 100644 index 000000000..726f0f49b --- /dev/null +++ b/.github/workflows/automated-release-tasks.yml @@ -0,0 +1,63 @@ +name: automated-release-tasks +on: + schedule: + # Cron syntax is "minute[0-59] hour[0-23] date[1-31] month[1-12] day[0-6]". '*' is 'any value,' and multiple values + # can be specified with comma-separated lists. All times are UTC. + # So this expression means "run at 12 PM UTC, every Friday". + - cron: "0 12 * * 5" + + +jobs: + # Depending on circumstances, we may want to exit early instead of running the workflow to completion. + verify-should-run: + runs-on: macos-latest + outputs: + should-run: ${{ steps.main.outputs.should_run }} + steps: + - id: main + run: | + # `date -u` returns UTC datetime, and `%u` formats the output to be the day of the week, with 1 being Monday, + # 2 being Tuesday, etc. + TODAY_DOW=$(date -u +%u) + # This `date` expression returns the last Tuesday of the month, which is our Release Day. %d formats the output + # as the day of the month (1-31). + NEXT_RELEASE_DATE=$(date -u -v1d -v+1m -v-1d -v-tue +%d) + # This `date` expression returns next Tuesday, and `%d` formats the output as the day of the month (1-31). + NEXT_TUESDAY_DATE=$(date -u -v+tue +%d) + # This workflow should only be allowed to run to completion on the Friday before Release Day. + [[ $TODAY_DOW != 5 || $NEXT_RELEASE_DATE != $NEXT_TUESDAY_DATE ]] && echo "should_run=false" >> "$GITHUB_OUTPUT" || echo "should_run=true" >> "$GITHUB_OUTPUT" + create-v5-release-branch: + runs-on: macos-latest + needs: verify-should-run + if: ${{ needs.verify-should-run.outputs.should-run == 'true' }} + steps: + - name: Invoke v5 beta workflow + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.SVC_CLI_BOT_GITHUB_TOKEN }} + script: | + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'create-release-branch.yml', + ref: 'dev' + }); + create-v4-release-branch: + runs-on: macos-latest + needs: verify-should-run + if: ${{ needs.verify-should-run.outputs.should-run == 'true' }} + steps: + - name: Invoke v4 GA workflow + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.SVC_CLI_BOT_GITHUB_TOKEN }} + script: | + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'create-release-branch.yml', + ref: 'dev-4', + inputs: { + "release-type": "minor" + } + }); diff --git a/.github/workflows/create-github-release.yml b/.github/workflows/create-github-release.yml index b8368b57d..1be0f5aae 100644 --- a/.github/workflows/create-github-release.yml +++ b/.github/workflows/create-github-release.yml @@ -2,7 +2,7 @@ name: create-github-release on: pull_request: branches: - - main-5 + - main types: # There's no event type for "merged", so we just run any time a PR is closed, and exit early # if the PR wasn't actually merged. @@ -10,7 +10,7 @@ on: jobs: create-github-release: - # Since the workflow runs any time a PR against main-5 is closed, we need this + # Since the workflow runs any time a PR against main is closed, we need this # `if` to make sure that the workflow only does anything meaningful if the PR # was actually merged. if: github.event.pull_request.merged == true @@ -18,10 +18,10 @@ jobs: permissions: contents: write steps: - - name: Checkout main-5 + - name: Checkout main uses: actions/checkout@v4 with: - ref: main-5 + ref: main - name: Get version property id: get-version-property run: | @@ -32,7 +32,7 @@ jobs: with: tag_name: v${{ steps.get-version-property.outputs.package_version }} name: v${{ steps.get-version-property.outputs.package_version }} - target_commitish: main-5 + target_commitish: main body: See [release notes](https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/guide/release-notes.html) token: ${{ secrets.SVC_CLI_BOT_GITHUB_TOKEN }} make_latest: true diff --git a/.github/workflows/create-release-branch.yml b/.github/workflows/create-release-branch.yml index 4007ef6b5..8f41a9b8a 100644 --- a/.github/workflows/create-release-branch.yml +++ b/.github/workflows/create-release-branch.yml @@ -12,10 +12,10 @@ jobs: outputs: branch-name: ${{ steps.create-branch.outputs.branch_name }} steps: - # Checkout `dev-5` + # Checkout `dev` - uses: actions/checkout@v4 with: - ref: 'dev-5' + ref: 'dev' # We need to set up Node and install our Node dependencies. - uses: actions/setup-node@v4 with: @@ -24,7 +24,7 @@ jobs: # Increment the version as desired locally, without actually committing anything. - name: Locally increment version run: | - npm --no-git-tag-version version prerelease --preid alpha + npm --no-git-tag-version version prerelease --preid beta # The branch protection rule for `release-x.y.z` branches prevents pushing commits directly. To work around this, # we create an interim branch that we _can_ push commits to, and we'll do our version bookkeeping in that branch # instead. diff --git a/.github/workflows/daily-smoke-tests.yml b/.github/workflows/daily-smoke-tests.yml index 9a0f0099d..16f0ada10 100644 --- a/.github/workflows/daily-smoke-tests.yml +++ b/.github/workflows/daily-smoke-tests.yml @@ -12,3 +12,17 @@ jobs: uses: ./.github/workflows/run-tests.yml with: node-matrix: "[{version: 'lts/*', artifact: 'lts'}, {version: 'latest', artifact: 'latest'}]" + v4-smoke-test: + runs-on: macos-latest + steps: + - name: Invoke v4 smoke tests + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.SVC_CLI_BOT_GITHUB_TOKEN }} + script: | + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'daily-smoke-tests.yml', + ref: 'dev-4' + }); diff --git a/.github/workflows/production-heartbeat.yml b/.github/workflows/production-heartbeat.yml index b72143bf4..5b4842514 100644 --- a/.github/workflows/production-heartbeat.yml +++ b/.github/workflows/production-heartbeat.yml @@ -10,139 +10,16 @@ on: - cron: '45 13,17,21 * * 1,2,3,4,5' jobs: production-heartbeat: - strategy: - # By default, if any job in a matrix fails, all other jobs are immediately cancelled. This makes the jobs run to completion instead. - fail-fast: false - matrix: - os: [{vm: ubuntu-latest, exe: .sh}, {vm: windows-2019, exe: .cmd}] - node: ['lts/*'] - runs-on: ${{ matrix.os.vm }} - timeout-minutes: 60 + runs-on: macos-latest steps: - # === Setup. We need to get the code, set up nodejs, and create the results directory. === - - uses: actions/checkout@v4 + - name: Invoke v4 workflow + uses: actions/github-script@v6 with: - ref: 'release' - - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node }} - - run: mkdir smoke-test-results - - # === Set our environment variables, either using default values or the repo's secrets === - - name: Set environment variables - id: env_var_setup - # We'll want to use bash for this, to avoid any cross-platform shenanigans - shell: bash - run: | - # In the following script, the use of the `echo "name=value" >> $GITHUB_ENV` structure is used to set/update - # environment variables. Such updates are visible to all subsequent steps. - # - # If the CLI_VERSION repo secret is set, we want to install that version ofsf-cli, so we set an environment - # variable. Otherwise, we leave the environment variable unset, so it implicitly defaults to `latest`. - # Note: This can be used to intentionally fail the GHA by providing an invalid version number. - if [[ -n "${{ secrets.CLI_VERSION }}" ]]; then - echo "CLI_VERSION=@${{ secrets.CLI_VERSION}}" >> $GITHUB_ENV - fi - # If the SCANNER_VERSION repo secret is set, we want to install that version of sfdx-scanner, so we set an - # environment variable. Otherwise, we leave the environment variable unset, so it implicitly defaults to `latest`. - # Note: This can be used to intentionally fail the GHA by providing an invalid version number. - if [[ -n "${{ secrets.SCANNER_VERSION }}" ]]; then - echo "SCANNER_VERSION=@${{ secrets.SCANNER_VERSION }}" >> $GITHUB_ENV - fi - # If the FAIL_SMOKE_TESTS repo secret is set to ANY value, we should respond by deleting the `test/test-jars` - # folder. The smoke tests expect this folder's contents to exist, so an invocation of `scanner:rule:add` should - # fail, thereby failing the smoke tests as a whole. - # Note: This serves no purpose aside from providing a way to simulate a smoke test failure. - if [[ -n "${{ secrets.FAIL_SMOKE_TESTS }}" ]]; then - rm -rf ./test/test-jars - fi - - - # === Make three attempts to install SF through npm === - - name: Install SF - id: sf_install - # If the first attempt fails, wait a minute and try again. After a second failure, wait 5 minutes then try again. Then give up. - # Set an output parameter, `retry_count`, indicating the number of retry attempts that were made. - run: | - (echo "::set-output name=retry_count::0" && npm install -g @salesforce/cli${{ env.CLI_VERSION }}) || - (echo "::set-output name=retry_count::1" && sleep 60 && npm install -g @salesforce/cli${{ env.CLI_VERSION }}) || - (echo "::set-output name=retry_count::2" && sleep 300 && npm install -g @salesforce/cli${{ env.CLI_VERSION }}) - - # === Make three attempts to install the scanner plugin through sf === - - name: Install Scanner Plugin - id: scanner_install - # If the first attempt fails, wait a minute and try again. After a second failure, wait 5 minutes then try again. Then give up. - # Set an output parameter, `retry_count`, indicating the number of retry attempts that were made. - run: | - (echo "::set-output name=retry_count::0" && sf plugins install @salesforce/sfdx-scanner${{ env.SCANNER_VERSION }}) || - (echo "::set-output name=retry_count::1" && sleep 60 && sf plugins install @salesforce/sfdx-scanner${{ env.SCANNER_VERSION }}) || - (echo "::set-output name=retry_count::2" && sleep 300 && sf plugins install @salesforce/sfdx-scanner${{ env.SCANNER_VERSION }}) - - # === Log the installed plugins for easier debugging === - - name: Log plugins - run: sf plugins - - # === Attempt to execute the smoke tests === - - name: Run smoke tests - id: smoke_tests - run: smoke-tests/smoke-test${{ matrix.os.exe }} sf - - # === Upload the smoke-test-results folder as an artifact === - - name: Upload smoke-test-results folder as artifact - if: ${{ always() }} - uses: actions/upload-artifact@v4 - with: - name: smoke-test-results-${{ runner.os }} - path: smoke-test-results - - # === Report any problems === - - name: Report problems - # There are problems if any step failed or was skipped. - # Note that the `join()` call omits null values, so if any steps were skipped, they won't have a corresponding - # value in the string. - if: ${{ failure() || cancelled() }} - shell: bash - env: - # If we're here because steps failed or were skipped, then that's a critical problem. Otherwise it's a normal one. - # We can't use the `failure()` or `cancelled()` convenience methods outside of the `if` condition, hence the - # `contains()` calls. - IS_CRITICAL: ${{ contains(join(steps.*.outcome), 'failure') || contains(join(steps.*.outcome), 'skipped') }} - # Build the status strings for each step as environment variables to save space later. Null retry_count values - # will be replaced with `n/a` to maintain readability in the alert. - CLI_INSTALL_STATUS: ${{ steps.sf_install.outcome }} after ${{ steps.sf_install.outputs.retry_count || 'n/a' }} retries - SCANNER_INSTALL_STATUS: ${{ steps.scanner_install.outcome }} after ${{ steps.scanner_install.outputs.retry_count || 'n/a' }} retries - SMOKE_TESTS_STATUS: ${{ steps.smoke_tests.outcome }} - # A link to this run, so the PagerDuty assignee can quickly get here. - RUN_LINK: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - run: | - # GHA env-vars don't have robust conditional logic, so we'll use this if-else branch to define some bash env-vars. - if [[ ${{ env.IS_CRITICAL }} == true ]]; then - ALERT_SEV="critical" - ALERT_SUMMARY="Production heartbeat script failed on ${{ runner.os }}" - else - ALERT_SEV="info" - ALERT_SUMMARY="Production heartbeat script succeeded with retries on ${{ runner.os }}" - fi - # Define a helper function to create our POST request's data, to sidestep issues with nested quotations. - generate_post_data() { - # This is known as a HereDoc, and it lets us declare multi-line input ending when the specified limit string, - # in this case EOF, is encountered. - cat <> $GITHUB_OUTPUT id: get-branch-commit # Checkout the tag we want to release, and get its head commit as output for later. @@ -31,9 +31,9 @@ jobs: - name: Fail non-matching commits if: ${{ steps.get-branch-commit.outputs.COMMIT_ID != steps.get-tag-commit.outputs.COMMIT_ID }} run: | - echo "Tag commit must match latest commit in main-5. Branch is ${{ steps.get-branch-commit.outputs.COMMIT_ID }}. Tag is ${{ steps.get-tag-commit.outputs.COMMIT_ID }}" + echo "Tag commit must match latest commit in main. Branch is ${{ steps.get-branch-commit.outputs.COMMIT_ID }}. Tag is ${{ steps.get-tag-commit.outputs.COMMIT_ID }}" exit 1 - # Verify that the `package.json`'s version property is 5.Y.Z, as we want to restrict the `dev-5` and `main-5` + # Verify that the `package.json`'s version property is 5.Y.Z, as we want to restrict the `dev` and `main` # branches to publishing v5.x. - name: Verify major version run: | @@ -53,7 +53,7 @@ jobs: with: ctc: false # We've been told we don't have to care about this until someone makes us care. sign: true - tag: latest-alpha-rc # Publish as a release candidate, so we can do our validations against it. + tag: latest-beta-rc # Publish as a release candidate, so we can do our validations against it. githubTag: ${{ github.event.release.tag_name || inputs.tag }} secrets: inherit # Step 3: Run smoke tests against the release candidate. @@ -81,7 +81,7 @@ jobs: java-version: '11' # For now, Java version is hardcoded. # Install SF, and the release candidate version. - run: npm install -g @salesforce/cli - - run: sf plugins install @salesforce/plugin-code-analyzer@latest-alpha-rc + - run: sf plugins install @salesforce/plugin-code-analyzer@latest-beta-rc # Log the installed plugins for easier debugging. - run: sf plugins # Attempt to run the smoke tests. @@ -102,9 +102,9 @@ jobs: node-version: 'lts/*' - run: | echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc - npm dist-tag add @salesforce/plugin-code-analyzer@${{ github.event.release.tag_name || inputs.tag }} latest-alpha + npm dist-tag add @salesforce/plugin-code-analyzer@${{ github.event.release.tag_name || inputs.tag }} latest-beta npm dist-tag add @salesforce/plugin-code-analyzer@${{ github.event.release.tag_name || inputs.tag }} latest - # Step 5: Create a Pull Request for merging `main-5` into `dev-5` + # Step 5: Create a Pull Request for merging `main` into `dev` create-main2dev-pull-request: needs: promote-to-latest runs-on: macos-latest @@ -114,31 +114,31 @@ jobs: contents: write pull-requests: write steps: - # Check out `main-5` + # Check out `main` - uses: actions/checkout@v4 with: - ref: 'main-5' - # Create a new branch based on `main-5`, so that merge conflicts can be manually resolved if need be. + ref: 'main' + # Create a new branch based on `main`, so that merge conflicts can be manually resolved if need be. - run: | NEW_VERSION=$(jq -r ".version" package.json) git checkout -b m2d/v$NEW_VERSION git push --set-upstream origin m2d/v$NEW_VERSION - # Create a Pull Request from the new branch into `dev-5`. + # Create a Pull Request from the new branch into `dev`. - run: | NEW_VERSION=$(jq -r ".version" package.json) # For whatever reason, the version of 'echo' on GHAs doesn't process backspace by default. # The non-POSIX-standard -e flag causes it to do that. echo -e "This branch and PR were automatically created following the successful release of v$NEW_VERSION.\n\ - It must be MERGED into dev-5, NOT SQUASHED OR REBASED. Squashing or rebasing this branch onto dev-5 can cause potentially irreconcilable merge conflicts later.\n\ - As an additional safeguard and reminder, the title of this PR MUST include the word 'merging' in the description portion of the PR title, e.g., 'Main2Dev @W-XXXXXXX@ Merging main-5 to dev-5 after vX.Y.Z'.\n\ - If there are conflicts between dev-5 and this branch, you should do the following locally:\n\ - - $ git checkout dev-5\n\ + It must be MERGED into dev, NOT SQUASHED OR REBASED. Squashing or rebasing this branch onto dev can cause potentially irreconcilable merge conflicts later.\n\ + As an additional safeguard and reminder, the title of this PR MUST include the word 'merging' in the description portion of the PR title, e.g., 'Main2Dev @W-XXXXXXX@ Merging main to dev after vX.Y.Z'.\n\ + If there are conflicts between dev and this branch, you should do the following locally:\n\ + - $ git checkout dev\n\ - $ git pull\n\ - $ git fetch --all\n\ - $ git checkout m2d/v$NEW_VERSION\n\ - - $ git pull origin dev-5 --no-rebase # You MUST include this flag, or someone's day will be ruined.\n\ + - $ git pull origin dev --no-rebase # You MUST include this flag, or someone's day will be ruined.\n\ - Resolve the merge conflicts manually. When in doubt, ask the code's author for help.\n\ - $ git commit\n\ - $ git push" > body.txt # Create the pull request. - gh pr create -B dev-5 -H m2d/v$NEW_VERSION --title "Filler title. Read description and rename." -F body.txt + gh pr create -B dev -H m2d/v$NEW_VERSION --title "Filler title. Read description and rename." -F body.txt diff --git a/.github/workflows/validate-pr.yml b/.github/workflows/validate-pr.yml index d2ed0a913..2e1747677 100644 --- a/.github/workflows/validate-pr.yml +++ b/.github/workflows/validate-pr.yml @@ -4,14 +4,14 @@ on: types: [edited, opened, reopened, synchronize] jobs: - # We want to prevent cross-contamination between the 3.x and 4.x pipelines. So we should prevent PRs - # based on this flow to merge into `dev-3` or `release-3`. + # We want to prevent cross-contamination between the 4.x and 5.x pipelines. So we should prevent PRs + # based on this flow to merge into `dev-4` or `main-4`. verify_target_branch: runs-on: ubuntu-latest steps: - - if: ${{ github.base_ref == 'dev-3' || github.base_ref == 'release-3' }} + - if: ${{ github.base_ref == 'dev-4' || github.base_ref == 'main-4' }} run: | - echo "Forbidden to merge this branch into dev-3 or release-3" + echo "Forbidden to merge this branch into dev-4 or release-4" exit 1 # We need to verify that the Pull Request's title matches the desired format. verify_pr_title: diff --git a/github-actions/verify-pr-title/dist/index.js b/github-actions/verify-pr-title/dist/index.js index f1f8e7cae..e7ef48617 100644 --- a/github-actions/verify-pr-title/dist/index.js +++ b/github-actions/verify-pr-title/dist/index.js @@ -31258,7 +31258,7 @@ function run() { return; } } - else if (baseBranch == "dev" || /^release-\d+\.\d+\.\d+$/.test(baseBranch)) { + else if (baseBranch == "dev" || /^release-\d+\.\d+\.\d+\.*$/.test(baseBranch)) { // There's a title convention for merging feature branch PRs into `dev` or `release-X.Y.Z` // branches. if ((0, verifyFeaturePrTitle_1.verifyFeaturePrTitle)(title)) { diff --git a/github-actions/verify-pr-title/src/index.ts b/github-actions/verify-pr-title/src/index.ts index 8de7ff413..7ab4e6eb9 100644 --- a/github-actions/verify-pr-title/src/index.ts +++ b/github-actions/verify-pr-title/src/index.ts @@ -46,7 +46,7 @@ function run(): void { ); return; } - } else if (baseBranch == "dev" || /^release-\d+\.\d+\.\d+$/.test(baseBranch)) { + } else if (baseBranch == "dev" || /^release-\d+\.\d+\.\d+\.*$/.test(baseBranch)) { // There's a title convention for merging feature branch PRs into `dev` or `release-X.Y.Z` // branches. if (verifyFeaturePrTitle(title)) { From 7be3a6e3a63984912858585cefb855b3412c9218 Mon Sep 17 00:00:00 2001 From: Josh Feingold Date: Thu, 12 Dec 2024 14:42:07 -0600 Subject: [PATCH 26/35] CHANGE @W-17312010@ Adding PMD AppExchange rule docs to keep links functional (#1697) --- pmd-appexchange/docs/AvoidApiSessionId.md | 18 ++++++++++ .../docs/AvoidApiSessionIdInXML.md | 18 ++++++++++ .../docs/AvoidAuraAppWithLockerDisabled.md | 18 ++++++++++ .../docs/AvoidAuraCmpWithLockerDisabled.md | 18 ++++++++++ .../docs/AvoidChangeProtectionUnprotected.md | 18 ++++++++++ .../docs/AvoidCreateElementScriptLinkTag.md | 28 ++++++++++++++++ .../docs/AvoidDisableProtocolSecurity.md | 18 ++++++++++ .../docs/AvoidDisableProtocolSecurityInXML.md | 18 ++++++++++ .../docs/AvoidGetInstanceWithTaint.md | 20 +++++++++++ .../AvoidGlobalInstallUninstallHandlers.md | 23 +++++++++++++ .../docs/AvoidHardCodedCredentialsInAura.md | 18 ++++++++++ .../docs/AvoidHardCodedSecretsInVFAttrs.md | 18 ++++++++++ .../AvoidHardcodedCredentialsInFieldDecls.md | 19 +++++++++++ .../AvoidHardcodedCredentialsInHttpHeader.md | 17 ++++++++++ .../AvoidHardcodedCredentialsInSetPassword.md | 18 ++++++++++ .../AvoidHardcodedCredentialsInVarAssign.md | 23 +++++++++++++ .../AvoidHardcodedCredentialsInVarDecls.md | 19 +++++++++++ .../AvoidInsecureHttpRemoteSiteSetting.md | 18 ++++++++++ ...AvoidInsecureHttpRemoteSiteSettingInXML.md | 18 ++++++++++ .../AvoidInvalidCrudContentDistribution.md | 33 +++++++++++++++++++ .../docs/AvoidJavaScriptCustomObject.md | 18 ++++++++++ .../docs/AvoidJavaScriptHomePageComponent.md | 18 ++++++++++ .../docs/AvoidJavaScriptWeblink.md | 18 ++++++++++ .../docs/AvoidJsLinksInCustomObject.md | 18 ++++++++++ .../docs/AvoidJsLinksInWebLinks.md | 18 ++++++++++ pmd-appexchange/docs/AvoidLmcIsExposedTrue.md | 18 ++++++++++ .../docs/AvoidLmcIsExposedTrueInXML.md | 18 ++++++++++ .../docs/AvoidLwcBubblesComposedTrue.md | 18 ++++++++++ pmd-appexchange/docs/AvoidSControls.md | 18 ++++++++++ .../AvoidSecurityEnforcedOldApiVersion.md | 18 ++++++++++ .../docs/AvoidSystemModeInFlows.md | 18 ++++++++++ .../AvoidUnauthorizedApiSessionIdInApex.md | 18 ++++++++++ .../AvoidUnauthorizedApiSessionIdInFlows.md | 18 ++++++++++ ...voidUnauthorizedApiSessionIdVisualforce.md | 18 ++++++++++ .../AvoidUnauthorizedGetSessionIdInApex.md | 18 ++++++++++ ...idUnauthorizedGetSessionIdInVisualforce.md | 18 ++++++++++ pmd-appexchange/docs/AvoidUnescapedHtml.md | 18 ++++++++++ .../docs/AvoidUnsafePasswordManagementUse.md | 18 ++++++++++ .../docs/LimitConnectedAppScope.md | 19 +++++++++++ pmd-appexchange/docs/LoadCSSApexStylesheet.md | 26 +++++++++++++++ pmd-appexchange/docs/LoadCSSLinkHref.md | 26 +++++++++++++++ .../docs/LoadJavaScriptHtmlScript.md | 26 +++++++++++++++ .../docs/LoadJavaScriptIncludeScript.md | 26 +++++++++++++++ pmd-appexchange/docs/ProtectSensitiveData.md | 16 +++++++++ .../docs/UpgradeLwcLockerSecuritySupport.md | 18 ++++++++++ pmd-appexchange/docs/UseHttpsCallbackUrl.md | 18 ++++++++++ pmd-appexchange/docs/UseLwcDomManual.md | 27 +++++++++++++++ 47 files changed, 924 insertions(+) create mode 100644 pmd-appexchange/docs/AvoidApiSessionId.md create mode 100644 pmd-appexchange/docs/AvoidApiSessionIdInXML.md create mode 100644 pmd-appexchange/docs/AvoidAuraAppWithLockerDisabled.md create mode 100644 pmd-appexchange/docs/AvoidAuraCmpWithLockerDisabled.md create mode 100644 pmd-appexchange/docs/AvoidChangeProtectionUnprotected.md create mode 100644 pmd-appexchange/docs/AvoidCreateElementScriptLinkTag.md create mode 100644 pmd-appexchange/docs/AvoidDisableProtocolSecurity.md create mode 100644 pmd-appexchange/docs/AvoidDisableProtocolSecurityInXML.md create mode 100644 pmd-appexchange/docs/AvoidGetInstanceWithTaint.md create mode 100644 pmd-appexchange/docs/AvoidGlobalInstallUninstallHandlers.md create mode 100644 pmd-appexchange/docs/AvoidHardCodedCredentialsInAura.md create mode 100644 pmd-appexchange/docs/AvoidHardCodedSecretsInVFAttrs.md create mode 100644 pmd-appexchange/docs/AvoidHardcodedCredentialsInFieldDecls.md create mode 100644 pmd-appexchange/docs/AvoidHardcodedCredentialsInHttpHeader.md create mode 100644 pmd-appexchange/docs/AvoidHardcodedCredentialsInSetPassword.md create mode 100644 pmd-appexchange/docs/AvoidHardcodedCredentialsInVarAssign.md create mode 100644 pmd-appexchange/docs/AvoidHardcodedCredentialsInVarDecls.md create mode 100644 pmd-appexchange/docs/AvoidInsecureHttpRemoteSiteSetting.md create mode 100644 pmd-appexchange/docs/AvoidInsecureHttpRemoteSiteSettingInXML.md create mode 100644 pmd-appexchange/docs/AvoidInvalidCrudContentDistribution.md create mode 100644 pmd-appexchange/docs/AvoidJavaScriptCustomObject.md create mode 100644 pmd-appexchange/docs/AvoidJavaScriptHomePageComponent.md create mode 100644 pmd-appexchange/docs/AvoidJavaScriptWeblink.md create mode 100644 pmd-appexchange/docs/AvoidJsLinksInCustomObject.md create mode 100644 pmd-appexchange/docs/AvoidJsLinksInWebLinks.md create mode 100644 pmd-appexchange/docs/AvoidLmcIsExposedTrue.md create mode 100644 pmd-appexchange/docs/AvoidLmcIsExposedTrueInXML.md create mode 100644 pmd-appexchange/docs/AvoidLwcBubblesComposedTrue.md create mode 100644 pmd-appexchange/docs/AvoidSControls.md create mode 100644 pmd-appexchange/docs/AvoidSecurityEnforcedOldApiVersion.md create mode 100644 pmd-appexchange/docs/AvoidSystemModeInFlows.md create mode 100644 pmd-appexchange/docs/AvoidUnauthorizedApiSessionIdInApex.md create mode 100644 pmd-appexchange/docs/AvoidUnauthorizedApiSessionIdInFlows.md create mode 100644 pmd-appexchange/docs/AvoidUnauthorizedApiSessionIdVisualforce.md create mode 100644 pmd-appexchange/docs/AvoidUnauthorizedGetSessionIdInApex.md create mode 100644 pmd-appexchange/docs/AvoidUnauthorizedGetSessionIdInVisualforce.md create mode 100644 pmd-appexchange/docs/AvoidUnescapedHtml.md create mode 100644 pmd-appexchange/docs/AvoidUnsafePasswordManagementUse.md create mode 100644 pmd-appexchange/docs/LimitConnectedAppScope.md create mode 100644 pmd-appexchange/docs/LoadCSSApexStylesheet.md create mode 100644 pmd-appexchange/docs/LoadCSSLinkHref.md create mode 100644 pmd-appexchange/docs/LoadJavaScriptHtmlScript.md create mode 100644 pmd-appexchange/docs/LoadJavaScriptIncludeScript.md create mode 100644 pmd-appexchange/docs/ProtectSensitiveData.md create mode 100644 pmd-appexchange/docs/UpgradeLwcLockerSecuritySupport.md create mode 100644 pmd-appexchange/docs/UseHttpsCallbackUrl.md create mode 100644 pmd-appexchange/docs/UseLwcDomManual.md diff --git a/pmd-appexchange/docs/AvoidApiSessionId.md b/pmd-appexchange/docs/AvoidApiSessionId.md new file mode 100644 index 000000000..97a2490a5 --- /dev/null +++ b/pmd-appexchange/docs/AvoidApiSessionId.md @@ -0,0 +1,18 @@ +AvoidApiSessionId[](#avoidapisessionid) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Session ID use may not be approved. + + +**Priority:** High (2) + +**Description:** + + Detects use of Api.Session_ID to retrieve a session ID. For more guidance on approved use cases, read the [Session Id Guidance][https://partners.salesforce.com/sfc/servlet.shepherd/version/download/0684V00000O83jT?asPdf=false&operationContext=CHATTER] document. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidApiSessionIdInXML.md b/pmd-appexchange/docs/AvoidApiSessionIdInXML.md new file mode 100644 index 000000000..a8b810832 --- /dev/null +++ b/pmd-appexchange/docs/AvoidApiSessionIdInXML.md @@ -0,0 +1,18 @@ +AvoidApiSessionIdInXML[](#avoidapisessionidinxml) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Session ID use is not approved. + + +**Priority:** High (2) + +**Description:** + + Detects use of Api.Session_ID to retrieve a session ID. For more guidance on approved use cases, read the [Session Id Guidance][https://partners.salesforce.com/sfc/servlet.shepherd/version/download/0684V00000O83jT?asPdf=false&operationContext=CHATTER] document. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidAuraAppWithLockerDisabled.md b/pmd-appexchange/docs/AvoidAuraAppWithLockerDisabled.md new file mode 100644 index 000000000..8c01d3458 --- /dev/null +++ b/pmd-appexchange/docs/AvoidAuraAppWithLockerDisabled.md @@ -0,0 +1,18 @@ +AvoidAuraAppWithLockerDisabled[](#avoidauraappwithlockerdisabled) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + To enable Lightning Locker, update the apiVersion to version 40 or greater. + + +**Priority:** Critical (1) + +**Description:** + + Detects use of API versions with Lightning Locker disabled in Aura components. Use API version 40 or greater. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidAuraCmpWithLockerDisabled.md b/pmd-appexchange/docs/AvoidAuraCmpWithLockerDisabled.md new file mode 100644 index 000000000..998cc0ef1 --- /dev/null +++ b/pmd-appexchange/docs/AvoidAuraCmpWithLockerDisabled.md @@ -0,0 +1,18 @@ +AvoidAuraCmpWithLockerDisabled[](#avoidauracmpwithlockerdisabled) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + To enable Lightning Locker, update the apiVersion to version 40 or greater. + + +**Priority:** Critical (1) + +**Description:** + + Detects use of API versions with Lightning Locker disabled in Aura components. Use API version 40 or greater. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidChangeProtectionUnprotected.md b/pmd-appexchange/docs/AvoidChangeProtectionUnprotected.md new file mode 100644 index 000000000..c66a30f3d --- /dev/null +++ b/pmd-appexchange/docs/AvoidChangeProtectionUnprotected.md @@ -0,0 +1,18 @@ +AvoidChangeProtectionUnprotected[](#avoidchangeprotectionunprotected) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Ensure appropriate authorization checks are in-place before invoking FeatureManagement.changeProtection called with 'UnProtected' argument. + + +**Priority:** Critical (1) + +**Description:** + + Detects potential misuse of FeatureManagement.changeProtection. + +**Example(s):** + + + diff --git a/pmd-appexchange/docs/AvoidCreateElementScriptLinkTag.md b/pmd-appexchange/docs/AvoidCreateElementScriptLinkTag.md new file mode 100644 index 000000000..0e07ad64a --- /dev/null +++ b/pmd-appexchange/docs/AvoidCreateElementScriptLinkTag.md @@ -0,0 +1,28 @@ +AvoidCreateElementScriptLinkTag[](#avoidcreateelementscriptlinktag) +------------------------------------------------------------------------------------------------------------------------------------------------------ + +**Violation:** + + Load JavaScript/CSS only from static resources. + + +**Priority:** High (2) + +**Description:** + +Detects dynamic creation of script or link tags +Note: This rule identifies the `