diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml index 34800298..23afefe8 100644 --- a/.github/workflows/default.yml +++ b/.github/workflows/default.yml @@ -15,30 +15,30 @@ jobs: default: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: - node-version: 18 + node-version-file: .node-version - name: Install dependencies run: | yarn install - yarn global add sfdx-cli@7.172.0 + yarn global add @salesforce/cli@${SF_CLI_VERSION:-"latest"} - name: Run unit tests run: yarn test - name: Authenticate DevHub and create scratch org env: SFDX_AUTH_URL_DEVHUB: ${{ secrets.SFDX_AUTH_URL_DEVHUB }} run: | - sfdx auth:sfdxurl:store -d -a devhub -f /dev/stdin <<< "${SFDX_AUTH_URL_DEVHUB}" + sf org login sfdx-url -d -a devhub -f <(echo "${SFDX_AUTH_URL_DEVHUB}") yarn develop - name: Run end-to-end tests run: yarn test:e2e - name: Delete scratch org if: always() run: | - sfdx force:org:delete -p + sf org delete scratch -p - name: Release package run: npx semantic-release env: diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml index 32bef18c..5640c518 100644 --- a/.github/workflows/preview.yml +++ b/.github/workflows/preview.yml @@ -7,27 +7,27 @@ jobs: default: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: - node-version: 18 + node-version-file: .node-version - name: Install dependencies run: | yarn install - yarn global add sfdx-cli@7.172.0 + yarn global add @salesforce/cli@${SF_CLI_VERSION:-"latest"} - name: Run unit tests run: yarn test - name: Authenticate DevHub and create scratch org env: SFDX_AUTH_URL_DEVHUB: ${{ secrets.SFDX_AUTH_URL_DEVHUB }} run: | - sfdx auth:sfdxurl:store -d -a devhub -f /dev/stdin <<< "${SFDX_AUTH_URL_DEVHUB}" - yarn develop release=preview + sf org login sfdx-url -d -a devhub -f <(echo "${SFDX_AUTH_URL_DEVHUB}") + yarn develop --release preview - name: Run end-to-end tests run: yarn test:e2e - name: Delete scratch org if: always() run: | - sfdx force:org:delete -p + sf org delete scratch -p diff --git a/.node-version b/.node-version index 3c032078..209e3ef4 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -18 +20 diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index 32ebab4e..00000000 --- a/.prettierrc.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "singleQuote": true, - "trailingComma": "none" -} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d0faaf5c..97ba761b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -50,9 +50,9 @@ Bravo 👏, you have just generated a working browserforce plugin! Create a scratch org and try it yourself: ```console -sfdx force:org:create -f config/project-scratch-def.json -a browserforce-dev -s -BROWSER_DEBUG=true ./bin/run browserforce:apply -f src/plugins/admins-can-log-in-as-any-user/enable.json -u browserforce-dev -BROWSER_DEBUG=true ./bin/run browserforce:apply -f src/plugins/admins-can-log-in-as-any-user/disable.json -u browserforce-dev +sf org create scratch -f config/project-scratch-def.json -a browserforce-dev -d +BROWSER_DEBUG=true ./bin/run browserforce apply -f src/plugins/admins-can-log-in-as-any-user/enable.json -u browserforce-dev +BROWSER_DEBUG=true ./bin/run browserforce apply -f src/plugins/admins-can-log-in-as-any-user/disable.json -u browserforce-dev ``` Now it's your turn! @@ -115,7 +115,7 @@ This allows to run multiple actions (from multiple plugins) using a single confi #### Implementation (`index.ts`) -Plugins are written in [Typescript](https://www.typescriptlang.org), just like `sfdx` and most of the available sfdx plugins. +Plugins are written in [Typescript](https://www.typescriptlang.org), just like `sf` and most of the available sf plugins. [Puppeteer](https://pptr.dev) is being used as a library for browser automation. If you need more inspiration regarding Puppeteer, checkout [this curated list](https://github.com/transitive-bullshit/awesome-puppeteer) of awesome Puppeteer resources. @@ -167,7 +167,7 @@ To run the **end to end tests**, you might want to create a new **default scratc > Note: Your default scratch org will be used in the tests! ```console -sfdx force:org:create -f config/project-scratch-def.json --setdefaultusername +sf org create scratch -f config/project-scratch-def.json -d ``` ```console diff --git a/README.md b/README.md index 5546d339..997defbd 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,13 @@ [![Actions Status](https://github.com/amtrack/sfdx-browserforce-plugin/workflows/Test%20and%20Release/badge.svg)](https://github.com/amtrack/sfdx-browserforce-plugin/actions) Unlike the [Scratch Org Definition Configuration](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file.htm) which can only be used **on the creation of a scratch org** (`sfdx force:org:create -f config/scratch-def.json`), -the _Browserforce Configuration_ allows to "shape" **any org**, (e.g. scratch org, sandbox or production org) with **similar preferences and unofficial preferences** that are not (yet) available in the _Scratch Org Definition Configuration_ or as _Metadata_ (`sfdx browserforce:apply -f config/setup-admin-login-as-any.json -u myOrg@example.com`). +the _Browserforce Configuration_ allows to "shape" **any org**, (e.g. scratch org, sandbox or production org) with **similar preferences and unofficial preferences** that are not (yet) available in the _Scratch Org Definition Configuration_ or as _Metadata_ (`sf browserforce apply -f config/setup-admin-login-as-any.json -u myOrg@example.com`). Further benefits: - comfortable configuration using JSON Schema (similar to the [Scratch Org Definition Configuration](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file.htm)) - idempotency of the `apply` command only applies what's necessary and allows re-execution (concept similar to [terraform](https://www.terraform.io/docs/commands/apply.html)) -- browser automation powered by [Puppeteer](https://github.com/GoogleChrome/puppeteer) (Chromium) +- browser automation powered by Puppeteer and "Chrome for Testing", [learn more about Puppeteer and Browserforce](#puppeteer) - implement your own custom preferences (a.k.a. plugins; to be improved) # Installation @@ -19,8 +19,8 @@ Further benefits: There are several different methods to install `sfdx-browserforce-plugin`: ```console -# as an sfdx plugin globally -sfdx plugins:install sfdx-browserforce-plugin +# as an sf plugin globally +sf plugins install sfdx-browserforce-plugin # or standalone globally npm install --global sfdx-browserforce-plugin @@ -34,8 +34,8 @@ npm install --save-dev sfdx-browserforce-plugin Depending on your choice of installation, you can find the `browserforce` namespace: ```console -# globally in the sfdx cli -sfdx browserforce +# globally in the sf cli +sf browserforce # globally in the sfdx-browserforce-plugin executable sfdx-browserforce-plugin browserforce @@ -49,14 +49,14 @@ $ sfdx-browserforce browserforce -h browser automation USAGE - $ sfdx-browserforce-plugin browserforce:COMMAND + $ sfdx-browserforce-plugin browserforce COMMAND COMMANDS - browserforce:apply apply a plan from a definition file - browserforce:plan retrieve state and generate plan file + browserforce apply apply a plan from a definition file + browserforce plan retrieve state and generate plan file ``` -Both the `browserforce:apply` and `browserforce:plan` commands expect a config file and a target username or alias for the org. +Both the `browserforce apply` and `browserforce plan` commands expect a config file and a target username or alias for the org. # Example @@ -80,7 +80,7 @@ Tip: If you use _Visual Studio Code_, you can leverage tab completion to build t Next apply the config: ```console -$ sfdx browserforce:apply -f ./config/setup-admin-login-as-any.json --targetusername myOrg@example.com +$ sf browserforce apply -f ./config/setup-admin-login-as-any.json --target-org myOrg@example.com logging in... done Applying definition file ./config/setup-admin-login-as-any.json to org myOrg@example.com [Security] retrieving state... done @@ -162,6 +162,31 @@ Here is a full blown example showing most of the supported settings in action: - `BROWSERFORCE_RETRY_MAX_RETRIES`: number of retries on failures opening a page (default: `4`) - `BROWSERFORCE_RETRY_TIMEOUT_MS`: initial time between retries in exponential mode (default: `4000`) +# Puppeteer + +We use [Puppeteer](https://github.com/puppeteer/puppeteer) for browser automation which comes with its own "Chrome for Testing" browser. + +The puppeteer [installation doc](https://github.com/puppeteer/puppeteer#installation) describes how this works: + +> When you install Puppeteer, it automatically downloads a recent version of +> [Chrome for Testing](https://goo.gle/chrome-for-testing) (~170MB macOS, ~282MB Linux, ~280MB Windows) that is [guaranteed to +> work](https://pptr.dev/faq#q-why-doesnt-puppeteer-vxxx-work-with-chromium-vyyy) +> with Puppeteer. The browser is downloaded to the `$HOME/.cache/puppeteer` folder +> by default (starting with Puppeteer v19.0.0). + +In most of the cases this just works! If you still want to skip the download and use another browser installation, you can do this as follows: + +```console +export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true +sf plugins install sfdx-browserforce-plugin +export PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser +sf browserforce:apply ... +``` + +Troubleshooting: + +- The installation is triggered via the `postinstall` hook of npm/yarn. If you've disabled running scripts with npm (`--ignore-scripts` or via config file), it will not download the browser. + # Contributing Please see [CONTRIBUTING.md](CONTRIBUTING.md) for getting started. diff --git a/_templates/plugin/new/index.e2e-spec.ejs.t b/_templates/plugin/new/index.e2e-spec.ejs.t index 89039855..da210a32 100644 --- a/_templates/plugin/new/index.e2e-spec.ejs.t +++ b/_templates/plugin/new/index.e2e-spec.ejs.t @@ -2,59 +2,32 @@ to: src/plugins/<%= h.changeCase.paramCase(name) %>/index.e2e-spec.ts --- import assert from 'assert'; -import * as child from 'child_process'; -import * as path from 'path'; -import { <%= h.changeCase.pascalCase(name) %> } from '.'; +import { type Config, <%= h.changeCase.pascalCase(name) %> } from '.'; describe(<%= h.changeCase.pascalCase(name) %>.name, function() { - this.slow('30s'); - this.timeout('2m'); - it('should enable', () => { - const enableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'enable.json')) - ]); - assert.deepStrictEqual(enableCmd.status, 0, enableCmd.output.toString()); - assert.ok( - /to 'true'/.test(enableCmd.output.toString()), - enableCmd.output.toString() - ); + let plugin: <%= h.changeCase.pascalCase(name) %>; + before(() => { + plugin = new <%= h.changeCase.pascalCase(name) %>(global.bf); }); - it('should already be enabled', () => { - const enableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(__dirname, 'enable.json') - ]); - assert.deepStrictEqual(enableCmd.status, 0, enableCmd.output.toString()); - assert.ok( - /no action necessary/.test(enableCmd.output.toString()), - enableCmd.output.toString() - ); + + const configEnabled: Config = { + enabled: true + }; + const configDisabled: Config = { + enabled: true + }; + it('should enable', async () => { + await plugin.run(configEnabled); + }); + it('should already be enabled', async () => { + const res = await plugin.run(configEnabled); + assert.deepStrictEqual(res, { message: 'no action necessary' }); }); - it('should disable', () => { - const disableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'disable.json')) - ]); - assert.deepStrictEqual(disableCmd.status, 0, disableCmd.output.toString()); - assert.ok( - /to 'false'/.test(disableCmd.output.toString()), - disableCmd.output.toString() - ); + it('should disable', async () => { + await plugin.run(configDisabled); }); - it('should already be disabled', () => { - const disableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(__dirname, 'disable.json') - ]); - assert.deepStrictEqual(disableCmd.status, 0, disableCmd.output.toString()); - assert.ok( - /no action necessary/.test(disableCmd.output.toString()), - disableCmd.output.toString() - ); + it('should already be disabled', async () => { + const res = await plugin.run(configDisabled); + assert.deepStrictEqual(res, { message: 'no action necessary' }); }); }); diff --git a/_templates/plugin/new/index.ejs.t b/_templates/plugin/new/index.ejs.t index ef3bbb20..f4769e3e 100644 --- a/_templates/plugin/new/index.ejs.t +++ b/_templates/plugin/new/index.ejs.t @@ -13,7 +13,7 @@ const SELECTORS = { SAVE_BUTTON: 'input[id$=":save"]' }; -type Config = { +export type Config = { enabled: boolean; }; @@ -27,6 +27,7 @@ export class <%= h.changeCase.pascalCase(name) %> extends BrowserforcePlugin { (el: HTMLInputElement) => el.checked ) }; + await page.close(); return response; } @@ -44,5 +45,6 @@ export class <%= h.changeCase.pascalCase(name) %> extends BrowserforcePlugin { page.waitForSelector(SELECTORS.CONFIRM_MESSAGE), page.click(SELECTORS.SAVE_BUTTON) ]); + await page.close(); } } diff --git a/package.json b/package.json index 87a79b87..e31ee500 100644 --- a/package.json +++ b/package.json @@ -8,20 +8,21 @@ }, "dependencies": { "@mdapi-issues/listmetadata-standardvalueset": "2.0.3", - "@salesforce/command": "5.2.16", - "json-merge-patch": "1.0.2", + "@salesforce/sf-plugins-core": "4.1.1", "p-retry": "4.6.2", - "puppeteer": "19.2.0", - "tslib": "2.4.0" + "puppeteer": "21.5.1" }, "devDependencies": { - "@types/mocha": "10.0.1", - "@types/node": "18.16.8", + "@salesforce/dev-config": "4.1.0", + "@salesforce/prettier-config": "0.0.3", + "@types/mocha": "10.0.4", + "@types/node": "20.9.0", "mocha": "10.2.0", "nyc": "15.1.0", - "oclif": "3.9.0", + "oclif": "4.0.3", + "prettier": "3.1.0", "ts-node": "10.9.1", - "typescript": "5.0.4" + "typescript": "5.2.2" }, "engines": { "node": ">=14.0.0" @@ -39,7 +40,8 @@ ], "license": "MIT", "oclif": { - "bin": "sfdx-browserforce-plugin", + "bin": "sf", + "topicSeparator": " ", "commands": "./lib/commands", "topics": { "browserforce": { @@ -58,7 +60,7 @@ "generate:plugin": "npx hygen plugin new", "prepack": "yarn build", "prepare": "yarn build", - "test": "nyc --reporter=lcov --reporter=text mocha --require ts-node/register \"test/**/*.test.ts\" \"src/**/*.test.ts\"", - "test:e2e": "mocha --require ts-node/register \"test/**/*.e2e-spec.ts\" \"src/**/*.e2e-spec.ts\"" + "test": "tsc -p test && nyc --reporter=lcov --reporter=text mocha --require ts-node/register \"test/**/*.test.ts\" \"src/**/*.test.ts\"", + "test:e2e": "tsc -p test && mocha --require ts-node/register --slow 30s --timeout 2m --file test/e2e-setup.ts \"test/**/*.e2e-spec.ts\" \"src/**/*.e2e-spec.ts\"" } } diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 00000000..0f386e2b --- /dev/null +++ b/prettier.config.js @@ -0,0 +1,6 @@ +const salesforcePrettierConfig = require('@salesforce/prettier-config'); + +module.exports = { + ...salesforcePrettierConfig, + trailingComma: 'none' +}; diff --git a/scripts/develop.sh b/scripts/develop.sh index 717718fe..046aa415 100755 --- a/scripts/develop.sh +++ b/scripts/develop.sh @@ -33,12 +33,12 @@ _help() { _main() { alias="${alias:-${DEFAULT_ALIAS}}" # shellcheck disable=SC2068 - sfdx force:org:create -f config/project-scratch-def.json \ + sf org create scratch -f config/project-scratch-def.json \ -a "$alias" \ - -s \ - description="${alias}" ${POSITIONAL_ARGS[@]} - sfdx force:org:display -u "$alias" - sfdx force:source:push -u "$alias" + -d \ + ${POSITIONAL_ARGS[@]} + sf org display -o "$alias" + sf project deploy start -o "$alias" } if [[ "$0" == "${BASH_SOURCE[0]}" ]]; then diff --git a/src/browserforce-command.ts b/src/browserforce-command.ts index 0f9a59f5..f205bcdf 100644 --- a/src/browserforce-command.ts +++ b/src/browserforce-command.ts @@ -1,5 +1,5 @@ -import { flags, SfdxCommand } from '@salesforce/command'; import { Messages } from '@salesforce/core'; +import { Flags, SfCommand, Ux, requiredOrgFlagWithDeprecations } from '@salesforce/sf-plugins-core'; import { promises } from 'fs'; import * as path from 'path'; import { Browserforce } from './browserforce'; @@ -7,27 +7,26 @@ import { ConfigParser } from './config-parser'; import * as DRIVERS from './plugins'; Messages.importMessagesDirectory(__dirname); -const messages = Messages.loadMessages( - 'sfdx-browserforce-plugin', - 'browserforce' -); +const messages = Messages.loadMessages('sfdx-browserforce-plugin', 'browserforce'); -export class BrowserforceCommand extends SfdxCommand { - protected static requiresUsername = true; - - protected static flagsConfig = { - definitionfile: flags.string({ +export class BrowserforceCommand extends SfCommand { + public static readonly flags = { + 'target-org': requiredOrgFlagWithDeprecations, + definitionfile: Flags.string({ char: 'f', + summary: messages.getMessage('definitionFileDescription'), description: messages.getMessage('definitionFileDescription') }), - planfile: flags.string({ + planfile: Flags.string({ char: 'p', name: 'plan', + summary: messages.getMessage('planFileDescription'), description: messages.getMessage('planFileDescription') }), - statefile: flags.string({ + statefile: Flags.string({ char: 's', name: 'state', + summary: messages.getMessage('stateFileDescription'), description: messages.getMessage('stateFileDescription') }) }; @@ -36,35 +35,35 @@ export class BrowserforceCommand extends SfdxCommand { protected settings: any[]; public async init(): Promise { + const { flags } = await this.parse(BrowserforceCommand); await super.init(); - const definitionFileData = await promises.readFile( - path.resolve(this.flags.definitionfile), - 'utf8' - ); let definition; - try { - definition = JSON.parse(definitionFileData); - } catch (err) { - throw new Error('Failed parsing definitionfile'); + if (flags.definitionfile) { + const definitionFileData = await promises.readFile(path.resolve(flags.definitionfile), 'utf8'); + try { + definition = JSON.parse(definitionFileData); + } catch (err) { + throw new Error('Failed parsing definitionfile'); + } } // TODO: use require.resolve to dynamically load plugins from npm packages this.settings = ConfigParser.parse(DRIVERS, definition); - this.bf = new Browserforce(this.org, this.ux); - this.ux.startSpinner('logging in'); + this.bf = new Browserforce(flags['target-org'], new Ux({ jsonEnabled: this.jsonEnabled() })); + this.spinner.start('logging in'); await this.bf.login(); - this.ux.stopSpinner(); + this.spinner.stop(); } public async run(): Promise { throw new Error('BrowserforceCommand should not be run directly'); } - public async finally(err: Error): Promise { - this.ux.stopSpinner(); + public async finally(err?: Error): Promise { + this.spinner.stop(err?.message); if (this.bf) { - this.ux.startSpinner('logging out'); + this.spinner.start('logging out'); await this.bf.logout(); - this.ux.stopSpinner(); + this.spinner.stop(); } } } diff --git a/src/browserforce.ts b/src/browserforce.ts index e9b1592f..012e4f16 100644 --- a/src/browserforce.ts +++ b/src/browserforce.ts @@ -1,8 +1,9 @@ import { MyDomainResolver, Org } from '@salesforce/core'; +import { type Ux } from '@salesforce/sf-plugins-core'; import pRetry, { AbortError } from 'p-retry'; -import { Browser, Frame, launch, Page, WaitForOptions } from 'puppeteer'; +import { Browser, Frame, Page, WaitForOptions, launch } from 'puppeteer'; import * as querystring from 'querystring'; -import { parse, URL } from 'url'; +import { URL, parse } from 'url'; const POST_LOGIN_PATH = 'setup/forcecomHomepage.apexp'; @@ -10,18 +11,12 @@ const ERROR_DIV_SELECTOR = '#errorTitle'; const ERROR_DIVS_SELECTOR = 'div.errorMsg'; const VF_IFRAME_SELECTOR = 'iframe[name^=vfFrameId]'; -export interface Logger { - log(...args: string[]): unknown; - warn(message: string): unknown; - error(...args: unknown[]): unknown; -} - export class Browserforce { public org: Org; - public logger: Logger; + public logger?: Ux; public browser: Browser; public page: Page; - constructor(org: Org, logger?: Logger) { + constructor(org: Org, logger?: Ux) { this.org = org; this.logger = logger; } @@ -34,12 +29,10 @@ export class Browserforce { // workaround for navigating frames https://github.com/puppeteer/puppeteer/issues/5123 '--disable-features=site-per-process' ], - headless: !(process.env.BROWSER_DEBUG === 'true') + headless: process.env.BROWSER_DEBUG === 'true' ? false : 'new' }); await this.openPage( - `secur/frontdoor.jsp?sid=${ - this.org.getConnection().accessToken - }&retURL=${encodeURIComponent(POST_LOGIN_PATH)}` + `secur/frontdoor.jsp?sid=${this.org.getConnection().accessToken}&retURL=${encodeURIComponent(POST_LOGIN_PATH)}` ); return this; } @@ -51,10 +44,7 @@ export class Browserforce { public async resolveDomains(): Promise { // resolve ip addresses of both LEX and classic domains - const salesforceUrls = [ - this.getInstanceUrl(), - this.getLightningUrl() - ].filter((u) => u); + const salesforceUrls = [this.getInstanceUrl(), this.getLightningUrl()].filter((u) => u); for (const salesforceUrl of salesforceUrls) { const resolver = await MyDomainResolver.create({ url: new URL(salesforceUrl) @@ -68,19 +58,14 @@ export class Browserforce { } // path instead of url - public async openPage( - urlPath: string, - options?: WaitForOptions - ): Promise { + public async openPage(urlPath: string, options?: WaitForOptions): Promise { let page; const result = await pRetry( async () => { // there seems to be an issue with Enhanced Domains // await this.resolveDomains(); page = await this.browser.newPage(); - page.setDefaultNavigationTimeout( - parseInt(process.env.BROWSERFORCE_NAVIGATION_TIMEOUT_MS, 10) || 90000 - ); + page.setDefaultNavigationTimeout(parseInt(process.env.BROWSERFORCE_NAVIGATION_TIMEOUT_MS ?? '90000', 10)); await page.setViewport({ width: 1024, height: 768 }); const url = `${this.getInstanceUrl()}/${urlPath}`; const parsedUrl = parse(urlPath); @@ -91,29 +76,17 @@ export class Browserforce { throw new Error(`${response.status()}: ${response.statusText()}`); } if (response.url().indexOf('/?ec=302') > 0) { - const salesforceUrls = [ - this.getInstanceUrl(), - this.getLightningUrl() - ].filter((u) => u); - if ( - salesforceUrls.some((salesforceUrl) => - response.url().startsWith(salesforceUrl) - ) - ) { + const salesforceUrls = [this.getInstanceUrl(), this.getLightningUrl()].filter((u) => u); + if (salesforceUrls.some((salesforceUrl) => response.url().startsWith(salesforceUrl))) { // the url looks ok so it is a login error throw new AbortError('login failed'); - } else if ( - parsedUrl.pathname === 'secur/frontdoor.jsp' && - parsedUrl.query.includes('retURL=') - ) { + } else if (parsedUrl.pathname === 'secur/frontdoor.jsp' && parsedUrl.query?.includes('retURL=')) { if (this.logger) { this.logger.warn('trying frontdoor workaround...'); } // try opening page directly without frontdoor as login might have already been successful const qsUrl = querystring.parse(parsedUrl.query); - urlPath = Array.isArray(qsUrl.retURL) - ? qsUrl.retURL[0] - : qsUrl.retURL; + urlPath = Array.isArray(qsUrl.retURL) ? qsUrl.retURL[0] : qsUrl.retURL!; throw new Error('frontdoor error'); } else { // the url is not as expected @@ -137,9 +110,7 @@ export class Browserforce { { onFailedAttempt: async (error) => { if (this.logger) { - this.logger.warn( - `retrying ${error.retriesLeft} more time(s) because of "${error}"` - ); + this.logger.warn(`retrying ${error.retriesLeft} more time(s) because of "${error}"`); } if (page) { try { @@ -149,12 +120,8 @@ export class Browserforce { } } }, - retries: process.env.BROWSERFORCE_RETRY_MAX_RETRIES - ? parseInt(process.env.BROWSERFORCE_RETRY_MAX_RETRIES, 10) - : 4, - minTimeout: process.env.BROWSERFORCE_RETRY_TIMEOUT_MS - ? parseInt(process.env.BROWSERFORCE_RETRY_TIMEOUT_MS, 10) - : 4000 + retries: parseInt(process.env.BROWSERFORCE_RETRY_MAX_RETRIES ?? '4', 10), + minTimeout: parseInt(process.env.BROWSERFORCE_RETRY_TIMEOUT_MS ?? '4000', 10) } ); return result; @@ -163,34 +130,27 @@ export class Browserforce { // If LEX is enabled, the classic url will be opened in an iframe. // Wait for either the selector in the page or in the iframe. // returns the page or the frame - public async waitForSelectorInFrameOrPage( - page: Page, - selector: string - ): Promise { - await page.waitForSelector( - `pierce/force-aloha-page ${VF_IFRAME_SELECTOR}, ${VF_IFRAME_SELECTOR}, ${selector}` - ); - const frameElementHandle = await page.$( - `pierce/force-aloha-page ${VF_IFRAME_SELECTOR}, ${VF_IFRAME_SELECTOR}` - ); + public async waitForSelectorInFrameOrPage(page: Page, selector: string): Promise { + await page.waitForSelector(`pierce/${VF_IFRAME_SELECTOR}, ${selector}`); + const frameElementHandle = await page.$(`pierce/${VF_IFRAME_SELECTOR}`); let frameOrPage: Page | Frame = page; if (frameElementHandle) { - const frame = await frameElementHandle.contentFrame(); - if (frame) { - frameOrPage = frame; - } + const frame = await page.waitForFrame( + async (f) => f.name().startsWith('vfFrameId') && f.url()?.length > 0 && f.url() !== 'about:blank' + ); + frameOrPage = frame; } await frameOrPage.waitForSelector(selector); return frameOrPage; } - public getMyDomain(): string { + public getMyDomain(): string | null { const instanceUrl = this.getInstanceUrl(); // acme.my.salesforce.com // acme--.csN.my.salesforce.com const matches = instanceUrl.match(/https:\/\/(.*)\.my\.salesforce\.com/); if (matches) { - return matches[1].split('.')[0]; + return matches[1]; } return null; } @@ -204,12 +164,12 @@ export class Browserforce { if (matches) { const parts = matches[1].split('.'); if (parts.length === 3 && parts[2] === 'my') { - return parts[1]; + return `${parts[0]}.${parts[1]}`; } else if (!['test', 'login'].includes(parts[0])) { return parts[0]; } } - return null; + throw new Error(`Could not determine the instance URL from: ${instanceUrl}`); } public getInstanceUrl(): string { @@ -224,17 +184,14 @@ export class Browserforce { if (myDomainOrInstance) { return `https://${myDomainOrInstance}.lightning.force.com`; } - return null; + throw new Error(`Could not determine the lightning URL from: ${myDomainOrInstance} and ${instanceDomain}`); } } export async function throwPageErrors(page: Page): Promise { const errorHandle = await page.$(ERROR_DIV_SELECTOR); if (errorHandle) { - const errorMsg = await page.evaluate( - (div: HTMLDivElement) => div.innerText, - errorHandle - ); + const errorMsg = await page.evaluate((div: HTMLDivElement) => div.innerText, errorHandle); await errorHandle.dispose(); if (errorMsg && errorMsg.trim()) { throw new Error(errorMsg.trim()); @@ -242,9 +199,12 @@ export async function throwPageErrors(page: Page): Promise { } const errorElements = await page.$$(ERROR_DIVS_SELECTOR); if (errorElements.length) { - const errorMessages = await page.evaluate((...errorDivs) => { - return errorDivs.map((div: HTMLDivElement) => div.innerText); - }, ...errorElements); + const errorMessages = await page.evaluate( + (...errorDivs) => { + return errorDivs.map((div: HTMLDivElement) => div.innerText); + }, + ...errorElements + ); const errorMsg = errorMessages .map((m) => m.trim()) .join(' ') @@ -254,3 +214,14 @@ export async function throwPageErrors(page: Page): Promise { } } } + +export async function retry(input: (attemptCount: number) => PromiseLike | T): Promise { + const res = await pRetry(input, { + onFailedAttempt: (error) => { + console.warn(`retrying ${error.retriesLeft} more time(s) because of "${error}"`); + }, + retries: parseInt(process.env.BROWSERFORCE_RETRY_MAX_RETRIES ?? '6', 10), + minTimeout: parseInt(process.env.BROWSERFORCE_RETRY_TIMEOUT_MS ?? '4000', 10) + }); + return res; +} diff --git a/src/commands/browserforce/apply.ts b/src/commands/browserforce/apply.ts index 27313fb4..7040a4ab 100644 --- a/src/commands/browserforce/apply.ts +++ b/src/commands/browserforce/apply.ts @@ -2,16 +2,13 @@ import { Messages } from '@salesforce/core'; import { BrowserforceCommand } from '../../browserforce-command'; Messages.importMessagesDirectory(__dirname); -const messages = Messages.loadMessages( - 'sfdx-browserforce-plugin', - 'browserforce' -); +const messages = Messages.loadMessages('sfdx-browserforce-plugin', 'browserforce'); -export default class BrowserforceApply extends BrowserforceCommand { +export class BrowserforceApply extends BrowserforceCommand { public static description = messages.getMessage('applyCommandDescription'); public static examples = [ - `$ sfdx browserforce:apply -f ./config/setup-admin-login-as-any.json --targetusername myOrg@example.com + `$ <%= config.bin %> <%= command.id %> -f ./config/setup-admin-login-as-any.json --target-org myOrg@example.com logging in... done Applying definition file ./config/setup-admin-login-as-any.json to org myOrg@example.com [Security] retrieving state... done @@ -21,42 +18,38 @@ export default class BrowserforceApply extends BrowserforceCommand { ]; public async run(): Promise { - this.ux.log( - `Applying definition file ${ - this.flags.definitionfile - } to org ${this.org.getUsername()}` - ); + const { flags } = await this.parse(BrowserforceApply); + this.log(`Applying definition file ${flags.definitionfile} to org ${flags['target-org'].getUsername()}`); for (const setting of this.settings) { const driver = setting.Driver; - const instance = new driver(this.bf, this.org); - this.ux.startSpinner(`[${driver.name}] retrieving state`); + const instance = new driver(this.bf); + this.spinner.start(`[${driver.name}] retrieving state`); let state; try { state = await instance.retrieve(setting.value); } catch (err) { - this.ux.stopSpinner('failed'); + this.spinner.stop('failed'); throw err; } - this.ux.stopSpinner(); - const action = instance.diff(state, setting.value); - this.ux.stopSpinner(); - if (action && Object.keys(action).length) { - this.ux.startSpinner( - `[${driver.name}] ${Object.keys(action) + this.spinner.stop(); + const diff = instance.diff(state, setting.value); + if (diff !== undefined) { + this.spinner.start( + `[${driver.name}] ${Object.keys(diff) .map((key) => { - return `changing '${key}' to '${JSON.stringify(action[key])}'`; + return `changing '${key}' to '${JSON.stringify(diff[key])}'`; }) .join('\n')}` ); try { - await instance.apply(action); + await instance.apply(diff); } catch (err) { - this.ux.stopSpinner('failed'); + this.spinner.stop('failed'); throw err; } - this.ux.stopSpinner(); + this.spinner.stop(); } else { - this.ux.log(`[${driver.name}] no action necessary`); + this.log(`[${driver.name}] no action necessary`); } } return { success: true }; diff --git a/src/commands/browserforce/plan.ts b/src/commands/browserforce/plan.ts index fe453b5e..200027c6 100644 --- a/src/commands/browserforce/plan.ts +++ b/src/commands/browserforce/plan.ts @@ -4,16 +4,13 @@ import * as path from 'path'; import { BrowserforceCommand } from '../../browserforce-command'; Messages.importMessagesDirectory(__dirname); -const messages = Messages.loadMessages( - 'sfdx-browserforce-plugin', - 'browserforce' -); +const messages = Messages.loadMessages('sfdx-browserforce-plugin', 'browserforce'); -export default class BrowserforcePlanCommand extends BrowserforceCommand { +export class BrowserforcePlanCommand extends BrowserforceCommand { public static description = messages.getMessage('planCommandDescription'); public static examples = [ - `$ sfdx browserforce:plan -f ./config/setup-admin-login-as-any.json --targetusername myOrg@example.com + `$ <%= config.bin %> <%= command.id %> -f ./config/setup-admin-login-as-any.json --target-org myOrg@example.com logging in... done Generating plan with definition file ./config/setup-admin-login-as-any.json from org myOrg@example.com [Security] retrieving state... done @@ -23,10 +20,9 @@ export default class BrowserforcePlanCommand extends BrowserforceCommand { ]; public async run(): Promise { - this.ux.log( - `Generating plan with definition file ${ - this.flags.definitionfile - } from org ${this.org.getUsername()}` + const { flags } = await this.parse(BrowserforcePlanCommand); + this.log( + `Generating plan with definition file ${flags.definitionfile} from org ${flags['target-org'].getUsername()}` ); const state = { settings: {} @@ -36,37 +32,31 @@ export default class BrowserforcePlanCommand extends BrowserforceCommand { }; for (const setting of this.settings) { const driver = setting.Driver; - const instance = new driver(this.bf, this.org); - this.ux.startSpinner(`[${driver.name}] retrieving state`); + const instance = new driver(this.bf); + this.spinner.start(`[${driver.name}] retrieving state`); let driverState; try { driverState = await instance.retrieve(setting.value); state.settings[setting.key] = driverState; } catch (err) { - this.ux.stopSpinner('failed'); + this.spinner.stop('failed'); throw err; } - this.ux.stopSpinner(); - this.ux.startSpinner(`[${driver.name}] generating plan`); + this.spinner.stop(); + this.spinner.start(`[${driver.name}] generating plan`); const driverPlan = instance.diff(driverState, setting.value); plan.settings[setting.key] = driverPlan; - this.ux.stopSpinner(); + this.spinner.stop(); } - if (this.flags.statefile) { - this.ux.startSpinner('writing state file'); - await writeFile( - path.resolve(this.flags.statefile), - JSON.stringify(state, null, 2) - ); - this.ux.stopSpinner(); + if (flags.statefile) { + this.spinner.start('writing state file'); + await writeFile(path.resolve(flags.statefile), JSON.stringify(state, null, 2)); + this.spinner.stop(); } - if (this.flags.planfile) { - this.ux.startSpinner('writing plan file'); - await writeFile( - path.resolve(this.flags.planfile), - JSON.stringify(plan, null, 2) - ); - this.ux.stopSpinner(); + if (flags.planfile) { + this.spinner.start('writing plan file'); + await writeFile(path.resolve(flags.planfile), JSON.stringify(plan, null, 2)); + this.spinner.stop(); } return { success: true, plan }; } diff --git a/src/config-parser.ts b/src/config-parser.ts index 968b2c99..f04cfaf1 100644 --- a/src/config-parser.ts +++ b/src/config-parser.ts @@ -1,7 +1,7 @@ import { BrowserforcePlugin } from './plugin'; type Drivers = { - [key: string]: unknown; + [key: string]: typeof BrowserforcePlugin; }; type Data = { @@ -16,8 +16,8 @@ type Config = { export class ConfigParser { public static parse(drivers: Drivers, data: Data): Config[] { - const settings = []; - if (data && data.settings) { + const settings: Config[] = []; + if (data?.settings) { for (const driverName of Object.keys(data.settings)) { if (drivers[driverName]) { settings.push({ @@ -26,17 +26,11 @@ export class ConfigParser { value: data.settings[driverName] }); } else { - throw new Error( - `Could not find plugin named '${driverName}' in definition: ${JSON.stringify( - data - )}` - ); + throw new Error(`Could not find plugin named '${driverName}' in definition: ${JSON.stringify(data)}`); } } } else { - throw new Error( - `Missing 'settings' attribute in definition: ${JSON.stringify(data)}` - ); + throw new Error(`Missing 'settings' attribute in definition: ${JSON.stringify(data)}`); } return settings; } diff --git a/src/jsforce-utils.ts b/src/jsforce-utils.ts index 7f5117b0..89728873 100644 --- a/src/jsforce-utils.ts +++ b/src/jsforce-utils.ts @@ -2,9 +2,7 @@ * workaround as the Metadata API (converted from XML) returns an object instead of an array of length 1 * @param prop result of a Metadata API call (array or object) */ -export function ensureArray( - prop: T -): Array { +export function ensureArray(prop: T | T[]): T[] { if (Array.isArray(prop)) { return prop; } diff --git a/src/plugin.ts b/src/plugin.ts index 51b6dbf7..333b21f2 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -1,18 +1,35 @@ import { Org } from '@salesforce/core'; -import * as jsonMergePatch from 'json-merge-patch'; import { Browserforce } from './browserforce'; +import { deepDiff } from './plugins/utils'; export abstract class BrowserforcePlugin { - protected org: Org; protected browserforce: Browserforce; + protected org: Org; - public constructor(browserforce: Browserforce, org: Org) { + public constructor(browserforce: Browserforce) { this.browserforce = browserforce; - this.org = org; + this.org = browserforce?.org; } public abstract retrieve(definition?: unknown): Promise; + /** + * deep diff + * @param state + * @param definition + * @returns undefined when there is no diff + */ public diff(state: unknown, definition: unknown): unknown { - return jsonMergePatch.generate(state, definition); + return deepDiff(state, definition); } public abstract apply(plan: unknown): Promise; + public async run(definition: unknown): Promise { + const state = await this.retrieve(definition); + const diff = this.diff(state, definition); + if (diff !== undefined) { + const result = await this.apply(diff); + return result; + } + return { + message: 'no action necessary' + }; + } } diff --git a/src/plugins/activity-settings/index.e2e-spec.ts b/src/plugins/activity-settings/index.e2e-spec.ts index 87c161f4..6e703191 100644 --- a/src/plugins/activity-settings/index.e2e-spec.ts +++ b/src/plugins/activity-settings/index.e2e-spec.ts @@ -1,65 +1,37 @@ import assert from 'assert'; -import * as child from 'child_process'; -import * as path from 'path'; import { ActivitySettings } from '.'; -describe(ActivitySettings.name, function() { - this.slow('30s'); - this.timeout('2m'); - it('should enable allowUsersToRelateMultipleContactsToTasksAndEvents', () => { - const enableManyWhoPrefCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'enable-many-who-pref.json')) - ]); - assert.deepStrictEqual( - enableManyWhoPrefCmd.status, - 0, - enableManyWhoPrefCmd.output.toString() - ); - assert.ok( - /'allowUsersToRelateMultipleContactsToTasksAndEvents' to 'true'/.test( - enableManyWhoPrefCmd.output.toString() - ), - enableManyWhoPrefCmd.output.toString() - ); +describe(ActivitySettings.name, function () { + let plugin; + before(() => { + plugin = new ActivitySettings(global.bf); }); - it('should already be enabled: allowUsersToRelateMultipleContactsToTasksAndEvents', () => { - const enableManyWhoPrefCmd2 = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'enable-many-who-pref.json')) - ]); - assert.deepStrictEqual( - enableManyWhoPrefCmd2.status, - 0, - enableManyWhoPrefCmd2.output.toString() - ); - assert.ok( - /no action necessary/.test(enableManyWhoPrefCmd2.output.toString()), - enableManyWhoPrefCmd2.output.toString() - ); - }); - it('should fail to disable allowUsersToRelateMultipleContactsToTasksAndEvents', () => { - const disableManyWhoPrefCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'disable-many-who-pref.json')) - ]); - assert.deepStrictEqual( - disableManyWhoPrefCmd.status, - 1, - disableManyWhoPrefCmd.output.toString() - ); - assert.ok( - /'allowUsersToRelateMultipleContactsToTasksAndEvents' to 'false'/.test( - disableManyWhoPrefCmd.output.toString() - ), - disableManyWhoPrefCmd.output.toString() - ); - assert.ok( - /can only be disabled/.test(disableManyWhoPrefCmd.output.toString()), - disableManyWhoPrefCmd.output.toString() - ); + + describe('allowUsersToRelateMultipleContactsToTasksAndEvents', () => { + const configEnabled = { + allowUsersToRelateMultipleContactsToTasksAndEvents: true + }; + const configDisabled = { + allowUsersToRelateMultipleContactsToTasksAndEvents: false + }; + + it('should enable', async () => { + await plugin.run(configEnabled); + }); + it('should be enabled', async () => { + const res = await plugin.retrieve(); + assert.deepStrictEqual(res, configEnabled); + }); + it('should fail to disable', async () => { + let err; + try { + await plugin.apply(configDisabled); + } catch (e) { + err = e; + } + assert.throws(() => { + throw err; + }, /can only be disabled/); + }); }); }); diff --git a/src/plugins/activity-settings/index.ts b/src/plugins/activity-settings/index.ts index 7f2c61d6..e8412569 100644 --- a/src/plugins/activity-settings/index.ts +++ b/src/plugins/activity-settings/index.ts @@ -23,6 +23,7 @@ export class ActivitySettings extends BrowserforcePlugin { (el: HTMLInputElement) => el.checked ) }; + await page.close(); return response; } @@ -41,9 +42,7 @@ export class ActivitySettings extends BrowserforcePlugin { }, config.allowUsersToRelateMultipleContactsToTasksAndEvents ); - await Promise.all([ - page.waitForNavigation(), - page.click(SELECTORS.SUBMIT_BUTTON) - ]); + await Promise.all([page.waitForNavigation(), page.click(SELECTORS.SUBMIT_BUTTON)]); + await page.close(); } } diff --git a/src/plugins/communities/index.e2e-spec.ts b/src/plugins/communities/index.e2e-spec.ts index 4b890bb4..1aa3ea9c 100644 --- a/src/plugins/communities/index.e2e-spec.ts +++ b/src/plugins/communities/index.e2e-spec.ts @@ -1,37 +1,35 @@ import assert from 'assert'; -import * as child from 'child_process'; -import * as path from 'path'; import { Communities } from '.'; -describe.skip(Communities.name, function() { - this.slow('30s'); - this.timeout('2m'); - it('should enable', () => { - const enableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'enable.json')) - ]); - assert.deepStrictEqual(enableCmd.status, 0, enableCmd.output.toString()); - assert.ok( - /to 'true'/.test(enableCmd.output.toString()), - enableCmd.output.toString() - ); +describe.skip(Communities.name, function () { + let plugin; + before(() => { + plugin = new Communities(global.bf); }); - it('should fail to disable', () => { - const disableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'disable.json')) - ]); - assert.deepStrictEqual(disableCmd.status, 1, disableCmd.output.toString()); - assert.ok( - /to 'false'/.test(disableCmd.output.toString()), - disableCmd.output.toString() - ); - assert.ok( - /cannot be disabled/.test(disableCmd.output.toString()), - disableCmd.output.toString() - ); + + const configEnabled = { + enabled: true + }; + const configDisabled = { + enabled: false + }; + + it('should enable', async () => { + await plugin.run(configEnabled); + }); + it('should be enabled', async () => { + const res = await plugin.run(configEnabled); + assert.deepStrictEqual(res, { message: 'no action necessary' }); + }); + it('should fail to disable', async () => { + let err; + try { + await plugin.apply(configDisabled); + } catch (e) { + err = e; + } + assert.throws(() => { + throw err; + }, /cannot be disabled/); }); }); diff --git a/src/plugins/communities/index.ts b/src/plugins/communities/index.ts index 301d7bd0..8aa1f16c 100644 --- a/src/plugins/communities/index.ts +++ b/src/plugins/communities/index.ts @@ -18,20 +18,15 @@ type Config = { export class Communities extends BrowserforcePlugin { public async retrieve(): Promise { const page = await this.browserforce.openPage(PATHS.BASE); - const frameOrPage = await this.browserforce.waitForSelectorInFrameOrPage( - page, - SELECTORS.BASE - ); + const frameOrPage = await this.browserforce.waitForSelectorInFrameOrPage(page, SELECTORS.BASE); const response = { enabled: true }; const inputEnable = await frameOrPage.$(SELECTORS.ENABLE_CHECKBOX); if (inputEnable) { - response.enabled = await frameOrPage.$eval( - SELECTORS.ENABLE_CHECKBOX, - (el: HTMLInputElement) => el.checked - ); + response.enabled = await frameOrPage.$eval(SELECTORS.ENABLE_CHECKBOX, (el: HTMLInputElement) => el.checked); } + await page.close(); return response; } @@ -41,27 +36,20 @@ export class Communities extends BrowserforcePlugin { } const page = await this.browserforce.openPage(PATHS.BASE); - const frameOrPage = await this.browserforce.waitForSelectorInFrameOrPage( - page, - SELECTORS.ENABLE_CHECKBOX - ); + const frameOrPage = await this.browserforce.waitForSelectorInFrameOrPage(page, SELECTORS.ENABLE_CHECKBOX); await frameOrPage.click(SELECTORS.ENABLE_CHECKBOX); const domainName = ( config.domainName || this.browserforce.getMyDomain() || - `comm-${Math.random() - .toString(36) - .substr(2)}` + `comm-${Math.random().toString(36).substr(2)}` ).substring(0, 22); await frameOrPage.waitForSelector(SELECTORS.DOMAIN_NAME_INPUT_TEXT); await frameOrPage.type(SELECTORS.DOMAIN_NAME_INPUT_TEXT, domainName); - page.on('dialog', async dialog => { + page.on('dialog', async (dialog) => { await dialog.accept(); }); await frameOrPage.waitForSelector(SELECTORS.SAVE_BUTTON); - await Promise.all([ - page.waitForNavigation(), - frameOrPage.click(SELECTORS.SAVE_BUTTON) - ]); + await Promise.all([page.waitForNavigation(), frameOrPage.click(SELECTORS.SAVE_BUTTON)]); + await page.close(); } } diff --git a/src/plugins/company-information/index.e2e-spec.ts b/src/plugins/company-information/index.e2e-spec.ts index a11c8e2f..94010e07 100644 --- a/src/plugins/company-information/index.e2e-spec.ts +++ b/src/plugins/company-information/index.e2e-spec.ts @@ -1,62 +1,38 @@ import assert from 'assert'; -import * as child from 'child_process'; -import * as path from 'path'; -import { CompanyInformation } from '.'; -import Os from 'os'; +import { CompanyInformation, Config } from '.'; describe(CompanyInformation.name, function () { - this.slow('30s'); - this.timeout('2m'); + let plugin: CompanyInformation; + before(() => { + plugin = new CompanyInformation(global.bf); + }); - const execStr = path.resolve('bin', Os.platform().startsWith('win') ? 'run.cmd' : 'run'); + const configZAR: Config = { + defaultCurrencyIsoCode: 'English (South Africa) - ZAR' + }; + const configIRE: Config = { + defaultCurrencyIsoCode: 'English (Ireland) - EUR' + }; - it('should set the currency to "English (South Africa) - ZAR" for next steps', () => { - const bffile = path.join(__dirname, 'currency-zar.json'); - const apply = child.spawnSync(execStr, [ - 'browserforce:apply', - '-f', - bffile - ]); - assert.deepStrictEqual(apply.status, 0, apply.output.toString()); - // no additional assertions are done here as this is a preparation for the followup tests + it('should set the currency to "English (South Africa) - ZAR" for next steps', async () => { + await plugin.run(configZAR); }); - it('should change currency to "English (Ireland) - EUR"', () => { - const bffile = path.join(__dirname, 'currency-ireland.json'); - const apply = child.spawnSync(execStr, [ - 'browserforce:apply', - '-f', - bffile - ]); - assert.deepStrictEqual(apply.status, 0, apply.output.toString()); - assert.ok( - /to '"English \(Ireland\) - EUR"'/.test(apply.output.toString()), - apply.output.toString() - ); + it('should change currency to "English (Ireland) - EUR"', async () => { + await plugin.run(configIRE); }); - it('should respond to no action necessary for currency change', () => { - const bffile = path.join(__dirname, 'currency-ireland.json'); - const apply = child.spawnSync(execStr, [ - 'browserforce:apply', - '-f', - bffile - ]); - assert.deepStrictEqual(apply.status, 0, apply.output.toString()); - assert.ok( - /no action necessary/.test(apply.output.toString()), - apply.output.toString() - ); + it('should respond to no action necessary for currency change', async () => { + const res = await plugin.run(configIRE); + assert.deepStrictEqual(res, { message: 'no action necessary' }); }); - it('should error on invalid input for invalid currency', () => { - const bffile = path.join(__dirname, 'currency-invalid.json'); - const apply = child.spawnSync(execStr, [ - 'browserforce:apply', - '-f', - bffile - ]); - assert.notDeepStrictEqual(apply.status, 0, apply.output.toString()); - assert.ok( - /Invalid currency provided/.test(apply.output.toString()), - apply.output.toString() - ); + it('should error on invalid input for invalid currency', async () => { + let err; + try { + await plugin.apply({ defaultCurrencyIsoCode: 'Invalid Currency' }); + } catch (e) { + err = e; + } + assert.throws(() => { + throw err; + }, /Invalid currency provided/); }); }); diff --git a/src/plugins/company-information/index.ts b/src/plugins/company-information/index.ts index c6866a00..122a2105 100644 --- a/src/plugins/company-information/index.ts +++ b/src/plugins/company-information/index.ts @@ -9,8 +9,8 @@ const SELECTORS = { SAVE_BUTTON: 'input[class="btn"][type="submit"][name="save"]' }; -type Config = { - defaultCurrencyIsoCode?: string; +export type Config = { + defaultCurrencyIsoCode: string; }; export class CompanyInformation extends BrowserforcePlugin { @@ -19,22 +19,21 @@ export class CompanyInformation extends BrowserforcePlugin { const page = await this.browserforce.openPage(path.BASE); await page.waitForSelector(SELECTORS.CURRENCY_DROPDOWN); - const response = { + const response: Config = { defaultCurrencyIsoCode: '' }; - const selectedOptions = await page.$$eval( - `${SELECTORS.CURRENCY_DROPDOWN} > option[selected]`, - options => options.map(option => option.textContent) + const selectedOptions = await page.$$eval(`${SELECTORS.CURRENCY_DROPDOWN} > option[selected]`, (options) => + options.map((option) => option.textContent) ); - if (!selectedOptions) { - throw new Error('No available existing value'); + if (selectedOptions?.length) { + response.defaultCurrencyIsoCode = selectedOptions[0] ?? ''; } - response.defaultCurrencyIsoCode = selectedOptions[0]; + await page.close(); return response; } public async apply(config: Config): Promise { - if (config.defaultCurrencyIsoCode?.length > 0) { + if (config.defaultCurrencyIsoCode !== undefined) { const path = PATHS(this.org.getOrgId()); const page = await this.browserforce.openPage(path.BASE); @@ -45,29 +44,28 @@ export class CompanyInformation extends BrowserforcePlugin { // apply changes // await page.click(SELECTORS.CURRENCY_DROPDOWN); - const optionList = await page.$$eval( - `${SELECTORS.CURRENCY_DROPDOWN} > option`, - options => options.map(option => ({ + const optionList = await page.$$eval(`${SELECTORS.CURRENCY_DROPDOWN} > option`, (options) => + options.map((option) => ({ value: (option as HTMLOptionElement).value, textContent: option.textContent })) ); - const toBeSelectedOption = optionList.find(option => option.textContent == config.defaultCurrencyIsoCode); + const toBeSelectedOption = optionList.find((option) => option.textContent == config.defaultCurrencyIsoCode); if (!toBeSelectedOption) { - throw new Error(`Invalid currency provided. '${config.defaultCurrencyIsoCode}' is not a valid option available for currencies. Please use the exact name as it appears in the list.`); + throw new Error( + `Invalid currency provided. '${config.defaultCurrencyIsoCode}' is not a valid option available for currencies. Please use the exact name as it appears in the list.` + ); } - await selectElem.select(toBeSelectedOption.value); + await selectElem!.select(toBeSelectedOption.value); // auto accept the dialog when it appears - page.on("dialog", (dialog) => { + page.on('dialog', (dialog) => { dialog.accept(); }); // save - await Promise.all([ - page.waitForNavigation(), - page.click(SELECTORS.SAVE_BUTTON) - ]); + await Promise.all([page.waitForNavigation(), page.click(SELECTORS.SAVE_BUTTON)]); + await page.close(); } } } diff --git a/src/plugins/customer-portal/available-custom-objects/index.test.ts b/src/plugins/customer-portal/available-custom-objects/index.test.ts index 81147412..4b179d37 100644 --- a/src/plugins/customer-portal/available-custom-objects/index.test.ts +++ b/src/plugins/customer-portal/available-custom-objects/index.test.ts @@ -1,14 +1,19 @@ import assert from 'assert'; -import { CustomerPortalAvailableCustomObjects } from '.'; +import { type Config, CustomerPortalAvailableCustomObjects } from '.'; -const tests = [ +type T = { + description: string; + source: Config; + target: Config; + expected: Config; +}; +const tests: T[] = [ { description: 'should only return necessary fields', source: [ { _id: 'p1', name: 'Dummy', - namespacePrefix: null, available: false } ], @@ -21,15 +26,16 @@ const tests = [ expected: [ { _id: 'p1', + name: 'Dummy', available: true } - ] + ] as Config } ]; describe('CustomerPortalAvailableCustomObjects', () => { describe('diff()', () => { - const p = new CustomerPortalAvailableCustomObjects(null, null); + const p = new CustomerPortalAvailableCustomObjects(global.bf); for (const t of tests) { it(t.description, () => { const actual = p.diff(t.source, t.target); diff --git a/src/plugins/customer-portal/available-custom-objects/index.ts b/src/plugins/customer-portal/available-custom-objects/index.ts index 4baf515c..80815ba0 100644 --- a/src/plugins/customer-portal/available-custom-objects/index.ts +++ b/src/plugins/customer-portal/available-custom-objects/index.ts @@ -1,6 +1,6 @@ -import type { Record } from "jsforce"; -import * as jsonMergePatch from 'json-merge-patch'; +import type { Record } from 'jsforce'; import { BrowserforcePlugin } from '../../../plugin'; +import { semanticallyCleanObject } from '../../utils'; const SELECTORS = { SAVE_BUTTON: 'input[name="save"]', @@ -9,7 +9,7 @@ const SELECTORS = { interface CustomObjectRecord extends Record { DeveloperName: string; - NamespacePrefix: string; + NamespacePrefix?: string; } export type Config = AvailableCustomObjectConfig[]; @@ -22,11 +22,11 @@ type AvailableCustomObjectConfig = { }; export class CustomerPortalAvailableCustomObjects extends BrowserforcePlugin { - public async retrieve(definition?: Config): Promise { - const response = []; + public async retrieve(definition: Config): Promise { + const response: Config = []; if (definition) { const availableCustomObjectList = definition - .map(customObject => { + .map((customObject) => { return `'${customObject.name}'`; }) .join(','); @@ -36,32 +36,30 @@ export class CustomerPortalAvailableCustomObjects extends BrowserforcePlugin { `SELECT Id, DeveloperName, NamespacePrefix FROM CustomObject WHERE DeveloperName IN (${availableCustomObjectList})`, { scanAll: false } ); + for (const record of customObjects?.records) { + if (record.NamespacePrefix === null) { + record.NamespacePrefix = undefined; + } + } // BUG in jsforce: query acts with scanAll:true and returns deleted CustomObjects. // It cannot be disabled. // This will throw a timeout error waitingFor('#options_9') const page = await this.browserforce.openPage(''); // new URLs for LEX: https://help.salesforce.com/articleView?id=FAQ-for-the-New-URL-Format-for-Lightning-Experience-and-the-Salesforce-Mobile-App&type=1 - const isLEX = - page.url().indexOf('/one/one.app') >= 0 || - page.url().indexOf('/lightning/') >= 0; - const getObjectPageUrl = function(customObject, isLexUi = true) { + const isLEX = page.url().includes('/one/one.app') || page.url().includes('/lightning/'); + const getObjectPageUrl = function (customObject, isLexUi = true) { const classicUiPath = `${customObject._id}/e`; if (isLexUi) { return `lightning/setup/ObjectManager/${ customObject._id - }/edit?nodeId=ObjectManager&address=${encodeURIComponent( - `/${classicUiPath}` - )}`; + }/edit?nodeId=ObjectManager&address=${encodeURIComponent(`/${classicUiPath}`)}`; } else { return classicUiPath; } }; for (const availableCustomObject of definition) { - const customObject = customObjects.records.find(co => { - if (availableCustomObject.namespacePrefix === undefined) { - availableCustomObject.namespacePrefix = null; - } + const customObject = customObjects.records.find((co) => { return ( co.DeveloperName === availableCustomObject.name && co.NamespacePrefix === availableCustomObject.namespacePrefix @@ -73,7 +71,7 @@ export class CustomerPortalAvailableCustomObjects extends BrowserforcePlugin { ); } const result = { - _id: customObject.Id, + _id: customObject.Id!, name: customObject.DeveloperName, namespacePrefix: customObject.NamespacePrefix }; @@ -90,57 +88,52 @@ export class CustomerPortalAvailableCustomObjects extends BrowserforcePlugin { (el: HTMLInputElement) => el.checked ) }); + await editPage.close(); } + await page.close(); } return response; } - public diff(state: Config, definition: Config): Config { - const response = []; + public diff(state?: Config, definition?: Config): Config | undefined { + const response: Config = []; if (state && definition) { for (const availableCustomObject of definition) { - const oldCustomObject = state.find(customObject => { - if (availableCustomObject.namespacePrefix === undefined) { - availableCustomObject.namespacePrefix = null; - } + const oldCustomObject = state.find((customObject) => { return ( customObject.name === availableCustomObject.name && - customObject.namespacePrefix === - availableCustomObject.namespacePrefix + customObject.namespacePrefix === availableCustomObject.namespacePrefix ); }); - // move id of existing object to new object to be retained and used + if (!oldCustomObject) { + throw new Error(`Could not find CustomObject "${availableCustomObject.name}"`); + } + // copy id of existing object to new object to be retained and used availableCustomObject._id = oldCustomObject._id; - delete oldCustomObject._id; - const diff = jsonMergePatch.generate( - oldCustomObject, - availableCustomObject - ); - if (diff.available !== undefined) { + const diff = semanticallyCleanObject(super.diff(oldCustomObject, availableCustomObject), '_id') as + | AvailableCustomObjectConfig + | undefined; + if (diff?.available !== undefined) { response.push(diff); } } } - return response; + return response.length ? response : undefined; } public async apply(plan: Config): Promise { if (plan && plan.length) { const page = await this.browserforce.openPage(''); // new URLs for LEX: https://help.salesforce.com/articleView?id=FAQ-for-the-New-URL-Format-for-Lightning-Experience-and-the-Salesforce-Mobile-App&type=1 - const isLEX = - page.url().indexOf('/one/one.app') >= 0 || - page.url().indexOf('/lightning/') >= 0; - const getObjectPageUrl = function(customObject, isLexUi = true) { - const classicUiPath = `${customObject._id}/e?options_9=${ - customObject.available ? 1 : 0 - }&retURL=/${customObject._id}`; + const isLEX = page.url().includes('/one/one.app') || page.url().includes('/lightning/'); + const getObjectPageUrl = function (customObject, isLexUi = true) { + const classicUiPath = `${customObject._id}/e?options_9=${customObject.available ? 1 : 0}&retURL=/${ + customObject._id + }`; if (isLexUi) { return `lightning/setup/ObjectManager/${ customObject._id - }/edit?nodeId=ObjectManager&address=${encodeURIComponent( - `/${classicUiPath}` - )}`; + }/edit?nodeId=ObjectManager&address=${encodeURIComponent(`/${classicUiPath}`)}`; } else { return classicUiPath; } @@ -149,15 +142,11 @@ export class CustomerPortalAvailableCustomObjects extends BrowserforcePlugin { for (const customObject of plan) { const pageUrl = getObjectPageUrl(customObject, isLEX); const editPage = await this.browserforce.openPage(pageUrl); - const frameOrPage = await this.browserforce.waitForSelectorInFrameOrPage( - editPage, - SELECTORS.SAVE_BUTTON - ); - await Promise.all([ - frameOrPage.waitForNavigation(), - frameOrPage.click(SELECTORS.SAVE_BUTTON) - ]); + const frameOrPage = await this.browserforce.waitForSelectorInFrameOrPage(editPage, SELECTORS.SAVE_BUTTON); + await Promise.all([editPage.waitForNavigation(), frameOrPage.click(SELECTORS.SAVE_BUTTON)]); + await editPage.close(); } + await page.close(); } } } diff --git a/src/plugins/customer-portal/enabled/index.test.ts b/src/plugins/customer-portal/enabled/index.test.ts index 6f6a4d33..aa42672d 100644 --- a/src/plugins/customer-portal/enabled/index.test.ts +++ b/src/plugins/customer-portal/enabled/index.test.ts @@ -1,7 +1,14 @@ import assert from 'assert'; import { CustomerPortalEnable as CustomerPortalEnabled } from '.'; -const tests = [ +type T = { + description: string; + source: boolean; + target?: boolean; + expected?: boolean; +}; + +const tests: T[] = [ { description: 'should ignore a non-existent target flag', source: true, @@ -24,7 +31,7 @@ const tests = [ describe('CustomerPortalEnabled', () => { describe('diff()', () => { - const p = new CustomerPortalEnabled(null, null); + const p = new CustomerPortalEnabled(global.bf); for (const t of tests) { it(t.description, () => { const actual = p.diff(t.source, t.target); diff --git a/src/plugins/customer-portal/enabled/index.ts b/src/plugins/customer-portal/enabled/index.ts index 2b7b2722..1c2d3c3b 100644 --- a/src/plugins/customer-portal/enabled/index.ts +++ b/src/plugins/customer-portal/enabled/index.ts @@ -8,19 +8,13 @@ const SELECTORS = { SAVE_BUTTON: 'input[name="save"]' }; -export type Config = boolean; +export type Config = boolean | undefined; export class CustomerPortalEnable extends BrowserforcePlugin { - public async retrieve(definition?: Config): Promise { + public async retrieve(): Promise { const conn = await this.browserforce.org.getConnection(); const orgSettings = await conn.metadata.read('OrgSettings', 'Org'); - return orgSettings.enableCustomerSuccessPortal; - } - - public diff(state: Config, definition: Config): Config { - if (state !== definition) { - return definition; - } + return orgSettings.enableCustomerSuccessPortal ?? false; } public async apply(plan: Config): Promise { @@ -38,10 +32,8 @@ export class CustomerPortalEnable extends BrowserforcePlugin { }, plan ); - await Promise.all([ - page.waitForNavigation(), - page.click(SELECTORS.SAVE_BUTTON) - ]); + await Promise.all([page.waitForNavigation(), page.click(SELECTORS.SAVE_BUTTON)]); + await page.close(); } } } diff --git a/src/plugins/customer-portal/index.e2e-spec.ts b/src/plugins/customer-portal/index.e2e-spec.ts index 6f1607b2..37d79e56 100644 --- a/src/plugins/customer-portal/index.e2e-spec.ts +++ b/src/plugins/customer-portal/index.e2e-spec.ts @@ -5,258 +5,193 @@ import { CustomerPortalAvailableCustomObjects } from './available-custom-objects import { CustomerPortalEnable } from './enabled'; import { CustomerPortalSetup } from './portals'; -describe(CustomerPortalEnable.name, function() { - this.slow('30s'); - this.timeout('2m 30s'); - const dir = path.resolve(path.join(__dirname, 'enabled')); - it('should enable', () => { - const enableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(dir, 'enable.json') - ]); - assert.deepStrictEqual(enableCmd.status, 0, enableCmd.output.toString()); - assert.ok( - /to 'true'/.test(enableCmd.output.toString()), - enableCmd.output.toString() - ); - }); - it('should already be enabled', () => { - const enableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(dir, 'enable.json') - ]); - assert.deepStrictEqual(enableCmd.status, 0, enableCmd.output.toString()); - assert.ok( - /no action necessary/.test(enableCmd.output.toString()), - enableCmd.output.toString() - ); - }); - it('should fail to disable', () => { - const disableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(dir, 'disable.json') - ]); - assert.deepStrictEqual(disableCmd.status, 1, disableCmd.output.toString()); - assert.ok( - /to 'false'/.test(disableCmd.output.toString()), - disableCmd.output.toString() - ); - assert.ok( - /cannot be disabled/.test(disableCmd.output.toString()), - disableCmd.output.toString() - ); +describe('CustomerPortal', () => { + describe(CustomerPortalEnable.name, function () { + let plugin; + before(() => { + plugin = new CustomerPortalEnable(global.bf); + }); + + it('should enable', async () => { + await plugin.run(true); + }); + it('should be enabled', async () => { + const res = await plugin.retrieve(); + assert.deepStrictEqual(res, true); + }); + it('should fail to disable', async () => { + let err; + try { + await plugin.run(false); + } catch (e) { + err = e; + } + assert.throws(() => { + throw err; + }, /cannot be disabled/); + }); }); -}); -describe(CustomerPortalSetup.name, function() { - this.slow('30s'); - this.timeout('2m 30s'); - const dir = path.resolve(path.join(__dirname, 'portals')); - describe('portals', () => { - it('should fail to set portal admin user without permset', () => { - const setupPortalCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(dir, 'set-portal-admin.json') - ]); - assert.deepStrictEqual( - setupPortalCmd.status, - 1, - setupPortalCmd.output.toString() - ); - assert.ok( - /changing 'portals' to .*"User User"/.test( - setupPortalCmd.output.toString() - ), - setupPortalCmd.output.toString() - ); - assert.ok( - /This user has insufficient permissions to be a portal administrator/.test( - setupPortalCmd.output.toString() - ), - setupPortalCmd.output.toString() - ); + describe(CustomerPortalSetup.name, function () { + let plugin; + before(() => { + plugin = new CustomerPortalSetup(global.bf); }); - it('should setup user for portal', () => { - const sourceDeployCmd = child.spawnSync('sfdx', [ - 'force:source:deploy', - '-p', + + const configSetPortalAdmin = [ + { + name: 'Customer Portal', + adminUser: 'User User', + isSelfRegistrationActivated: true + } + ]; + const configSetupPortal = [ + { + name: 'Foo Portal', + oldName: 'Customer Portal', + description: 'Foo Portal', + adminUser: 'User User', + isSelfRegistrationActivated: true, + selfRegUserDefaultLicense: 'Customer Portal Manager Custom', + selfRegUserDefaultRole: 'User', + selfRegUserDefaultProfile: 'Customer Portal Manager Custom', + portalProfileMemberships: [ + { + name: 'Customer Portal Manager Standard', + active: false + }, + { + name: 'Dummy', + active: true + } + ] + } + ]; + const configRevertPortal = [ + { + name: 'Customer Portal', + oldName: 'Foo Portal', + description: 'Customer Portal', + isSelfRegistrationActivated: false + } + ]; + const dir = path.resolve(path.join(__dirname, 'portals')); + it('should fail to set portal admin user without permset', async () => { + let err; + try { + await plugin.run(configSetPortalAdmin); + } catch (e) { + err = e; + } + assert.throws(() => { + throw err; + }, /This user has insufficient permissions to be a portal administrator/); + }); + it('should set up user for portal', async () => { + const sourceDeployCmd = child.spawnSync('sf', [ + 'project', + 'deploy', + 'start', + '-d', path.join(dir, 'sfdx-source'), '--json' ]); - assert.deepStrictEqual( - sourceDeployCmd.status, - 0, - sourceDeployCmd.output.toString() - ); - const stdout = JSON.parse(sourceDeployCmd.stdout.toString()); - assert.ok( - stdout.result && - stdout.result.deployedSource && - stdout.result.deployedSource.find( - source => source.fullName === 'Customer_Portal_Admin' - ), - sourceDeployCmd.output.toString() - ); - const permSetAssignCmd = child.spawnSync('sfdx', [ - 'force:user:permset:assign', - '-n', - 'Customer_Portal_Admin' - ]); - assert.deepStrictEqual( - permSetAssignCmd.status, - 0, - permSetAssignCmd.output.toString() - ); - assert.ok( - /Customer_Portal_Admin/.test(permSetAssignCmd.output.toString()), - permSetAssignCmd.output.toString() - ); + assert.deepStrictEqual(sourceDeployCmd.status, 0, sourceDeployCmd.output.toString()); + const permSetAssignCmd = child.spawnSync('sf', ['org', 'assign', 'permset', '-n', 'Customer_Portal_Admin']); + assert.deepStrictEqual(permSetAssignCmd.status, 0, permSetAssignCmd.output.toString()); }); - it('should setup portal', () => { - const setupPortalCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(dir, 'setup-portal.json') - ]); - assert.deepStrictEqual( - setupPortalCmd.status, - 0, - setupPortalCmd.output.toString() - ); - assert.ok( - /changing 'portals' to .*"name":"Foo Portal"/.test( - setupPortalCmd.output.toString() - ), - setupPortalCmd.output.toString() - ); - assert.ok( - /changing 'portals' to .*isSelfRegistrationActivated/.test( - setupPortalCmd.output.toString() - ), - setupPortalCmd.output.toString() - ); - assert.ok( - /changing 'portals' to .*portalProfileMemberships/.test( - setupPortalCmd.output.toString() - ), - setupPortalCmd.output.toString() - ); + it('should set up portal', async () => { + await plugin.run(configSetupPortal); }); - it('should already be set up', () => { - const setupPortalCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(dir, 'setup-portal.json') + it('portal should be set up', async () => { + const res = await plugin.run(configSetupPortal); + assert.deepStrictEqual(res, { message: 'no action necessary' }); + }); + it('should revert back', async () => { + await plugin.run(configRevertPortal); + }); + it('should be reverted back', async () => { + const res = await plugin.run(configRevertPortal); + assert.deepStrictEqual(res, { message: 'no action necessary' }); + }); + it('should cleanup', async () => { + const conn = global.bf.org.getConnection(); + await conn.metadata.delete('Profile', ['Dummy']); + const permSetUnassignCmd = child.spawnSync('sf', [ + 'data', + 'delete', + 'record', + '-s', + 'PermissionSetAssignment', + '-w', + 'PermissionSet.Name=Customer_Portal_Admin' ]); - assert.deepStrictEqual( - setupPortalCmd.status, - 0, - setupPortalCmd.output.toString() - ); - assert.ok( - /no action necessary/.test(setupPortalCmd.output.toString()), - setupPortalCmd.output.toString() - ); + assert.deepStrictEqual(permSetUnassignCmd.status, 0, permSetUnassignCmd.output.toString()); + await conn.metadata.delete('PermissionSet', ['Customer_Portal_Admin']); }); }); -}); -describe(CustomerPortalAvailableCustomObjects.name, function() { - this.slow('30s'); - this.timeout('2m 30s'); - const dir = path.resolve(path.join(__dirname, 'available-custom-objects')); - it('should fail to make non-existent custom objects available for customer portal', () => { - const setupPortalCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(dir, 'available.json') - ]); - assert.deepStrictEqual( - setupPortalCmd.status, - 1, - setupPortalCmd.output.toString() - ); - assert.ok( - /Could not find CustomObject/.test(setupPortalCmd.output.toString()), - setupPortalCmd.output.toString() - ); - }); - it('should deploy custom object', () => { - const sourceDeployCmd = child.spawnSync('sfdx', [ - 'force:source:deploy', - '-p', - path.join(dir, 'sfdx-source'), - '--json' - ]); - assert.deepStrictEqual( - sourceDeployCmd.status, - 0, - sourceDeployCmd.output.toString() - ); - const stdout = JSON.parse(sourceDeployCmd.stdout.toString()); - assert.ok( - stdout.result && - stdout.result.deployedSource && - stdout.result.deployedSource.find( - source => source.fullName === 'Dummy__c' - ), - sourceDeployCmd.output.toString() - ); - }); - it('should make custom objects available for customer portal', () => { - const setupCustomObjectsCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(dir, 'available.json') - ]); - assert.deepStrictEqual( - setupCustomObjectsCmd.status, - 0, - setupCustomObjectsCmd.output.toString() - ); - assert.ok( - /changing 'availableCustomObjects' to .*"available":true/.test( - setupCustomObjectsCmd.output.toString() - ), - setupCustomObjectsCmd.output.toString() - ); - }); - it('should have applied checkbox available for customer portal', () => { - const setupCustomObjectsCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(dir, 'available.json') - ]); - assert.deepStrictEqual( - setupCustomObjectsCmd.status, - 0, - setupCustomObjectsCmd.output.toString() - ); - assert.ok( - /no action necessary/.test(setupCustomObjectsCmd.output.toString()), - setupCustomObjectsCmd.output.toString() - ); - }); - it('should make custom objects unavailable for customer portal', () => { - const setupCustomObjectsCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(dir, 'unavailable.json') - ]); - assert.deepStrictEqual( - setupCustomObjectsCmd.status, - 0, - setupCustomObjectsCmd.output.toString() - ); - assert.ok( - /changing 'availableCustomObjects' to .*"available":false/.test( - setupCustomObjectsCmd.output.toString() - ), - setupCustomObjectsCmd.output.toString() - ); + describe(CustomerPortalAvailableCustomObjects.name, function () { + let plugin; + before(() => { + plugin = new CustomerPortalAvailableCustomObjects(global.bf); + }); + + const configAvailableCustomObjects = [ + { + name: 'Dummy', + available: true + } + ]; + const configNonAvailableCustomObjects = [ + { + name: 'DummyXYZ', + available: true + } + ]; + const configUnavailableCustomObjects = [ + { + name: 'Dummy', + available: false + } + ]; + + const dir = path.resolve(path.join(__dirname, 'available-custom-objects')); + it('should fail to make non-existent custom objects available for customer portal', async () => { + let err; + try { + await plugin.run(configNonAvailableCustomObjects); + } catch (e) { + err = e; + } + assert.throws(() => { + throw err; + }, /Could not find CustomObject/); + }); + it('should deploy custom object', () => { + const sourceDeployCmd = child.spawnSync('sf', [ + 'project', + 'deploy', + 'start', + '-d', + path.join(dir, 'sfdx-source'), + '--json' + ]); + assert.deepStrictEqual(sourceDeployCmd.status, 0, sourceDeployCmd.output.toString()); + }); + it('should make custom objects available for customer portal', async () => { + await plugin.run(configAvailableCustomObjects); + }); + it('should have applied checkbox available for customer portal', async () => { + const res = await plugin.run(configAvailableCustomObjects); + assert.deepStrictEqual(res, { message: 'no action necessary' }); + }); + it('should make custom objects unavailable for customer portal', async () => { + await plugin.run(configUnavailableCustomObjects); + }); + it('should remove the CustomObject', async () => { + const conn = global.bf.org.getConnection(); + await conn.metadata.delete('CustomObject', ['Dummy__c']); + }); }); }); diff --git a/src/plugins/customer-portal/index.test.ts b/src/plugins/customer-portal/index.test.ts index 97e01429..c1fd68aa 100644 --- a/src/plugins/customer-portal/index.test.ts +++ b/src/plugins/customer-portal/index.test.ts @@ -8,7 +8,7 @@ const tests = [ enabled: true }, target: {}, - expected: {} + expected: undefined }, { description: 'should ignore a matching target flag', @@ -18,7 +18,7 @@ const tests = [ target: { enabled: true }, - expected: {} + expected: undefined }, { description: 'should detect a changed flag', @@ -63,6 +63,7 @@ const tests = [ expected: { portals: [ { + name: 'Customer Portal', description: 'new description', _id: 'p1' } @@ -73,7 +74,7 @@ const tests = [ describe('CustomerPortal', () => { describe('diff()', () => { - const p = new CustomerPortal(null, null); + const p = new CustomerPortal(global.bf); for (const t of tests) { it(t.description, () => { const actual = p.diff(t.source, t.target); diff --git a/src/plugins/customer-portal/index.ts b/src/plugins/customer-portal/index.ts index d64fc3e3..ab796ee7 100644 --- a/src/plugins/customer-portal/index.ts +++ b/src/plugins/customer-portal/index.ts @@ -1,17 +1,10 @@ import { BrowserforcePlugin } from '../../plugin'; -import { removeEmptyValues } from '../utils'; import { - Config as CustomerPortalAvailableCustomObjectsConfig, - CustomerPortalAvailableCustomObjects + CustomerPortalAvailableCustomObjects, + Config as CustomerPortalAvailableCustomObjectsConfig } from './available-custom-objects'; -import { - Config as CustomerPortalEnableConfig, - CustomerPortalEnable -} from './enabled'; -import { - Config as CustomerPortalSetupConfig, - CustomerPortalSetup -} from './portals'; +import { CustomerPortalEnable, Config as CustomerPortalEnableConfig } from './enabled'; +import { CustomerPortalSetup, Config as CustomerPortalSetupConfig } from './portals'; type Config = { enabled?: CustomerPortalEnableConfig; @@ -20,27 +13,21 @@ type Config = { }; export class CustomerPortal extends BrowserforcePlugin { - public async retrieve(definition?: Config): Promise { - const pluginEnable = new CustomerPortalEnable(this.browserforce, this.org); - const response = { + public async retrieve(definition: Config): Promise { + const pluginEnable = new CustomerPortalEnable(this.browserforce); + const response: Config = { enabled: false, portals: [], availableCustomObjects: [] }; - response.enabled = await pluginEnable.retrieve(definition.enabled); + response.enabled = await pluginEnable.retrieve(); if (response.enabled) { if (definition.portals) { - const pluginSetup = new CustomerPortalSetup( - this.browserforce, - this.org - ); - response.portals = await pluginSetup.retrieve(definition.portals); + const pluginSetup = new CustomerPortalSetup(this.browserforce); + response.portals = await pluginSetup.retrieve(); } if (definition.availableCustomObjects) { - const pluginAvailableCustomObjects = new CustomerPortalAvailableCustomObjects( - this.browserforce, - this.org - ); + const pluginAvailableCustomObjects = new CustomerPortalAvailableCustomObjects(this.browserforce); response.availableCustomObjects = await pluginAvailableCustomObjects.retrieve( definition.availableCustomObjects ); @@ -49,41 +36,40 @@ export class CustomerPortal extends BrowserforcePlugin { return response; } - public diff(state: Config, definition: Config): Config { - const pluginEnable = new CustomerPortalEnable(null, null); - const pluginSetup = new CustomerPortalSetup(null, null); - const pluginAvailableCustomObjects = new CustomerPortalAvailableCustomObjects( - null, - null + public diff(state: Config, definition: Config): Config | undefined { + const enabled = new CustomerPortalEnable(this.browserforce).diff(state.enabled, definition.enabled) as + | boolean + | undefined; + const portals = new CustomerPortalSetup(this.browserforce).diff(state.portals, definition.portals); + const availableCustomObjects = new CustomerPortalAvailableCustomObjects(this.browserforce).diff( + state.availableCustomObjects, + definition.availableCustomObjects ); - const response = { - enabled: pluginEnable.diff(state.enabled, definition.enabled), - portals: pluginSetup.diff(state.portals, definition.portals), - availableCustomObjects: pluginAvailableCustomObjects.diff( - state.availableCustomObjects, - definition.availableCustomObjects - ) + const response: Config = { + ...(enabled !== undefined && { + enabled + }), + ...(portals !== undefined && { + portals + }), + ...(availableCustomObjects !== undefined && { + availableCustomObjects + }) }; - return removeEmptyValues(response); + return Object.keys(response).length ? response : undefined; } public async apply(config: Config): Promise { if (config.enabled !== undefined) { - const pluginEnable = new CustomerPortalEnable( - this.browserforce, - this.org - ); + const pluginEnable = new CustomerPortalEnable(this.browserforce); await pluginEnable.apply(config.enabled); } - if (config.portals && config.portals.length) { - const pluginSetup = new CustomerPortalSetup(this.browserforce, this.org); + if (config.portals?.length) { + const pluginSetup = new CustomerPortalSetup(this.browserforce); await pluginSetup.apply(config.portals); } if (config.availableCustomObjects) { - const pluginAvailableCustomObjects = new CustomerPortalAvailableCustomObjects( - this.browserforce, - this.org - ); + const pluginAvailableCustomObjects = new CustomerPortalAvailableCustomObjects(this.browserforce); await pluginAvailableCustomObjects.apply(config.availableCustomObjects); } } diff --git a/src/plugins/customer-portal/portals/index.test.ts b/src/plugins/customer-portal/portals/index.test.ts index 3a621734..5aa62ece 100644 --- a/src/plugins/customer-portal/portals/index.test.ts +++ b/src/plugins/customer-portal/portals/index.test.ts @@ -25,13 +25,13 @@ const tests = [ expected: [ { _id: 'p1', + name: 'Customer Portal', description: 'new description' } ] }, { - description: - 'should only return portal and portalProfileMemberships fields', + description: 'should only return portal and portalProfileMemberships fields', source: [ { name: 'Customer Portal', @@ -61,9 +61,11 @@ const tests = [ expected: [ { _id: 'p1', + name: 'Customer Portal', portalProfileMemberships: [ { _id: 'a1', + name: 'Customer Portal Manager Standard', active: false } ] @@ -122,13 +124,13 @@ const tests = [ ] } ], - expected: [] + expected: undefined } ]; describe('CustomerPortalSetup', () => { describe('diff()', () => { - const p = new CustomerPortalSetup(null, null); + const p = new CustomerPortalSetup(global.bf); for (const t of tests) { it(t.description, () => { const actual = p.diff(t.source, t.target); diff --git a/src/plugins/customer-portal/portals/index.ts b/src/plugins/customer-portal/portals/index.ts index 551dc6c8..7eb02a82 100644 --- a/src/plugins/customer-portal/portals/index.ts +++ b/src/plugins/customer-portal/portals/index.ts @@ -1,7 +1,6 @@ -import * as jsonMergePatch from 'json-merge-patch'; import * as queryString from 'querystring'; import { BrowserforcePlugin } from '../../../plugin'; -import { removeNullValues, semanticallyCleanObject } from '../../utils'; +import { semanticallyCleanObject } from '../../utils'; const PATHS = { LIST_VIEW: '_ui/core/portal/CustomerSuccessPortalSetup/d', @@ -44,32 +43,27 @@ type PortalProfileMembership = { }; export class CustomerPortalSetup extends BrowserforcePlugin { - public async retrieve(definition?: Config): Promise { + public async retrieve(): Promise { const page = await this.browserforce.openPage(PATHS.LIST_VIEW); await page.waitForXPath(SELECTORS.LIST_VIEW_PORTAL_LINKS_XPATH); - const customerPortalLinks = await page.$x( - SELECTORS.LIST_VIEW_PORTAL_LINKS_XPATH + const customerPortalLinks = await page.$x(SELECTORS.LIST_VIEW_PORTAL_LINKS_XPATH); + const response: Config = await page.evaluate( + (...links) => { + return links.map((a: HTMLAnchorElement) => { + return { + _id: a.pathname.split('/')[1], + name: a.text, + portalProfileMemberships: [] + }; + }); + }, + ...customerPortalLinks ); - const response: Config = await page.evaluate((...links) => { - return links.map((a: HTMLAnchorElement) => { - return { - _id: a.pathname.split('/')[1], - name: a.text, - portalProfileMemberships: [] - }; - }); - }, ...customerPortalLinks); for (const portal of response) { const portalPage = await this.browserforce.openPage(`${portal._id}/e`); await portalPage.waitForSelector(SELECTORS.PORTAL_DESCRIPTION); - portal.description = await portalPage.$eval( - SELECTORS.PORTAL_DESCRIPTION, - (el: HTMLInputElement) => el.value - ); - portal.adminUser = await portalPage.$eval( - `#${SELECTORS.PORTAL_ADMIN_ID}`, - (el: HTMLInputElement) => el.value - ); + portal.description = await portalPage.$eval(SELECTORS.PORTAL_DESCRIPTION, (el: HTMLInputElement) => el.value); + portal.adminUser = await portalPage.$eval(`#${SELECTORS.PORTAL_ADMIN_ID}`, (el: HTMLInputElement) => el.value); portal.isSelfRegistrationActivated = await portalPage.$eval( `#${SELECTORS.PORTAL_IS_SELF_REGISTRATION_ACTIVATED_ID}`, (el: HTMLInputElement) => el.checked @@ -86,6 +80,7 @@ export class CustomerPortalSetup extends BrowserforcePlugin { `#${SELECTORS.PORTAL_SELF_REG_USER_DEFAULT_PROFILE_ID}`, (el: HTMLSelectElement) => el.selectedOptions[0].text ); + await portalPage.close(); // portalProfileMemberships const portalProfilePage = await this.browserforce.openPage( `${PATHS.PORTAL_PROFILE_MEMBERSHIP}?portalId=${portal._id}&setupid=CustomerSuccessPortalSettings` @@ -94,13 +89,13 @@ export class CustomerPortalSetup extends BrowserforcePlugin { const profiles = await portalProfilePage.$$eval( SELECTORS.PORTAL_PROFILE_MEMBERSHIP_PROFILES, (ths: HTMLTableHeaderCellElement[]) => { - return ths.map(th => th.innerText.trim()); + return ths.map((th) => th.innerText.trim()); } ); const checkboxes = await portalProfilePage.$$eval( SELECTORS.PORTAL_PROFILE_MEMBERSHIP_CHECKBOXES, (inputs: HTMLInputElement[]) => { - return inputs.map(input => { + return inputs.map((input) => { return { active: input.checked, _id: input.id @@ -108,7 +103,7 @@ export class CustomerPortalSetup extends BrowserforcePlugin { }); } ); - const portalProfileMemberships = []; + const portalProfileMemberships: PortalProfileMembership[] = []; for (let i = 0; i < profiles.length; i++) { portalProfileMemberships.push({ name: profiles[i], @@ -117,18 +112,21 @@ export class CustomerPortalSetup extends BrowserforcePlugin { }); } portal.portalProfileMemberships = portalProfileMemberships; + await portalProfilePage.close(); } + await page.close(); return response; } - public diff(source: Config, target: Config): Config { - const response = []; + public diff(source?: Config, target?: Config): Config | undefined { + const response: Config = []; if (source && target) { - for (const portal of target) { - let sourcePortal = source.find(p => p.name === portal.name); + for (const plannedPortal of target) { + const portal: PortalConfig = JSON.parse(JSON.stringify(plannedPortal)); + let sourcePortal = source.find((p) => p.name === portal.name); if (portal.oldName && !sourcePortal) { // fallback to old name of portal - sourcePortal = source.find(p => p.name === portal.oldName); + sourcePortal = source.find((p) => p.name === portal.oldName); } if (!sourcePortal) { throw new Error( @@ -137,32 +135,22 @@ export class CustomerPortalSetup extends BrowserforcePlugin { } delete portal.oldName; if (sourcePortal) { - // move id of existing portal to new portal to be retained and used + // copy id of existing portal to new portal to be retained and used portal._id = sourcePortal._id; - delete sourcePortal._id; } - if ( - sourcePortal.portalProfileMemberships && - portal.portalProfileMemberships - ) { - const membershipResponse = []; + if (sourcePortal.portalProfileMemberships && portal.portalProfileMemberships) { + const membershipResponse: PortalProfileMembership[] = []; for (const member of portal.portalProfileMemberships) { - // move id of existing member to new member to be retained and used - const sourceMember = sourcePortal.portalProfileMemberships.find( - m => m.name === member.name - ); + // copy id of existing member to new member to be retained and used + const sourceMember = sourcePortal.portalProfileMemberships.find((m) => m.name === member.name); if (sourceMember) { member._id = sourceMember._id; - delete sourceMember._id; } else { - throw new Error( - `Could not find portal profile membership for '${member.name}'` - ); + throw new Error(`Could not find portal profile membership for '${member.name}'`); } - const membershipDiff = semanticallyCleanObject( - removeNullValues(jsonMergePatch.generate(sourceMember, member)), - '_id' - ); + const membershipDiff = semanticallyCleanObject(super.diff(sourceMember, member), '_id') as + | PortalProfileMembership + | undefined; if (membershipDiff) { membershipResponse.push(membershipDiff); } @@ -173,16 +161,13 @@ export class CustomerPortalSetup extends BrowserforcePlugin { portal.portalProfileMemberships = membershipResponse; } } - const diff = semanticallyCleanObject( - removeNullValues(jsonMergePatch.generate(sourcePortal, portal)), - '_id' - ); - if (diff) { + const diff = semanticallyCleanObject(super.diff(sourcePortal, portal), '_id') as PortalConfig | undefined; + if (diff !== undefined) { response.push(diff); } } } - return response; + return response.length ? response : undefined; } public async apply(config: Config): Promise { @@ -200,13 +185,11 @@ export class CustomerPortalSetup extends BrowserforcePlugin { urlAttributes[SELECTORS.PORTAL_ADMIN_ID] = portal.adminUser; } if (portal.isSelfRegistrationActivated !== undefined) { - urlAttributes[ - SELECTORS.PORTAL_IS_SELF_REGISTRATION_ACTIVATED_ID - ] = portal.isSelfRegistrationActivated ? 1 : 0; + urlAttributes[SELECTORS.PORTAL_IS_SELF_REGISTRATION_ACTIVATED_ID] = portal.isSelfRegistrationActivated + ? 1 + : 0; } - const page = await this.browserforce.openPage( - `${portal._id}/e?${queryString.stringify(urlAttributes)}` - ); + const page = await this.browserforce.openPage(`${portal._id}/e?${queryString.stringify(urlAttributes)}`); await page.waitForSelector(SELECTORS.PORTAL_DESCRIPTION); if (portal.selfRegUserDefaultLicense) { const licenseValue = await page.evaluate( @@ -217,10 +200,7 @@ export class CustomerPortalSetup extends BrowserforcePlugin { ) )[0] ); - await page.select( - `#${SELECTORS.PORTAL_SELF_REG_USER_DEFAULT_LICENSE_ID}`, - licenseValue - ); + await page.select(`#${SELECTORS.PORTAL_SELF_REG_USER_DEFAULT_LICENSE_ID}`, licenseValue); } if (portal.selfRegUserDefaultRole) { const roleValue = await page.evaluate( @@ -231,10 +211,7 @@ export class CustomerPortalSetup extends BrowserforcePlugin { ) )[0] ); - await page.select( - `#${SELECTORS.PORTAL_SELF_REG_USER_DEFAULT_ROLE_ID}`, - roleValue - ); + await page.select(`#${SELECTORS.PORTAL_SELF_REG_USER_DEFAULT_ROLE_ID}`, roleValue); } if (portal.selfRegUserDefaultProfile) { const profileValue = await page.evaluate( @@ -245,16 +222,10 @@ export class CustomerPortalSetup extends BrowserforcePlugin { ) )[0] ); - await page.select( - `#${SELECTORS.PORTAL_SELF_REG_USER_DEFAULT_PROFILE_ID}`, - profileValue - ); + await page.select(`#${SELECTORS.PORTAL_SELF_REG_USER_DEFAULT_PROFILE_ID}`, profileValue); } await page.waitForSelector(SELECTORS.SAVE_BUTTON); - await Promise.all([ - page.waitForNavigation(), - page.click(SELECTORS.SAVE_BUTTON) - ]); + await Promise.all([page.waitForNavigation(), page.click(SELECTORS.SAVE_BUTTON)]); if ((await page.url()).includes(portal._id)) { // error handling await page.waitForSelector(SELECTORS.PORTAL_DESCRIPTION); @@ -265,21 +236,18 @@ export class CustomerPortalSetup extends BrowserforcePlugin { if (portal.portalProfileMemberships) { const membershipUrlAttributes = {}; for (const member of portal.portalProfileMemberships) { - membershipUrlAttributes[member._id] = member.active ? 1 : 0; + membershipUrlAttributes[member._id!] = member.active ? 1 : 0; } const portalProfilePage = await this.browserforce.openPage( `${PATHS.PORTAL_PROFILE_MEMBERSHIP}?portalId=${ portal._id - }&setupid=CustomerSuccessPortalSettings&${queryString.stringify( - membershipUrlAttributes - )}` + }&setupid=CustomerSuccessPortalSettings&${queryString.stringify(membershipUrlAttributes)}` ); await portalProfilePage.waitForSelector(SELECTORS.SAVE_BUTTON); - await Promise.all([ - portalProfilePage.waitForNavigation(), - portalProfilePage.click(SELECTORS.SAVE_BUTTON) - ]); + await Promise.all([portalProfilePage.waitForNavigation(), portalProfilePage.click(SELECTORS.SAVE_BUTTON)]); + await portalProfilePage.close(); } + await page.close(); } } } diff --git a/src/plugins/defer-sharing-calculation/index.e2e-spec.ts b/src/plugins/defer-sharing-calculation/index.e2e-spec.ts index 26e1fcbe..b4be13fa 100644 --- a/src/plugins/defer-sharing-calculation/index.e2e-spec.ts +++ b/src/plugins/defer-sharing-calculation/index.e2e-spec.ts @@ -3,93 +3,65 @@ import * as child from 'child_process'; import * as path from 'path'; import { DeferSharingCalculation } from '.'; -describe(DeferSharingCalculation.name, function() { - this.slow('30s'); - this.timeout('2m'); +describe(DeferSharingCalculation.name, function () { + let plugin; + before(() => { + plugin = new DeferSharingCalculation(global.bf); + }); + const configSuspend = { + suspend: true + }; + const configResume = { + suspend: false + }; it('should assign the user defer sharing permissions', () => { - const sourceDeployCmd = child.spawnSync('sfdx', [ - 'force:source:deploy', - '-p', + const sourceDeployCmd = child.spawnSync('sf', [ + 'project', + 'deploy', + 'start', + '-d', path.join(__dirname, 'sfdx-source'), '--json' ]); - assert.deepStrictEqual( - sourceDeployCmd.status, - 0, - sourceDeployCmd.output.toString() - ); - const stdout = JSON.parse(sourceDeployCmd.stdout.toString()); - assert.ok( - stdout.result && - stdout.result.deployedSource && - stdout.result.deployedSource.find( - source => source.fullName === 'Defer_Sharing' - ), - sourceDeployCmd.output.toString() - ); - const permSetAssignCmd = child.spawnSync('sfdx', [ - 'force:user:permset:assign', - '-n', - 'Defer_Sharing' - ]); - assert.deepStrictEqual( - permSetAssignCmd.status, - 0, - permSetAssignCmd.output.toString() - ); - assert.ok( - /Defer_Sharing/.test(permSetAssignCmd.output.toString()), - permSetAssignCmd.output.toString() - ); + assert.deepStrictEqual(sourceDeployCmd.status, 0, sourceDeployCmd.output.toString()); + const permSetAssignCmd = child.spawnSync('sf', ['org', 'assign', 'permset', '-n', 'Defer_Sharing']); + assert.deepStrictEqual(permSetAssignCmd.status, 0, permSetAssignCmd.output.toString()); }); - it('should suspend', () => { - const suspendCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'suspend.json')) - ]); - assert.deepStrictEqual(suspendCmd.status, 0, suspendCmd.output.toString()); - assert.ok( - /to 'true'/.test(suspendCmd.output.toString()), - suspendCmd.output.toString() - ); + it('should suspend', async () => { + await plugin.run(configSuspend); }); - it('should already be suspended', () => { - const suspendCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(__dirname, 'suspend.json') - ]); - assert.deepStrictEqual(suspendCmd.status, 0, suspendCmd.output.toString()); - assert.ok( - /no action necessary/.test(suspendCmd.output.toString()), - suspendCmd.output.toString() - ); + it('should already be suspended', async () => { + const res = await plugin.run(configSuspend); + assert.deepStrictEqual(res, { message: 'no action necessary' }); }); - it('should resume', () => { - const resumeCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'resume.json')) - ]); - assert.deepStrictEqual(resumeCmd.status, 0, resumeCmd.output.toString()); - assert.ok( - /to 'false'/.test(resumeCmd.output.toString()), - resumeCmd.output.toString() - ); + it('should resume', async () => { + await plugin.run(configResume); + }); + it('should already be resumed', async () => { + let err; + let res; + try { + res = await plugin.run(configResume); + } catch (e) { + err = e; + assert.throws(() => { + throw err; + }, /Sharing recalculation is currently in progress, please wait until this has completed to plan/); + } + if (!err) { + assert.deepStrictEqual(res, { message: 'no action necessary' }); + } }); - it('should already be resumed', () => { - const resumeCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(__dirname, 'resume.json') + it('should delete the PermissionSetAssignment', async () => { + const permSetUnassignCmd = child.spawnSync('sf', [ + 'data', + 'delete', + 'record', + '-s', + 'PermissionSetAssignment', + '-w', + 'PermissionSet.Name=Defer_Sharing' ]); - assert.ok( - /no action necessary/.test(resumeCmd.output.toString()) || - /Sharing recalculation is currently in progress, please wait until this has completed to plan/.test( - resumeCmd.output.toString() - ), - resumeCmd.output.toString() - ); + assert.deepStrictEqual(permSetUnassignCmd.status, 0, permSetUnassignCmd.output.toString()); }); }); diff --git a/src/plugins/defer-sharing-calculation/index.ts b/src/plugins/defer-sharing-calculation/index.ts index 1b49abd5..25845b4c 100644 --- a/src/plugins/defer-sharing-calculation/index.ts +++ b/src/plugins/defer-sharing-calculation/index.ts @@ -19,19 +19,12 @@ export class DeferSharingCalculation extends BrowserforcePlugin { await page.waitForSelector(SELECTORS.SUSPEND_BUTTON); await page.waitForSelector(SELECTORS.RESUME_BUTTON); - const isSuspendDisabled = await page.$eval( - SELECTORS.SUSPEND_BUTTON, - (el: HTMLInputElement) => el.disabled - ); - const isResumeDisabled = await page.$eval( - SELECTORS.RESUME_BUTTON, - (el: HTMLInputElement) => el.disabled - ); + const isSuspendDisabled = await page.$eval(SELECTORS.SUSPEND_BUTTON, (el: HTMLInputElement) => el.disabled); + const isResumeDisabled = await page.$eval(SELECTORS.RESUME_BUTTON, (el: HTMLInputElement) => el.disabled); if (isSuspendDisabled && isResumeDisabled) { - throw new Error( - 'Sharing recalculation is currently in progress, please wait until this has completed to plan' - ); + throw new Error('Sharing recalculation is currently in progress, please wait until this has completed to plan'); } + await page.close(); return { suspend: isSuspendDisabled }; @@ -39,19 +32,15 @@ export class DeferSharingCalculation extends BrowserforcePlugin { public async apply(config: Config): Promise { const page = await this.browserforce.openPage(PATHS.BASE); - const button = config.suspend - ? SELECTORS.SUSPEND_BUTTON - : SELECTORS.RESUME_BUTTON; + const button = config.suspend ? SELECTORS.SUSPEND_BUTTON : SELECTORS.RESUME_BUTTON; await page.waitForSelector(button); await Promise.all([page.waitForNavigation(), page.click(button)]); + await page.close(); if (!config.suspend) { - await page.close(); const refreshedPage = await this.browserforce.openPage(PATHS.BASE); await refreshedPage.waitForSelector(SELECTORS.RECALCULATE_BUTTON); - await Promise.all([ - refreshedPage.waitForNavigation(), - refreshedPage.click(SELECTORS.RECALCULATE_BUTTON) - ]); + await Promise.all([refreshedPage.waitForNavigation(), refreshedPage.click(SELECTORS.RECALCULATE_BUTTON)]); + await refreshedPage.close(); } } } diff --git a/src/plugins/density-settings/index.e2e-spec.ts b/src/plugins/density-settings/index.e2e-spec.ts index eceff9a8..bf36cf2e 100644 --- a/src/plugins/density-settings/index.e2e-spec.ts +++ b/src/plugins/density-settings/index.e2e-spec.ts @@ -1,73 +1,40 @@ import assert from 'assert'; -import * as child from 'child_process'; -import * as path from 'path'; import { DensitySettings } from '.'; -describe(DensitySettings.name, function() { - this.slow('30s'); - this.timeout('2m'); - it('should set to Compact', () => { - const setCompactCommand = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'compact.json')) - ]); - assert.deepStrictEqual( - setCompactCommand.status, - 0, - setCompactCommand.output.toString() - ); - assert.ok( - /to '"Compact"'/.test(setCompactCommand.output.toString()), - setCompactCommand.output.toString() - ); +describe(DensitySettings.name, function () { + let plugin; + before(() => { + plugin = new DensitySettings(global.bf); }); - it('should already be set to Compact', () => { - const setCompactCommand2 = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'compact.json')) - ]); - assert.deepStrictEqual( - setCompactCommand2.status, - 0, - setCompactCommand2.output.toString() - ); - assert.ok( - /no action necessary/.test(setCompactCommand2.output.toString()), - setCompactCommand2.output.toString() - ); + + const configComfy = { + density: 'Comfy' + }; + const configCompact = { density: 'Compact' }; + + it('should set to Compact', async () => { + await plugin.run(configCompact); + }); + it('should be set to Compact', async () => { + const res = await plugin.retrieve(); + assert.deepStrictEqual(res, configCompact); + }); + it('should set to Comfy', async () => { + await plugin.apply(configComfy); }); - it('should set to Comfy', () => { - const setComfyCommand = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'comfy.json')) - ]); - assert.deepStrictEqual( - setComfyCommand.status, - 0, - setComfyCommand.output.toString() - ); - assert.ok( - /to '"Comfy"'/.test(setComfyCommand.output.toString()), - setComfyCommand.output.toString() - ); + it('should be set to Comfy', async () => { + const res = await plugin.retrieve(); + assert.deepStrictEqual(res, configComfy); }); - it('should already be set to Comfy', () => { - const setComfyCommand2 = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'comfy.json')) - ]); - assert.deepStrictEqual( - setComfyCommand2.status, - 0, - setComfyCommand2.output.toString() - ); - assert.ok( - /no action necessary/.test(setComfyCommand2.output.toString()), - setComfyCommand2.output.toString() - ); + it('should throw for invalid density', async () => { + let err; + try { + await plugin.run({ density: 'Foo' }); + } catch (e) { + err = e; + } + assert.throws(() => { + throw err; + }, /Could not find density/); }); }); diff --git a/src/plugins/density-settings/index.ts b/src/plugins/density-settings/index.ts index a0caf62b..801b7837 100644 --- a/src/plugins/density-settings/index.ts +++ b/src/plugins/density-settings/index.ts @@ -6,8 +6,7 @@ const PATHS = { }; const SELECTORS = { - PICKER_ITEMS: - 'pierce/one-density-visual-picker one-density-visual-picker-item input' + PICKER_ITEMS: 'pierce/one-density-visual-picker one-density-visual-picker-item input' }; type Config = { @@ -24,29 +23,29 @@ export class DensitySettings extends BrowserforcePlugin { public async retrieve(): Promise { const page = await this.browserforce.openPage(PATHS.BASE); const densities = await this.getDensities(page); - const selected = densities.find(input => input.checked); + const selected = densities.find((input) => input.checked); + await page.close(); return { - density: selected?.value + density: selected!.value }; } public async apply(config: Config): Promise { const page = await this.browserforce.openPage(PATHS.BASE); await this.setDensity(page, config.density); + await page.close(); } async getDensities(page: Page): Promise { await page.waitForSelector(SELECTORS.PICKER_ITEMS); const elementHandles = await page.$$(SELECTORS.PICKER_ITEMS); - const result = await page.$$eval( - SELECTORS.PICKER_ITEMS, - (radioInputs: HTMLInputElement[]) => - radioInputs.map(input => { - return { - value: input.value, - checked: input.checked - }; - }) + const result = await page.$$eval(SELECTORS.PICKER_ITEMS, (radioInputs: HTMLInputElement[]) => + radioInputs.map((input) => { + return { + value: input.value, + checked: input.checked + }; + }) ); return result.map((input, i) => { return { ...input, elementHandle: elementHandles[i] }; @@ -55,15 +54,15 @@ export class DensitySettings extends BrowserforcePlugin { async setDensity(page: Page, name: string): Promise { const densities = await this.getDensities(page); - const densityToSelect = densities.find(input => input.value === name); + const densityToSelect = densities.find((input) => input.value === name); + if (!densityToSelect) { + throw new Error(`Could not find density "${name}" in list of densities: ${densities.map((d) => d.value)}`); + } await Promise.all([ page.waitForResponse( - response => - response - .url() - .includes( - 'UserSettings.DensityUserSettings.setDefaultDensitySetting=1' - ) && response.status() === 200 + (response) => + response.url().includes('UserSettings.DensityUserSettings.setDefaultDensitySetting=1') && + response.status() === 200 ), densityToSelect.elementHandle.evaluate((input: HTMLInputElement) => input.click()) ]); diff --git a/src/plugins/email-deliverability/index.e2e-spec.ts b/src/plugins/email-deliverability/index.e2e-spec.ts index b4cbc089..0e28f32c 100644 --- a/src/plugins/email-deliverability/index.e2e-spec.ts +++ b/src/plugins/email-deliverability/index.e2e-spec.ts @@ -1,94 +1,55 @@ import assert from 'assert'; -import * as child from 'child_process'; -import * as path from 'path'; import { EmailDeliverability } from '.'; -describe(EmailDeliverability.name, function() { - this.slow('30s'); - this.timeout('2m'); +describe(EmailDeliverability.name, function () { + let plugin; + before(() => { + plugin = new EmailDeliverability(global.bf); + }); + const configNone = { + accessLevel: 'No access' + }; + const configAll = { + accessLevel: 'All email' + }; + const configSystem = { + accessLevel: 'System email only' + }; + const configInvalid = { + accessLevel: 'Invalid' + }; + // Note order is important here, the scratch org will be created with all access set, I have placed last so if a scratch is reused at least it is in the same state - it('should set "no access"', () => { - const applyNoAccessCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'no-access.json')) - ]); - assert.deepStrictEqual(applyNoAccessCmd.status, 0, applyNoAccessCmd.output.toString()); - assert.ok( - /to '"No access"'/.test(applyNoAccessCmd.output.toString()), - applyNoAccessCmd.output.toString() - ); + it('should set "no access"', async () => { + await plugin.run(configNone); }); - it('should already be set to "no access"', () => { - const applyNoAccessCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(__dirname, 'no-access.json') - ]); - assert.deepStrictEqual(applyNoAccessCmd.status, 0, applyNoAccessCmd.output.toString()); - assert.ok( - /no action necessary/.test(applyNoAccessCmd.output.toString()), - applyNoAccessCmd.output.toString() - ); + it('should already be set to "no access"', async () => { + const res = await plugin.retrieve(); + assert.deepStrictEqual(res, configNone); }); - it('should set "system only"', () => { - const systemEmailCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'system.json')) - ]); - assert.deepStrictEqual(systemEmailCmd.status, 0, systemEmailCmd.output.toString()); - assert.ok( - /to '"System email only"'/.test(systemEmailCmd.output.toString()), - systemEmailCmd.output.toString() - ); + it('should set "system only"', async () => { + await plugin.apply(configSystem); }); - it('should already be set to no access', () => { - const systemEmailCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(__dirname, 'system.json') - ]); - assert.deepStrictEqual(systemEmailCmd.status, 0, systemEmailCmd.output.toString()); - assert.ok( - /no action necessary/.test(systemEmailCmd.output.toString()), - systemEmailCmd.output.toString() - ); + it('should be set to "system only"', async () => { + const res = await plugin.retrieve(); + assert.deepStrictEqual(res, configSystem); }); - it('should apply all email', () => { - const applyAllCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'all.json')) - ]); - assert.deepStrictEqual(applyAllCmd.status, 0, applyAllCmd.output.toString()); - assert.ok( - /to '"All email"'/.test(applyAllCmd.output.toString()), - applyAllCmd.output.toString() - ); + it('should apply all email', async () => { + await plugin.apply(configAll); }); - it('should already be have all enabled', () => { - const applyAllCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(__dirname, 'all.json') - ]); - assert.deepStrictEqual(applyAllCmd.status, 0, applyAllCmd.output.toString()); - assert.ok( - /no action necessary/.test(applyAllCmd.output.toString()), - applyAllCmd.output.toString() - ); + it('should already be have all enabled', async () => { + const res = await plugin.retrieve(); + assert.deepStrictEqual(res, configAll); }); - it('should error on invalid input', () => { - const systemEmailCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(__dirname, 'invalid.json') - ]); - assert.notDeepStrictEqual(systemEmailCmd.status, 0, systemEmailCmd.output.toString()); - assert.ok( - /Invalid email access level/.test(systemEmailCmd.output.toString()), - systemEmailCmd.output.toString() - ); + it('should error on invalid input', async () => { + let err; + try { + await plugin.apply(configInvalid); + } catch (e) { + err = e; + } + assert.throws(() => { + throw err; + }, /Invalid email access level/); }); }); diff --git a/src/plugins/email-deliverability/index.ts b/src/plugins/email-deliverability/index.ts index 0031e7e6..8b89bfa3 100644 --- a/src/plugins/email-deliverability/index.ts +++ b/src/plugins/email-deliverability/index.ts @@ -9,8 +9,8 @@ const SELECTORS = { SAVE_BUTTON: 'input[id$=":saveBtn"]' }; const ACCESS_LEVEL_VALUES = new Map([ - ['No access', '0',], - ['System email only', '1',], + ['No access', '0'], + ['System email only', '1'], ['All email', '2'] ]); @@ -20,30 +20,29 @@ type Config = { export class EmailDeliverability extends BrowserforcePlugin { public async retrieve(definition?: Config): Promise { - if (!ACCESS_LEVEL_VALUES.has(definition.accessLevel)) { - throw new Error(`Invalid email access level ${definition.accessLevel}`); - } const page = await this.browserforce.openPage(PATHS.BASE); await page.waitForSelector(SELECTORS.ACCESS_LEVEL); - const selectedOptions = await page.$$eval( - `${SELECTORS.ACCESS_LEVEL} > option[selected]`, - options => options.map(option => option.textContent) + const selectedOptions = await page.$$eval(`${SELECTORS.ACCESS_LEVEL} > option[selected]`, (options) => + options.map((option) => option.textContent ?? '') ); + await page.close(); if (!selectedOptions) { - throw new Error('Selected access level not found...') + throw new Error('Selected access level not found...'); } return { accessLevel: selectedOptions[0] - };; + }; } public async apply(config: Config): Promise { + const accessLevelNumber = ACCESS_LEVEL_VALUES.get(config.accessLevel); + if (accessLevelNumber === undefined) { + throw new Error(`Invalid email access level ${config.accessLevel}`); + } const page = await this.browserforce.openPage(PATHS.BASE); await page.waitForSelector(SELECTORS.ACCESS_LEVEL); - await page.select(SELECTORS.ACCESS_LEVEL, ACCESS_LEVEL_VALUES.get(config.accessLevel)); - await Promise.all([ - page.waitForSelector(SELECTORS.CONFIRM_MESSAGE), - page.click(SELECTORS.SAVE_BUTTON) - ]); + await page.select(SELECTORS.ACCESS_LEVEL, accessLevelNumber); + await Promise.all([page.waitForSelector(SELECTORS.CONFIRM_MESSAGE), page.click(SELECTORS.SAVE_BUTTON)]); + await page.close(); } } diff --git a/src/plugins/high-velocity-sales-settings/index.e2e-spec.ts b/src/plugins/high-velocity-sales-settings/index.e2e-spec.ts index fb209fd3..32214547 100644 --- a/src/plugins/high-velocity-sales-settings/index.e2e-spec.ts +++ b/src/plugins/high-velocity-sales-settings/index.e2e-spec.ts @@ -1,57 +1,31 @@ import assert from 'assert'; -import * as child from 'child_process'; -import * as path from 'path'; -import { HighVelocitySalesSettings } from '.'; +import { Config, HighVelocitySalesSettings } from '.'; -describe(HighVelocitySalesSettings.name, function() { - this.slow('30s'); - this.timeout('2m'); - it('should enable', () => { - const enableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'enable.json')) - ]); - assert.deepStrictEqual(enableCmd.status, 0, enableCmd.output.toString()); - assert.ok( - /to 'true'/.test(enableCmd.output.toString()), - enableCmd.output.toString() - ); +describe(HighVelocitySalesSettings.name, function () { + let plugin: HighVelocitySalesSettings; + before(() => { + plugin = new HighVelocitySalesSettings(global.bf); }); - it('should already be enabled', () => { - const enableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(__dirname, 'enable.json') - ]); - assert.deepStrictEqual(enableCmd.status, 0, enableCmd.output.toString()); - assert.ok( - /no action necessary/.test(enableCmd.output.toString()), - enableCmd.output.toString() - ); + + const configEnabled: Config = { + setUpAndEnable: true + }; + const configDisabled = { + setUpAndEnable: false + }; + + it('should enable', async () => { + await plugin.run(configEnabled); + }); + it('should already be enabled', async () => { + const res = await plugin.run(configEnabled); + assert.deepStrictEqual(res, { message: 'no action necessary' }); }); - it('should disable', () => { - const disableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'disable.json')) - ]); - assert.deepStrictEqual(disableCmd.status, 0, disableCmd.output.toString()); - assert.ok( - /to 'false'/.test(disableCmd.output.toString()), - disableCmd.output.toString() - ); + it('should disable', async () => { + await plugin.run(configDisabled); }); - it('should already be disabled', () => { - const disableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(__dirname, 'disable.json') - ]); - assert.deepStrictEqual(disableCmd.status, 0, disableCmd.output.toString()); - assert.ok( - /no action necessary/.test(disableCmd.output.toString()), - disableCmd.output.toString() - ); + it('should already be disabled', async () => { + const res = await plugin.run(configDisabled); + assert.deepStrictEqual(res, { message: 'no action necessary' }); }); }); diff --git a/src/plugins/high-velocity-sales-settings/index.ts b/src/plugins/high-velocity-sales-settings/index.ts index 7e452dc1..2cce3fca 100644 --- a/src/plugins/high-velocity-sales-settings/index.ts +++ b/src/plugins/high-velocity-sales-settings/index.ts @@ -5,7 +5,7 @@ import { HighVelocitySalesSetupPage } from './page'; const MSG_NOT_AVAILABLE = `HighVelocitySales is not available in this organization. Please add 'HighVelocitySales' to your Scratch Org Features or purchase a license.`; -type Config = { +export type Config = { setUpAndEnable: boolean; }; @@ -14,18 +14,10 @@ export class HighVelocitySalesSettings extends BrowserforcePlugin { const conn = this.org.getConnection(); const result = { setUpAndEnable: false }; try { - const settings = await conn.metadata.read( - 'HighVelocitySalesSettings', - 'HighVelocitySales' - ); - result.setUpAndEnable = - settings['enableHighVelocitySalesSetup'] === true; + const settings = await conn.metadata.read('HighVelocitySalesSettings', 'HighVelocitySales'); + result.setUpAndEnable = settings['enableHighVelocitySalesSetup'] === true; } catch (e) { - if ( - /INVALID_TYPE: This type of metadata is not available for this organization/.test( - e - ) - ) { + if (/INVALID_TYPE: This type of metadata is not available for this organization/.test(e)) { throw new Error(MSG_NOT_AVAILABLE); } else { throw e; @@ -47,9 +39,7 @@ export class HighVelocitySalesSettings extends BrowserforcePlugin { } } -export async function disableHighVelocitySalesUsingMetadata( - conn: Connection -): Promise { +export async function disableHighVelocitySalesUsingMetadata(conn: Connection): Promise { const settings = { fullName: 'HighVelocitySales', enableHighVelocitySalesSetup: false, diff --git a/src/plugins/high-velocity-sales-settings/page.ts b/src/plugins/high-velocity-sales-settings/page.ts index 4a2c10e7..c48f9f82 100644 --- a/src/plugins/high-velocity-sales-settings/page.ts +++ b/src/plugins/high-velocity-sales-settings/page.ts @@ -3,9 +3,10 @@ import { throwPageErrors } from '../../browserforce'; const SET_UP_AND_ENABLE_HVS_BUTTON = 'button.setupAndEnableButton'; const ENABLE_TOGGLE = '#toggleHighVelocitySalesPref'; +const AUTOMATION_TAB_ITEM = 'pierce/#automationTab__item'; export class HighVelocitySalesSetupPage { - private page; + private page: Page; constructor(page: Page) { this.page = page; @@ -16,9 +17,20 @@ export class HighVelocitySalesSetupPage { } public async setUpAndEnable(): Promise { - await this.page.waitForSelector(SET_UP_AND_ENABLE_HVS_BUTTON); - await this.page.click(SET_UP_AND_ENABLE_HVS_BUTTON); + // starting Winter 24 (v59.0) there is a new tab bar and the item is located in the "Automation" tab + // wait for tab item or the button directly + await this.page.waitForSelector(`${AUTOMATION_TAB_ITEM}, ${SET_UP_AND_ENABLE_HVS_BUTTON}`, { timeout: 60_000 }); + const tab = await this.page.$(AUTOMATION_TAB_ITEM); + if (tab) { + await this.page.evaluate((e: HTMLElement) => e.click(), tab); + } + await this.page.waitForSelector(SET_UP_AND_ENABLE_HVS_BUTTON, { timeout: 60_000 }); + const enableButton = await this.page.$(SET_UP_AND_ENABLE_HVS_BUTTON); + await Promise.all([ + this.page.waitForSelector(ENABLE_TOGGLE, { timeout: 60_000 }), + this.page.evaluate((e: HTMLElement) => e.click(), enableButton!) + ]); await throwPageErrors(this.page); - await this.page.waitForSelector(ENABLE_TOGGLE); + await this.page.close(); } } diff --git a/src/plugins/home-page-layouts/index.e2e-spec.ts b/src/plugins/home-page-layouts/index.e2e-spec.ts index 09f0b7a0..49c93af1 100644 --- a/src/plugins/home-page-layouts/index.e2e-spec.ts +++ b/src/plugins/home-page-layouts/index.e2e-spec.ts @@ -1,48 +1,48 @@ import assert from 'assert'; -import * as child from 'child_process'; -import * as path from 'path'; import { HomePageLayouts } from '.'; -describe(HomePageLayouts.name, function() { - this.slow('30s'); - this.timeout('2m'); - it('should assign the home page default', () => { - const assignHomePageDefaultCmd = child.spawnSync( - path.resolve('bin', 'run'), - [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'home-page-default.json')) - ] - ); - assert.deepStrictEqual( - assignHomePageDefaultCmd.status, - 0, - assignHomePageDefaultCmd.output.toString() - ); - assert.ok( - /'\[{"profile":"Standard User","layout":""},{"profile":"System Administrator","layout":""}\]'/.test( - assignHomePageDefaultCmd.output.toString() - ), - assignHomePageDefaultCmd.output.toString() - ); +describe(HomePageLayouts.name, function () { + let plugin; + before(() => { + plugin = new HomePageLayouts(global.bf); }); - it('should assign the org default', () => { - const assignOrgDefaultCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'org-default.json')) - ]); - assert.deepStrictEqual( - assignOrgDefaultCmd.status, - 0, - assignOrgDefaultCmd.output.toString() - ); - assert.ok( - /'\[{"profile":"Standard User","layout":"DE Default"},{"profile":"System Administrator","layout":"DE Default"}\]'/.test( - assignOrgDefaultCmd.output.toString() - ), - assignOrgDefaultCmd.output.toString() - ); + + const configPageDefault = { + homePageLayoutAssignments: [ + { + profile: 'Standard User', + layout: '' + }, + { + profile: 'System Administrator', + layout: '' + } + ] + }; + const configOrgDefault = { + homePageLayoutAssignments: [ + { + profile: 'Standard User', + layout: 'DE Default' + }, + { + profile: 'System Administrator', + layout: 'DE Default' + } + ] + }; + it('should assign some layouts', async () => { + await plugin.run(configPageDefault); + }); + it('should be assigned', async () => { + const res = await plugin.run(configPageDefault); + assert.deepStrictEqual(res, { message: 'no action necessary' }); + }); + it('should unassign some layouts', async () => { + await plugin.apply(configOrgDefault); + }); + it('should be unassigned', async () => { + const res = await plugin.run(configOrgDefault); + assert.deepStrictEqual(res, { message: 'no action necessary' }); }); }); diff --git a/src/plugins/home-page-layouts/index.test.ts b/src/plugins/home-page-layouts/index.test.ts new file mode 100644 index 00000000..d8c4422b --- /dev/null +++ b/src/plugins/home-page-layouts/index.test.ts @@ -0,0 +1,105 @@ +import assert from 'assert'; +import { HomePageLayouts } from '.'; + +const tests = [ + { + description: 'should return no change', + source: { + homePageLayoutAssignments: [ + { + profile: 'Standard User', + layout: '' + }, + { + profile: 'System Administrator', + layout: '' + } + ] + }, + target: { + homePageLayoutAssignments: [ + { + profile: 'Standard User', + layout: '' + }, + { + profile: 'System Administrator', + layout: '' + } + ] + }, + expected: undefined + }, + { + description: 'should filter irrelevant assignments', + source: { + homePageLayoutAssignments: [ + { + profile: 'Foo User', + layout: '' + }, + { + profile: 'Standard User', + layout: '' + }, + { + profile: 'System Administrator', + layout: '' + } + ] + }, + target: { + homePageLayoutAssignments: [ + { + profile: 'Standard User', + layout: '' + }, + { + profile: 'System Administrator', + layout: '' + } + ] + }, + expected: undefined + }, + { + description: 'should match when unsorted', + source: { + homePageLayoutAssignments: [ + { + profile: 'System Administrator', + layout: '' + }, + { + profile: 'Standard User', + layout: '' + } + ] + }, + target: { + homePageLayoutAssignments: [ + { + profile: 'Standard User', + layout: '' + }, + { + profile: 'System Administrator', + layout: '' + } + ] + }, + expected: undefined + } +]; + +describe('HomePageLayouts', () => { + describe('diff()', () => { + const p = new HomePageLayouts(global.bf); + for (const t of tests) { + it(t.description, () => { + const actual = p.diff(t.source, t.target); + assert.deepStrictEqual(actual, t.expected); + }); + } + }); +}); diff --git a/src/plugins/home-page-layouts/index.ts b/src/plugins/home-page-layouts/index.ts index 44ffa8ab..3f0c9bac 100644 --- a/src/plugins/home-page-layouts/index.ts +++ b/src/plugins/home-page-layouts/index.ts @@ -1,5 +1,4 @@ import type { Record } from 'jsforce'; -import * as jsonMergePatch from 'json-merge-patch'; import { BrowserforcePlugin } from '../../plugin'; const PATHS = { @@ -28,50 +27,44 @@ type HomePageLayoutAssignment = { }; export class HomePageLayouts extends BrowserforcePlugin { - public async retrieve(definition?: Config): Promise { + public async retrieve(): Promise { const page = await this.browserforce.openPage(PATHS.BASE); await page.waitForSelector(SELECTORS.BASE); - const profiles = await page.$$eval( - 'table.detailList tbody tr td label', - (labels: HTMLLabelElement[]) => { - return labels.map((label) => { - for (let i = 0; label.childNodes.length; i++) { - if (label.childNodes[i].nodeType === label.TEXT_NODE) { - return label.childNodes[i].nodeValue; - } + const profiles = await page.$$eval('table.detailList tbody tr td label', (labels: HTMLLabelElement[]) => { + return labels.map((label) => { + for (let i = 0; label.childNodes.length; i++) { + if (label.childNodes[i].nodeType === label.TEXT_NODE) { + return label.childNodes[i].nodeValue ?? ''; } - throw new Error('retrieving HomePageLayouts failed'); - }); - } - ); - const layouts = await page.$$eval( - 'table.detailList tbody tr td select', - (selects: HTMLSelectElement[]) => { - return selects - .map((select) => select.selectedOptions[0].text) - .map((text) => (text === 'Home Page Default' ? '' : text)); - } - ); - const homePageLayoutAssignments = []; + } + throw new Error('retrieving HomePageLayouts failed'); + }); + }); + const layouts = await page.$$eval('table.detailList tbody tr td select', (selects: HTMLSelectElement[]) => { + return selects + .map((select) => select.selectedOptions[0].text) + .map((text) => (text === 'Home Page Default' ? '' : text)); + }); + const homePageLayoutAssignments: HomePageLayoutAssignment[] = []; for (let i = 0; i < profiles.length; i++) { homePageLayoutAssignments.push({ profile: profiles[i], layout: layouts[i] }); } + await page.close(); return { homePageLayoutAssignments }; } - public diff(source: Config, target: Config): Config { - const profileNames = target.homePageLayoutAssignments.map( - (assignment) => assignment.profile - ); - source.homePageLayoutAssignments = source.homePageLayoutAssignments.filter( - (assignment) => profileNames.includes(assignment.profile) - ); - return jsonMergePatch.generate(source, target); + public diff(source: Config, target: Config): Config | undefined { + target.homePageLayoutAssignments.sort(compareAssignment); + const profileNames = target.homePageLayoutAssignments.map((assignment) => assignment.profile); + source.homePageLayoutAssignments = source.homePageLayoutAssignments + .filter((assignment) => profileNames.includes(assignment.profile)) + .sort(compareAssignment); + return super.diff(source, target) as Config | undefined; } public async apply(config: Config): Promise { @@ -87,38 +80,39 @@ export class HomePageLayouts extends BrowserforcePlugin { .join(','); const profiles = await this.org .getConnection() - .tooling.query( - `SELECT Id, Name FROM Profile WHERE Name IN (${profilesList})` - ); + .tooling.query(`SELECT Id, Name FROM Profile WHERE Name IN (${profilesList})`); const homePageLayouts = await this.org .getConnection() - .tooling.query( - `SELECT Id, Name FROM HomePageLayout WHERE Name IN (${layoutsList})` - ); + .tooling.query(`SELECT Id, Name FROM HomePageLayout WHERE Name IN (${layoutsList})`); const page = await this.browserforce.openPage(PATHS.BASE); await page.waitForSelector(SELECTORS.BASE); for (const assignment of config.homePageLayoutAssignments) { const homePageLayoutName = assignment.layout; - const profile = profiles.records.find( - (p) => p.Name === assignment.profile - ); + const profile = profiles.records.find((p) => p.Name === assignment.profile); if (!profile) { throw new Error(`could not find profile '${assignment.profile}'`); } - let homePageLayout = homePageLayouts.records.find( - (l) => l.Name === homePageLayoutName - ); + let homePageLayout = homePageLayouts.records.find((l) => l.Name === homePageLayoutName); if (homePageLayoutName === '') { homePageLayout = { Id: 'default', Name: 'default' }; } - const profileSelector = `select[id='${profile.Id.substring(0, 15)}']`; + if (homePageLayout === undefined) { + throw new Error( + `Could not find home page layout "${homePageLayoutName}" in list of home page layouts: ${homePageLayouts.records.map( + (l) => l.Name + )}` + ); + } + const profileSelector = `select[id='${profile.Id!.substring(0, 15)}']`; await page.waitForSelector(profileSelector); - await page.select(profileSelector, homePageLayout.Id.substring(0, 15)); + await page.select(profileSelector, homePageLayout.Id!.substring(0, 15)); } - await Promise.all([ - page.waitForNavigation(), - page.click(SELECTORS.SAVE_BUTTON) - ]); + await Promise.all([page.waitForNavigation(), page.click(SELECTORS.SAVE_BUTTON)]); + await page.close(); } } + +function compareAssignment(a: HomePageLayoutAssignment, b: HomePageLayoutAssignment): number { + return `${a.profile}:${a.layout}`.localeCompare(`${b.profile}:${b.layout}`, 'en', { numeric: true }); +} diff --git a/src/plugins/index.ts b/src/plugins/index.ts index b7f89725..dd88d161 100644 --- a/src/plugins/index.ts +++ b/src/plugins/index.ts @@ -15,6 +15,7 @@ import { ReportsAndDashboards as reportsAndDashboards } from './reports-and-dash import { SalesforceToSalesforce as salesforceToSalesforce } from './salesforce-to-salesforce'; import { Security as security } from './security'; import { CompanyInformation as companyInformation } from './company-information'; +import { LinkedInSalesNavigatorSettings as linkedInSalesNavigatorSettings } from './linkedin-sales-navigator-settings'; export { activitySettings, @@ -33,5 +34,6 @@ export { reportsAndDashboards, salesforceToSalesforce, security, - companyInformation + companyInformation, + linkedInSalesNavigatorSettings }; diff --git a/src/plugins/lightning-experience-settings/index.e2e-spec.ts b/src/plugins/lightning-experience-settings/index.e2e-spec.ts index 2d2a771f..027c04cb 100644 --- a/src/plugins/lightning-experience-settings/index.e2e-spec.ts +++ b/src/plugins/lightning-experience-settings/index.e2e-spec.ts @@ -1,59 +1,39 @@ import assert from 'assert'; -import * as child from 'child_process'; -import * as path from 'path'; import { LightningExperienceSettings } from '.'; -describe(LightningExperienceSettings.name, function() { - this.slow('30s'); - this.timeout('2m'); - it('should activate LightningLite theme', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'activate-lightning-lite.json')) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /changing 'activeThemeName' to '"LightningLite"'/.test( - cmd.output.toString() - ), - cmd.output.toString() - ); - }); - it('LightningLite theme should already be activated', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(__dirname, 'activate-lightning-lite.json') - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /no action necessary/.test(cmd.output.toString()), - cmd.output.toString() - ); - }); - it('should activate Lightning theme', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'activate-lightning.json')) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /changing 'activeThemeName' to '"Lightning"'/.test(cmd.output.toString()), - cmd.output.toString() - ); - }); - it('Lightning theme should already be activated', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(__dirname, 'activate-lightning.json') - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /no action necessary/.test(cmd.output.toString()), - cmd.output.toString() - ); +describe(LightningExperienceSettings.name, function () { + describe('activeThemeName', () => { + let plugin; + before(() => { + plugin = new LightningExperienceSettings(global.bf); + }); + + const configLightningLite = { activeThemeName: 'LightningLite' }; + const configLightning = { activeThemeName: 'Lightning' }; + it('should activate LightningLite theme', async () => { + await plugin.run(configLightningLite); + }); + it('LightningLite theme should already be activated', async () => { + const state = await plugin.retrieve(); + assert.deepStrictEqual(state, configLightningLite); + }); + it('should activate Lightning theme', async () => { + await plugin.apply(configLightning); + }); + it('Lightning theme should already be activated', async () => { + const state = await plugin.retrieve(); + assert.deepStrictEqual(state, configLightning); + }); + it('should throw for invalid theme', async () => { + let err; + try { + await plugin.run({ activeThemeName: 'Foo' }); + } catch (e) { + err = e; + } + assert.throws(() => { + throw err; + }, /Could not find theme/); + }); }); }); diff --git a/src/plugins/lightning-experience-settings/index.ts b/src/plugins/lightning-experience-settings/index.ts index 6b8c411b..ce0a659a 100644 --- a/src/plugins/lightning-experience-settings/index.ts +++ b/src/plugins/lightning-experience-settings/index.ts @@ -5,8 +5,7 @@ const PATHS = { BASE: 'lightning/setup/ThemingAndBranding/home' }; -const THEME_ROW_SELECTOR = - 'pierce/#setupComponent lightning-datatable table > tbody > tr'; +const THEME_ROW_SELECTOR = 'pierce/#setupComponent lightning-datatable table > tbody > tr'; const SELECTORS = { DEVELOPER_NAMES: `${THEME_ROW_SELECTOR} > td:nth-child(2) > lightning-primitive-cell-factory lightning-base-formatted-text`, STATES: `${THEME_ROW_SELECTOR} > td:nth-child(6) > lightning-primitive-cell-factory` @@ -26,31 +25,29 @@ export class LightningExperienceSettings extends BrowserforcePlugin { public async retrieve(): Promise { const page = await this.browserforce.openPage(PATHS.BASE); const themes = await this.getThemeData(page); - const activeTheme = themes.find(theme => theme.isActive); + const activeTheme = themes.find((theme) => theme.isActive); const response = { - activeThemeName: activeTheme.developerName + activeThemeName: activeTheme!.developerName }; + await page.close(); return response; } public async apply(config: Config): Promise { const page = await this.browserforce.openPage(PATHS.BASE); - await this.setActiveTheme(page, config.activeThemeName); + await page.close(); } async getThemeData(page: Page): Promise { await page.waitForSelector(THEME_ROW_SELECTOR); const rowElementHandles = await page.$$(THEME_ROW_SELECTOR); await page.waitForSelector(SELECTORS.DEVELOPER_NAMES); - const developerNames = await page.$$eval(SELECTORS.DEVELOPER_NAMES, cells => + const developerNames = await page.$$eval(SELECTORS.DEVELOPER_NAMES, (cells) => cells.map((cell: HTMLTableCellElement) => cell.innerText) ); - const states = await page.$$eval(SELECTORS.STATES, cells => - cells.map( - cell => - cell.shadowRoot?.querySelector('lightning-primitive-icon') !== null - ) + const states = await page.$$eval(SELECTORS.STATES, (cells) => + cells.map((cell) => cell.shadowRoot?.querySelector('lightning-primitive-icon') !== null) ); return developerNames.map((developerName, i) => { return { @@ -63,9 +60,12 @@ export class LightningExperienceSettings extends BrowserforcePlugin { async setActiveTheme(page: Page, themeDeveloperName: string): Promise { const data = await this.getThemeData(page); - const theme = data.find( - theme => theme.developerName === themeDeveloperName - ); + const theme = data.find((theme) => theme.developerName === themeDeveloperName); + if (!theme) { + throw new Error( + `Could not find theme "${themeDeveloperName}" in list of themes: ${data.map((d) => d.developerName)}` + ); + } const newActiveThemeRowElementHandle = theme.rowElementHandle; await page.waitForSelector(`${THEME_ROW_SELECTOR} lightning-button-menu`, { visible: true @@ -73,17 +73,13 @@ export class LightningExperienceSettings extends BrowserforcePlugin { const menuButton = await newActiveThemeRowElementHandle.$( 'pierce/td lightning-primitive-cell-factory lightning-primitive-cell-actions lightning-button-menu' ); - await menuButton.click(); - await page.waitForSelector( - `${THEME_ROW_SELECTOR} lightning-button-menu slot lightning-menu-item`, - { visible: true } - ); - const menuItems = await menuButton.$$('pierce/slot lightning-menu-item'); + await page.evaluate((e: HTMLElement) => e.click(), menuButton); + await page.waitForSelector(`${THEME_ROW_SELECTOR} lightning-button-menu slot lightning-menu-item`, { + visible: true + }); + const menuItems = await menuButton!.$$('pierce/slot lightning-menu-item'); // second last item: [show, activate, preview] const activateMenuItem = menuItems[menuItems.length - 2]; - await Promise.all([ - page.waitForNavigation(), - activateMenuItem.click() - ]); + await Promise.all([page.waitForNavigation(), page.evaluate((e: HTMLElement) => e.click(), activateMenuItem)]); } } diff --git a/src/plugins/linkedin-sales-navigator-settings/disable.json b/src/plugins/linkedin-sales-navigator-settings/disable.json new file mode 100644 index 00000000..a31912f0 --- /dev/null +++ b/src/plugins/linkedin-sales-navigator-settings/disable.json @@ -0,0 +1,8 @@ +{ + "$schema": "../schema.json", + "settings": { + "linkedInSalesNavigatorSettings": { + "enabled": false + } + } +} diff --git a/src/plugins/linkedin-sales-navigator-settings/enable.json b/src/plugins/linkedin-sales-navigator-settings/enable.json new file mode 100644 index 00000000..bbda4c25 --- /dev/null +++ b/src/plugins/linkedin-sales-navigator-settings/enable.json @@ -0,0 +1,8 @@ +{ + "$schema": "../schema.json", + "settings": { + "linkedInSalesNavigatorSettings": { + "enabled": true + } + } +} diff --git a/src/plugins/linkedin-sales-navigator-settings/index.e2e-spec.ts b/src/plugins/linkedin-sales-navigator-settings/index.e2e-spec.ts new file mode 100644 index 00000000..fc95fe83 --- /dev/null +++ b/src/plugins/linkedin-sales-navigator-settings/index.e2e-spec.ts @@ -0,0 +1,31 @@ +import assert from 'assert'; +import { Config, LinkedInSalesNavigatorSettings } from '.'; + +describe(LinkedInSalesNavigatorSettings.name, function () { + let plugin: LinkedInSalesNavigatorSettings; + before(() => { + plugin = new LinkedInSalesNavigatorSettings(global.bf); + }); + + const configEnabled: Config = { + enabled: true + }; + const configDisabled: Config = { + enabled: false + }; + + it('should enable', async () => { + await plugin.run(configEnabled); + }); + it('should already be enabled', async () => { + const res = await plugin.run(configEnabled); + assert.deepStrictEqual(res, { message: 'no action necessary' }); + }); + it('should disable', async () => { + await plugin.run(configDisabled); + }); + it('should already be disabled', async () => { + const res = await plugin.run(configDisabled); + assert.deepStrictEqual(res, { message: 'no action necessary' }); + }); +}); diff --git a/src/plugins/linkedin-sales-navigator-settings/index.ts b/src/plugins/linkedin-sales-navigator-settings/index.ts new file mode 100644 index 00000000..f69a9856 --- /dev/null +++ b/src/plugins/linkedin-sales-navigator-settings/index.ts @@ -0,0 +1,20 @@ +import { BrowserforcePlugin } from '../../plugin'; +import { LinkedInSalesNavigatorPage } from './page'; + +export type Config = { + enabled: boolean; +}; + +export class LinkedInSalesNavigatorSettings extends BrowserforcePlugin { + public async retrieve(definition?: Config): Promise { + const result = { enabled: false }; + const page = new LinkedInSalesNavigatorPage(await this.browserforce.openPage(LinkedInSalesNavigatorPage.getUrl())); + result.enabled = await page.getStatus(); + return result; + } + + public async apply(config: Config): Promise { + const page = new LinkedInSalesNavigatorPage(await this.browserforce.openPage(LinkedInSalesNavigatorPage.getUrl())); + await page.setStatus(config.enabled); + } +} diff --git a/src/plugins/linkedin-sales-navigator-settings/page.ts b/src/plugins/linkedin-sales-navigator-settings/page.ts new file mode 100644 index 00000000..78e3cecc --- /dev/null +++ b/src/plugins/linkedin-sales-navigator-settings/page.ts @@ -0,0 +1,43 @@ +import { Page } from 'puppeteer'; +import { throwPageErrors } from '../../browserforce'; + +const ENABLE_TOGGLE = 'div[data-aura-class="setup_sales_linkedinLinkedInSetupRow"] input[type="checkbox"]'; +const CONFIRM_CHECKBOX = + 'pierce/lightning-primitive-input-checkbox input[name="LinkedIn Sales Navigator Integration Acceptance Checkbox"]'; +const ACCEPT_BUTTON = + 'section[data-aura-class="setup_sales_linkedinLinkedInSetupAcceptTermsModal"] div div button:not(:disabled):nth-child(2)'; + +export class LinkedInSalesNavigatorPage { + private page: Page; + + constructor(page: Page) { + this.page = page; + } + + public static getUrl(): string { + return 'lightning/setup/LinkedInSalesNavigatorPage/home'; + } + + public async getStatus(): Promise { + await this.page.waitForSelector(ENABLE_TOGGLE, { visible: true }); + const isEnabled = await this.page.$eval(ENABLE_TOGGLE, (el: HTMLInputElement) => el.checked); + await this.page.close(); + return isEnabled; + } + + public async setStatus(enable: boolean): Promise { + await this.page.waitForSelector(ENABLE_TOGGLE, { visible: true }); + await this.page.click(ENABLE_TOGGLE); + + if (enable) { + await this.page.waitForSelector(CONFIRM_CHECKBOX, { visible: true }); + const checkbox = await this.page.$(CONFIRM_CHECKBOX); + await checkbox?.evaluate((input: HTMLInputElement) => input.click()); + await this.page.waitForSelector(ACCEPT_BUTTON, { visible: true }); + await this.page.click(ACCEPT_BUTTON); + } + + await throwPageErrors(this.page); + await this.page.close(); + } +} diff --git a/src/plugins/linkedin-sales-navigator-settings/schema.json b/src/plugins/linkedin-sales-navigator-settings/schema.json new file mode 100644 index 00000000..9958ddc3 --- /dev/null +++ b/src/plugins/linkedin-sales-navigator-settings/schema.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "https://github.com/amtrack/sfdx-browserforce-plugin/src/plugins/linkedin-sales-navigator-settings/schema.json", + "title": "LinkedIn Sales Navigator Settings", + "description": "", + "type": "object", + "properties": { + "enabled": { + "title": "Enable LinkedIn Sales Navigator", + "type": "boolean" + } + } +} diff --git a/src/plugins/opportunity-splits/index.e2e-spec.ts b/src/plugins/opportunity-splits/index.e2e-spec.ts index a169ffcb..72902f6b 100644 --- a/src/plugins/opportunity-splits/index.e2e-spec.ts +++ b/src/plugins/opportunity-splits/index.e2e-spec.ts @@ -4,67 +4,40 @@ import * as path from 'path'; import { OpportunitySplits } from '.'; describe(OpportunitySplits.name, function () { - this.slow('30s'); - this.timeout('2m'); + let plugin; + before(() => { + plugin = new OpportunitySplits(global.bf); + }); + + const configEnabled = { + enabled: true + }; + const configDisabled = { + enabled: false + }; it('should enable Opportunity Teams as prerequisite', () => { - const sourceDeployCmd = child.spawnSync('sfdx', [ - 'force:source:deploy', - '-p', + const sourceDeployCmd = child.spawnSync('sf', [ + 'project', + 'deploy', + 'start', + '-d', path.join(__dirname, 'sfdx-source'), '--json' ]); - assert.deepStrictEqual( - sourceDeployCmd.status, - 0, - sourceDeployCmd.output.toString() - ); + assert.deepStrictEqual(sourceDeployCmd.status, 0, sourceDeployCmd.output.toString()); }); - it('should enable', () => { - const enableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'enable.json')) - ]); - assert.deepStrictEqual(enableCmd.status, 0, enableCmd.output.toString()); - assert.ok( - /to 'true'/.test(enableCmd.output.toString()), - enableCmd.output.toString() - ); + it('should enable', async () => { + await plugin.run(configEnabled); }); - it('should already be enabled', () => { - const enableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(__dirname, 'enable.json') - ]); - assert.deepStrictEqual(enableCmd.status, 0, enableCmd.output.toString()); - assert.ok( - /no action necessary/.test(enableCmd.output.toString()), - enableCmd.output.toString() - ); + it('should be enabled', async () => { + const state = await plugin.retrieve(); + assert.deepStrictEqual(state, configEnabled); }); - it('should disable', () => { - const disableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'disable.json')) - ]); - assert.deepStrictEqual(disableCmd.status, 0, disableCmd.output.toString()); - assert.ok( - /to 'false'/.test(disableCmd.output.toString()), - disableCmd.output.toString() - ); + it('should disable', async () => { + await plugin.apply(configDisabled); }); - it('should already be disabled', () => { - const disableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(__dirname, 'disable.json') - ]); - assert.deepStrictEqual(disableCmd.status, 0, disableCmd.output.toString()); - assert.ok( - /no action necessary/.test(disableCmd.output.toString()), - disableCmd.output.toString() - ); + it('should be disabled', async () => { + const state = await plugin.retrieve(); + assert.deepStrictEqual(state, configDisabled); }); }); diff --git a/src/plugins/opportunity-splits/index.ts b/src/plugins/opportunity-splits/index.ts index 6a045d1f..b68e2181 100644 --- a/src/plugins/opportunity-splits/index.ts +++ b/src/plugins/opportunity-splits/index.ts @@ -1,3 +1,4 @@ +import { Page } from 'puppeteer'; import { BrowserforcePlugin } from '../../plugin'; import { OverviewPage } from './pages/overview'; import { SetupPage } from './pages/setup'; @@ -13,21 +14,24 @@ export class OpportunitySplits extends BrowserforcePlugin { const response = { enabled: await overviewPage.isEnabled() }; + await page.close(); return response; } public async apply(config: Config): Promise { + let page: Page; if (config.enabled) { - const page = await this.browserforce.openPage(SetupPage.PATH); + page = await this.browserforce.openPage(SetupPage.PATH); const setupPage = new SetupPage(page); const layoutSelectionPage = await setupPage.enable(); const overviewPage = await layoutSelectionPage.choose(); await overviewPage.waitUntilEnabled(); } else { - const page = await this.browserforce.openPage(OverviewPage.PATH); + page = await this.browserforce.openPage(OverviewPage.PATH); const overviewPage = new OverviewPage(page); await overviewPage.disable(); await overviewPage.waitUntilDisabled(); } + await page.close(); } } diff --git a/src/plugins/opportunity-splits/pages/layout-selection.ts b/src/plugins/opportunity-splits/pages/layout-selection.ts index f8bc75b8..3dec1c07 100644 --- a/src/plugins/opportunity-splits/pages/layout-selection.ts +++ b/src/plugins/opportunity-splits/pages/layout-selection.ts @@ -4,8 +4,7 @@ import { OverviewPage } from './overview'; const SAVE_BUTTON = 'input[id$=":save"]'; export class LayoutSelectionPage { - static PATH = - 'opp/opportunitySplitSetupLayout.apexp?setupid=OpportunitySplitSetup'; + static PATH = 'opp/opportunitySplitSetupLayout.apexp?setupid=OpportunitySplitSetup'; private page; constructor(page: Page) { @@ -14,10 +13,7 @@ export class LayoutSelectionPage { public async choose(): Promise { await this.page.waitForSelector(SAVE_BUTTON); - await Promise.all([ - this.page.waitForNavigation(), - this.page.click(SAVE_BUTTON) - ]); + await Promise.all([this.page.waitForNavigation(), this.page.click(SAVE_BUTTON)]); return new OverviewPage(this.page); } } diff --git a/src/plugins/opportunity-splits/pages/overview.ts b/src/plugins/opportunity-splits/pages/overview.ts index 0087d935..c2875c6d 100644 --- a/src/plugins/opportunity-splits/pages/overview.ts +++ b/src/plugins/opportunity-splits/pages/overview.ts @@ -4,12 +4,10 @@ const IN_PRGOGRESS = '#enablingInProgress'; const COMPLETED = '#prefSettingSucceeded'; const DISABLE_LINK = 'div[id*=":disable_form:"] a'; const DISABLE_CONFIRM_CHECKBOX = 'input#dis_confirm'; -const DISABLE_CONFIRM_BUTTON = - 'input#splitsDisableConfirmDialog_overlayConfirmButton'; +const DISABLE_CONFIRM_BUTTON = 'input#splitsDisableConfirmDialog_overlayConfirmButton'; export class OverviewPage { - static PATH = - 'opp/opportunitySplitSetupOverview.apexp?setupid=OpportunitySplitSetup'; + static PATH = 'opp/opportunitySplitSetupOverview.apexp?setupid=OpportunitySplitSetup'; private page; constructor(page: Page) { @@ -32,10 +30,7 @@ export class OverviewPage { await this.page.waitForSelector(DISABLE_CONFIRM_CHECKBOX); await this.page.click(DISABLE_CONFIRM_CHECKBOX); await this.page.waitForSelector(DISABLE_CONFIRM_BUTTON); - await Promise.all([ - this.page.waitForNavigation(), - this.page.click(DISABLE_CONFIRM_BUTTON) - ]); + await Promise.all([this.page.waitForNavigation(), this.page.click(DISABLE_CONFIRM_BUTTON)]); return this; } diff --git a/src/plugins/opportunity-splits/pages/setup.ts b/src/plugins/opportunity-splits/pages/setup.ts index d47f9267..db520a40 100644 --- a/src/plugins/opportunity-splits/pages/setup.ts +++ b/src/plugins/opportunity-splits/pages/setup.ts @@ -2,12 +2,10 @@ import { Page } from 'puppeteer'; import { LayoutSelectionPage } from './layout-selection'; const SAVE_BUTTON = 'input[id$=":form:SaveButton"]'; -const MODAL_CONFIRM_BUTTON = - 'input[id="splitsMassOperationConfirmDialog_overlayConfirmButton"]'; +const MODAL_CONFIRM_BUTTON = 'input[id="splitsMassOperationConfirmDialog_overlayConfirmButton"]'; export class SetupPage { - static PATH = - 'opp/opportunitySplitSetupEdit.apexp?setupid=OpportunitySplitSetup'; + static PATH = 'opp/opportunitySplitSetupEdit.apexp?setupid=OpportunitySplitSetup'; private page; constructor(page: Page) { @@ -18,10 +16,7 @@ export class SetupPage { await this.page.waitForSelector(SAVE_BUTTON); await this.page.click(SAVE_BUTTON); await this.page.waitForSelector(MODAL_CONFIRM_BUTTON); - await Promise.all([ - this.page.waitForNavigation(), - this.page.click(MODAL_CONFIRM_BUTTON) - ]); + await Promise.all([this.page.waitForNavigation(), this.page.click(MODAL_CONFIRM_BUTTON)]); return new LayoutSelectionPage(this.page); } } diff --git a/src/plugins/picklists/field-dependencies/index.test.ts b/src/plugins/picklists/field-dependencies/index.test.ts new file mode 100644 index 00000000..f83926ab --- /dev/null +++ b/src/plugins/picklists/field-dependencies/index.test.ts @@ -0,0 +1,72 @@ +import assert from 'assert'; +import { Config } from '.'; +import { deepDiff } from '../../utils'; + +type T = { + description: string; + source: Config; + target: Config; + expected: Config | undefined; +}; +const tests: T[] = [ + { + description: 'should return no change', + source: [ + { + object: 'Vehicle__c', + dependentField: 'Gears__c', + controllingField: null + } + ], + target: [ + { + object: 'Vehicle__c', + dependentField: 'Gears__c', + controllingField: null + } + ], + expected: undefined + }, + { + description: 'should unset controlling field', + source: [ + { + object: 'Vehicle__c', + dependentField: 'Gears__c', + controllingField: 'Foo__c' + } + ], + target: [ + { + object: 'Vehicle__c', + dependentField: 'Gears__c', + controllingField: null + } + ], + expected: [ + { + object: 'Vehicle__c', + dependentField: 'Gears__c', + controllingField: null + } + ] + } +]; + +describe('FieldDependencies', () => { + describe('diff()', () => { + // const p = new FieldDependencies(global.bf); + // for (const t of tests) { + // it(t.description, () => { + // const actual = p.diff(t.source, t.target); + // assert.deepStrictEqual(actual, t.expected); + // }); + // } + for (const t of tests) { + it(t.description, () => { + const actual = deepDiff(t.source, t.target); + assert.deepStrictEqual(actual, t.expected); + }); + } + }); +}); diff --git a/src/plugins/picklists/field-dependencies/index.ts b/src/plugins/picklists/field-dependencies/index.ts index d2d7b310..c88bae23 100644 --- a/src/plugins/picklists/field-dependencies/index.ts +++ b/src/plugins/picklists/field-dependencies/index.ts @@ -1,29 +1,27 @@ +import { retry } from '../../../browserforce'; +import { ensureArray } from '../../../jsforce-utils'; import { BrowserforcePlugin } from '../../../plugin'; import { FieldDependencyPage, NewFieldDependencyPage } from './pages'; export type FieldDependencyConfig = { object: string; dependentField: string; - controllingField: string; + controllingField: string | null; }; export type Config = FieldDependencyConfig[]; export class FieldDependencies extends BrowserforcePlugin { - public async retrieve(definition?: Config): Promise { + public async retrieve(definition: Config): Promise { const conn = this.org.getConnection(); - const dependentFieldNames = definition.map( - f => `${f.object}.${f.dependentField}` - ); + const dependentFieldNames = definition.map((f) => `${f.object}.${f.dependentField}`); const result = await conn.metadata.read('CustomField', dependentFieldNames); - const metadata = Array.isArray(result) ? result : [result]; - const state = definition.map(f => { + const metadata = ensureArray(result); + const state = definition.map((f) => { const fieldState = { ...f }; - const field = metadata.find( - m => m.fullName === `${f.object}.${f.dependentField}` - ); + const field = metadata.find((m) => m.fullName === `${f.object}.${f.dependentField}`); // for diffing: to unset a field dependency, set it to null - fieldState.controllingField = field?.['valueSet']?.controllingField || null; + fieldState.controllingField = field?.valueSet?.controllingField ?? null; return fieldState; }); return state; @@ -37,44 +35,39 @@ export class FieldDependencies extends BrowserforcePlugin { }, { type: 'CustomField' } ]); - const fileProperties = Array.isArray(listMetadataResult) - ? listMetadataResult - : [listMetadataResult]; + const fileProperties = ensureArray(listMetadataResult); for (const dep of plan) { - const customObject = fileProperties.find( - x => x.type === 'CustomObject' && x.fullName === dep.object - ); - const dependentField = fileProperties.find( - x => - x.type === 'CustomField' && - x.fullName === `${dep.object}.${dep.dependentField}` - ); - // always try deleting an existing dependency first - const fieldDependenciesPage = new FieldDependencyPage( - await this.browserforce.openPage( - FieldDependencyPage.getUrl(customObject.id) - ) - ); - await fieldDependenciesPage.clickDeleteDependencyActionForField( - dependentField.id - ); - if (dep.controllingField) { - const controllingField = fileProperties.find( - x => - x.type === 'CustomField' && - x.fullName === `${dep.object}.${dep.controllingField}` + await retry(async () => { + const customObject = fileProperties.find((x) => x.type === 'CustomObject' && x.fullName === dep.object); + if (!customObject) { + throw new Error(`Could not find CustomObject "${dep.object}"`); + } + const dependentField = fileProperties.find( + (x) => x.type === 'CustomField' && x.fullName === `${dep.object}.${dep.dependentField}` ); - const newFieldDependencyPage = new NewFieldDependencyPage( - await this.browserforce.openPage( - NewFieldDependencyPage.getUrl( - customObject.id, - dependentField.id, - controllingField.id - ) - ) + if (!dependentField) { + throw new Error(`Could not find dependent field "${dep.object}.${dep.dependentField}"`); + } + // always try deleting an existing dependency first + const fieldDependenciesPage = new FieldDependencyPage( + await this.browserforce.openPage(FieldDependencyPage.getUrl(customObject.id)) ); - await newFieldDependencyPage.save(); - } + await fieldDependenciesPage.clickDeleteDependencyActionForField(dependentField.id); + if (dep.controllingField) { + const controllingField = fileProperties.find( + (x) => x.type === 'CustomField' && x.fullName === `${dep.object}.${dep.controllingField}` + ); + if (!controllingField) { + throw new Error(`Could not find controlling field "${dep.object}.${dep.controllingField}"`); + } + const newFieldDependencyPage = new NewFieldDependencyPage( + await this.browserforce.openPage( + NewFieldDependencyPage.getUrl(customObject.id, dependentField.id, controllingField.id) + ) + ); + await newFieldDependencyPage.save(); + } + }); } } } diff --git a/src/plugins/picklists/field-dependencies/pages.ts b/src/plugins/picklists/field-dependencies/pages.ts index 7e5baed8..6a20c03a 100644 --- a/src/plugins/picklists/field-dependencies/pages.ts +++ b/src/plugins/picklists/field-dependencies/pages.ts @@ -9,32 +9,22 @@ export class FieldDependencyPage { } public static getUrl(customObjectId: string): string { - return `setup/ui/dependencyList.jsp?tableEnumOrId=${customObjectId.substring( - 0, - 15 - )}&setupid=CustomObjects`; + return `setup/ui/dependencyList.jsp?tableEnumOrId=${customObjectId.substring(0, 15)}&setupid=CustomObjects`; } - public async clickDeleteDependencyActionForField( - customFieldId: string - ): Promise { + public async clickDeleteDependencyActionForField(customFieldId: string): Promise { // wait for "new" button in field dependencies releated list header - await this.page.waitForSelector( - 'div.listRelatedObject div.pbHeader input[name="new"]' - ); + await this.page.waitForSelector('div.listRelatedObject div.pbHeader input[name="new"]'); const xpath = `//a[contains(@href, "/p/dependency/NewDependencyUI/e") and contains(@href, "delID=${customFieldId.substring( 0, 15 )}")]`; const actionLinkHandles = await this.page.$x(xpath); if (actionLinkHandles.length) { - this.page.on('dialog', async dialog => { + this.page.on('dialog', async (dialog) => { await dialog.accept(); }); - await Promise.all([ - this.page.waitForNavigation(), - actionLinkHandles[0].click() - ]); + await Promise.all([this.page.waitForNavigation(), this.page.evaluate((e) => e.click(), actionLinkHandles[0])]); await throwPageErrors(this.page); } return this.page; @@ -49,18 +39,11 @@ export class NewFieldDependencyPage { this.page = page; } - public static getUrl( - customObjectId: string, - dependentFieldId: string, - controllingFieldId: string - ): string { + public static getUrl(customObjectId: string, dependentFieldId: string, controllingFieldId: string): string { return `p/dependency/NewDependencyUI/e?tableEnumOrId=${customObjectId.substring( 0, 15 - )}&setupid=CustomObjects&controller=${controllingFieldId.substring( - 0, - 15 - )}&dependent=${dependentFieldId.substring( + )}&setupid=CustomObjects&controller=${controllingFieldId.substring(0, 15)}&dependent=${dependentFieldId.substring( 0, 15 )}&retURL=/${customObjectId.substring(0, 15)}`; @@ -68,20 +51,15 @@ export class NewFieldDependencyPage { async save(): Promise { await this.page.waitForSelector(this.saveButton); - await Promise.all([ - this.page.waitForNavigation(), - this.page.click(this.saveButton) - ]); + await Promise.all([this.page.waitForNavigation(), this.page.click(this.saveButton)]); await throwPageErrors(this.page); // second step in wizard - this.page.on('dialog', async dialog => { + this.page.on('dialog', async (dialog) => { await dialog.accept(); }); await this.page.waitForSelector(this.saveButton); - await Promise.all([ - this.page.waitForNavigation(), - this.page.click(this.saveButton) - ]); + await Promise.all([this.page.waitForNavigation(), this.page.click(this.saveButton)]); await throwPageErrors(this.page); + await this.page.close(); } } diff --git a/src/plugins/picklists/index.e2e-spec.ts b/src/plugins/picklists/index.e2e-spec.ts index a5ad26fb..7d4b4d22 100644 --- a/src/plugins/picklists/index.e2e-spec.ts +++ b/src/plugins/picklists/index.e2e-spec.ts @@ -4,205 +4,92 @@ import * as path from 'path'; import { Picklists } from '.'; import { FieldDependencies } from './field-dependencies'; -describe(Picklists.name, function() { - this.slow('30s'); +describe(Picklists.name, function () { this.timeout('10m'); + let plugin; + before(() => { + plugin = new Picklists(global.bf); + }); + + const configNew = require('./new.json').settings.picklists; + const configReplace = require('./replace.json').settings.picklists; + const configReplaceAndDelete = require('./replace-and-delete.json').settings.picklists; + const configDeactivate = require('./deactivate.json').settings.picklists; + const configActivate = require('./activate.json').settings.picklists; + const configReplaceAndDeactivate = require('./replace-and-deactivate.json').settings.picklists; + it('should deploy a CustomObject for testing', () => { - const sourceDeployCmd = child.spawnSync('sfdx', [ - 'force:source:deploy', - '-p', + const sourceDeployCmd = child.spawnSync('sf', [ + 'project', + 'deploy', + 'start', + '-d', path.join(__dirname, 'sfdx-source'), '--json' ]); - assert.deepStrictEqual( - sourceDeployCmd.status, - 0, - sourceDeployCmd.output.toString() - ); - }); - it('should add a new picklist value when it does not exist', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'new.json')) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /changing 'picklistValues' to.*/.test(cmd.output.toString()), - cmd.output.toString() - ); - }); - it('should not do anything when picklist value already exists', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'new.json')) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /no action necessary/.test(cmd.output.toString()), - cmd.output.toString() - ); - }); - it('should replace picklist values', () => { - const replaceCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'replace.json')) - ]); - assert.deepStrictEqual(replaceCmd.status, 0, replaceCmd.output.toString()); - assert.ok( - /changing 'picklistValues' to.*/.test(replaceCmd.output.toString()), - replaceCmd.output.toString() - ); - }); - it('should replace and delete picklist values', () => { - const replaceCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'replace-and-delete.json')) - ]); - assert.deepStrictEqual(replaceCmd.status, 0, replaceCmd.output.toString()); - assert.ok( - /changing 'picklistValues' to.*/.test(replaceCmd.output.toString()), - replaceCmd.output.toString() - ); - }); - it('should not do anything when the picklist values do not exist', () => { - const replaceCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'replace-and-delete.json')) - ]); - assert.deepStrictEqual(replaceCmd.status, 0, replaceCmd.output.toString()); - assert.ok( - /no action necessary/.test(replaceCmd.output.toString()), - replaceCmd.output.toString() - ); - }); - it('should deactivate picklist value', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'deactivate.json')) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /changing 'picklistValues' to.*/.test(cmd.output.toString()), - cmd.output.toString() - ); - }); - it('should activate picklist value', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'activate.json')) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /changing 'picklistValues' to.*/.test(cmd.output.toString()), - cmd.output.toString() - ); - }); - it('should not do anything when the picklist values do not exist', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'activate.json')) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /no action necessary/.test(cmd.output.toString()), - cmd.output.toString() - ); - }); - it('should replace and deactivate a picklist value', () => { - const replaceCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'replace-and-deactivate.json')) - ]); - assert.deepStrictEqual(replaceCmd.status, 0, replaceCmd.output.toString()); - assert.ok( - /changing 'picklistValues' to.*/.test(replaceCmd.output.toString()), - replaceCmd.output.toString() - ); + assert.deepStrictEqual(sourceDeployCmd.status, 0, sourceDeployCmd.output.toString()); + }); + it('should add a new picklist value when it does not exist', async () => { + await plugin.run(configNew); + }); + it('should not do anything when picklist value already exists', async () => { + const res = await plugin.run(configNew); + assert.deepStrictEqual(res, { message: 'no action necessary' }); + }); + it('should replace picklist values', async () => { + await plugin.run(configReplace); + }); + it('should replace and delete picklist values', async () => { + await plugin.run(configReplaceAndDelete); + }); + it('should not do anything when the picklist values do not exist', async () => { + const res = await plugin.run(configReplaceAndDelete); + assert.deepStrictEqual(res, { message: 'no action necessary' }); + }); + it('should deactivate picklist value', async () => { + await plugin.run(configDeactivate); + }); + it('should activate picklist value', async () => { + await plugin.run(configActivate); + }); + it('should not do anything when the picklist values already exist', async () => { + const res = await plugin.run(configActivate); + assert.deepStrictEqual(res, { message: 'no action necessary' }); + }); + it('should replace and deactivate a picklist value', async () => { + await plugin.run(configReplaceAndDeactivate); }); }); -describe(FieldDependencies.name, function() { - this.slow('30s'); +describe(FieldDependencies.name, function () { this.timeout('10m'); - it('should not do anything when the dependency is already set', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'field-dependencies', 'set.json')) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /no action necessary/.test(cmd.output.toString()), - cmd.output.toString() - ); - }); - it('should unset a field dependency', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'field-dependencies', 'unset.json')) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /changing 'fieldDependencies' to.*/.test(cmd.output.toString()), - cmd.output.toString() - ); - }); - it('should not do anything when the dependency is already unset', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'field-dependencies', 'unset.json')) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /no action necessary/.test(cmd.output.toString()), - cmd.output.toString() - ); - }); - it('should set a field dependency', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'field-dependencies', 'set.json')) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /changing 'fieldDependencies' to.*/.test(cmd.output.toString()), - cmd.output.toString() - ); - }); - it('should change a field dependency', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'field-dependencies', 'change.json')) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /changing 'fieldDependencies' to.*/.test(cmd.output.toString()), - cmd.output.toString() - ); - }); - it('should change back a field dependency', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'field-dependencies', 'set.json')) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /changing 'fieldDependencies' to.*/.test(cmd.output.toString()), - cmd.output.toString() - ); + let plugin; + before(() => { + plugin = new FieldDependencies(global.bf); + }); + + const configSet = require('./field-dependencies/set.json').settings.picklists.fieldDependencies; + const configUnset = require('./field-dependencies/unset.json').settings.picklists.fieldDependencies; + const configChange = require('./field-dependencies/change.json').settings.picklists.fieldDependencies; + + it('should not do anything when the dependency is already set', async () => { + const res = await plugin.run(configSet); + assert.deepStrictEqual(res, { message: 'no action necessary' }); + }); + it('should unset a field dependency', async () => { + await plugin.run(configUnset); + }); + it('should not do anything when the dependency is already unset', async () => { + const res = await plugin.run(configUnset); + assert.deepStrictEqual(res, { message: 'no action necessary' }); + }); + it('should set a field dependency', async () => { + await plugin.run(configSet); + }); + it('should change a field dependency', async () => { + await plugin.run(configChange); + }); + it('should change back a field dependency', async () => { + await plugin.run(configSet); }); }); diff --git a/src/plugins/picklists/index.ts b/src/plugins/picklists/index.ts index 7b2328f1..cb1d47aa 100644 --- a/src/plugins/picklists/index.ts +++ b/src/plugins/picklists/index.ts @@ -1,21 +1,14 @@ import type { FileProperties } from 'jsforce/api/metadata'; +import { retry } from '../../browserforce'; import { ensureArray } from '../../jsforce-utils'; import { BrowserforcePlugin } from '../../plugin'; -import { removeEmptyValues } from '../utils'; -import { - Config as FieldDependenciesConfig, - FieldDependencies -} from './field-dependencies'; -import { - PicklistPage, - DefaultPicklistAddPage, - StatusPicklistAddPage -} from './pages'; +import { FieldDependencies, Config as FieldDependenciesConfig } from './field-dependencies'; +import { DefaultPicklistAddPage, PicklistPage, StatusPicklistAddPage } from './pages'; import { determineStandardValueSetEditUrl } from './standard-value-set'; type Config = { - picklistValues: PicklistValuesConfig[]; - fieldDependencies: FieldDependenciesConfig; + picklistValues?: PicklistValuesConfig[]; + fieldDependencies?: FieldDependenciesConfig; }; type PicklistValuesConfig = { @@ -31,83 +24,73 @@ type PicklistValuesConfig = { }; export class Picklists extends BrowserforcePlugin { - public async retrieve(definition?: Config): Promise { + public async retrieve(definition: Config): Promise { const conn = this.org.getConnection(); - const result = { picklistValues: [], fieldDependencies: [] }; + const result: Config = { picklistValues: [], fieldDependencies: [] }; if (definition.picklistValues) { const fileProperties = await listMetadata( conn, - definition.picklistValues.map(x => x.metadataType) + definition.picklistValues.map((x) => x.metadataType) ); for (const action of definition.picklistValues) { // check if given picklist values exist - const picklistUrl = getPicklistUrl( - action.metadataType, - action.metadataFullName, - fileProperties - ); + const picklistUrl = getPicklistUrl(action.metadataType, action.metadataFullName, fileProperties); const page = await this.browserforce.openPage(picklistUrl); const picklistPage = new PicklistPage(page); const values = await picklistPage.getPicklistValues(); const state = { ...action }; - const valueMatch = - action.value !== undefined - ? values.find(x => x.value === action.value) - : undefined; + const valueMatch = action.value !== undefined ? values.find((x) => x.value === action.value) : undefined; const newValueMatch = - action.newValue !== undefined - ? values.find(x => x.value === action.newValue) - : undefined; + action.newValue !== undefined ? values.find((x) => x.value === action.newValue) : undefined; state.absent = !valueMatch; state.active = valueMatch?.active; - state._newValueExists = - Boolean(newValueMatch) || action.newValue === null; - result.picklistValues.push(state); + state._newValueExists = Boolean(newValueMatch) || action.newValue === null; + result.picklistValues!.push(state); + await page.close(); } } if (definition.fieldDependencies) { - result.fieldDependencies = await new FieldDependencies( - this.browserforce, - this.org - ).retrieve(definition.fieldDependencies); + const deps = await new FieldDependencies(this.browserforce).retrieve(definition.fieldDependencies); + result.fieldDependencies!.push(...deps); } return result; } - public diff(state: Config, definition: Config): Config { - const changes = {}; + public diff(state: Config, definition: Config): Config | undefined { + const changes: Config = {}; if (definition.picklistValues) { - changes['picklistValues'] = definition.picklistValues.filter( - (target, i) => { - const source = state.picklistValues[i]; - if (target.absent) { - return target.absent !== source.absent; - } - if (target.active !== undefined) { - return target.active !== source.active; - } - // replacing a picklist value is not idempotent - if ( - source._newValueExists && - (target.value !== undefined || target.replaceAllBlankValues) - ) { - return true; - } - if (target.newValue && !source._newValueExists) { - // New value doesn't exist in org yet - return true; - } - return false; + const picklistValues = definition.picklistValues.filter((target, i) => { + const source = state.picklistValues?.[i]; + if (target.absent) { + return target.absent !== source?.absent; } - ); + if (target.active !== undefined) { + return target.active !== source?.active; + } + // replacing a picklist value is not idempotent + if (source?._newValueExists && (target.value !== undefined || target.replaceAllBlankValues)) { + return true; + } + if (target.newValue && !source?._newValueExists) { + // New value doesn't exist in org yet + return true; + } + return false; + }); + if (picklistValues.length) { + changes.picklistValues = picklistValues; + } } if (definition.fieldDependencies) { - changes['fieldDependencies'] = new FieldDependencies( - this.browserforce, - this.org - ).diff(state.fieldDependencies, definition.fieldDependencies); + const fieldDependencies = new FieldDependencies(this.browserforce).diff( + state.fieldDependencies, + definition.fieldDependencies + ) as FieldDependenciesConfig; + if (fieldDependencies !== undefined) { + changes.fieldDependencies = fieldDependencies; + } } - return removeEmptyValues(changes); + return Object.keys(changes).length ? changes : undefined; } public async apply(config: Config): Promise { @@ -115,72 +98,59 @@ export class Picklists extends BrowserforcePlugin { if (config.picklistValues) { const fileProperties = await listMetadata( conn, - config.picklistValues.map(x => x.metadataType) + config.picklistValues.map((x) => x.metadataType) ); for (const action of config.picklistValues) { - const picklistUrl = getPicklistUrl( - action.metadataType, - action.metadataFullName, - fileProperties - ); - const page = await this.browserforce.openPage(picklistUrl); - const picklistPage = new PicklistPage(page); - if (action.active !== undefined) { - await picklistPage.clickActivateDeactivateActionForValue( - action.value, - action.active - ); - } else if (action.absent) { - const replacePage = await picklistPage.clickDeleteActionForValue( - action.value - ); - await replacePage.replaceAndDelete(action.newValue); - } else if ( - !action.value && - action.newValue && - !action.replaceAllBlankValues - ) { - await picklistPage.clickNewActionButton(); - - if (action.statusCategory) { - await new StatusPicklistAddPage(page).add( - action.newValue, - action.statusCategory - ); + await retry(async () => { + const picklistUrl = getPicklistUrl(action.metadataType, action.metadataFullName, fileProperties); + const page = await this.browserforce.openPage(picklistUrl); + const picklistPage = new PicklistPage(page); + if (action.active !== undefined && action.value !== undefined) { + // activate/deactivate + await picklistPage.clickActivateDeactivateActionForValue(action.value, action.active); + } else if (action.absent && action.value !== undefined) { + // delete + const replacePage = await picklistPage.clickDeleteActionForValue(action.value); + await replacePage.replaceAndDelete(action.newValue); + await replacePage.save(); + } else if ( + action.value === undefined && + action.newValue !== undefined && + action.replaceAllBlankValues === undefined + ) { + // create + await picklistPage.clickNewActionButton(); + if (action.statusCategory) { + await new StatusPicklistAddPage(page).add(action.newValue, action.statusCategory); + } else { + await new DefaultPicklistAddPage(page).add(action.newValue); + } + } else if (action.value !== undefined && action.newValue !== undefined) { + // replace + const replacePage = await picklistPage.clickReplaceActionButton(); + await replacePage.replace(action.value, action.newValue, action.replaceAllBlankValues); } else { - await new DefaultPicklistAddPage(page).add(action.newValue); + throw new Error(`Could not determine action for input: ${JSON.stringify(action)}`); } - } else { - const replacePage = await picklistPage.clickReplaceActionButton(); - await replacePage.replace( - action.value, - action.newValue, - action.replaceAllBlankValues - ); - } + await page.close(); + }); } } if (config.fieldDependencies) { - await new FieldDependencies(this.browserforce, this.org).apply( - config.fieldDependencies - ); + await new FieldDependencies(this.browserforce).apply(config.fieldDependencies); } } } -function getPicklistUrl( - type: string, - fullName: string, - fileProperties?: Array -): string { +function getPicklistUrl(type: string, fullName: string, fileProperties?: FileProperties[]): string { let picklistUrl; if (type === 'StandardValueSet') { picklistUrl = determineStandardValueSetEditUrl(fullName); } else { - const fileProperty = fileProperties.find( - x => x.type === type && x.fullName === fullName - ); - picklistUrl = `${fileProperty.id}`; + const fileProperty = fileProperties?.find((x) => x.type === type && x.fullName === fullName); + if (fileProperty) { + picklistUrl = `${fileProperty.id}`; + } } return picklistUrl; } @@ -188,8 +158,8 @@ function getPicklistUrl( async function listMetadata(conn, sobjectTypes): Promise { let uniqueSobjectTypes = [...new Set(sobjectTypes)]; // don't list StandardValueSet as the FileProperties are broken - uniqueSobjectTypes = uniqueSobjectTypes.filter(x => x !== 'StandardValueSet'); - const queries = uniqueSobjectTypes.map(type => { + uniqueSobjectTypes = uniqueSobjectTypes.filter((x) => x !== 'StandardValueSet'); + const queries = uniqueSobjectTypes.map((type) => { return { type }; diff --git a/src/plugins/picklists/pages.ts b/src/plugins/picklists/pages.ts index 750ac521..174a8017 100644 --- a/src/plugins/picklists/pages.ts +++ b/src/plugins/picklists/pages.ts @@ -1,4 +1,3 @@ -import pRetry from 'p-retry'; import { JSHandle, Page } from 'puppeteer'; // table columns @@ -19,17 +18,15 @@ export class PicklistPage { this.page = page; } - public async getPicklistValues(): Promise> { + public async getPicklistValues(): Promise { // wait for New button in any related list await this.page.waitForSelector('body table input[name="new"]'); - const resolvePicklistValueNames = async xpath => { + const resolvePicklistValueNames = async (xpath) => { const fullNameHandles = await this.page.$x(xpath); const innerTextJsHandles = await Promise.all>( - fullNameHandles.map(handle => handle.getProperty('innerText')) - ); - const fullNames = await Promise.all( - innerTextJsHandles.map(handle => handle.jsonValue()) + fullNameHandles.map((handle) => handle.getProperty('innerText')) ); + const fullNames = await Promise.all(innerTextJsHandles.map((handle) => handle.jsonValue())); return fullNames; }; const active = await resolvePicklistValueNames( @@ -39,10 +36,10 @@ export class PicklistPage { `//tr[td[1]//a[contains(@href, "/setup/ui/picklist_masteractivate")]]//td[2]` ); return [ - ...active.map(x => { + ...active.map((x) => { return { value: x, active: true }; }), - ...inactive.map(x => { + ...inactive.map((x) => { return { value: x, active: false }; }) ]; @@ -51,41 +48,27 @@ export class PicklistPage { const NEW_ACTION_BUTTON_XPATH = '//tr[td[2]]//input[contains(@onclick, "/setup/ui/picklist_masteredit")][@value=" New "]'; await this.page.waitForXPath(NEW_ACTION_BUTTON_XPATH); - const NEW_ACTION_BUTTON = (await this.page.$x(NEW_ACTION_BUTTON_XPATH))[0]; - await Promise.all([ - this.page.waitForNavigation(), - NEW_ACTION_BUTTON.click() - ]); + const newActionButton = (await this.page.$x(NEW_ACTION_BUTTON_XPATH))[0]; + await Promise.all([this.page.waitForNavigation(), this.page.evaluate((e) => e.click(), newActionButton)]); } public async clickReplaceActionButton(): Promise { const REPLACE_ACTION_BUTTON = 'input[name="replace"]'; await this.page.waitForSelector(REPLACE_ACTION_BUTTON); - await Promise.all([ - this.page.waitForNavigation(), - this.page.click(REPLACE_ACTION_BUTTON) - ]); + await Promise.all([this.page.waitForNavigation(), this.page.click(REPLACE_ACTION_BUTTON)]); return new PicklistReplacePage(this.page); } - public async clickDeleteActionForValue( - picklistValueApiName: string - ): Promise { - const xpath = `//tr[td[2][text() = "${picklistValueApiName}"]]//td[1]//a[contains(@href, "/setup/ui/picklist_masterdelete.jsp") and contains(@href, "deleteType=0")]`; + public async clickDeleteActionForValue(picklistValueApiName: string): Promise { + // deactivate: deleteType=1 + // delete: deleteType=0 or no deleteType=1 + const xpath = `//tr[td[2][text() = "${picklistValueApiName}"]]//td[1]//a[contains(@href, "/setup/ui/picklist_masterdelete.jsp") and not(contains(@href, "deleteType=1"))]`; await this.page.waitForXPath(xpath); - const actionLinkHandles = await this.page.$x(xpath); - if (actionLinkHandles.length !== 1) { - throw new Error( - `Could not find delete action for picklist value: ${picklistValueApiName}` - ); - } - this.page.on('dialog', async dialog => { + const deleteLink = (await this.page.$x(xpath))[0]; + this.page.on('dialog', async (dialog) => { await dialog.accept(); }); - await Promise.all([ - this.page.waitForNavigation(), - actionLinkHandles[0].click() - ]); + await Promise.all([this.page.waitForNavigation(), this.page.evaluate((e) => e.click(), deleteLink)]); await throwPageErrors(this.page); return new PicklistReplaceAndDeletePage(this.page); } @@ -95,28 +78,19 @@ export class PicklistPage { active: boolean ): Promise { let xpath; - let actionName; if (active) { xpath = `//tr[td[2][text() = "${picklistValueApiName}"]]//td[1]//a[contains(@href, "/setup/ui/picklist_masteractivate.jsp")]`; - actionName = 'activate'; } else { + // deactivate: deleteType=1 + // delete: deleteType=0 or no deleteType=1 xpath = `//tr[td[2][text() = "${picklistValueApiName}"]]//td[1]//a[contains(@href, "/setup/ui/picklist_masterdelete.jsp") and contains(@href, "deleteType=1")]`; - actionName = 'deactivate'; } await this.page.waitForXPath(xpath); - const actionLinkHandles = await this.page.$x(xpath); - if (actionLinkHandles.length !== 1) { - throw new Error( - `Could not find ${actionName} action for picklist value: ${picklistValueApiName}` - ); - } - this.page.on('dialog', async dialog => { + const actionLink = (await this.page.$x(xpath))[0]; + this.page.on('dialog', async (dialog) => { await dialog.accept(); }); - await Promise.all([ - this.page.waitForNavigation(), - actionLinkHandles[0].click() - ]); + await Promise.all([this.page.waitForNavigation(), this.page.evaluate((e) => e.click(), actionLink)]); await throwPageErrors(this.page); return this.page; } @@ -140,29 +114,9 @@ export class DefaultPicklistAddPage { } async save(): Promise { - await pRetry( - async () => { - await this.page.waitForSelector(this.saveButton); - await Promise.all([ - this.page.waitForNavigation(), - this.page.click(this.saveButton) - ]); - await throwPageErrors(this.page); - }, - { - onFailedAttempt: error => { - console.warn( - `retrying ${error.retriesLeft} more time(s) because of "${error}"` - ); - }, - retries: process.env.BROWSERFORCE_RETRY_MAX_RETRIES - ? parseInt(process.env.BROWSERFORCE_RETRY_MAX_RETRIES, 10) - : 6, - minTimeout: process.env.BROWSERFORCE_RETRY_TIMEOUT_MS - ? parseInt(process.env.BROWSERFORCE_RETRY_TIMEOUT_MS, 10) - : 4000 - } - ); + await this.page.waitForSelector(this.saveButton); + await Promise.all([this.page.waitForNavigation(), this.page.click(this.saveButton)]); + await throwPageErrors(this.page); } } @@ -188,29 +142,9 @@ export class StatusPicklistAddPage { } async save(): Promise { - await pRetry( - async () => { - await this.page.waitForSelector(this.saveButton); - await Promise.all([ - this.page.waitForNavigation(), - this.page.click(this.saveButton) - ]); - await throwPageErrors(this.page); - }, - { - onFailedAttempt: error => { - console.warn( - `retrying ${error.retriesLeft} more time(s) because of "${error}"` - ); - }, - retries: process.env.BROWSERFORCE_RETRY_MAX_RETRIES - ? parseInt(process.env.BROWSERFORCE_RETRY_MAX_RETRIES, 10) - : 6, - minTimeout: process.env.BROWSERFORCE_RETRY_TIMEOUT_MS - ? parseInt(process.env.BROWSERFORCE_RETRY_TIMEOUT_MS, 10) - : 4000 - } - ); + await this.page.waitForSelector(this.saveButton); + await Promise.all([this.page.waitForNavigation(), this.page.click(this.saveButton)]); + await throwPageErrors(this.page); } } @@ -222,11 +156,7 @@ export class PicklistReplacePage { this.page = page; } - async replace( - value: string, - newValue: string, - replaceAllBlankValues?: boolean - ): Promise { + async replace(value: string, newValue: string, replaceAllBlankValues?: boolean): Promise { const OLD_VALUE_SELECTOR = 'input#nf'; const NEW_VALUE_SELECTOR = 'select#nv'; const REPLACE_ALL_BLANK_VALUES_CHECKBOX = 'input#fnv'; @@ -246,29 +176,9 @@ export class PicklistReplacePage { } async save(): Promise { - await pRetry( - async () => { - await this.page.waitForSelector(this.saveButton); - await Promise.all([ - this.page.waitForNavigation(), - this.page.click(this.saveButton) - ]); - await throwPageErrors(this.page); - }, - { - onFailedAttempt: error => { - console.warn( - `retrying ${error.retriesLeft} more time(s) because of "${error}"` - ); - }, - retries: process.env.BROWSERFORCE_RETRY_MAX_RETRIES - ? parseInt(process.env.BROWSERFORCE_RETRY_MAX_RETRIES, 10) - : 6, - minTimeout: process.env.BROWSERFORCE_RETRY_TIMEOUT_MS - ? parseInt(process.env.BROWSERFORCE_RETRY_TIMEOUT_MS, 10) - : 4000 - } - ); + await this.page.waitForSelector(this.saveButton); + await Promise.all([this.page.waitForNavigation(), this.page.click(this.saveButton)]); + await throwPageErrors(this.page); } } @@ -278,10 +188,9 @@ export class PicklistReplaceAndDeletePage extends PicklistReplacePage { this.saveButton = 'input[name="delID"][type="submit"]'; } - async replaceAndDelete(newValue: string): Promise { + async replaceAndDelete(newValue?: string): Promise { const NEW_VALUE_SELECTOR = 'select#p13'; - const REPLACE_WITH_BLANK_VALUE_RADIO_INPUT = - 'input#ReplaceValueWithNullValue'; + const REPLACE_WITH_BLANK_VALUE_RADIO_INPUT = 'input#ReplaceValueWithNullValue'; // select option value if (newValue !== undefined && newValue !== null) { await this.page.waitForSelector(NEW_VALUE_SELECTOR); @@ -290,17 +199,13 @@ export class PicklistReplaceAndDeletePage extends PicklistReplacePage { await this.page.waitForSelector(REPLACE_WITH_BLANK_VALUE_RADIO_INPUT); await this.page.click(REPLACE_WITH_BLANK_VALUE_RADIO_INPUT); } - await this.save(); } } async function throwPageErrors(page: Page): Promise { const errorHandle = await page.$('div#validationError div.messageText'); if (errorHandle) { - const errorMsg = await page.evaluate( - (div: HTMLDivElement) => div.innerText, - errorHandle - ); + const errorMsg = await page.evaluate((div: HTMLDivElement) => div.innerText, errorHandle); await errorHandle.dispose(); if (errorMsg && errorMsg.trim()) { throw new Error(errorMsg.trim()); diff --git a/src/plugins/picklists/standard-value-set.ts b/src/plugins/picklists/standard-value-set.ts index 73631e50..fe566418 100644 --- a/src/plugins/picklists/standard-value-set.ts +++ b/src/plugins/picklists/standard-value-set.ts @@ -1,9 +1,7 @@ import STANDARDVALUESET_MAPPING from '@mdapi-issues/listmetadata-standardvalueset/lib/mapping'; -const editUrl = (id: string, type: string) => - `_ui/common/config/field/StandardFieldAttributes/d?id=${id}&type=${type}`; -const editUrlMasterDetail = (tid: string, pt: string) => - `setup/ui/picklist_masterdetail.jsp?tid=${tid}&pt=${pt}`; +const editUrl = (id: string, type: string) => `_ui/common/config/field/StandardFieldAttributes/d?id=${id}&type=${type}`; +const editUrlMasterDetail = (tid: string, pt: string) => `setup/ui/picklist_masterdetail.jsp?tid=${tid}&pt=${pt}`; const mapping = { AccountContactMultiRoles: editUrl('Roles', 'AccountContactRelation'), @@ -70,19 +68,15 @@ const mapping = { WorkTypeGroupAddInfo: '' }; -export function determineStandardValueSetEditUrl( - standardValueSet: string -): string { +export function determineStandardValueSetEditUrl(standardValueSet: string): string { if (mapping[standardValueSet] !== '') { return mapping[standardValueSet]; } else { const standardField = Object.keys(STANDARDVALUESET_MAPPING).find( - key => STANDARDVALUESET_MAPPING[key] === standardValueSet + (key) => STANDARDVALUESET_MAPPING[key] === standardValueSet ); if (!standardField) { - throw new Error( - `Could not determine Edit URL for StandardValueSet:${standardValueSet}` - ); + throw new Error(`Could not determine Edit URL for StandardValueSet:${standardValueSet}`); } return editUrl(standardValueSet, standardField.split('.')[0]); } diff --git a/src/plugins/record-types/index.e2e-spec.ts b/src/plugins/record-types/index.e2e-spec.ts index 36b7d673..77579e97 100644 --- a/src/plugins/record-types/index.e2e-spec.ts +++ b/src/plugins/record-types/index.e2e-spec.ts @@ -3,70 +3,70 @@ import * as child from 'child_process'; import * as path from 'path'; import { RecordTypes } from '.'; -describe(RecordTypes.name, function() { - this.slow('30s'); - this.timeout('2m'); - this.slow('30s'); +describe(RecordTypes.name, function () { this.timeout('10m'); + let plugin; + before(() => { + plugin = new RecordTypes(global.bf); + }); + + const configDelete = { + deletions: [ + { + fullName: 'Vehicle__c.SUV' + } + ] + }; + const configDeleteActive = { + deletions: [ + { + fullName: 'Vehicle__c.CUV' + } + ] + }; + const configDeleteAndReplace = { + deletions: [ + { + fullName: 'Vehicle__c.SportsCar', + replacement: 'Vehicle__c.Bicycle' + } + ] + }; + it('should deploy a CustomObject for testing', () => { - const sourceDeployCmd = child.spawnSync('sfdx', [ - 'force:source:deploy', - '-p', + const sourceDeployCmd = child.spawnSync('sf', [ + 'project', + 'deploy', + 'start', + '-d', path.join(__dirname, 'sfdx-source'), '--json' ]); - assert.deepStrictEqual( - sourceDeployCmd.status, - 0, - sourceDeployCmd.output.toString() - ); + assert.deepStrictEqual(sourceDeployCmd.status, 0, sourceDeployCmd.output.toString()); }); - it('should delete a record type', () => { - const replaceCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'delete.json')) - ]); - assert.deepStrictEqual(replaceCmd.status, 0, replaceCmd.output.toString()); - assert.ok( - /changing 'deletions' to.*/.test(replaceCmd.output.toString()), - replaceCmd.output.toString() - ); + it('should delete a record type', async () => { + await plugin.run(configDelete); }); - it('should not do anything when the record type does not exist', () => { - const replaceCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'delete.json')) - ]); - assert.deepStrictEqual(replaceCmd.status, 0, replaceCmd.output.toString()); - assert.ok( - /no action necessary/.test(replaceCmd.output.toString()), - replaceCmd.output.toString() - ); + it('should not do anything when the record type does not exist', async () => { + const res = await plugin.run(configDelete); + assert.deepStrictEqual(res, { message: 'no action necessary' }); }); - it('should fail deleting an active record type', () => { - const replaceCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'delete-active.json')) - ]); - assert.deepStrictEqual(replaceCmd.status, 1, replaceCmd.output.toString()); - assert.ok( - /Cannot delete active RecordType/.test(replaceCmd.output.toString()), - replaceCmd.output.toString() - ); + it('should fail deleting an active record type', async () => { + let err; + try { + await plugin.run(configDeleteActive); + } catch (e) { + err = e; + } + assert.throws(() => { + throw err; + }, /Cannot delete active RecordType/); }); - it('should delete and replace a record type', () => { - const replaceCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'delete-and-replace.json')) - ]); - assert.deepStrictEqual(replaceCmd.status, 0, replaceCmd.output.toString()); - assert.ok( - /changing 'deletions' to.*/.test(replaceCmd.output.toString()), - replaceCmd.output.toString() - ); + it('should delete and replace a record type', async () => { + await plugin.run(configDeleteAndReplace); + }); + it('should not need to do anything for non-existent picklists', async () => { + const res = await plugin.run(configDeleteAndReplace); + assert.deepStrictEqual(res, { message: 'no action necessary' }); }); }); diff --git a/src/plugins/record-types/index.ts b/src/plugins/record-types/index.ts index 76cf9e47..95f60661 100644 --- a/src/plugins/record-types/index.ts +++ b/src/plugins/record-types/index.ts @@ -12,40 +12,27 @@ type RecordTypeConfig = { }; export class RecordTypes extends BrowserforcePlugin { - public async retrieve(definition?: Config): Promise { + public async retrieve(definition: Config): Promise { const conn = this.org.getConnection(); - const response = { + const response: Config = { deletions: [] }; const recordTypeFileProperties = await listRecordTypes(conn); const recordTypes = await queryRecordTypes(conn); for (const deletion of definition.deletions) { - const recordType = getRecordType( - deletion.fullName, - recordTypeFileProperties, - recordTypes - ); + const recordType = getRecordType(deletion.fullName, recordTypeFileProperties, recordTypes); if (recordType) { if (recordType.IsActive) { - throw new Error( - `Cannot delete active RecordType: ${deletion.fullName}` - ); + throw new Error(`Cannot delete active RecordType: ${deletion.fullName}`); } if (deletion.replacement) { - const replacementRecordType = getRecordType( - deletion.replacement, - recordTypeFileProperties, - recordTypes - ); + const replacementRecordType = getRecordType(deletion.replacement, recordTypeFileProperties, recordTypes); if (!replacementRecordType) { - throw new Error( - `Could not find replacement RecordType: ${deletion.replacement}` - ); + throw new Error(`Could not find replacement RecordType: ${deletion.replacement}`); } } response.deletions.push({ - ...deletion, - actionRequired: true + ...deletion }); } else { response.deletions.push(deletion); @@ -60,11 +47,7 @@ export class RecordTypes extends BrowserforcePlugin { const recordTypes = await queryRecordTypes(conn); for (const deletion of config.deletions) { - const recordType = getRecordType( - deletion.fullName, - recordTypeFileProperties, - recordTypes - ); + const recordType = getRecordType(deletion.fullName, recordTypeFileProperties, recordTypes); const page = await this.browserforce.openPage( `ui/setup/rectype/RecordTypes?type=${recordType.EntityDefinitionId}` ); @@ -72,22 +55,20 @@ export class RecordTypes extends BrowserforcePlugin { const deletePage = await recordTypePage.clickDeleteAction(recordType.Id); let newRecordTypeId; if (deletion.replacement) { - const replacementRecordType = getRecordType( - deletion.replacement, - recordTypeFileProperties, - recordTypes - ); + const replacementRecordType = getRecordType(deletion.replacement, recordTypeFileProperties, recordTypes); newRecordTypeId = replacementRecordType.Id; } await deletePage.replace(newRecordTypeId); + await page.close(); } } } async function listRecordTypes(conn) { - return await conn.metadata.list({ + const recordTypes = await conn.metadata.list({ type: 'RecordType' }); + return recordTypes; } type RecordType = { @@ -96,7 +77,7 @@ type RecordType = { IsActive: boolean; }; -async function queryRecordTypes(conn: Connection): Promise> { +async function queryRecordTypes(conn: Connection): Promise { const recordTypesResult = await conn.tooling.query( `SELECT Id, EntityDefinitionId, IsActive FROM RecordType` ); @@ -105,9 +86,7 @@ async function queryRecordTypes(conn: Connection): Promise> { } function getRecordType(fullName: string, fileProperties, recordTypes) { - const recordTypeFileProperty = fileProperties.find( - (fp) => fp.fullName === fullName - ); + const recordTypeFileProperty = fileProperties.find((fp) => fp.fullName === fullName); if (recordTypeFileProperty) { return recordTypes.find((x) => x.Id === recordTypeFileProperty.id); } diff --git a/src/plugins/record-types/pages.ts b/src/plugins/record-types/pages.ts index 20001cfa..840ba747 100644 --- a/src/plugins/record-types/pages.ts +++ b/src/plugins/record-types/pages.ts @@ -7,24 +7,11 @@ export class RecordTypePage { this.page = page; } - public async clickDeleteAction( - recordTypeId: string - ): Promise { - const xpath = `//a[contains(@href, "setup/ui/recordtypedelete.jsp?id=${recordTypeId.slice( - 0, - 15 - )}")]`; + public async clickDeleteAction(recordTypeId: string): Promise { + const xpath = `//a[contains(@href, "setup/ui/recordtypedelete.jsp?id=${recordTypeId.slice(0, 15)}")]`; await this.page.waitForXPath(xpath); - const actionLinkHandles = await this.page.$x(xpath); - if (actionLinkHandles.length !== 1) { - throw new Error( - `Could not find delete action for record type id: ${recordTypeId}` - ); - } - await Promise.all([ - this.page.waitForNavigation(), - actionLinkHandles[0].click() - ]); + const deleteLink = (await this.page.$x(xpath))[0]; + await Promise.all([this.page.waitForNavigation(), this.page.evaluate((e) => e.click(), deleteLink)]); return new RecordTypeDeletePage(this.page); } } @@ -49,10 +36,7 @@ export class RecordTypeDeletePage { async save(): Promise { await this.page.waitForSelector(this.saveButton); - await Promise.all([ - this.page.waitForNavigation(), - this.page.click(this.saveButton) - ]); + await Promise.all([this.page.waitForNavigation(), this.page.click(this.saveButton)]); await this.throwPageErrors(); } @@ -61,12 +45,9 @@ export class RecordTypeDeletePage { if (!saveButton) { const bodyHandle = await this.page.$('div.pbBody'); if (bodyHandle) { - const errorMsg = await this.page.evaluate( - (div: HTMLDivElement) => div.textContent, - bodyHandle - ); + const errorMsg = await this.page.evaluate((div: HTMLDivElement) => div.textContent, bodyHandle); await bodyHandle.dispose(); - if (errorMsg && errorMsg.trim()) { + if (errorMsg?.trim()) { throw new Error(errorMsg.trim()); } } @@ -74,16 +55,11 @@ export class RecordTypeDeletePage { } async throwPageErrors(): Promise { - const errorHandle = await this.page.$( - 'div#validationError div.messageText' - ); + const errorHandle = await this.page.$('div#validationError div.messageText'); if (errorHandle) { - const errorMsg = await this.page.evaluate( - (div: HTMLDivElement) => div.innerText, - errorHandle - ); + const errorMsg = await this.page.evaluate((div: HTMLDivElement) => div.innerText, errorHandle); await errorHandle.dispose(); - if (errorMsg && errorMsg.trim()) { + if (errorMsg?.trim()) { throw new Error(errorMsg.trim()); } } diff --git a/src/plugins/relate-contact-to-multiple-accounts/index.e2e-spec.ts b/src/plugins/relate-contact-to-multiple-accounts/index.e2e-spec.ts index 1837ac9f..f812b84b 100644 --- a/src/plugins/relate-contact-to-multiple-accounts/index.e2e-spec.ts +++ b/src/plugins/relate-contact-to-multiple-accounts/index.e2e-spec.ts @@ -1,57 +1,31 @@ import assert from 'assert'; -import * as child from 'child_process'; -import * as path from 'path'; import { RelateContactToMultipleAccounts } from '.'; -describe(RelateContactToMultipleAccounts.name, function() { - this.slow('30s'); - this.timeout('2m'); - it('should enable', () => { - const enableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'enable.json')) - ]); - assert.deepStrictEqual(enableCmd.status, 0, enableCmd.output.toString()); - assert.ok( - /to 'true'/.test(enableCmd.output.toString()), - enableCmd.output.toString() - ); +describe(RelateContactToMultipleAccounts.name, function () { + let plugin; + before(() => { + plugin = new RelateContactToMultipleAccounts(global.bf); }); - it('should already be enabled', () => { - const enableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(__dirname, 'enable.json') - ]); - assert.deepStrictEqual(enableCmd.status, 0, enableCmd.output.toString()); - assert.ok( - /no action necessary/.test(enableCmd.output.toString()), - enableCmd.output.toString() - ); + + const configEnabled = { + enabled: true + }; + const configDisabled = { + enabled: false + }; + + it('should enable', async () => { + await plugin.run(configEnabled); + }); + it('should be enabled', async () => { + const res = await plugin.run(configEnabled); + assert.deepStrictEqual(res, { message: 'no action necessary' }); }); - it('should disable', () => { - const disableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'disable.json')) - ]); - assert.deepStrictEqual(disableCmd.status, 0, disableCmd.output.toString()); - assert.ok( - /to 'false'/.test(disableCmd.output.toString()), - disableCmd.output.toString() - ); + it('should disable', async () => { + await plugin.run(configDisabled); }); - it('should already be disabled', () => { - const disableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.join(__dirname, 'disable.json') - ]); - assert.deepStrictEqual(disableCmd.status, 0, disableCmd.output.toString()); - assert.ok( - /no action necessary/.test(disableCmd.output.toString()), - disableCmd.output.toString() - ); + it('should be disabled', async () => { + const res = await plugin.run(configDisabled); + assert.deepStrictEqual(res, { message: 'no action necessary' }); }); }); diff --git a/src/plugins/relate-contact-to-multiple-accounts/index.ts b/src/plugins/relate-contact-to-multiple-accounts/index.ts index 871b110b..baa591f8 100644 --- a/src/plugins/relate-contact-to-multiple-accounts/index.ts +++ b/src/plugins/relate-contact-to-multiple-accounts/index.ts @@ -1,3 +1,5 @@ +import { Page } from 'puppeteer'; +import { retry, throwPageErrors } from '../../browserforce'; import { BrowserforcePlugin } from '../../plugin'; const PATHS = { @@ -5,8 +7,14 @@ const PATHS = { }; const SELECTORS = { ENABLED: 'input[id$=":sharedContactsCheckBox"]', + DISABLED_CHECKBOX: 'input[id$=":sharedContactsCheckBox"][disabled=disabled]', EDIT_BUTTON: 'input[id$=":edit"]', - SAVE_BUTTON: 'input[id$=":save"]' + SAVE_BUTTON: 'input[id$=":save"]', + DISABLE_CONFIRM_CHECKBOX: 'input#disable_confirm', + DISABLE_CONFIRM_BUTTON: 'input#sharedContactsDisableConfirmButton', + ENABLING_IN_PROGRESS: '#enablingInProgress', + DISABLING_IN_PROGRESS: '#disablingInProgress', + APPLYING_SETTING_SUCEEDED: '#prefSettingSucceeded' }; type Config = { @@ -16,38 +24,51 @@ type Config = { export class RelateContactToMultipleAccounts extends BrowserforcePlugin { public async retrieve(definition?: Config): Promise { const page = await this.browserforce.openPage(PATHS.BASE); - await page.waitForSelector(SELECTORS.ENABLED); + await page.waitForSelector(SELECTORS.ENABLED, { visible: true }); const response = { - enabled: await page.$eval( - SELECTORS.ENABLED, - (el: HTMLInputElement) => el.checked - ) + enabled: await page.$eval(SELECTORS.ENABLED, (el: HTMLInputElement) => el.checked) }; + await page.close(); return response; } public async apply(config: Config): Promise { const page = await this.browserforce.openPage(PATHS.BASE); + await this.waitForProcessFinished(page); // First we have to click the 'Edit' button, to make the checkbox editable await page.waitForSelector(SELECTORS.EDIT_BUTTON); - await Promise.all([ - page.waitForNavigation(), - page.click(SELECTORS.EDIT_BUTTON) - ]) + await Promise.all([page.waitForNavigation(), page.click(SELECTORS.EDIT_BUTTON)]); // Change the value of the checkbox - await page.waitForSelector(SELECTORS.ENABLED); - await page.$eval( - SELECTORS.ENABLED, - (e: HTMLInputElement, v: boolean) => { - e.checked = v; - }, - config.enabled - ); + await page.waitForSelector(SELECTORS.ENABLED, { visible: true }); + await page.click(SELECTORS.ENABLED); // Save - await page.waitForSelector(SELECTORS.SAVE_BUTTON); - await Promise.all([ - page.waitForNavigation(), - page.click(SELECTORS.SAVE_BUTTON) - ]); + if (config.enabled) { + await page.waitForSelector(SELECTORS.SAVE_BUTTON); + await Promise.all([page.waitForNavigation(), page.click(SELECTORS.SAVE_BUTTON)]); + } else { + await page.waitForSelector(SELECTORS.SAVE_BUTTON); + await page.click(SELECTORS.SAVE_BUTTON); + await page.waitForSelector(SELECTORS.DISABLE_CONFIRM_CHECKBOX, { visible: true }); + await page.click(SELECTORS.DISABLE_CONFIRM_CHECKBOX); + await page.waitForSelector(SELECTORS.DISABLE_CONFIRM_BUTTON); + await Promise.all([page.waitForNavigation(), page.click(SELECTORS.DISABLE_CONFIRM_BUTTON)]); + } + await throwPageErrors(page); + await page.close(); + } + + async waitForProcessFinished(page: Page): Promise { + await retry(async () => { + const enabling = await page.$(SELECTORS.ENABLING_IN_PROGRESS); + if (enabling) { + const message = await enabling.evaluate((div: HTMLDivElement) => div.innerText); + throw new Error(message); + } + const disabling = await page.$(SELECTORS.DISABLING_IN_PROGRESS); + if (disabling) { + const message = await disabling.evaluate((div: HTMLDivElement) => div.innerText); + throw new Error(message); + } + }); } } diff --git a/src/plugins/reports-and-dashboards/folder-sharing/index.ts b/src/plugins/reports-and-dashboards/folder-sharing/index.ts index 7edee6f8..05c4b1c3 100644 --- a/src/plugins/reports-and-dashboards/folder-sharing/index.ts +++ b/src/plugins/reports-and-dashboards/folder-sharing/index.ts @@ -1,3 +1,4 @@ +import { Page } from 'puppeteer'; import { BrowserforcePlugin } from '../../../plugin'; const PATHS = { @@ -18,12 +19,10 @@ export class FolderSharing extends BrowserforcePlugin { const response = { enableEnhancedFolderSharing: true }; + let page: Page; try { - const page = await this.browserforce.openPage(PATHS.BASE); - const frameOrPage = await this.browserforce.waitForSelectorInFrameOrPage( - page, - SELECTORS.BASE - ); + page = await this.browserforce.openPage(PATHS.BASE); + const frameOrPage = await this.browserforce.waitForSelectorInFrameOrPage(page, SELECTORS.BASE); const inputEnable = await frameOrPage.$(SELECTORS.ENABLE_CHECKBOX); if (inputEnable) { response.enableEnhancedFolderSharing = await frameOrPage.$eval( @@ -40,14 +39,13 @@ export class FolderSharing extends BrowserforcePlugin { } throw e; } + await page.close(); return response; } public async apply(config: Config): Promise { if (config.enableEnhancedFolderSharing === false) { - throw new Error( - '`enableEnhancedFolderSharing` cannot be disabled once enabled' - ); + throw new Error('`enableEnhancedFolderSharing` cannot be disabled once enabled'); } const page = await this.browserforce.openPage(PATHS.BASE); await page.waitForSelector(SELECTORS.ENABLE_CHECKBOX); @@ -59,9 +57,7 @@ export class FolderSharing extends BrowserforcePlugin { config.enableEnhancedFolderSharing ); await page.waitForSelector(SELECTORS.SAVE_BUTTON); - await Promise.all([ - page.waitForNavigation(), - page.click(SELECTORS.SAVE_BUTTON) - ]); + await Promise.all([page.waitForNavigation(), page.click(SELECTORS.SAVE_BUTTON)]); + await page.close(); } } diff --git a/src/plugins/reports-and-dashboards/index.ts b/src/plugins/reports-and-dashboards/index.ts index b117effd..257b0001 100644 --- a/src/plugins/reports-and-dashboards/index.ts +++ b/src/plugins/reports-and-dashboards/index.ts @@ -1,6 +1,5 @@ import { BrowserforcePlugin } from '../../plugin'; -import { removeEmptyValues } from '../utils'; -import { Config as FolderSharingConfig, FolderSharing } from './folder-sharing'; +import { FolderSharing, Config as FolderSharingConfig } from './folder-sharing'; type Config = { folderSharing?: FolderSharingConfig; @@ -11,35 +10,27 @@ export class ReportsAndDashboards extends BrowserforcePlugin { const response: Config = {}; if (definition) { if (definition.folderSharing) { - const pluginFolderSharing = new FolderSharing( - this.browserforce, - this.org - ); - response.folderSharing = await pluginFolderSharing.retrieve( - definition.folderSharing - ); + const pluginFolderSharing = new FolderSharing(this.browserforce); + response.folderSharing = await pluginFolderSharing.retrieve(definition.folderSharing); } } return response; } - public diff(state: Config, definition: Config): Config { - const pluginFolderSharing = new FolderSharing(null, null); - const response = { - folderSharing: pluginFolderSharing.diff( - state.folderSharing, - definition.folderSharing - ) - }; - return removeEmptyValues(response); + public diff(state: Config, definition: Config): Config | undefined { + const response: Config = {}; + const folderSharing = new FolderSharing(this.browserforce).diff(state.folderSharing, definition.folderSharing) as + | FolderSharingConfig + | undefined; + if (folderSharing !== undefined) { + response.folderSharing = folderSharing; + } + return Object.keys(response).length ? response : undefined; } public async apply(plan: Config): Promise { if (plan.folderSharing) { - const pluginFolderSharing = new FolderSharing( - this.browserforce, - this.org - ); + const pluginFolderSharing = new FolderSharing(this.browserforce); await pluginFolderSharing.apply(plan.folderSharing); } } diff --git a/src/plugins/salesforce-to-salesforce/index.e2e-spec.ts b/src/plugins/salesforce-to-salesforce/index.e2e-spec.ts index b4b331b4..befd4953 100644 --- a/src/plugins/salesforce-to-salesforce/index.e2e-spec.ts +++ b/src/plugins/salesforce-to-salesforce/index.e2e-spec.ts @@ -1,37 +1,35 @@ import assert from 'assert'; -import * as child from 'child_process'; -import * as path from 'path'; import { SalesforceToSalesforce } from '.'; -describe(SalesforceToSalesforce.name, function() { - this.slow('30s'); - this.timeout('2m'); - it('should enable', () => { - const enableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'enable.json')) - ]); - assert.deepStrictEqual(enableCmd.status, 0, enableCmd.output.toString()); - assert.ok( - /to 'true'/.test(enableCmd.output.toString()), - enableCmd.output.toString() - ); +describe(SalesforceToSalesforce.name, function () { + let plugin; + before(() => { + plugin = new SalesforceToSalesforce(global.bf); }); - it('should fail to disable', () => { - const disableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'disable.json')) - ]); - assert.deepStrictEqual(disableCmd.status, 1, disableCmd.output.toString()); - assert.ok( - /to 'false'/.test(disableCmd.output.toString()), - disableCmd.output.toString() - ); - assert.ok( - /cannot be disabled/.test(disableCmd.output.toString()), - disableCmd.output.toString() - ); + + const configEnabled = { + enabled: true + }; + const configDisabled = { + enabled: false + }; + + it('should enable', async () => { + await plugin.run(configEnabled); + }); + it('should be enabled', async () => { + const state = await plugin.retrieve(); + assert.deepStrictEqual(state, configEnabled); + }); + it('should fail to disable', async () => { + let err; + try { + await plugin.apply(configDisabled); + } catch (e) { + err = e; + } + assert.throws(() => { + throw err; + }, /cannot be disabled/); }); }); diff --git a/src/plugins/salesforce-to-salesforce/index.ts b/src/plugins/salesforce-to-salesforce/index.ts index fbed9156..98be728b 100644 --- a/src/plugins/salesforce-to-salesforce/index.ts +++ b/src/plugins/salesforce-to-salesforce/index.ts @@ -23,11 +23,9 @@ export class SalesforceToSalesforce extends BrowserforcePlugin { }; const inputEnable = await page.$(SELECTORS.ENABLED); if (inputEnable) { - response.enabled = await page.$eval( - SELECTORS.ENABLED, - (el: HTMLInputElement) => el.checked - ); + response.enabled = await page.$eval(SELECTORS.ENABLED, (el: HTMLInputElement) => el.checked); } + await page.close(); return response; } @@ -46,11 +44,9 @@ export class SalesforceToSalesforce extends BrowserforcePlugin { }, config.enabled ); - await Promise.all([ - page.waitForNavigation(), - page.click(SELECTORS.SAVE_BUTTON) - ]); + await Promise.all([page.waitForNavigation(), page.click(SELECTORS.SAVE_BUTTON)]); const result = await this.retrieve(); + await page.close(); if (result.enabled !== config.enabled) { throw new Error('setting was not applied as expected'); } diff --git a/src/plugins/security/certificate-and-key-management/index.test.ts b/src/plugins/security/certificate-and-key-management/index.test.ts new file mode 100644 index 00000000..7afdcc78 --- /dev/null +++ b/src/plugins/security/certificate-and-key-management/index.test.ts @@ -0,0 +1,69 @@ +import assert from 'assert'; +import { CertificateAndKeyManagement, Config } from '.'; + +type T = { + description: string; + source: Config; + target: Config; + expected: Config | undefined; +}; + +const tests: T[] = [ + { + description: 'should not do anything if keystore already exists', + source: { + importFromKeystore: [ + { + name: 'Dummy' + } + ] + }, + target: { + importFromKeystore: [ + { + name: 'Dummy', + filePath: 'foo.jks' + } + ] + }, + expected: undefined + }, + { + description: 'should try to import keystore', + source: { + importFromKeystore: [ + { + name: 'Foo' + } + ] + }, + target: { + importFromKeystore: [ + { + name: 'Dummy', + filePath: 'foo.jks' + } + ] + }, + expected: { + importFromKeystore: [ + { + name: 'Dummy', + filePath: 'foo.jks' + } + ] + } + } +]; + +describe('CertificateAndKeyManagement', () => { + describe('diff()', () => { + const p = new CertificateAndKeyManagement(global.bf); + for (const t of tests) { + it(t.description, () => { + const actual = p.diff(t.source, t.target); + assert.deepStrictEqual(actual, t.expected); + }); + } + }); +}); diff --git a/src/plugins/security/certificate-and-key-management/index.ts b/src/plugins/security/certificate-and-key-management/index.ts index 1769d9b3..cef099f4 100644 --- a/src/plugins/security/certificate-and-key-management/index.ts +++ b/src/plugins/security/certificate-and-key-management/index.ts @@ -1,15 +1,9 @@ import { existsSync } from 'fs'; import type { Record } from 'jsforce'; -import * as jsonMergePatch from 'json-merge-patch'; import * as path from 'path'; import type { ElementHandle } from 'puppeteer'; import * as queryString from 'querystring'; import { BrowserforcePlugin } from '../../../plugin'; -import { - removeEmptyValues, - removeNullValues, - semanticallyCleanObject -} from '../../utils'; const PATHS = { CERT_PREFIX: '0P1', @@ -43,37 +37,30 @@ type Certificate = { type KeyStore = { name: string; - filePath: string; + filePath?: string; password?: string; }; export class CertificateAndKeyManagement extends BrowserforcePlugin { - public async retrieve(definition?: Config): Promise { + public async retrieve(definition: Config): Promise { const response: Config = { certificates: [], importFromKeystore: [] }; let existingCertificates; - if ( - definition?.certificates?.length || - definition?.importFromKeystore?.length - ) { - existingCertificates = await this.org - .getConnection() - .tooling.query( - `SELECT Id, DeveloperName, MasterLabel, OptionsIsPrivateKeyExportable, KeySize FROM Certificate`, - { scanAll: false } - // BUG in jsforce: query acts with scanAll:true and returns deleted CustomObjects. - // It cannot be disabled. - ); + if (definition?.certificates?.length || definition?.importFromKeystore?.length) { + existingCertificates = await this.org.getConnection().tooling.query( + `SELECT Id, DeveloperName, MasterLabel, OptionsIsPrivateKeyExportable, KeySize FROM Certificate`, + { scanAll: false } + // BUG in jsforce: query acts with scanAll:true and returns deleted CustomObjects. + // It cannot be disabled. + ); } if (definition?.certificates?.length) { for (const cert of definition.certificates) { - const existingCert = existingCertificates.records.find( - co => co.DeveloperName === cert.name - ); + const existingCert = existingCertificates.records.find((co) => co.DeveloperName === cert.name); if (existingCert) { - response.certificates.push({ + response.certificates!.push({ _id: existingCert.Id, name: existingCert.DeveloperName, label: existingCert.MasterLabel, @@ -85,13 +72,10 @@ export class CertificateAndKeyManagement extends BrowserforcePlugin { } if (definition?.importFromKeystore?.length) { for (const cert of definition.importFromKeystore) { - const existingCert = existingCertificates.records.find( - co => co.DeveloperName === cert.name - ); + const existingCert = existingCertificates.records.find((co) => co.DeveloperName === cert.name); if (existingCert) { - response.importFromKeystore.push({ - name: existingCert.DeveloperName, - filePath: null + response.importFromKeystore!.push({ + name: existingCert.DeveloperName }); } } @@ -99,35 +83,33 @@ export class CertificateAndKeyManagement extends BrowserforcePlugin { return response; } - public diff(state: Config, definition: Config): Config { - const response: Config = { - certificates: [], - importFromKeystore: [] - }; + public diff(state?: Config, definition?: Config): Config | undefined { + const response: Config = {}; if (state && definition && state.certificates && definition.certificates) { for (const cert of definition.certificates) { - const existingCert = state.certificates.find(c => c.name === cert.name); + const existingCert = state.certificates.find((c) => c.name === cert.name); if (existingCert) { - // move id from state to definition to be retained and used + // copy id from state to definition to be retained and used cert._id = existingCert._id; - delete existingCert._id; } - const certDiff = semanticallyCleanObject( - removeNullValues(jsonMergePatch.generate(existingCert, cert)), - '_id' - ); - if (certDiff) { - response.certificates.push(certDiff); + const certDiff = super.diff(existingCert, cert) as Certificate | undefined; + if (certDiff !== undefined) { + if (!response.certificates) { + response.certificates = []; + } + response.certificates!.push(certDiff); } } } if (definition?.importFromKeystore?.length) { - response.importFromKeystore = - definition?.importFromKeystore?.filter( - cert => !state.importFromKeystore.find(c => c.name === cert.name) - ) || []; + const importFromKeystore = definition?.importFromKeystore?.filter( + (cert) => !state?.importFromKeystore?.find((c) => c.name === cert.name) + ); + if (importFromKeystore.length) { + response.importFromKeystore = importFromKeystore; + } } - return removeEmptyValues(response); + return Object.keys(response).length ? response : undefined; } public async apply(plan: Config): Promise { @@ -151,21 +133,20 @@ export class CertificateAndKeyManagement extends BrowserforcePlugin { `${PATHS.CERT_PREFIX}/e?${queryString.stringify(urlAttributes)}` ); await page.waitForSelector(SELECTORS.SAVE_BUTTON); - await Promise.all([ - page.waitForNavigation(), - page.click(SELECTORS.SAVE_BUTTON) - ]); + await Promise.all([page.waitForNavigation(), page.click(SELECTORS.SAVE_BUTTON)]); + await page.close(); } } } if (plan.importFromKeystore) { for (const certificate of plan.importFromKeystore) { - const page = await this.browserforce.openPage( - `${PATHS.KEYSTORE_IMPORT}` - ); + const page = await this.browserforce.openPage(`${PATHS.KEYSTORE_IMPORT}`); await page.waitForSelector(SELECTORS.FILE_UPLOAD); - const elementHandle = await page.$(SELECTORS.FILE_UPLOAD) as ElementHandle; + const elementHandle = (await page.$(SELECTORS.FILE_UPLOAD)) as ElementHandle; // TODO: make relative to this.command.flags.definitionfile + if (!certificate.filePath) { + throw new Error(`To import a certificate, the filePath is mandatory.`); + } const filePath = path.resolve(certificate.filePath); if (!existsSync(filePath)) { throw new Error(`file does not exist: ${filePath}`); @@ -176,10 +157,7 @@ export class CertificateAndKeyManagement extends BrowserforcePlugin { await page.type(SELECTORS.KEYSTORE_PASSWORD, certificate.password); } await page.waitForSelector(SELECTORS.SAVE_BUTTON); - await Promise.all([ - page.waitForNavigation(), - page.click(SELECTORS.SAVE_BUTTON) - ]); + await Promise.all([page.waitForNavigation(), page.click(SELECTORS.SAVE_BUTTON)]); if (certificate.name) { // rename cert as it has the wrong name // JKS aliases are case-insensitive (and so lowercase) @@ -193,11 +171,10 @@ export class CertificateAndKeyManagement extends BrowserforcePlugin { `${importedCert.Id}/e?MasterLabel=${certificate.name}&DeveloperName=${certificate.name}` ); await certPage.waitForSelector(SELECTORS.SAVE_BUTTON); - await Promise.all([ - certPage.waitForNavigation(), - certPage.click(SELECTORS.SAVE_BUTTON) - ]); + await Promise.all([certPage.waitForNavigation(), certPage.click(SELECTORS.SAVE_BUTTON)]); + await certPage.close(); } + await page.close(); } } } diff --git a/src/plugins/security/identity-provider/index.ts b/src/plugins/security/identity-provider/index.ts index 17408e50..7e8b2fb1 100644 --- a/src/plugins/security/identity-provider/index.ts +++ b/src/plugins/security/identity-provider/index.ts @@ -1,8 +1,6 @@ import type { Record } from 'jsforce'; -import * as jsonMergePatch from 'json-merge-patch'; import pRetry, { AbortError } from 'p-retry'; import { BrowserforcePlugin } from '../../../plugin'; -import { removeNullValues } from '../../utils'; const PATHS = { EDIT_VIEW: 'setup/secur/idp/IdpPage.apexp' @@ -21,34 +19,30 @@ interface CertificateRecord extends Record { } export type Config = { - enabled?: boolean; + enabled: boolean; certificate?: string; }; export class IdentityProvider extends BrowserforcePlugin { - public async retrieve(definition?: Config): Promise { + public async retrieve(): Promise { const page = await this.browserforce.openPage(PATHS.EDIT_VIEW); await page.waitForSelector(SELECTORS.EDIT_BUTTON); const disableButton = await page.$(SELECTORS.DISABLE_BUTTON); - const certNameHandle = await page.$(SELECTORS.CERT_NAME_SPAN); - const response = { - enabled: disableButton !== null + const enabled = disableButton !== null; + const response: Config = { + enabled }; - if (certNameHandle) { - response['certificate'] = await page.evaluate( - (span: HTMLSpanElement) => span.innerText, - certNameHandle - ); + if (enabled) { + const certNameHandle = await page.$(SELECTORS.CERT_NAME_SPAN); + response.certificate = await page.evaluate((span: HTMLSpanElement) => span.innerText, certNameHandle); } + await page.close(); return response; } - public diff(state: Config, definition: Config): Config { - return removeNullValues(jsonMergePatch.generate(state, definition)); - } - public async apply(plan: Config): Promise { if (plan.enabled && plan.certificate && plan.certificate !== '') { + // enable with required certificate // wait for cert to become available in Identity Provider UI await pRetry( async () => { @@ -58,21 +52,16 @@ export class IdentityProvider extends BrowserforcePlugin { `SELECT Id, DeveloperName FROM Certificate WHERE DeveloperName = '${plan.certificate}'` ); if (!certsResponse.totalSize) { - throw new AbortError( - `Could not find Certificate '${plan.certificate}'` - ); + throw new AbortError(`Could not find Certificate '${plan.certificate}'`); } const page = await this.browserforce.openPage(PATHS.EDIT_VIEW); await page.waitForSelector(SELECTORS.EDIT_BUTTON); - await Promise.all([ - page.waitForNavigation(), - page.click(SELECTORS.EDIT_BUTTON) - ]); + await Promise.all([page.waitForNavigation(), page.click(SELECTORS.EDIT_BUTTON)]); await page.waitForSelector(SELECTORS.CHOOSE_CERT); const chooseCertOptions = await page.$$eval( `${SELECTORS.CHOOSE_CERT} option`, (options: HTMLOptionElement[]) => { - return options.map(option => { + return options.map((option) => { return { text: option.text, value: option.value @@ -80,23 +69,19 @@ export class IdentityProvider extends BrowserforcePlugin { }); } ); - const chooseCertOption = chooseCertOptions.find( - x => x.text === plan.certificate - ); + const chooseCertOption = chooseCertOptions.find((x) => x.text === plan.certificate); if (!chooseCertOption) { throw new Error( `Waiting for Certificate '${plan.certificate}' to be available in Identity Provider picklist timed out` ); } await page.select(SELECTORS.CHOOSE_CERT, chooseCertOption.value); - page.on('dialog', async dialog => { + page.on('dialog', async (dialog) => { await dialog.accept(); }); await page.waitForSelector(SELECTORS.SAVE_BUTTON); - await Promise.all([ - page.waitForNavigation(), - page.click(SELECTORS.SAVE_BUTTON) - ]); + await Promise.all([page.waitForNavigation(), page.click(SELECTORS.SAVE_BUTTON)]); + await page.close(); }, { retries: 5, @@ -104,16 +89,15 @@ export class IdentityProvider extends BrowserforcePlugin { } ); } else { + // disable const page = await this.browserforce.openPage(PATHS.EDIT_VIEW); await page.waitForSelector(SELECTORS.EDIT_BUTTON); await page.$(SELECTORS.DISABLE_BUTTON); - page.on('dialog', async dialog => { + page.on('dialog', async (dialog) => { await dialog.accept(); }); - await Promise.all([ - page.waitForNavigation(), - page.click(SELECTORS.DISABLE_BUTTON) - ]); + await Promise.all([page.waitForNavigation(), page.click(SELECTORS.DISABLE_BUTTON)]); + await page.close(); } } } diff --git a/src/plugins/security/index.e2e-spec.ts b/src/plugins/security/index.e2e-spec.ts index 11e24bd6..15755e46 100644 --- a/src/plugins/security/index.e2e-spec.ts +++ b/src/plugins/security/index.e2e-spec.ts @@ -1,120 +1,78 @@ import { Org } from '@salesforce/core'; import assert from 'assert'; -import * as child from 'child_process'; -import * as path from 'path'; import { CertificateAndKeyManagement } from './certificate-and-key-management'; import { IdentityProvider } from './identity-provider'; -describe(`${CertificateAndKeyManagement.name} and ${IdentityProvider.name}`, function() { - this.slow('30s'); - this.timeout('2m'); - it('should fail to enable identity provider with non-existing Certificate', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'identity-provider', 'enable.json')) - ]); - assert.deepStrictEqual(cmd.status, 1, cmd.output.toString()); - assert.ok( - /changing 'identityProvider' to .*"enabled":true/.test( - cmd.output.toString() - ), - cmd.output.toString() - ); - assert.ok( - /Could not find Certificate 'identity_provider'/.test( - cmd.output.toString() - ), - cmd.output.toString() - ); +describe(`${CertificateAndKeyManagement.name} and ${IdentityProvider.name}`, function () { + let pluginIdentityProvider, pluginCertificateManagement; + before(() => { + pluginIdentityProvider = new IdentityProvider(global.bf); + pluginCertificateManagement = new CertificateAndKeyManagement(global.bf); }); - it('should create a self-signed certificate and enable Identity Provider', function() { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve( - path.join(__dirname, 'identity-provider', 'create-cert-and-enable.json') - ) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /changing 'certificateAndKeyManagement' to '{"certificates":\[.*"name":"identity_provider"/.test( - cmd.output.toString() - ), - cmd.output.toString() - ); - assert.ok( - /changing 'identityProvider' to .*"enabled":true/.test( - cmd.output.toString() - ), - cmd.output.toString() - ); + + const configEnabled = { + enabled: true, + certificate: 'identity_provider' + }; + const configDisabled = { + enabled: false + }; + const configGeneratedCert = { + certificates: [ + { + name: 'identity_provider', + label: 'identity_provider' + } + ] + }; + const configImportFromKeystore = { + importFromKeystore: [ + { + filePath: './src/plugins/security/certificate-and-key-management/Dummy.jks', + name: 'Dummy' + } + ] + }; + + it('should fail to enable identity provider with non-existing Certificate', async () => { + let err; + try { + await pluginIdentityProvider.run(configEnabled); + } catch (e) { + err = e; + } + assert.throws(() => { + throw err; + }, /Could not find Certificate 'identity_provider'/); + }); + it('should create a self-signed certificate', async () => { + await pluginCertificateManagement.apply(configGeneratedCert); + }); + it('should not do anything if self-signed certificate is already available', async () => { + // explictly pass definition to retrieve + const res = await pluginCertificateManagement.run(configGeneratedCert); + assert.deepStrictEqual(res, { message: 'no action necessary' }); + }); + it('should enable Identity Provider with generated cert', async () => { + await pluginIdentityProvider.apply(configEnabled); + }); + it('Identity Provider should be enabled', async () => { + const state = await pluginIdentityProvider.retrieve(); + assert.deepStrictEqual(state.enabled, true); }); - it('should not do anything if self-signed certificate is already available', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve( - path.join(__dirname, 'identity-provider', 'create-cert-and-enable.json') - ) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /no action necessary/.test(cmd.output.toString()), - cmd.output.toString() - ); + it('should disable Identity Provider', async () => { + await pluginIdentityProvider.apply(configDisabled); }); - it('should disable Identity Provider', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'identity-provider', 'disable.json')) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /changing 'identityProvider' to .*"enabled":false/.test( - cmd.output.toString() - ), - cmd.output.toString() - ); + it('Identity Provider should be disabled', async () => { + const state = await pluginIdentityProvider.retrieve(); + assert.deepStrictEqual(state.enabled, false); }); - it('should import a cert from a keystore', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve( - path.join( - __dirname, - 'certificate-and-key-management', - 'import-from-keystore.json' - ) - ) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /changing 'certificateAndKeyManagement' to '{"importFromKeystore":\[.*"filePath"/.test( - cmd.output.toString() - ), - cmd.output.toString() - ); + it('should import a cert from a keystore', async () => { + await pluginCertificateManagement.run(configImportFromKeystore); }); - it('should not do anything if cert is already available in keystore', () => { - const cmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve( - path.join( - __dirname, - 'certificate-and-key-management', - 'import-from-keystore.json' - ) - ) - ]); - assert.deepStrictEqual(cmd.status, 0, cmd.output.toString()); - assert.ok( - /no action necessary/.test(cmd.output.toString()), - cmd.output.toString() - ); + it('should not do anything if cert is already available in keystore', async () => { + const res = await pluginCertificateManagement.run(configImportFromKeystore); + assert.deepStrictEqual(res, { message: 'no action necessary' }); }); it('should delete certificates using Metadata API', async () => { const org = await Org.create({}); diff --git a/src/plugins/security/index.ts b/src/plugins/security/index.ts index f6d07cd6..53dcea9a 100644 --- a/src/plugins/security/index.ts +++ b/src/plugins/security/index.ts @@ -1,18 +1,11 @@ import { BrowserforcePlugin } from '../../plugin'; -import { removeEmptyValues } from '../utils'; import { - Config as CertificateAndKeyManagementConfig, - CertificateAndKeyManagement + CertificateAndKeyManagement, + Config as CertificateAndKeyManagementConfig } from './certificate-and-key-management'; -import { - Config as IdentityProviderConfig, - IdentityProvider -} from './identity-provider'; -import { - Config as LoginAccessPoliciesConfig, - LoginAccessPolicies -} from './login-access-policies'; -import { Config as SharingConfig, Sharing } from './sharing'; +import { IdentityProvider, Config as IdentityProviderConfig } from './identity-provider'; +import { LoginAccessPolicies, Config as LoginAccessPoliciesConfig } from './login-access-policies'; +import { Sharing, Config as SharingConfig } from './sharing'; type Config = { certificateAndKeyManagement?: CertificateAndKeyManagementConfig; @@ -26,87 +19,73 @@ export class Security extends BrowserforcePlugin { const response: Config = {}; if (definition) { if (definition.certificateAndKeyManagement) { - const pluginCKM = new CertificateAndKeyManagement( - this.browserforce, - this.org - ); - response.certificateAndKeyManagement = await pluginCKM.retrieve( - definition.certificateAndKeyManagement - ); + const pluginCKM = new CertificateAndKeyManagement(this.browserforce); + response.certificateAndKeyManagement = await pluginCKM.retrieve(definition.certificateAndKeyManagement); } if (definition.identityProvider) { - const pluginIdentityProvider = new IdentityProvider( - this.browserforce, - this.org - ); - response.identityProvider = await pluginIdentityProvider.retrieve( - definition.identityProvider - ); + const pluginIdentityProvider = new IdentityProvider(this.browserforce); + response.identityProvider = await pluginIdentityProvider.retrieve(); } if (definition.loginAccessPolicies) { - const pluginLoginAccessPolicies = new LoginAccessPolicies( - this.browserforce, - this.org - ); - response.loginAccessPolicies = await pluginLoginAccessPolicies.retrieve( - definition.loginAccessPolicies - ); + const pluginLoginAccessPolicies = new LoginAccessPolicies(this.browserforce); + response.loginAccessPolicies = await pluginLoginAccessPolicies.retrieve(); } if (definition.sharing) { - const pluginSharing = new Sharing(this.browserforce, this.org); - response.sharing = await pluginSharing.retrieve(definition.sharing); + const pluginSharing = new Sharing(this.browserforce); + response.sharing = await pluginSharing.retrieve(); } } return response; } - public diff(state: Config, definition: Config): Config { - const pluginCKM = new CertificateAndKeyManagement(null, null); - const pluginIdentityProvider = new IdentityProvider(null, null); - const pluginLoginAccessPolicies = new LoginAccessPolicies(null, null); - const pluginSharing = new Sharing(null, null); - const response = { - certificateAndKeyManagement: pluginCKM.diff( - state.certificateAndKeyManagement, - definition.certificateAndKeyManagement - ), - identityProvider: pluginIdentityProvider.diff( - state.identityProvider, - definition.identityProvider - ), - loginAccessPolicies: pluginLoginAccessPolicies.diff( - state.loginAccessPolicies, - definition.loginAccessPolicies - ), - sharing: pluginSharing.diff(state.sharing, definition.sharing) - }; - return removeEmptyValues(response); + public diff(state: Config, definition: Config): Config | undefined { + const certificateAndKeyManagement = new CertificateAndKeyManagement(this.browserforce).diff( + state.certificateAndKeyManagement, + definition.certificateAndKeyManagement + ); + const identityProvider = new IdentityProvider(this.browserforce).diff( + state.identityProvider, + definition.identityProvider + ) as IdentityProviderConfig | undefined; + const loginAccessPolicies = new LoginAccessPolicies(this.browserforce).diff( + state.loginAccessPolicies, + definition.loginAccessPolicies + ) as LoginAccessPoliciesConfig | undefined; + const sharing = new Sharing(this.browserforce).diff(state.sharing, definition.sharing) as SharingConfig | undefined; + const response: Config = {}; + if (certificateAndKeyManagement !== undefined) { + response.certificateAndKeyManagement = certificateAndKeyManagement; + } + if (identityProvider !== undefined) { + response.identityProvider = identityProvider; + } + if (loginAccessPolicies !== undefined) { + response.loginAccessPolicies = loginAccessPolicies; + } + if (loginAccessPolicies !== undefined) { + response.loginAccessPolicies = loginAccessPolicies; + } + if (sharing !== undefined) { + response.sharing = sharing; + } + return Object.keys(response).length ? response : undefined; } public async apply(plan: Config): Promise { if (plan.certificateAndKeyManagement) { - const pluginCKM = new CertificateAndKeyManagement( - this.browserforce, - this.org - ); + const pluginCKM = new CertificateAndKeyManagement(this.browserforce); await pluginCKM.apply(plan.certificateAndKeyManagement); } if (plan.identityProvider) { - const pluginIdentityProvider = new IdentityProvider( - this.browserforce, - this.org - ); + const pluginIdentityProvider = new IdentityProvider(this.browserforce); await pluginIdentityProvider.apply(plan.identityProvider); } if (plan.loginAccessPolicies) { - const pluginLoginAccessPolicies = new LoginAccessPolicies( - this.browserforce, - this.org - ); + const pluginLoginAccessPolicies = new LoginAccessPolicies(this.browserforce); await pluginLoginAccessPolicies.apply(plan.loginAccessPolicies); } if (plan.sharing) { - const pluginSharing = new Sharing(this.browserforce, this.org); + const pluginSharing = new Sharing(this.browserforce); await pluginSharing.apply(plan.sharing); } } diff --git a/src/plugins/security/login-access-policies/index.e2e-spec.ts b/src/plugins/security/login-access-policies/index.e2e-spec.ts index c86b99be..457cee10 100644 --- a/src/plugins/security/login-access-policies/index.e2e-spec.ts +++ b/src/plugins/security/login-access-policies/index.e2e-spec.ts @@ -1,37 +1,29 @@ import assert from 'assert'; -import * as child from 'child_process'; -import * as path from 'path'; -import { LoginAccessPolicies } from '.'; +import { type Config, LoginAccessPolicies } from '.'; -describe(LoginAccessPolicies.name, function() { - this.slow('30s'); - this.timeout('2m'); - it('should enable', () => { - const enableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'enable.json')) - ]); - assert.deepStrictEqual(enableCmd.status, 0, enableCmd.output.toString()); - assert.ok( - /changing 'loginAccessPolicies' to '{"administratorsCanLogInAsAnyUser":true}'/.test( - enableCmd.output.toString() - ), - enableCmd.output.toString() - ); +describe(LoginAccessPolicies.name, function () { + let plugin; + before(() => { + plugin = new LoginAccessPolicies(global.bf); }); - it('should disable', () => { - const disableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'disable.json')) - ]); - assert.deepStrictEqual(disableCmd.status, 0, disableCmd.output.toString()); - assert.ok( - /changing 'loginAccessPolicies' to '{"administratorsCanLogInAsAnyUser":false}'/.test( - disableCmd.output.toString() - ), - disableCmd.output.toString() - ); + + describe('administratorsCanLogInAsAnyUser', () => { + const configDisabled: Config = { administratorsCanLogInAsAnyUser: false }; + const configEnabled: Config = { administratorsCanLogInAsAnyUser: true }; + + it('should enable', async () => { + await plugin.run(configEnabled); + }); + it('should be enabled', async () => { + const res = await plugin.retrieve(); + assert.deepStrictEqual(res, configEnabled); + }); + it('should disable', async () => { + await plugin.apply(configDisabled); + }); + it('should be disabled', async () => { + const res = await plugin.retrieve(); + assert.deepStrictEqual(res, configDisabled); + }); }); }); diff --git a/src/plugins/security/login-access-policies/index.ts b/src/plugins/security/login-access-policies/index.ts index 13e4c222..067eb069 100644 --- a/src/plugins/security/login-access-policies/index.ts +++ b/src/plugins/security/login-access-policies/index.ts @@ -14,15 +14,13 @@ export type Config = { }; export class LoginAccessPolicies extends BrowserforcePlugin { - public async retrieve(definition?: Config): Promise { + public async retrieve(): Promise { const page = await this.browserforce.openPage(PATHS.BASE); await page.waitForSelector(SELECTORS.ENABLED); const response = { - administratorsCanLogInAsAnyUser: await page.$eval( - SELECTORS.ENABLED, - (el: HTMLInputElement) => el.checked - ) + administratorsCanLogInAsAnyUser: await page.$eval(SELECTORS.ENABLED, (el: HTMLInputElement) => el.checked) }; + await page.close(); return response; } @@ -36,9 +34,7 @@ export class LoginAccessPolicies extends BrowserforcePlugin { }, config.administratorsCanLogInAsAnyUser ); - await Promise.all([ - page.waitForSelector(SELECTORS.CONFIRM_MESSAGE), - page.click(SELECTORS.SAVE_BUTTON) - ]); + await Promise.all([page.waitForSelector(SELECTORS.CONFIRM_MESSAGE), page.click(SELECTORS.SAVE_BUTTON)]); + await page.close(); } } diff --git a/src/plugins/security/sharing/index.e2e-spec.ts b/src/plugins/security/sharing/index.e2e-spec.ts index 49b42242..3e8ce45c 100644 --- a/src/plugins/security/sharing/index.e2e-spec.ts +++ b/src/plugins/security/sharing/index.e2e-spec.ts @@ -1,37 +1,31 @@ import assert from 'assert'; -import * as child from 'child_process'; -import * as path from 'path'; import { Sharing } from '.'; -describe.skip(Sharing.name, function() { - this.slow('30s'); - this.timeout('2m'); - it('should enable', () => { - const enableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'enable.json')) - ]); - assert.deepStrictEqual(enableCmd.status, 0, enableCmd.output.toString()); - assert.ok( - /to '{"enableExternalSharingModel":true}'/.test( - enableCmd.output.toString() - ), - enableCmd.output.toString() - ); +describe.skip(Sharing.name, function () { + let plugin; + before(() => { + plugin = new Sharing(global.bf); }); - it('should disable', () => { - const disableCmd = child.spawnSync(path.resolve('bin', 'run'), [ - 'browserforce:apply', - '-f', - path.resolve(path.join(__dirname, 'disable.json')) - ]); - assert.deepStrictEqual(disableCmd.status, 0, disableCmd.output.toString()); - assert.ok( - /to '{"enableExternalSharingModel":false}'/.test( - disableCmd.output.toString() - ), - disableCmd.output.toString() - ); + + const configEnabled = { + enableExternalSharingModel: true + }; + const configDisabled = { + enableExternalSharingModel: true + }; + + it('should enable', async () => { + await plugin.run(configEnabled); + }); + it('should be enabled', async () => { + const state = await plugin.retrieve(); + assert.deepStrictEqual(state, configEnabled); + }); + it('should disable', async () => { + await plugin.apply(configDisabled); + }); + it('should be disabled', async () => { + const state = await plugin.retrieve(); + assert.deepStrictEqual(state, configDisabled); }); }); diff --git a/src/plugins/security/sharing/index.ts b/src/plugins/security/sharing/index.ts index 52f64a63..738eb060 100644 --- a/src/plugins/security/sharing/index.ts +++ b/src/plugins/security/sharing/index.ts @@ -5,8 +5,7 @@ const PATHS = { }; const SELECTORS = { EXTERNAL_SHARING_MODEL_BUTTON: '#externalSharingModelButton', - ENABLE_BUTTON: - 'input#externalSharingModelButton:not([onclick*="Modal.confirm"])', + ENABLE_BUTTON: 'input#externalSharingModelButton:not([onclick*="Modal.confirm"])', DISABLE_BUTTON: 'input#externalSharingModelButton[onclick*="Modal.confirm"]', MODAL_DIALOG: 'Modal.confirm' }; @@ -16,35 +15,30 @@ export type Config = { }; export class Sharing extends BrowserforcePlugin { - public async retrieve(definition?: Config): Promise { + public async retrieve(): Promise { const page = await this.browserforce.openPage(PATHS.BASE); await page.waitForSelector(SELECTORS.EXTERNAL_SHARING_MODEL_BUTTON); const buttonOnclick = await page.$eval( SELECTORS.EXTERNAL_SHARING_MODEL_BUTTON, - (el: HTMLInputElement) => el.onclick.toString() + (el: HTMLInputElement) => el.onclick?.toString() || '' ); + await page.close(); return { - enableExternalSharingModel: - buttonOnclick.indexOf(SELECTORS.MODAL_DIALOG) >= 0 + enableExternalSharingModel: buttonOnclick.includes(SELECTORS.MODAL_DIALOG) }; } public async apply(config: Config): Promise { const page = await this.browserforce.openPage(PATHS.BASE); await page.waitForSelector(SELECTORS.EXTERNAL_SHARING_MODEL_BUTTON); - page.on('dialog', async dialog => { + page.on('dialog', async (dialog) => { await dialog.accept(); }); if (config.enableExternalSharingModel) { - await Promise.all([ - page.waitForSelector(SELECTORS.DISABLE_BUTTON), - page.click(SELECTORS.ENABLE_BUTTON) - ]); + await Promise.all([page.waitForSelector(SELECTORS.DISABLE_BUTTON), page.click(SELECTORS.ENABLE_BUTTON)]); } else { - await Promise.all([ - page.waitForSelector(SELECTORS.ENABLE_BUTTON), - page.click(SELECTORS.DISABLE_BUTTON) - ]); + await Promise.all([page.waitForSelector(SELECTORS.ENABLE_BUTTON), page.click(SELECTORS.DISABLE_BUTTON)]); } + await page.close(); } } diff --git a/src/plugins/utils.ts b/src/plugins/utils.ts index 8ccc16d2..e7048f01 100644 --- a/src/plugins/utils.ts +++ b/src/plugins/utils.ts @@ -1,42 +1,47 @@ -export function removeEmptyValues(obj: any): any { - if (!obj) { - obj = {}; - } - return Object.entries(obj).reduce((acc, [key, value]) => { - if (Array.isArray(value)) { - if (value.length) { - acc[key] = value; - } - } else if (typeof value === 'object') { - if (Object.keys(value).length) { - acc[key] = value; - } - } else if (value !== undefined && value !== null) { - acc[key] = value; +import { isDeepStrictEqual } from 'util'; + +// an object only containing an id is semantically empty +export function semanticallyCleanObject(obj: T, id = 'id'): T | undefined { + if (typeof obj === 'object' && obj !== null) { + if (Object.keys(obj).length === 1 && Object.keys(obj)[0] === id) { + return undefined; } - return acc; - }, {}); + } + return obj; } -export function removeNullValues(obj: any): any { - if (!obj) { - obj = {}; +export function isEmptyObjectOrArray(arg: unknown): boolean { + if (typeof arg === 'object' && arg !== null) { + return Object.keys(arg).length === 0; } - Object.entries(obj).forEach( - ([key, val]) => - (val && typeof val === 'object' && removeNullValues(val)) || - ((val === null || val === undefined) && delete obj[key]) - ); - return obj; + return false; } -// an object only containing an id is semantically empty -export function semanticallyCleanObject(obj: any, id = 'id'): any { - if (!obj) { - obj = {}; +export function deepDiff(source: T | undefined, target: T | undefined): T | undefined { + if (isDeepStrictEqual(source, target)) { + return undefined; } - if (Object.keys(obj).length === 1 && Object.keys(obj)[0] === id) { - return null; + if (typeof target === 'object' && target !== null && typeof source === 'object' && source !== null) { + let objectOrArray: T | undefined; + if (Array.isArray(target)) { + objectOrArray = target.map((item, i) => deepDiff(source?.[i], item)).filter((x) => x !== undefined) as + | T + | undefined; + } else { + const targetKeys = Object.keys(target); + const minSource = Object.fromEntries( + Object.entries(source).filter(([key, value]) => targetKeys.includes(key)) + ) as T | {}; + if (!isDeepStrictEqual(minSource, source)) { + return deepDiff(minSource as T, target); + } + objectOrArray = target; + } + if (isEmptyObjectOrArray(objectOrArray)) { + return undefined; + } + return objectOrArray; } - return obj; + // simple value + return target; } diff --git a/test/browserforce.e2e-spec.ts b/test/browserforce.e2e-spec.ts index 9f1b2ec7..a06225b7 100644 --- a/test/browserforce.e2e-spec.ts +++ b/test/browserforce.e2e-spec.ts @@ -1,107 +1,66 @@ -import { UX } from '@salesforce/command'; +import { Ux } from '@salesforce/sf-plugins-core'; import { Org } from '@salesforce/core'; import assert from 'assert'; import { Browserforce } from '../src/browserforce'; describe('Browser', function () { - this.slow('30s'); - this.timeout('2m'); describe('login()', () => { it('should successfully login with valid credentials', async () => { - const defaultScratchOrg = await Org.create({}); - const ux = await UX.create(); - const bf = new Browserforce(defaultScratchOrg, ux); - await bf.login(); - await bf.logout(); + // handled by e2e-setup.ts assert.ok(true); }); it('should fail login with invalid credentials', async () => { const fakeOrg = await Org.create({}); fakeOrg.getConnection().accessToken = 'invalid'; - const ux = await UX.create(); + const ux = new Ux(); const bf = new Browserforce(fakeOrg, ux); await assert.rejects(async () => { await bf.login(); }, /login failed/); - bf.logout(); + await bf.logout(); }); }); describe('getMyDomain()', () => { it('should determine a my domain for a scratch org', async () => { - const defaultScratchOrg = await Org.create({}); - const ux = await UX.create(); - const bf = new Browserforce(defaultScratchOrg, ux); - await bf.login(); - const myDomain = bf.getMyDomain(); - assert.notDeepEqual(null, myDomain); - await bf.logout(); + const myDomain = global.bf.getMyDomain(); + assert.notDeepStrictEqual(myDomain, null); }); }); describe('getInstanceDomain()', () => { it('should determine an instance domain for a scratch org with my domain', async () => { - const defaultScratchOrg = await Org.create({}); - const ux = await UX.create(); - const bf = new Browserforce(defaultScratchOrg, ux); - await bf.login(); - const instanceDomain = bf.getInstanceDomain(); - assert.notDeepEqual(null, instanceDomain); - await bf.logout(); + const instanceDomain = global.bf.getInstanceDomain(); + assert.notDeepStrictEqual(instanceDomain, null); }); }); describe('getLightningUrl()', () => { it('should determine a LEX URL for a scratch org with my domain', async () => { - const defaultScratchOrg = await Org.create({}); - const ux = await UX.create(); - const bf = new Browserforce(defaultScratchOrg, ux); - await bf.login(); - const lexUrl = bf.getLightningUrl(); - assert.notDeepEqual(null, lexUrl); - await bf.logout(); + const lexUrl = global.bf.getLightningUrl(); + assert.notDeepStrictEqual(lexUrl, null); }); }); describe('waitForSelectorInFrameOrPage()', () => { it('should query a selector in LEX and Classic UI', async () => { - const defaultScratchOrg = await Org.create({}); - const ux = await UX.create(); - const bf = new Browserforce(defaultScratchOrg, ux); - await bf.login(); - const page = await bf.openPage('lightning/setup/ExternalStrings/home'); - const frame = await bf.waitForSelectorInFrameOrPage( - page, - 'input[name="edit"]' - ); - await Promise.all([ - page.waitForNavigation(), - frame.click('input[name="edit"]') - ]); - await bf.logout(); + const page = await global.bf.openPage('lightning/setup/ExternalStrings/home'); + const frame = await global.bf.waitForSelectorInFrameOrPage(page, 'input[name="edit"]'); + const button = await frame.$('input[name="edit"]'); + assert.ok(!page.url().includes('/page')); + await Promise.all([page.waitForNavigation(), frame.evaluate((x) => x.click(), button)]); + assert.ok(page.url().includes('/page')); + await page.close(); }); }); describe('throwPageErrors()', () => { it('should throw the page error on internal errors', async () => { - const defaultScratchOrg = await Org.create({}); - const ux = await UX.create(); - const bf = new Browserforce(defaultScratchOrg, ux); - await bf.login(); process.env.BROWSERFORCE_RETRY_TIMEOUT_MS = '0'; await assert.rejects(async () => { - await bf.openPage( - '_ui/common/config/field/StandardFieldAttributes/d?type=Account&id=INVALID_Name' - ); + await global.bf.openPage('_ui/common/config/field/StandardFieldAttributes/d?type=Account&id=INVALID_Name'); }, /Insufficient Privileges/); delete process.env.BROWSERFORCE_RETRY_TIMEOUT_MS; - await bf.logout(); }); it('should not throw any error opening a page', async () => { - const defaultScratchOrg = await Org.create({}); - const ux = await UX.create(); - const bf = new Browserforce(defaultScratchOrg, ux); - await bf.login(); - await bf.openPage( - '_ui/common/config/field/StandardFieldAttributes/d?type=Account&id=Name' - ); - await bf.logout(); + const page = await global.bf.openPage('_ui/common/config/field/StandardFieldAttributes/d?type=Account&id=Name'); + await page.close(); }); }); }); diff --git a/test/e2e-setup.ts b/test/e2e-setup.ts new file mode 100644 index 00000000..cb052692 --- /dev/null +++ b/test/e2e-setup.ts @@ -0,0 +1,15 @@ +import { Org } from '@salesforce/core'; +import { Browserforce } from '../src/browserforce'; +import { Ux } from '@salesforce/sf-plugins-core'; + +before('global setup', async () => { + const org = await Org.create({}); + const ux = new Ux(); + const bf = new Browserforce(org, ux); + global.bf = bf; + await bf.login(); +}); + +after('global setup', async () => { + await global.bf.logout(); +}); diff --git a/test/plugin.test.ts b/test/plugin.test.ts index 2c5d0965..1cde8ea9 100644 --- a/test/plugin.test.ts +++ b/test/plugin.test.ts @@ -12,60 +12,92 @@ class DummyPlugin extends BrowserforcePlugin { describe('BrowserforcePlugin', () => { describe('#diff()', async () => { - it('generates a diff for a simple object', async () => { - const plugin = new DummyPlugin(null, null); - const actions = plugin.diff({ a: 1 }, { a: 2 }); - assert.deepStrictEqual(actions, { a: 2 }); - }); - it('generates a diff for a deep object', async () => { - const plugin = new DummyPlugin(null, null); - const actions = plugin.diff( - { - a: [ - { - a: 1 - } - ] - }, + const plugin = new DummyPlugin(global.bf); + const tests: [description: string, input: [state: unknown, definition: unknown], expected: unknown][] = [ + ['should return target for simple value', [false, true], true], + ['should return target for simple string', [undefined, ''], ''], + ['should return target number vs undefined', [1, undefined], undefined], + ['should return target for simple string', [null, ''], ''], + ['should return target keys only', [{ a: 1 }, { a: 2 }], { a: 2 }], + ['should only keep the object keys of the target', [{ a: 1, b: 1 }, { a: 2 }], { a: 2 }], + ['should recursively compare', [{ a: 1, b: 1 }, { a: 1 }], undefined], + [ + 'should allow unsetting via undefined/null/ or empty string', + [ + { a: 1, n: 1, u: 1, s: 'foo' }, + { a: 2, n: null, u: undefined, s: '' } + ], + { a: 2, n: null, u: undefined, s: '' } + ], + [ + 'should allow unsetting via undefined/null/ or empty string in an array', + [[{ a: 1, n: 1, u: 1, s: 'foo' }], [{ a: 2, n: null, u: undefined, s: '' }]], + [{ a: 2, n: null, u: undefined, s: '' }] + ], + ['should allow unsetting via null in an array', [[{ a: 1, n: 1 }], [{ a: 1, n: null }]], [{ a: 1, n: null }]], + [ + 'generates a diff for a deep object', + [ + { + a: [ + { + a: 1 + } + ] + }, + { a: [{ a: 2 }] } + ], { a: [{ a: 2 }] } - ); - assert.deepStrictEqual(actions, { a: [{ a: 2 }] }); - }); - it('generates a diff for a deep object', async () => { - const plugin = new DummyPlugin(null, null); - const actions = plugin.diff( - { - a: [ - { - a: 1 - }, + ], + [ + 'compares arrays of different lengths by index', + [ + { + a: [ + { + a: 1, + c: 'foo' + }, + { + a: 2, + c: 'baz' + } + ] + }, + { + a: [ + { + a: 2, + b: true + } + ] + } + ], + { a: [{ a: 2, b: true }] } + ], + [ + 'generates a diff for an array', + [ + [ { - a: 2 + a: 1, + b: 'foo' } - ] - }, - { - a: [ + ], + [ { - a: 2, - b: true + a: 2 } ] - } - ); - assert.deepStrictEqual(actions, { a: [{ a: 2, b: true }] }); - }); - it('generates a diff for an array', async () => { - const plugin = new DummyPlugin(null, null); - const actions = plugin.diff( - [ - { - a: 1 - } ], [{ a: 2 }] - ); - assert.deepStrictEqual(actions, [{ a: 2 }]); - }); + ] + ]; + for (const t of tests) { + it(t[0], () => { + const diff = plugin.diff(...t[1]); + assert.deepStrictEqual(diff, t[2]); + }); + } }); }); diff --git a/test/tsconfig.json b/test/tsconfig.json new file mode 100644 index 00000000..1d909c3b --- /dev/null +++ b/test/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "@salesforce/dev-config/tsconfig-test", + "include": ["./**/*.ts"], + "compilerOptions": { + "lib": ["dom", "es2021"], + "skipLibCheck": true, + "strictNullChecks": true, + "esModuleInterop": true + } +} diff --git a/test/utils.test.ts b/test/utils.test.ts index ea776b50..6a648585 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -1,15 +1,12 @@ import assert from 'assert'; -import { semanticallyCleanObject } from '../src/plugins/utils'; +import { isEmptyObjectOrArray, semanticallyCleanObject } from '../src/plugins/utils'; describe('semanticallyCleanObject', () => { it('should clean object', async () => { - assert.deepStrictEqual(semanticallyCleanObject({ id: 'a2' }), null); + assert.deepStrictEqual(semanticallyCleanObject({ id: 'a2' }), undefined); }); it('should clean object with custom id', async () => { - assert.deepStrictEqual( - semanticallyCleanObject({ myid: 'a2' }, 'myid'), - null - ); + assert.deepStrictEqual(semanticallyCleanObject({ myid: 'a2' }, 'myid'), undefined); }); it('should return object as is', async () => { assert.deepStrictEqual(semanticallyCleanObject({ id: 'a2', a: 'hi' }), { @@ -18,9 +15,17 @@ describe('semanticallyCleanObject', () => { }); }); it('should return object as is with custom id', async () => { - assert.deepStrictEqual( - semanticallyCleanObject({ myid: 'a2', a: 'hi' }, 'myid'), - { myid: 'a2', a: 'hi' } - ); + assert.deepStrictEqual(semanticallyCleanObject({ myid: 'a2', a: 'hi' }, 'myid'), { myid: 'a2', a: 'hi' }); }); }); + +describe('isEmptyObjectOrArray', () => { + const shouldBeEmpty: unknown[] = [[], {}]; + const shouldNotBeEmpty: unknown[] = [true, false, 'foo', { foo: 'bar' }, ['bar'], '', undefined, null]; + for (const t of shouldBeEmpty) { + it(`${t} should be empty`, () => assert.ok(isEmptyObjectOrArray(t))); + } + for (const t of shouldNotBeEmpty) { + it(`${t} should not be empty`, () => assert.ok(!isEmptyObjectOrArray(t))); + } +}); diff --git a/tsconfig.json b/tsconfig.json index 8f016886..9a5d2dd9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,17 +1,13 @@ { + "extends": "@salesforce/dev-config/tsconfig", + "include": ["./src/**/*.ts"], "compilerOptions": { "outDir": "lib", - "module": "commonjs", - "target": "es2020", - "lib": ["dom", "es2020"], - "sourceMap": true, - "declaration": true, - "moduleResolution": "node", + "rootDir": "src", + "lib": ["dom", "es2021"], + "skipLibCheck": true, + "strictNullChecks": true, "esModuleInterop": true, - "alwaysStrict": true, - "noUnusedLocals": true, - "skipLibCheck": true - }, - "include": ["./src/**/*"], - "exclude": ["./src/**/*.test.ts", "./src/**/*.e2e-spec.ts"] + "declaration": false, + } } diff --git a/yarn.lock b/yarn.lock index 3db5283e..c933f106 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,206 +2,206 @@ # yarn lockfile v1 -"@ampproject/remapping@^2.1.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" - integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== dependencies: - "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" - integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.22.13": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== dependencies: - "@babel/highlight" "^7.18.6" + "@babel/highlight" "^7.22.13" + chalk "^2.4.2" -"@babel/compat-data@^7.19.3": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.4.tgz#95c86de137bf0317f3a570e1b6e996b427299747" - integrity sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw== +"@babel/compat-data@^7.22.9": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.2.tgz#6a12ced93455827037bfb5ed8492820d60fc32cc" + integrity sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ== "@babel/core@^7.7.5": - version "7.19.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.3.tgz#2519f62a51458f43b682d61583c3810e7dcee64c" - integrity sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.19.3" - "@babel/helper-compilation-targets" "^7.19.3" - "@babel/helper-module-transforms" "^7.19.0" - "@babel/helpers" "^7.19.0" - "@babel/parser" "^7.19.3" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.3" - "@babel/types" "^7.19.3" - convert-source-map "^1.7.0" + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.2.tgz#ed10df0d580fff67c5f3ee70fd22e2e4c90a9f94" + integrity sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-module-transforms" "^7.23.0" + "@babel/helpers" "^7.23.2" + "@babel/parser" "^7.23.0" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.2" + "@babel/types" "^7.23.0" + convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" - json5 "^2.2.1" - semver "^6.3.0" + json5 "^2.2.3" + semver "^6.3.1" -"@babel/generator@^7.19.3", "@babel/generator@^7.19.4": - version "7.19.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.5.tgz#da3f4b301c8086717eee9cab14da91b1fa5dcca7" - integrity sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg== +"@babel/generator@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" + integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== dependencies: - "@babel/types" "^7.19.4" + "@babel/types" "^7.23.0" "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" -"@babel/helper-compilation-targets@^7.19.3": - version "7.19.3" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz#a10a04588125675d7c7ae299af86fa1b2ee038ca" - integrity sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg== - dependencies: - "@babel/compat-data" "^7.19.3" - "@babel/helper-validator-option" "^7.18.6" - browserslist "^4.21.3" - semver "^6.3.0" - -"@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== - -"@babel/helper-function-name@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" - integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== - dependencies: - "@babel/template" "^7.18.10" - "@babel/types" "^7.19.0" - -"@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-module-imports@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" - integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-module-transforms@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30" - integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.18.6" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" - -"@babel/helper-simple-access@^7.18.6": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz#be553f4951ac6352df2567f7daa19a0ee15668e7" - integrity sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg== - dependencies: - "@babel/types" "^7.19.4" - -"@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-string-parser@^7.19.4": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" - integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== - -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== - -"@babel/helper-validator-option@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" - integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== - -"@babel/helpers@^7.19.0": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.4.tgz#42154945f87b8148df7203a25c31ba9a73be46c5" - integrity sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw== - dependencies: - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.4" - "@babel/types" "^7.19.4" - -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" +"@babel/helper-compilation-targets@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" + integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.15" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + +"@babel/helper-module-transforms@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz#3ec246457f6c842c0aee62a01f60739906f7047e" + integrity sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/helper-validator-option@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" + integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== + +"@babel/helpers@^7.23.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.2.tgz#2832549a6e37d484286e15ba36a5330483cac767" + integrity sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ== + dependencies: + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.2" + "@babel/types" "^7.23.0" + +"@babel/highlight@^7.22.13": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" + integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" js-tokens "^4.0.0" -"@babel/parser@^7.18.10", "@babel/parser@^7.19.3", "@babel/parser@^7.19.4": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.4.tgz#03c4339d2b8971eb3beca5252bafd9b9f79db3dc" - integrity sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA== +"@babel/parser@^7.22.15", "@babel/parser@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" + integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== "@babel/runtime-corejs3@^7.12.5": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.19.4.tgz#870dbfd9685b3dad5aeb2d00841bb8b6192e3095" - integrity sha512-HzjQ8+dzdx7dmZy4DQ8KV8aHi/74AjEbBGTFutBmg/pd3dY5/q1sfuOGPTFGEytlQhWoeVXqcK5BwMgIkRkNDQ== + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.23.2.tgz#a5cd9d8b408fb946b2f074b21ea40c04e516795c" + integrity sha512-54cIh74Z1rp4oIjsHjqN+WM4fMyCBYe+LpZ9jWm51CZ1fbH3SkAzQD/3XLoNkjbJ7YEmjobLXyvQrFypRHOrXw== dependencies: - core-js-pure "^3.25.1" - regenerator-runtime "^0.13.4" + core-js-pure "^3.30.2" + regenerator-runtime "^0.14.0" "@babel/runtime@^7.12.5": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.4.tgz#a42f814502ee467d55b38dd1c256f53a7b885c78" - integrity sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/template@^7.18.10": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" - integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.18.10" - "@babel/types" "^7.18.10" - -"@babel/traverse@^7.19.0", "@babel/traverse@^7.19.3", "@babel/traverse@^7.19.4": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.4.tgz#f117820e18b1e59448a6c1fa9d0ff08f7ac459a8" - integrity sha512-w3K1i+V5u2aJUOXBFFC5pveFLmtq1s3qcdDNC2qRI6WPBQIDaKFqXxDEqDO/h1dQ3HjsZoZMyIy6jGLq0xtw+g== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.19.4" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.19.4" - "@babel/types" "^7.19.4" + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" + integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/template@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + +"@babel/traverse@^7.23.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" + integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.0" + "@babel/types" "^7.23.0" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.19.3", "@babel/types@^7.19.4": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.4.tgz#0dd5c91c573a202d600490a35b33246fed8a41c7" - integrity sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw== +"@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" + integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== dependencies: - "@babel/helper-string-parser" "^7.19.4" - "@babel/helper-validator-identifier" "^7.19.1" + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" "@cspotcode/source-map-support@^0.8.0": @@ -211,11 +211,30 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@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== + dependencies: + eslint-visitor-keys "^3.3.0" + "@gar/promisify@^1.0.1", "@gar/promisify@^1.1.3": version "1.1.3" resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + "@isaacs/string-locale-compare@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz#291c227e93fd407a96ecd59879a35809120e432b" @@ -237,37 +256,29 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" - integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== - dependencies: - "@jridgewell/set-array" "^1.0.0" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/gen-mapping@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== dependencies: "@jridgewell/set-array" "^1.0.1" "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== +"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== -"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": +"@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== "@jridgewell/trace-mapping@0.3.9": version "0.3.9" @@ -277,13 +288,13 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.9": - version "0.3.17" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" - integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.20" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" + integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" "@mdapi-issues/listmetadata-standardvalueset@2.0.3": version "2.0.3" @@ -367,6 +378,13 @@ "@gar/promisify" "^1.1.3" semver "^7.3.5" +"@npmcli/fs@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e" + integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w== + dependencies: + semver "^7.3.5" + "@npmcli/git@^2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-2.1.0.tgz#2fbd77e147530247d37f325930d457b3ebe894f6" @@ -381,6 +399,20 @@ semver "^7.3.5" which "^2.0.2" +"@npmcli/git@^4.0.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-4.1.0.tgz#ab0ad3fd82bc4d8c1351b6c62f0fa56e8fe6afa6" + integrity sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ== + dependencies: + "@npmcli/promise-spawn" "^6.0.0" + lru-cache "^7.4.4" + npm-pick-manifest "^8.0.0" + proc-log "^3.0.0" + promise-inflight "^1.0.1" + promise-retry "^2.0.1" + semver "^7.3.5" + which "^3.0.0" + "@npmcli/installed-package-contents@^1.0.6", "@npmcli/installed-package-contents@^1.0.7": version "1.0.7" resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz#ab7408c6147911b970a8abe261ce512232a3f4fa" @@ -389,6 +421,14 @@ npm-bundled "^1.1.1" npm-normalize-package-bin "^1.0.1" +"@npmcli/installed-package-contents@^2.0.1": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz#bfd817eccd9e8df200919e73f57f9e3d9e4f9e33" + integrity sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ== + dependencies: + npm-bundled "^3.0.0" + npm-normalize-package-bin "^3.0.0" + "@npmcli/map-workspaces@^2.0.0": version "2.0.4" resolved "https://registry.yarnpkg.com/@npmcli/map-workspaces/-/map-workspaces-2.0.4.tgz#9e5e8ab655215a262aefabf139782b894e0504fc" @@ -435,6 +475,11 @@ resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-1.0.3.tgz#a912e637418ffc5f2db375e93b85837691a43a33" integrity sha512-fnkhw+fmX65kiLqk6E3BFLXNC26rUhK90zVwe2yncPliVT/Qos3xjhTLE59Df8KnPlcwIERXKVlU1bXoUQ+liA== +"@npmcli/node-gyp@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz#101b2d0490ef1aa20ed460e4c0813f0db560545a" + integrity sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA== + "@npmcli/package-json@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@npmcli/package-json/-/package-json-1.0.1.tgz#1ed42f00febe5293c3502fd0ef785647355f6e89" @@ -449,6 +494,13 @@ dependencies: infer-owner "^1.0.4" +"@npmcli/promise-spawn@^6.0.0", "@npmcli/promise-spawn@^6.0.1": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz#c8bc4fa2bd0f01cb979d8798ba038f314cfa70f2" + integrity sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg== + dependencies: + which "^3.0.0" + "@npmcli/run-script@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-2.0.0.tgz#9949c0cab415b17aaac279646db4f027d6f1e743" @@ -459,33 +511,31 @@ node-gyp "^8.2.0" read-package-json-fast "^2.0.1" -"@oclif/color@^1.0.3": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@oclif/color/-/color-1.0.4.tgz#07e54e3bd76a29e77d6ad71aef33222fe4f728e7" - integrity sha512-HEcVnSzpQkjskqWJyVN3tGgR0H0F8GrBmDjgQ1N0ZwwktYa4y9kfV07P/5vt5BjPXNyslXHc4KAO8Bt7gmErCA== +"@npmcli/run-script@^6.0.0": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-6.0.2.tgz#a25452d45ee7f7fb8c16dfaf9624423c0c0eb885" + integrity sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA== dependencies: - ansi-styles "^4.2.1" - chalk "^4.1.0" - strip-ansi "^6.0.1" - supports-color "^8.1.1" - tslib "^2" + "@npmcli/node-gyp" "^3.0.0" + "@npmcli/promise-spawn" "^6.0.0" + node-gyp "^9.0.0" + read-package-json-fast "^3.0.0" + which "^3.0.0" -"@oclif/core@^1.19.1": - version "1.19.1" - resolved "https://registry.yarnpkg.com/@oclif/core/-/core-1.19.1.tgz#6dba92cfb7f1412e43068db3e9716215786f85a3" - integrity sha512-+LtMYQNzfLoYUcBTsWSFQ/4mqiA70XRU6tP+lDNmQQTrB5FHzDoBbyYvdjvMeS42izg78gjlN++rLUaAUCloNw== +"@oclif/core@^2.15.0": + version "2.15.0" + resolved "https://registry.yarnpkg.com/@oclif/core/-/core-2.15.0.tgz#f27797b30a77d13279fba88c1698fc34a0bd0d2a" + integrity sha512-fNEMG5DzJHhYmI3MgpByTvltBOMyFcnRIUMxbiz2ai8rhaYgaTHMG3Q38HcosfIvtw9nCjxpcQtC8MN8QtVCcA== dependencies: - "@oclif/linewrap" "^1.0.0" - "@oclif/screen" "^3.0.2" + "@types/cli-progress" "^3.11.0" ansi-escapes "^4.3.2" ansi-styles "^4.3.0" cardinal "^2.1.1" chalk "^4.1.2" clean-stack "^3.0.1" - cli-progress "^3.10.0" + cli-progress "^3.12.0" debug "^4.3.4" - ejs "^3.1.6" - fs-extra "^9.1.0" + ejs "^3.1.8" get-package-type "^0.1.0" globby "^11.1.0" hyperlinker "^1.0.0" @@ -495,30 +545,30 @@ natural-orderby "^2.0.3" object-treeify "^1.1.33" password-prompt "^1.1.2" - semver "^7.3.7" + slice-ansi "^4.0.0" string-width "^4.2.3" strip-ansi "^6.0.1" supports-color "^8.1.1" supports-hyperlinks "^2.2.0" - tslib "^2.3.1" + ts-node "^10.9.1" + tslib "^2.5.0" widest-line "^3.1.0" + wordwrap "^1.0.0" wrap-ansi "^7.0.0" -"@oclif/core@^2.0.3", "@oclif/core@^2.0.7": - version "2.0.7" - resolved "https://registry.yarnpkg.com/@oclif/core/-/core-2.0.7.tgz#a17a85dfa105dda120fbc5647432010feaa97a9e" - integrity sha512-pj7hIH8SBeH3qha47fmyqdaBdNVEqesRgnKFh8Ytdb4S41/4BYOiQuyQGuvnKgvicH6DMxp4FbM9EQEW46V9xw== +"@oclif/core@^3.0.0", "@oclif/core@^3.0.4": + version "3.8.0" + resolved "https://registry.yarnpkg.com/@oclif/core/-/core-3.8.0.tgz#45f5f630b3b593c3486e7835953ad6fb2af01bcb" + integrity sha512-fKqg9QzjIflDcYljZkZEeY6zoRyk4AZ5e2V4LUIsSOR7+B78qpqNqDPJFTI8TvrEU3+Q+ssELntOL2VA3SMsqQ== dependencies: - "@types/cli-progress" "^3.11.0" ansi-escapes "^4.3.2" ansi-styles "^4.3.0" cardinal "^2.1.1" chalk "^4.1.2" clean-stack "^3.0.1" - cli-progress "^3.10.0" + cli-progress "^3.12.0" debug "^4.3.4" - ejs "^3.1.6" - fs-extra "^9.1.0" + ejs "^3.1.9" get-package-type "^0.1.0" globby "^11.1.0" hyperlinker "^1.0.0" @@ -528,22 +578,20 @@ natural-orderby "^2.0.3" object-treeify "^1.1.33" password-prompt "^1.1.2" - semver "^7.3.7" + slice-ansi "^4.0.0" string-width "^4.2.3" strip-ansi "^6.0.1" supports-color "^8.1.1" supports-hyperlinks "^2.2.0" - tslib "^2.4.1" widest-line "^3.1.0" wordwrap "^1.0.0" wrap-ansi "^7.0.0" -"@oclif/core@^2.8.4": - version "2.8.5" - resolved "https://registry.yarnpkg.com/@oclif/core/-/core-2.8.5.tgz#7964057bbee5e91dae8b35e030e767f38e50a19e" - integrity sha512-316DLfrHQDYmWDriI4Woxk9y1wVUrPN1sZdbQLHdOdlTA9v/twe7TdHpWOriEypfl6C85NWEJKc1870yuLtjrQ== +"@oclif/core@^3.3.1": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@oclif/core/-/core-3.9.0.tgz#51c53ea4eafd3d643a55a37477f3e7c9d2cc2942" + integrity sha512-9UT0ySJgaUvERUQwDFh0u9Q5cfoBttfyaJ1sorSms6H5AELIjQ2Yvu2QfzPmnAit2rod+hdcDZ+O1Hia5Zcz+Q== dependencies: - "@types/cli-progress" "^3.11.0" ansi-escapes "^4.3.2" ansi-styles "^4.3.0" cardinal "^2.1.1" @@ -551,8 +599,7 @@ clean-stack "^3.0.1" cli-progress "^3.12.0" debug "^4.3.4" - ejs "^3.1.8" - fs-extra "^9.1.0" + ejs "^3.1.9" get-package-type "^0.1.0" globby "^11.1.0" hyperlinker "^1.0.0" @@ -562,64 +609,41 @@ natural-orderby "^2.0.3" object-treeify "^1.1.33" password-prompt "^1.1.2" - semver "^7.3.7" + slice-ansi "^4.0.0" string-width "^4.2.3" strip-ansi "^6.0.1" supports-color "^8.1.1" supports-hyperlinks "^2.2.0" - ts-node "^10.9.1" - tslib "^2.5.0" widest-line "^3.1.0" wordwrap "^1.0.0" wrap-ansi "^7.0.0" -"@oclif/linewrap@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@oclif/linewrap/-/linewrap-1.0.0.tgz#aedcb64b479d4db7be24196384897b5000901d91" - integrity sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw== - -"@oclif/plugin-help@^5.1.19": - version "5.2.2" - resolved "https://registry.yarnpkg.com/@oclif/plugin-help/-/plugin-help-5.2.2.tgz#f00e60b1349c4ec62c1d6a98d3a424899373c5ad" - integrity sha512-ok8gS2phqA4MiGkjCrZPFvhNIHIp35WsvNNVUn4GL8WZYQ5mk1cZuu+IIqTZxBFZ4QDUZLVkumrhsqx3oNId9A== +"@oclif/plugin-help@^5.2.14": + version "5.2.20" + resolved "https://registry.yarnpkg.com/@oclif/plugin-help/-/plugin-help-5.2.20.tgz#4035a0ac231f95fb8e334da342175e3ca00f6abc" + integrity sha512-u+GXX/KAGL9S10LxAwNUaWdzbEBARJ92ogmM7g3gDVud2HioCmvWQCDohNRVZ9GYV9oKwZ/M8xwd6a1d95rEKQ== dependencies: - "@oclif/core" "^2.0.7" + "@oclif/core" "^2.15.0" -"@oclif/plugin-not-found@^2.3.7": - version "2.3.17" - resolved "https://registry.yarnpkg.com/@oclif/plugin-not-found/-/plugin-not-found-2.3.17.tgz#c27fd323591d559110ef022a34074bf9732eb41c" - integrity sha512-KTh4vQ3GIiHNeuqsMV58cdvRBO1IREoEGuAE+e73OcP5VEjjsbJNQS+IXg0UHivMQhVBl7FeadgvAqGzUHPv5w== +"@oclif/plugin-not-found@^2.3.32": + version "2.4.3" + resolved "https://registry.yarnpkg.com/@oclif/plugin-not-found/-/plugin-not-found-2.4.3.tgz#3d24095adb0f3876cb4bcfdfdcb775086cf6d4b5" + integrity sha512-nIyaR4y692frwh7wIHZ3fb+2L6XEecQwRDIb4zbEam0TvaVmBQWZoColQyWA84ljFBPZ8XWiQyTz+ixSwdRkqg== dependencies: - "@oclif/color" "^1.0.3" - "@oclif/core" "^2.0.3" + "@oclif/core" "^2.15.0" + chalk "^4" fast-levenshtein "^3.0.0" - lodash "^4.17.21" -"@oclif/plugin-warn-if-update-available@^2.0.14": - version "2.0.24" - resolved "https://registry.yarnpkg.com/@oclif/plugin-warn-if-update-available/-/plugin-warn-if-update-available-2.0.24.tgz#dffc4b19cf64baf0bf3a4d9925b17bfb111cc1c8" - integrity sha512-Rq8/EZ8wQawvPWS6W59Zhf/zSz/umLc3q75I1ybi7pul6YMNwf/E1eDVHytSUEQ6yQV+p3cCs034IItz4CVdjw== +"@oclif/plugin-warn-if-update-available@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@oclif/plugin-warn-if-update-available/-/plugin-warn-if-update-available-3.0.2.tgz#76d02069c0d5545b5000660460edb6085272cbcd" + integrity sha512-dUXfRNFtnezS4uqQ+Ap4qb6UP0DWExTvoqghNvvGTIN4PEgfYHogvBORn+rFnDXXE8kgZFuqP4ZQJRP9NyLhOA== dependencies: - "@oclif/core" "^2.0.7" - chalk "^4.1.0" + "@oclif/core" "^3.3.1" + chalk "^5.3.0" debug "^4.1.0" - fs-extra "^9.0.1" http-call "^5.2.2" - lodash "^4.17.21" - semver "^7.3.8" - -"@oclif/screen@^3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@oclif/screen/-/screen-3.0.2.tgz#969054308fe98d130c02844a45cc792199b75670" - integrity sha512-S/SF/XYJeevwIgHFmVDAFRUvM3m+OjhvCAYMk78ZJQCYCQ5wS7j+LTt1ZEv2jpEEGg2tx/F6TYYWxddNAYHrFQ== - -"@oclif/test@^2.2.4": - version "2.2.6" - resolved "https://registry.yarnpkg.com/@oclif/test/-/test-2.2.6.tgz#2c98bb1ecab3ddf6b01b51f8a3489c9105353d67" - integrity sha512-rf67rTBkEeulpomdeBYm0D+Q0e1uMqTPUNPhY2/G6guAJhmu3M+78HvSKpLdG7WqpbfQJ68D5Dh5HnauO+MY2g== - dependencies: - "@oclif/core" "^1.19.1" - fancy-test "^2.0.5" + lodash.template "^4.5.0" "@octokit/auth-token@^2.4.4": version "2.5.0" @@ -722,73 +746,119 @@ dependencies: "@octokit/openapi-types" "^12.11.0" -"@salesforce/bunyan@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@salesforce/bunyan/-/bunyan-2.0.0.tgz#8dbe377f2cf7d35348a23260416fee15adba5f97" - integrity sha512-5hq+HWQSeymuygl3i9ehlQo3XWrlBE+A+QzmpDaoK37op4u9M+SBUbXfOW0IABOQCg+JmfQPocSMV74hRoqU9w== - dependencies: - dayjs "^1.8.16" - dayjs-plugin-utc "^0.1.2" - optionalDependencies: - dtrace-provider "~0.6" - mv "~2" - safe-json-stringify "~1" - -"@salesforce/command@5.2.16": - version "5.2.16" - resolved "https://registry.yarnpkg.com/@salesforce/command/-/command-5.2.16.tgz#e9fd778403dfe29ff992d225f0105389e20152cd" - integrity sha512-rYC/URrIae8LjeuMlg+/PrxyWBEYgOTy2aHfTryiL4dEr9F28b2/xgSLh+5RGEblhPo52GXR33bFQU81pkq/BQ== - dependencies: - "@oclif/core" "^1.19.1" - "@oclif/test" "^2.2.4" - "@salesforce/core" "^3.31.16" - "@salesforce/kit" "^1.6.1" - "@salesforce/ts-types" "^1.5.21" - chalk "^2.4.2" +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== -"@salesforce/core@^3.31.16": - version "3.31.16" - resolved "https://registry.yarnpkg.com/@salesforce/core/-/core-3.31.16.tgz#af52b01eda974b8f000c81d7111e299db64ee38c" - integrity sha512-at5J9chWR0RQxymQTNiyoNxsVJ56Opq79F7FIKt7Y0T/o+OkdOCnveny2tcVEFeJz4OjRV9+57R9eCsn0gg3gQ== - dependencies: - "@salesforce/bunyan" "^2.0.0" - "@salesforce/kit" "^1.7.0" - "@salesforce/schemas" "^1.1.0" - "@salesforce/ts-types" "^1.5.21" - "@types/graceful-fs" "^4.1.5" - "@types/semver" "^7.3.9" - ajv "^8.11.0" - archiver "^5.3.0" +"@puppeteer/browsers@1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-1.8.0.tgz#fb6ee61de15e7f0e67737aea9f9bab1512dbd7d8" + integrity sha512-TkRHIV6k2D8OlUe8RtG+5jgOF/H98Myx0M6AOafC8DdNVOFiBSFa5cpRDtpm8LXOa9sVwe0+e6Q3FC56X/DZfg== + dependencies: + debug "4.3.4" + extract-zip "2.0.1" + progress "2.0.3" + proxy-agent "6.3.1" + tar-fs "3.0.4" + unbzip2-stream "1.4.3" + yargs "17.7.2" + +"@salesforce/core@^5.3.1": + version "5.3.12" + resolved "https://registry.yarnpkg.com/@salesforce/core/-/core-5.3.12.tgz#0ff38307b39d9abb8aedaa575ecd6d037bc8eee1" + integrity sha512-A2oOBiGvZRxcdUcz8oA1B0l2nQZApmBQnbUUrsH18isgb9seQLTGuV6YelY4rLZbGsfcp3rzbERMGrHas+OuXQ== + dependencies: + "@salesforce/kit" "^3.0.14" + "@salesforce/schemas" "^1.6.0" + "@salesforce/ts-types" "^2.0.8" + "@types/semver" "^7.5.3" + ajv "^8.12.0" change-case "^4.1.2" - debug "^3.2.7" faye "^1.4.0" form-data "^4.0.0" - graceful-fs "^4.2.9" js2xmlparser "^4.0.1" - jsforce "^2.0.0-beta.19" - jsonwebtoken "8.5.1" - ts-retry-promise "^0.7.0" + jsforce "^2.0.0-beta.28" + jsonwebtoken "9.0.2" + jszip "3.10.1" + pino "^8.16.0" + pino-abstract-transport "^1.0.0" + pino-pretty "^10.2.3" + proper-lockfile "^4.1.2" + semver "^7.5.4" + ts-retry-promise "^0.7.1" + +"@salesforce/dev-config@4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@salesforce/dev-config/-/dev-config-4.1.0.tgz#e529576466d074e7a5f1441236510fef123da01e" + integrity sha512-2iDDepiIwjXHS5IVY7pwv8jMo4xWosJ7p/UTj+lllpB/gnJiYLhjJPE4Z3FCGFKyvfg5jGaimCd8Ca6bLGsCQA== -"@salesforce/kit@^1.6.1", "@salesforce/kit@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@salesforce/kit/-/kit-1.7.0.tgz#f14ef71662742edf0fb74ffb23c530fad5ccb4c9" - integrity sha512-AxJi7W9skYEVQrZMGyWtG3xOOLzdRu7638Hlea3gtPdMpMRc0aB1Nvpg7Ru+VLtULNhXnnQ3nXesDl0d2TA04w== +"@salesforce/kit@^3.0.13", "@salesforce/kit@^3.0.14": + version "3.0.15" + resolved "https://registry.yarnpkg.com/@salesforce/kit/-/kit-3.0.15.tgz#713df3f5767f874c70a2e731c7cb5ba677989559" + integrity sha512-XkA8jsuLvVnyP460dAbU3pBFP2IkmmmsVxMQVifcKKbNWaIBbZBzAfj+vdaQfnvZyflLhsrFT3q2xkb0vHouPg== dependencies: - "@salesforce/ts-types" "^1.5.21" - shx "^0.3.3" - tslib "^2.2.0" + "@salesforce/ts-types" "^2.0.9" + tslib "^2.6.2" -"@salesforce/schemas@^1.1.0": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@salesforce/schemas/-/schemas-1.1.3.tgz#fce83f55c7557d47b9c814d5d02978ad734300b3" - integrity sha512-XWohlOT2oQDqAJH00OXS3f2MGjkwZ6pr4emnnkHSQbg7UdGW0rvGpEnRKqBbDUfZ4K5YKSo9Gj216ZtaP3JLXg== +"@salesforce/prettier-config@0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@salesforce/prettier-config/-/prettier-config-0.0.3.tgz#ba648d4886bb38adabe073dbea0b3a91b3753bb0" + integrity sha512-hYOhoPTCSYMDYn+U1rlEk16PoBeAJPkrdg4/UtAzupM1mRRJOwEPMG1d7U8DxJFKuXW3DMEYWr2MwAIBDaHmFg== + +"@salesforce/schemas@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@salesforce/schemas/-/schemas-1.6.0.tgz#14505ebad2fb2d4f7b14837545d662766d293561" + integrity sha512-SwhDTLucj/GRbPpxlEoDZeqlX22o+G6fiebTXTu1cZKmd1oE0W2L7SlTTgJnWck8bhTeBIgQi9cpD8c2t5ISKA== + +"@salesforce/sf-plugins-core@4.1.1": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@salesforce/sf-plugins-core/-/sf-plugins-core-4.1.1.tgz#685843bf9fbb1c2e448b922a1399dde1808ed549" + integrity sha512-oyRjy/WpU7F8sVWwsUuxZ+WnfnJ4s/60dsIOXyKYezHfywMp8APPmZwETpyFTkKl23rZQT1vciFwTDKXYEP82A== + dependencies: + "@oclif/core" "^3.0.0" + "@salesforce/core" "^5.3.1" + "@salesforce/kit" "^3.0.13" + "@salesforce/ts-types" "^2.0.7" + "@types/inquirer" "^8.2.3" + chalk "^4" + inquirer "^8.2.5" + +"@salesforce/ts-types@^2.0.7", "@salesforce/ts-types@^2.0.8", "@salesforce/ts-types@^2.0.9": + version "2.0.9" + resolved "https://registry.yarnpkg.com/@salesforce/ts-types/-/ts-types-2.0.9.tgz#66bff7b41720065d6b01631b6f6a3ccca02857c5" + integrity sha512-boUD9jw5vQpTCPCCmK/NFTWjSuuW+lsaxOynkyNXLW+zxOc4GDjhtKc4j0vWZJQvolpafbyS8ZLFHZJvs12gYA== + dependencies: + tslib "^2.6.2" + +"@sigstore/bundle@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@sigstore/bundle/-/bundle-1.1.0.tgz#17f8d813b09348b16eeed66a8cf1c3d6bd3d04f1" + integrity sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog== + dependencies: + "@sigstore/protobuf-specs" "^0.2.0" + +"@sigstore/protobuf-specs@^0.2.0": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz#be9ef4f3c38052c43bd399d3f792c97ff9e2277b" + integrity sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A== + +"@sigstore/sign@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@sigstore/sign/-/sign-1.0.0.tgz#6b08ebc2f6c92aa5acb07a49784cb6738796f7b4" + integrity sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA== + dependencies: + "@sigstore/bundle" "^1.1.0" + "@sigstore/protobuf-specs" "^0.2.0" + make-fetch-happen "^11.0.1" -"@salesforce/ts-types@^1.5.21": - version "1.5.21" - resolved "https://registry.yarnpkg.com/@salesforce/ts-types/-/ts-types-1.5.21.tgz#e62784872f0e74bf4ae13381dc58aa4644ee2df3" - integrity sha512-qG8r8WOzqpFOHaH3EGU3IwGrY/pSv9NQp4B0wGxOuPDBbraXVvd3KhWVStxaLGKBkJClJ7/+t+iCSP82sEiGcg== +"@sigstore/tuf@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-1.0.3.tgz#2a65986772ede996485728f027b0514c0b70b160" + integrity sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg== dependencies: - tslib "^2.2.0" + "@sigstore/protobuf-specs" "^0.2.0" + tuf-js "^1.1.7" "@sindresorhus/is@^4.0.0": version "4.6.0" @@ -812,6 +882,11 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== +"@tootallnate/quickjs-emscripten@^0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz#db4ecfd499a9765ab24002c3b696d02e6d32a12c" + integrity sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA== + "@tsconfig/node10@^1.0.7": version "1.0.9" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" @@ -828,9 +903,22 @@ integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== "@tsconfig/node16@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" - integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + +"@tufjs/canonical-json@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz#eade9fd1f537993bc1f0949f3aea276ecc4fab31" + integrity sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ== + +"@tufjs/models@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tufjs/models/-/models-1.0.4.tgz#5a689630f6b9dbda338d4b208019336562f176ef" + integrity sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A== + dependencies: + "@tufjs/canonical-json" "1.0.0" + minimatch "^9.0.0" "@types/cacheable-request@^6.0.1": version "6.0.3" @@ -842,15 +930,10 @@ "@types/node" "*" "@types/responselike" "^1.0.0" -"@types/chai@*": - version "4.3.3" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.3.tgz#3c90752792660c4b562ad73b3fbd68bf3bc7ae07" - integrity sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g== - "@types/cli-progress@^3.11.0": - version "3.11.0" - resolved "https://registry.yarnpkg.com/@types/cli-progress/-/cli-progress-3.11.0.tgz#ec79df99b26757c3d1c7170af8422e0fc95eef7e" - integrity sha512-XhXhBv1R/q2ahF3BM7qT5HLzJNlIL0wbcGyZVjqOTqAybAnsLisd7gy1UCyIqpL+5Iv6XhlSyzjLCnI2sIdbCg== + version "3.11.4" + resolved "https://registry.yarnpkg.com/@types/cli-progress/-/cli-progress-3.11.4.tgz#58d9e60bd5fd85a57984890ef9c9d831a0dda896" + integrity sha512-yufTxeeNCZuEIxx2uebK8lpSAsJM4lvzakm/VxzYhDtqhXCzwH9jpn7nPCxzrROuEbLATqhFq4MIPoG0tlrsvw== dependencies: "@types/node" "*" @@ -859,17 +942,23 @@ resolved "https://registry.yarnpkg.com/@types/expect/-/expect-1.20.4.tgz#8288e51737bf7e3ab5d7c77bfa695883745264e5" integrity sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg== -"@types/graceful-fs@^4.1.5": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" - integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== +"@types/http-cache-semantics@*": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz#a3ff232bf7d5c55f38e4e45693eda2ebb545794d" + integrity sha512-V46MYLFp08Wf2mmaBhvgjStM3tPa+2GAdy/iqoX+noX1//zje2x4XmrIU0cAwyClATsTmahbtoQ2EwP7I5WSiA== + +"@types/inquirer@^8.2.3": + version "8.2.10" + resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-8.2.10.tgz#9444dce2d764c35bc5bb4d742598aaa4acb6561b" + integrity sha512-IdD5NmHyVjWM8SHWo/kPBgtzXatwPkfwzyP3fN1jF2g9BWt5WO+8hL2F4o2GKIYsU40PpqeevuUWvkS/roXJkA== dependencies: - "@types/node" "*" + "@types/through" "*" + rxjs "^7.2.0" -"@types/http-cache-semantics@*": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" - integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== +"@types/json-schema@^7.0.12": + version "7.0.14" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.14.tgz#74a97a5573980802f32c8e47b663530ab3b6b7d1" + integrity sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw== "@types/keyv@^3.1.4": version "3.1.4" @@ -878,55 +967,49 @@ dependencies: "@types/node" "*" -"@types/lodash@*": - version "4.14.186" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.186.tgz#862e5514dd7bd66ada6c70ee5fce844b06c8ee97" - integrity sha512-eHcVlLXP0c2FlMPm56ITode2AgLMSa6aJ05JTTbYbI+7EMkCEE5qk2E41d5g2lCVTqRe0GnnRFurmlCsDODrPw== - "@types/minimatch@^3.0.3": version "3.0.5" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== -"@types/mocha@10.0.1": - version "10.0.1" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.1.tgz#2f4f65bb08bc368ac39c96da7b2f09140b26851b" - integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== +"@types/mocha@10.0.4": + version "10.0.4" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.4.tgz#b5331955ebca216604691fd4fcd2dbdc2bd559a4" + integrity sha512-xKU7bUjiFTIttpWaIZ9qvgg+22O1nmbA+HRxdlR+u6TWsGfmFdXrheJoK4fFxrHNVIOBDvDNKZG+LYBpMHpX3w== "@types/node@*": - version "18.11.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.0.tgz#f38c7139247a1d619f6cc6f27b072606af7c289d" - integrity sha512-IOXCvVRToe7e0ny7HpT/X9Rb2RYtElG1a+VshjwT00HxrM2dWBApHQoqsI6WiY7Q03vdf2bCrIGzVrkF/5t10w== + version "20.8.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.9.tgz#646390b4fab269abce59c308fc286dcd818a2b08" + integrity sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg== + dependencies: + undici-types "~5.26.4" -"@types/node@18.16.8": - version "18.16.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.8.tgz#fcd9bd0a793aba2701caff4aeae7c988d4da6ce5" - integrity sha512-p0iAXcfWCOTCBbsExHIDFCfwsqFwBTgETJveKMT+Ci3LY9YqQCI91F5S+TB20+aRCXpcWfvx5Qr5EccnwCm2NA== +"@types/node@20.9.0": + version "20.9.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.9.0.tgz#bfcdc230583aeb891cf51e73cfdaacdd8deae298" + integrity sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw== + dependencies: + undici-types "~5.26.4" "@types/node@^12.19.9": version "12.20.55" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== -"@types/node@^15.6.1": +"@types/node@^15.6.2": version "15.14.9" resolved "https://registry.yarnpkg.com/@types/node/-/node-15.14.9.tgz#bc43c990c3c9be7281868bbc7b8fdd6e2b57adfa" integrity sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A== "@types/normalize-package-data@^2.4.0": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" - integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== - -"@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + version "2.4.3" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.3.tgz#291c243e4b94dbfbc0c0ee26b7666f1d5c030e2c" + integrity sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg== "@types/responselike@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" - integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.2.tgz#8de1b0477fd7c12df77e50832fa51701a8414bd6" + integrity sha512-/4YQT5Kp6HxUDb4yhRkm0bJ7TbjvTddqX7PZ5hz6qV3pxSo72f/6YPRo+Mu2DU307tm9IioO69l7uAwn5XNcFA== dependencies: "@types/node" "*" @@ -935,39 +1018,81 @@ resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== -"@types/semver@^7.3.9": - version "7.3.12" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.12.tgz#920447fdd78d76b19de0438b7f60df3c4a80bf1c" - integrity sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A== +"@types/semver@^7.5.0", "@types/semver@^7.5.3": + version "7.5.4" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.4.tgz#0a41252ad431c473158b22f9bfb9a63df7541cff" + integrity sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ== -"@types/sinon@*": - version "10.0.13" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-10.0.13.tgz#60a7a87a70d9372d0b7b38cc03e825f46981fb83" - integrity sha512-UVjDqJblVNQYvVNUsj0PuYYw0ELRmgt1Nt5Vk0pT5f16ROGfcKJY8o1HVuMOJOpD727RrGB9EGvoaTQE5tgxZQ== +"@types/through@*": + version "0.0.33" + resolved "https://registry.yarnpkg.com/@types/through/-/through-0.0.33.tgz#14ebf599320e1c7851e7d598149af183c6b9ea56" + integrity sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ== dependencies: - "@types/sinonjs__fake-timers" "*" - -"@types/sinonjs__fake-timers@*": - version "8.1.2" - resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz#bf2e02a3dbd4aecaf95942ecd99b7402e03fad5e" - integrity sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA== + "@types/node" "*" "@types/vinyl@^2.0.4": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@types/vinyl/-/vinyl-2.0.6.tgz#b2d134603557a7c3d2b5d3dc23863ea2b5eb29b0" - integrity sha512-ayJ0iOCDNHnKpKTgBG6Q6JOnHTj9zFta+3j2b8Ejza0e4cvRyMn0ZoLEmbPrTHe5YYRlDYPvPWVdV4cTaRyH7g== + version "2.0.9" + resolved "https://registry.yarnpkg.com/@types/vinyl/-/vinyl-2.0.9.tgz#5686de441312881498665744c1dcdffe80721ea5" + integrity sha512-KCr4aTEUkzSF89qw09e2oxsC/RXXT3K5ZPv4gvj3XTiWVrxNoi7WrqNTahNE/Hul5C9z3B8w+yWNTQgua12oag== dependencies: "@types/expect" "^1.20.4" "@types/node" "*" "@types/yauzl@^2.9.1": - version "2.10.0" - resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.0.tgz#b3248295276cf8c6f153ebe6a9aba0c988cb2599" - integrity sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw== + version "2.10.2" + resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.2.tgz#dab926ef9b41a898bc943f11bca6b0bad6d4b729" + integrity sha512-Km7XAtUIduROw7QPgvcft0lIupeG8a8rdKL8RiSyKvlE7dYY31fEn41HVuQsRFDuROA8tA4K2UVL+WdfFmErBA== dependencies: "@types/node" "*" -abbrev@1: +"@typescript-eslint/scope-manager@6.9.0": + version "6.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz#2626e9a7fe0e004c3e25f3b986c75f584431134e" + integrity sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw== + dependencies: + "@typescript-eslint/types" "6.9.0" + "@typescript-eslint/visitor-keys" "6.9.0" + +"@typescript-eslint/types@6.9.0": + version "6.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.9.0.tgz#86a0cbe7ac46c0761429f928467ff3d92f841098" + integrity sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw== + +"@typescript-eslint/typescript-estree@6.9.0": + version "6.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz#d0601b245be873d8fe49f3737f93f8662c8693d4" + integrity sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ== + dependencies: + "@typescript-eslint/types" "6.9.0" + "@typescript-eslint/visitor-keys" "6.9.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/utils@^6.7.5": + version "6.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.9.0.tgz#5bdac8604fca4823f090e4268e681c84d3597c9f" + integrity sha512-5Wf+Jsqya7WcCO8me504FBigeQKVLAMPmUzYgDbWchINNh1KJbxCgVya3EQ2MjvJMVeXl3pofRmprqX6mfQkjQ== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.9.0" + "@typescript-eslint/types" "6.9.0" + "@typescript-eslint/typescript-estree" "6.9.0" + semver "^7.5.4" + +"@typescript-eslint/visitor-keys@6.9.0": + version "6.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz#cc69421c10c4ac997ed34f453027245988164e80" + integrity sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg== + dependencies: + "@typescript-eslint/types" "6.9.0" + eslint-visitor-keys "^3.4.1" + +abbrev@1, abbrev@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== @@ -985,9 +1110,9 @@ acorn-walk@^8.1.1: integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== acorn@^8.4.1: - version "8.8.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" - integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6, agent-base@^6.0.2: version "6.0.2" @@ -996,13 +1121,18 @@ agent-base@6, agent-base@^6.0.2: dependencies: debug "4" +agent-base@^7.0.2, agent-base@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434" + integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg== + dependencies: + debug "^4.3.4" + agentkeepalive@^4.1.3, agentkeepalive@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.2.1.tgz#a7975cbb9f83b367f06c90cc51ff28fe7d499717" - integrity sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA== + version "4.5.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" + integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== dependencies: - debug "^4.1.0" - depd "^1.1.2" humanize-ms "^1.2.1" aggregate-error@^3.0.0: @@ -1013,10 +1143,10 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ajv@^8.11.0: - version "8.11.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" - integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== +ajv@^8.12.0: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -1028,11 +1158,6 @@ ansi-colors@4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== -ansi-escapes@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== - ansi-escapes@^4.2.1, ansi-escapes@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" @@ -1040,49 +1165,44 @@ ansi-escapes@^4.2.1, ansi-escapes@^4.3.2: dependencies: type-fest "^0.21.3" -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== - -ansi-regex@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" - integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== - ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA== +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== -ansi-styles@^3.0.0, ansi-styles@^3.2.1: +ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" -ansi-styles@^4.0.0, ansi-styles@^4.1.0, ansi-styles@^4.2.1, ansi-styles@^4.3.0: +ansi-styles@^4.0.0, ansi-styles@^4.1.0, ansi-styles@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + ansicolors@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" integrity sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg== anymatch@~3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" @@ -1099,35 +1219,6 @@ append-transform@^2.0.0: resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== -archiver-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2" - integrity sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw== - dependencies: - glob "^7.1.4" - graceful-fs "^4.2.0" - lazystream "^1.0.0" - lodash.defaults "^4.2.0" - lodash.difference "^4.5.0" - lodash.flatten "^4.4.0" - lodash.isplainobject "^4.0.6" - lodash.union "^4.6.0" - normalize-path "^3.0.0" - readable-stream "^2.0.0" - -archiver@^5.3.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/archiver/-/archiver-5.3.1.tgz#21e92811d6f09ecfce649fbefefe8c79e57cbbb6" - integrity sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w== - dependencies: - archiver-utils "^2.1.0" - async "^3.2.3" - buffer-crc32 "^0.2.1" - readable-stream "^3.6.0" - readdir-glob "^1.0.0" - tar-stream "^2.2.0" - zip-stream "^4.1.0" - archy@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" @@ -1186,6 +1277,25 @@ asap@*, asap@^2.0.0: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== +ast-types@^0.13.4: + version "0.13.4" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.4.tgz#ee0d77b343263965ecc3fb62da16e7222b2b6782" + integrity sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w== + dependencies: + tslib "^2.0.1" + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +async-retry@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.3.tgz#0e7f36c04d8478e7a58bdbed80cedf977785f280" + integrity sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw== + dependencies: + retry "0.13.1" + async@^3.2.3: version "3.2.4" resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" @@ -1196,10 +1306,10 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -at-least-node@^1.0.0: +atomic-sleep@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" + integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== available-typed-arrays@^1.0.5: version "1.0.5" @@ -1207,9 +1317,9 @@ available-typed-arrays@^1.0.5: integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== aws-sdk@^2.1231.0: - version "2.1233.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1233.0.tgz#3386515966ca8a5baac048d986ad0977119c0765" - integrity sha512-e1GbVltsoQpWvx0gxQlEtKOdOrNWyjhD8bjFIMx/3Nwwzw4ac2KOy7CyC5I+lBj8el4AB0399umLHJZmL5WcVg== + version "2.1481.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1481.0.tgz#2ecfbb9b404feaf345c0fd65f3f2541909b7ca92" + integrity sha512-frg2IDi5Ozw6Vym0Y7WNyGUpgGalhmz41oAJVVvNl9AfKFLMw8AU8RfUvKt16snQ1yq847wuF14O73eFIKuIpw== dependencies: buffer "4.9.2" events "1.1.1" @@ -1220,7 +1330,12 @@ aws-sdk@^2.1231.0: url "0.10.3" util "^0.12.4" uuid "8.0.0" - xml2js "0.4.19" + xml2js "0.5.0" + +b4a@^1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.4.tgz#ef1c1422cae5ce6535ec191baeed7567443f36c9" + integrity sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw== balanced-match@^1.0.0: version "1.0.2" @@ -1237,6 +1352,11 @@ base64url@^3.0.1: resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d" integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A== +basic-ftp@^5.0.2: + version "5.0.3" + resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.0.3.tgz#b14c0fe8111ce001ec913686434fe0c2fb461228" + integrity sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g== + before-after-hook@^2.2.0: version "2.2.3" resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" @@ -1264,7 +1384,7 @@ binaryextensions@^4.15.0, binaryextensions@^4.16.0: resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-4.18.0.tgz#22aeada2d14de062c60e8ca59a504a5636a76ceb" integrity sha512-PQu3Kyv9dM4FnwB7XGj1+HucW+ShvJzJqjuw1JkKVs1mWdwOKVcRjOi+pV9X52A0tNvrPCsPkbFFQb+wE1EAXw== -bl@^4.0.3, bl@^4.1.0: +bl@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== @@ -1300,17 +1420,17 @@ browser-stdout@1.3.1: resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== -browserslist@^4.21.3: - version "4.21.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" - integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== +browserslist@^4.21.9: + version "4.22.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619" + integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== dependencies: - caniuse-lite "^1.0.30001400" - electron-to-chromium "^1.4.251" - node-releases "^2.0.6" - update-browserslist-db "^1.0.9" + caniuse-lite "^1.0.30001541" + electron-to-chromium "^1.4.535" + node-releases "^2.0.13" + update-browserslist-db "^1.0.13" -buffer-crc32@^0.2.1, buffer-crc32@^0.2.13, buffer-crc32@~0.2.3: +buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== @@ -1337,11 +1457,26 @@ buffer@^5.2.1, buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + builtins@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== +builtins@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.0.1.tgz#87f6db9ab0458be728564fa81d876d8d74552fa9" + integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== + dependencies: + semver "^7.0.0" + cacache@^15.0.3, cacache@^15.0.5, cacache@^15.2.0: version "15.3.0" resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" @@ -1390,15 +1525,33 @@ cacache@^16.1.0: tar "^6.1.11" unique-filename "^2.0.0" +cacache@^17.0.0: + version "17.1.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.1.4.tgz#b3ff381580b47e85c6e64f801101508e26604b35" + integrity sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A== + dependencies: + "@npmcli/fs" "^3.1.0" + fs-minipass "^3.0.0" + glob "^10.2.2" + lru-cache "^7.7.1" + minipass "^7.0.3" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + p-map "^4.0.0" + ssri "^10.0.0" + tar "^6.1.11" + unique-filename "^3.0.0" + cacheable-lookup@^5.0.3: version "5.0.4" resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== cacheable-request@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" - integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== + version "7.0.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817" + integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg== dependencies: clone-response "^1.0.2" get-stream "^5.1.0" @@ -1418,13 +1571,14 @@ caching-transform@^4.0.0: package-hash "^4.0.0" write-file-atomic "^3.0.0" -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== +call-bind@^1.0.2, call-bind@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" callsites@^3.0.0: version "3.1.0" @@ -1449,10 +1603,10 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001400: - version "1.0.30001420" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001420.tgz#f62f35f051e0b6d25532cf376776d41e45b47ef6" - integrity sha512-OnyeJ9ascFA9roEj72ok2Ikp7PHJTKubtEJIQ/VK3fdsS50q4KWy+Z5X0A1/GswEItKX0ctAp8n4SYDE7wTu6A== +caniuse-lite@^1.0.30001541: + version "1.0.30001554" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001554.tgz#ba80d88dff9acbc0cd4b7535fc30e0191c5e2e2a" + integrity sha512-A2E3U//MBwbJVzebddm1YfNp7Nud5Ip+IPn4BozBmn4KqVX7AvluoIDFWjsv5OkGnKUXQVmMSoMKLa3ScCblcQ== capital-case@^1.0.4: version "1.0.4" @@ -1471,18 +1625,7 @@ cardinal@^2.1.1: ansicolors "~0.3.2" redeyed "~2.1.0" -chalk@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A== - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.0.0, chalk@^2.4.2: +chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1491,7 +1634,7 @@ chalk@^2.0.0, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: +chalk@^4, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -1499,7 +1642,12 @@ chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" -change-case@^4.1.2: +chalk@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" + integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== + +change-case@^4, change-case@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/change-case/-/change-case-4.1.2.tgz#fedfc5f136045e2398c0410ee441f95704641e12" integrity sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A== @@ -1537,16 +1685,19 @@ chokidar@3.5.3: optionalDependencies: fsevents "~2.3.2" -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - chownr@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== +chromium-bidi@0.4.33: + version "0.4.33" + resolved "https://registry.yarnpkg.com/chromium-bidi/-/chromium-bidi-0.4.33.tgz#9a9aba5a5b07118c8e7d6405f8ee79f47418dd1d" + integrity sha512-IxoFM5WGQOIAd95qrSXzJUv4eXIrh+RvU3rwwqIiwYuvfE7U/Llj4fejbsJnjJMUYCuGtVQsY2gv7oGl4aTNSQ== + dependencies: + mitt "3.0.1" + urlpattern-polyfill "9.0.0" + clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" @@ -1559,11 +1710,6 @@ clean-stack@^3.0.1: dependencies: escape-string-regexp "4.0.0" -cli-boxes@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" - integrity sha512-3Fo5wu8Ytle8q9iCzS4D2MWVL2X7JVWRiS1BnXbTFDhS9c/REkM9vd1AmabsoZoY5/dGi5TT9iKL8Kb6DeBRQg== - cli-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" @@ -1571,13 +1717,6 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-progress@^3.10.0: - version "3.11.2" - resolved "https://registry.yarnpkg.com/cli-progress/-/cli-progress-3.11.2.tgz#f8c89bd157e74f3f2c43bcfb3505670b4d48fc77" - integrity sha512-lCPoS6ncgX4+rJu5bS3F/iCz17kZ9MPZ6dpuTtI0KXKABkhyXIdYB3Inby1OpaGti3YlI3EeEkM9AuWpelJrVA== - dependencies: - string-width "^4.2.3" - cli-progress@^3.12.0: version "3.12.0" resolved "https://registry.yarnpkg.com/cli-progress/-/cli-progress-3.12.0.tgz#807ee14b66bcc086258e444ad0f19e7d42577942" @@ -1586,9 +1725,9 @@ cli-progress@^3.12.0: string-width "^4.2.3" cli-spinners@^2.5.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.7.0.tgz#f815fd30b5f9eaac02db604c7a231ed7cb2f797a" - integrity sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw== + version "2.9.1" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.1.tgz#9c0b9dad69a6d47cbb4333c14319b060ed395a35" + integrity sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ== cli-table@^0.3.1: version "0.3.11" @@ -1672,11 +1811,6 @@ cmd-shim@^5.0.0: dependencies: mkdirp-infer-owner "^2.0.0" -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== - color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -1706,6 +1840,11 @@ color-support@^1.1.2, color-support@^1.1.3: resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== +colorette@^2.0.7: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + colors@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" @@ -1738,36 +1877,11 @@ commondir@^1.0.1: resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== -compress-commons@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-4.1.1.tgz#df2a09a7ed17447642bad10a85cc9a19e5c42a7d" - integrity sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ== - dependencies: - buffer-crc32 "^0.2.13" - crc32-stream "^4.0.2" - normalize-path "^3.0.0" - readable-stream "^3.6.0" - concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -concurrently@^7.6.0: - version "7.6.0" - resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-7.6.0.tgz#531a6f5f30cf616f355a4afb8f8fcb2bba65a49a" - integrity sha512-BKtRgvcJGeZ4XttiDiNcFiRlxoAeZOseqUvyYRUp/Vtd+9p1ULmeoSqGsDA+2ivdeDFpqrJvGvmI+StKfKl5hw== - dependencies: - chalk "^4.1.0" - date-fns "^2.29.1" - lodash "^4.17.21" - rxjs "^7.0.0" - shell-quote "^1.7.3" - spawn-command "^0.0.2-1" - supports-color "^8.1.0" - tree-kill "^1.2.2" - yargs "^17.3.1" - console-control-strings@^1.0.0, console-control-strings@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" @@ -1783,76 +1897,56 @@ constant-case@^3.0.4: upper-case "^2.0.2" content-type@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== convert-source-map@^1.7.0: version "1.9.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== -core-js-pure@^3.25.1: - version "3.25.5" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.25.5.tgz#79716ba54240c6aa9ceba6eee08cf79471ba184d" - integrity sha512-oml3M22pHM+igfWHDfdLVq2ShWmjM2V4L+dQEBs0DWVIqEm9WHCwGAlZ6BmyBQGy5sFrJmcx+856D9lVKyGWYg== +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +core-js-pure@^3.30.2: + version "3.33.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.33.1.tgz#7f27dd239da8eb97dbea30120071be8e5565cb0e" + integrity sha512-wCXGbLjnsP10PlK/thHSQlOLlLKNEkaWbTzVvHHZ79fZNeN1gUmw2gBlpItxPv/pvqldevEXFh/d5stdNvl6EQ== core-js@^3.6.4: - version "3.25.5" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.25.5.tgz#e86f651a2ca8a0237a5f064c2fe56cef89646e27" - integrity sha512-nbm6eZSjm+ZuBQxCUPQKQCoUEfFOXjUZ8dTTyikyKaWrTYmAVbykQfwsKE5dBK88u3QCkCrzsx/PPlKfhsvgpw== + version "3.33.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.1.tgz#ef3766cfa382482d0a2c2bc5cb52c6d88805da52" + integrity sha512-qVSq3s+d4+GsqN0teRCJtM6tdEEXyWxjzbhVrCHmBS5ZTM0FS2MOS0D13dUXAWDUN6a+lHI/N1hF9Ytz6iLl9Q== core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cosmiconfig@7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" - integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== +cosmiconfig@8.3.6: + version "8.3.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" + integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" path-type "^4.0.0" - yaml "^1.10.0" - -crc-32@^1.2.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" - integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== - -crc32-stream@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-4.0.2.tgz#c922ad22b38395abe9d3870f02fa8134ed709007" - integrity sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w== - dependencies: - crc-32 "^1.2.0" - readable-stream "^3.4.0" create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-fetch@3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" - integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== - dependencies: - node-fetch "2.6.7" - -cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== +cross-fetch@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-4.0.0.tgz#f037aef1580bb3a1a35164ea2a848ba81b445983" + integrity sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g== dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" + node-fetch "^2.6.12" cross-spawn@^7.0.0, cross-spawn@^7.0.3: version "7.0.3" @@ -1885,26 +1979,16 @@ dargs@^7.0.0: resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== -date-fns@^2.29.1: - version "2.29.3" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.3.tgz#27402d2fc67eb442b511b70bbdf98e6411cd68a8" - integrity sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA== +data-uri-to-buffer@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz#540bd4c8753a25ee129035aebdedf63b078703c7" + integrity sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg== -dateformat@^4.5.0: +dateformat@^4.5.0, dateformat@^4.6.3: version "4.6.3" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.6.3.tgz#556fa6497e5217fedb78821424f8a1c22fa3f4b5" integrity sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA== -dayjs-plugin-utc@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/dayjs-plugin-utc/-/dayjs-plugin-utc-0.1.2.tgz#48e552407024143922d6499a40f6c765f8c93d03" - integrity sha512-ExERH5o3oo6jFOdkvMP3gytTCQ9Ksi5PtylclJWghr7k7m3o2U5QrwtdiJkOxLOH4ghr0EKhpqGefzGz1VvVJg== - -dayjs@^1.8.16: - version "1.11.5" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.5.tgz#00e8cc627f231f9499c19b38af49f56dc0ac5e93" - integrity sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA== - debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" @@ -1912,13 +1996,6 @@ debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, de dependencies: ms "2.1.2" -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -1965,13 +2042,23 @@ defer-to-connect@^2.0.0: resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== -define-properties@^1.1.3, define-properties@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== +define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" has-property-descriptors "^1.0.0" - object-keys "^1.1.1" + +degenerator@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-5.0.1.tgz#9403bf297c6dad9a1ece409b37db27954f91f2f5" + integrity sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ== + dependencies: + ast-types "^0.13.4" + escodegen "^2.1.0" + esprima "^4.0.1" delayed-stream@~1.0.0: version "1.0.0" @@ -1983,20 +2070,15 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== -depd@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - deprecation@^2.0.0, deprecation@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== -devtools-protocol@0.0.1056733: - version "0.0.1056733" - resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1056733.tgz#55bb1d56761014cc221131cca5e6bad94eefb2b9" - integrity sha512-CmTu6SQx2g3TbZzDCAV58+LTxVdKplS7xip0g5oDXpZ+isr0rv5dDP8ToyVRywzPHkCCPKgKgScEcwz4uPWDIA== +devtools-protocol@0.0.1203626: + version "0.0.1203626" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1203626.tgz#4366a4c81a7e0d4fd6924e9182c67f1e5941e820" + integrity sha512-nEzHZteIUZfGCZtTiS1fRpC8UZmsfD1SiyPvaUNvS13dvKf666OAm8YTi0+Ca3n1nLEyu49Cy4+dPWpaHFJk9g== dezalgo@^1.0.0: version "1.0.4" @@ -2036,12 +2118,10 @@ dot-case@^3.0.4: no-case "^3.0.4" tslib "^2.0.3" -dtrace-provider@~0.6: - version "0.6.0" - resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.6.0.tgz#0b078d5517937d873101452d9146737557b75e51" - integrity sha512-yqNrDWYWOR3wumcWPhlIGIKRSFMbDEwilGi+xYeaY4wW82cZrWsqGE+jsVnouxMqt/kCVsNmy/XDXLrm/J6SJg== - dependencies: - nan "^2.0.8" +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== ecdsa-sig-formatter@1.0.11: version "1.0.11" @@ -2050,23 +2130,28 @@ ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer "^5.0.1" -ejs@^3.1.6, ejs@^3.1.8: - version "3.1.8" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.8.tgz#758d32910c78047585c7ef1f92f9ee041c1c190b" - integrity sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ== +ejs@^3.1.8, ejs@^3.1.9: + version "3.1.9" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" + integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== dependencies: jake "^10.8.5" -electron-to-chromium@^1.4.251: - version "1.4.283" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.283.tgz#d4f263f5df402fd799c0a06255d580dcf8aa9a8e" - integrity sha512-g6RQ9zCOV+U5QVHW9OpFR7rdk/V7xfopNXnyAamdpFgCHgZ1sjI8VuR1+zG2YG/TZk+tQ8mpNkug4P8FU0fuOA== +electron-to-chromium@^1.4.535: + version "1.4.567" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.567.tgz#c92e8fbc2bd15df3068d92571733a218a5413add" + integrity sha512-8KR114CAYQ4/r5EIEsOmOMqQ9j0MRbJZR3aXD/KFA8RuKzyoUB4XrUCg+l8RUGqTVQgKNIgTpjaG8YHRPAbX2w== emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + encoding@^0.1.12, encoding@^0.1.13: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" @@ -2074,7 +2159,7 @@ encoding@^0.1.12, encoding@^0.1.13: dependencies: iconv-lite "^0.6.2" -end-of-stream@^1.1.0, end-of-stream@^1.4.1: +end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -2103,45 +2188,6 @@ error@^10.4.0: resolved "https://registry.yarnpkg.com/error/-/error-10.4.0.tgz#6fcf0fd64bceb1e750f8ed9a3dd880f00e46a487" integrity sha512-YxIFEJuhgcICugOUvRx5th0UM+ActZ9sjY0QJmeVwsQdvosZ7kYzc9QqS0Da3R5iUmgU5meGIxh0xBeZpMVeLw== -es-abstract@^1.19.0, es-abstract@^1.19.5, es-abstract@^1.20.0: - version "1.20.4" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.4.tgz#1d103f9f8d78d4cf0713edcd6d0ed1a46eed5861" - integrity sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.1.3" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-symbols "^1.0.3" - internal-slot "^1.0.3" - is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-weakref "^1.0.2" - object-inspect "^1.12.2" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" - safe-regex-test "^1.0.0" - string.prototype.trimend "^1.0.5" - string.prototype.trimstart "^1.0.5" - unbox-primitive "^1.0.2" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - es6-error@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" @@ -2157,16 +2203,51 @@ escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== -esprima@^4.0.0, esprima@~4.0.0: +escodegen@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" + integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionalDependencies: + source-map "~0.6.1" + +eslint-plugin-perfectionist@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-2.2.0.tgz#a1b1f1407ce9bc20a4f0e2b8113fb84e5b9dfb9f" + integrity sha512-/nG2Uurd6AY7CI6zlgjHPOoiPY8B7EYMUWdNb5w+EzyauYiQjjD5lQwAI1FlkBbCCFFZw/CdZIPQhXumYoiyaw== + dependencies: + "@typescript-eslint/utils" "^6.7.5" + minimatch "^9.0.3" + natural-compare-lite "^1.4.0" + +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: + 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== + +esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + event-target-shim@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" @@ -2182,6 +2263,11 @@ events@1.1.1: resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" integrity sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw== +events@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + execa@^5.0.0, execa@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -2197,6 +2283,11 @@ execa@^5.0.0, execa@^5.1.1: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +exponential-backoff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" + integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== + external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -2217,29 +2308,25 @@ extract-zip@2.0.1: optionalDependencies: "@types/yauzl" "^2.9.1" -fancy-test@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/fancy-test/-/fancy-test-2.0.5.tgz#eb39e10b77e476147aa4ed5a81e14e809b46aaae" - integrity sha512-ASPLNVkHSSIdRI/uLlK+XGhf1ul/MpRN9VE84ehXL+FOprQjXrDXX3wW1wqKvtcTTC+AW0E0RxdpJ5IEopjhQA== - dependencies: - "@types/chai" "*" - "@types/lodash" "*" - "@types/node" "*" - "@types/sinon" "*" - lodash "^4.17.13" - mock-stdin "^1.0.0" - nock "^13.0.0" - stdout-stderr "^0.1.9" +fast-copy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/fast-copy/-/fast-copy-3.0.1.tgz#9e89ef498b8c04c1cd76b33b8e14271658a732aa" + integrity sha512-Knr7NOtK3HWRYGtHoJrjkaWepqT8thIVGAwt0p0aUs1zqkAzXZV4vo9fFNwyb5fcqK1GKYFYxldQdIDVKhUAfA== -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: +fast-deep-equal@^3.1.1: version "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-fifo@^1.1.0, fast-fifo@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" + integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== + fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -2254,15 +2341,25 @@ fast-levenshtein@^3.0.0: dependencies: fastest-levenshtein "^1.0.7" +fast-redact@^3.1.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.3.0.tgz#7c83ce3a7be4898241a46560d51de10f653f7634" + integrity sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ== + +fast-safe-stringify@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" + integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== + fastest-levenshtein@^1.0.7: version "1.0.16" resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== dependencies: reusify "^1.0.4" @@ -2299,7 +2396,7 @@ figures@^3.0.0: dependencies: escape-string-regexp "^1.0.5" -filelist@^1.0.1: +filelist@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== @@ -2380,6 +2477,14 @@ foreground-child@^2.0.0: cross-spawn "^7.0.0" signal-exit "^3.0.2" +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -2394,11 +2499,6 @@ fromentries@^1.2.0: resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.3.2.tgz#e4bca6808816bf8f93b52750f1127f5a6fd86e3a" integrity sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg== -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - fs-extra@^8.1, fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" @@ -2408,16 +2508,6 @@ fs-extra@^8.1, fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^9.0.1, fs-extra@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -2425,35 +2515,27 @@ fs-minipass@^2.0.0, fs-minipass@^2.1.0: dependencies: minipass "^3.0.0" +fs-minipass@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" + integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== + dependencies: + minipass "^7.0.3" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" - -functions-have-names@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== gauge@^3.0.0: version "3.0.2" @@ -2494,25 +2576,21 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" - integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== +get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== dependencies: - function-bind "^1.1.1" - has "^1.0.3" + function-bind "^1.1.2" + has-proto "^1.0.1" has-symbols "^1.0.3" + hasown "^2.0.0" get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - integrity sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw== - get-stream@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" @@ -2525,13 +2603,15 @@ get-stream@^6.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== +get-uri@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-6.0.2.tgz#e019521646f4a8ff6d291fbaea2c46da204bb75b" + integrity sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" + basic-ftp "^5.0.2" + data-uri-to-buffer "^6.0.0" + debug "^4.3.4" + fs-extra "^8.1.0" github-slugger@^1.5.0: version "1.5.0" @@ -2564,16 +2644,16 @@ glob@7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^6.0.1: - version "6.0.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" - integrity sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A== +glob@^10.2.2: + version "10.3.10" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" + integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" + foreground-child "^3.1.0" + jackspeak "^2.3.5" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" glob@^7.0.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.2.3" @@ -2587,10 +2667,10 @@ glob@^7.0.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^8.0.1: - version "8.0.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e" - integrity sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ== +glob@^8.0.0, glob@^8.0.1: + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -2615,6 +2695,13 @@ globby@^11.0.1, globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + got@^11: version "11.8.6" resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" @@ -2632,28 +2719,16 @@ got@^11: p-cancelable "^2.0.0" responselike "^2.0.0" -graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.5, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.6, graceful-fs@^4.2.9: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.5, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== grouped-queue@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/grouped-queue/-/grouped-queue-2.0.0.tgz#a2c6713f2171e45db2c300a3a9d7c119d694dac8" integrity sha512-/PiFUa7WIsl48dUeCvhIHnwNmAAzlI/eHoJl0vu3nsFA366JleY7Ff8EVTplZu5kO0MIdZjKTTnzItL61ahbnw== -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg== - dependencies: - ansi-regex "^2.0.0" - -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -2665,11 +2740,16 @@ has-flag@^4.0.0: integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== dependencies: - get-intrinsic "^1.1.1" + get-intrinsic "^1.2.2" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" @@ -2688,13 +2768,6 @@ has-unicode@^2.0.1: resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - hasha@^5.0.0: version "5.2.2" resolved "https://registry.yarnpkg.com/hasha/-/hasha-5.2.2.tgz#a48477989b3b327aea3c04f53096d816d97522a1" @@ -2703,6 +2776,13 @@ hasha@^5.0.0: is-stream "^2.0.0" type-fest "^0.8.0" +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + he@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" @@ -2716,6 +2796,14 @@ header-case@^2.0.4: capital-case "^1.0.4" tslib "^2.0.3" +help-me@^4.0.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/help-me/-/help-me-4.2.0.tgz#50712bfd799ff1854ae1d312c36eafcea85b0563" + integrity sha512-TAOnTB8Tz5Dw8penUuzHVrKNKlCIbwwbHnXraNJxPwf8LRtE2HlM84RYuezMFcwOJmoYOCWVDyJ8TQGxn9PgxA== + dependencies: + glob "^8.0.0" + readable-stream "^3.6.0" + hosted-git-info@^2.1.4: version "2.8.9" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" @@ -2728,21 +2816,23 @@ hosted-git-info@^4.0.1: dependencies: lru-cache "^6.0.0" +hosted-git-info@^6.0.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-6.1.1.tgz#629442c7889a69c05de604d52996b74fe6f26d58" + integrity sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w== + dependencies: + lru-cache "^7.5.1" + html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -http-cache-semantics@^4.0.0: +http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0, http-cache-semantics@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== -http-cache-semantics@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== - http-call@^5.2.2: version "5.3.0" resolved "https://registry.yarnpkg.com/http-call/-/http-call-5.3.0.tgz#4ded815b13f423de176eb0942d69c43b25b148db" @@ -2778,6 +2868,14 @@ http-proxy-agent@^5.0.0: agent-base "6" debug "4" +http-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz#e9096c5afd071a3fce56e6252bb321583c124673" + integrity sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ== + dependencies: + agent-base "^7.1.0" + debug "^4.3.4" + http2-wrapper@^1.0.0-beta.5.2: version "1.0.3" resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" @@ -2786,7 +2884,7 @@ http2-wrapper@^1.0.0-beta.5.2: quick-lru "^5.1.1" resolve-alpn "^1.0.0" -https-proxy-agent@5.0.1, https-proxy-agent@^5.0.0: +https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== @@ -2794,6 +2892,14 @@ https-proxy-agent@5.0.1, https-proxy-agent@^5.0.0: agent-base "6" debug "4" +https-proxy-agent@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz#e2645b846b90e96c6e6f347fb5b2e41f1590b09b" + integrity sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA== + dependencies: + agent-base "^7.0.2" + debug "4" + human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -2830,7 +2936,7 @@ ieee754@1.1.13: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== -ieee754@^1.1.13, ieee754@^1.1.4: +ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -2842,12 +2948,24 @@ ignore-walk@^4.0.1: dependencies: minimatch "^3.0.4" +ignore-walk@^6.0.0: + version "6.0.3" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.3.tgz#0fcdb6decaccda35e308a7b0948645dd9523b7bb" + integrity sha512-C7FfFoTA+bI10qfeydT8aZbvr91vAEU+2W5BZUlzPec47oNb07SsOfwYrtxuvOYdUApPP/Qlh4DtAO51Ekk2QA== + dependencies: + minimatch "^9.0.0" + ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== -import-fresh@^3.2.1: +import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -2902,10 +3020,10 @@ inquirer@^7.0.0: strip-ansi "^6.0.0" through "^2.3.6" -inquirer@^8.0.0: - version "8.2.4" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.4.tgz#ddbfe86ca2f67649a67daa6f1051c128f684f0b4" - integrity sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg== +inquirer@^8.0.0, inquirer@^8.2.5: + version "8.2.6" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.6.tgz#733b74888195d8d400a67ac332011b5fae5ea562" + integrity sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg== dependencies: ansi-escapes "^4.2.1" chalk "^4.1.1" @@ -2921,22 +3039,18 @@ inquirer@^8.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" through "^2.3.6" - wrap-ansi "^7.0.0" - -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== - dependencies: - get-intrinsic "^1.1.0" - has "^1.0.3" - side-channel "^1.0.4" + wrap-ansi "^6.0.1" interpret@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== +ip@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48" + integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== + ip@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" @@ -2955,13 +3069,6 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -2969,32 +3076,17 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: +is-callable@^1.1.3: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-core-module@^2.5.0, is-core-module@^2.9.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" - integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== +is-core-module@^2.13.0, is-core-module@^2.5.0, is-core-module@^2.8.1: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== dependencies: - has-tostringtag "^1.0.0" + hasown "^2.0.0" is-docker@^2.0.0: version "2.2.1" @@ -3006,18 +3098,6 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== - is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" @@ -3030,7 +3110,7 @@ is-generator-function@^1.0.7: dependencies: has-tostringtag "^1.0.0" -is-glob@^4.0.1, is-glob@~4.0.1: +is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -3047,18 +3127,6 @@ is-lambda@^1.0.1: resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -3074,14 +3142,6 @@ is-plain-object@^5.0.0: resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - is-retry-allowed@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" @@ -3094,42 +3154,17 @@ is-scoped@^2.1.0: dependencies: scoped-regex "^2.0.0" -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - is-stream@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== +is-typed-array@^1.1.3: + version "1.1.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typed-array@^1.1.3, is-typed-array@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.9.tgz#246d77d2871e7d9f5aeb1d54b9f52c71329ece67" - integrity sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - es-abstract "^1.20.0" - for-each "^0.3.3" - has-tostringtag "^1.0.0" + which-typed-array "^1.1.11" is-typedarray@^1.0.0: version "1.0.0" @@ -3146,13 +3181,6 @@ is-utf8@^0.2.0, is-utf8@^0.2.1: resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -3170,7 +3198,7 @@ isarray@^1.0.0, isarray@~1.0.0: resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== -isbinaryfile@^4.0.10, isbinaryfile@^4.0.8: +isbinaryfile@^4.0.10: version "4.0.10" resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== @@ -3220,12 +3248,12 @@ istanbul-lib-processinfo@^2.0.2: uuid "^8.3.2" istanbul-lib-report@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" - integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== dependencies: istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" + make-dir "^4.0.0" supports-color "^7.1.0" istanbul-lib-source-maps@^4.0.0: @@ -3238,34 +3266,48 @@ istanbul-lib-source-maps@^4.0.0: source-map "^0.6.1" istanbul-reports@^3.0.2: - version "3.1.5" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" - integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== + version "3.1.6" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" + integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +jackspeak@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + jake@^10.8.5: - version "10.8.5" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" - integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== + version "10.8.7" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" + integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== dependencies: async "^3.2.3" chalk "^4.0.2" - filelist "^1.0.1" - minimatch "^3.0.4" + filelist "^1.0.4" + minimatch "^3.1.2" jmespath@0.16.0: version "0.16.0" resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.16.0.tgz#b15b0a85dfd4d930d43e69ed605943c802785076" integrity sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw== +joycon@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03" + integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@4.1.0: +js-yaml@4.1.0, js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== @@ -3292,10 +3334,10 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== -jsforce@^2.0.0-beta.19: - version "2.0.0-beta.19" - resolved "https://registry.yarnpkg.com/jsforce/-/jsforce-2.0.0-beta.19.tgz#4a136b88d6a9f6668714c4ccbb0acd55e46ea493" - integrity sha512-WdF6hs7kukXNGvp/VRhu2DngldgiBBorsc2WA5us08oJGbEIPwn/itqYJWKJ+rfPXepz5JbkWQd48XHGjqmPpw== +jsforce@^2.0.0-beta.28: + version "2.0.0-beta.28" + resolved "https://registry.yarnpkg.com/jsforce/-/jsforce-2.0.0-beta.28.tgz#5fd8d9b8e5efc798698793b147e00371f3d74e8f" + integrity sha512-tTmKRhr4yWNinhmurY/tiiltLFQq9RQ+gpYAt3wjFdCGjzd49/wqYQIFw4SsI3+iLjxXnc0uTgGwdAkDjxDWnA== dependencies: "@babel/runtime" "^7.12.5" "@babel/runtime-corejs3" "^7.12.5" @@ -3316,20 +3358,13 @@ jsforce@^2.0.0-beta.19: open "^7.0.0" regenerator-runtime "^0.13.3" strip-ansi "^6.0.0" - xml2js "^0.4.22" + xml2js "^0.5.0" json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== -json-merge-patch@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-merge-patch/-/json-merge-patch-1.0.2.tgz#c4626811943b2f362f8607ae8f03d528875465b0" - integrity sha512-M6Vp2GN9L7cfuMXiWOmHj9bEFbeC250iVtcKQbqVgEsDVYnIsrNsbU+h/Y/PkbBQCtEa4Bez+Ebv0zfbC8ObLg== - dependencies: - fast-deep-equal "^3.1.3" - json-parse-better-errors@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -3340,6 +3375,11 @@ json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== +json-parse-even-better-errors@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz#2cb2ee33069a78870a0c7e3da560026b89669cf7" + integrity sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA== + json-schema-traverse@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" @@ -3350,15 +3390,10 @@ json-stringify-nice@^1.1.4: resolved "https://registry.yarnpkg.com/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz#2c937962b80181d3f317dd39aa323e14f5a60a67" integrity sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw== -json-stringify-safe@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - -json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== jsonfile@^4.0.0: version "4.0.0" @@ -3367,24 +3402,15 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - jsonparse@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== -jsonwebtoken@8.5.1: - version "8.5.1" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" - integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== +jsonwebtoken@9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" + integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== dependencies: jws "^3.2.2" lodash.includes "^4.3.0" @@ -3395,17 +3421,27 @@ jsonwebtoken@8.5.1: lodash.isstring "^4.0.1" lodash.once "^4.0.0" ms "^2.1.1" - semver "^5.6.0" + semver "^7.5.4" + +jszip@3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" + integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== + dependencies: + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + setimmediate "^1.0.5" just-diff-apply@^5.2.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/just-diff-apply/-/just-diff-apply-5.4.1.tgz#1debed059ad009863b4db0e8d8f333d743cdd83b" - integrity sha512-AAV5Jw7tsniWwih8Ly3fXxEZ06y+6p5TwQMsw0dzZ/wPKilzyDgdAnL0Ug4NNIquPUOh1vfFWEHbmXUqM5+o8g== + version "5.5.0" + resolved "https://registry.yarnpkg.com/just-diff-apply/-/just-diff-apply-5.5.0.tgz#771c2ca9fa69f3d2b54e7c3f5c1dfcbcc47f9f0f" + integrity sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw== just-diff@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/just-diff/-/just-diff-5.1.1.tgz#8da6414342a5ed6d02ccd64f5586cbbed3146202" - integrity sha512-u8HXJ3HlNrTzY7zrYYKjNEfBlyjqhdBkoyTVdjtn7p02RJD5NvR8rIClzeGA7t+UYP1/7eAkWNLU0+P3QrEqKQ== + version "5.2.0" + resolved "https://registry.yarnpkg.com/just-diff/-/just-diff-5.2.0.tgz#60dca55891cf24cd4a094e33504660692348a241" + integrity sha512-6ufhP9SHjb7jibNFrNxyFZ6od3g+An6Ai9mhGRvcYe8UJlH0prseN64M+6ZBBUoKYHZsitDP42gAJ8+eVWr3lw== jwa@^1.4.1: version "1.4.1" @@ -3425,18 +3461,18 @@ jws@^3.2.2: safe-buffer "^5.0.1" keyv@^4.0.0: - version "4.5.2" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.2.tgz#0e310ce73bf7851ec702f2eaf46ec4e3805cce56" - integrity sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g== + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== dependencies: json-buffer "3.0.1" -lazystream@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.1.tgz#494c831062f1f9408251ec44db1cba29242a2638" - integrity sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw== +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== dependencies: - readable-stream "^2.0.5" + immediate "~3.0.5" lines-and-columns@^1.1.6: version "1.2.4" @@ -3467,20 +3503,10 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash.defaults@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" - integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== - -lodash.difference@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" - integrity sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA== - -lodash.flatten@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" - integrity sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g== +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA== lodash.flattendeep@^4.4.0: version "4.4.0" @@ -3522,12 +3548,22 @@ lodash.once@^4.0.0: resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== -lodash.union@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" - integrity sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw== +lodash.template@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" + integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" + integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== + dependencies: + lodash._reinterpolate "^3.0.0" -lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.19, lodash@^4.17.21: +lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.19, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -3552,6 +3588,13 @@ lowercase-keys@^2.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -3559,10 +3602,15 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^7.7.1: - version "7.14.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.14.0.tgz#21be64954a4680e303a09e9468f880b98a0b3c7f" - integrity sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ== +lru-cache@^7.14.1, lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: + version "7.18.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + +"lru-cache@^9.1.1 || ^10.0.0": + version "10.0.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" + integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== make-dir@^3.0.0, make-dir@^3.0.2: version "3.1.0" @@ -3571,6 +3619,13 @@ make-dir@^3.0.0, make-dir@^3.0.2: dependencies: semver "^6.0.0" +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" @@ -3598,6 +3653,27 @@ make-fetch-happen@^10.0.1: socks-proxy-agent "^7.0.0" ssri "^9.0.0" +make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1, make-fetch-happen@^11.0.3, make-fetch-happen@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz#85ceb98079584a9523d4bf71d32996e7e208549f" + integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== + dependencies: + agentkeepalive "^4.2.1" + cacache "^17.0.0" + http-cache-semantics "^4.1.1" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^7.7.1" + minipass "^5.0.0" + minipass-fetch "^3.0.0" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + promise-retry "^2.0.1" + socks-proxy-agent "^7.0.0" + ssri "^10.0.0" + make-fetch-happen@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" @@ -3620,23 +3696,7 @@ make-fetch-happen@^9.1.0: socks-proxy-agent "^6.0.0" ssri "^8.0.0" -"mem-fs-editor@^8.1.2 || ^9.0.0": - version "9.5.0" - resolved "https://registry.yarnpkg.com/mem-fs-editor/-/mem-fs-editor-9.5.0.tgz#9368724bd37f76eebfcf24d71fc6624b01588969" - integrity sha512-7p+bBDqsSisO20YIZf2ntYvST27fFJINn7CKE21XdPUQDcLV62b/yB5sTOooQeEoiZ3rldZQ+4RfONgL/gbRoA== - dependencies: - binaryextensions "^4.16.0" - commondir "^1.0.1" - deep-extend "^0.6.0" - ejs "^3.1.8" - globby "^11.1.0" - isbinaryfile "^4.0.8" - minimatch "^3.1.2" - multimatch "^5.0.0" - normalize-path "^3.0.0" - textextensions "^5.13.0" - -mem-fs-editor@^9.0.0: +"mem-fs-editor@^8.1.2 || ^9.0.0", mem-fs-editor@^9.0.0: version "9.7.0" resolved "https://registry.yarnpkg.com/mem-fs-editor/-/mem-fs-editor-9.7.0.tgz#dbb458b8acb885c84013645e93f71aa267a7fdf6" integrity sha512-ReB3YD24GNykmu4WeUL/FDIQtkoyGB6zfJv60yfCo3QjKeimNcTqv2FT83bP0ccs6uu+sm5zyoBlspAzigmsdg== @@ -3653,11 +3713,11 @@ mem-fs-editor@^9.0.0: textextensions "^5.13.0" "mem-fs@^1.2.0 || ^2.0.0": - version "2.2.1" - resolved "https://registry.yarnpkg.com/mem-fs/-/mem-fs-2.2.1.tgz#c87bc8a53fb17971b129d4bcd59a9149fb78c5b1" - integrity sha512-yiAivd4xFOH/WXlUi6v/nKopBh1QLzwjFi36NK88cGt/PRXI8WeBASqY+YSjIVWvQTx3hR8zHKDBMV6hWmglNA== + version "2.3.0" + resolved "https://registry.yarnpkg.com/mem-fs/-/mem-fs-2.3.0.tgz#d38bdd729ab0316bfb56d0d0ff669f91e7078463" + integrity sha512-GftCCBs6EN8sz3BoWO1bCj8t7YBtT713d8bUgbhg9Iel5kFSqnSvCK06TYIDJAtJ51cSiWkM/YemlT0dfoFycw== dependencies: - "@types/node" "^15.6.1" + "@types/node" "^15.6.2" "@types/vinyl" "^2.0.4" vinyl "^2.0.1" vinyl-file "^3.0.0" @@ -3707,13 +3767,6 @@ mimic-response@^3.1.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== -"minimatch@2 || 3", minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - minimatch@5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" @@ -3721,10 +3774,17 @@ minimatch@5.0.1: dependencies: brace-expansion "^2.0.1" -minimatch@^5.0.1, minimatch@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" - integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg== +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== dependencies: brace-expansion "^2.0.1" @@ -3735,10 +3795,17 @@ minimatch@^7.2.0: dependencies: brace-expansion "^2.0.1" -minimist@^1.1.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: - version "1.2.7" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" - integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== +minimatch@^9.0.0, minimatch@^9.0.1, minimatch@^9.0.3: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.5, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== minipass-collect@^1.0.2: version "1.0.2" @@ -3769,6 +3836,17 @@ minipass-fetch@^2.0.3: optionalDependencies: encoding "^0.1.13" +minipass-fetch@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.4.tgz#4d4d9b9f34053af6c6e597a64be8e66e42bf45b7" + integrity sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg== + dependencies: + minipass "^7.0.3" + minipass-sized "^1.0.3" + minizlib "^2.1.2" + optionalDependencies: + encoding "^0.1.13" + minipass-flush@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" @@ -3799,12 +3877,22 @@ minipass-sized@^1.0.3: minipass "^3.0.0" minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3, minipass@^3.1.6: - version "3.3.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.4.tgz#ca99f95dd77c43c7a76bf51e6d200025eee0ffae" - integrity sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw== + version "3.3.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== dependencies: yallist "^4.0.0" +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.3: + version "7.0.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" + integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== + minizlib@^2.0.0, minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" @@ -3813,6 +3901,11 @@ minizlib@^2.0.0, minizlib@^2.1.1, minizlib@^2.1.2: minipass "^3.0.0" yallist "^4.0.0" +mitt@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1" + integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw== + mkdirp-classic@^0.5.2: version "0.5.3" resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" @@ -3832,13 +3925,6 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mkdirp@~0.5.1: - version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" - integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== - dependencies: - minimist "^1.2.6" - mocha@10.2.0: version "10.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" @@ -3866,11 +3952,6 @@ mocha@10.2.0: yargs-parser "20.2.4" yargs-unparser "2.0.0" -mock-stdin@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/mock-stdin/-/mock-stdin-1.0.0.tgz#efcfaf4b18077e14541742fd758b9cae4e5365ea" - integrity sha512-tukRdb9Beu27t6dN+XztSRHq9J0B/CoAOySGzHfn8UTfmqipA5yNT/sDUEyYdAV3Hpka6Wx6kOMxuObdOex60Q== - ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -3905,44 +3986,30 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -mv@~2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" - integrity sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg== - dependencies: - mkdirp "~0.5.1" - ncp "~2.0.0" - rimraf "~2.4.0" - -nan@^2.0.8: - version "2.17.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" - integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== - nanoid@3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + natural-orderby@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/natural-orderby/-/natural-orderby-2.0.3.tgz#8623bc518ba162f8ff1cdb8941d74deb0fdcc016" integrity sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q== -ncp@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" - integrity sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA== - negotiator@^0.6.2, negotiator@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +netmask@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7" + integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg== no-case@^3.0.4: version "3.0.4" @@ -3952,20 +4019,10 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -nock@^13.0.0: - version "13.2.9" - resolved "https://registry.yarnpkg.com/nock/-/nock-13.2.9.tgz#4faf6c28175d36044da4cfa68e33e5a15086ad4c" - integrity sha512-1+XfJNYF1cjGB+TKMWi29eZ0b82QOvQs2YoLNzbpWGqFMtRQHTa57osqdGj4FrFPgkO4D4AZinzUJR9VvW3QUA== - dependencies: - debug "^4.1.0" - json-stringify-safe "^5.0.1" - lodash "^4.17.21" - propagate "^2.0.0" - -node-fetch@2.6.7, node-fetch@^2.6.1, node-fetch@^2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== +node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.7: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" @@ -3985,6 +4042,23 @@ node-gyp@^8.2.0: tar "^6.1.2" which "^2.0.2" +node-gyp@^9.0.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.0.tgz#2a7a91c7cba4eccfd95e949369f27c9ba704f369" + integrity sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg== + dependencies: + env-paths "^2.2.0" + exponential-backoff "^3.1.1" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^11.0.3" + nopt "^6.0.0" + npmlog "^6.0.0" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.2" + which "^2.0.2" + node-preload@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/node-preload/-/node-preload-0.2.1.tgz#c03043bb327f417a18fee7ab7ee57b408a144301" @@ -3992,10 +4066,10 @@ node-preload@^0.2.1: dependencies: process-on-spawn "^1.0.0" -node-releases@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" - integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== +node-releases@^2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== nopt@^5.0.0: version "5.0.0" @@ -4004,6 +4078,13 @@ nopt@^5.0.0: dependencies: abbrev "1" +nopt@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d" + integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== + dependencies: + abbrev "^1.0.0" + normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -4024,6 +4105,16 @@ normalize-package-data@^3.0.3: semver "^7.3.4" validate-npm-package-license "^3.0.1" +normalize-package-data@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-5.0.0.tgz#abcb8d7e724c40d88462b84982f7cbf6859b4588" + integrity sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q== + dependencies: + hosted-git-info "^6.0.0" + is-core-module "^2.8.1" + semver "^7.3.5" + validate-npm-package-license "^3.0.4" + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -4041,6 +4132,13 @@ npm-bundled@^1.1.1: dependencies: npm-normalize-package-bin "^1.0.1" +npm-bundled@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-3.0.0.tgz#7e8e2f8bb26b794265028491be60321a25a39db7" + integrity sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ== + dependencies: + npm-normalize-package-bin "^3.0.0" + npm-install-checks@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-4.0.0.tgz#a37facc763a2fde0497ef2c6d0ac7c3fbe00d7b4" @@ -4048,6 +4146,13 @@ npm-install-checks@^4.0.0: dependencies: semver "^7.1.1" +npm-install-checks@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-6.3.0.tgz#046552d8920e801fa9f919cad569545d60e826fe" + integrity sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw== + dependencies: + semver "^7.1.1" + npm-normalize-package-bin@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" @@ -4058,6 +4163,21 @@ npm-normalize-package-bin@^2.0.0: resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz#9447a1adaaf89d8ad0abe24c6c84ad614a675fff" integrity sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ== +npm-normalize-package-bin@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz#25447e32a9a7de1f51362c61a559233b89947832" + integrity sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ== + +npm-package-arg@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-10.1.0.tgz#827d1260a683806685d17193073cc152d3c7e9b1" + integrity sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA== + dependencies: + hosted-git-info "^6.0.0" + proc-log "^3.0.0" + semver "^7.3.5" + validate-npm-package-name "^5.0.0" + npm-package-arg@^8.0.1, npm-package-arg@^8.1.2, npm-package-arg@^8.1.5: version "8.1.5" resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.5.tgz#3369b2d5fe8fdc674baa7f1786514ddc15466e44" @@ -4077,6 +4197,13 @@ npm-packlist@^3.0.0: npm-bundled "^1.1.1" npm-normalize-package-bin "^1.0.1" +npm-packlist@^7.0.0: + version "7.0.4" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-7.0.4.tgz#033bf74110eb74daf2910dc75144411999c5ff32" + integrity sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q== + dependencies: + ignore-walk "^6.0.0" + npm-pick-manifest@^6.0.0, npm-pick-manifest@^6.1.0, npm-pick-manifest@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz#7b5484ca2c908565f43b7f27644f36bb816f5148" @@ -4087,6 +4214,16 @@ npm-pick-manifest@^6.0.0, npm-pick-manifest@^6.1.0, npm-pick-manifest@^6.1.1: npm-package-arg "^8.1.2" semver "^7.3.4" +npm-pick-manifest@^8.0.0: + version "8.0.2" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz#2159778d9c7360420c925c1a2287b5a884c713aa" + integrity sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg== + dependencies: + npm-install-checks "^6.0.0" + npm-normalize-package-bin "^3.0.0" + npm-package-arg "^10.0.0" + semver "^7.3.5" + npm-registry-fetch@^12.0.0, npm-registry-fetch@^12.0.1: version "12.0.2" resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-12.0.2.tgz#ae583bb3c902a60dae43675b5e33b5b1f6159f1e" @@ -4099,6 +4236,19 @@ npm-registry-fetch@^12.0.0, npm-registry-fetch@^12.0.1: minizlib "^2.1.2" npm-package-arg "^8.1.5" +npm-registry-fetch@^14.0.0: + version "14.0.5" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz#fe7169957ba4986a4853a650278ee02e568d115d" + integrity sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA== + dependencies: + make-fetch-happen "^11.0.0" + minipass "^5.0.0" + minipass-fetch "^3.0.0" + minipass-json-stream "^1.0.1" + minizlib "^2.1.2" + npm-package-arg "^10.0.0" + proc-log "^3.0.0" + npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" @@ -4126,11 +4276,6 @@ npmlog@^6.0.0: gauge "^4.0.3" set-blocking "^2.0.0" -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== - nyc@15.1.0: version "15.1.0" resolved "https://registry.yarnpkg.com/nyc/-/nyc-15.1.0.tgz#1335dae12ddc87b6e249d5a1994ca4bdaea75f02" @@ -4169,55 +4314,39 @@ object-assign@^4.1.1: resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-inspect@^1.12.2, object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - object-treeify@^1.1.33: version "1.1.33" resolved "https://registry.yarnpkg.com/object-treeify/-/object-treeify-1.1.33.tgz#f06fece986830a3cba78ddd32d4c11d1f76cdf40" integrity sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A== -object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - has-symbols "^1.0.3" - object-keys "^1.1.1" - -oclif@3.9.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/oclif/-/oclif-3.9.0.tgz#d52beb9300a60a660f897fe9ae810fffd48a1571" - integrity sha512-fsFyHVQYJdE50EcKrBjwzl2WT5sZUtTiRY1vqMwykgLFUDYrQS0lj7yqy2IgcPSmAWaLQryODdfBujCWOU98Ww== - dependencies: - "@oclif/core" "^2.8.4" - "@oclif/plugin-help" "^5.1.19" - "@oclif/plugin-not-found" "^2.3.7" - "@oclif/plugin-warn-if-update-available" "^2.0.14" +oclif@4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/oclif/-/oclif-4.0.3.tgz#2ff8fab10c29b2cd0bbf8e9c87640a64151b65ff" + integrity sha512-Bq7t1bJvAKYwW3DKQIzok3jkXv7yUIMneoSec1qUr9wfSqzRTZQB0UUDovwlT/L+3TBMVoRyw1WeX+YDvfRJNA== + dependencies: + "@oclif/core" "^3.0.4" + "@oclif/plugin-help" "^5.2.14" + "@oclif/plugin-not-found" "^2.3.32" + "@oclif/plugin-warn-if-update-available" "^3.0.0" + async-retry "^1.3.3" aws-sdk "^2.1231.0" - concurrently "^7.6.0" + change-case "^4" debug "^4.3.3" + eslint-plugin-perfectionist "^2.1.0" find-yarn-workspace-root "^2.0.0" fs-extra "^8.1" github-slugger "^1.5.0" got "^11" - lodash "^4.17.21" + lodash.template "^4.5.0" normalize-package-data "^3.0.3" semver "^7.3.8" - shelljs "^0.8.5" - tslib "^2.3.1" yeoman-environment "^3.15.1" yeoman-generator "^5.8.0" - yosay "^2.0.2" + +on-exit-leak-free@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz#fed195c9ebddb7d9e4c3842f93f281ac8dadd3b8" + integrity sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA== once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" @@ -4349,6 +4478,29 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +pac-proxy-agent@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz#6b9ddc002ec3ff0ba5fdf4a8a21d363bcc612d75" + integrity sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A== + dependencies: + "@tootallnate/quickjs-emscripten" "^0.23.0" + agent-base "^7.0.2" + debug "^4.3.4" + get-uri "^6.0.1" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.2" + pac-resolver "^7.0.0" + socks-proxy-agent "^8.0.2" + +pac-resolver@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-7.0.0.tgz#79376f1ca26baf245b96b34c339d79bff25e900c" + integrity sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg== + dependencies: + degenerator "^5.0.0" + ip "^1.1.8" + netmask "^2.0.2" + package-hash@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-4.0.0.tgz#3537f654665ec3cc38827387fc904c163c54f506" @@ -4384,10 +4536,34 @@ pacote@^12.0.0, pacote@^12.0.2: ssri "^8.0.1" tar "^6.1.0" -pad-component@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/pad-component/-/pad-component-0.0.1.tgz#ad1f22ce1bf0fdc0d6ddd908af17f351a404b8ac" - integrity sha512-8EKVBxCRSvLnsX1p2LlSFSH3c2/wuhY9/BXXWu8boL78FbVKqn2L5SpURt1x5iw6Gq8PTqJ7MdPoe5nCtX3I+g== +pacote@^15.2.0: + version "15.2.0" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-15.2.0.tgz#0f0dfcc3e60c7b39121b2ac612bf8596e95344d3" + integrity sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA== + dependencies: + "@npmcli/git" "^4.0.0" + "@npmcli/installed-package-contents" "^2.0.1" + "@npmcli/promise-spawn" "^6.0.1" + "@npmcli/run-script" "^6.0.0" + cacache "^17.0.0" + fs-minipass "^3.0.0" + minipass "^5.0.0" + npm-package-arg "^10.0.0" + npm-packlist "^7.0.0" + npm-pick-manifest "^8.0.0" + npm-registry-fetch "^14.0.0" + proc-log "^3.0.0" + promise-retry "^2.0.1" + read-package-json "^6.0.0" + read-package-json-fast "^3.0.0" + sigstore "^1.3.0" + ssri "^10.0.0" + tar "^6.1.11" + +pako@~1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== param-case@^3.0.4: version "3.0.4" @@ -4421,7 +4597,7 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" -parse-json@^5.0.0: +parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -4440,12 +4616,12 @@ pascal-case@^3.1.2: tslib "^2.0.3" password-prompt@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/password-prompt/-/password-prompt-1.1.2.tgz#85b2f93896c5bd9e9f2d6ff0627fa5af3dc00923" - integrity sha512-bpuBhROdrhuN3E7G/koAju0WjVw9/uQOG5Co5mokNj0MiOSBVZS1JTwM4zl55hu0WFmIEFvO9cU9sJQiBIYeIA== + version "1.1.3" + resolved "https://registry.yarnpkg.com/password-prompt/-/password-prompt-1.1.3.tgz#05e539f4e7ca4d6c865d479313f10eb9db63ee5f" + integrity sha512-HkrjG2aJlvF0t2BMH0e2LB/EHf3Lcq3fNMzy4GYHcQblAvOl+QQji1Lx7WRBMqpVK8p+KR7bCg7oqAMXtdgqyw== dependencies: - ansi-escapes "^3.1.0" - cross-spawn "^6.0.5" + ansi-escapes "^4.3.2" + cross-spawn "^7.0.3" path-case@^3.0.4: version "3.0.4" @@ -4465,11 +4641,6 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== - path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" @@ -4480,6 +4651,14 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -4510,6 +4689,56 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== +pino-abstract-transport@^1.0.0, pino-abstract-transport@v1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-1.1.0.tgz#083d98f966262164504afb989bccd05f665937a8" + integrity sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA== + dependencies: + readable-stream "^4.0.0" + split2 "^4.0.0" + +pino-pretty@^10.2.3: + version "10.2.3" + resolved "https://registry.yarnpkg.com/pino-pretty/-/pino-pretty-10.2.3.tgz#db539c796a1421fd4d130734fa994f5a26027783" + integrity sha512-4jfIUc8TC1GPUfDyMSlW1STeORqkoxec71yhxIpLDQapUu8WOuoz2TTCoidrIssyz78LZC69whBMPIKCMbi3cw== + dependencies: + colorette "^2.0.7" + dateformat "^4.6.3" + fast-copy "^3.0.0" + fast-safe-stringify "^2.1.1" + help-me "^4.0.1" + joycon "^3.1.1" + minimist "^1.2.6" + on-exit-leak-free "^2.1.0" + pino-abstract-transport "^1.0.0" + pump "^3.0.0" + readable-stream "^4.0.0" + secure-json-parse "^2.4.0" + sonic-boom "^3.0.0" + strip-json-comments "^3.1.1" + +pino-std-serializers@^6.0.0: + version "6.2.2" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz#d9a9b5f2b9a402486a5fc4db0a737570a860aab3" + integrity sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA== + +pino@^8.16.0: + version "8.16.1" + resolved "https://registry.yarnpkg.com/pino/-/pino-8.16.1.tgz#dcaf82764b1a27f24101317cdd6453e96290f1d9" + integrity sha512-3bKsVhBmgPjGV9pyn4fO/8RtoVDR8ssW1ev819FsRXlRNgW8gR/9Kx+gCK4UPWd4JjrRDLWpzd/pb1AyWm3MGA== + dependencies: + atomic-sleep "^1.0.0" + fast-redact "^3.1.1" + on-exit-leak-free "^2.1.0" + pino-abstract-transport v1.1.0 + pino-std-serializers "^6.0.0" + process-warning "^2.0.0" + quick-format-unescaped "^4.0.3" + real-require "^0.2.0" + safe-stable-stringify "^2.3.1" + sonic-boom "^3.7.0" + thread-stream "^2.0.0" + pkg-dir@^4.1.0, pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" @@ -4518,15 +4747,20 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: find-up "^4.0.0" preferred-pm@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/preferred-pm/-/preferred-pm-3.0.3.tgz#1b6338000371e3edbce52ef2e4f65eb2e73586d6" - integrity sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ== + version "3.1.2" + resolved "https://registry.yarnpkg.com/preferred-pm/-/preferred-pm-3.1.2.tgz#aedb70550734a574dffcbf2ce82642bd1753bdd6" + integrity sha512-nk7dKrcW8hfCZ4H6klWcdRknBOXWzNQByJ0oJyX97BOupsYD+FzLS4hflgEu/uPUEHZCuRfMxzCBsuWd7OzT8Q== dependencies: find-up "^5.0.0" find-yarn-workspace-root2 "1.2.16" path-exists "^4.0.0" which-pm "2.0.0" +prettier@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.1.0.tgz#c6d16474a5f764ea1a4a373c593b779697744d5e" + integrity sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw== + pretty-bytes@^5.3.0: version "5.6.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" @@ -4537,6 +4771,11 @@ proc-log@^1.0.0: resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-1.0.0.tgz#0d927307401f69ed79341e83a0b2c9a13395eb77" integrity sha512-aCk8AO51s+4JyuYGg3Q/a6gnrlDO09NpVWePtjp7xwphcoQ04x5WAfCyugcsbLooWcMJ87CLkD4+604IckEdhg== +proc-log@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8" + integrity sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A== + process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -4549,6 +4788,16 @@ process-on-spawn@^1.0.0: dependencies: fromentries "^1.2.0" +process-warning@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-2.2.0.tgz#008ec76b579820a8e5c35d81960525ca64feb626" + integrity sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + progress@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" @@ -4560,9 +4809,9 @@ promise-all-reject-late@^1.0.0: integrity sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw== promise-call-limit@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-call-limit/-/promise-call-limit-1.0.1.tgz#4bdee03aeb85674385ca934da7114e9bcd3c6e24" - integrity sha512-3+hgaa19jzCGLuSCbieeRsu5C2joKfYn8pY6JAuXFRVfF4IO+L7UPpFWNTeWT9pM7uhskvbPPd/oEOktCn317Q== + version "1.0.2" + resolved "https://registry.yarnpkg.com/promise-call-limit/-/promise-call-limit-1.0.2.tgz#f64b8dd9ef7693c9c7613e7dfe8d6d24de3031ea" + integrity sha512-1vTUnfI2hzui8AEIixbdAJlFY4LFDXqQswy/2eOlThAscXCY4It8FdVuI0fMJGAB2aWGbdQf/gv0skKYXmdrHA== promise-inflight@^1.0.1: version "1.0.1" @@ -4577,12 +4826,30 @@ promise-retry@^2.0.1: err-code "^2.0.2" retry "^0.12.0" -propagate@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/propagate/-/propagate-2.0.1.tgz#40cdedab18085c792334e64f0ac17256d38f9a45" - integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag== +proper-lockfile@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-4.1.2.tgz#c8b9de2af6b2f1601067f98e01ac66baa223141f" + integrity sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA== + dependencies: + graceful-fs "^4.2.4" + retry "^0.12.0" + signal-exit "^3.0.2" -proxy-from-env@1.1.0: +proxy-agent@6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-6.3.1.tgz#40e7b230552cf44fd23ffaf7c59024b692612687" + integrity sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ== + dependencies: + agent-base "^7.0.2" + debug "^4.3.4" + http-proxy-agent "^7.0.0" + https-proxy-agent "^7.0.2" + lru-cache "^7.14.1" + pac-proxy-agent "^7.0.1" + proxy-from-env "^1.1.0" + socks-proxy-agent "^8.0.2" + +proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== @@ -4606,37 +4873,30 @@ punycode@1.3.2: integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== -puppeteer-core@19.2.0: - version "19.2.0" - resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-19.2.0.tgz#b2502a74b01725bfdd92f984faa4915166aee996" - integrity sha512-wdoZDzf46y1ScpPEUDAzIWDmvG272BbdqSvDMvtYNjy2UJZT/j5OS5k813o2lfT4HtOle79eByCLs24iXbat1g== +puppeteer-core@21.5.1: + version "21.5.1" + resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-21.5.1.tgz#36b0a4b3838f9109423b6e4cb56e1f21f8fbca4f" + integrity sha512-u6c3SZKAOaOQogaTkQvllxT/o2PP16wkbrUWINtMhfvrB4ko+xwqC1pb+vyCPMmNUh3N/CX5YGqb3DWx2fUPSQ== dependencies: - cross-fetch "3.1.5" + "@puppeteer/browsers" "1.8.0" + chromium-bidi "0.4.33" + cross-fetch "4.0.0" debug "4.3.4" - devtools-protocol "0.0.1056733" - extract-zip "2.0.1" - https-proxy-agent "5.0.1" - proxy-from-env "1.1.0" - rimraf "3.0.2" - tar-fs "2.1.1" - unbzip2-stream "1.4.3" - ws "8.10.0" + devtools-protocol "0.0.1203626" + ws "8.14.2" -puppeteer@19.2.0: - version "19.2.0" - resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-19.2.0.tgz#6d39c6b6da4a648928d8dc736b864de493f175f7" - integrity sha512-rhr5ery8htpOTikmm/wrDU707wtmJ7ccX2WLkBf0A8eYYpscck5/iz04/fHOiIRWMFfnYOvaO9wNb4jcO3Mjyg== +puppeteer@21.5.1: + version "21.5.1" + resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-21.5.1.tgz#7607748b8c5e487edded2105551968a944e9436c" + integrity sha512-NkI06BXckVZeZUkODK+BbgGelQSu7uYEp9PaJDozxpwNRFDYoVfHQvd2G4dERoLdP6+qx4EBPwEhk4dEkQc2Kg== dependencies: - cosmiconfig "7.0.1" - devtools-protocol "0.0.1056733" - https-proxy-agent "5.0.1" - progress "2.0.3" - proxy-from-env "1.1.0" - puppeteer-core "19.2.0" + "@puppeteer/browsers" "1.8.0" + cosmiconfig "8.3.6" + puppeteer-core "21.5.1" querystring@0.2.0: version "0.2.0" @@ -4653,6 +4913,16 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +queue-tick@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142" + integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag== + +quick-format-unescaped@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" + integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== + quick-lru@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" @@ -4678,6 +4948,24 @@ read-package-json-fast@^2.0.1, read-package-json-fast@^2.0.2, read-package-json- json-parse-even-better-errors "^2.3.0" npm-normalize-package-bin "^1.0.1" +read-package-json-fast@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz#394908a9725dc7a5f14e70c8e7556dff1d2b1049" + integrity sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw== + dependencies: + json-parse-even-better-errors "^3.0.0" + npm-normalize-package-bin "^3.0.0" + +read-package-json@^6.0.0: + version "6.0.4" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-6.0.4.tgz#90318824ec456c287437ea79595f4c2854708836" + integrity sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw== + dependencies: + glob "^10.2.2" + json-parse-even-better-errors "^3.0.0" + normalize-package-data "^5.0.0" + npm-normalize-package-bin "^3.0.0" + read-pkg-up@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" @@ -4697,10 +4985,10 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.3.5: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== +readable-stream@^2.0.2, readable-stream@^2.3.5, readable-stream@~2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -4710,21 +4998,25 @@ readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.5, readable string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== +readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== dependencies: inherits "^2.0.3" string_decoder "^1.1.1" util-deprecate "^1.0.1" -readdir-glob@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/readdir-glob/-/readdir-glob-1.1.2.tgz#b185789b8e6a43491635b6953295c5c5e3fd224c" - integrity sha512-6RLVvwJtVwEDfPdn6X6Ille4/lxGl0ATOY4FN/B9nxQcgOazvvI0nodiD19ScKq0PvA/29VpaOQML36o5IzZWA== +readable-stream@^4.0.0, readable-stream@^4.3.0: + version "4.4.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.4.2.tgz#e6aced27ad3b9d726d8308515b9a1b98dc1b9d13" + integrity sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA== dependencies: - minimatch "^5.1.0" + abort-controller "^3.0.0" + buffer "^6.0.3" + events "^3.3.0" + process "^0.11.10" + string_decoder "^1.3.0" readdir-scoped-modules@^1.1.0: version "1.1.0" @@ -4743,6 +5035,11 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +real-require@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.2.0.tgz#209632dea1810be2ae063a6ac084fee7e33fba78" + integrity sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg== + rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -4757,19 +5054,15 @@ redeyed@~2.1.0: dependencies: esprima "~4.0.0" -regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4: - version "0.13.10" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz#ed07b19616bcbec5da6274ebc75ae95634bfc2ee" - integrity sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw== +regenerator-runtime@^0.13.3: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== -regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== release-zalgo@^1.0.0: version "1.0.0" @@ -4824,11 +5117,11 @@ resolve-from@^5.0.0: integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== resolve@^1.1.6, resolve@^1.10.0: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== dependencies: - is-core-module "^2.9.0" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -4847,35 +5140,28 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" +retry@0.13.1, retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== -retry@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: +rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" -rimraf@~2.4.0: - version "2.4.5" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da" - integrity sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ== - dependencies: - glob "^6.0.1" - run-async@^2.0.0, run-async@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" @@ -4895,14 +5181,14 @@ rxjs@^6.6.0: dependencies: tslib "^1.9.0" -rxjs@^7.0.0, rxjs@^7.5.5: - version "7.5.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.7.tgz#2ec0d57fdc89ece220d2e702730ae8f1e49def39" - integrity sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA== +rxjs@^7.2.0, rxjs@^7.5.5: + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== dependencies: tslib "^2.1.0" -safe-buffer@*, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: +safe-buffer@*, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -4912,19 +5198,10 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-json-stringify@~1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd" - integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg== - -safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-regex "^1.1.4" +safe-stable-stringify@^2.3.1: + version "2.4.3" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" + integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" @@ -4937,29 +5214,34 @@ sax@1.2.1: integrity sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA== sax@>=0.6.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + version "1.3.0" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0" + integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA== scoped-regex@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/scoped-regex/-/scoped-regex-2.1.0.tgz#7b9be845d81fd9d21d1ec97c61a0b7cf86d2015f" integrity sha512-g3WxHrqSWCZHGHlSrF51VXFdjImhwvH8ZO/pryFH56Qi0cDsZfylQa/t0jCzVQFNbNvM00HfHjkDPEuarKDSWQ== -"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== +secure-json-parse@^2.4.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862" + integrity sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw== -semver@^6.0.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +"semver@2 || 3 || 4 || 5": + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: - version "7.3.8" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== +semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" @@ -4989,12 +5271,20 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== dependencies: - shebang-regex "^1.0.0" + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== shebang-command@^2.0.0: version "2.0.0" @@ -5003,21 +5293,11 @@ shebang-command@^2.0.0: dependencies: shebang-regex "^3.0.0" -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== - shebang-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@^1.7.3: - version "1.7.4" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.4.tgz#33fe15dee71ab2a81fcbd3a52106c5cfb9fb75d8" - integrity sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw== - shelljs@^0.8.5: version "0.8.5" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" @@ -5027,33 +5307,41 @@ shelljs@^0.8.5: interpret "^1.0.0" rechoir "^0.6.2" -shx@^0.3.3: - version "0.3.4" - resolved "https://registry.yarnpkg.com/shx/-/shx-0.3.4.tgz#74289230b4b663979167f94e1935901406e40f02" - integrity sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g== - dependencies: - minimist "^1.2.3" - shelljs "^0.8.5" - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +sigstore@^1.3.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-1.9.0.tgz#1e7ad8933aa99b75c6898ddd0eeebc3eb0d59875" + integrity sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A== + dependencies: + "@sigstore/bundle" "^1.1.0" + "@sigstore/protobuf-specs" "^0.2.0" + "@sigstore/sign" "^1.0.0" + "@sigstore/tuf" "^1.0.3" + make-fetch-happen "^11.0.1" + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + smart-buffer@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" @@ -5085,7 +5373,16 @@ socks-proxy-agent@^7.0.0: debug "^4.3.3" socks "^2.6.2" -socks@^2.6.2: +socks-proxy-agent@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz#5acbd7be7baf18c46a3f293a840109a430a640ad" + integrity sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g== + dependencies: + agent-base "^7.0.2" + debug "^4.3.4" + socks "^2.7.1" + +socks@^2.6.2, socks@^2.7.1: version "2.7.1" resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== @@ -5093,6 +5390,13 @@ socks@^2.6.2: ip "^2.0.0" smart-buffer "^4.2.0" +sonic-boom@^3.0.0, sonic-boom@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-3.7.0.tgz#b4b7b8049a912986f4a92c51d4660b721b11f2f2" + integrity sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg== + dependencies: + atomic-sleep "^1.0.0" + sort-keys@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-4.2.0.tgz#6b7638cee42c506fff8c1cecde7376d21315be18" @@ -5100,16 +5404,11 @@ sort-keys@^4.2.0: dependencies: is-plain-obj "^2.0.0" -source-map@^0.6.1: +source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -spawn-command@^0.0.2-1: - version "0.0.2-1" - resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" - integrity sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg== - spawn-wrap@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-2.0.0.tgz#103685b8b8f9b79771318827aa78650a610d457e" @@ -5123,9 +5422,9 @@ spawn-wrap@^2.0.0: which "^2.0.1" spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" @@ -5144,15 +5443,27 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.12" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz#69077835abe2710b65f03969898b6637b505a779" - integrity sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA== + version "3.0.16" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz#a14f64e0954f6e25cc6587bd4f392522db0d998f" + integrity sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw== + +split2@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +ssri@^10.0.0: + version "10.0.5" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.5.tgz#e49efcd6e36385196cb515d3a2ad6c3f0265ef8c" + integrity sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A== + dependencies: + minipass "^7.0.3" + ssri@^8.0.0, ssri@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" @@ -5167,24 +5478,15 @@ ssri@^9.0.0: dependencies: minipass "^3.1.1" -stdout-stderr@^0.1.9: - version "0.1.13" - resolved "https://registry.yarnpkg.com/stdout-stderr/-/stdout-stderr-0.1.13.tgz#54e3450f3d4c54086a49c0c7f8786a44d1844b6f" - integrity sha512-Xnt9/HHHYfjZ7NeQLvuQDyL1LnbsbddgMFKCuaQKwGCdJm8LnstZIXop+uOY36UR1UXXoHXfMbC1KlVdVd2JLA== - dependencies: - debug "^4.1.1" - strip-ansi "^6.0.0" - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== +streamx@^2.15.0: + version "2.15.5" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.15.5.tgz#87bcef4dc7f0b883f9359671203344a4e004c7f1" + integrity sha512-9thPGMkKC2GctCzyCUjME3yR03x2xNo0GPKGkRw2UMYN+gqWa9uqpyNWhmsNCutU5zHmkUum0LsCRQTXUgUCAg== dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" + fast-fifo "^1.1.0" + queue-tick "^1.0.1" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -5193,33 +5495,16 @@ string-width@^1.0.1: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string.prototype.trimend@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" - integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - -string.prototype.trimstart@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" - integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" -string_decoder@^1.1.1: +string_decoder@^1.1.1, string_decoder@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== @@ -5233,27 +5518,20 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow== - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + strip-bom-buf@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz#1cb45aaf57530f4caf86c7f75179d2c9a51dd572" @@ -5291,23 +5569,18 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-json-comments@3.1.1: +strip-json-comments@3.1.1, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -supports-color@8.1.1, supports-color@^8.1.0, supports-color@^8.1.1: +supports-color@8.1.1, supports-color@^8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g== - supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -5335,43 +5608,32 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -taketalk@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/taketalk/-/taketalk-1.0.0.tgz#b4d4f0deed206ae7df775b129ea2ca6de52f26dd" - integrity sha512-kS7E53It6HA8S1FVFBWP7HDwgTiJtkmYk7TsowGlizzVrivR1Mf9mgjXHY1k7rOfozRVMZSfwjB3bevO4QEqpg== - dependencies: - get-stdin "^4.0.1" - minimist "^1.1.0" - -tar-fs@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" - integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== +tar-fs@3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.4.tgz#a21dc60a2d5d9f55e0089ccd78124f1d3771dbbf" + integrity sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w== dependencies: - chownr "^1.1.1" mkdirp-classic "^0.5.2" pump "^3.0.0" - tar-stream "^2.1.4" + tar-stream "^3.1.5" -tar-stream@^2.1.4, tar-stream@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== +tar-stream@^3.1.5: + version "3.1.6" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.6.tgz#6520607b55a06f4a2e2e04db360ba7d338cc5bab" + integrity sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg== dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" + b4a "^1.6.4" + fast-fifo "^1.2.0" + streamx "^2.15.0" tar@^6.0.2, tar@^6.1.0, tar@^6.1.11, tar@^6.1.2: - version "6.1.11" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" - integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== + version "6.2.0" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" + integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" - minipass "^3.0.0" + minipass "^5.0.0" minizlib "^2.1.1" mkdirp "^1.0.3" yallist "^4.0.0" @@ -5391,9 +5653,16 @@ text-table@^0.2.0: integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== textextensions@^5.12.0, textextensions@^5.13.0: - version "5.15.0" - resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-5.15.0.tgz#4bb3296ad6fc111cf4b39c589dd028d8aaaf7060" - integrity sha512-MeqZRHLuaGamUXGuVn2ivtU3LA3mLCCIO5kUGoohTCoGmCBg/+8yPhWVX9WSl9telvVd8erftjFk9Fwb2dD6rw== + version "5.16.0" + resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-5.16.0.tgz#57dd60c305019bba321e848b1fdf0f99bfa59ec1" + integrity sha512-7D/r3s6uPZyU//MCYrX6I14nzauDwJ5CxazouuRGNuvSCihW87ufN6VLoROLCrHg6FblLuJrT6N2BVaPVzqElw== + +thread-stream@^2.0.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-2.4.1.tgz#6d588b14f0546e59d3f306614f044bc01ce43351" + integrity sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg== + dependencies: + real-require "^0.2.0" through@^2.3.6, through@^2.3.8: version "2.3.8" @@ -5420,9 +5689,9 @@ to-regex-range@^5.0.1: is-number "^7.0.0" tough-cookie@*: - version "4.1.2" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874" - integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ== + version "4.1.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" + integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== dependencies: psl "^1.1.33" punycode "^2.1.1" @@ -5434,16 +5703,16 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== -tree-kill@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" - integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== - treeverse@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/treeverse/-/treeverse-1.0.4.tgz#a6b0ebf98a1bca6846ddc7ecbc900df08cb9cd5f" integrity sha512-whw60l7r+8ZU8Tu/Uc2yxtc4ZTZbR/PF3u1IPNKGQ6p8EICLb3Z2lAgoqw9bqYd8IkgnsaOcLzYHFckjqNsf0g== +ts-api-utils@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" + integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== + ts-node@10.9.1, ts-node@^10.9.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" @@ -5463,12 +5732,12 @@ ts-node@10.9.1, ts-node@^10.9.1: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -ts-retry-promise@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/ts-retry-promise/-/ts-retry-promise-0.7.0.tgz#08f2dcbbf5d2981495841cb63389a268324e8147" - integrity sha512-x6yWZXC4BfXy4UyMweOFvbS1yJ/Y5biSz/mEPiILtJZLrqD3ZxIpzVOGGgifHHdaSe3WxzFRtsRbychI6zofOg== +ts-retry-promise@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ts-retry-promise/-/ts-retry-promise-0.7.1.tgz#176d6eee6415f07b6c7c286d3657355e284a6906" + integrity sha512-NhHOCZ2AQORvH42hOPO5UZxShlcuiRtm7P2jIq2L2RY3PBxw2mLnUsEdHrIslVBFya1v5aZmrR55lWkzo13LrQ== -tslib@2.4.0, tslib@^2, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.2.0, tslib@^2.3.1: +tslib@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== @@ -5478,10 +5747,19 @@ tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.4.1, tslib@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== +tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.5.0, tslib@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + +tuf-js@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-1.1.7.tgz#21b7ae92a9373015be77dfe0cb282a80ec3bbe43" + integrity sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg== + dependencies: + "@tufjs/models" "1.0.4" + debug "^4.3.4" + make-fetch-happen "^11.1.1" tunnel-agent@*, tunnel-agent@^0.6.0: version "0.6.0" @@ -5512,20 +5790,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@5.0.4: - version "5.0.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" - integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== - -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" +typescript@5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" + integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== unbzip2-stream@1.4.3: version "1.4.3" @@ -5535,6 +5803,11 @@ unbzip2-stream@1.4.3: buffer "^5.2.1" through "^2.3.8" +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + unique-filename@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" @@ -5549,6 +5822,13 @@ unique-filename@^2.0.0: dependencies: unique-slug "^3.0.0" +unique-filename@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea" + integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g== + dependencies: + unique-slug "^4.0.0" + unique-slug@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" @@ -5563,6 +5843,13 @@ unique-slug@^3.0.0: dependencies: imurmurhash "^0.1.4" +unique-slug@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3" + integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ== + dependencies: + imurmurhash "^0.1.4" + universal-user-agent@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" @@ -5578,20 +5865,15 @@ universalify@^0.2.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - untildify@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== -update-browserslist-db@^1.0.9: - version "1.0.10" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== +update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== dependencies: escalade "^3.1.1" picocolors "^1.0.0" @@ -5633,21 +5915,25 @@ url@0.10.3: punycode "1.3.2" querystring "0.2.0" +urlpattern-polyfill@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz#bc7e386bb12fd7898b58d1509df21d3c29ab3460" + integrity sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g== + util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== util@^0.12.4: - version "0.12.4" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253" - integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw== + version "0.12.5" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== dependencies: inherits "^2.0.3" is-arguments "^1.0.4" is-generator-function "^1.0.7" is-typed-array "^1.1.3" - safe-buffer "^5.1.2" which-typed-array "^1.1.2" uuid@8.0.0: @@ -5665,7 +5951,7 @@ v8-compile-cache-lib@^3.0.1: resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== -validate-npm-package-license@^3.0.1: +validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== @@ -5680,6 +5966,13 @@ validate-npm-package-name@^3.0.0: dependencies: builtins "^1.0.3" +validate-npm-package-name@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz#f16afd48318e6f90a1ec101377fa0384cfc8c713" + integrity sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ== + dependencies: + builtins "^5.0.0" + vinyl-file@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/vinyl-file/-/vinyl-file-3.0.0.tgz#b104d9e4409ffa325faadd520642d0a3b488b365" @@ -5742,21 +6035,10 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== + version "2.0.1" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" + integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== which-pm@2.0.0: version "2.0.0" @@ -5766,24 +6048,16 @@ which-pm@2.0.0: load-yaml-file "^0.2.0" path-exists "^4.0.0" -which-typed-array@^1.1.2: - version "1.1.8" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.8.tgz#0cfd53401a6f334d90ed1125754a42ed663eb01f" - integrity sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw== +which-typed-array@^1.1.11, which-typed-array@^1.1.2: + version "1.1.13" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" + integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== dependencies: available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - es-abstract "^1.20.0" + call-bind "^1.0.4" for-each "^0.3.3" + gopd "^1.0.1" has-tostringtag "^1.0.0" - is-typed-array "^1.1.9" - -which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" which@^2.0.1, which@^2.0.2: version "2.0.2" @@ -5792,6 +6066,13 @@ which@^2.0.1, which@^2.0.2: dependencies: isexe "^2.0.0" +which@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/which/-/which-3.0.1.tgz#89f1cd0c23f629a8105ffe69b8172791c87b4be1" + integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg== + dependencies: + isexe "^2.0.0" + wide-align@^1.1.2, wide-align@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" @@ -5816,15 +6097,16 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw== +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" -wrap-ansi@^6.2.0: +wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== @@ -5833,14 +6115,14 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" wrappy@1: version "1.0.2" @@ -5865,23 +6147,15 @@ write-file-atomic@^4.0.0: imurmurhash "^0.1.4" signal-exit "^3.0.7" -ws@8.10.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.10.0.tgz#00a28c09dfb76eae4eb45c3b565f771d6951aa51" - integrity sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw== - -xml2js@0.4.19: - version "0.4.19" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" - integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== - dependencies: - sax ">=0.6.0" - xmlbuilder "~9.0.1" +ws@8.14.2: + version "8.14.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" + integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== -xml2js@^0.4.22: - version "0.4.23" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" - integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== +xml2js@0.5.0, xml2js@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.5.0.tgz#d9440631fbb2ed800203fad106f2724f62c493b7" + integrity sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA== dependencies: sax ">=0.6.0" xmlbuilder "~11.0.0" @@ -5891,11 +6165,6 @@ xmlbuilder@~11.0.0: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== -xmlbuilder@~9.0.1: - version "9.0.7" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" - integrity sha512-7YXTQc3P2l9+0rjaUbLwMKRhtmwg1M1eDf6nag7urC7pIPYLD9W/jmzQ4ptRSUbodw5S0jfoGTflLemQibSpeQ== - xmlcreate@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-2.0.4.tgz#0c5ab0f99cdd02a81065fa9cd8f8ae87624889be" @@ -5911,16 +6180,16 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^1.10.0: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - yargs-parser@20.2.4: version "20.2.4" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" @@ -5939,7 +6208,7 @@ yargs-parser@^20.2.2: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs-parser@^21.0.0: +yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== @@ -5967,6 +6236,19 @@ yargs@16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yargs@17.7.2: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + yargs@^15.0.2: version "15.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" @@ -5984,19 +6266,6 @@ yargs@^15.0.2: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^17.3.1: - version "17.6.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.0.tgz#e134900fc1f218bc230192bdec06a0a5f973e46c" - integrity sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.0.0" - yauzl@^2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" @@ -6006,9 +6275,9 @@ yauzl@^2.10.0: fd-slicer "~1.1.0" yeoman-environment@^3.15.1: - version "3.16.1" - resolved "https://registry.yarnpkg.com/yeoman-environment/-/yeoman-environment-3.16.1.tgz#526fe768812a5ab2cab167653776437db844accf" - integrity sha512-imr+wDb7YdWrfy8lnesYnHTsv3oEsu3UWyq/dQ1fp9V/soZfLZJ5HqendQ2xu3Z27FQcZrxQcGR07nOVonj32Q== + version "3.19.3" + resolved "https://registry.yarnpkg.com/yeoman-environment/-/yeoman-environment-3.19.3.tgz#49c2339805fdf695fac42c88334a1daa94ee8b6c" + integrity sha512-/+ODrTUHtlDPRH9qIC0JREH8+7nsRcjDl3Bxn2Xo/rvAaVvixH5275jHwg0C85g4QsF4P6M2ojfScPPAl+pLAg== dependencies: "@npmcli/arborist" "^4.0.4" are-we-there-yet "^2.0.0" @@ -6040,6 +6309,7 @@ yeoman-environment@^3.15.1: pacote "^12.0.2" preferred-pm "^3.0.3" pretty-bytes "^5.3.0" + readable-stream "^4.3.0" semver "^7.1.3" slash "^3.0.0" strip-ansi "^6.0.0" @@ -6048,9 +6318,9 @@ yeoman-environment@^3.15.1: untildify "^4.0.0" yeoman-generator@^5.8.0: - version "5.8.0" - resolved "https://registry.yarnpkg.com/yeoman-generator/-/yeoman-generator-5.8.0.tgz#a1951ce0d95555f94adc5975a517d4741b5ce24d" - integrity sha512-dsrwFn9/c2/MOe80sa2nKfbZd/GaPTgmmehdgkFifs1VN/I7qPsW2xcBfvSkHNGK+PZly7uHyH8kaVYSFNUDhQ== + version "5.10.0" + resolved "https://registry.yarnpkg.com/yeoman-generator/-/yeoman-generator-5.10.0.tgz#0dde5be9d815b01f77a7e77ee6f9047edcbeca04" + integrity sha512-iDUKykV7L4nDNzeYSedRmSeJ5eMYFucnKDi6KN1WNASXErgPepKqsQw55TgXPHnmpcyOh2Dd/LAZkyc+f0qaAw== dependencies: chalk "^4.1.0" dargs "^7.0.0" @@ -6060,6 +6330,7 @@ yeoman-generator@^5.8.0: lodash "^4.17.11" mem-fs-editor "^9.0.0" minimist "^1.2.5" + pacote "^15.2.0" read-pkg-up "^7.0.1" run-async "^2.0.0" semver "^7.2.1" @@ -6076,27 +6347,3 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -yosay@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/yosay/-/yosay-2.0.2.tgz#a7017e764cd88d64a1ae64812201de5b157adf6d" - integrity sha512-avX6nz2esp7IMXGag4gu6OyQBsMh/SEn+ZybGu3yKPlOTE6z9qJrzG/0X5vCq/e0rPFy0CUYCze0G5hL310ibA== - dependencies: - ansi-regex "^2.0.0" - ansi-styles "^3.0.0" - chalk "^1.0.0" - cli-boxes "^1.0.0" - pad-component "0.0.1" - string-width "^2.0.0" - strip-ansi "^3.0.0" - taketalk "^1.0.0" - wrap-ansi "^2.0.0" - -zip-stream@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-4.1.0.tgz#51dd326571544e36aa3f756430b313576dc8fc79" - integrity sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A== - dependencies: - archiver-utils "^2.1.0" - compress-commons "^4.1.0" - readable-stream "^3.6.0"