diff --git a/.eslintrc.yml b/.eslintrc.yml index e2d833ce5..1717fe0c4 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -1,13 +1,24 @@ extends: - - standard-with-typescript - - "plugin:prettier/recommended" + - 'eslint:recommended' + - 'plugin:import/typescript' + - 'plugin:@typescript-eslint/eslint-recommended' + - 'plugin:@typescript-eslint/recommended' + - 'plugin:prettier/recommended' + - prettier +parser: '@typescript-eslint/parser' parserOptions: project: './tsconfig.json' +plugins: + - import + - node + - '@typescript-eslint' + - prettier rules: - prettier/prettier: - - error - - trailingComma: es5 - singleQuote: true - semi: false + 'prettier/prettier': 2 # requires strictNullChecks compiler option, produces many errors with messages objects '@typescript-eslint/strict-boolean-expressions': off + '@typescript-eslint/no-explicit-any': off + '@typescript-eslint/no-inferrable-types': off + '@typescript-eslint/no-empty-function': off + '@typescript-eslint/ban-types': off + '@typescript-eslint/no-unused-vars': off diff --git a/.gitattributes b/.gitattributes index fcadb2cf9..7041a5c2e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,3 @@ * text eol=lf +*.gif binary +*.png binary diff --git a/.github/workflows/build.yml b/.github/workflows/build.yaml similarity index 70% rename from .github/workflows/build.yml rename to .github/workflows/build.yaml index 06ccb6867..c6f5cdfcf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yaml @@ -3,7 +3,13 @@ name: Build -on: [push, pull_request] +on: + push: + branches: + - main + pull_request: + branches: + - main jobs: test: @@ -13,7 +19,7 @@ jobs: os: - ubuntu-latest - windows-latest - node-version: [10.x, 12.x, 14.x, 15.x] + node-version: [12.x, 14.x, 16.x] fail-fast: false steps: @@ -22,8 +28,8 @@ jobs: uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} - - run: yarn install - - run: yarn test + - run: npm i -g npm@7 + - run: npm install-test coverage: runs-on: ubuntu-latest @@ -31,12 +37,16 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: 14.x - - run: yarn install - - run: yarn test-coverage + node-version: 16.x + - run: npm install + - run: npm run test-coverage - uses: coverallsapp/github-action@master with: github-token: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/upload-artifact@v2 + with: + name: reports + path: reports audit-dependencies: runs-on: ubuntu-latest @@ -44,5 +54,5 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: 14.x - - run: yarn audit + node-version: 16.x + - run: npm audit --groups dependencies diff --git a/.github/workflows/release-github.yaml b/.github/workflows/release-github.yaml new file mode 100644 index 000000000..4a882ad7b --- /dev/null +++ b/.github/workflows/release-github.yaml @@ -0,0 +1,18 @@ +name: Release GitHub + +on: + push: + branches: [release/*] + +jobs: + create-github-release: + name: Create GitHub Release and Git tag + runs-on: ubuntu-latest + environment: Release + permissions: + contents: write + steps: + - uses: actions/checkout@v2 + - uses: cucumber/action-create-github-release@v1.1.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-npm.yaml b/.github/workflows/release-npm.yaml new file mode 100644 index 000000000..896127c17 --- /dev/null +++ b/.github/workflows/release-npm.yaml @@ -0,0 +1,22 @@ +name: Release NPM + +on: + push: + branches: [release/*] + +jobs: + publish-npm: + name: Publish NPM module + runs-on: ubuntu-latest + environment: Release + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: '16' + cache: 'npm' + cache-dependency-path: package-lock.json + - run: npm install-test + - uses: cucumber/action-publish-npm@v1.0.0 + with: + npm-token: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index 9089df5c6..e83be239a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,11 +4,13 @@ .nyc_output/ @rerun.txt coverage/ -html-formatter.html lib/ -messages.ndjson node_modules tmp/ -usage.txt +reports/*.html +reports/*.ndjson +reports/*.txt yarn-error.log .vscode +.DS_Store +src/version.ts diff --git a/.mocharc.yml b/.mocharc.yml index 09b9087a2..b4eac47fb 100644 --- a/.mocharc.yml +++ b/.mocharc.yml @@ -2,6 +2,8 @@ colors: true file: - test/test_helper.ts full-trace: true +forbid-only: true +forbid-pending: true recursive: true reporter: dot require: 'ts-node/register' diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..503b5e4b8 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "trailingComma": "es5", + "singleQuote": true, + "semi": false +} diff --git a/.whitesource b/.whitesource deleted file mode 100644 index db4b0fec8..000000000 --- a/.whitesource +++ /dev/null @@ -1,15 +0,0 @@ -{ - "scanSettings": { - "configMode": "AUTO", - "configExternalURL": "", - "projectToken": "", - "baseBranches": [] - }, - "checkRunSettings": { - "vulnerableCheckRunConclusionLevel": "failure", - "displayMode": "diff" - }, - "issueSettings": { - "minSeverityLevel": "LOW" - } -} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b00a2ef6..643b69412 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ # Changelog + All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) @@ -6,1882 +7,1445 @@ and this project adheres to [Semantic Versioning](http://semver.org/). Please see [CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CONTRIBUTING.md) on how to contribute to Cucumber. ----- -## [Unreleased] (In Git) +## [Unreleased] +### Changed +- Switch from `colors` to `chalk` for terminal coloring ([#1895](https://github.com/cucumber/cucumber-js/pull/1895)) +## [8.0.0-rc.2] - 2022-01-10 ### Added +- Export cucumber version number. It is now possible to retrieve the current version +of cucumber using `import { version } from '@cucumber/cucumber'`. +([PR#1866](https://github.com/cucumber/cucumber-js/pull/1866) +[Issue#1853](https://github.com/cucumber/cucumber-js/issues/1853)) ### Changed +- Switched to new `@cucumber/ci-environment` library for CI detection ([#1868](https://github.com/cucumber/cucumber-js/pull/1868)) -* Clarify that the JSON formatter will not be removed any time soon - -### Deprecated +### Fixed +- Handles spaces in paths for developers working on cucumbers's own code ([#1845](https://github.com/cucumber/cucumber-js/issues/1845)) +- Ensure package.json can be imported by consuming projects +([PR#1870](https://github.com/cucumber/cucumber-js/pull/1870) +[Issue#1869](https://github.com/cucumber/cucumber-js/issues/1869)) +- Allows for parentheses in paths for developers working on cucumber's own code ([[#1735](https://github.com/cucumber/cucumber-js/issues/1735)]) +- Smoother onboarding for Windows developers ([#1863](https://github.com/cucumber/cucumber-js/pull/1863)) +- Pin `colors` to `1.4.0` to fix security vulnerability ([#1884](https://github.com/cucumber/cucumber-js/issues/1884)) +- Pin `cli-table3` to `0.6.1` to fix security vulnerability ([#251](https://github.com/cli-table/cli-table3/pull/251)) + +## [8.0.0-rc.1] - 2021-10-19 +### Added +- Add `wrapPromiseWithTimeout` to public API ([#1566](https://github.com/cucumber/cucumber-js/pull/1566)) +- Add support for user code as native ES modules +- `BeforeStep` and `AfterStep` hook functions now have access to the `pickleStep` in their argument object. +- `--config` option to the CLI. It allows you to specify a configuration file other than `cucumber.js`. +See [docs/profiles.md](./docs/profiles.md#using-another-file-than-cucumberjs) for more info. +[#1794](https://github.com/cucumber/cucumber-js/pull/1794) -### Removed +### Changed +- Relative paths for custom snippet syntaxes must begin with `.` ([#1640](https://github.com/cucumber/cucumber-js/issues/1640)) +- Use performance timers for test case duration measurement. +[#1793](https://github.com/cucumber/cucumber-js/pull/1793) ### Fixed +- Allow targetting same file multiple times ([#1708](https://github.com/cucumber/cucumber-js/pull/1708)) +- When running with `--dry-run`, undefined or ambiguous steps no longer cause the process to exit with code 1. ([#1814](https://github.com/cucumber/cucumber-js/pull/1814)) +- When running the help command, it now shows all available formatters under the --format option. +[#1798](https://github.com/cucumber/cucumber-js/pull/1798) -* Json formatter now works with tagged examples - ([#1621](https://github.com/cucumber/cucumber-js/issues/1621) - [#1651](https://github.com/cucumber/cucumber-js/pull/1651)) +### Removed +- Drop support for Node.js 10 and 15, add support for Node.js 16 +- Remove deprecated `--retryTagFilter` option (the correct option is `--retry-tag-filter`) ([#1713](https://github.com/cucumber/cucumber-js/pull/1713)) +- Remove validation that step definition functions are not generators +- Remove `--predictable-ids` option (was only used for internal testing) -## [7.2.1] (2021-04-21) +## [7.3.1] - 2021-07-20 +### Deprecated +- Deprecate `setDefinitionFunctionWrapper` and step definition option `wrapperOptions` ### Fixed +- Prevent duplicate scenario execution where the same feature is targeted in multiple line expressions ([#1706](https://github.com/cucumber/cucumber-js/issues/1706)) +- Fixed reports banner to point to [new docs](https://cucumber.io/docs/cucumber/environment-variables/) about environment variables +- Re-add color functions for use with custom formatters [1582](https://github.com/cucumber/cucumber-js/issues/1582) +- IParameterTypeDefinition regexp fix [1702](https://github.com/cucumber/cucumber-js/issues/1702) -* Temporarily remove ESM changes due to impact on formatters - -## [7.2.0] (2021-04-20) - +## [7.3.0] - 2021-06-17 ### Added +- Experimental support for [Markdown](https://github.com/cucumber/common/blob/main/gherkin/MARKDOWN_WITH_GHERKIN.md) +([#1645](https://github.com/cucumber/cucumber-js/pull/1645)) -* Experimental support for native ES modules via the [`--esm` flag](./docs/cli.md#es-modules-experimental-nodejs-12) ([#1589](https://github.com/cucumber/cucumber-js/pull/1589)) +### Changed +- All `testCase` messages now emitted upfront at the start of the run (relevant for formatter authors) ([#1408](https://github.com/cucumber/cucumber-js/issues/1408) +[#1669](https://github.com/cucumber/cucumber-js/pull/1669)) +- Clarify that the JSON formatter will not be removed any time soon -## [7.1.0] (2021-04-06) +### Fixed +- `this` now has correct TypeScript type in support code functions ([#1667](https://github.com/cucumber/cucumber-js/issues/1667) [#1690](https://github.com/cucumber/cucumber-js/pull/1690)) +- Progress bar formatter now reports total step count correctly ([#1579](https://github.com/cucumber/cucumber-js/issues/1579) +[#1669](https://github.com/cucumber/cucumber-js/pull/1669)) +- Rerun functionality will now run nothing if the rerun file is empty from the previous run ([#1302](https://github.com/cucumber/cucumber-js/issues/1302) [#1568](https://github.com/cucumber/cucumber-js/pull/1568)) +- All messages now emitted with project-relative `uri`s +([#1534](https://github.com/cucumber/cucumber-js/issues/1534) +[#1672](https://github.com/cucumber/cucumber-js/pull/1672)) +- Json formatter now works with tagged examples +([#1621](https://github.com/cucumber/cucumber-js/issues/1621) +[#1651](https://github.com/cucumber/cucumber-js/pull/1651)) + +## [7.2.1] - 2021-04-21 +### Fixed +- Temporarily remove ESM changes due to impact on formatters +## [7.2.0] - 2021-04-20 ### Added +- Experimental support for native ES modules via the [`--esm` flag](./docs/cli.md#es-modules-experimental-nodejs-12) ([#1589](https://github.com/cucumber/cucumber-js/pull/1589)) +## [7.1.0] - 2021-04-06 +### Added - Support attachments that are already base64-encoded via a prefix on the MIME type e.g. `this.attach(base64String, 'base64:image/png')` ([#1552](https://github.com/cucumber/cucumber-js/pull/1552)) - Support tagged rules ([cucumber#1123](https://github.com/cucumber/cucumber/issues/1123)) ### Fixed +- Fix types for hook functions so they can return e.g. `'skipped'` ([#1542](https://github.com/cucumber/cucumber-js/pull/1542)) +- Display the response of the reports server when an error is returned before failing. ([#1608](https://github.com/cucumber/cucumber-js/pull/1608)) +- Remove unnecessary implicit dependency on `long` package ([cucumber#1313](https://github.com/cucumber/cucumber/pull/1313)) +- Remove unnecessary transitive dependencies on `react` etc ([cucumber#1308](https://github.com/cucumber/cucumber/pull/1308)) -* Fix types for hook functions so they can return e.g. `'skipped'` ([#1542](https://github.com/cucumber/cucumber-js/pull/1542)) -* Display the response of the reports server when an error is returned before failing. ([#1608](https://github.com/cucumber/cucumber-js/pull/1608)) -* Remove unnecessary implicit dependency on `long` package ([cucumber#1313](https://github.com/cucumber/cucumber/pull/1313)) -* Remove unnecessary transitive dependencies on `react` etc ([cucumber#1308](https://github.com/cucumber/cucumber/pull/1308)) - -## [7.0.0] (2020-12-21) - +## [7.0.0] - 2020-12-21 ### Added - -* Add a built in `html` formatter for rich HTML reports output as a standalone page ([#1432](https://github.com/cucumber/cucumber-js/pull/1432)) -* Add support for `BeforeStep` and `AfterStep` hooks ([#1416](https://github.com/cucumber/cucumber-js/pull/1416)) -* Custom formatters can now be resolved by a module name (as well as by a relative path), enabling use of Yarn PnP ([#1413](https://github.com/cucumber/cucumber-js/pull/1413)) - -### Removed - -* Support for running Cucumber in web browsers has been removed ([#1508](https://github.com/cucumber/cucumber-js/pull/1508)). This feature was increasingly difficult to support and seldom used. Node.js will now be the only support runtime for Cucumber itself; of course as before you can still use tools like WebDriver and Puppeteer to instrument testing of browser-based software. See [the discussion in #1437](https://github.com/cucumber/cucumber-js/issues/1437) for more about why this change is happening. +- Add a built in `html` formatter for rich HTML reports output as a standalone page ([#1432](https://github.com/cucumber/cucumber-js/pull/1432)) +- Add support for `BeforeStep` and `AfterStep` hooks ([#1416](https://github.com/cucumber/cucumber-js/pull/1416)) +- Custom formatters can now be resolved by a module name (as well as by a relative path), enabling use of Yarn PnP ([#1413](https://github.com/cucumber/cucumber-js/pull/1413)) ### Fixed +- Wrong version in meta message [#1439](https://github.com/cucumber/cucumber-js/issues/1439) [#1442](https://github.com/cucumber/cucumber-js/pull/1442) -* Wrong version in meta message [#1439](https://github.com/cucumber/cucumber-js/issues/1439) [#1442](https://github.com/cucumber/cucumber-js/pull/1442) - -## [7.0.0-rc.0] (2020-09-14) - -See the [migration guide](./docs/migration.md) for details of how to migrate from 6.x.x. - -### New Features - -* Add `--publish` option to publish reports to [reports.cucumber.io](https://reports.cucumber.io) [#1423](https://github.com/cucumber/cucumber-js/issues/1423), [#1424](https://github.com/cucumber/cucumber-js/pull/1424) -* Add support for Gherkin's [Rule/Example syntax](https://cucumber.io/docs/gherkin/reference/#rule) -* Add `transpose` method to [data table interface](docs/support_files/data_table_interface.md) -* Add `log` function to world, providing a shorthand to log plain text as [attachment(s)](docs/support_files/attachments.md) -* Now includes [TypeScript](https://www.typescriptlang.org/) type definitions, deprecating the need for `@types/cucumber` in TypeScript projects - -### Breaking changes - -* The npm module has changed name from `cucumber` to `@cucumber/cucumber` - `require`/`import` statements must be changed from `cucumber` to `@cucumber/cucumber` -* TypeScript users must rename `TableDefinition` to `DataTable` -* Drop support for Node.js 8, add support for Node.js 14 -* Formatters - * Events are now based on [cucumber-messages](https://github.com/cucumber/cucumber/tree/master/messages) - * `event-protocol` formatter has been removed and replaced with `message` -* Remove long-deprecated `typeName` from options object for `defineParameterType` in favour of `name` -* Parallel runtime environment variables renamed for inclusivity: - * `CUCUMBER_TOTAL_SLAVES` is now `CUCUMBER_TOTAL_WORKERS` - * `CUCUMBER_SLAVE_ID` is now `CUCUMBER_WORKER_ID` -* Custom formatters are now loaded via the regular require paths relative to the current directory, unless it begins with a dot (e.g. `--format=./relpath/to/formatter`). Previously this was always loaded as a file relative to the current directory. - -### Deprecations - -* `json` formatter is deprecated and will be removed in next major release. Custom formatters should migrate to use the `message` formatter, or the [standalone JSON formatter](https://github.com/cucumber/cucumber/tree/master/json-formatter) as a stopgap. - -### Bug fixes - -* don't execute BeforeAll and AfterAll hooks when in dry-run -* support correct case for `--retry-tag-filter` CLI argument - -## [6.0.5] (2019-11-13) - -### Bug fixes - -* json formatter: fix duration to be nanoseconds (was femtoseconds) - -## [6.0.4] (2019-11-10) - -### Bug fixes - -* retry: create a new World instance for every attempt - -## [6.0.3] (2019-10-27) - -* Revert JSON formatter changes to be backward compatible - -## [6.0.2] (2019-10-07) - -* Upgrade to cucumber-expressions 8.0.1 to fix failure on multiple installs - -## [6.0.1] (2019-10-06) +### Removed +- Support for running Cucumber in web browsers has been removed ([#1508](https://github.com/cucumber/cucumber-js/pull/1508)). This feature was increasingly difficult to support and seldom used. Node.js will now be the only support runtime for Cucumber itself; of course as before you can still use tools like WebDriver and Puppeteer to instrument testing of browser-based software. See [the discussion in #1437](https://github.com/cucumber/cucumber-js/issues/1437) for more about why this change is happening. -* Release to fix missing lib +## [7.0.0-rc.0] - 2020-09-14 +### Added +- Add `--publish` option to publish reports to [reports.cucumber.io](https://reports.cucumber.io) [#1423](https://github.com/cucumber/cucumber-js/issues/1423), [#1424](https://github.com/cucumber/cucumber-js/pull/1424) +- Add support for Gherkin's [Rule/Example syntax](https://cucumber.io/docs/gherkin/reference/#rule) +- Add `transpose` method to [data table interface](docs/support_files/data_table_interface.md) +- Add `log` function to world, providing a shorthand to log plain text as [attachment(s)](docs/support_files/attachments.md) +- Now includes [TypeScript](https://www.typescriptlang.org/) type definitions, deprecating the need for `@types/cucumber` in TypeScript projects -## [6.0.0] (2019-10-06) +### Changed +- The npm module has changed name from `cucumber` to `@cucumber/cucumber` - `require`/`import` statements must be changed from `cucumber` to `@cucumber/cucumber` +- TypeScript users must rename `TableDefinition` to `DataTable` +- Drop support for Node.js 8, add support for Node.js 14 +- Events are now based on [cucumber-messages](https://github.com/cucumber/cucumber/tree/master/messages) +- `event-protocol` formatter has been removed and replaced with `message` +- Formatters +- Remove long-deprecated `typeName` from options object for `defineParameterType` in favour of `name` +- `CUCUMBER_TOTAL_SLAVES` is now `CUCUMBER_TOTAL_WORKERS` +- `CUCUMBER_SLAVE_ID` is now `CUCUMBER_WORKER_ID` +- Parallel runtime environment variables renamed for inclusivity: +- Custom formatters are now loaded via the regular require paths relative to the current directory, unless it begins with a dot (e.g. `--format=./relpath/to/formatter`). Previously this was always loaded as a file relative to the current directory. -### BREAKING CHANGES +### Deprecated +- `json` formatter is deprecated and will be removed in next major release. Custom formatters should migrate to use the `message` formatter, or the [standalone JSON formatter](https://github.com/cucumber/cucumber/tree/master/json-formatter) as a stopgap. -* Drop support for Node.js 6 -* JSON formatter has major breaking changes. View some sample outputs [here](/features/fixtures/formatters/). The `*.json.js` files contain the js objects the json parses to. (UPDATE - reverted in 6.0.3) -* Duration is now in nanoseconds in event-protocol formatter and in events sent to custom formatters -* Custom formatters: Formatter helpers and EventDataCollector had breaking changes to support retry +### Fixed +- don't execute BeforeAll and AfterAll hooks when in dry-run +- support correct case for `--retry-tag-filter` CLI argument -### Bug fixes +## [6.0.5] - 2019-11-13 +### Fixed +- json formatter: fix duration to be nanoseconds (was femtoseconds) -* Prevent after hooks from updating skipped scenarios to passed -* Parallel: beforeAll / afterAll errors fail the suite -* Fix CLI help link +## [6.0.4] - 2019-11-10 +### Fixed +- retry: create a new World instance for every attempt -### New features +## [6.0.3] - 2019-10-27 +### Fixed +- Revert JSON formatter changes to be backward compatible -* Add ability to retry flaky tests - * Use `--retry ` and limit what tests will be retried with `--retryTagFilter ` - * Event-protocol added an `attemptNumber` to test case started, test case finished, and all test step events and a `retried` boolean to the test case result to signify if the test case was retried -* usage-json formatter: add code and patternType -* Add support for Node.js 12 +## [6.0.2] - 2019-10-07 +### Fixed +- Upgrade to cucumber-expressions 8.0.1 to fix failure on multiple installs -## [5.1.0] (2018-12-28) +## [6.0.1] - 2019-10-06 +### Fixed +- Release to fix missing lib -### Internals +## [6.0.0] - 2019-10-06 +### Added +- Use `--retry ` and limit what tests will be retried with `--retryTagFilter ` +- Event-protocol added an `attemptNumber` to test case started, test case finished, and all test step events and a `retried` boolean to the test case result to signify if the test case was retried +- Add ability to retry flaky tests +- usage-json formatter: add code and patternType +- Add support for Node.js 12 -* Upgrade to babel 7 +### Changed +- Drop support for Node.js 6 +- JSON formatter has major Changed. View some sample outputs [here](/features/fixtures/formatters/). The `*.json.js` files contain the js objects the json parses to. (UPDATE - reverted in 6.0.3) +- Duration is now in nanoseconds in event-protocol formatter and in events sent to custom formatters +- Custom formatters: Formatter helpers and EventDataCollector had Changed to support retry -## [5.0.3] (2018-12-03) +### Fixed +- Prevent after hooks from updating skipped scenarios to passed +- Parallel: beforeAll / afterAll errors fail the suite +- Fix CLI help link -### Speed Improvements +## [5.1.0] - 2018-12-28 +### Fixed +- Upgrade to babel 7 -* Only create Cucumber Expressions once +## [5.0.3] - 2018-12-03 +### Fixed +- Only create Cucumber Expressions once -## [5.0.2] (2018-10-06) +## [5.0.2] - 2018-10-06 +### Fixed +- Update default of formatters' colors enabled to be true only if the stream is a TTY +- Allow writing to stdout when running in parallel +- Skip other before hooks if one returns skipped -### Bug Fixes +## [5.0.1] +### Fixed +- Update dependencies to avoid licensing problems -* Update default of formatters' colors enabled to be true only if the stream is a TTY -* Allow writing to stdout when running in parallel -* Skip other before hooks if one returns skipped +## [5.0.0] - 2018-04-09 +### Added +- Add support for Node.js 10 -## [5.0.1] (2018-04-09) +### Changed +- Drop support for Node.js 4 -### Bug Fixes +### Fixed +- Update dependencies to avoid licensing problems +- Provide better error message when trying to attach data after the scenario has finished. This is possible if not waiting for the attach to finish. -* Update dependencies to avoid licensing problems +## [4.2.1] - 2018-04-09 +### Fixed +- improve the error message for gherkin parse errors -## [5.0.0] (2018-04-09) +## 4.2.0 - 2018-04-03 +### Added +- add cli option `--order ` to run scenarios in the specified order. Type should be `defined` or `random` -### BREAKING CHANGES +## [4.1.0] - 2018-03-27 +### Added +- update step timeout error message for each interface ([#1028](https://github.com/cucumber/cucumber-js/pull/1028), Bruce Lindsay) +- default to synchronous snippets +- print text step attachments ([#1041](https://github.com/cucumber/cucumber-js/pull/1041), DevSide) -* Drop support for Node.js 4 +### Fixed +- cucumber-expressions: Upgrade from 5.0.7 to [5.0.13](https://github.com/cucumber/cucumber/blob/master/cucumber-expressions/CHANGELOG.md#5013---2018-01-21) +- fix error serialization in parallel mode -### Bug Fixes +## [4.0.0] - 2018-01-24 +### Added +- can now use glob patterns for selecting what features to run +- update `--require` to support glob patterns +- add `--require-module ` to require node modules before support code is loaded +- add snippet interface "async-await" +- add `--parallel ` option to run tests in parallel. Note this is an experimental feature. See [here](/docs/cli.md#parallel-experimental) for more information -* Update dependencies to avoid licensing problems -* Provide better error message when trying to attach data after the scenario has finished. This is possible if not waiting for the attach to finish. +### Changed +- cucumber now waits for the event loop to drain before exiting. To exit immediately when the tests finish running use `--exit`. Use of this flag is discouraged. See [here](/docs/cli.md#exiting) for more information +- remove `--compiler` option. See [here](/docs/cli.md#transpilers) for the new way to use transpilers +- remove binaries `cucumber.js` and `cucumberjs`. Use `cucumber-js` -### New features +### Deprecated +- `defineSupportCode` is deprecated. Require/import the individual methods instead -* Add support for Node.js 10 +### Fixed +- revert json formatter duration to nanoseconds -## [4.2.1] (2018-04-09) +## [3.2.1] - 2018-01-03 +### Fixed +- revert json formatter mime type ([#995](https://github.com/cucumber/cucumber-js/pull/995) -### Bug Fixes +## [3.2.0] - 2017-12-08 +### Added +- add exception to `test-case-finished` event ([#952](https://github.com/cucumber/cucumber-js/pull/952) Giuseppe DiBella) +- compiler option - allow `:` in module name to support specifying an absolute path on Windows ([#958](https://github.com/cucumber/cucumber-js/pull/958) Darrin Holst) +- json formatter: format step result exception ([#973](https://github.com/cucumber/cucumber-js/pull/973) Valerio Innocenti Sedili) -* improve the error message for gherkin parse errors +### Fixed +- cucumber-expressions: Upgrade from 5.0.3 to [5.0.6](https://github.com/cucumber/cucumber/blob/master/cucumber-expressions/CHANGELOG.md#506---2017-11-28) +- tag-expressions: Upgrade from 1.0.1 to [1.1.1](https://github.com/cucumber/cucumber/blob/master/tag-expressions/CHANGELOG.md#111---2017-12-01) -## [4.2.0] (2018-04-03) +## [3.1.0] - 2017-10-25 +### Added +- add `--language` cli option to provide the default language for feature files -* add cli option `--order ` to run scenarios in the specified order. Type should be `defined` or `random` +### Fixed +- pickle filter: support relative paths ([#962](https://github.com/cucumber/cucumber-js/pull/962) Marco Muller) -## [4.1.0] (2018-03-27) +## [3.0.6] - 2017-10-18 +### Fixed +- cli: fix `--format` option parsing on Windows ([#954](https://github.com/cucumber/cucumber-js/pull/954) Darrin Holst) -### New Features +## [3.0.5] - 2017-10-14 +### Added +- `defineParameterType`: The `transformer` function's `this` object is now the current World (as long as it's not an arrow function). ([#948](https://github.com/cucumber/cucumber-js/pull/948) Aslak Hellesøy) +- `Before` / `After`: The first argument now includes a `pickle` property which can +be used to get the name / tags of the running scenario. ([#947](https://github.com/cucumber/cucumber-js/pull/947) Giuseppe DiBella) -* update step timeout error message for each interface ([#1028](https://github.com/cucumber/cucumber-js/pull/1028), Bruce Lindsay) -* default to synchronous snippets -* print text step attachments ([#1041](https://github.com/cucumber/cucumber-js/pull/1041), DevSide) +## [3.0.4] - 2017-10-04 +### Added +- cli: make `--tags` option repeatable (joined with `and`) ([#940](https://github.com/cucumber/cucumber-js/issues/940), Ilya Kozhevnikov) +- rerun formatter: make separator configurable. See docs [here](https://github.com/cucumber/cucumber-js/blob/fb9e8fc2e68d4395b9b0a124d18e036d00a8c69f/docs/cli.md) ([#930](https://github.com/cucumber/cucumber-js/issues/930), Máté Karácsony) -### Bug Fixes +## [3.0.3] - 2017-09-23 +### Added +- support to imperatively skip steps. See documentation [here](/docs/support_files/step_definitions.md#skipped-steps) ([#912](https://github.com/cucumber/cucumber-js/issues/912), jshifflet) -* cucumber-expressions: Upgrade from 5.0.7 to [5.0.13](https://github.com/cucumber/cucumber/blob/master/cucumber-expressions/CHANGELOG.md#5013---2018-01-21) -* fix error serialization in parallel mode +## [3.0.2] - 2017-09-13 +### Added +- `defineParameterType`: new options `useForSnippets` and `preferForRegexpMatch`. Please see documentation for usage. -## [4.0.0] (2018-01-24) +### Deprecated +- `defineParameterType`: `typeName` option is deprecated in favor of `name` -### BREAKING CHANGES +### Fixed +- fix `usage` and `usage-json` formatters when there are undefined steps -* cucumber now waits for the event loop to drain before exiting. To exit immediately when the tests finish running use `--exit`. Use of this flag is discouraged. See [here](/docs/cli.md#exiting) for more information -* remove `--compiler` option. See [here](/docs/cli.md#transpilers) for the new way to use transpilers -* remove binaries `cucumber.js` and `cucumberjs`. Use `cucumber-js` +## [3.0.1] - 2017-08-28 +### Fixed +- JSON formatter: add type to scenario ([#893](https://github.com/cucumber/cucumber-js/issues/893), szymonprz) +- BeforeAll/AfterAll hooks: fix timeout support ([#899](https://github.com/cucumber/cucumber-js/issues/899)) +- format output paths: allow absolute paths ([#906](https://github.com/cucumber/cucumber-js/issues/906), Darrin Holst) +- Before/After: fix undefined hook parameter ([#919](https://github.com/cucumber/cucumber-js/issues/919)) +- update nodejs example +([#898](https://github.com/cucumber/cucumber-js/issues/898), João Guilherme Farias Duda) +- fix typo and make punctuation consistent +([#909](https://github.com/cucumber/cucumber-js/issues/909), Dmitry Shirokov) +- normalize CHANGELOG +([#915](https://github.com/cucumber/cucumber-js/issues/915), Jayson Smith) -### New Features +## [3.0.0] - 2017-08-08 +### Added +- Add `--i18n-languages` and `--i18n-keywords ` CLI options +- Add `BeforeAll` / `AfterAll` hooks for suite level setup / teardown +- Add event protocol formatter +- Add built in `{word}` parameter type which is equivalent to `[A-Za-z0-9_]+` +- Allow multiple parameter types to use the same regular expression +- `cucumber-expressions`: +- Improve error message when using multiple asynchronous interfaces -* can now use glob patterns for selecting what features to run -* update `--require` to support glob patterns -* add `--require-module ` to require node modules before support code is loaded -* add snippet interface "async-await" -* add `--parallel ` option to run tests in parallel. Note this is an experimental feature. See [here](/docs/cli.md#parallel-experimental) for more information +### Changed +- `pretty` formatter has been removed. All errors are now reported in a `pretty` format instead. The `progress` formatter is now the default. +- Major changes to [custom formatter](/docs/custom_formatters.md) and [custom snippet syntax](/docs/custom_snippet_syntaxes.md) APIs due to rewrite in support of the event protocol. Please see the updated documentation. +- Remove `registerHandler` and `registerListener`. Use `BeforeAll` / `AfterAll` for setup code. Use the event protocol formatter if used for reporting. Please open an issue if you have another use case. +- Remove deprecated `addTransform`. Use `defineParameterType` instead. +- using an undefined parameter type now results in an error +- `{stringInDoubleQuotes}` is now `{string}` which works for strings in single or double quotes +- `cucumber-expressions`: +- Undefined steps fail the build in non-strict mode. Non-strict mode only allows pending steps now. -### Bug Fixes +### Fixed +- Fix support code line and uri references when using direct imports -* revert json formatter duration to nanoseconds +## [2.3.1] - 2017-06-09 +### Added +- pass step specific options to definition function wrapper ([#838](https://github.com/cucumber/cucumber-js/issues/838), Łukasz Gandecki) -### Deprecations +## [2.3.0] - 2017-06-01 +### Added +- Add support code aliases for every method in the [support code API](./docs/support_files/api_reference.md). -* `defineSupportCode` is deprecated. Require/import the individual methods instead - ```js - var {defineSupportCode} = require('cucumber'); +## [2.2.0] - 2017-05-20 +### Added +- Add `progress-bar` formatter inspired by [fuubar-cucumber](https://github.com/martinciu/fuubar-cucumber) and [fuubar](https://github.com/thekompanee/fuubar) which outputs a progress bar and errors as they happen - defineSupportCode(function({Given}) { - Given(/^a step$/, function() {}); - }); +## [2.1.0] - 2017-05-12 +### Fixed +- throw descriptive error message when running a global install - // Should be updated to +## [1.3.3] - 2016-04-26 +### Fixed +- fix unhandled rejections in handlers ([#792](https://github.com/cucumber/cucumber-js/issues/792), yaronassa) - var {Given} = require('cucumber'); +## [1.3.2] - 2016-03-20 +### Fixed +- dependency: fix use of gherkin to not rely on removed field - Given(/^a step$/, function() {}); - ``` +## [2.0.0-rc.9] - 2017-03-16 +### Fixed +- dependency: fix use of gherkin to not rely on removed field -## [3.2.1] (2018-01-03) +## [2.0.0-rc.8] - 2017-03-10 +### Added +- all async parameter type transform functions (Aslak Hellesøy) +- make all formatters available when requiring -### Bug Fixes -* revert json formatter mime type ([#995](https://github.com/cucumber/cucumber-js/pull/995) +### Deprecated +- `addTransform` was deprecated in favor of `defineParameterType` -## [3.2.0] (2017-12-08) +### Fixed +- generated step definition snippets are not found ([#732](https://github.com/cucumber/cucumber-js/issues/732), Aslak Hellesøy) +- catch attempt to define duplicate parameter type regular expression ([#780](https://github.com/cucumber/cucumber-js/issues/780), Aslak Hellesøy) +- catch errors in parameter type transform functions (Aslak Hellesøy) +- normalize syntax highlighting ([#726](https://github.com/cucumber/cucumber-js/issues/726), Martin Delille) +- fix setWorldConstructor example -### New Features -* add exception to `test-case-finished` event ([#952](https://github.com/cucumber/cucumber-js/pull/952) Giuseppe DiBella) -* compiler option - allow `:` in module name to support specifying an absolute path on Windows ([#958](https://github.com/cucumber/cucumber-js/pull/958) Darrin Holst) -* json formatter: format step result exception ([#973](https://github.com/cucumber/cucumber-js/pull/973) Valerio Innocenti Sedili) +## [2.0.0-rc.7] - 2017-01-30 +### Fixed +- fix after hook run order ([#743](https://github.com/cucumber/cucumber-js/issues/743)) +- normalize syntax highlighting ([#726](https://github.com/cucumber/cucumber-js/issues/726), (Martin Delille) +- fix addTransform parameter name ([#738](https://github.com/cucumber/cucumber-js/issues/738)) -### Bug Fixes -* cucumber-expressions: Upgrade from 5.0.3 to [5.0.6](https://github.com/cucumber/cucumber/blob/master/cucumber-expressions/CHANGELOG.md#506---2017-11-28) -* tag-expressions: Upgrade from 1.0.1 to [1.1.1](https://github.com/cucumber/cucumber/blob/master/tag-expressions/CHANGELOG.md#111---2017-12-01) +## [2.0.0-rc.6] - 2017-01-06 +### Added +- usage and usage-json formatters +- update error reporting for `registerHandler` errors +- add ability to disable timeout -## [3.1.0] (2017-10-25) +### Fixed +- update snippets to new support code interface -### New Features -* add `--language` cli option to provide the default language for feature files +## [2.0.0-rc.5] - 2016-12-22 +### Changed +- Drop support for Node 0.12 +- format assertion errors to display diffs -### Bug Fixes -* pickle filter: support relative paths ([#962](https://github.com/cucumber/cucumber-js/pull/962) Marco Muller) +### Fixed +- fix CLI format-options name ([#703](https://github.com/cucumber/cucumber-js/issues/703), Florian Ribon) +- add link on README.md to custom formatters documentation -## [3.0.6] (2017-10-18) +## [2.0.0-rc.4] - 2016-12-19 +### Changed +- update support code library interface - instead of exporting a function and calling methods on `this`, require the `cucumber` module and call `defineSupportCode` which passes an object as the first argument whch exposes the methods. Overriding the world constructor has changed from overriding the World property to calling `setWorldConstructor`. -* cli: fix `--format` option parsing on Windows ([#954](https://github.com/cucumber/cucumber-js/pull/954) Darrin Holst) +## [2.0.0-rc.3] - 2016-12-19 +### Added +- validate argument types -## [3.0.5] (2017-10-14) +### Changed +- make strict the default +- previously pending and undefined steps did not cause an exit code of 1. This could be overridden with `--strict`. Strict is now the default and you can use `--no-strict` to return to the previous behavior. +- update automatically required files +- if the features live in a `features` directory at any level, all support files in the `features` directory are loaded. -### New Features +### Fixed +- prevent crash on empty feature file +- docs: fix tag expression migration guide ([#691](https://github.com/cucumber/cucumber-js/issues/691), Aslak Hellesøy) -* `defineParameterType`: The `transformer` function's `this` object is now the current World (as long as it's not an arrow function). ([#948](https://github.com/cucumber/cucumber-js/pull/948) Aslak Hellesøy) -* `Before` / `After`: The first argument now includes a `pickle` property which can -be used to get the name / tags of the running scenario. ([#947](https://github.com/cucumber/cucumber-js/pull/947) Giuseppe DiBella) +## [2.0.0-rc.2] - 2016-12-04 +### Added +- json formatter: add `isBackground` to steps -## [3.0.4] (2017-10-04) +### Changed +- pass `attach` to world constructor instead of assigning it to world +- the world constructor now receives `{attach, parameters}` as the first argument instead of `parameters` -### New Features +### Fixed +- clear timeouts of asynchronous hooks/steps +- stop running features with no scenarios +- update node js example -* cli: make `--tags` option repeatable (joined with `and`) ([#940](https://github.com/cucumber/cucumber-js/issues/940), Ilya Kozhevnikov) -* rerun formatter: make separator configurable. See docs [here](https://github.com/cucumber/cucumber-js/blob/fb9e8fc2e68d4395b9b0a124d18e036d00a8c69f/docs/cli.md) ([#930](https://github.com/cucumber/cucumber-js/issues/930), Máté Karácsony) +## [2.0.0-rc.1] - 2016-11-25 +### Fixed +- fix browser version -## [3.0.3] (2017-09-23) +## [2.0.0-rc.0] - 2016-11-25 +### Added +- Attachments: +- When attaching a stream, the interface can either accept a callback as a third argument or will return a promise if not passed a callback +- Step Definitions +- Ability to add custom argument transformations +- Support Files +- When used together rerun formatter will output all skipped scenarios that didn't run due to a failure +- Fail fast / rerun formatter -### New Features +### Changed +- Dropped support for Node 0.10 +- `--colors / --no-colors` has moved to `--format-options '{"colorsEnabled": }'` +- `--require `: the required files are no longer reordered to require anything in a `support` directory first +- `--snippet-interface ` has moved to `--format-options '{"snippetInterface": ""}'` +- `--snippet-syntax ` has moved to `--format-options '{"snippetSyntax": ""}'` +- `--tags ` now uses [cucumber-tag-expressions](https://docs.cucumber.io/tag-expressions/). It is no longer repeatable and new values will override previous +- `--tags @dev` stays the same +- `--tags ~@dev` becomes `--tags 'not @dev'` +- `--tags @foo,@bar` becomes `--tags '@foo or @bar'` +- `--tags @foo --tags @bar` becomes `--tags '@foo and @bar'` +- CLI +- complete rewrite using ES2015 and promises +- Internals +- String attachments are no longer base64 encoded. Buffer and Stream attachments are still base64 encoded. +- JSON Formatter +- Attachments +- The `attach` function used for adding attachments moved from the API scenario object to world. It is thus now available in step definitions without saving a reference to the scenario. +- When attaching buffers or strings, the callback argument is ignored. +- Hooks +- Hooks now receive a [ScenarioResult](/src/models/scenario_result.js) instead of the Scenario +- The `tags` option for hook should now be a string instead of an array and uses [cucumber-tag-expressions](https://docs.cucumber.io/tag-expressions/) +- Step Definitions +- String patterns were removed in favor [cucumber-expressions](https://docs.cucumber.io/cucumber-expressions/) +- capture groups matching `(-?\d+)` will be automatically converted to an integer using `parseInt` +- capture groups matching `(-?\d*\.?\d+)` will be automatically converted to a float using `parseFloat` +- Regular Expressions +- Generator functions are no longer automatically run with `co`. To retain the previous functionality, use [this.setDefinitionFunctionWrapper](/docs/support_files/step_definitions.md#definition-function-wrapper) +- Event Handlers +- For example: `scenario.getName()` is now just `scenario.name` +- Objects no longer have `get*` methods and instead have exposed properties +- `StepResult` duration is now in milliseconds instead of nanoseconds +- Support Files -* support to imperatively skip steps. See documentation [here](/docs/support_files/step_definitions.md#skipped-steps) ([#912](https://github.com/cucumber/cucumber-js/issues/912), jshifflet) +### Fixed +- remove empty lines from `@rerun` files ([#660](https://github.com/cucumber/cucumber-js/issues/660), Cody Ray Hoeft) +- catch uncaught errors in the browser (Charlie Rudolph) +- fix typo ([#659](https://github.com/cucumber/cucumber-js/issues/659), gforceg) +- update support files api reference ([#661](https://github.com/cucumber/cucumber-js/issues/661), Zearin) -## [3.0.2] (2017-09-13) +## [1.3.1] - 2016-09-30 +### Fixed +- pass formatter options to listener ([#641](https://github.com/cucumber/cucumber-js/issues/641), Charlie Rudolph) +- rerun formatter: output any scenario that doesn't pass (Charlie Rudolph) +- populate scenario definition ([#647](https://github.com/cucumber/cucumber-js/issues/647), Charlie Rudolph) +- handle empty stacktraces ([#605](https://github.com/cucumber/cucumber-js/issues/605), Hugues Malphettes) +- use cross-platform symbols ([#635](https://github.com/cucumber/cucumber-js/issues/635), Kevin Goslar) +- fix node.js example ([#637](https://github.com/cucumber/cucumber-js/issues/637), Jonathan Gomez) +- fix links in event_handlers.md ([#638](https://github.com/cucumber/cucumber-js/issues/638), Oliver Rogers) +- fix hooks example ([#644](https://github.com/cucumber/cucumber-js/issues/644), John McLaughlin) + +## [1.3.0] - 2016-09-08 +### Added +- add `--snippet-interface ` CLI option (Charlie Rudolph) +- add `--world-parameters ` CLI option (Charlie Rudolph) +- add snippets formatter (Charlie Rudolph) +- add support for ES6 default module syntax (dbillingham) +- pretty formatter: add symbols (Charlie Rudolph) +- add simplified hook parameters (Charlie Rudolph) -### New Features +### Fixed +- step definition snippets internationalization (Charlie Rudolph) +- document order of execution for multiple hooks (John McLaughlin) +- breakup README.md, organize docs (Charlie Rudolph) -* `defineParameterType`: new options `useForSnippets` and `preferForRegexpMatch`. Please see documentation for usage. +## [1.2.2] - 2016-08-05 +### Fixed +- Fix error when stack trace has no frames ([#610](https://github.com/cucumber/cucumber-js/issues/610), Jan Molak) -### Bug Fixes +## [1.2.1] - 2016-07-01 +### Fixed +- Fix hook / step definition location and stacktraces in the browser ([#567](https://github.com/cucumber/cucumber-js/issues/567), [#538](https://github.com/cucumber/cucumber-js/issues/538), Charlie Rudolph) -* fix `usage` and `usage-json` formatters when there are undefined steps +## [1.2.0] - 2016-06-24 +### Fixed +- Remove intermediate conversion to string (Charlie Rudolph) +- Use native base64 encoding which can encode binary ([#589](https://github.com/cucumber/cucumber-js/issues/589), Benjamín Eidelman) +- Attachments -### Deprecations +## [1.1.0] - 2016-06-23 +### Added +- Can now use all supported functions interfaces (synchronous, callback, promise, generators) +- Will throw any error received and immediately kill the test suite +- Supports handler specific timeouts +- Updated documentation +- Add full support to `registerHandler` (Charlie Rudolph) -* `defineParameterType`: `typeName` option is deprecated in favor of `name` +### Fixed +- CLI format: support absolute path on windows (Charlie Rudolph) +- Fix typo in event name. ([#590](https://github.com/cucumber/cucumber-js/issues/590), Artur Pomadowski) +- Don't run hooks in dry run mode (Charlie Rudolph) -## [3.0.1] (2017-08-28) +## [1.0.0] - 2016-05-30 +### Fixed +- Escape all instances of special characters in example / data table (Charlie Rudolph) -### Bug Fixes +## [0.10.4] - 2016-05-30 +### Added +- Allow time to be faked by utilities such as `sinon.useFakeTimers` (John McLaughlin) -* JSON formatter: add type to scenario ([#893](https://github.com/cucumber/cucumber-js/issues/893), szymonprz) -* BeforeAll/AfterAll hooks: fix timeout support ([#899](https://github.com/cucumber/cucumber-js/issues/899)) -* format output paths: allow absolute paths ([#906](https://github.com/cucumber/cucumber-js/issues/906), Darrin Holst) -* Before/After: fix undefined hook parameter ([#919](https://github.com/cucumber/cucumber-js/issues/919)) +## [0.10.3] - 2016-05-19 +### Fixed +- Escape newlines in table cells in pretty formatter (Julien Biezemans) +- Fix handling of unusual error objects (efokschaner) -### Documentation +## [0.10.2] - 2016-04-07 +### Added +- Add match location to JSON formatter output (Charlie Rudolph) -* update nodejs example -([#898](https://github.com/cucumber/cucumber-js/issues/898), João Guilherme Farias Duda) -* fix typo and make punctuation consistent -([#909](https://github.com/cucumber/cucumber-js/issues/909), Dmitry Shirokov) -* normalize CHANGELOG -([#915](https://github.com/cucumber/cucumber-js/issues/915), Jayson Smith) +### Fixed +- Undefined background step (Scott Deakin) -## [3.0.0] (2017-08-08) +## [0.10.1] - 2016-04-01 +### Added +- Support generators for hooks/step definitions (Ádám Gólya) -### BREAKING CHANGES +## [0.10.0] - 2016-04-01 +### Added +- support hook specific timeouts (Charlie Rudolph) +- reworked formatter error reporting (Charlie Rudolph) -* `pretty` formatter has been removed. All errors are now reported in a `pretty` format instead. The `progress` formatter is now the default. -* Major changes to [custom formatter](/docs/custom_formatters.md) and [custom snippet syntax](/docs/custom_snippet_syntaxes.md) APIs due to rewrite in support of the event protocol. Please see the updated documentation. -* Remove `registerHandler` and `registerListener`. Use `BeforeAll` / `AfterAll` for setup code. Use the event protocol formatter if used for reporting. Please open an issue if you have another use case. -* Remove deprecated `addTransform`. Use `defineParameterType` instead. -* `cucumber-expressions`: - * using an undefined parameter type now results in an error - * `{stringInDoubleQuotes}` is now `{string}` which works for strings in single or double quotes -* Undefined steps fail the build in non-strict mode. Non-strict mode only allows pending steps now. +### Changed +- how to update: use separate before and after hooks. If this is not sufficient, please create an issue. +- removed around hooks (Charlie Rudolph) +- how to update: change `callback.pending()` to `callback(null, 'pending')` or use one of the new pending step interfaces +- updated pending step interface (Charlie Rudolph) +- updated tagged hook interface (Charlie Rudolph) -### New Features +## [0.9.5] - 2016-02-16 +### Added +- Allow rerun file to be in subfolder (Charlie Rudolph) -* Add `--i18n-languages` and `--i18n-keywords ` CLI options -* Add `BeforeAll` / `AfterAll` hooks for suite level setup / teardown -* Add event protocol formatter -* `cucumber-expressions`: - * Add built in `{word}` parameter type which is equivalent to `[A-Za-z0-9_]+` - * Allow multiple parameter types to use the same regular expression -* Improve error message when using multiple asynchronous interfaces +### Fixed +- Fix rerun formatter output (Charlie Rudolph) -### Bug Fixes +## [0.9.4] - 2016-01-28 +### Fixed +- Publish release folder to npm (Charlie Rudolph) -* Fix support code line and uri references when using direct imports +## [0.9.3] - 2016-01-27 +### Added +- Run scenario by name (Charlie Rudolph) -## [2.3.1] (2017-06-09) +### Fixed +- Prevent maximum call stack from being exceeded (John Krull) +- Add documentation of profiles (Charlie Rudolph) +- README improvements (Miika Hänninen, Kevin Goslar, Maxim Koretskiy) -### New Features +## [0.9.2] +### Added +- Bump stack-chain (Rick Lee-Morlang) -* pass step specific options to definition function wrapper ([#838](https://github.com/cucumber/cucumber-js/issues/838), Łukasz Gandecki) +## [0.9.1] +### Added +- Add rerun formatter (Charlie Rudolph) -## [2.3.0] (2017-06-01) +### Fixed +- Add ability to execute scenario outline example (Charlie Rudolph) +- Support tags on scenario outline examples (Charlie Rudolph) +- Fix invalid hook documentation (Charlie Rudolph) -### New Features +## [0.9.0] +### Added +- pretty formatter: source shows step definition location (Charlie Rudolph) +- support node 5 (Charlie Rudolph) -* Add support code aliases for every method in the [support code API](./docs/support_files/api_reference.md). The following are now equivalent: - ```javascript - // Using defineSupportCode - var {defineSupportCode} = require('cucumber'); +### Changed +- catch ambiguous step definitions (Charlie Rudolph) +- remove use of domain (Charlie Rudolph) - defineSupportCode(function({Given}) { - Given(/^a step$/, function() {}); - }); +### Fixed +- Fix `Api.Scenario#attach` callback handling (Julien Biezemans) +- Add async example to README (Artem Bronitsky) +- Document hooks sync/async protocols (Julien Biezemans) +- Remove useless callbacks in documentation (Julien Biezemans) +- Fix browser example (Karine Pires) - // Using aliases - var {Given} = require('cucumber'); +## [0.8.1] +### Fixed +- Update World constructor documentation (Charlie Rudolph) +- Remove badges from README.md (Charlie Rudolph) - Given(/^a step$/, function() {}); - ``` - (Nico Jansen and Łukasz Gandecki) +## [0.8.0] +### Added +- Add cli option to fail fast (Charlie Rudolph) +- Add cli for specifying multiple formatters (Charlie Rudolph) +- Add support for passing multiple line numbers (Charlie Rudolph) +- Add ability to disable colors (Charlie Rudolph) +- Add support for custom snippet syntaxes (Charlie Rudolph) -## [2.2.0] (2017-05-20) +### Changed +- Add strict function length checking to hooks and step definitions (Charlie Rudolph) +- Make World constructors strictly synchronous (Julien Biezemans) +- Hide errors in pretty formatter summary (Charlie Rudolph) +- Remove unnecessary whitespaces in pretty formatter output (Charlie Rudolph) -### New Features +### Fixed +- Properly ask configurations for strict mode (Julien Biezemans) +- Document data table interface (Charlie Rudolph) +- Refactor: statuses (Charlie Rudolph) +- Refactor: cleanup step definitions (Charlie Rudolph) +- Cleanup: remove log to console from listeners (Charlie Rudolph) +- Use svg badges (Charlie Rudolph) +- Rename CONTRIBUTE.md to CONTRIBUTING.md (Julien Biezemans) +- Require maintainers to document API changes in release tag descriptions (Julien Biezemans) +- Add build-release NPM script (Julien Biezemans) + +## [0.7.0] +### Added +- Time out steps that take too long (Charles Rudolph) +- Print execution time (Charles Rudolph) -* Add `progress-bar` formatter inspired by [fuubar-cucumber]( https://github.com/martinciu/fuubar-cucumber) and [fuubar](https://github.com/thekompanee/fuubar) which outputs a progress bar and errors as they happen +### Changed +- Remove callback.fail() (Charles Rudolph) +- Update hooks interface (Charles Rudolph) -## [2.1.0](https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.9...v2.1.0) (2017-05-12) +### Fixed +- Don't try to handle empty features (Julien Biezemans) +- Fix unpredictable nopt behavior (Charles Rudolph) +- Fix pretty formatter step indentation after doc string (Charles Rudolph) +- Rename Collection functions: forEach/syncForEach -> asyncForEach/forEach (Charles Rudolph) +- Simplify installation instructions (Charles Rudolph) +- Fix spec on Windows (Marcel Hoyer) +- Simplify World examples in README (Charles Rudolph) +- Update license in package.json (Charles Rudolph) +- Convert test framework from jasmine-node to jasmine (Charles Rudolph) +- Separate test output (Charles Rudolph) +- Remove ruby, legacy features, cucumber-tck (Charles Rudolph) + +## [0.6.0] +### Added +- Add --no-source to hide uris (Eddie Loeffen) +- Add dry run capability (Karthik Viswanath) +- Introduce --compiler CLI option (Charles Rudolph) -### Bug Fixes +### Fixed +- Stop IRC and email notifications from Travis (Julien Biezemans) +- Remove Node.js 0.11 explicit support (Julien Biezemans) +- Use basic for loop for array iterations (Charles Rudolph) +- Bump browserify (Charles Rudolph) +- Add CLI help for --profile (Charles Rudolph) +- Use colors library (Charles Rudolph) +- Improve --compiler help (Julien Biezemans) +- Fix loading of external compiler modules (Julien Biezemans) +- Document a few common compiler usages (Julien Biezemans) + +## [0.5.3] +### Added +- Add support for profiles (Charles Rudolph) -* throw descriptive error message when running a global install +### Changed +- Allow for multiple instances of placeholder (Charles Rudolph) +- Print relative paths in summary output (Charles Rudolph) -## [1.3.3] (2016-04-26) +### Fixed +- Remove duplicate line number from output (Charles Rudolph) +- Return clone of array from DataTable.Row.raw() (Julien Biezemans) +- Update various urls (Dale Gardner) +- Bump CoffeeScript (Julien Biezemans) +- Bump PogoScript (Julien Biezemans) +- Bump underscore (Julien Biezemans) +- Bump underscore.string (Julien Biezemans) +- Bump stack-chain (Julien Biezemans) +- Bump nopt (Julien Biezemans) +- Bump connect (Julien Biezemans) +- Bump exorcist (Julien Biezemans) +- Bump uglifyify (Julien Biezemans) +- Bump through (Julien Biezemans) +- Bump serve-static (Julien Biezemans) +- Bump rimraf (Julien Biezemans) +- Bump mkdirp (Julien Biezemans) +- Bump jshint (Julien Biezemans) +- Remove extra bracket in README example (Julien Biezemans) +- Officially support Node.js 4.x (Julien Biezemans) +- Use a profile for own build (Julien Biezemans) + +## [0.5.2] +### Added +- Add rowsHash method to data tables (Mark Amery) -### Bug Fixes +### Fixed +- Remove CLI resource leak timeout (Julien Biezemans) +- Point to cucumber.io instead of cukes.info (Julien Biezemans) +- Fix mixed tabs and spaces (Mark Amery) +- Use hexadecimal values for console colours (Julien Biezemans) +- Update walkdir module to 0.0.10 (Artem Repko) +- Fix ruby tests on Windows (zs-zs) +- Fix npm test to run on Windows (zs-zs) +- Normalize OS-specific path separators in output assertions (zs-zs) +- Relax check for promises in step definitions (zs-zs) +- Add Ast.Feature.getFeatureElements() (Mark Derbecker) +- Add Util.Collection.sort() (Mark Derbecker) +- Add waffle.io badge (Julien Biezemans) + +## [0.5.1] +### Added +- Support placeholders in scenario outlines (chrismilleruk) +- Add failure exception to scenario object (Mateusz Derks) -* fix unhandled rejections in handlers ([#792](https://github.com/cucumber/cucumber-js/issues/792), yaronassa) +### Fixed +- Fix World example in README (Julien Biezemans) +- Remove moot `version` property from bower.json (Kevin Kirsche) +- Remove obsolete release instruction for bower (Julien Biezemans) +- Add Gitter badge (Julien Biezemans) +- Rephrase spec example (Julien Biezemans) +- Add documentation for attachments (Simon Dean) +- Fix name of Cucumber.Api.Scenario in README (Simon Dean) + +## [0.5.0] +### Added +- Support promises from step definitions (Will Farrell) +- Support synchronous step definitions (Julien Biezemans) -## [1.3.2] (2016-03-20) +### Fixed +- Remove irrelevant feature file (Julien Biezemans) +- Reorganise callback feature (Julien Biezemans) +- Remove unused dependency (Julien Biezemans) +- Document new step definition styles (Julien Biezemans) +- Make step definitions synchronous in example app (Julien Biezemans) -### Bug Fixes +## [0.4.9] +### Added +- Make pretty formatter the default (Julien Biezemans) +- Filter stack traces (close [#157](https://github.com/cucumber/cucumber-js/issues/157), Julien Biezemans) -* dependency: fix use of gherkin to not rely on removed field +### Fixed +- Separate source map from bundle (Julien Biezemans) +- Hint (Julien Biezemans) +- Fix misspelling io.js (Sonny Piers) +- Add 0.12 to supported engines in NPM manifest (Julien Biezemans) +- Fix test script to be more portable (Sam Saccone) +- Force Cucumber for now (Julien Biezemans) +- Bump Cucumber gem to 2.0.0 (Julien Biezemans) +- Explicitly require json module in Ruby stepdefs (Julien Biezemans) +- Add CLI help section for --backtrace (Julien Biezemans) + +## [0.4.8] +### Added +- Support IO.js (Sam Saccone) +- Support Node.js 0.12 (Julien Biezemans) -## [2.0.0-rc.9](https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.8...v2.0.0-rc.9) (2017-03-16) +### Fixed +- Handle BOM and fix regexp for hyphenated languages ([#144](https://github.com/cucumber/cucumber-js/issues/144), Aslak Hellesøy) +- Fix attachment clean up in hooks ([#282](https://github.com/cucumber/cucumber-js/issues/282), nebehr) +- More thorough specs for GherkinLexer. Fix build? (Aslak Hellesøy) +- Add jshintrc (Jesse Harlin) +- Hint lib/ (Julien Biezemans) +- Hint bundler and bin (Julien Biezemans) +- Hint spec/ (Julien Biezemans) +- Be consistent in anonymous function syntax (Julien Biezemans) +- Use named functions for all constructors (Julien Biezemans) +- Indent (Julien Biezemans) +- Add more diagnostics to build (Julien Biezemans) +- Remove unnecessary spaces in shell commands (Julien Biezemans) + +## [0.4.7] +### Fixed +- Do not dispose of step domains (Julien Biezemans) +- Refactor and add debug code (Julien Biezemans) +- Create a single domain per run (Julien Biezemans) +- Add missing AstTreeWalker specs (Julien Biezemans) +- Indent (Julien Biezemans) +- Spec domain enter/exit in AstTreeWalker (Julien Biezemans) + +## [0.4.6] +### Added +- Add --no-snippets flag to CLI (close [#207](https://github.com/cucumber/cucumber-js/issues/207), Krispin Schulz) +- Add strict mode (close [#211](https://github.com/cucumber/cucumber-js/issues/211), Elwyn) +- Add strict mode to volatile configuration (close [#258](https://github.com/cucumber/cucumber-js/issues/258), Jan-Eric Duden) -### Bug Fixes +### Fixed +- Fix code loader on windows (close [#226](https://github.com/cucumber/cucumber-js/issues/226), Gary Taylor) +- Connect to Rubygems through SSL (Julien Biezemans) +- Use Node domain's enter/exit in stepdefs (Julien Biezemans) +- Do not display snippets in build (Julien Biezemans) +- Asynchronously dispose of step domains (Julien Biezemans) +- Change order of tests in build (Julien Biezemans) +- Fix tests to run on Windows (close [#216](https://github.com/cucumber/cucumber-js/issues/216), kostya.misura) +- Fix registerHandler() example in README (Julien Biezemans) +- Fix typo in variable name (Julien Biezemans) +- Fix World property assignment in README example (Julian) +- Unix EOLs (Julien Biezemans) +- Ignore .ruby-* (Julien Biezemans) + +## [0.4.5] +### Fixed +- Fix issue with npm upgrade on node.js v0.8 (Simon Dean) +- Use Node domain to handle asynchronous exceptions (Julien Biezemans) -* dependency: fix use of gherkin to not rely on removed field +## [0.4.4] +### Fixed +- Allow >1 parameter in string step definitions (Craig Morris) +- Don't skip scenario outlines (close [#245](https://github.com/cucumber/cucumber-js/issues/245), Julien Biezemans) +- Bump nopt (Julien Biezemans) +- Bump coffee-script (Julien Biezemans) +- Bump pogo (Julien Biezemans) +- Bump underscore (Julien Biezemans) +- Bump rimraf (Julien Biezemans) +- Bump jasmine-node (Julien Biezemans) +- Bump connect (Julien Biezemans) +- Rewrite bundling system (close [#186](https://github.com/cucumber/cucumber-js/issues/186), Julien Biezemans) +- Rename release script (Julien Biezemans) +- Upgrade NPM on Travis (Julien Biezemans) +- Drop Node 0.6 support (Julien Biezemans) +- Drop Node 0.6 support (manifest) (Julien Biezemans) + +## [0.4.3] +### Fixed +- Scenario outline fixes (Simon Dean) +- Correct the embeddings JSON to match other ports of Cucumber (Simon Dean) -## [2.0.0-rc.8](https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.7...v2.0.0-rc.8) (2017-03-10) +## [0.4.2] +### Added +- Support attachments (close [#189](https://github.com/cucumber/cucumber-js/issues/189), Julien Biezemans) -### Bug Fixes +### Fixed +- Fix world example in main readme (Sam Saccone) +- Update instructings for running tests (Sam Saccone) -* generated step definition snippets are not found ([#732](https://github.com/cucumber/cucumber-js/issues/732), Aslak Hellesøy) -* catch attempt to define duplicate parameter type regular expression ([#780](https://github.com/cucumber/cucumber-js/issues/780), Aslak Hellesøy) -* catch errors in parameter type transform functions (Aslak Hellesøy) +## [0.4.1] +### Added +- Target scenario by line number on CLI (close [#168](https://github.com/cucumber/cucumber-js/issues/168), Simon Lampen) -### New Features +### Fixed +- Ensure no stdout output is lost (Simon Dean) +- Properly tag scenario outlines (close [#195](https://github.com/cucumber/cucumber-js/issues/195), [#197](https://github.com/cucumber/cucumber-js/issues/197), Artur Kania) +- Align snippet comment with Cucumber-Ruby/JVM (close [#150](https://github.com/cucumber/cucumber-js/issues/150), Julien Biezemans) +- Update build badge URL on README (Julien Biezemans) +- Add line number pattern to --help on CLI (Julien Biezemans) +- Document AfterFeatures event (close [#171](https://github.com/cucumber/cucumber-js/issues/171), Eddie Loeffen) +- Include 'features' in *Features events payload (Stanley Shyiko) +- Try to fix build on Travis (Julien Biezemans) +- Remove bower as a dev dependency (close [#191](https://github.com/cucumber/cucumber-js/issues/191), Simon Dean) +- Remove obsolete Travis trick for Node 0.8 (Julien Biezemans) +- Remove development status table from README (Julien Biezemans) +- Help the guy produce changelogs (Julien Biezemans) + +## [0.4.0] +### Added +- Add support for scenario outlines and examples (close [#155](https://github.com/cucumber/cucumber-js/issues/155), Ben Van Treese) +- Add i18n support (close [#156](https://github.com/cucumber/cucumber-js/issues/156), Lukas Degener) -* all async parameter type transform functions (Aslak Hellesøy) -* make all formatters available when requiring +### Changed +- Pass scenario to hooks (Marat Dyatko) +- Minor change to stepdef snippets (JS) (Julien Biezemans) +- Make feature id in JSON output replace all spaces (close #[127](https://github.com/cucumber/cucumber-js/issues/127), Tim Perry) +- Bump CoffeeScript (close [#154](https://github.com/cucumber/cucumber-js/issues/154), Gabe Hayes) -### Deprecations +### Fixed +- Add Hook spec example for single-arg function (close [#143](https://github.com/cucumber/cucumber-js/issues/143), Julien Biezemans) +- Update README with Hook scenario object doc (Julien Biezemans) +- Style (Julien Biezemans) -* `addTransform` was deprecated in favor of `defineParameterType` +## [0.3.3] +### Added +- Output step definition snippets in CoffeeScript (John George Wright) +- Add colors to CLI (Johny Jose) -### Documentation +### Changed +- Add durations to JSON formatter (Simon Dean) -* normalize syntax highlighting ([#726](https://github.com/cucumber/cucumber-js/issues/726), Martin Delille) -* fix setWorldConstructor example +### Fixed +- Bump most dependencies (Julien Biezemans) +- DRY (Julien Biezemans) +- Refactor (Julien Biezemans) -## [2.0.0-rc.7](https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.6...v2.0.0-rc.7) (2017-01-30) +## [0.3.2] +### Added +- Add PogoScript support (Josh Chisholm) +- Add listener and event handler registration (close [#130](https://github.com/cucumber/cucumber-js/issues/130), Paul Shannon) -### Bug Fixes +### Fixed +- Added some nice stats (Aslak Hellesøy) +- Fix spelling of "GitHub" (Peter Suschlik) +- Add Code Climate badge to README (Julien Biezemans) +- Update README.md (Sebastian Schürmann) -* fix after hook run order ([#743](https://github.com/cucumber/cucumber-js/issues/743)) +## [0.3.1] +### Added +- Add DataTable.rows() (Niklas Närhinen) +- Officially support Node 0.10 and 0.11 (Julien Biezemans) -### Documentation +### Changed +- Update cucumber-html (Aslak Hellesøy) +- Bump Gherkin (Julien Biezemans) +- Add options parameter to JSON formatter (Israël Hallé) +- Updated CoffeeScript (Matteo Collina) +- Specify strict coffee-script version number (Julien Biezemans) +- Bump jasmine-node (Julien Biezemans) -* normalize syntax highlighting ([#726](https://github.com/cucumber/cucumber-js/issues/726), (Martin Delille) -* fix addTransform parameter name ([#738](https://github.com/cucumber/cucumber-js/issues/738)) +### Fixed +- Fix travis build Node versions (Julien Biezemans) +- Fix Travis CI configuration (Julien Biezemans) +- Remove words in History (Julien Biezemans) +- Update dev status table in README (Julien Biezemans) +- Update LICENSE (Julien Biezemans) +- Add contributors (Julien Biezemans) +- Move data table scenario to TCK (Julien Biezemans) +- Be consistent in spec matchers (Julien Biezemans) +- Remove cucumber.no.de links (Kim, Jang-hwan) +- Fix broken link in README dev status table ([#118](https://github.com/cucumber/cucumber-js/issues/118), Michael Zedeler) +- Refactor hook-related Given steps in JS stepdefs (Julien Biezemans) +- Refactor failing mapping JS step definitions (Julien Biezemans & Matt Wynne) +- Update README.md to correct error in example for zombie initialization (Tom V) +- Update minor typos in README.md (David Godfrey) + +## [0.3.0] +### Added +- Allow for node-like callback errors (Julien Biezemans) +- Accept multiple features in volatile configuration ([#52](https://github.com/cucumber/cucumber-js/issues/52), Julien Biezemans) -## [2.0.0-rc.6](https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.5...v2.0.0-rc.6) (2017-01-06) +### Fixed +- Add ^ prefix and $ suffix to string-based step definition regexps ([#77](https://github.com/cucumber/cucumber-js/issues/77), Julien Biezemans) +- Allow for unsafe regexp characters in stepdef string patterns ([#77](https://github.com/cucumber/cucumber-js/issues/77), Julien Biezemans) +- Build on Node.js 0.8 on Travis (Julien Biezemans) +- Rewrite README's status table in HTML (Julien Biezemans) +- Bump Gherkin ([#78](https://github.com/cucumber/cucumber-js/issues/78), Julien Biezemans) +- Switch to HTML tables in README (Julien Biezemans) +- Bump Aruba (Julien Biezemans) + +## [0.2.22] +### Added +- Print data tables and doc strings in pretty formatter output ([#89](https://github.com/cucumber/cucumber-js/issues/89), [#81](https://github.com/cucumber/cucumber-js/issues/81), Julien Biezemans) -### New Features +### Fixed +- Exclude unmatched features from AST ([#80](https://github.com/cucumber/cucumber-js/issues/80), Julien Biezemans) -* usage and usage-json formatters -* update error reporting for `registerHandler` errors -* add ability to disable timeout +## [0.2.21] +### Added +- Add bundler (Julien Biezemans) -### Bug Fixes +## [0.2.20] +### Added +- Add JSON formatter ([#79](https://github.com/cucumber/cucumber-js/issues/79), Chris Young) -* update snippets to new support code interface +### Fixed +- Fix data table and tags handling in JSON formatter (Julien Biezemans) +- Force example feature execution order in JSON feature (Julien Biezemans) -## [2.0.0-rc.5](https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.4...v2.0.0-rc.5) (2016-12-22) +## [0.2.19] +### Fixed +- Fix CLI arguments passing ([#83](https://github.com/cucumber/cucumber-js/issues/83), Omar Gonzalez) +- Refactor "summarizer" listener to summary formatter ([#71](https://github.com/cucumber/cucumber-js/issues/71), 28b74ef, Julien Biezemans) +- Add "summary" formatter to available CLI formatters (Julien Biezemans) +- Fix spec example description (Julien Biezemans) -### Breaking Changes +## [0.2.18] +### Fixed +- Replace findit with walkdir to fix file loading on Windows ([#73](https://github.com/cucumber/cucumber-js/issues/73), Aaron Garvey) +- Rename spec file (Julien Biezemans) +- Extract developer documentation from README to CONTRIBUTE (Julien Biezemans) +- Bump browserify (Julien Biezemans) +- Update supported Node.js versions (Julien Biezemans) -* Drop support for Node 0.12 -* format assertion errors to display diffs +## [0.2.17] +### Added +- Add pretty formatter (simplified, monochrome) ([#59](https://github.com/cucumber/cucumber-js/issues/59), @renier, Julien Biezemans) -### Documentation +### Fixed +- Display only master branch build status in README (Julien Biezemans) +- Rename "summary logger" to "summarizer" ([#59](https://github.com/cucumber/cucumber-js/issues/59), Julien Biezemans) +- Extract common formatter methods ([#59](https://github.com/cucumber/cucumber-js/issues/59), [#63](https://github.com/cucumber/cucumber-js/issues/63), Julien Biezemans) -* fix CLI format-options name ([#703](https://github.com/cucumber/cucumber-js/issues/703), Florian Ribon) -* add link on README.md to custom formatters documentation +## [0.2.16] +### Added +- Display failing scenario URIs in summary (Julien Biezemans) -## [2.0.0-rc.4](https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.3...v2.0.0-rc.4) (2016-12-19) +### Fixed +- Ran a gem update (Aslak Hellesøy) +- Update NPM dependencies ([#69](https://github.com/cucumber/cucumber-js/issues/69), Aslak Hellesøy) +- Refactor listener infrastructure ([#35](https://github.com/cucumber/cucumber-js/issues/35), [#59](https://github.com/cucumber/cucumber-js/issues/59), [#63](https://github.com/cucumber/cucumber-js/issues/63), Julien Biezemans) +- Extract summary logger from progress formatter ([#59](https://github.com/cucumber/cucumber-js/issues/59), [#63](https://github.com/cucumber/cucumber-js/issues/63), Julien Biezemans) +- Store URI on AST elements (Julien Biezemans) -### Breaking Changes +## [0.2.15] +### Added +- Handle asynchronous exceptions ([#51](https://github.com/cucumber/cucumber-js/issues/51), Julien Biezemans) -* update support code library interface - instead of exporting a function and calling methods on `this`, require the `cucumber` module and call `defineSupportCode` which passes an object as the first argument whch exposes the methods. Overriding the world constructor has changed from overriding the World property to calling `setWorldConstructor`. +### Fixed +- Remove commented code (Julien Biezemans) - ```javascript - // 1.3.1 - module.exports = function () { - this.Given(/^a step$/, function() {}); - this.World = CustomWorld - }); +## [0.2.14] +### Added +- Mention CS support in README (Julien Biezemans) +- Update command-line documentation in README (Julien Biezemans) - // 2.0.0 - var {defineSupportCode} = require('cucumber'); +### Fixed +- Add alternate binary script for Windows ([#60](https://github.com/cucumber/cucumber-js/issues/60), Julien Biezemans) - defineSupportCode(function({Given, setWorldConstructor}) { - Given(/^a step$/, function() {}); - setWorldConstructor(CustomWorld); - }); - ``` +## [0.2.13] +### Added +- Add support for string-based step definition patterns ([#48](https://github.com/cucumber/cucumber-js/issues/48), Ted de Koning, Julien Biezemans) -## [2.0.0-rc.3](https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.2...v2.0.0-rc.3) (2016-12-19) +### Fixed +- Pass step instance to step definition invocation ([#57](https://github.com/cucumber/cucumber-js/issues/57), Julien Biezemans) +- Refactor step result specs (Julien Biezemans) +- Store step on step results ([#57](https://github.com/cucumber/cucumber-js/issues/57), Julien Biezemans) +- Increase Aruba timeout delay for slow Travis (Julien Biezemans) +- Decouple pattern from regexp in step definition ([#48](https://github.com/cucumber/cucumber-js/issues/48), Julien Biezemans) -### Breaking Changes +## [0.2.12] +### Changed +- Allow World constructor to set explicit World object ([#50](https://github.com/cucumber/cucumber-js/issues/50), Julien Biezemans) -* make strict the default - * previously pending and undefined steps did not cause an exit code of 1. This could be overridden with `--strict`. Strict is now the default and you can use `--no-strict` to return to the previous behavior. -* update automatically required files - * if the features live in a `features` directory at any level, all support files in the `features` directory are loaded. +### Fixed +- Add semicolons (Julien Biezemans) +- Add documentation about World to README (Julien Biezemans) -### Bug Fixes +## [0.2.11] +### Changed +- Simplify World callbacks ([#49](https://github.com/cucumber/cucumber-js/issues/49), Julien Biezemans) -* prevent crash on empty feature file +### Fixed +- Fix callback.fail() when called without any reasons (Julien Biezemans) +- Add toHaveBeenCalledWithInstanceOfConstructorAsNthParameter() spec helper (Julien Biezemans) +- Simplify default World constructor callback (Julien Biezemans) +- Adapt World constructors (Julien Biezemans) -### New Features +## [0.2.10] +### Fixed +- Fix path handling on Windows platforms ([#47](https://github.com/cucumber/cucumber-js/issues/47), Julien Biezemans) +- Add tagged hooks example to README (Julien Biezemans) +- Fix browserify setup for example page load (Julien Biezemans) +- Rename bundle to 'cucumber.js' in web example (Julien Biezemans) +- Remove obsolete browserify directive (Julien Biezemans) +- Improve platform detection (Julien Biezemans) + +## [0.2.9] +### Added +- Add support for tagged hooks ([#32](https://github.com/cucumber/cucumber-js/issues/32), Julien Biezemans) -* validate argument types +### Changed +- Allow for whitespaces in tag groups (Julien Biezemans) -### Documentation +### Fixed +- Add Cucumber.Type.String and String#trim(, Julien Biezemans) +- Remove unnecessary this. from stepdefs (Julien Biezemans) +- Simplify tag-related stepdefs (Julien Biezemans) +- Simplify tag selection syntax in volatile configuration (Julien Biezemans) +- Mark hooks "done" in README dev status (Julien Biezemans) -* docs: fix tag expression migration guide ([#691](https://github.com/cucumber/cucumber-js/issues/691), Aslak Hellesøy) +## [0.2.8] +### Added +- Add around hooks ([#32](https://github.com/cucumber/cucumber-js/issues/32), Julien Biezemans) -## [2.0.0-rc.2](https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.1...v2.0.0-rc.2) (2016-12-04) +### Changed +- Treat undefined and skipped step as any other step (Julien Biezemans) -### Breaking Changes +### Fixed +- Remove unused parameter in parser spec (Julien Biezemans) +- Add JS stepdef for async failing steps scenario (Julien Biezemans) +- Assign zombie in README example ([#44](https://github.com/cucumber/cucumber-js/issues/44), Julien Biezemans) +- Remove trailing spaces (Julien Biezemans) +- Get rid of obsolete PendingStepException (Julien Biezemans) +- Refactor SupportCode.Library spec (Julien Biezemans) +- Add around hooks documentation ([#32](https://github.com/cucumber/cucumber-js/issues/32), Julien Biezemans) + +## [0.2.7] +### Added +- Allow for asynchronous pending steps (Julien Biezemans) +- Allow for asynchronous step failures (Julien Biezemans) -* pass `attach` to world constructor instead of assigning it to world - * the world constructor now receives `{attach, parameters}` as the first argument instead of `parameters` +### Fixed +- Fix matching groups in step definition snippets ([#42](https://github.com/cucumber/cucumber-js/issues/42), Julien Biezemans) +- Remove obsolete dependency from snippet builder spec (Julien Biezemans) +- Add steps to release process in README (Julien Biezemans) +- Update development status table in README (Julien Biezemans) +- Import implementation-specific scenarios from cucumber-tck/undefined_steps (Julien Biezemans) +- Switch from throwing exceptions to callback.fail() in web example (Julien Biezemans) +- Add callback.fail() example to README (Julien Biezemans) + +## [0.2.6] +### Added +- Add tags support ([#7](https://github.com/cucumber/cucumber-js/issues/7), Julien Biezemans) +- Add support for tags on features ([#7](https://github.com/cucumber/cucumber-js/issues/7), Julien Biezemans) -### New Features +### Changed +- Handle missing instance in World constructor callback ([#40](https://github.com/cucumber/cucumber-js/issues/40), Julien Biezemans) -* json formatter: add `isBackground` to steps +### Fixed +- Update development status in README (Julien Biezemans) +- Typo in README (Julien Biezemans) +- Refactor parser and add AST assembler (required by [#7](https://github.com/cucumber/cucumber-js/issues/7), Julien Biezemans) +- Indent properly (Julien Biezemans) +- Refactor AST assembler to be stateful (needed by [#7](https://github.com/cucumber/cucumber-js/issues/7), Julien Biezemans) +- Update master diff in History (Julien Biezemans) +- Add --tags documentation to --help (CLI, Julien Biezemans) + +## [0.2.5] +### Added +- Add Before/After hooks ([#32](https://github.com/cucumber/cucumber-js/issues/32), [#31](https://github.com/cucumber/cucumber-js/issues/31), Tristan Dunn) -### Bug Fixes +### Changed +- Interpret "*" step keyword as a repeat keyword (Julien Biezemans) -* clear timeouts of asynchronous hooks/steps -* stop running features with no scenarios +### Fixed +- Add NPM publishing to README release checklist (Julien Biezemans) +- Add "Help & Support" to README (Julien Biezemans) +- Words in README (Julien Biezemans) +- Document before and after hooks (Julien Biezemans) -### Documentation +## [0.2.4] +### Added +- Add --version to CLI (Julien Biezemans) +- Add --help to CLI (Julien Biezemans) -* update node js example +### Changed +- Add styles for reported errors on web example (Julien Biezemans) +- Make and expect World constructors to be asynchronous ([#39](https://github.com/cucumber/cucumber-js/issues/39), Julien Biezemans) -## [2.0.0-rc.1](https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.0...v2.0.0-rc.1) (2016-11-25) +### Fixed +- Update README (Julien Biezemans) +- Add development status to README (Julien Biezemans) +- Add link to demo at cucumber.no.de (Julien Biezemans) +- Add link to example app to README (Julien Biezemans) +- Add usage documentation to README ([#23](https://github.com/cucumber/cucumber-js/issues/23), Olivier Melcher) +- Add examples to run features with the CLI (Olivier Melcher) +- Fix header levels and whitespaces in README (Julien Biezemans) +- Add Opera to supported browsers in README (Julien Biezemans) +- Fix World constructor in README (Julien Biezemans) +- Simplify World#visit in README (Julien Biezemans) +- Rewrite step definition and wrapper documentation (Julien Biezemans) +- Remove useless words (Julien Biezemans) +- Use more consistent Markdown in README (Julien Biezemans) +- Fix Gherkin comment in README (Julien Biezemans) +- Add credits (Julien Biezemans) +- Add Aruba setup details to README (Julien Biezemans) +- Fix World constructor on web example according to the recent API changes (Julien Biezemans) +- Tell Travis CI to post build results to #cucumber (Julien Biezemans) +- Add release checklist to README (Julien Biezemans) + +## [0.2.3] +### Added +- Add support for Node 0.6 (Julien Biezemans) -### Bug Fixes +### Fixed +- Prevent the same step definition snippet from being suggested twice (Julien Biezemans) +- Don't make NPM ignore `example/` anymore (Julien Biezemans) +- Bump cucumber-features (Julien Biezemans) +- Use non-deprecated "url" key instead of "web" in NPM manifest (Julien Biezemans) +- Add JS step definitions related to data table scenarios (Julien Biezemans) +- Move from cucumber-features to cucumber-tck (Julien Biezemans) +- Bump Gherkin (Julien Biezemans) +- Bump jasmine-node (Julien Biezemans) +- Bump connect (Julien Biezemans) +- Fix Travis build (Julien Biezemans) +- Bump browserify (Julien Biezemans) +- Bump nopt (Julien Biezemans) +- Bump underscore (Julien Biezemans) +- Bump underscore.string (Julien Biezemans) +- Bump rimraf (Julien Biezemans) +- Bump mkdirp (Julien Biezemans) +- Bump Aruba (Julien Biezemans) + +## [0.2.2] +### Added +- Suggest step definition snippets for undefined steps ([#33](https://github.com/cucumber/cucumber-js/issues/33), Julien Biezemans) -* fix browser version +### Fixed +- Add contributors to NPM package manifest (Julien Biezemans) +- Clean up JS step definitions (Julien Biezemans) +- Bump cucumber-features and reflect step changes (Julien Biezemans) +- Set up [continuous integration on Travis CI](http://travis-ci.org/#!/cucumber/cucumber-js) (Julien Biezemans) +- Add Travis's build status icon to README (Julien Biezemans) -## [2.0.0-rc.0](https://github.com/cucumber/cucumber-js/compare/v1.3.1...v2.0.0-rc.0) (2016-11-25) +## [0.2.1] +### Added +- Allow custom World constructors (Julien Biezemans) +- Add support for data tables (with conversion to hashes) ([#12](https://github.com/cucumber/cucumber-js/issues/12), Julien Biezemans) -### Breaking Changes +### Changed +- Demonstrate World object usages in web example (Julien Biezemans) -* Dropped support for Node 0.10 -* CLI - * `--colors / --no-colors` has moved to `--format-options '{"colorsEnabled": }'` - * `--require `: the required files are no longer reordered to require anything in a `support` directory first - * `--snippet-interface ` has moved to `--format-options '{"snippetInterface": ""}'` - * `--snippet-syntax ` has moved to `--format-options '{"snippetSyntax": ""}'` - * `--tags ` now uses [cucumber-tag-expressions](https://docs.cucumber.io/tag-expressions/). It is no longer repeatable and new values will override previous - * `--tags @dev` stays the same - * `--tags ~@dev` becomes `--tags 'not @dev'` - * `--tags @foo,@bar` becomes `--tags '@foo or @bar'` - * `--tags @foo --tags @bar` becomes `--tags '@foo and @bar'` -* Internals - * complete rewrite using ES2015 and promises -* JSON Formatter - * String attachments are no longer base64 encoded. Buffer and Stream attachments are still base64 encoded. -* Support Files - * Attachments - * The `attach` function used for adding attachments moved from the API scenario object to world. It is thus now available in step definitions without saving a reference to the scenario. +## [0.2.0] +### Added +- Setup application to run on [Travis CI](http://travis-ci.org/#!/jbpros/cucumber-js) (Julien Biezemans) +- Add CoffeeScript support for step definition files (Paul Jensen) +- Add "World" ([#26](https://github.com/cucumber/cucumber-js/issues/26), Julien Biezemans) - ```javascript - // 1.3.0 - this.After(function(scenario, callback) { - scenario.attach(new Buffer([137, 80, 78, 71]), 'image/png') - }); +### Changed +- Add link to the Github repository on web example (Julien Biezemans) +- Allow specifying the port the web example server should listen on (Julien Biezemans) +- Update web example to use cucumber-html formatter (Julien Biezemans) - // 2.0.0 - this.After(function() { - this.attach(new Buffer([137, 80, 78, 71]), 'image/png'); - }); - ``` +### Fixed +- Fix load paths in spec helper (Julien Biezemans) +- Prevent 'crypto' module from being included by browserify in web example (Julien Biezemans) +- Fix HTML indentation (Julien Biezemans) +- Prevent CLI support code loader from calling module main exports which are not functions (Julien Biezemans) +- Remove use of username for submodule (Kushal Pisavadia) +- Bump jasmine-node +- Update README (Julien Biezemans) +- Bump Gherkin twice (Julien Biezemans) +- Bump cucumber-features twice (Julien Biezemans) +- Add missing getters on several AST feature elements (mostly getLine()) (Julien Biezemans) +- Ignore example/ on NPM (Julien Biezemans) +- Add Procfile (used by Heroku when deploying to cucumber.heroku.com) (Julien Biezemans) +- Bump Aruba (Julien Biezemans) +- Add guard-jasmine-node (Julien Biezemans) +- Improve Guardfile regular expressions (Julien Biezemans) +- Bump cucumber-html and remove DOM templates from web example HTML file (Julien Biezemans) +- Fix PathExpander internal name (Julien Biezemans) +- Remove unneeded requires from FeaturePathExpander (Julien Biezemans) +- Bump browserify (Julien Biezemans) +- Remove "glob" from dependencies (Julien Biezemans) +- Refactor SupportCodePathExpander spec (Julien Biezemans) +- Add feature for CoffeeScript support ([#29](https://github.com/cucumber/cucumber-js/issues/29), Julien Biezemans) + +## [0.1.5] +### Added +- Add support for background ([#9](https://github.com/cucumber/cucumber-js/issues/9), Julien Biezemans) - * When attaching buffers or strings, the callback argument is ignored. - * Hooks - * Hooks now receive a [ScenarioResult](/src/models/scenario_result.js) instead of the Scenario +### Fixed +- Bump cucumber-features (twice) (Julien Biezemans) +- Bump gherkin and reflect changes in its API (add DocString content type) (Julien Biezemans) - ```javascript - // 1.3.0 - this.After(function(scenario) {}); +## [0.1.4] +### Changed +- Stop polluting the global namespace with Given(), When() and Then() ([#2](https://github.com/cucumber/cucumber-js/issues/2), Julien Biezemans) +- Step definitions can be created with the support code helper passed as 'this': +this.Given(), this.When(), this.Then() and this.defineStep() ([#2](https://github.com/cucumber/cucumber-js/issues/2), Julien Biezemans) - // 2.0.0 - this.After(function(scenarioResult) {}); - ``` +### Fixed +- Fix typo "occured" -> "occurred" (Fernando Acorreia) +- Improve variable names in CLI support code loader (Julien Biezemans) - * The `tags` option for hook should now be a string instead of an array and uses [cucumber-tag-expressions](https://docs.cucumber.io/tag-expressions/) +## [0.1.3] +### Added +- Allow several features to run at once ([#14](https://github.com/cucumber/cucumber-js/issues/14), Julien Biezemans) +- Add support for --require (Julien Biezemans) - ```javascript - // 1.3.0 - this.Before({tags: ["@foo"]}, function (scenario) {}) - this.Before({tags: ["@foo,@bar"]}, function (scenario) {}) - this.Before({tags: ["@foo", "@bar"]}, function (scenario) {}) +### Fixed +- Improve features and support code API (Julien Biezemans) +- Add "Cli" and "Volatile" configurations (Julien Biezemans) +- Internal refactoring and cleanup (Julien Biezemans) +- Cucumber.js can now fully test itself (Julien Biezemans) +- Remove run_all_features script in favor of bin/cucumber.js (Julien Biezemans) - // 2.0.0 - this.Before({tags: "@foo"}, function (scenario) {}) - this.Before({tags: "@foo and @bar"}, function (scenario) {}) - this.Before({tags: "@foo or @bar"}, function (scenario) {}) - ``` +## [0.1.2] +### Added +- Add failure reporting to the progress formatter ([#20](https://github.com/cucumber/cucumber-js/issues/20), Julien Biezemans) - * Step Definitions - * String patterns were removed in favor [cucumber-expressions](https://docs.cucumber.io/cucumber-expressions/) - * Regular Expressions - * capture groups matching `(-?\d+)` will be automatically converted to an integer using `parseInt` - * capture groups matching `(-?\d*\.?\d+)` will be automatically converted to a float using `parseFloat` - * Generator functions are no longer automatically run with `co`. To retain the previous functionality, use [this.setDefinitionFunctionWrapper](/docs/support_files/step_definitions.md#definition-function-wrapper) - * Event Handlers - * Objects no longer have `get*` methods and instead have exposed properties - * For example: `scenario.getName()` is now just `scenario.name` - * `StepResult` duration is now in milliseconds instead of nanoseconds +## [0.1.1] +### Added +- Publish Cucumber.js to NPM as [`cucumber`](https://www.npmjs.com/search?q=cucumber) (Julien Biezemans) -### Bug Fixes +### Changed +- Throw a clearer exception on missing feature argument (CLI) (Julien Biezemans) -* remove empty lines from `@rerun` files ([#660](https://github.com/cucumber/cucumber-js/issues/660), Cody Ray Hoeft) -* catch uncaught errors in the browser (Charlie Rudolph) +### Fixed +- Unify and clean up js-specific features and step definitions ([#21](https://github.com/cucumber/cucumber-js/issues/21), Julien Biezemans) -### New Features +## [0.1.0] +### Added +- Add cucumber.js executable (Julien Biezemans) +- Handle step failures ([#6](https://github.com/cucumber/cucumber-js/issues/6), Julien Biezemans) +- Add the progress formatter ([#16](https://github.com/cucumber/cucumber-js/issues/16), Julien Biezemans) +- Add support for pending steps ([#18](https://github.com/cucumber/cucumber-js/issues/18), Julien Biezemans) +- Add support for undefined steps ([#19](https://github.com/cucumber/cucumber-js/issues/19), Julien Biezemans) -* Support Files - * Attachments: - * When attaching a stream, the interface can either accept a callback as a third argument or will return a promise if not passed a callback - * Step Definitions - * Ability to add custom argument transformations -* Fail fast / rerun formatter - * When used together rerun formatter will output all skipped scenarios that didn't run due to a failure +### Changed +- Update web example to use the new progress formatter (Julien Biezemans) -### Documentation - -* fix typo ([#659](https://github.com/cucumber/cucumber-js/issues/659), gforceg) -* update support files api reference ([#661](https://github.com/cucumber/cucumber-js/issues/661), Zearin) - -## [1.3.1] (2016-09-30) - -### Bug Fixes - -* pass formatter options to listener ([#641](https://github.com/cucumber/cucumber-js/issues/641), Charlie Rudolph) -* rerun formatter: output any scenario that doesn't pass (Charlie Rudolph) -* populate scenario definition ([#647](https://github.com/cucumber/cucumber-js/issues/647), Charlie Rudolph) -* handle empty stacktraces ([#605](https://github.com/cucumber/cucumber-js/issues/605), Hugues Malphettes) -* use cross-platform symbols ([#635](https://github.com/cucumber/cucumber-js/issues/635), Kevin Goslar) - -### Documentation - -* fix node.js example ([#637](https://github.com/cucumber/cucumber-js/issues/637), Jonathan Gomez) -* fix links in event_handlers.md ([#638](https://github.com/cucumber/cucumber-js/issues/638), Oliver Rogers) -* fix hooks example ([#644](https://github.com/cucumber/cucumber-js/issues/644), John McLaughlin) - -## [1.3.0] (2016-09-08) - -### New Features - -* add `--snippet-interface ` CLI option (Charlie Rudolph) -* add `--world-parameters ` CLI option (Charlie Rudolph) -* add snippets formatter (Charlie Rudolph) -* add support for ES6 default module syntax (dbillingham) -* pretty formatter: add symbols (Charlie Rudolph) -* add simplified hook parameters (Charlie Rudolph) - -### Bug Fixes - -* step definition snippets internationalization (Charlie Rudolph) - -### Documentation - -* document order of execution for multiple hooks (John McLaughlin) -* breakup README.md, organize docs (Charlie Rudolph) - -## [1.2.2] (2016-08-05) - -### Bug Fixes - -* Fix error when stack trace has no frames ([#610](https://github.com/cucumber/cucumber-js/issues/610), Jan Molak) - -## [1.2.1] (2016-07-01) - -### Bug Fixes - -* Fix hook / step definition location and stacktraces in the browser ([#567](https://github.com/cucumber/cucumber-js/issues/567), [#538](https://github.com/cucumber/cucumber-js/issues/538), Charlie Rudolph) - -## [1.2.0] (2016-06-24) - -### Bug Fixes - -* Attachments - * Remove intermediate conversion to string (Charlie Rudolph) - * Use native base64 encoding which can encode binary ([#589](https://github.com/cucumber/cucumber-js/issues/589), Benjamín Eidelman) - -## [1.1.0] (2016-06-23) - -### New Features - -* Add full support to `registerHandler` (Charlie Rudolph) - * Can now use all supported functions interfaces (synchronous, callback, promise, generators) - * Will throw any error received and immediately kill the test suite - * Supports handler specific timeouts - * Updated documentation - -### Bug Fixes - -* CLI format: support absolute path on windows (Charlie Rudolph) -* Fix typo in event name. ([#590](https://github.com/cucumber/cucumber-js/issues/590), Artur Pomadowski) -* Don't run hooks in dry run mode (Charlie Rudolph) - -## [1.0.0] (2016-05-30) - -### Bug Fixes - -* Escape all instances of special characters in example / data table (Charlie Rudolph) - -## [0.10.4] (2016-05-30) - -### New Features - -* Allow time to be faked by utilities such as `sinon.useFakeTimers` (John McLaughlin) - -## [0.10.3] (2016-05-19) - -### Bug Fixes - -* Escape newlines in table cells in pretty formatter (Julien Biezemans) -* Fix handling of unusual error objects (efokschaner) - -## [0.10.2] (2016-04-07) - -### New Features - -* Add match location to JSON formatter output (Charlie Rudolph) - -### Bug Fixes - -* Undefined background step (Scott Deakin) - -## [0.10.1] (2016-04-01) - -### New Features - -* Support generators for hooks/step definitions (Ádám Gólya) - -## [0.10.0] (2016-04-01) - -### Breaking changes - -* removed around hooks (Charlie Rudolph) - * how to update: use separate before and after hooks. If this is not sufficient, please create an issue. - -* updated pending step interface (Charlie Rudolph) - * how to update: change `callback.pending()` to `callback(null, 'pending')` or use one of the new pending step interfaces - -* updated tagged hook interface (Charlie Rudolph) - * how to update: - - ```javascript - this.Before('@tagA', function() { ... }) - // becomes - this.Before({tags: ['@tagA']}, function() { ... }) - - this.Before('@tagA', '@tagB,@tagC', function() { ... }) - // becomes - this.Before({tags: ['@tagA', '@tagB,@tagC']}, function() { ... }) - ``` - - -### New Features - -* support hook specific timeouts (Charlie Rudolph) -* reworked formatter error reporting (Charlie Rudolph) - -## [0.9.5] (2016-02-16) - -### Bug Fixes - -* Fix rerun formatter output (Charlie Rudolph) - -### New Features - -* Allow rerun file to be in subfolder (Charlie Rudolph) - -## [0.9.4] (2016-01-28) - -### Bug Fixes - -* Publish release folder to npm (Charlie Rudolph) - -## [0.9.3] (2016-01-27) - -### New Features - -* Run scenario by name (Charlie Rudolph) - -### Bug Fixes - -* Prevent maximum call stack from being exceeded (John Krull) - -### Documentation - -* Add documentation of profiles (Charlie Rudolph) -* README improvements (Miika Hänninen, Kevin Goslar, Maxim Koretskiy) - -## [0.9.2] - -### New Features - -* Bump stack-chain (Rick Lee-Morlang) - -## [0.9.1] - -### New Features - -* Add rerun formatter (Charlie Rudolph) - -### Fixes - -* Add ability to execute scenario outline example (Charlie Rudolph) -* Support tags on scenario outline examples (Charlie Rudolph) - -### Documentation - -* Fix invalid hook documentation (Charlie Rudolph) - -## [0.9.0] - -### Breaking changes - -* catch ambiguous step definitions (Charlie Rudolph) -* remove use of domain (Charlie Rudolph) - -### New Features - -* pretty formatter: source shows step definition location (Charlie Rudolph) -* support node 5 (Charlie Rudolph) - -### Fixes - -* Fix `Api.Scenario#attach` callback handling (Julien Biezemans) - -### Documentation - -* Add async example to README (Artem Bronitsky) -* Document hooks sync/async protocols (Julien Biezemans) -* Remove useless callbacks in documentation (Julien Biezemans) -* Fix browser example (Karine Pires) - -## [v0.8.1] - -### Documentation, internals and tests - -* Update World constructor documentation (Charlie Rudolph) -* Remove badges from README.md (Charlie Rudolph) - -## [v0.8.0] - -### Breaking changes - -* Add strict function length checking to hooks and step definitions (Charlie Rudolph) -* Make World constructors strictly synchronous (Julien Biezemans) - -### New features - -* Add cli option to fail fast (Charlie Rudolph) -* Add cli for specifying multiple formatters (Charlie Rudolph) -* Add support for passing multiple line numbers (Charlie Rudolph) -* Add ability to disable colors (Charlie Rudolph) -* Add support for custom snippet syntaxes (Charlie Rudolph) - -### Changed features - -* Hide errors in pretty formatter summary (Charlie Rudolph) -* Remove unnecessary whitespaces in pretty formatter output (Charlie Rudolph) - -### Fixes - -* Properly ask configurations for strict mode (Julien Biezemans) - -### Documentation, internals and tests - -* Document data table interface (Charlie Rudolph) -* Refactor: statuses (Charlie Rudolph) -* Refactor: cleanup step definitions (Charlie Rudolph) -* Cleanup: remove log to console from listeners (Charlie Rudolph) -* Use svg badges (Charlie Rudolph) -* Rename CONTRIBUTE.md to CONTRIBUTING.md (Julien Biezemans) -* Require maintainers to document API changes in release tag descriptions (Julien Biezemans) -* Add build-release NPM script (Julien Biezemans) - -## [v0.7.0] - -### New features - -* Time out steps that take too long (Charles Rudolph) -* Print execution time (Charles Rudolph) - -### Changed features - -* Remove callback.fail() (Charles Rudolph) -* Update hooks interface (Charles Rudolph) - -### Fixes - -* Don't try to handle empty features (Julien Biezemans) -* Fix unpredictable nopt behavior (Charles Rudolph) -* Fix pretty formatter step indentation after doc string (Charles Rudolph) - -### Documentation, internals and tests - -* Rename Collection functions: forEach/syncForEach -> asyncForEach/forEach (Charles Rudolph) -* Simplify installation instructions (Charles Rudolph) -* Fix spec on Windows (Marcel Hoyer) -* Simplify World examples in README (Charles Rudolph) -* Update license in package.json (Charles Rudolph) -* Convert test framework from jasmine-node to jasmine (Charles Rudolph) -* Separate test output (Charles Rudolph) -* Remove ruby, legacy features, cucumber-tck (Charles Rudolph) - -## [v0.6.0] - -### New features - -* Add --no-source to hide uris (Eddie Loeffen) -* Add dry run capability (Karthik Viswanath) -* Introduce --compiler CLI option (Charles Rudolph) - -### Documentation, internals and tests - -* Stop IRC and email notifications from Travis (Julien Biezemans) -* Remove Node.js 0.11 explicit support (Julien Biezemans) -* Use basic for loop for array iterations (Charles Rudolph) -* Bump browserify (Charles Rudolph) -* Add CLI help for --profile (Charles Rudolph) -* Use colors library (Charles Rudolph) -* Improve --compiler help (Julien Biezemans) -* Fix loading of external compiler modules (Julien Biezemans) -* Document a few common compiler usages (Julien Biezemans) - -## [v0.5.3] - -### New features - -* Add support for profiles (Charles Rudolph) - -### Changed features - -* Allow for multiple instances of placeholder (Charles Rudolph) -* Print relative paths in summary output (Charles Rudolph) - -### Fixes - -* Remove duplicate line number from output (Charles Rudolph) -* Return clone of array from DataTable.Row.raw() (Julien Biezemans) - -### Documentation, internals and tests - -* Update various urls (Dale Gardner) -* Bump CoffeeScript (Julien Biezemans) -* Bump PogoScript (Julien Biezemans) -* Bump underscore (Julien Biezemans) -* Bump underscore.string (Julien Biezemans) -* Bump stack-chain (Julien Biezemans) -* Bump nopt (Julien Biezemans) -* Bump connect (Julien Biezemans) -* Bump exorcist (Julien Biezemans) -* Bump uglifyify (Julien Biezemans) -* Bump through (Julien Biezemans) -* Bump serve-static (Julien Biezemans) -* Bump rimraf (Julien Biezemans) -* Bump mkdirp (Julien Biezemans) -* Bump jshint (Julien Biezemans) -* Remove extra bracket in README example (Julien Biezemans) -* Officially support Node.js 4.x (Julien Biezemans) -* Use a profile for own build (Julien Biezemans) - -## [v0.5.2] - -### New features - -* Add rowsHash method to data tables (Mark Amery) - -### Documentation, internals and tests - -* Remove CLI resource leak timeout (Julien Biezemans) -* Point to cucumber.io instead of cukes.info (Julien Biezemans) -* Fix mixed tabs and spaces (Mark Amery) -* Use hexadecimal values for console colours (Julien Biezemans) -* Update walkdir module to 0.0.10 (Artem Repko) -* Fix ruby tests on Windows (zs-zs) -* Fix npm test to run on Windows (zs-zs) -* Normalize OS-specific path separators in output assertions (zs-zs) -* Relax check for promises in step definitions (zs-zs) -* Add Ast.Feature.getFeatureElements() (Mark Derbecker) -* Add Util.Collection.sort() (Mark Derbecker) -* Add waffle.io badge (Julien Biezemans) - -## [v0.5.1] - -### New features - -* Support placeholders in scenario outlines (chrismilleruk) -* Add failure exception to scenario object (Mateusz Derks) - -### Documentation, internals and tests - -* Fix World example in README (Julien Biezemans) -* Remove moot `version` property from bower.json (Kevin Kirsche) -* Remove obsolete release instruction for bower (Julien Biezemans) -* Add Gitter badge (Julien Biezemans) -* Rephrase spec example (Julien Biezemans) -* Add documentation for attachments (Simon Dean) -* Fix name of Cucumber.Api.Scenario in README (Simon Dean) - -## [v0.5.0] - -### New features - -* Support promises from step definitions (Will Farrell) -* Support synchronous step definitions (Julien Biezemans) - -### Documentation, internals and tests - -* Remove irrelevant feature file (Julien Biezemans) -* Reorganise callback feature (Julien Biezemans) -* Remove unused dependency (Julien Biezemans) -* Document new step definition styles (Julien Biezemans) -* Make step definitions synchronous in example app (Julien Biezemans) - -## [v0.4.9] - -### New features - -* Make pretty formatter the default (Julien Biezemans) -* Filter stack traces (close [#157](https://github.com/cucumber/cucumber-js/issues/157), Julien Biezemans) - -### Documentation, internals and tests - -* Separate source map from bundle (Julien Biezemans) -* Hint (Julien Biezemans) -* Fix misspelling io.js (Sonny Piers) -* Add 0.12 to supported engines in NPM manifest (Julien Biezemans) -* Fix test script to be more portable (Sam Saccone) -* Force Cucumber <2 for now (Julien Biezemans) -* Bump Cucumber gem to 2.0.0 (Julien Biezemans) -* Explicitly require json module in Ruby stepdefs (Julien Biezemans) -* Add CLI help section for --backtrace (Julien Biezemans) - -## [v0.4.8] - -### New features - -* Support IO.js (Sam Saccone) -* Support Node.js 0.12 (Julien Biezemans) - -### Fixes - -* Handle BOM and fix regexp for hyphenated languages ([#144](https://github.com/cucumber/cucumber-js/issues/144), Aslak Hellesøy) -* Fix attachment clean up in hooks ([#282](https://github.com/cucumber/cucumber-js/issues/282), nebehr) - -### Documentation, internals and tests - -* More thorough specs for GherkinLexer. Fix build? (Aslak Hellesøy) -* Add jshintrc (Jesse Harlin) -* Hint lib/ (Julien Biezemans) -* Hint bundler and bin (Julien Biezemans) -* Hint spec/ (Julien Biezemans) -* Be consistent in anonymous function syntax (Julien Biezemans) -* Use named functions for all constructors (Julien Biezemans) -* Indent (Julien Biezemans) -* Add more diagnostics to build (Julien Biezemans) -* Remove unnecessary spaces in shell commands (Julien Biezemans) - -## [v0.4.7] - -### Documentation, internals and tests - -* Do not dispose of step domains (Julien Biezemans) -* Refactor and add debug code (Julien Biezemans) -* Create a single domain per run (Julien Biezemans) -* Add missing AstTreeWalker specs (Julien Biezemans) -* Indent (Julien Biezemans) -* Spec domain enter/exit in AstTreeWalker (Julien Biezemans) - -## [v0.4.6] - -### New features - -* Add --no-snippets flag to CLI (close [#207](https://github.com/cucumber/cucumber-js/issues/207), Krispin Schulz) -* Add strict mode (close [#211](https://github.com/cucumber/cucumber-js/issues/211), Elwyn) -* Add strict mode to volatile configuration (close [#258](https://github.com/cucumber/cucumber-js/issues/258), Jan-Eric Duden) - -### Fixes - -* Fix code loader on windows (close [#226](https://github.com/cucumber/cucumber-js/issues/226), Gary Taylor) - -### Documentation, internals and tests - -* Connect to Rubygems through SSL (Julien Biezemans) -* Use Node domain's enter/exit in stepdefs (Julien Biezemans) -* Do not display snippets in build (Julien Biezemans) -* Asynchronously dispose of step domains (Julien Biezemans) -* Change order of tests in build (Julien Biezemans) -* Fix tests to run on Windows (close [#216](https://github.com/cucumber/cucumber-js/issues/216), kostya.misura) -* Fix registerHandler() example in README (Julien Biezemans) -* Fix typo in variable name (Julien Biezemans) -* Fix World property assignment in README example (Julian) -* Unix EOLs (Julien Biezemans) -* Ignore .ruby-* (Julien Biezemans) - -## [v0.4.5] - -### Documentation, internals and tests - -* Fix issue with npm upgrade on node.js v0.8 (Simon Dean) -* Use Node domain to handle asynchronous exceptions (Julien Biezemans) - -## [v0.4.4] - -### Fixes - -* Allow >1 parameter in string step definitions (Craig Morris) -* Don't skip scenario outlines (close [#245](https://github.com/cucumber/cucumber-js/issues/245), Julien Biezemans) - -### Documentation, internals and tests - -* Bump nopt (Julien Biezemans) -* Bump coffee-script (Julien Biezemans) -* Bump pogo (Julien Biezemans) -* Bump underscore (Julien Biezemans) -* Bump rimraf (Julien Biezemans) -* Bump jasmine-node (Julien Biezemans) -* Bump connect (Julien Biezemans) -* Rewrite bundling system (close [#186](https://github.com/cucumber/cucumber-js/issues/186), Julien Biezemans) -* Rename release script (Julien Biezemans) -* Upgrade NPM on Travis (Julien Biezemans) -* Drop Node 0.6 support (Julien Biezemans) -* Drop Node 0.6 support (manifest) (Julien Biezemans) - -## [v0.4.3] - -### Fixes - -* Scenario outline fixes (Simon Dean) -* Correct the embeddings JSON to match other ports of Cucumber (Simon Dean) - -## [v0.4.2] - -### New features - -* Support attachments (close [#189](https://github.com/cucumber/cucumber-js/issues/189), Julien Biezemans) - -### Documentation, internals and tests - -* Fix world example in main readme (Sam Saccone) -* Update instructings for running tests (Sam Saccone) - -## [v0.4.1] - -### New features - -* Target scenario by line number on CLI (close [#168](https://github.com/cucumber/cucumber-js/issues/168), Simon Lampen) - -### Fixes - -* Ensure no stdout output is lost (Simon Dean) -* Properly tag scenario outlines (close [#195](https://github.com/cucumber/cucumber-js/issues/195), [#197](https://github.com/cucumber/cucumber-js/issues/197), Artur Kania) - -### Documentation, internals and tests - -* Align snippet comment with Cucumber-Ruby/JVM (close [#150](https://github.com/cucumber/cucumber-js/issues/150), Julien Biezemans) -* Update build badge URL on README (Julien Biezemans) -* Add line number pattern to --help on CLI (Julien Biezemans) -* Document AfterFeatures event (close [#171](https://github.com/cucumber/cucumber-js/issues/171), Eddie Loeffen) -* Include 'features' in *Features events payload (Stanley Shyiko) -* Try to fix build on Travis (Julien Biezemans) -* Remove bower as a dev dependency (close [#191](https://github.com/cucumber/cucumber-js/issues/191), Simon Dean) -* Remove obsolete Travis trick for Node 0.8 (Julien Biezemans) -* Remove development status table from README (Julien Biezemans) -* Help the guy produce changelogs (Julien Biezemans) - -## [v0.4.0] - -### New features - -* Add support for scenario outlines and examples (close [#155](https://github.com/cucumber/cucumber-js/issues/155), Ben Van Treese) -* Add i18n support (close [#156](https://github.com/cucumber/cucumber-js/issues/156), Lukas Degener) - -### Changed features - -* Pass scenario to hooks (Marat Dyatko) -* Minor change to stepdef snippets (JS) (Julien Biezemans) -* Make feature id in JSON output replace all spaces (close #[127](https://github.com/cucumber/cucumber-js/issues/127), Tim Perry) -* Bump CoffeeScript (close [#154](https://github.com/cucumber/cucumber-js/issues/154), Gabe Hayes) - -### Documentation, internals and tests - -* Add Hook spec example for single-arg function (close [#143](https://github.com/cucumber/cucumber-js/issues/143), Julien Biezemans) -* Update README with Hook scenario object doc (Julien Biezemans) -* Style (Julien Biezemans) - -## [v0.3.3] - -### New features - -* Output step definition snippets in CoffeeScript (John George Wright) -* Add colors to CLI (Johny Jose) - -### Changed features - -* Add durations to JSON formatter (Simon Dean) - -### Documentation, internals and tests - -* Bump most dependencies (Julien Biezemans) -* DRY (Julien Biezemans) -* Refactor (Julien Biezemans) - -## [v0.3.2] - -### New features - -* Add PogoScript support (Josh Chisholm) -* Add listener and event handler registration (close [#130](https://github.com/cucumber/cucumber-js/issues/130), Paul Shannon) - -### Documentation, internals and tests - -* Added some nice stats (Aslak Hellesøy) -* Fix spelling of "GitHub" (Peter Suschlik) -* Add Code Climate badge to README (Julien Biezemans) -* Update README.md (Sebastian Schürmann) - -## [v0.3.1] - -### New features - -* Add DataTable.rows() (Niklas Närhinen) -* Officially support Node 0.10 and 0.11 (Julien Biezemans) - -### Changed features - -* Update cucumber-html (Aslak Hellesøy) -* Bump Gherkin (Julien Biezemans) -* Add options parameter to JSON formatter (Israël Hallé) -* Updated CoffeeScript (Matteo Collina) -* Specify strict coffee-script version number (Julien Biezemans) -* Bump jasmine-node (Julien Biezemans) - -### Fixes - -* Fix travis build Node versions (Julien Biezemans) -* Fix Travis CI configuration (Julien Biezemans) - -### Documentation, internals and tests - -* Remove words in History (Julien Biezemans) -* Update dev status table in README (Julien Biezemans) -* Update LICENSE (Julien Biezemans) -* Add contributors (Julien Biezemans) -* Move data table scenario to TCK (Julien Biezemans) -* Be consistent in spec matchers (Julien Biezemans) -* Remove cucumber.no.de links (Kim, Jang-hwan) -* Fix broken link in README dev status table ([#118](https://github.com/cucumber/cucumber-js/issues/118), Michael Zedeler) -* Refactor hook-related Given steps in JS stepdefs (Julien Biezemans) -* Refactor failing mapping JS step definitions (Julien Biezemans & Matt Wynne) -* Update README.md to correct error in example for zombie initialization (Tom V) -* Update minor typos in README.md (David Godfrey) - - - -## [v0.3.0] - -### New features - -* Allow for node-like callback errors (Julien Biezemans) -* Accept multiple features in volatile configuration ([#52](https://github.com/cucumber/cucumber-js/issues/52), Julien Biezemans) - -### Fixes - -* Add ^ prefix and $ suffix to string-based step definition regexps ([#77](https://github.com/cucumber/cucumber-js/issues/77), Julien Biezemans) -* Allow for unsafe regexp characters in stepdef string patterns ([#77](https://github.com/cucumber/cucumber-js/issues/77), Julien Biezemans) - -### Documentation, internals and tests - -* Build on Node.js 0.8 on Travis (Julien Biezemans) -* Rewrite README's status table in HTML (Julien Biezemans) -* Bump Gherkin ([#78](https://github.com/cucumber/cucumber-js/issues/78), Julien Biezemans) -* Switch to HTML tables in README (Julien Biezemans) -* Bump Aruba (Julien Biezemans) - - - -## [v0.2.x](https://github.com/cucumber/cucumber-js/compare/v0.2.0...v0.3.0^) - -## [v0.2.22] - -### New features - -* Print data tables and doc strings in pretty formatter output ([#89](https://github.com/cucumber/cucumber-js/issues/89), [#81](https://github.com/cucumber/cucumber-js/issues/81), Julien Biezemans) - -### Fixes - -* Exclude unmatched features from AST ([#80](https://github.com/cucumber/cucumber-js/issues/80), Julien Biezemans) - - - -## [v0.2.21] - -### New features - -* Add bundler (Julien Biezemans) - - - -**TBD** - -## [v0.2.20] - -### New features - -* Add JSON formatter ([#79](https://github.com/cucumber/cucumber-js/issues/79), Chris Young) - -### Fixes - -* Fix data table and tags handling in JSON formatter (Julien Biezemans) - -### Documentation, internals and tests - -* Force example feature execution order in JSON feature (Julien Biezemans) - - - -## [v0.2.19] - -### Fixes - -* Fix CLI arguments passing ([#83](https://github.com/cucumber/cucumber-js/issues/83), Omar Gonzalez) - -### Documentation, internals and tests - -* Refactor "summarizer" listener to summary formatter ([#71](https://github.com/cucumber/cucumber-js/issues/71), 28b74ef, Julien Biezemans) -* Add "summary" formatter to available CLI formatters (Julien Biezemans) -* Fix spec example description (Julien Biezemans) - - - -## [v0.2.18] - -### Fixes - -* Replace findit with walkdir to fix file loading on Windows ([#73](https://github.com/cucumber/cucumber-js/issues/73), Aaron Garvey) - -### Documentation, internals and tests - -* Rename spec file (Julien Biezemans) -* Extract developer documentation from README to CONTRIBUTE (Julien Biezemans) -* Bump browserify (Julien Biezemans) -* Update supported Node.js versions (Julien Biezemans) - - - -## [v0.2.17] - -### New features - -* Add pretty formatter (simplified, monochrome) ([#59](https://github.com/cucumber/cucumber-js/issues/59), @renier, Julien Biezemans) - -### Documentation, internals and tests - -* Display only master branch build status in README (Julien Biezemans) -* Rename "summary logger" to "summarizer" ([#59](https://github.com/cucumber/cucumber-js/issues/59), Julien Biezemans) -* Extract common formatter methods ([#59](https://github.com/cucumber/cucumber-js/issues/59), [#63](https://github.com/cucumber/cucumber-js/issues/63), Julien Biezemans) - - - -## [v0.2.16] - -### New features - -* Display failing scenario URIs in summary (Julien Biezemans) - -### Documentation, internals and tests - -* Ran a gem update (Aslak Hellesøy) -* Update NPM dependencies ([#69](https://github.com/cucumber/cucumber-js/issues/69), Aslak Hellesøy) -* Refactor listener infrastructure ([#35](https://github.com/cucumber/cucumber-js/issues/35), [#59](https://github.com/cucumber/cucumber-js/issues/59), [#63](https://github.com/cucumber/cucumber-js/issues/63), Julien Biezemans) -* Extract summary logger from progress formatter ([#59](https://github.com/cucumber/cucumber-js/issues/59), [#63](https://github.com/cucumber/cucumber-js/issues/63), Julien Biezemans) -* Store URI on AST elements (Julien Biezemans) - - - -## [v0.2.15] - -### New features - -* Handle asynchronous exceptions ([#51](https://github.com/cucumber/cucumber-js/issues/51), Julien Biezemans) - -### Documentation, internals and tests - -* Remove commented code (Julien Biezemans) - - - -## [v0.2.14] - -### New features - -* Mention CS support in README (Julien Biezemans) -* Update command-line documentation in README (Julien Biezemans) - -### Fixes - -* Add alternate binary script for Windows ([#60](https://github.com/cucumber/cucumber-js/issues/60), Julien Biezemans) - - - -## [v0.2.13] - -### New features - -* Add support for string-based step definition patterns ([#48](https://github.com/cucumber/cucumber-js/issues/48), Ted de Koning, Julien Biezemans) - -### Documentation, internals and tests - -* Pass step instance to step definition invocation ([#57](https://github.com/cucumber/cucumber-js/issues/57), Julien Biezemans) -* Refactor step result specs (Julien Biezemans) -* Store step on step results ([#57](https://github.com/cucumber/cucumber-js/issues/57), Julien Biezemans) -* Increase Aruba timeout delay for slow Travis (Julien Biezemans) -* Decouple pattern from regexp in step definition ([#48](https://github.com/cucumber/cucumber-js/issues/48), Julien Biezemans) - - - -## [v0.2.12] - -### Changed features - -* Allow World constructor to set explicit World object ([#50](https://github.com/cucumber/cucumber-js/issues/50), Julien Biezemans) - -### Documentation, internals and tests - -* Add semicolons (Julien Biezemans) -* Add documentation about World to README (Julien Biezemans) - - - -## [v0.2.11] - -### Changed features - -* Simplify World callbacks ([#49](https://github.com/cucumber/cucumber-js/issues/49), Julien Biezemans) - -### Fixes - -* Fix callback.fail() when called without any reasons (Julien Biezemans) - -### Documentation, internals and tests - -* Add toHaveBeenCalledWithInstanceOfConstructorAsNthParameter() spec helper (Julien Biezemans) -* Simplify default World constructor callback (Julien Biezemans) -* Adapt World constructors (Julien Biezemans) - - - -## [v0.2.10] - -### Fixes - -* Fix path handling on Windows platforms ([#47](https://github.com/cucumber/cucumber-js/issues/47), Julien Biezemans) - -### Documentation, internals and tests - -* Add tagged hooks example to README (Julien Biezemans) -* Fix browserify setup for example page load (Julien Biezemans) -* Rename bundle to 'cucumber.js' in web example (Julien Biezemans) -* Remove obsolete browserify directive (Julien Biezemans) -* Improve platform detection (Julien Biezemans) - - - -## [v0.2.9] - -### New features - -* Add support for tagged hooks ([#32](https://github.com/cucumber/cucumber-js/issues/32), Julien Biezemans) - -### Changed features - -* Allow for whitespaces in tag groups (Julien Biezemans) - -### Documentation, internals and tests - -* Add Cucumber.Type.String and String#trim(, Julien Biezemans) -* Remove unnecessary this. from stepdefs (Julien Biezemans) -* Simplify tag-related stepdefs (Julien Biezemans) -* Simplify tag selection syntax in volatile configuration (Julien Biezemans) -* Mark hooks "done" in README dev status (Julien Biezemans) - - - -## [v0.2.8] - -### New features - -* Add around hooks ([#32](https://github.com/cucumber/cucumber-js/issues/32), Julien Biezemans) - -### Changed features - -* Treat undefined and skipped step as any other step (Julien Biezemans) - -### Documentation, internals and tests - -* Remove unused parameter in parser spec (Julien Biezemans) -* Add JS stepdef for async failing steps scenario (Julien Biezemans) -* Assign zombie in README example ([#44](https://github.com/cucumber/cucumber-js/issues/44), Julien Biezemans) -* Remove trailing spaces (Julien Biezemans) -* Get rid of obsolete PendingStepException (Julien Biezemans) -* Refactor SupportCode.Library spec (Julien Biezemans) -* Add around hooks documentation ([#32](https://github.com/cucumber/cucumber-js/issues/32), Julien Biezemans) - - - -## [v0.2.7] - -### New features - -* Allow for asynchronous pending steps (Julien Biezemans) -* Allow for asynchronous step failures (Julien Biezemans) - -### Fixes - -* Fix matching groups in step definition snippets ([#42](https://github.com/cucumber/cucumber-js/issues/42), Julien Biezemans) -* Remove obsolete dependency from snippet builder spec (Julien Biezemans) - -### Documentation, internals and tests - -* Add steps to release process in README (Julien Biezemans) -* Update development status table in README (Julien Biezemans) -* Import implementation-specific scenarios from cucumber-tck/undefined_steps (Julien Biezemans) -* Switch from throwing exceptions to callback.fail() in web example (Julien Biezemans) -* Add callback.fail() example to README (Julien Biezemans) - -## [v0.2.6] - -### New features - -* Add tags support ([#7](https://github.com/cucumber/cucumber-js/issues/7), Julien Biezemans) -* Add support for tags on features ([#7](https://github.com/cucumber/cucumber-js/issues/7), Julien Biezemans) - -### Changed features - -* Handle missing instance in World constructor callback ([#40](https://github.com/cucumber/cucumber-js/issues/40), Julien Biezemans) - -### Documentation, internals and tests - -* Update development status in README (Julien Biezemans) -* Typo in README (Julien Biezemans) -* Refactor parser and add AST assembler (required by [#7](https://github.com/cucumber/cucumber-js/issues/7), Julien Biezemans) -* Indent properly (Julien Biezemans) -* Refactor AST assembler to be stateful (needed by [#7](https://github.com/cucumber/cucumber-js/issues/7), Julien Biezemans) -* Update master diff in History (Julien Biezemans) -* Add --tags documentation to --help (CLI, Julien Biezemans) - - - -## [v0.2.5] - -### New features - -* Add Before/After hooks ([#32](https://github.com/cucumber/cucumber-js/issues/32), [#31](https://github.com/cucumber/cucumber-js/issues/31), Tristan Dunn) - -### Changed features - -* Interpret "*" step keyword as a repeat keyword (Julien Biezemans) - -### Documentation, internals and tests - -* Add NPM publishing to README release checklist (Julien Biezemans) -* Add "Help & Support" to README (Julien Biezemans) -* Words in README (Julien Biezemans) -* Document before and after hooks (Julien Biezemans) - - - -## [v0.2.4] - -### New features - -* Add --version to CLI (Julien Biezemans) -* Add --help to CLI (Julien Biezemans) - -### Changed features - -* Add styles for reported errors on web example (Julien Biezemans) -* Make and expect World constructors to be asynchronous ([#39](https://github.com/cucumber/cucumber-js/issues/39), Julien Biezemans) - -### Documentation, internals and tests - -* Update README (Julien Biezemans) -* Add development status to README (Julien Biezemans) -* Add link to demo at cucumber.no.de (Julien Biezemans) -* Add link to example app to README (Julien Biezemans) -* Add usage documentation to README ([#23](https://github.com/cucumber/cucumber-js/issues/23), Olivier Melcher) -* Add examples to run features with the CLI (Olivier Melcher) -* Fix header levels and whitespaces in README (Julien Biezemans) -* Add Opera to supported browsers in README (Julien Biezemans) -* Fix World constructor in README (Julien Biezemans) -* Simplify World#visit in README (Julien Biezemans) -* Rewrite step definition and wrapper documentation (Julien Biezemans) -* Remove useless words (Julien Biezemans) -* Use more consistent Markdown in README (Julien Biezemans) -* Fix Gherkin comment in README (Julien Biezemans) -* Add credits (Julien Biezemans) -* Add Aruba setup details to README (Julien Biezemans) -* Fix World constructor on web example according to the recent API changes (Julien Biezemans) -* Tell Travis CI to post build results to #cucumber (Julien Biezemans) -* Add release checklist to README (Julien Biezemans) - - - -## [v0.2.3] - -### New features - -* Add support for Node 0.6 (Julien Biezemans) - -### Fixes - -* Prevent the same step definition snippet from being suggested twice (Julien Biezemans) - -### Documentation, internals and tests - -* Don't make NPM ignore `example/` anymore (Julien Biezemans) -* Bump cucumber-features (Julien Biezemans) -* Use non-deprecated "url" key instead of "web" in NPM manifest (Julien Biezemans) -* Add JS step definitions related to data table scenarios (Julien Biezemans) -* Move from cucumber-features to cucumber-tck (Julien Biezemans) -* Bump Gherkin (Julien Biezemans) -* Bump jasmine-node (Julien Biezemans) -* Bump connect (Julien Biezemans) -* Fix Travis build (Julien Biezemans) -* Bump browserify (Julien Biezemans) -* Bump nopt (Julien Biezemans) -* Bump underscore (Julien Biezemans) -* Bump underscore.string (Julien Biezemans) -* Bump rimraf (Julien Biezemans) -* Bump mkdirp (Julien Biezemans) -* Bump Aruba (Julien Biezemans) - - - -## [v0.2.2] - -### New features - -* Suggest step definition snippets for undefined steps ([#33](https://github.com/cucumber/cucumber-js/issues/33), Julien Biezemans) - -### Documentation, internals and tests - -* Add contributors to NPM package manifest (Julien Biezemans) -* Clean up JS step definitions (Julien Biezemans) -* Bump cucumber-features and reflect step changes (Julien Biezemans) -* Set up [continuous integration on Travis CI](http://travis-ci.org/#!/cucumber/cucumber-js) (Julien Biezemans) -* Add Travis's build status icon to README (Julien Biezemans) - - - -## [v0.2.1] - -### New features - -* Allow custom World constructors (Julien Biezemans) -* Add support for data tables (with conversion to hashes) ([#12](https://github.com/cucumber/cucumber-js/issues/12), Julien Biezemans) - -### Changed features - -* Demonstrate World object usages in web example (Julien Biezemans) - - - -## [v0.2.0] - -### New features - -* Setup application to run on [Travis CI](http://travis-ci.org/#!/jbpros/cucumber-js) (Julien Biezemans) -* Add CoffeeScript support for step definition files (Paul Jensen) -* Add "World" ([#26](https://github.com/cucumber/cucumber-js/issues/26), Julien Biezemans) - -### Changed features - -* Add link to the Github repository on web example (Julien Biezemans) -* Allow specifying the port the web example server should listen on (Julien Biezemans) -* Update web example to use cucumber-html formatter (Julien Biezemans) - -### Fixes - -* Fix load paths in spec helper (Julien Biezemans) -* Prevent 'crypto' module from being included by browserify in web example (Julien Biezemans) -* Fix HTML indentation (Julien Biezemans) -* Prevent CLI support code loader from calling module main exports which are not functions (Julien Biezemans) -* Remove use of username for submodule (Kushal Pisavadia) - -### Documentation, internals and tests - -* Bump jasmine-node -* Update README (Julien Biezemans) -* Bump Gherkin twice (Julien Biezemans) -* Bump cucumber-features twice (Julien Biezemans) -* Add missing getters on several AST feature elements (mostly getLine()) (Julien Biezemans) -* Ignore example/ on NPM (Julien Biezemans) -* Add Procfile (used by Heroku when deploying to cucumber.heroku.com) (Julien Biezemans) -* Bump Aruba (Julien Biezemans) -* Add guard-jasmine-node (Julien Biezemans) -* Improve Guardfile regular expressions (Julien Biezemans) -* Bump cucumber-html and remove DOM templates from web example HTML file (Julien Biezemans) -* Fix PathExpander internal name (Julien Biezemans) -* Remove unneeded requires from FeaturePathExpander (Julien Biezemans) -* Bump browserify (Julien Biezemans) -* Remove "glob" from dependencies (Julien Biezemans) -* Refactor SupportCodePathExpander spec (Julien Biezemans) -* Add feature for CoffeeScript support ([#29](https://github.com/cucumber/cucumber-js/issues/29), Julien Biezemans) - - - -## [v0.1.x](https://github.com/cucumber/cucumber-js/compare/v0.1.0...v0.2.0^) - -## [v0.1.5] - -### New features - -* Add support for background ([#9](https://github.com/cucumber/cucumber-js/issues/9), Julien Biezemans) - -### Documentation, internals and tests - -* Bump cucumber-features (twice) (Julien Biezemans) -* Bump gherkin and reflect changes in its API (add DocString content type) (Julien Biezemans) - - - -## [v0.1.4] - -### Changed features - -* Stop polluting the global namespace with Given(), When() and Then() ([#2](https://github.com/cucumber/cucumber-js/issues/2), Julien Biezemans) -* Step definitions can be created with the support code helper passed as 'this': - this.Given(), this.When(), this.Then() and this.defineStep() ([#2](https://github.com/cucumber/cucumber-js/issues/2), Julien Biezemans) - -### Documentation, internals and tests - -* Fix typo "occured" -> "occurred" (Fernando Acorreia) -* Improve variable names in CLI support code loader (Julien Biezemans) - - - -## [v0.1.3] - -### New features - -* Allow several features to run at once ([#14](https://github.com/cucumber/cucumber-js/issues/14), Julien Biezemans) -* Add support for --require (Julien Biezemans) - -### Documentation, internals and tests - -* Improve features and support code API (Julien Biezemans) -* Add "Cli" and "Volatile" configurations (Julien Biezemans) -* Internal refactoring and cleanup (Julien Biezemans) -* Cucumber.js can now fully test itself (Julien Biezemans) -* Remove run_all_features script in favor of bin/cucumber.js (Julien Biezemans) - - - -## [v0.1.2] - -### New features - -* Add failure reporting to the progress formatter ([#20](https://github.com/cucumber/cucumber-js/issues/20), Julien Biezemans) - - - -## [v0.1.1] - -### New features - -* Publish Cucumber.js to NPM as [`cucumber`](https://www.npmjs.com/search?q=cucumber) (Julien Biezemans) - -### Changed features - -* Throw a clearer exception on missing feature argument (CLI) (Julien Biezemans) - -### Documentation, internals and tests - -* Unify and clean up js-specific features and step definitions ([#21](https://github.com/cucumber/cucumber-js/issues/21), Julien Biezemans) - - - -## [v0.1.0] - -### New features - -* Add cucumber.js executable (Julien Biezemans) -* Handle step failures ([#6](https://github.com/cucumber/cucumber-js/issues/6), Julien Biezemans) -* Add the progress formatter ([#16](https://github.com/cucumber/cucumber-js/issues/16), Julien Biezemans) -* Add support for pending steps ([#18](https://github.com/cucumber/cucumber-js/issues/18), Julien Biezemans) -* Add support for undefined steps ([#19](https://github.com/cucumber/cucumber-js/issues/19), Julien Biezemans) - -### Changed features - -* Update web example to use the new progress formatter (Julien Biezemans) - -### Fixes - -* Fix asynchronous step definition callbacks ([#1](https://github.com/cucumber/cucumber-js/issues/1), Julien Biezemans) -* Fix stepResult.isSuccessful call in ProgressFormatter (Julien Biezemans) -* Load Gherkin properly in browsers (Julien Biezemans) -* Remove calls to console.log in web example (Julien Biezemans) - -### Documentation, internals and tests - -* Pass against core.feature in its new form, both with the Cucumber-ruby/Aruba pair and cucumber-js itself (Julien Biezemans) -* Refactor cucumber-features JS mappings (Julien Biezemans) -* Refactor js-specific features (Julien Biezemans) -* Rename PyString to DocString ([#15](https://github.com/cucumber/cucumber-js/issues/15), Julien Biezemans) -* Update Gherkin to 2.4.0 (Julien Biezemans) -* Modularize the project and use browserify.js to serve a single JS file to browsers. ([#3](https://github.com/cucumber/cucumber-js/issues/3), Julien Biezemans) -* Rename Cucumber.Types to Cucumber.Type (Julien Biezemans) -* Use progress formatter in cucumber-features ([#17](https://github.com/cucumber/cucumber-js/issues/17), Julien Biezemans) - - - -## [v0.0.x](https://github.com/cucumber/cucumber-js/compare/v0.0.1...v0.1.0^) - -## [v0.0.1](https://github.com/cucumber/cucumber-js/tree/v0.0.1) - -* Emerge Cucumber.js with bare support for features, scenarios and steps. It does not handle several Gherkin elements nor failures yet. (Julien Biezemans) - - - -[Unreleased]: https://github.com/cucumber/cucumber-js/compare/v7.2.1...master -[7.2.1]: https://github.com/cucumber/cucumber-js/compare/7.2.1-rc.0...7.0.0 -[7.2.0]: https://github.com/cucumber/cucumber-js/compare/7.2.0-rc.0...7.0.0 -[7.1.0]: https://github.com/cucumber/cucumber-js/compare/7.1.0-rc.0...7.0.0 -[7.0.0]: https://github.com/cucumber/cucumber-js/compare/7.0.0-rc.0...v7.0.0 -[7.0.0-rc.0]: https://github.com/cucumber/cucumber-js/compare/v6.0.5...v7.0.0-rc.0 -[6.0.5]: https://github.com/cucumber/cucumber-js/compare/v6.0.4...v6.0.5 -[6.0.4]: https://github.com/cucumber/cucumber-js/compare/v6.0.3...v6.0.4 -[6.0.3]: https://github.com/cucumber/cucumber-js/compare/v6.0.2...v6.0.3 -[6.0.2]: https://github.com/cucumber/cucumber-js/compare/v6.0.1...v6.0.2 -[6.0.1]: https://github.com/cucumber/cucumber-js/compare/v6.0.0...v6.0.1 -[6.0.0]: https://github.com/cucumber/cucumber-js/compare/v5.1.0...v6.0.0 -[5.1.0]: https://github.com/cucumber/cucumber-js/compare/v5.0.3...v5.1.0 -[5.0.3]: https://github.com/cucumber/cucumber-js/compare/v5.0.2...v5.0.3 -[5.0.2]: https://github.com/cucumber/cucumber-js/compare/v5.0.1...v5.0.2 -[5.0.1]: https://github.com/cucumber/cucumber-js/compare/v4.2.1...v5.0.1 -[4.2.1]: https://github.com/cucumber/cucumber-js/compare/v4.2.0...v4.2.1 -[4.2.0]: https://github.com/cucumber/cucumber-js/compare/v4.1.0...v4.2.0 -[4.1.0]: https://github.com/cucumber/cucumber-js/compare/v4.0.0...v4.1.0 -[4.0.0]: https://github.com/cucumber/cucumber-js/compare/v3.2.1...v4.0.0 -[3.2.1]: https://github.com/cucumber/cucumber-js/compare/v3.2.0...v3.2.1 -[3.2.0]: https://github.com/cucumber/cucumber-js/compare/v3.1.0...v3.2.0 -[3.1.0]: https://github.com/cucumber/cucumber-js/compare/v3.0.6...v3.1.0 -[3.0.6]: https://github.com/cucumber/cucumber-js/compare/v3.0.5...v3.0.6 -[3.0.5]: https://github.com/cucumber/cucumber-js/compare/v3.0.4...v3.0.5 -[3.0.4]: https://github.com/cucumber/cucumber-js/compare/v3.0.3...v3.0.4 -[3.0.3]: https://github.com/cucumber/cucumber-js/compare/v3.0.2...v3.0.3 -[3.0.2]: https://github.com/cucumber/cucumber-js/compare/v3.0.1...v3.0.2 -[3.0.1]: https://github.com/cucumber/cucumber-js/compare/v3.0.0...v3.0.1 -[3.0.0]: https://github.com/cucumber/cucumber-js/compare/v2.3.1...v3.0.0 -[2.3.1]: https://github.com/cucumber/cucumber-js/compare/v2.3.0...v2.3.1 -[2.3.0]: https://github.com/cucumber/cucumber-js/compare/v2.2.0...v2.3.0 -[2.2.0]: https://github.com/cucumber/cucumber-js/compare/v2.1.0...v2.2.0 -[2.1.0]: https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.9...v2.1.0 -[1.3.3]: https://github.com/cucumber/cucumber-js/compare/v1.3.2...v1.3.3 -[1.3.2]: https://github.com/cucumber/cucumber-js/compare/v1.3.1...v1.3.2 -[1.3.1]: https://github.com/cucumber/cucumber-js/compare/v1.3.0...v1.3.1 -[1.3.0]: https://github.com/cucumber/cucumber-js/compare/v1.2.2...v1.3.0 -[1.2.2]: https://github.com/cucumber/cucumber-js/compare/v1.2.1...v1.2.2 -[1.2.1]: https://github.com/cucumber/cucumber-js/compare/v1.2.0...v1.2.1 -[1.2.0]: https://github.com/cucumber/cucumber-js/compare/v1.1.0...v1.2.0 -[1.1.0]: https://github.com/cucumber/cucumber-js/compare/v1.0.0...v1.1.0 -[1.0.0]: https://github.com/cucumber/cucumber-js/compare/v0.10.4...v1.0.0 -[0.10.4]: https://github.com/cucumber/cucumber-js/compare/v0.10.3...v0.10.4 -[0.10.3]: https://github.com/cucumber/cucumber-js/compare/v0.10.2...v0.10.3 -[0.10.2]: https://github.com/cucumber/cucumber-js/compare/v0.10.1...v0.10.2 -[0.10.1]: https://github.com/cucumber/cucumber-js/compare/v0.10.0...v0.10.1 -[0.10.0]: https://github.com/cucumber/cucumber-js/compare/v0.9.5...v0.10.0 -[0.9.5]: https://github.com/cucumber/cucumber-js/compare/v0.9.4...v0.9.5 -[0.9.4]: https://github.com/cucumber/cucumber-js/compare/v0.9.3...v0.9.4 -[0.9.3]: https://github.com/cucumber/cucumber-js/compare/v0.9.2...v0.9.3 -[0.9.2]: https://github.com/cucumber/cucumber-js/compare/v0.9.1...v0.9.2 -[0.9.1]: https://github.com/cucumber/cucumber-js/compare/v0.9.0...v0.9.1 -[0.9.0]: https://github.com/cucumber/cucumber-js/compare/v0.8.1...v0.9.0 +### Fixed +- Fix asynchronous step definition callbacks ([#1](https://github.com/cucumber/cucumber-js/issues/1), Julien Biezemans) +- Fix stepResult.isSuccessful call in ProgressFormatter (Julien Biezemans) +- Load Gherkin properly in browsers (Julien Biezemans) +- Remove calls to console.log in web example (Julien Biezemans) +- Pass against core.feature in its new form, both with the Cucumber-ruby/Aruba pair and cucumber-js itself (Julien Biezemans) +- Refactor cucumber-features JS mappings (Julien Biezemans) +- Refactor js-specific features (Julien Biezemans) +- Rename PyString to DocString ([#15](https://github.com/cucumber/cucumber-js/issues/15), Julien Biezemans) +- Update Gherkin to 2.4.0 (Julien Biezemans) +- Modularize the project and use browserify.js to serve a single JS file to browsers. ([#3](https://github.com/cucumber/cucumber-js/issues/3), Julien Biezemans) +- Rename Cucumber.Types to Cucumber.Type (Julien Biezemans) +- Use progress formatter in cucumber-features ([#17](https://github.com/cucumber/cucumber-js/issues/17), Julien Biezemans) + +## 0.0.1 + +[Unreleased]: https://github.com/cucumber/cucumber-js/compare/v8.0.0-rc.2...HEAD +[8.0.0-rc.2]: https://github.com/cucumber/cucumber-js/compare/v8.0.0-rc.1...v8.0.0-rc.2 +[8.0.0-rc.1]: https://github.com/cucumber/cucumber-js/compare/v7.3.1...8.0.0-rc.1 +[7.3.1]: https://github.com/cucumber/cucumber-js/compare/v7.3.0...v7.3.1 +[7.3.0]: https://github.com/cucumber/cucumber-js/compare/v7.2.1...v7.3.0 +[7.2.1]: https://github.com/cucumber/cucumber-js/compare/v7.2.0...v7.2.1 +[7.2.0]: https://github.com/cucumber/cucumber-js/compare/v7.1.0...v7.2.0 +[7.1.0]: https://github.com/cucumber/cucumber-js/compare/v7.0.0-rc.0...v7.1.0 +[7.0.0]: https://github.com/cucumber/cucumber-js/compare/v6.0.5...v7.0.0 +[7.0.0-rc.0]: https://github.com/cucumber/cucumber-js/compare/v7.0.0...v7.0.0-rc.0 +[6.0.5]: https://github.com/cucumber/cucumber-js/compare/v6.0.4...v6.0.5 +[6.0.4]: https://github.com/cucumber/cucumber-js/compare/v6.0.3...v6.0.4 +[6.0.3]: https://github.com/cucumber/cucumber-js/compare/v6.0.2...v6.0.3 +[6.0.2]: https://github.com/cucumber/cucumber-js/compare/v6.0.1...v6.0.2 +[6.0.1]: https://github.com/cucumber/cucumber-js/compare/v6.0.0...v6.0.1 +[6.0.0]: https://github.com/cucumber/cucumber-js/compare/v5.1.0...v6.0.0 +[5.1.0]: https://github.com/cucumber/cucumber-js/compare/v5.0.3...v5.1.0 +[5.0.3]: https://github.com/cucumber/cucumber-js/compare/v5.0.2...v5.0.3 +[5.0.2]: https://github.com/cucumber/cucumber-js/compare/v5.0.1...v5.0.2 +[5.0.1]: https://github.com/cucumber/cucumber-js/compare/v5.0.0...v5.0.1 +[5.0.0]: https://github.com/cucumber/cucumber-js/compare/v4.2.1...v5.0.0 +[4.2.1]: https://github.com/cucumber/cucumber-js/compare/v4.1.0...v4.2.1 +[4.1.0]: https://github.com/cucumber/cucumber-js/compare/v4.0.0...v4.1.0 +[4.0.0]: https://github.com/cucumber/cucumber-js/compare/v3.2.1...v4.0.0 +[3.2.1]: https://github.com/cucumber/cucumber-js/compare/v3.2.0...v3.2.1 +[3.2.0]: https://github.com/cucumber/cucumber-js/compare/v3.1.0...v3.2.0 +[3.1.0]: https://github.com/cucumber/cucumber-js/compare/v3.0.6...v3.1.0 +[3.0.6]: https://github.com/cucumber/cucumber-js/compare/v3.0.5...v3.0.6 +[3.0.5]: https://github.com/cucumber/cucumber-js/compare/v3.0.4...v3.0.5 +[3.0.4]: https://github.com/cucumber/cucumber-js/compare/v3.0.3...v3.0.4 +[3.0.3]: https://github.com/cucumber/cucumber-js/compare/v3.0.2...v3.0.3 +[3.0.2]: https://github.com/cucumber/cucumber-js/compare/v3.0.1...v3.0.2 +[3.0.1]: https://github.com/cucumber/cucumber-js/compare/v3.0.0...v3.0.1 +[3.0.0]: https://github.com/cucumber/cucumber-js/compare/v2.3.1...v3.0.0 +[2.3.1]: https://github.com/cucumber/cucumber-js/compare/v2.3.0...v2.3.1 +[2.3.0]: https://github.com/cucumber/cucumber-js/compare/v2.2.0...v2.3.0 +[2.2.0]: https://github.com/cucumber/cucumber-js/compare/v2.1.0...v2.2.0 +[2.1.0]: https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.9...v2.1.0 +[1.3.3]: https://github.com/cucumber/cucumber-js/compare/v1.3.2...v1.3.3 +[1.3.2]: https://github.com/cucumber/cucumber-js/compare/v1.3.1...v1.3.2 +[2.0.0-rc.9]: https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.8...v2.0.0-rc.9 +[2.0.0-rc.8]: https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.7...v2.0.0-rc.8 +[2.0.0-rc.7]: https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.6...v2.0.0-rc.7 +[2.0.0-rc.6]: https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.5...v2.0.0-rc.6 +[2.0.0-rc.5]: https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.4...v2.0.0-rc.5 +[2.0.0-rc.4]: https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.3...v2.0.0-rc.4 +[2.0.0-rc.3]: https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.2...v2.0.0-rc.3 +[2.0.0-rc.2]: https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.1...v2.0.0-rc.2 +[2.0.0-rc.1]: https://github.com/cucumber/cucumber-js/compare/v2.0.0-rc.0...v2.0.0-rc.1 +[2.0.0-rc.0]: https://github.com/cucumber/cucumber-js/compare/v1.3.3...v2.0.0-rc.0 +[1.3.1]: https://github.com/cucumber/cucumber-js/compare/v1.3.0...v1.3.1 +[1.3.0]: https://github.com/cucumber/cucumber-js/compare/v1.2.2...v1.3.0 +[1.2.2]: https://github.com/cucumber/cucumber-js/compare/v1.2.1...v1.2.2 +[1.2.1]: https://github.com/cucumber/cucumber-js/compare/v1.2.0...v1.2.1 +[1.2.0]: https://github.com/cucumber/cucumber-js/compare/v1.1.0...v1.2.0 +[1.1.0]: https://github.com/cucumber/cucumber-js/compare/v1.0.0...v1.1.0 +[1.0.0]: https://github.com/cucumber/cucumber-js/compare/v0.9.5...v1.0.0 +[0.10.4]: https://github.com/cucumber/cucumber-js/compare/v0.10.3...v0.10.4 +[0.10.3]: https://github.com/cucumber/cucumber-js/compare/v0.10.2...v0.10.3 +[0.10.2]: https://github.com/cucumber/cucumber-js/compare/v0.10.1...v0.10.2 +[0.10.1]: https://github.com/cucumber/cucumber-js/compare/v0.10.0...v0.10.1 +[0.10.0]: https://github.com/cucumber/cucumber-js/compare/v0.1.5...v0.10.0 +[0.9.5]: https://github.com/cucumber/cucumber-js/compare/v0.9.4...v0.9.5 +[0.9.4]: https://github.com/cucumber/cucumber-js/compare/v0.9.3...v0.9.4 +[0.9.3]: https://github.com/cucumber/cucumber-js/compare/v0.9.2...v0.9.3 +[0.9.2]: https://github.com/cucumber/cucumber-js/compare/v0.9.1...v0.9.2 +[0.9.1]: https://github.com/cucumber/cucumber-js/compare/v0.9.0...v0.9.1 +[0.9.0]: https://github.com/cucumber/cucumber-js/compare/v0.8.1...v0.9.0 +[0.8.1]: https://github.com/cucumber/cucumber-js/compare/v0.8.0...v0.8.1 +[0.8.0]: https://github.com/cucumber/cucumber-js/compare/v0.7.0...v0.8.0 +[0.7.0]: https://github.com/cucumber/cucumber-js/compare/v0.6.0...v0.7.0 +[0.6.0]: https://github.com/cucumber/cucumber-js/compare/v0.5.3...v0.6.0 +[0.5.3]: https://github.com/cucumber/cucumber-js/compare/v0.5.2...v0.5.3 +[0.5.2]: https://github.com/cucumber/cucumber-js/compare/v0.5.1...v0.5.2 +[0.5.1]: https://github.com/cucumber/cucumber-js/compare/v0.5.0...v0.5.1 +[0.5.0]: https://github.com/cucumber/cucumber-js/compare/v0.4.9...v0.5.0 +[0.4.9]: https://github.com/cucumber/cucumber-js/compare/v0.4.8...v0.4.9 +[0.4.8]: https://github.com/cucumber/cucumber-js/compare/v0.4.7...v0.4.8 +[0.4.7]: https://github.com/cucumber/cucumber-js/compare/v0.4.6...v0.4.7 +[0.4.6]: https://github.com/cucumber/cucumber-js/compare/v0.4.5...v0.4.6 +[0.4.5]: https://github.com/cucumber/cucumber-js/compare/v0.4.4...v0.4.5 +[0.4.4]: https://github.com/cucumber/cucumber-js/compare/v0.4.3...v0.4.4 +[0.4.3]: https://github.com/cucumber/cucumber-js/compare/v0.4.2...v0.4.3 +[0.4.2]: https://github.com/cucumber/cucumber-js/compare/v0.4.1...v0.4.2 +[0.4.1]: https://github.com/cucumber/cucumber-js/compare/v0.4.0...v0.4.1 +[0.4.0]: https://github.com/cucumber/cucumber-js/compare/v0.3.3...v0.4.0 +[0.3.3]: https://github.com/cucumber/cucumber-js/compare/v0.3.2...v0.3.3 +[0.3.2]: https://github.com/cucumber/cucumber-js/compare/v0.3.1...v0.3.2 +[0.3.1]: https://github.com/cucumber/cucumber-js/compare/v0.3.0...v0.3.1 +[0.3.0]: https://github.com/cucumber/cucumber-js/compare/v0.2.9...v0.3.0 +[0.2.22]: https://github.com/cucumber/cucumber-js/compare/v0.2.21...v0.2.22 +[0.2.21]: https://github.com/cucumber/cucumber-js/compare/v0.2.20...v0.2.21 +[0.2.20]: https://github.com/cucumber/cucumber-js/compare/v0.2.2...v0.2.20 +[0.2.19]: https://github.com/cucumber/cucumber-js/compare/v0.2.18...v0.2.19 +[0.2.18]: https://github.com/cucumber/cucumber-js/compare/v0.2.17...v0.2.18 +[0.2.17]: https://github.com/cucumber/cucumber-js/compare/v0.2.16...v0.2.17 +[0.2.16]: https://github.com/cucumber/cucumber-js/compare/v0.2.15...v0.2.16 +[0.2.15]: https://github.com/cucumber/cucumber-js/compare/v0.2.14...v0.2.15 +[0.2.14]: https://github.com/cucumber/cucumber-js/compare/v0.2.13...v0.2.14 +[0.2.13]: https://github.com/cucumber/cucumber-js/compare/v0.2.12...v0.2.13 +[0.2.12]: https://github.com/cucumber/cucumber-js/compare/v0.2.11...v0.2.12 +[0.2.11]: https://github.com/cucumber/cucumber-js/compare/v0.2.10...v0.2.11 +[0.2.10]: https://github.com/cucumber/cucumber-js/compare/v0.2.1...v0.2.10 +[0.2.9]: https://github.com/cucumber/cucumber-js/compare/v0.2.8...v0.2.9 +[0.2.8]: https://github.com/cucumber/cucumber-js/compare/v0.2.7...v0.2.8 +[0.2.7]: https://github.com/cucumber/cucumber-js/compare/v0.2.6...v0.2.7 +[0.2.6]: https://github.com/cucumber/cucumber-js/compare/v0.2.5...v0.2.6 +[0.2.5]: https://github.com/cucumber/cucumber-js/compare/v0.2.4...v0.2.5 +[0.2.4]: https://github.com/cucumber/cucumber-js/compare/v0.2.3...v0.2.4 +[0.2.3]: https://github.com/cucumber/cucumber-js/compare/v0.2.22...v0.2.3 +[0.2.2]: https://github.com/cucumber/cucumber-js/compare/v0.2.19...v0.2.2 +[0.2.1]: https://github.com/cucumber/cucumber-js/compare/v0.2.0...v0.2.1 +[0.2.0]: https://github.com/cucumber/cucumber-js/compare/v0.10.4...v0.2.0 +[0.1.5]: https://github.com/cucumber/cucumber-js/compare/v0.1.4...v0.1.5 +[0.1.4]: https://github.com/cucumber/cucumber-js/compare/v0.1.3...v0.1.4 +[0.1.3]: https://github.com/cucumber/cucumber-js/compare/v0.1.2...v0.1.3 +[0.1.2]: https://github.com/cucumber/cucumber-js/compare/v0.1.1...v0.1.2 +[0.1.1]: https://github.com/cucumber/cucumber-js/compare/v0.1.0...v0.1.1 +[0.1.0]: https://github.com/cucumber/cucumber-js/compare/v0.0.1...v0.1.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ee7a43ea9..f96eeac9a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,29 +1,44 @@ -# Thank you! +# Welcome 💖 -Before anything else, thank you. Thank you for taking some of your precious time helping this project move forward. +Before anything else, thank you for taking some of your precious time to help this project move forward. ❤️ -## Setup +If you're new to open source and feeling a bit nervous 😳, we understand! We recommend watching [this excellent guide](https://egghead.io/talks/git-how-to-make-your-first-open-source-contribution) +to give you a grounding in some of the basic concepts. We want you to feel safe to make mistakes, and ask questions. -* install [Node.Js](https://nodejs.org/en/) and [Yarn](https://yarnpkg.com/) -* `yarn install` +If anything in this guide or anywhere else in the codebase doesn't make sense to you, please let us know! It's through your feedback that we can make this codebase more welcoming, so we'll be glad to hear thoughts. + +You can chat with us in the [#committers-js](https://cucumberbdd.slack.com/archives/C612KCP1P) channel in our [Community Slack], or feel free to [raise an issue] if you're experiencing any friction trying make your contribution. + +## Local setup + +To get a local development environment: + +* use [Git] to [fork and clone] the repo +* If you're running Windows, make sure to enable [Developer Mode] +* install [Node.Js](https://nodejs.org/en/) +* Make sure you have a recent version of `npm` installed: `npm install -g npm` +* `npm install` - Install dependencies +* `npm test` - Compile typescript and run the tests + +If everything passes, you're ready to hack! ⛏ ## Tests -See the `package.json` scripts section for how to run each category of tests. +Type `npm run` or see the `package.json` scripts section for how to run each category of tests. -* lint - `yarn lint` +* lint - `npm run lint` * [prettier](https://github.com/prettier/prettier) * [eslint](https://eslint.org/) * [dependency-lint](https://github.com/charlierudolph/dependency-lint) -* typescript tests - `yarn types-test` +* typescript tests - `npm run types-test` * [tsd](https://github.com/SamVerschueren/tsd) -* unit tests - `yarn unit-test` +* unit tests - `npm run unit-test` * [mocha](https://mochajs.org/) * [chai](https://www.chaijs.com/) * [sinon](https://sinonjs.org/) -* compatibility kit - `yarn cck-test` - * checking that cucumber-js emits the [correct messages](https://github.com/cucumber/cucumber/tree/master/compatibility-kit) -* feature tests - `yarn feature-test` +* compatibility kit - `npm run cck-test` + * checking that cucumber-js emits the [correct messages](https://github.com/cucumber/cucumber/tree/master/compatibility-kit) +* feature tests - `npm run feature-test` * cucumber-js tests itself ## Internals @@ -57,81 +72,8 @@ The runtime emits events with an [EventEmitter](https://nodejs.org/api/events.ht * The contributor should update the changelog * Each entry in the changelog should include a link to the relevant issues/PRs -## Release process - -_The following is a checklist for maintainers when preparing a new release_ - -### Major releases - -We will always make a release candidate before issuing a major release. The release candidate will be available for at least a month to give users -time to validate that there are no unexpected breaking changes. - -### Process - -The release is done from the [cucumber-build](https://github.com/cucumber/cucumber-build/) docker container. This makes -sure we use the same environment for all releases. - -**Every command should be run from within the Docker container**. - -Start the container: - - make docker-run - -Inside the container, install the correct versions of Node and Yarn: - - nvm install --lts - npm install -g yarn - -Then update the dependencies and test: - - yarn update-dependencies - yarn - yarn test - -If the tests fail, update your code to be compatible with the new libraries, or revert the library upgrades that break the build. - -* Add missing entries to `CHANGELOG.md` - * Ideally the CHANGELOG should be up-to-date, but sometimes there will be accidental omissions when merging PRs. Missing PRs should be added. - * Describe the major changes introduced. API changes must be documented. In particular, backward-incompatible changes must be well explained, with examples when possible. - * `git log --format=format:"* %s (%an)" --reverse ..HEAD` might be handy. -* Update the contributors list in `package.json` - * `git log --format=format:"%an <%ae>" --reverse ..HEAD | grep -vEi "(renovate|dependabot|Snyk)" | sort| uniq -i` - * Manually add contributors (in alphabetical order) - -[Decide what the next version should be](https://github.com/cucumber/cucumber/blob/master/RELEASE_PROCESS.md#decide-what-the-next-version-should-be). - -Update CHANGELOG links: - - NEW_VERSION= make update-changelog - -Verify changes to the CHANGELOG are correct. Stage uncommitted changes: - - git add . - git commit -am "Release " - -Then bump the version number and create a git tag. Run *one* of the following: - - # Major prelease - npm version premajor --preid=rc - - # Major release - npm version major - - # Minor release - npm version minor - - # Patch release - npm version patch - -Publish to npm: - - npm publish --access public - -Push to git: - - git push - git push --tags - -* Update [docs.cucumber.io](https://github.com/cucumber/docs.cucumber.io) - * Update the cucumber-js version `data/versions.yaml` - * Ensure the javascript examples are up to date +[Community Slack]: https://cucumber.io/community#slack +[raise an issue]: https://github.com/cucumber/cucumber-js/issues/new/choose +[Developer Mode]: https://docs.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging +[fork and clone]: https://docs.github.com/en/get-started/quickstart/fork-a-repo +[Git]: https://docs.github.com/en/get-started/quickstart/set-up-git diff --git a/README.md b/README.md index 73fae425f..549aa49c8 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ We've put a demo of Cucumber.js to [run in your browser](https://cucumber.github ## Help & support -* See here: https://cucumber.io/support +* See here: https://cucumber.io/support. ## Contributing @@ -52,11 +52,9 @@ $ npm install cucumber@6 ## Documentation -The following documentation is for master. See below for documentation for older versions. +The following documentation is for master. See below the documentation for older versions. * [CLI](/docs/cli.md) -* [Custom Formatters](/docs/custom_formatters.md) -* [Custom Snippet Syntaxes](/docs/custom_snippet_syntaxes.md) * [NodeJs Example](/docs/nodejs_example.md) * Support Files * [World](/docs/support_files/world.md) @@ -66,6 +64,15 @@ The following documentation is for master. See below for documentation for older * [Data Table Interface](/docs/support_files/data_table_interface.md) * [Attachments](/docs/support_files/attachments.md) * [API Reference](/docs/support_files/api_reference.md) +* Guides + * [Dry Run](./docs/dry_run.md) + * [ES Modules](./docs/esm.md) + * [Formatters](./docs/formatters.md) + * [Running in parallel](./docs/parallel.md) + * [Profiles](./docs/profiles.md) + * [Rerunning just failures](./docs/rerun.md) + * [Retrying flaky scenarios](./docs/retry.md) + * [Snippets for undefined steps](./docs/snippets.md) * [FAQ](/docs/faq.md) #### Documentation for older versions diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 000000000..71e0bb877 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1 @@ +See [.github/RELEASING](https://github.com/cucumber/.github/blob/main/RELEASING.md). diff --git a/compatibility/cck_spec.ts b/compatibility/cck_spec.ts index 54c1e6abf..c0d2ce48d 100644 --- a/compatibility/cck_spec.ts +++ b/compatibility/cck_spec.ts @@ -3,14 +3,20 @@ import { config, expect, use } from 'chai' import chaiExclude from 'chai-exclude' import glob from 'glob' import fs from 'fs' -import ndjsonParse from 'ndjson-parse' import path from 'path' -import { PassThrough } from 'stream' -import { Cli } from '../lib' +import { PassThrough, pipeline, Writable } from 'stream' import toString from 'stream-to-string' -import { doesHaveValue, doesNotHaveValue } from '../src/value_checker' -import { normalizeMessageOutput } from '../features/support/formatter_output_helpers' +import { + ignorableKeys, + normalizeMessageOutput, +} from '../features/support/formatter_output_helpers' +import * as messages from '@cucumber/messages' +import * as messageStreams from '@cucumber/message-streams' +import util from 'util' +import { runCucumber } from '../src/run' +import { IRunConfiguration } from '../src/configuration' +const asyncPipeline = util.promisify(pipeline) const PROJECT_PATH = path.join(__dirname, '..') const CCK_FEATURES_PATH = 'node_modules/@cucumber/compatibility-kit/features' const CCK_IMPLEMENTATIONS_PATH = 'compatibility/features' @@ -20,78 +26,70 @@ use(chaiExclude) describe('Cucumber Compatibility Kit', () => { glob.sync(`${CCK_FEATURES_PATH}/**/*.ndjson`).forEach((fixturePath) => { - const suiteName = /^.+\/(.+)\.ndjson$/.exec(fixturePath)[1] + const match = /^.+\/(.+)(\.feature(?:\.md)?)\.ndjson$/.exec(fixturePath) + const suiteName = match[1] + const extension = match[2] it(`passes the cck suite for '${suiteName}'`, async () => { - const args = [ - 'node', - path.join(PROJECT_PATH, 'bin', 'cucumber-js'), - ].concat([ - `${CCK_FEATURES_PATH}/${suiteName}/${suiteName}.feature`, - '--require', - `${CCK_IMPLEMENTATIONS_PATH}/${suiteName}/${suiteName}.ts`, - '--profile', - 'cck', - ]) const stdout = new PassThrough() + const runConfiguration: IRunConfiguration = { + sources: { + paths: [`${CCK_FEATURES_PATH}/${suiteName}/${suiteName}${extension}`], + }, + support: { + transpileWith: ['ts-node/register'], + paths: [`${CCK_IMPLEMENTATIONS_PATH}/${suiteName}/${suiteName}.ts`], + }, + formats: { + stdout: 'message', + }, + runtime: { + retry: suiteName === 'retry' ? 2 : 0, + }, + } try { - await new Cli({ - argv: args, + await runCucumber(runConfiguration, { cwd: PROJECT_PATH, stdout, - }).run() + env: process.env, + }) } catch (ignored) { console.error(ignored) } stdout.end() const rawOutput = await toString(stdout) - const actualMessages = normalize(ndjsonParse(rawOutput)) - const expectedMessages = ndjsonParse( - fs.readFileSync(fixturePath, { encoding: 'utf-8' }) + // TODO: consider validating (at run-time) the parsed message is really an Envelope + const actualMessages = normalize( + rawOutput + .split('\n') + .filter((line) => line.trim() !== '') + .map((line) => JSON.parse(line)) + ) + + const expectedMessages: messages.Envelope[] = [] + await asyncPipeline( + fs.createReadStream(fixturePath, { encoding: 'utf-8' }), + new messageStreams.NdjsonToMessageStream(), + new Writable({ + objectMode: true, + write(envelope: messages.Envelope, _: BufferEncoding, callback) { + expectedMessages.push(envelope) + callback() + }, + }) ) + expect(actualMessages) - .excludingEvery([ - 'meta', - // sources - 'uri', - 'line', - // ids - 'astNodeId', - 'astNodeIds', - 'hookId', - 'id', - 'pickleId', - 'pickleStepId', - 'stepDefinitionIds', - 'testCaseId', - 'testCaseStartedId', - 'testStepId', - // time - 'nanos', - 'seconds', - // errors - 'message', - ]) + .excludingEvery(ignorableKeys) .to.deep.eq(expectedMessages) }) }) }) -function normalize(messages: any[]): any[] { +function normalize(messages: messages.Envelope[]): messages.Envelope[] { messages = normalizeMessageOutput( messages, path.join(PROJECT_PATH, 'compatibility') ) - const testCases: any[] = messages.filter((message) => - doesHaveValue(message.testCase) - ) - const everythingElse: any[] = messages.filter((message) => - doesNotHaveValue(message.testCase) - ) - const testRunStarted = everythingElse.findIndex((message) => - doesHaveValue(message.testRunStarted) - ) - // move all `testCase` messages to just after `testRunStarted` - everythingElse.splice(testRunStarted + 1, 0, ...testCases) - return everythingElse + return messages } diff --git a/compatibility/features/attachments/attachments.ts b/compatibility/features/attachments/attachments.ts index 1b9555017..4d130baa4 100644 --- a/compatibility/features/attachments/attachments.ts +++ b/compatibility/features/attachments/attachments.ts @@ -1,4 +1,4 @@ -import { Before, When, World } from '../../..' +import { Before, When, World } from '../../../src' import { ReadableStreamBuffer } from 'stream-buffers' import fs from 'fs' import path from 'path' @@ -63,9 +63,26 @@ When('a JPEG image is attached', async function (this: World) { 'compatibility-kit', 'features', 'attachments', - 'cucumber-growing-on-vine.jpg' + 'cucumber.png' ) ), - 'image/jpg' + 'image/png' + ) +}) + +When('the {word} png is attached', async function (filename) { + await this.attach( + fs.createReadStream( + path.join( + process.cwd(), + 'node_modules', + '@cucumber', + 'compatibility-kit', + 'features', + 'attachments', + filename + ) + ), + 'image/png' ) }) diff --git a/compatibility/features/data-tables/data-tables.ts b/compatibility/features/data-tables/data-tables.ts index 16781e2f4..168180f3c 100644 --- a/compatibility/features/data-tables/data-tables.ts +++ b/compatibility/features/data-tables/data-tables.ts @@ -1,13 +1,17 @@ -import { When, Then, DataTable } from '../../..' +import { When, Then, DataTable } from '../../../src' import { expect } from 'chai' +type World = { + transposed: DataTable +} + When( 'the following table is transposed:', - function (this: any, table: DataTable) { + function (this: World, table: DataTable) { this.transposed = table.transpose() } ) -Then('it should be:', function (this: any, expected: DataTable) { +Then('it should be:', function (this: World, expected: DataTable) { expect(this.transposed.raw()).to.deep.eq(expected.raw()) }) diff --git a/compatibility/features/examples-tables/examples-tables.ts b/compatibility/features/examples-tables/examples-tables.ts index da89a7eec..e824a1792 100644 --- a/compatibility/features/examples-tables/examples-tables.ts +++ b/compatibility/features/examples-tables/examples-tables.ts @@ -1,17 +1,24 @@ import assert from 'assert' -import { Given, When, Then } from '../../..' +import { Given, When, Then } from '../../../src' -Given('there are {int} cucumbers', function (this: any, initialCount: number) { - this.count = initialCount -}) +type World = { + count: number +} + +Given( + 'there are {int} cucumbers', + function (this: World, initialCount: number) { + this.count = initialCount + } +) -When('I eat {int} cucumbers', function (this: any, eatCount: number) { +When('I eat {int} cucumbers', function (this: World, eatCount: number) { this.count -= eatCount }) Then( 'I should have {int} cucumbers', - function (this: any, expectedCount: number) { + function (this: World, expectedCount: number) { assert.strictEqual(this.count, expectedCount) } ) diff --git a/compatibility/features/hooks/hooks.ts b/compatibility/features/hooks/hooks.ts index 8660be563..1ce001c6f 100644 --- a/compatibility/features/hooks/hooks.ts +++ b/compatibility/features/hooks/hooks.ts @@ -1,4 +1,6 @@ -import { When, Before, After } from '../../..' +import { When, Before, After, World } from '../../../src' +import fs from 'fs' +import path from 'path' Before(function () { // no-op @@ -19,3 +21,20 @@ After(function () { After('@some-tag or @some-other-tag', function () { throw new Error('Exception in conditional hook') }) + +After('@with-attachment', async function (this: World) { + await this.attach( + fs.createReadStream( + path.join( + process.cwd(), + 'node_modules', + '@cucumber', + 'compatibility-kit', + 'features', + 'hooks', + 'cucumber.svg' + ) + ), + 'image/svg+xml' + ) +}) diff --git a/compatibility/features/markdown/markdown.ts b/compatibility/features/markdown/markdown.ts new file mode 100644 index 000000000..8731e3682 --- /dev/null +++ b/compatibility/features/markdown/markdown.ts @@ -0,0 +1,25 @@ +import assert from 'assert' +import { Given, DataTable, Then, When, World } from '../../../src' + +Given('some TypeScript code:', function (dataTable: DataTable) { + assert(dataTable) +}) + +Given('some classic Gherkin:', function (gherkin: string) { + assert(gherkin) +}) + +When( + 'we use a data table and attach something and then {word}', + async function (this: World, word: string, dataTable: DataTable) { + assert(dataTable) + await this.log(`We are logging some plain text (${word})`) + if (word === 'fail') { + throw new Error('You asked me to fail') + } + } +) + +Then('this might or might not run', function () { + // no-op +}) diff --git a/compatibility/features/minimal/minimal.ts b/compatibility/features/minimal/minimal.ts index 2be7b5a78..bccc4f289 100644 --- a/compatibility/features/minimal/minimal.ts +++ b/compatibility/features/minimal/minimal.ts @@ -1,5 +1,5 @@ import assert from 'assert' -import { Given } from '../../..' +import { Given } from '../../../src' Given('I have {int} cukes in my belly', function (cukeCount: number) { assert(cukeCount) diff --git a/compatibility/features/parameter-types/parameter-types.ts b/compatibility/features/parameter-types/parameter-types.ts index 37a6a6cc9..8a5a57ed1 100644 --- a/compatibility/features/parameter-types/parameter-types.ts +++ b/compatibility/features/parameter-types/parameter-types.ts @@ -1,4 +1,4 @@ -import { Given, defineParameterType } from '../../..' +import { Given, defineParameterType } from '../../../src' import { expect } from 'chai' class Flight { diff --git a/compatibility/features/pending/pending.ts b/compatibility/features/pending/pending.ts new file mode 100644 index 000000000..c0e4fc84d --- /dev/null +++ b/compatibility/features/pending/pending.ts @@ -0,0 +1,13 @@ +import { Given } from '../../../src' + +Given('an implemented step', function () { + // no-op +}) + +Given('a step that isnt implemented yet', function () { + return 'pending' +}) + +Given('a step that we expect to be skipped', function () { + // no-op +}) diff --git a/compatibility/features/retry/retry.ts b/compatibility/features/retry/retry.ts new file mode 100644 index 000000000..888982124 --- /dev/null +++ b/compatibility/features/retry/retry.ts @@ -0,0 +1,25 @@ +import { Given } from '../../../src' + +Given('a step that always passes', function () { + // no-op +}) + +let secondTimePass = 0 +Given('a step that passes the second time', function () { + secondTimePass++ + if (secondTimePass < 2) { + throw new Error('Exception in step') + } +}) + +let thirdTimePass = 0 +Given('a step that passes the third time', function () { + thirdTimePass++ + if (thirdTimePass < 3) { + throw new Error('Exception in step') + } +}) + +Given('a step that always fails', function () { + throw new Error('Exception in step') +}) diff --git a/compatibility/features/rules/rules.ts b/compatibility/features/rules/rules.ts index 05b7adb0b..629a15b34 100644 --- a/compatibility/features/rules/rules.ts +++ b/compatibility/features/rules/rules.ts @@ -1,5 +1,5 @@ import assert from 'assert' -import { Given, When, Then } from '../../..' +import { Given, When, Then } from '../../../src' Given( 'there are {int} {float} coins inside', diff --git a/compatibility/features/skipped/skipped.ts b/compatibility/features/skipped/skipped.ts new file mode 100644 index 000000000..4f9885d67 --- /dev/null +++ b/compatibility/features/skipped/skipped.ts @@ -0,0 +1,17 @@ +import { Before, Given } from '../../../src' + +Before('@skip', function () { + return 'skipped' +}) + +Given('an implemented step', function () { + // no-op +}) + +Given('a step that we expect to be skipped', function () { + // no-op +}) + +Given('a step that skips', function () { + return 'skipped' +}) diff --git a/compatibility/features/stack-traces/stack-traces.ts b/compatibility/features/stack-traces/stack-traces.ts index 6fb0b3e31..80d544c91 100644 --- a/compatibility/features/stack-traces/stack-traces.ts +++ b/compatibility/features/stack-traces/stack-traces.ts @@ -1,4 +1,4 @@ -import { When } from '../../..' +import { When } from '../../../src' When('a step throws an exception', function () { throw new Error('BOOM') diff --git a/compatibility/features/undefined/undefined.ts b/compatibility/features/undefined/undefined.ts new file mode 100644 index 000000000..245813d63 --- /dev/null +++ b/compatibility/features/undefined/undefined.ts @@ -0,0 +1,9 @@ +import { Given } from '../../../src' + +Given('an implemented step', function () { + // no-op +}) + +Given('a step that we expect to be skipped', function () { + // no-op +}) diff --git a/compatibility/features/unknown-parameter-type/unknown-parameter-type.ts b/compatibility/features/unknown-parameter-type/unknown-parameter-type.ts index a7c1be050..4d56e21ae 100644 --- a/compatibility/features/unknown-parameter-type/unknown-parameter-type.ts +++ b/compatibility/features/unknown-parameter-type/unknown-parameter-type.ts @@ -1,6 +1,6 @@ -import { Given } from '../../..' +import { Given } from '../../../src' // eslint-disable-next-line @typescript-eslint/no-unused-vars -Given('{airport} is closed because of a strike', function (airport: any) { +Given('{airport} is closed because of a strike', function (airport: unknown) { throw new Error('Should not be called because airport type not defined') }) diff --git a/cucumber.js b/cucumber.js index 639d7601a..caa4fc985 100644 --- a/cucumber.js +++ b/cucumber.js @@ -1,46 +1,14 @@ -const feature = [ - '--require-module ts-node/register', - '--require features/**/*.ts', - `--format progress-bar`, - '--format rerun:@rerun.txt', - '--format usage:usage.txt', - '--format message:messages.ndjson', - '--publish-quiet', -].join(' ') - -const cck = [ - '--require-module', - 'ts-node/register', - '--format', - 'message', -].join(' ') - -const FORMATTERS_INCLUDE = [ - 'attachments', - 'data-tables', - 'examples-tables', - 'minimal', - 'parameter-types', - 'rules', - 'stack-traces', - '--publish-quiet', -] - -const htmlFormatter = [ - `node_modules/@cucumber/compatibility-kit/features/{${FORMATTERS_INCLUDE.join( - ',' - )}}/*.feature`, - '--require-module', - 'ts-node/register', - '--require', - `compatibility/features/{${FORMATTERS_INCLUDE.join(',')}}/*.ts`, - '--format', - 'html:html-formatter.html', - '--publish-quiet', -].join(' ') - module.exports = { - default: feature, - cck, - htmlFormatter, + default: [ + '--require-module ts-node/register', + '--require features/**/*.ts', + `--format progress-bar`, + '--format rerun:@rerun.txt', + '--format usage:reports/usage.txt', + '--format message:reports/messages.ndjson', + '--format html:reports/html-formatter.html', + '--retry 2', + '--retry-tag-filter @flaky', + '--publish-quiet', + ].join(' '), } diff --git a/dependency-lint.yml b/dependency-lint.yml index d85654c33..a4a45798d 100644 --- a/dependency-lint.yml +++ b/dependency-lint.yml @@ -20,9 +20,10 @@ ignoreErrors: - '@typescript-eslint/eslint-plugin' # peer dependency of standard-with-typescript - '@typescript-eslint/parser' # peer dependency of @typescript-eslint/eslint-plugin - '@types/*' # type definitions + - bluebird # features/generator_step_definitions.feature - coffeescript # features/compiler.feature - eslint-config-prettier # .eslintrc.yml - extends - prettier - - eslint-config-standard-with-typescript # .eslintrc.yml - extends - standard-with-typescript + - eslint-config-standard-with-typescript # .eslintrc.yml - extends - standard-with-typescript - eslint-plugin-import # peer dependency of eslint-config-standard-with-typescript - eslint-plugin-node # peer dependency of eslint-config-standard-with-typescript - eslint-plugin-prettier # .eslintrc.yml - extends - prettier @@ -36,6 +37,7 @@ requiredModules: dev: - '{compatibility,features,scripts,test}/**/*' - '**/*_spec.ts' + - 'test-d/**/*.ts' - 'example/index.ts' - '**/test_helpers.ts' ignore: @@ -43,6 +45,7 @@ requiredModules: - 'dist/**/*' - 'lib/**/*' - 'node_modules/**/*' + - 'src/importer.js' - 'tmp/**/*' root: '**/*.{js,ts}' stripLoaders: false diff --git a/docs/cli.md b/docs/cli.md index 754be340e..6ffccc5c2 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -44,32 +44,7 @@ _Note that once you specify any `--require` options, the defaults described abov Use `--format ` to specify the format of the output. -The `TYPE` can be one of: -* The name of one of the built-in formatters (below) e.g. `progress` -* A module/package name e.g. `@cucumber/pretty-formatter` -* A relative path to a local formatter implementation e.g. `./my-customer-formatter.js` - -If `PATH` is not supplied, the formatter prints to `stdout`. -If `PATH` is supplied, it prints to the given file. - -This option may be used multiple times in order to output different formats to different files. -If multiple formats are specified with the same output, only the last is used. - -### Built-in formatters - -* **message** - prints each [message](https://github.com/cucumber/cucumber/tree/master/cucumber-messages) in NDJSON form, which can then be consumed by other tools. -* **html** - prints a rich HTML report to a standalone page -* **json** - prints the feature as JSON. *Note: this formatter is in maintenance mode and won't have new features added to it. Where you need a structured data representation of your test run, it's best to use the `message` formatter. Tools that rely on this formatter will continue to work, but are encouraged to migrate to consume the `message` output instead.* -* **progress** - prints one character per scenario (default). -* **progress-bar** - prints a progress bar and outputs errors/warnings along the way. -* **rerun** - prints the paths of any non-passing scenarios ([example](/features/rerun_formatter.feature)) - * suggested use: add the rerun formatter to your default profile and the output file to your `.gitignore`. - * After a failed run, remove any arguments used for selecting feature files and add the rerun file in order to rerun just failed scenarios. The rerun file must start with an `@` sign in order for cucumber to parse it as a rerun file instead of a feature file. - * Use with `--fail-fast` to rerun the failure and the remaining features. -* **snippets** - prints just the code snippets for undefined steps. -* **summary** - prints a summary only, after all scenarios were executed. -* **usage** - prints a table with data about step definitions usage. -* **usage-json** - prints the step definitions usage data as JSON. +See [Formatters](./formatters.md). ### Officially-supported standalone formatters @@ -77,13 +52,9 @@ If multiple formats are specified with the same output, only the last is used. ### Format Options -You can pass in format options with `--format-options `. The JSON string must define an object. This option is repeatable and the objects will be merged with the last instance taking precedence. +You can pass in format options with `--format-options `. -* Suggested use: add with profiles so you can define an object and use `JSON.stringify` instead of writing `JSON` manually. - -## Colors - -Colors can be disabled with `--format-options '{"colorsEnabled": false}'` +See [Formatters](./formatters.md). ## Exiting @@ -99,48 +70,13 @@ disable _strict_ mode. By default, cucumber works in _strict_ mode, meaning it will fail if there are pending steps. -## Undefined Step Snippets - -Undefined steps snippets are printed in JavaScript using the callback interface by default. - -### Interface - -Override the snippet interface with `--format-options '{"snippetInterface": ""}'`. -Valid interfaces are 'async-await', 'callback', 'generator', 'promise', or 'synchronous'. - -### Syntax - -Override the snippet syntaxes with `--format-options '{"snippetSyntax": ""}'`. -See [here](/docs/custom_snippet_syntaxes.md) for documentation about building a custom snippet syntax. - -## Rerun separator - -The separator used by the rerun formatter can be overwritten by specifying `--format-options '{"rerun": {"separator": ""}}'`. -This is useful when one needs to rerun failed tests locally by copying a line from a CI log while using a space character as a separator. -The default separator is a newline character. -Note that the rerun file parser can only work with the default separator for now. - ## Parallel -You can run your scenarios in parallel with `--parallel `. Each worker is run in a separate Node process and receives the following env variables: - -* `CUCUMBER_PARALLEL` - set to 'true' -* `CUCUMBER_TOTAL_WORKERS` - set to the number of workers -* `CUCUMBER_WORKER_ID` - ID for worker ('0', '1', '2', etc.) - -### Timing - -When using parallel mode, the last line of the summary output differentiates between real time elapsed during the test run and aggregate time spent actually running steps: - -``` -73 scenarios (73 passed) -512 steps (512 passed) -0m51.627s (executing steps: 4m51.228s) -``` +See [Parallel](./parallel.md). ## Profiles -In order to store and reuse commonly used CLI options, you can add a `cucumber.js` file to your project root directory. The file should export an object where the key is the profile name and the value is a string of CLI options. The profile can be applied with `-p ` or `--profile `. This will prepend the profile's CLI options to the ones provided by the command line. Multiple profiles can be specified at a time. If no profile is specified and a profile named `default` exists, it will be applied. +See [Profiles](./profiles.md). ## Tags @@ -157,8 +93,7 @@ A note on using in conjunction with `--retry`: we consider a test case to have f ## Retry failing tests -Use `--retry ` to rerun tests that have been failing. This can be very helpful for flaky tests. -To only retry failing tests in a subset of test use `--retry-tag-filter ` (use the same as in Use [Tags](#tags)) +See [Retry](./retry.md) ## Transpilation @@ -228,10 +163,4 @@ Note that the first `--require tests.setup.js` overrides the default require glo ## World Parameters -You can pass in parameters to pass to the world constructor with `--world-parameters `. The JSON string must define an object. The parsed object will be passed as the `parameters` to the the world constructor. This option is repeatable and the objects will be merged with the last instance taking precedence. - -Example: - -``` ---world-parameters '{"fancySetting":true}' -``` +See [World](./support_files/world.md). diff --git a/docs/custom_snippet_syntaxes.md b/docs/custom_snippet_syntaxes.md index a8c85ad26..ce5d1e137 100644 --- a/docs/custom_snippet_syntaxes.md +++ b/docs/custom_snippet_syntaxes.md @@ -1,4 +1,4 @@ -#### Custom snippet syntaxes +# Custom Snippet Syntaxes * See the [JavaScript syntax](/src/formatter/step_definition_snippet_builder/javascript_snippet_syntax.ts) and the [custom snippet syntax](/features/step_definition_snippets_custom_syntax.feature) for examples. * Arguments passed to the constructor: diff --git a/docs/dry_run.md b/docs/dry_run.md new file mode 100644 index 000000000..1f0f8ea0b --- /dev/null +++ b/docs/dry_run.md @@ -0,0 +1,20 @@ +# Dry Run + +You can run cucumber-js in "Dry Run" mode like this: + +```shell +$ cucumber-js --dry-run +``` + +The effect is that cucumber-js will still do all the aggregation work of looking at your feature files, loading your support code etc but without actually executing the tests. Specifically: + +- No [hooks](./support_files/hooks.md) are executed +- Steps are reported as "skipped" instead of being executed +- Undefined and ambiguous steps are reported, but don't cause the process to fail + +A few examples where this is useful: + +- Finding unused step definitions with the [usage formatter](./formatters.md#usage) +- Generating [snippets](./snippets.md) for all undefined steps with the [snippets formatter](./formatters.md#snippets) +- Checking if your path, tag expression etc matches the scenarios you expect it to + diff --git a/docs/esm.md b/docs/esm.md new file mode 100644 index 000000000..bea20b256 --- /dev/null +++ b/docs/esm.md @@ -0,0 +1,34 @@ +# ES Modules (experimental) + +You can optionally write your support code (steps, hooks, etc) with native ES modules syntax - i.e. using `import` and `export` statements without transpiling. This is enabled without any additional configuration, and you can use either of the `.js` or `.mjs` file extensions. + +**Important**: please note that your configuration file referenced for [Profiles](./profiles.md) - aka `cucumber.js` file - must remain a CommonJS file. In a project with `type=module`, you can name the file `cucumber.cjs`, since Node expects `.js` files to be in ESM syntax in such projects. + +Example (adapted from [our original example](./nodejs_example.md)): + +```javascript +// features/support/steps.mjs +import { Given, When, Then } from '@cucumber/cucumber' +import { strict as assert } from 'assert' + +Given('a variable set to {int}', function (number) { + this.setTo(number) +}) + +When('I increment the variable by {int}', function (number) { + this.incrementBy(number) +}) + +Then('the variable should contain {int}', function (number) { + assert.equal(this.variable, number) +}) +``` + +As well as support code, these things can also be in ES modules syntax: + +- Custom formatters +- Custom snippets + +You can use ES modules selectively/incrementally - so you can have a mixture of CommonJS and ESM in the same project. + +When using a transpiler for e.g. TypeScript, ESM isn't supported - you'll need to configure your transpiler to output modules in CommonJS syntax (for now). diff --git a/docs/faq.md b/docs/faq.md index 21f00b2a2..530a6602d 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -2,12 +2,16 @@ ## The world instance isn’t available in my hooks or step definitions. -This has frequently been caused by the use of ES6 arrow functions. -If you are using the world instance (which is bound to `this`) in a step definition, then you cannot use ES6 arrow functions for step definitions or hooks because they bind `this` to the current context which prevents the world instance from being injected. +If you are referencing the world instance (which is bound to `this`) in a step definition or hook, then you cannot use ES6 arrow functions. + +Cucumber uses [apply](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) internally to call your [step definition](./support_files/step_definitions.md) and +[hook](./support_files/hooks.md) functions using the world object as `this`. + +Using `apply` [does not work with arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#call_apply_and_bind), so if you need to reference the world, use a regular `function`. ## Why do my definition patterns need to be globally unique instead of unique only within `Given`, `When`, `Then`? -To encourage a ubiquitous, non-ambiguous domain language. +To encourage a ubiquitous, non-ambiguous domain language. Using the same language to mean different things is basically the definition of ambiguous. If you have similar `Given` and `Then` patterns, try adding the word “should” to `Then` patterns. diff --git a/docs/formatters.md b/docs/formatters.md new file mode 100644 index 000000000..040a8f9f0 --- /dev/null +++ b/docs/formatters.md @@ -0,0 +1,127 @@ +# Formatters + +In cucumber-js, Formatters ingest data about your test run in real time and then output content, either to the console or a file, in a useful format. (Some frameworks refer to this kind of thing as "reporters".) + +cucumber-js provides many built-in Formatters, plus building blocks with which you can [write your own](./custom_formatters.md). + +You can specify one or more formats via the `--format ` CLI option, where `TYPE` is one of: + +* The name of one of the built-in formatters (below) e.g. `progress` +* A module/package name e.g. `@cucumber/pretty-formatter` +* A relative path to a local formatter implementation e.g. `./my-customer-formatter.js` + +If `PATH` is supplied, the formatter prints to the given file, otherwise it prints to `stdout`. + +Some notes on specifying Formatters: + +* If multiple formatters are specified with the same output, only the last is used. +* If no formatter for `stdout` is specified, we default to the `progress` formatter. + +## Options + +Many formatters, including the built-in ones, support some configurability via options. You can provide this data as a JSON literal via the `--format-options` CLI option, like this: + +```shell +$ cucumber-js --format-options '{"someOption":true}' +``` + +This option is repeatable, so you can use it multiple times and the objects will be merged with the later ones taking precedence. + +Some options offered by built-in formatters: + +- `colorsEnabled` - if set to `false`, colors in terminal output are disabled. + +## Built-in formatters + +### `summary` + +The Summary Formatter outputs a summary of the test run's results. + +If everything passed, this will be short and sweet: + +![](./images/summary_green.gif) + +If there were issues, you'll see useful details including: + +- Failed hooks or steps including error messages and stack traces +- Locations of any pending steps +- [Snippets](./snippets.md) to implement any undefined steps + +### `progress` + +The Progress Formatter has the same output as the Summary Formatter at the end of the test run, but also provides concise real-time feedback each time a step or hook completes: + +![](./images/progress.gif) + +### `progress-bar` + +Similar to the Progress Formatter, but provides a real-time updating progress bar based on the total number of steps to be executed in the test run: + +![](./images/progress_bar_green.gif) + +*Note: the Progress Bar Formatter will only work with a TTY terminal (and not, for example, a file stream).* + +### `html` + +The HTML Formatter produces a rich interactive report bundled as a standalone HTML page: + +![](./images/html_formatter.png) + +You can: + +- See detailed results including error messages and stack traces +- See attachments rendered in-place +- Filter to specific statuses +- Search by keywords or tag expressions + +### `message` + +Outputs all the [Cucumber Messages](https://github.com/cucumber/common/tree/main/messages) for the test run as newline-delimited JSON, which can then be consumed by other tools. + +### `json` + +Outputs details of the test run in the legacy JSON format. + +*Note: this formatter is in maintenance mode and won't have new features added to it. Where you need a structured data representation of your test run, it's best to use the `message` formatter. Tools that rely on this formatter will continue to work, but are encouraged to migrate to consume the `message` output instead.* + +### `snippets` + +The Snippets Formatter doesn't output anything regarding the test run; it just prints [Snippets to implement any undefined steps](./snippets.md). This is useful when you want to quickly zero in on the steps you have to implement and grab the snippet code for them in one go. + +### `usage` + +The Usage Formatter lists your step definitions and tells you about usages in your scenarios, including the duration of each usage, and any unused steps. Here's an example of the output: + +``` +┌───────────────────────────────────────┬──────────┬─────────────────────────────────┐ +│ Pattern / Text │ Duration │ Location │ +├───────────────────────────────────────┼──────────┼─────────────────────────────────┤ +│ an empty todo list │ 760.33ms │ support/steps/steps.ts:6 │ +│ an empty todo list │ 820ms │ features/empty.feature:4 │ +│ an empty todo list │ 761ms │ features/adding-todos.feature:4 │ +│ an empty todo list │ 700ms │ features/empty.feature:4 │ +├───────────────────────────────────────┼──────────┼─────────────────────────────────┤ +│ I add the todo {string} │ 432.00ms │ support/steps/steps.ts:10 │ +│ I add the todo "buy some cheese" │ 432ms │ features/adding-todos.feature:5 │ +├───────────────────────────────────────┼──────────┼─────────────────────────────────┤ +│ my cursor is ready to create a todo │ 53.00ms │ support/steps/steps.ts:27 │ +│ my cursor is ready to create a todo │ 101ms │ features/empty.feature:10 │ +│ my cursor is ready to create a todo │ 5ms │ features/adding-todos.feature:8 │ +├───────────────────────────────────────┼──────────┼─────────────────────────────────┤ +│ no todos are listed │ 46.00ms │ support/steps/steps.ts:15 │ +│ no todos are listed │ 46ms │ features/empty.feature:7 │ +├───────────────────────────────────────┼──────────┼─────────────────────────────────┤ +│ the todos are: │ 31.00ms │ support/steps/steps.ts:21 │ +│ the todos are: │ 31ms │ features/adding-todos.feature:6 │ +├───────────────────────────────────────┼──────────┼─────────────────────────────────┤ +│ I remove the todo {string} │ UNUSED │ support/steps/steps.ts:33 │ +└───────────────────────────────────────┴──────────┴─────────────────────────────────┘ +``` + +### `usage-json` + +Does what the Usage Formatter does, but outputs JSON, which can be output to a file and then consumed by other tools. + +### Other officially-supported formatters + +* [@cucumber/pretty-formatter](https://www.npmjs.com/package/@cucumber/pretty-formatter) - prints the feature with inline results, colours and custom themes. diff --git a/docs/images/html_formatter.png b/docs/images/html_formatter.png new file mode 100644 index 000000000..dc899e1da Binary files /dev/null and b/docs/images/html_formatter.png differ diff --git a/docs/images/progress.gif b/docs/images/progress.gif new file mode 100644 index 000000000..79fea358e Binary files /dev/null and b/docs/images/progress.gif differ diff --git a/docs/images/progress_bar_green.gif b/docs/images/progress_bar_green.gif new file mode 100644 index 000000000..f7e59d52a Binary files /dev/null and b/docs/images/progress_bar_green.gif differ diff --git a/docs/images/summary_green.gif b/docs/images/summary_green.gif new file mode 100644 index 000000000..ce6e54d82 Binary files /dev/null and b/docs/images/summary_green.gif differ diff --git a/docs/migration.md b/docs/migration.md index b965f9b6a..e45c9e569 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -1,18 +1,90 @@ +# Migrating to cucumber-js 8.x.x + +## Generator step definitions + +Generator functions used in step definitions (`function*` with the `yield` keyword) +are not natively supported anymore with cucumber-js. + +You may consider using `async`/`await` rather than generators. + +You can still use generators as before but you need to add your own dependencies +to `bluebird` and `is-generator`. Cucumber-js will no display explicit error message +anymore in case you use a generator without wrapping it properly. + +```javascript +const isGenerator = require('is-generator') +const {coroutine} = require('bluebird') +const {setDefinitionFunctionWrapper} = require('@cucumber/cucumber') + +setDefinitionFunctionWrapper(function (fn) { + if (isGenerator.fn(fn)) { + return coroutine(fn) + } else { + return fn + } +}) +``` + # Migrating to cucumber-js 7.x.x ## Package Name cucumber-js is now published at `@cucumber/cucumber` instead of `cucumber`. To upgrade, you'll need to remove the old package and add the new one: - + ```shell $ npm rm cucumber $ npm install --save-dev @cucumber/cucumber -``` - +``` + You'll need to update any `import`/`require` statements in your support code to use the new package name. (The executable is still `cucumber-js` though.) +## Hooks + +The result object passed as the argument to your `After` hook function has a different structure. + +Previously in `cucumber`: + +```js +{ + "sourceLocation": { + "uri": "features/example.feature", + "line": 7 + }, + "pickle": {...}, + "result": { + "duration": 660000000, + "status": "failed", + "exception": { + "name": "AssertionError", + "message": "...", + "showDiff": false, + "stack": "..." + }, + "retried": true + } +} +``` + +Now in `@cucumber/cucumber`: + +```js +{ + "gherkinDocument": {...}, // schema: https://github.com/cucumber/common/blob/messages/v16.0.1/messages/jsonschema/GherkinDocument.json + "pickle": {...}, // schema: https://github.com/cucumber/common/blob/messages/v16.0.1/messages/jsonschema/Pickle.json + "testCaseStartedId": "[uuid]", + "result": { + "status": "FAILED", // one of: UNKNOWN, PASSED, SKIPPED, PENDING, UNDEFINED, AMBIGUOUS, FAILED + "message": "...", // includes stack trace + "duration": { + "seconds": "0", + "nanos": 660000000 + } + } +} +``` + ## Formatters The underlying event/data model for cucumber-js is now [cucumber-messages](https://github.com/cucumber/cucumber/tree/master/messages), a shared standard across all official Cucumber implementations. This replaces the old "event protocol". @@ -49,4 +121,4 @@ There are a few minor differences to be aware of: - The type for data tables was named `TableDefinition` - it's now named `DataTable` - `World` was typed as an interface, but it's actually a class - you should `extend` it when [building a custom formatter](./custom_formatters.md) -Also, your `tsconfig.json` should have the `resolveJsonModule` compiler option switched on. Other than that, a pretty standard TypeScript setup should work as expected. \ No newline at end of file +Also, your `tsconfig.json` should have the `resolveJsonModule` compiler option switched on. Other than that, a pretty standard TypeScript setup should work as expected. diff --git a/docs/nodejs_example.md b/docs/nodejs_example.md index e880ade1c..9f4eb0650 100644 --- a/docs/nodejs_example.md +++ b/docs/nodejs_example.md @@ -1,6 +1,6 @@ ## Setup -- Install [Node.js](https://nodejs.org) (10 or higher) +- Install [Node.js](https://nodejs.org) (12 or higher) - Install Cucumber modules with [yarn](https://yarnpkg.com/en/) **or** [npm](https://www.npmjs.com/) ``` diff --git a/docs/parallel.md b/docs/parallel.md new file mode 100644 index 000000000..889c027d8 --- /dev/null +++ b/docs/parallel.md @@ -0,0 +1,29 @@ +# Parallel + +Cucumber supports running scenarios in parallel. The main process becomes a "coordinator" and spins up several separate Node processes to be the "workers". You can enable this with the `--parallel ` CLI option: + +```shell +$ cucumber-js --parallel 3 +``` + +The number you provide is the number of workers that will run scenarios in parallel. + +Each worker receives the following env variables (as well as a copy of `process.env` from the coordinator process): + +* `CUCUMBER_PARALLEL` - set to 'true' +* `CUCUMBER_TOTAL_WORKERS` - set to the number of workers +* `CUCUMBER_WORKER_ID` - ID for worker ('0', '1', '2', etc.) + +### Timing + +When using parallel mode, the last line of the summary output differentiates between real time elapsed during the test run and aggregate time spent actually running steps: + +``` +73 scenarios (73 passed) +512 steps (512 passed) +0m51.627s (executing steps: 4m51.228s) +``` + +### Hooks + +When using parallel mode, any `BeforeAll` and `AfterAll` hooks you have defined will run _once per worker_. diff --git a/docs/profiles.md b/docs/profiles.md new file mode 100644 index 000000000..eaff7cc21 --- /dev/null +++ b/docs/profiles.md @@ -0,0 +1,101 @@ +# Profiles + +If you have several permutations of running Cucumber with different CLI options in your project, it might be a bit cumbersome to manage. *Profiles* enable you to declare bundles of configuration and reference them with a single CLI option. You can use multiple profiles at once and you can still supply options directly on the command line when using profiles. + +Profiles are invoked from the command line using the `--profile` option. + +```shell +$ cucumber-js --profile my_profile +``` + +The short tag is `-p` + +```shell +$ cucumber-js -p my_profile +``` + +## Simple Example + +Let's take the common case of having some things a bit different locally than on a continuous integration server. Here's the command we've been running locally: + +```shell +$ cucumber-js --require-module ts-node/register --require 'support/**/*./ts' --world-parameters '{\"appUrl\":\"http://localhost:3000/\"}' --format progress-bar --format html:./cucumber-report.html +``` + +For argument's sake, we'll want these changes in CI: + +- The URL for the app (maybe dynamically provisioned?) +- The formatters we want to use + +To start using Profiles, we just need to create a `cucumber.js` file in our project's root. This file must be a CommonJS module, so when using Cucumber with ES6 modules the file will need to be named `cucumber.cjs`. + +This file is a simple JavaScript module that exports an object with profile names as keys and CLI options as values. We can lean on JavaScript to reduce duplication and grab things dynamically as needed. Here's what we might write to address the needs described above: + +```javascript +const worldParameters = { + appUrl: process.env.MY_APP_URL || "http://localhost:3000/" +} + +const common = `--require-module ts-node/register --require 'support/**/*./ts' --world-parameters '${JSON.stringify(worldParameters)}'` + +module.exports = { + 'default': `${common} --format progress-bar --format html:./cucumber-report.html`, + 'ci': `${common} --format html:./cucumber-report.html --publish` +} +``` + +Now, if we just run `cucumber-js` with no arguments, it will pick up our profiles and use the `default` one. To run the CI profile we will use this command: + +```shell +$ cucumber-js -p ci +``` + +## Using Profiles for Arguments + +Cucumber doesn't allow custom command line arguments. For example: + +```shell +$ cucumber-js --myArgument +``` + +The above will result in `error: unknown option '--myArgument'`. + +At first glance this can create problems for test suites that need configuration on the fly, particularly web page test suites that need to run the exact same tests against different browser engines and viewport sizes. However, profiles can be used to work around this problem. + +The intended method for passing arguments to tests is the `--world-parameters` CLI option, discussed in detail in the section on the [World](./support_files/world.md) object. As this argument expects a JSON literal it can be very tedious to use directly. However, we can use a profile as an alias for each of these options. + +Consider the following profile configuration file: + +```javascript +module.exports = { + desktop: `--world-parameters '{"device": {"type":"desktop","height":720,"width":1280}}'`, + phone: `--world-parameters '{"device": {"type":"phone","height":568,"width":320}}'`, + tablet: `--world-parameters '{"device": {"type":"tablet","height":1024,"width":768}}'`, + chromium: `--world-parameters '{"browser": "chromium"}'`, + firefox: `--world-parameters '{"browser": "firefox"}'`, + webkit: `--world-parameters '{"browser": "webkit"}'` +} +``` +With it in place we can invoke a test of the iPhone with this command: + +```shell +$ cucumber-js -p webkit -p phone +``` + +The world parameter arguments from the two profile calls will be merged. If you pass profiles that try to set the same parameter, the last one passed in the chain will win out. + +## Using another file than `cucumber.js` + +Run `cucumber-js` with `--config` - or `-c` - to specify your configuration file if it is something else than the default `cucumber.js`. + +```shell +$ cucumber-js --config .cucumber-rc.js +``` + +**NOTE:** The extension remains controlled by whether your project is configured to use ES6 modules. If it is, you have to use the `cjs` extension. + +## Summary +- Profiles are used to group common cli arguments together for easy reuse. +- They can also be used to create world-parameter options rather than trying to use a JSON literal on the command line. +- The `--profile` or `-p` CLI option is repeatable, so you can apply multiple profiles at once. +- You can still supply options directly on the command line when using profiles, they will be appended to whatever comes from profiles. diff --git a/docs/rerun.md b/docs/rerun.md new file mode 100644 index 000000000..6cf07292b --- /dev/null +++ b/docs/rerun.md @@ -0,0 +1,58 @@ +# Rerun + +*Note: if you want a mechanism to retry flaky scenarios when they fail in CI, take a look at [Retry](./retry.md) instead.* + +If you're doing TDD, you might sometimes work like this: + +1. Run all the tests to see what fails +2. Make changes to address failures +3. Run just the tests that failed +4. GOTO 2 + +Rerun makes this kind of workflow convenient, so you don't have to hand-craft command line arguments to run just the tests that failed on the previous run. + +First, enable the `rerun` formatter every time you run cucumber-js: + +```shell +--format rerun:@rerun.txt +``` + +You can do this via the CLI, or more likely via a [default profile](./profiles.md). + +The output file doesn't have to be named `@rerun.txt`, but its name _does_ have to start with `@` - this is how cucumber-js will later distinguish it from feature files. Either way, you should add this file to your `.gitignore` so you don't accidentally commit it. + +Let's say we run cucumber-js for a Todo app we've made, and a few scenarios fail. Our rerun file's contents would look something like this: + +``` +features/adding.feature:3:19 +features/editing.feature:8 +``` + +If this notation looks familiar, it's the same as for specifying scenarios by line on the CLI, and translates to: + +- In `adding.feature`, the scenarios on lines 3 and 19 +- In `editing.feature`, the scenario on line 8 + +So, let's say we've looked at the failure on `editing.feature` and fixed our code. Now let's run cucumber-js again, but pointing at the rerun file: + +```shell +$ cucumber-js @rerun.txt +``` + +cucumber-js will unpack this and just run those three failing scenarios accordingly. This time, it goes a bit better - our fix worked, and the rerun file now looks like this: + +``` +features/adding.feature:3:19 +``` + +In other words, the one we fixed has passed and thus dropped off. We can repeat this cycle as many times as needed until eventually the rerun file will be empty because everything has passed. If you run cucumber-js pointing at an empty rerun file, no scenarios will be run. + +## Separator + +By default, entries in the rerun file are separated by newlines. This can be overwritten via a [format option](./formatters.md#options): + +``` +--format-options '{"rerun": {"separator": ""}}' +``` + +This is useful when one needs to rerun failed tests locally by copying a line from a CI log while using a space character as a separator. Note that the rerun file parser can only work with the default separator for now. diff --git a/docs/retro/2021/07/17.md b/docs/retro/2021/07/17.md new file mode 100644 index 000000000..406c64bc6 --- /dev/null +++ b/docs/retro/2021/07/17.md @@ -0,0 +1,46 @@ +# 2021-07-17 + +This retrospective was from the first [new contributors mob/ensemble]. Sadly [@mattwynne] failed to record the stream, so there's no video from this session. + +## Who + +* [@artismarti] +* [@16sheep] +* [@eoola] +* [@mattwynne] (taking these notes) + +## What happened? + +* We read the issues at https://github.com/cucumber/cucumber-js/contribute +* We decided to tackle one +* We discussed how contributing to the repo worked +* We changed what to tackle and tackled something simpler +* We made a [PR](https://github.com/cucumber/cucumber-js/pull/1734). + +## What worked? What do you appreciate? + +* I learned general concepts that I could use in other open source projects +* The issues were good for first timers. I'm keen to explore more now I've looked through them! +* It was so much fun! All the intimidation I had about starting to do this vanished. Low stakes way of learning new things. A nice way of learning new stuff! +* The team gelled almost instantly + +## What was puzzling or frustrating? + +* Why did the tests pass on your device but not mine? +* Live Share vs Screen Share it was a bit confusing +* Would it be easier to just run it locally on one of our machines? More realistic. +* Twitch setup (Matt heard his own voice the whole way through, and we started late) + +## What should we decide / change for next time? + +* Do this regularly but on any codebase, not just Cucumber +* Would it be easier to just run it locally on one of our machines? +* Matt do more homeowrk on twitch setup +* Let's do this again! +* Update CONTRIBUTING.md guide to include pointers to basics about forking, how to name your branch etc., and some words of comfort and encouragement to make mistakes, ask for help etc. + +[@artismarti]: https://github.com/artismarti +[@mattwynne]: https://github.com/mattwynne +[@16sheep]: https://github.com/16sheep +[@eoola]: https://github.com/eoola +[new contributors mob/ensemble]: https://cucumber.io/blog/open-source/tackling-structural-racism-(and-sexism)-in-open-so/ \ No newline at end of file diff --git a/docs/retro/2021/08/06.md b/docs/retro/2021/08/06.md new file mode 100644 index 000000000..2de03e3ee --- /dev/null +++ b/docs/retro/2021/08/06.md @@ -0,0 +1,38 @@ +# 2021-08-06 + +This session was streamed live and recorded. Watch the video [here](https://youtu.be/EiqLzBBpjxM). + +## Who + +* [@artismarti] +* [@16sheep] +* [@mattwynne] (taking these notes) + +## What happened + +* Discussed what to do. +* Worked from Marju's fork, using our own local machines and VSCode each time we switched driver. +* Re-did the work we did last time on the mobbing machine, using Marju's machine to submit a new PR ([#1764]) cleanly. We learned about `git cherry-pick`. +* Started working through the pre-prepared issue [#1136] in a [branch on Marju's fork](https://github.com/16sheep/cucumber-js/tree/opt-out-print-attachments-1136) +* Arti had to leave a bit early + +## Insights + +* Preferred working on own machine, not using the live share / mobbing machine. +* Good to prepare. But, wonder if you over-prepare, it doesn't leave space for people to explore and learn. +* Good to have an issue to focus on, and perhaps a failing test (but we could also write this ourselves). + * It would help to share what we're goin g to work on beforehand so people watching can also know ahead of time. Decide now for next session? +* Matt didn't like being in charge of the timer. + * Could use different mechanism for changing turns, like when we make a commit, or when a test is passing? +* More people would be nice. Should we make it easier for people to join? How? How often can we run it? + +### Actions / decisions + +* Next time, continue with fixing [#1136] + +[@artismarti]: https://github.com/artismarti +[@mattwynne]: https://github.com/mattwynne +[@16sheep]: https://github.com/16sheep +[#1764]: https://github.com/cucumber/cucumber-js/pull/1764 +[#1136]: https://github.com/cucumber/cucumber-js/issues/1136 + diff --git a/docs/retro/2022/01/14.md b/docs/retro/2022/01/14.md new file mode 100644 index 000000000..129718da1 --- /dev/null +++ b/docs/retro/2022/01/14.md @@ -0,0 +1,24 @@ +# What we liked: + +* small pieces / small steps +* screensharing - made it easy to switch over, like when Demi left +* liked talking about cars! - personal connection is really important. +* liked the explanation of the World. Hugely valuable for Blaise! Cucumber ecosystem struggles defining these concepts for newcomers. +* A clear objective with many similar, small examples of it. Easy to shift context from one problem to the next, even though they were all slightly different. +* we just kept rolling when Blaise arrived and Demi left. +* Kate coming along even though she didn't feel she had a lot to contribute + +# Anything we would do differently? Puzzles? + +* Took half an hour to get started - setting up the environment, etc. A script to get everything set up beforehand? GitPod? 15 minutes was just spent chatting but we value that! +* Deciding what to work on took some time too - could we do that in Slack beforehand? +* We could log how time is spent. Blaise has acted as "the scribe" beforehand. +* VS Code linting was broken on Matt's machine at least. +* Matt's GPG keychain +* Tests run slowly + +# Actions + +* Kate: be the scribe next week, and spot how we spend our time +* Matt: Fix GPG key and linting thing +* Blaise: Come along next week! \ No newline at end of file diff --git a/docs/retro/2022/01/21.md b/docs/retro/2022/01/21.md new file mode 100644 index 000000000..a686e8ddb --- /dev/null +++ b/docs/retro/2022/01/21.md @@ -0,0 +1,33 @@ +# 2022-01-21 +## Who + +* Kate Dames +* Blaise Pabon +* Matt Wynne + +## What happened + +* Kate and Blaise showed up 2 weeks in a row! +* We talked about the docs, and their shortcomings +* We decided we wanted a real example of Cucumber used in practice +* We looked at https://github.com/gothinkster/realworld +* We decided to start work on the thingy to retire inactive contributors (https://github.com/cucumber/commitbit/issues/3) +* We made an example map: https://miro.com/app/board/uXjVOVYhVEw=/?moveToWidget=3458764517125398282&cot=14 +* We had this retro + +## Insights + +* Kate liked that we're using a real-world example. +* Kate liked going through the example mapping looking at actual data in the examples - e.g. Greg, Julien etc. +* Kate liked that we used Miro for collaboration to pin-down our thoughts - park some things for later etc. +* Blaise liked doing example mapping in action, so concretely. Learning the distinctions between a rule / example and a story. +* Blaise: Materials used to teach cucumber don't emphasise the end result (e.g. the intermediate progress towards a goal). Also don't emphasis how you can use a single test to run against multiple implementations. +* Matt: Our docs don't give people enough context as they arrive - straight into the guts of installation without any signposts +* Matt: How much we discovered about a problem I thought was simple. I love example mapping! +* Kate: I wanted to be more actively participating in the miro board. More hands on. Was it a lack of familiarity? Should we have mad more formal mob roles? What are the rules of the example mapping game? +* Kate: It was fun, thankyou! + +## Actions + +* Matt: figure out where we should implement this - in the existing commitbit repo or somewhere else? +* Kate: think about the process and formalising exmaple mapping diff --git a/docs/retro/README.md b/docs/retro/README.md new file mode 100644 index 000000000..261644f11 --- /dev/null +++ b/docs/retro/README.md @@ -0,0 +1,13 @@ +# Retrospective notes + +From time to time, we run a mobbing/ensemble session on this codebase. At the end of each session., we +run a brief [retrospective] conversation in an effort to "turn up the good" – Woody Zuill. + +Each retro we run is recorded in this folder as a dated Markdown file. + +e.g. To find the retrospective for 23rd May 2020 you would look in the file `2020/05/23.md` + +We use [retro-tools] to help manage these files. + +[retrospective]: https://www.agilealliance.org/glossary/heartbeatretro/ +[retro-tools]: https://github.com/tooky/retro-tools diff --git a/docs/retry.md b/docs/retry.md new file mode 100644 index 000000000..2cbdd953c --- /dev/null +++ b/docs/retry.md @@ -0,0 +1,28 @@ +# Retry + +*Note: if you want a mechanism to rerun just the failed scenarios when doing TDD, take a look at [Rerun](./rerun.md) instead.* + +If you have a flaky scenario (e.g. failing 10% of the time for some reason), you can use *Retry* to have Cucumber attempt it multiple times until either it passes or the maximum number of attempts is reached. You enable this via the `--retry ` CLI option, like this: + +```shell +$ cucumber-js --retry 1 +``` + +The number you provide is the number of retries that will be allowed after an initial failure. + +*Note:* Retry isn't recommended for routine use, but can be a good trade-off in some situations where you have a scenario that's too valuable to remove, but it's either not possible or not worth the effort to fix the flakiness. + +Some notes on how Retry works: + +- Only relevant failing scenarios are retried, not the whole test run. +- When a scenario is retried, it runs all hooks and steps again from the start with a fresh [World](./support_files/world.md) - nothing is retained from the failed attempt. +- When a scenario passes on a retry, it's treated as a pass overall in the results, although the details of each attempt are emitted so formatters can access them. + + +## Targeting scenarios + +Using the `--retry` option alone would mean every scenario would be allowed multiple attempts - this almost certainly isn't what you want, assuming you have a small set of flaky scenarios. To target just the relevant scenarios, you can provide a [tag expression](https://cucumber.io/docs/cucumber/api/#tag-expressions) via the `--retry-tag-filter ` CLI option, like this: + +```shell +$ cucumber-js --retry 1 --retry-tag-filter @flaky +``` diff --git a/docs/snippets.md b/docs/snippets.md new file mode 100644 index 000000000..b6540b430 --- /dev/null +++ b/docs/snippets.md @@ -0,0 +1,60 @@ +# Snippets + +Often in a BDD workflow, you'll write one or more steps in a feature file _before_ implementing the corresponding step definition(s). When you run cucumber-js and it finds these undefined steps, it will generate a Snippet for each one - a skeletal chunk of JavaScript with the correct expression and arguments that you can drop into your code to get started. [Formatters](./formatters.md) that are designed for the terminal will output the snippets. + +Let's say we're iterating on this feature: + +```gherkin +Feature: Removing todos + + Scenario: Add and then remove a todo from an empty list + Given an empty todo list + When I add the todo "buy some cheese" + And I remove the todo "buy some cheese" +``` + +The last step about removing todos isn't implemented yet - we just wrote that into the scenario, so now it's time to write the step definition. If we run cucumber-js, it will announce the undefined step and provide the Snippet in the output: + +```js +Then('I remove the todo {string}', function (string) { + // Write code here that turns the phrase above into concrete actions + return 'pending'; +}); +``` + +By default, the snippet uses the "synchronous" style. You can use the `snippetInterface` [format option](./formatters.md#options) to specify one of the styles that supports asynchronous steps: + +- "async-await" - Outputs an async function where you can use `await` - probably the best choice if you aren't sure. + Running with `--format-options '{"snippetInterface":"async-await"}'` yields: + ```js + Then('I remove the todo {string}', async function (string) { + // Write code here that turns the phrase above into concrete actions + return 'pending'; + }); + ``` +- "callback" - Outputs a plain function with a callback function as the final argument. + Running with `--format-options '{"snippetInterface":"callback"}'` yields: + ```js + Then('I remove the todo {string}', function (string, callback) { + // Write code here that turns the phrase above into concrete actions + callback(null, 'pending'); + }); + ``` +- "promise" - Outputs a plain function from which you should return a `Promise`. + Running with `--format-options '{"snippetInterface":"promise"}'` yields: + ```js + Then('I remove the todo {string}', function (string) { + // Write code here that turns the phrase above into concrete actions + return Promise.resolve('pending'); + }); + ``` +- "synchronous" - Outputs a plain function with no async pattern (see earlier example). + +## Options + +These [format options](./formatters.md#options) influence how the snippets are rendered by all formatters that output snippets: + +- `snippetInterface` - set to one of 'async-await', 'callback', 'promise', or 'synchronous' to alter the style of generated snippets for undefined steps +- `snippetSyntax` - module name of path of the [custom snippet syntax](./custom_snippet_syntaxes.md) to be used + + diff --git a/docs/support_files/api_reference.md b/docs/support_files/api_reference.md index 8a98404b3..c3fa28d45 100644 --- a/docs/support_files/api_reference.md +++ b/docs/support_files/api_reference.md @@ -2,7 +2,7 @@ ## API Reference -Each method can be destructed from the object returned by `require('@cucumber/cucumber')`. +Each method can be destructed from the object returned by `require('@cucumber/cucumber')`. --- @@ -14,7 +14,9 @@ Define a new parameter type and optionally convert an output parameter into some * `regexp`: A regular expression (or array of regular expressions) that match the parameter. * `transformer`: An optional function which transforms the captured argument from a string into what is passed to the step definition. If no transform function is specified, the captured argument is left as a string. - The function can be synchronous or return a `Promise` of the transformed value. The value of `this` is the current world, so the function can delegate to world functions. World delegation does not work with arrow functions. + The function can be synchronous or return a `Promise` of the transformed value. The value of `this` is the current world, so the function can delegate to world functions. + Note that your transformer functions cannot reference the [world](./world.md) as `this` if you use + arrow functions. See [FAQ](../faq.md) for details. * `useForSnippets`: Defaults to `true`. That means this parameter type will be used to generate snippets for undefined steps. If the `regexp` frequently matches text you don't intend to be used as arguments, disable its use for snippets with `false`. * `preferForRegexpMatch`: Defaults to `false`. Set to `true` if you use regular expressions and you want this parameter type's `regexp` to take precedence over others during a match. @@ -67,8 +69,9 @@ Defines a hook which is run after each step. * `tags`: String tag expression used to apply this hook to only specific scenarios. See [cucumber-tag-expressions](https://docs.cucumber.io/tag-expressions/) for more information. * `timeout`: A hook-specific timeout, to override the default timeout. * `fn`: A function, defined as follows: - * The first argument will be an object of the form `{pickle, gherkinDocument, result, testCaseStartedId, testStepId}` - * The pickle object comes from the [gherkin](https://github.com/cucumber/cucumber/tree/gherkin/v15.0.2/gherkin) library. See `testdata/good/*.pickles.ndjson` for examples of its structure. + * The first argument will be an object of the form `{pickle, pickleStep, gherkinDocument, result, testCaseStartedId, testStepId}` + * The `pickle` object comes from the [gherkin](https://github.com/cucumber/cucumber/tree/gherkin/v15.0.2/gherkin) library. See `testdata/good/*.pickles.ndjson` for examples of its structure. + * The `pickleStep` is the step in the `pickle` that this hook has been invoked for * When using the asynchronous callback interface, have one final argument for the callback function. `options` can also be a string as a shorthand for specifying `tags`. @@ -132,6 +135,8 @@ Set the default timeout for asynchronous steps. Defaults to `5000` milliseconds. #### `setDefinitionFunctionWrapper(wrapper)` +_Note: the usage of `setDefinitionFunctionWrapper` is discouraged in favor of [BeforeStep](#beforestepoptions-fn) and [AfterStep](#afterstepoptions-fn) hooks._ + Set a function used to wrap step / hook definitions. The `wrapper` function is expected to take 2 arguments: @@ -139,7 +144,7 @@ The `wrapper` function is expected to take 2 arguments: - `fn` is the original function defined for the step - needs to be called in order for the step to be run. - `options` is the step specific `wrapperOptions` and may be undefined. -A common use case is attaching a screenshot on step failure - this would typically look something like (for a promise-based setup): +Example: ```javascript setDefinitionFunctionWrapper(function(fn, options) { @@ -148,8 +153,6 @@ setDefinitionFunctionWrapper(function(fn, options) { // ensure return value of function is returned return fn.apply(this, args) .catch(error => { - // call a method on world - this.doScreenshot(); // rethrow error to avoid swallowing failure throw error; }); diff --git a/docs/support_files/hooks.md b/docs/support_files/hooks.md index 448585664..df9e25a63 100644 --- a/docs/support_files/hooks.md +++ b/docs/support_files/hooks.md @@ -2,6 +2,9 @@ Hooks are used for setup and teardown the environment before and after each scenario. See the [API reference](./api_reference.md) for the specification of the first argument passed to hooks. Multiple *Before* hooks are executed in the order that they were defined. Multiple *After* hooks are executed in the **reverse** order that they were defined. +Note that your hook functions cannot reference the [world](./world.md) as `this` if you use +arrow functions. See [FAQ](../faq.md) for details. + ```javascript var {After, Before} = require('@cucumber/cucumber'); @@ -121,4 +124,3 @@ AfterStep( function ({result}) { } }); ``` - diff --git a/docs/support_files/step_definitions.md b/docs/support_files/step_definitions.md index 15d116f96..b62e2da76 100644 --- a/docs/support_files/step_definitions.md +++ b/docs/support_files/step_definitions.md @@ -1,6 +1,6 @@ # Step Definitions -Step definitions (`Given`, `When`, `Then`) are the glue between features written in Gherkin and the actual tests implemenation. +Step definitions (`Given`, `When`, `Then`) are the glue between features written in Gherkin and the actual tests implementation. Cucumber supports two types of expressions: @@ -18,13 +18,16 @@ Given I have 42 cucumbers in my belly JS: ```js -import { Given } from 'cucumber'; +import { Given } from '@cucumber/cucumber'; Given('I have {int} cucumbers in my belly', function (cucumberCount) { assert.equal(this.responseStatus, cucumberCount) }); ``` +Note that your step definition functions cannot reference the [world](./world.md) as `this` if you use +arrow functions. See [FAQ](../faq.md) for details. + ## Regular expressions Matching groups in the regular expression are passed as parameters to the step definition. diff --git a/docs/support_files/timeouts.md b/docs/support_files/timeouts.md index b3c4dc822..4154821d0 100644 --- a/docs/support_files/timeouts.md +++ b/docs/support_files/timeouts.md @@ -23,7 +23,7 @@ Given(/^a slow step$/, {timeout: 60 * 1000}, function() { }); ``` -*Note that you should not call `setDefaultTimeout` from within a hook or step; it should be called globally.* +*Note that you should not call `setDefaultTimeout` from within other support code e.g. a step, hook or your World class; it should be called globally.* ## Disable Timeouts @@ -32,14 +32,13 @@ Given(/^a slow step$/, {timeout: 60 * 1000}, function() { Disable timeouts by setting it to -1. If you use this, you need to implement your own timeout protection. Otherwise the test suite may end prematurely or hang indefinitely. +The helper `wrapPromiseWithTimeout`, which cucumber-js itself uses to enforce timeouts is available if needed. ```javascript -var {Before, Given} = require('@cucumber/cucumber'); -var Promise = require('bluebird'); +var {Before, Given, wrapPromiseWithTimeout} = require('@cucumber/cucumber'); Given('the operation completes within {n} minutes', {timeout: -1}, function(minutes) { const milliseconds = (minutes + 1) * 60 * 1000 - const message = `operation did not complete within ${minutes} minutes` - return Promise(this.verifyOperationComplete()).timeout(milliseconds, message); + return wrapPromiseWithTimeout(this.verifyOperationComplete(), milliseconds); }); ``` diff --git a/docs/support_files/world.md b/docs/support_files/world.md index 59f768fd2..3d7066575 100644 --- a/docs/support_files/world.md +++ b/docs/support_files/world.md @@ -1,23 +1,46 @@ # World -*World* is an isolated context for each scenario, exposed to the hooks and steps as `this`. -The default world constructor is: +*World* is an isolated context for each scenario, exposed to the hooks and steps as `this`, enabling you to set and recall some state across the lifecycle of your scenario. + +Note that your hooks and step definition functions cannot reference the world as `this` if you use +arrow functions. See [FAQ](../faq.md) for details. + +A simple example: ```javascript -class World { - constructor({ attach, log, parameters }) { - this.attach = attach - this.log = log - this.parameters = parameters - } -} +const { When } = require('@cucumber/cucumber') + +When('something happens', async function() { + this.foo = 'bar' +}) +``` + +As well as being able to have arbitrary state, you get some helpers preset on the World for you: + +* `this.attach`: function used for adding [attachments](./attachments.md) to hooks/steps +* `this.log`: function used for [logging](./attachments.md#logging) information from hooks/steps +* `this.parameters`: object of parameters passed in via the [CLI](../cli.md#world-parameters) + +Some notes on the scope of World: + +- It's scoped to a single scenario only - not shared globally between scenarios. This reinforces a Cucumber principle: that scenarios should work entirely independently of one another. +- If you're using [Retry](../retry.md), you'll get a fresh World for every attempt at your scenario, so state isn't retained between attempts. + +## World Parameters + +You might want to provide some configuration/environmental data to your World at runtime. You can provide this data as a JSON literal via the `--world-parameters` CLI option, like this: + +```shell +$ cucumber-js --world-parameters '{"appUrl":"http://localhost:3000/"}' ``` -* `attach`: function used for adding [attachments](./attachments.md) to hooks/steps -* `log`: function used for [logging](./attachments.md#logging) information from hooks/steps -* `parameters`: object of parameters passed in via the [CLI](../cli.md#world-parameters) +This option is repeatable, so you can use it multiple times and the objects will be merged with the later ones taking precedence. + +This data is then available on `this.parameters` from your hooks and steps. -You can provide your own World class with its own properties and methods that help with your instrumentation. You can extend the built-in `World` with your own class and then call `setWorldConstructor` with it: +## Custom World + +You might also want to have methods on your World that hooks and steps can access to keep their own code simple. To do this, you can provide your own World class with its own properties and methods that help with your instrumentation, and then call `setWorldConstructor` to tell Cucumber about it. You should extend the built-in `World` class: ```javascript const { setWorldConstructor, World } = require('@cucumber/cucumber') @@ -27,11 +50,12 @@ class CustomWorld extends World { driver = new seleniumWebdriver.Builder() .forBrowser('firefox') .build() - + constructor(options) { + // needed so `attach`, `log` and `parameters` are properly set super(options) } - + // Returns a promise that resolves to the element async waitForElement(locator) { const condition = seleniumWebdriver.until.elementLocated(locator) @@ -41,5 +65,3 @@ class CustomWorld extends World { setWorldConstructor(CustomWorld) ``` - -**Note:** The World constructor was made strictly synchronous in *[v0.8.0](https://github.com/cucumber/cucumber-js/releases/tag/v0.8.0)*. diff --git a/features/attachments.feature b/features/attachments.feature index 86bf33ae5..739134c6e 100644 --- a/features/attachments.feature +++ b/features/attachments.feature @@ -128,17 +128,17 @@ Feature: Attachments Given a file named "features/support/hooks.js" with: """ const {After} = require('@cucumber/cucumber') - const Promise = require('bluebird') After(function() { - // Do not return the promise so that the attach happens after the hook completes - Promise.delay(100).then(() => { + // Do not use the callback / promise interface so that the attach happens after the hook completes + setTimeout(() => { this.attach("text") - }) + }, 100) }) """ When I run cucumber-js - Then the error output contains the text: + Then it fails + And the error output contains the text: """ Cannot attach when a step/hook is not running. Ensure your step/hook waits for the attach to finish. """ diff --git a/features/before_after_all_hook_interfaces.feature b/features/before_after_all_hook_interfaces.feature index 683881627..1b0dfc9e3 100644 --- a/features/before_after_all_hook_interfaces.feature +++ b/features/before_after_all_hook_interfaces.feature @@ -121,7 +121,6 @@ Feature: before / after all hook interfaces Given a file named "features/step_definitions/failing_steps.js" with: """ const {} = require('@cucumber/cucumber') - const Promise = require('bluebird') (function(callback) { return Promise.resolve() @@ -145,7 +144,6 @@ Feature: before / after all hook interfaces Given a file named "features/support/hooks.js" with: """ const {} = require('@cucumber/cucumber') - const Promise = require('bluebird') (function() { return Promise.resolve() @@ -163,7 +161,6 @@ Feature: before / after all hook interfaces Given a file named "features/support/hooks.js" with: """ const {} = require('@cucumber/cucumber') - const Promise = require('bluebird') (function() { return Promise.reject(new Error('my error')) @@ -185,7 +182,6 @@ Feature: before / after all hook interfaces Given a file named "features/support/hooks.js" with: """ const {} = require('@cucumber/cucumber') - const Promise = require('bluebird') (function() { return Promise.reject() @@ -208,7 +204,6 @@ Feature: before / after all hook interfaces Given a file named "features/support/hooks.js" with: """ const {} = require('@cucumber/cucumber') - const Promise = require('bluebird') (function() { return new Promise(function() { diff --git a/features/cli.feature b/features/cli.feature deleted file mode 100644 index 59beda6d5..000000000 --- a/features/cli.feature +++ /dev/null @@ -1,44 +0,0 @@ -Feature: Command line interface - In order to run cucumber in different contexts - As a person who wants to run features - I want to run Cucumber on the command line - - Scenario: run feature with non-default step definitions file location specified (-r option) - Given a file named "features/a.feature" with: - """ - Feature: some feature - Scenario: - When a step is passing - """ - And a file named "step_definitions/cucumber_steps.js" with: - """ - const {When} = require('@cucumber/cucumber') - - When(/^a step is passing$/, function() {}) - """ - When I run cucumber-js with `-r step_definitions/cucumber_steps.js` - - Scenario: run feature with step definitions in required directory (-r option) - Given a file named "features/a.feature" with: - """ - Feature: some feature - Scenario: - When a step is passing - """ - And a file named "step_definitions/cucumber_steps.js" with: - """ - const {When} = require('@cucumber/cucumber') - - When(/^a step is passing$/, function() {}); - """ - When I run cucumber-js with `-r step_definitions` - - @spawn - Scenario: display Cucumber version - When I run cucumber-js with `--version` - Then I see the version of Cucumber - - @spawn - Scenario: display help - When I run cucumber-js with `--help` - Then I see the help text for Cucumber diff --git a/features/cli.feature.md b/features/cli.feature.md new file mode 100644 index 000000000..5c8e86a54 --- /dev/null +++ b/features/cli.feature.md @@ -0,0 +1,66 @@ +# Command line interface +In order to run cucumber in different contexts +As a person who wants to run features +I want to run Cucumber on the command line + +## Scenario: run feature with non-default step definitions file location specified (-r option) + +* Given a file named "features/a.feature" with: + ```gherkin + Feature: some feature + Scenario: + When a step is passing + ``` +* And a file named "step_definitions/cucumber_steps.js" with: + ```javascript + const {When} = require('@cucumber/cucumber') + + When(/^a step is passing$/, function() {}) + ``` +* When I run cucumber-js with `-r step_definitions/cucumber_steps.js` +* Then it passes + +## Scenario: run Markdown feature with non-default step definitions file location specified (-r option) + +* Given a file named "features/a.feature.md" with: + ```markdown + # Feature: some feature + ## Scenario: + * When a step is passing + ``` +* And a file named "step_definitions/cucumber_steps.js" with: + ```javascript + const {When} = require('@cucumber/cucumber') + + When(/^a step is passing$/, function() {}) + ``` +* When I run cucumber-js with `-r step_definitions/cucumber_steps.js` +* Then it passes + +## Scenario: run feature with step definitions in required directory (-r option) + +* Given a file named "features/a.feature" with: + ```gherkin + Feature: some feature + Scenario: + When a step is passing + ``` +* And a file named "step_definitions/cucumber_steps.js" with: + ```javascript + const {When} = require('@cucumber/cucumber') + + When(/^a step is passing$/, function() {}); + ``` +* When I run cucumber-js with `-r step_definitions` +* Then it passes + +`@spawn` +# Scenario: display Cucumber version + +* When I run cucumber-js with `--version` +* Then I see the version of Cucumber + +`@spawn` +# Scenario: display help +* When I run cucumber-js with `--help` +* Then I see the help text for Cucumber diff --git a/features/custom_stack_trace.feature b/features/custom_stack_trace.feature deleted file mode 100644 index 4f940fb6f..000000000 --- a/features/custom_stack_trace.feature +++ /dev/null @@ -1,23 +0,0 @@ -Feature: Custom stack trace - - @spawn - Scenario: Error.prepareStackTrace override - Given a file named "features/a.feature" with: - """ - Feature: Some feature - Scenario: Some scenario - Given Error.prepareStackTrace has been overriden - """ - Given a file named "features/step_definitions/cucumber_steps.js" with: - """ - const {When} = require('@cucumber/cucumber') - - const _prepareStackTrace = Error.prepareStackTrace; - Error.prepareStackTrace = () => { return 'Custom message' } - - When(/^Error.prepareStackTrace has been overriden$/, function() {}) - - Error.prepareStackTrace = _prepareStackTrace - """ - When I run cucumber-js - Then it passes diff --git a/features/direct_imports.feature b/features/direct_imports.feature index c01905136..1bebbb903 100644 --- a/features/direct_imports.feature +++ b/features/direct_imports.feature @@ -44,3 +44,42 @@ Feature: Core feature elements execution using direct imports """ features/step_definitions/cucumber_steps.js:3 """ + + Scenario: deep imports don't break everything + Given a file named "features/a.feature" with: + """ + Feature: some feature + Scenario: some scenario + Given a step passes + """ + And a file named "features/step_definitions/cucumber_steps.js" with: + """ + const {Given} = require('@cucumber/cucumber') + const TestCaseHookDefinition = require('@cucumber/cucumber/lib/models/test_case_hook_definition') + + Given(/^a step passes$/, function() {}); + """ + When I run cucumber-js + Then it passes + + Scenario: we can import the version number from package.json and from the library + Given a file named "features/a.feature" with: + """ + Feature: some feature + Scenario: some scenario + Given a step checks the version number + """ + And a file named "features/step_definitions/cucumber_steps.js" with: + """ + const {Given} = require('@cucumber/cucumber') + const package_version = require('@cucumber/cucumber/package.json').version + const library_version = require('@cucumber/cucumber').version + + Given(/^a step checks the version number$/, function() { + if (package_version !== library_version) { + throw new Error(`package version: ${package_version} !== library version: ${library_version}`) + } + }); + """ + When I run cucumber-js + Then it passes diff --git a/features/dryrun_mode.feature b/features/dryrun_mode.feature index a0f52ebda..c71ff163c 100644 --- a/features/dryrun_mode.feature +++ b/features/dryrun_mode.feature @@ -18,6 +18,7 @@ Feature: Dryrun mode Given('a step', function() {}) """ When I run cucumber-js with `--dry-run` + And it passes Then scenario "some scenario" step "Given a step" has status "skipped" And scenario "some scenario" has status "skipped" @@ -30,12 +31,29 @@ Feature: Dryrun mode Given('a(n) step', function() {}); """ When I run cucumber-js with `--dry-run` - Then it fails + Then it passes And scenario "some scenario" step "Given a step" has status "ambiguous" + Scenario: pending step + + Since steps aren't actually executed in dry run, a step that would resolve to pending + will still show up as skipped. + + Given a file named "features/step_definitions/cucumber_steps.js" with: + """ + const {Given} = require('@cucumber/cucumber') + + Given('a step', function() { + return 'pending'; + }); + """ + When I run cucumber-js with `--dry-run` + Then it passes + And scenario "some scenario" step "Given a step" has status "skipped" + Scenario: undefined step When I run cucumber-js with `--dry-run` - Then it fails + Then it passes And scenario "some scenario" step "Given a step" has status "undefined" Scenario: hooks should not execute in dry run, serial runtime diff --git a/features/esm.feature b/features/esm.feature new file mode 100644 index 000000000..0191a59cf --- /dev/null +++ b/features/esm.feature @@ -0,0 +1,63 @@ +@esm +Feature: ES modules support + + cucumber-js works with native ES modules + + Scenario Outline: native module syntax works in support code, formatters and snippets + Given a file named "features/a.feature" with: + """ + Feature: + Scenario: one + Given a step passes + + Scenario: two + Given a step passes + """ + And a file named "features/step_definitions/cucumber_steps.js" with: + """ + import {Given} from '@cucumber/cucumber' + + Given(/^a step passes$/, function() {}); + """ + And a file named "custom-formatter.js" with: + """ + import {SummaryFormatter} from '@cucumber/cucumber' + + export default class CustomFormatter extends SummaryFormatter {} + """ + And a file named "custom-snippet-syntax.js" with: + """ + export default class CustomSnippetSyntax { + build(opts) { + return 'hello world' + } + } + """ + And a file named "cucumber.cjs" with: + """ + module.exports = { + 'default': '--format summary' + } + """ + When I run cucumber-js with ` --format ./custom-formatter.js --format-options '{"snippetSyntax": "./custom-snippet-syntax.js"}' ` + Then it passes + Examples: + | args | + | | + | --parallel 2 | + + Scenario: .mjs support code files are matched by default + Given a file named "features/a.feature" with: + """ + Feature: + Scenario: + Given a step passes + """ + And a file named "features/step_definitions/cucumber_steps.mjs" with: + """ + import {Given} from '@cucumber/cucumber' + + Given(/^a step passes$/, function() {}); + """ + When I run cucumber-js + Then it passes diff --git a/features/failing_steps.feature b/features/failing_steps.feature index f2df82d0b..f2971635b 100644 --- a/features/failing_steps.feature +++ b/features/failing_steps.feature @@ -93,7 +93,6 @@ Feature: Failing steps Given a file named "features/step_definitions/failing_steps.js" with: """ const {When} = require('@cucumber/cucumber') - const Promise = require('bluebird') When(/^a failing step$/, function(callback) { return Promise.resolve() @@ -113,7 +112,6 @@ Feature: Failing steps Given a file named "features/step_definitions/failing_steps.js" with: """ const {When} = require('@cucumber/cucumber') - const Promise = require('bluebird') When(/^a failing step$/, function() { return new Promise(function() { @@ -134,7 +132,6 @@ Feature: Failing steps Given a file named "features/step_definitions/failing_steps.js" with: """ const {When} = require('@cucumber/cucumber') - const Promise = require('bluebird') When(/^a failing step$/, function() { return Promise.reject(new Error('my error')) diff --git a/features/fixtures/formatters/failed.json.ts b/features/fixtures/formatters/failed.json.ts index e7fbc29e6..3dd5fc211 100644 --- a/features/fixtures/formatters/failed.json.ts +++ b/features/fixtures/formatters/failed.json.ts @@ -13,15 +13,14 @@ module.exports = [ arguments: [], keyword: 'Given ', line: 3, + name: 'a step', match: { location: 'features/step_definitions/steps.js:3', }, - name: 'a step', result: { - duration: 0, - error_message: - 'Error: my error\n at World. (features/step_definitions/steps.js:3:49)', status: 'failed', + duration: 0, + error_message: 'Error: my error', }, }, ], @@ -30,8 +29,8 @@ module.exports = [ }, ], id: 'a-feature', - keyword: 'Feature', line: 1, + keyword: 'Feature', name: 'a feature', tags: [], uri: 'features/a.feature', diff --git a/features/fixtures/formatters/failed.message.json.ts b/features/fixtures/formatters/failed.message.json.ts index c20a4fa85..11cef7318 100644 --- a/features/fixtures/formatters/failed.message.json.ts +++ b/features/fixtures/formatters/failed.message.json.ts @@ -8,15 +8,17 @@ module.exports = [ }, { gherkinDocument: { - uri: 'features/a.feature', + comments: [], feature: { location: { line: 1, column: 1, }, + tags: [], language: 'en', keyword: 'Feature', name: 'a feature', + description: '', children: [ { scenario: { @@ -24,8 +26,10 @@ module.exports = [ line: 2, column: 3, }, + tags: [], keyword: 'Scenario', name: 'a scenario', + description: '', steps: [ { location: { @@ -37,11 +41,13 @@ module.exports = [ id: '1', }, ], + examples: [], id: '2', }, }, ], }, + uri: 'features/a.feature', }, }, { @@ -52,11 +58,12 @@ module.exports = [ language: 'en', steps: [ { - text: 'a step', - id: '3', astNodeIds: ['1'], + id: '3', + text: 'a step', }, ], + tags: [], astNodeIds: ['2'], }, }, @@ -78,7 +85,7 @@ module.exports = [ { testRunStarted: { timestamp: { - seconds: '0', + seconds: 0, nanos: 0, }, }, @@ -92,64 +99,69 @@ module.exports = [ id: '6', pickleStepId: '3', stepDefinitionIds: ['0'], - stepMatchArgumentsLists: [{}], + stepMatchArgumentsLists: [ + { + stepMatchArguments: [], + }, + ], }, ], }, }, { testCaseStarted: { + attempt: 0, + id: '7', + testCaseId: '5', timestamp: { - seconds: '0', + seconds: 0, nanos: 1000000, }, - attempt: 0, - testCaseId: '5', - id: '7', }, }, { testStepStarted: { + testCaseStartedId: '7', + testStepId: '6', timestamp: { - seconds: '0', + seconds: 0, nanos: 2000000, }, - testStepId: '6', - testCaseStartedId: '7', }, }, { testStepFinished: { + testCaseStartedId: '7', + testStepId: '6', testStepResult: { - status: 'FAILED', - message: - 'Error: my error\n at World. (features/step_definitions/steps.js:3:49)', duration: { - seconds: '0', + seconds: 0, nanos: 0, }, + status: 'FAILED', + message: 'Error: my error', }, timestamp: { - seconds: '0', + seconds: 0, nanos: 3000000, }, - testStepId: '6', - testCaseStartedId: '7', }, }, { testCaseFinished: { + testCaseStartedId: '7', timestamp: { - seconds: '0', + seconds: 0, nanos: 4000000, }, - testCaseStartedId: '7', + willBeRetried: false, }, }, { testRunFinished: { + success: false, timestamp: { - seconds: '0', + seconds: 0, nanos: 5000000, }, }, diff --git a/features/fixtures/formatters/passed-rule.message.json.ts b/features/fixtures/formatters/passed-rule.message.json.ts index e2c51c81c..98210b60b 100644 --- a/features/fixtures/formatters/passed-rule.message.json.ts +++ b/features/fixtures/formatters/passed-rule.message.json.ts @@ -2,22 +2,23 @@ module.exports = [ { source: { uri: 'features/a.feature', - data: - 'Feature: a feature\n Rule: a rule\n Example: an example\n Given a step', + data: 'Feature: a feature\n Rule: a rule\n Example: an example\n Given a step', mediaType: 'text/x.cucumber.gherkin+plain', }, }, { gherkinDocument: { - uri: 'features/a.feature', + comments: [], feature: { location: { line: 1, column: 1, }, + tags: [], language: 'en', keyword: 'Feature', name: 'a feature', + description: '', children: [ { rule: { @@ -25,8 +26,10 @@ module.exports = [ line: 2, column: 3, }, + tags: [], keyword: 'Rule', name: 'a rule', + description: '', children: [ { scenario: { @@ -34,8 +37,10 @@ module.exports = [ line: 3, column: 5, }, + tags: [], keyword: 'Example', name: 'an example', + description: '', steps: [ { location: { @@ -47,6 +52,7 @@ module.exports = [ id: '1', }, ], + examples: [], id: '2', }, }, @@ -56,6 +62,7 @@ module.exports = [ }, ], }, + uri: 'features/a.feature', }, }, { @@ -66,11 +73,12 @@ module.exports = [ language: 'en', steps: [ { - text: 'a step', - id: '4', astNodeIds: ['1'], + id: '4', + text: 'a step', }, ], + tags: [], astNodeIds: ['2'], }, }, @@ -92,7 +100,7 @@ module.exports = [ { testRunStarted: { timestamp: { - seconds: '0', + seconds: 0, nanos: 0, }, }, @@ -106,62 +114,68 @@ module.exports = [ id: '7', pickleStepId: '4', stepDefinitionIds: ['0'], - stepMatchArgumentsLists: [{}], + stepMatchArgumentsLists: [ + { + stepMatchArguments: [], + }, + ], }, ], }, }, { testCaseStarted: { + attempt: 0, + id: '8', + testCaseId: '6', timestamp: { - seconds: '0', + seconds: 0, nanos: 1000000, }, - attempt: 0, - testCaseId: '6', - id: '8', }, }, { testStepStarted: { + testCaseStartedId: '8', + testStepId: '7', timestamp: { - seconds: '0', + seconds: 0, nanos: 2000000, }, - testStepId: '7', - testCaseStartedId: '8', }, }, { testStepFinished: { + testCaseStartedId: '8', + testStepId: '7', testStepResult: { - status: 'PASSED', duration: { - seconds: '0', + seconds: 0, nanos: 0, }, + status: 'PASSED', }, timestamp: { - seconds: '0', + seconds: 0, nanos: 3000000, }, - testStepId: '7', - testCaseStartedId: '8', }, }, { testCaseFinished: { + testCaseStartedId: '8', timestamp: { - seconds: '0', + seconds: 0, nanos: 4000000, }, - testCaseStartedId: '8', + willBeRetried: false, }, }, { testRunFinished: { + success: true, timestamp: { - seconds: '0', + seconds: 0, nanos: 5000000, }, }, diff --git a/features/fixtures/formatters/passed-scenario.message.json.ts b/features/fixtures/formatters/passed-scenario.message.json.ts index 943d14637..856dc5f32 100644 --- a/features/fixtures/formatters/passed-scenario.message.json.ts +++ b/features/fixtures/formatters/passed-scenario.message.json.ts @@ -8,15 +8,17 @@ module.exports = [ }, { gherkinDocument: { - uri: 'features/a.feature', + comments: [], feature: { location: { line: 1, column: 1, }, + tags: [], language: 'en', keyword: 'Feature', name: 'a feature', + description: '', children: [ { scenario: { @@ -24,8 +26,10 @@ module.exports = [ line: 2, column: 3, }, + tags: [], keyword: 'Scenario', name: 'a scenario', + description: '', steps: [ { location: { @@ -37,11 +41,13 @@ module.exports = [ id: '1', }, ], + examples: [], id: '2', }, }, ], }, + uri: 'features/a.feature', }, }, { @@ -52,11 +58,12 @@ module.exports = [ language: 'en', steps: [ { - text: 'a step', - id: '3', astNodeIds: ['1'], + id: '3', + text: 'a step', }, ], + tags: [], astNodeIds: ['2'], }, }, @@ -78,7 +85,7 @@ module.exports = [ { testRunStarted: { timestamp: { - seconds: '0', + seconds: 0, nanos: 0, }, }, @@ -92,62 +99,68 @@ module.exports = [ id: '6', pickleStepId: '3', stepDefinitionIds: ['0'], - stepMatchArgumentsLists: [{}], + stepMatchArgumentsLists: [ + { + stepMatchArguments: [], + }, + ], }, ], }, }, { testCaseStarted: { + attempt: 0, + id: '7', + testCaseId: '5', timestamp: { - seconds: '0', + seconds: 0, nanos: 1000000, }, - attempt: 0, - testCaseId: '5', - id: '7', }, }, { testStepStarted: { + testCaseStartedId: '7', + testStepId: '6', timestamp: { - seconds: '0', + seconds: 0, nanos: 2000000, }, - testStepId: '6', - testCaseStartedId: '7', }, }, { testStepFinished: { + testCaseStartedId: '7', + testStepId: '6', testStepResult: { - status: 'PASSED', duration: { - seconds: '0', + seconds: 0, nanos: 0, }, + status: 'PASSED', }, timestamp: { - seconds: '0', + seconds: 0, nanos: 3000000, }, - testStepId: '6', - testCaseStartedId: '7', }, }, { testCaseFinished: { + testCaseStartedId: '7', timestamp: { - seconds: '0', + seconds: 0, nanos: 4000000, }, - testCaseStartedId: '7', + willBeRetried: false, }, }, { testRunFinished: { + success: true, timestamp: { - seconds: '0', + seconds: 0, nanos: 5000000, }, }, diff --git a/features/fixtures/formatters/rejected-pickle.message.json.ts b/features/fixtures/formatters/rejected-pickle.message.json.ts index 6740e5f1c..6a827beaa 100644 --- a/features/fixtures/formatters/rejected-pickle.message.json.ts +++ b/features/fixtures/formatters/rejected-pickle.message.json.ts @@ -8,15 +8,17 @@ module.exports = [ }, { gherkinDocument: { - uri: 'features/a.feature', + comments: [], feature: { location: { line: 1, column: 1, }, + tags: [], language: 'en', keyword: 'Feature', name: 'a feature', + description: '', children: [ { scenario: { @@ -24,8 +26,10 @@ module.exports = [ line: 2, column: 3, }, + tags: [], keyword: 'Scenario', name: 'a scenario', + description: '', steps: [ { location: { @@ -37,11 +41,13 @@ module.exports = [ id: '0', }, ], + examples: [], id: '1', }, }, ], }, + uri: 'features/a.feature', }, }, { @@ -52,26 +58,28 @@ module.exports = [ language: 'en', steps: [ { - text: 'a step', - id: '2', astNodeIds: ['0'], + id: '2', + text: 'a step', }, ], + tags: [], astNodeIds: ['1'], }, }, { testRunStarted: { timestamp: { - seconds: '0', + seconds: 0, nanos: 0, }, }, }, { testRunFinished: { + success: true, timestamp: { - seconds: '0', + seconds: 0, nanos: 1000000, }, }, diff --git a/features/fixtures/formatters/retried.message.json.ts b/features/fixtures/formatters/retried.message.json.ts index 9a1d0ae39..cc8615094 100644 --- a/features/fixtures/formatters/retried.message.json.ts +++ b/features/fixtures/formatters/retried.message.json.ts @@ -8,15 +8,17 @@ module.exports = [ }, { gherkinDocument: { - uri: 'features/a.feature', + comments: [], feature: { location: { line: 1, column: 1, }, + tags: [], language: 'en', keyword: 'Feature', name: 'a feature', + description: '', children: [ { scenario: { @@ -24,8 +26,10 @@ module.exports = [ line: 2, column: 3, }, + tags: [], keyword: 'Scenario', name: 'a scenario', + description: '', steps: [ { location: { @@ -37,11 +41,13 @@ module.exports = [ id: '1', }, ], + examples: [], id: '2', }, }, ], }, + uri: 'features/a.feature', }, }, { @@ -52,11 +58,12 @@ module.exports = [ language: 'en', steps: [ { - text: 'a step', - id: '3', astNodeIds: ['1'], + id: '3', + text: 'a step', }, ], + tags: [], astNodeIds: ['2'], }, }, @@ -78,7 +85,7 @@ module.exports = [ { testRunStarted: { timestamp: { - seconds: '0', + seconds: 0, nanos: 0, }, }, @@ -92,112 +99,117 @@ module.exports = [ id: '6', pickleStepId: '3', stepDefinitionIds: ['0'], - stepMatchArgumentsLists: [{}], + stepMatchArgumentsLists: [ + { + stepMatchArguments: [], + }, + ], }, ], }, }, { testCaseStarted: { + attempt: 0, + id: '7', + testCaseId: '5', timestamp: { - seconds: '0', + seconds: 0, nanos: 1000000, }, - attempt: 0, - testCaseId: '5', - id: '7', }, }, { testStepStarted: { + testCaseStartedId: '7', + testStepId: '6', timestamp: { - seconds: '0', + seconds: 0, nanos: 2000000, }, - testStepId: '6', - testCaseStartedId: '7', }, }, { testStepFinished: { + testCaseStartedId: '7', + testStepId: '6', testStepResult: { - status: 'FAILED', - message: - 'Error: my error\n at World. (features/step_definitions/steps.js:11:12)', duration: { - seconds: '0', + seconds: 0, nanos: 0, }, - willBeRetried: true, + status: 'FAILED', + message: 'Error: my error', }, timestamp: { - seconds: '0', + seconds: 0, nanos: 3000000, }, - testStepId: '6', - testCaseStartedId: '7', }, }, { testCaseFinished: { + testCaseStartedId: '7', timestamp: { - seconds: '0', + seconds: 0, nanos: 4000000, }, - testCaseStartedId: '7', + willBeRetried: true, }, }, { testCaseStarted: { + attempt: 1, + id: '8', + testCaseId: '5', timestamp: { - seconds: '0', + seconds: 0, nanos: 5000000, }, - attempt: 1, - testCaseId: '5', - id: '8', }, }, { testStepStarted: { + testCaseStartedId: '8', + testStepId: '6', timestamp: { - seconds: '0', + seconds: 0, nanos: 6000000, }, - testStepId: '6', - testCaseStartedId: '8', }, }, { testStepFinished: { + testCaseStartedId: '8', + testStepId: '6', testStepResult: { - status: 'PASSED', duration: { - seconds: '0', + seconds: 0, nanos: 0, }, + status: 'PASSED', }, timestamp: { - seconds: '0', + seconds: 0, nanos: 7000000, }, - testStepId: '6', - testCaseStartedId: '8', }, }, { testCaseFinished: { + testCaseStartedId: '8', timestamp: { - seconds: '0', + seconds: 0, nanos: 8000000, }, - testCaseStartedId: '8', + willBeRetried: false, }, }, { testRunFinished: { + success: true, timestamp: { - seconds: '0', + seconds: 0, nanos: 9000000, }, }, diff --git a/features/formatter_paths.feature b/features/formatter_paths.feature index e9bb7cb6d..886f7a8e3 100644 --- a/features/formatter_paths.feature +++ b/features/formatter_paths.feature @@ -25,7 +25,7 @@ Feature: Formatter Paths Scenario: Absolute path Given "{{{tmpDir}}}" is an absolute path - When I run cucumber-js with `-f summary:{{{tmpDir}}}/summary.txt` + When I run cucumber-js with `-f summary:"{{{tmpDir}}}/summary.txt"` Then the file "{{{tmpDir}}}/summary.txt" has the text: """ 1 scenario (1 passed) diff --git a/features/formatters.feature b/features/formatters.feature index 84dfa0a35..3d75e3d5d 100644 --- a/features/formatters.feature +++ b/features/formatters.feature @@ -8,8 +8,8 @@ Feature: Formatters Given a step """ When I run cucumber-js with all formatters and `--tags @a` - Then the "message" formatter output matches the fixture "formatters/rejected-pickle.message.json" - Then the "json" formatter output matches the fixture "formatters/rejected-pickle.json" + Then the message formatter output matches the fixture "formatters/rejected-pickle.message.json" + Then the json formatter output matches the fixture "formatters/rejected-pickle.json" Then the html formatter output is complete Scenario: passed from Scenario @@ -26,8 +26,8 @@ Feature: Formatters Given(/^a step$/, function() {}) """ When I run cucumber-js with all formatters - Then the "message" formatter output matches the fixture "formatters/passed-scenario.message.json" - Then the "json" formatter output matches the fixture "formatters/passed-scenario.json" + Then the message formatter output matches the fixture "formatters/passed-scenario.message.json" + Then the json formatter output matches the fixture "formatters/passed-scenario.json" Then the html formatter output is complete Scenario: passed from Rule @@ -45,8 +45,8 @@ Feature: Formatters Given(/^a step$/, function() {}) """ When I run cucumber-js with all formatters - Then the "message" formatter output matches the fixture "formatters/passed-rule.message.json" - Then the "json" formatter output matches the fixture "formatters/passed-rule.json" + Then the message formatter output matches the fixture "formatters/passed-rule.message.json" + Then the json formatter output matches the fixture "formatters/passed-rule.json" Then the html formatter output is complete Scenario: failed @@ -63,8 +63,8 @@ Feature: Formatters Given(/^a step$/, function(callback) { callback(new Error('my error')) }) """ When I run cucumber-js with all formatters - Then the "message" formatter output matches the fixture "formatters/failed.message.json" - Then the "json" formatter output matches the fixture "formatters/failed.json" + Then the message formatter output matches the fixture "formatters/failed.message.json" + Then the json formatter output matches the fixture "formatters/failed.json" Then the html formatter output is complete And it fails @@ -91,6 +91,6 @@ Feature: Formatters }) """ When I run cucumber-js with all formatters and `--retry 1` - Then the "message" formatter output matches the fixture "formatters/retried.message.json" - Then the "json" formatter output matches the fixture "formatters/retried.json" + Then the message formatter output matches the fixture "formatters/retried.message.json" + Then the json formatter output matches the fixture "formatters/retried.json" Then the html formatter output is complete diff --git a/features/generator_step_definitions.feature b/features/generator_step_definitions.feature deleted file mode 100644 index a9f520286..000000000 --- a/features/generator_step_definitions.feature +++ /dev/null @@ -1,61 +0,0 @@ -Feature: Generator Step Definitions - In order to use new JavaScript features - As a developer - I want Cucumber to provide the possibility to use ES6 features - - Background: - Given a file named "features/a.feature" with: - """ - Feature: Step is a generator - Scenario: Step generator run successfully - When I call a step which is a generator with return value "ok" - Then I can see the yielded "ok" value in the context - """ - And a file named "features/step_definitions/cucumber_steps.js" with: - """ - const assert = require('assert') - const {setWorldConstructor, Then, When} = require('@cucumber/cucumber') - - setWorldConstructor(function () { - this.context = "" - }) - - When(/^I call a step which is a generator with return value "([^"]*)"$/, function *(return_value) { - this.context = yield Promise.resolve(return_value); - }) - - Then(/^I can see the yielded "([^"]*)" value in the context$/, function(return_value) { - assert.equal(this.context, return_value) - }) - """ - - @spawn - Scenario: without generator function runner - When I run cucumber-js - Then it fails - And the error output contains the text: - """ - The following hook/step definitions use generator functions: - - features/step_definitions/cucumber_steps.js:8 - - Use 'this.setDefinitionFunctionWrapper(fn)' to wrap them in a function that returns a promise - """ - - Scenario: with generator function wrapper - Given a file named "features/support/setup.js" with: - """ - const isGenerator = require('is-generator') - const {coroutine} = require('bluebird') - const {setDefinitionFunctionWrapper} = require('@cucumber/cucumber') - - setDefinitionFunctionWrapper(function (fn) { - if (isGenerator.fn(fn)) { - return coroutine(fn) - } else { - return fn - } - }) - """ - When I run cucumber-js - Then it passes diff --git a/features/hook_interface.feature b/features/hook_interface.feature index 9fab4031d..7fcd1b92a 100644 --- a/features/hook_interface.feature +++ b/features/hook_interface.feature @@ -129,7 +129,6 @@ Feature: After hook interface Given a file named "features/step_definitions/failing_steps.js" with: """ const {} = require('@cucumber/cucumber') - const Promise = require('bluebird') (function(scenario, callback) { return Promise.resolve() @@ -153,7 +152,6 @@ Feature: After hook interface Given a file named "features/support/hooks.js" with: """ const {} = require('@cucumber/cucumber') - const Promise = require('bluebird') (function() { return Promise.resolve() @@ -171,7 +169,6 @@ Feature: After hook interface Given a file named "features/support/hooks.js" with: """ const {} = require('@cucumber/cucumber') - const Promise = require('bluebird') (function(){ return Promise.reject(new Error('my error')) @@ -193,7 +190,6 @@ Feature: After hook interface Given a file named "features/support/hooks.js" with: """ const {} = require('@cucumber/cucumber') - const Promise = require('bluebird') (function() { return Promise.reject() @@ -216,7 +212,6 @@ Feature: After hook interface Given a file named "features/support/hooks.js" with: """ const {} = require('@cucumber/cucumber') - const Promise = require('bluebird') (function(){ return new Promise(function() { diff --git a/features/i18n.feature b/features/i18n.feature index 3370e8976..af7983c2e 100644 --- a/features/i18n.feature +++ b/features/i18n.feature @@ -1,3 +1,4 @@ +@spawn Feature: internationalization Scenario: view available languages @@ -26,6 +27,7 @@ Feature: internationalization """ ENGLISH KEYWORD | NATIVE KEYWORDS Feature | "フィーチャ", "機能" + Rule | "Rule" Background | "背景" Scenario | "シナリオ" Scenario Outline | "シナリオアウトライン", "シナリオテンプレート", "テンプレ", "シナリオテンプレ" diff --git a/features/parallel.feature b/features/parallel.feature index 686627ede..cc2f92045 100644 --- a/features/parallel.feature +++ b/features/parallel.feature @@ -4,7 +4,6 @@ Feature: Running scenarios in parallel Given a file named "features/step_definitions/cucumber_steps.js" with: """ const {Given} = require('@cucumber/cucumber') - const Promise = require('bluebird') Given(/^a slow step$/, function(callback) { setTimeout(callback, 1000) @@ -27,7 +26,6 @@ Feature: Running scenarios in parallel Given a file named "features/step_definitions/cucumber_steps.js" with: """ const {BeforeAll, Given} = require('@cucumber/cucumber') - const Promise = require('bluebird') Given(/^a slow step$/, function(callback) { setTimeout(callback, 1000) diff --git a/features/parameter_types.feature b/features/parameter_types.feature index 50e6d1a2a..f77e14063 100644 --- a/features/parameter_types.feature +++ b/features/parameter_types.feature @@ -113,7 +113,6 @@ Feature: Parameter types Given a file named "features/step_definitions/particular_steps.js" with: """ const {defineParameterType} = require('@cucumber/cucumber') - const Promise = require('bluebird') defineParameterType({ regexp: /particular/, diff --git a/features/passing_steps.feature b/features/passing_steps.feature index 9d33627f5..1b08c4bca 100644 --- a/features/passing_steps.feature +++ b/features/passing_steps.feature @@ -34,7 +34,6 @@ Feature: Passing steps Given a file named "features/step_definitions/passing_steps.js" with: """ const {Given} = require('@cucumber/cucumber') - const Promise = require('bluebird') Given(/^a passing step$/, function() { return Promise.resolve() diff --git a/features/profiles.feature b/features/profiles.feature index 97b17a2fe..fca00d0fc 100644 --- a/features/profiles.feature +++ b/features/profiles.feature @@ -69,3 +69,29 @@ Feature: default command line arguments 1 step (1 passed) """ + + Scenario Outline: specifying a configuration file + Given a file named ".cucumber-rc.js" with: + """ + module.exports = { + 'default': '--dry-run' + }; + """ + When I run cucumber-js with ` .cucumber-rc.js` + Then it outputs the text: + """ + - + + 1 scenario (1 skipped) + 1 step (1 skipped) + + """ + + Examples: + | OPT | + | -c | + | --config | + + Scenario: specifying a configuration file that doesn't exist + When I run cucumber-js with `--config doesntexist.js` + Then it fails diff --git a/features/publish.feature b/features/publish.feature index c86d36c52..debcf067a 100644 --- a/features/publish.feature +++ b/features/publish.feature @@ -1,3 +1,4 @@ +@flaky Feature: Publish reports Background: @@ -89,17 +90,17 @@ Feature: Publish reports When I run cucumber-js Then the error output contains the text: """ - ┌──────────────────────────────────────────────────────────────────────────┐ - │ Share your Cucumber Report with your team at https://reports.cucumber.io │ - │ │ - │ Command line option: --publish │ - │ Environment variable: CUCUMBER_PUBLISH_ENABLED=true │ - │ │ - │ More information at https://reports.cucumber.io/docs/cucumber-js │ - │ │ - │ To disable this message, add this to your ./cucumber.js: │ - │ module.exports = { default: '--publish-quiet' } │ - └──────────────────────────────────────────────────────────────────────────┘ + ┌──────────────────────────────────────────────────────────────────────────────┐ + │ Share your Cucumber Report with your team at https://reports.cucumber.io │ + │ │ + │ Command line option: --publish │ + │ Environment variable: CUCUMBER_PUBLISH_ENABLED=true │ + │ │ + │ More information at https://cucumber.io/docs/cucumber/environment-variables/ │ + │ │ + │ To disable this message, add this to your ./cucumber.js: │ + │ module.exports = { default: '--publish-quiet' } │ + └──────────────────────────────────────────────────────────────────────────────┘ """ @spawn diff --git a/features/rerun_formatter.feature b/features/rerun_formatter.feature index 33bda2080..c62d8df24 100644 --- a/features/rerun_formatter.feature +++ b/features/rerun_formatter.feature @@ -95,19 +95,11 @@ Feature: Rerun Formatter When I run cucumber-js with `@rerun.txt` Then it runs the scenario "C - passing" - Scenario: empty rerun file + Scenario: empty rerun file exits without running any scenarios Given an empty file named "@rerun.txt" When I run cucumber-js with `@rerun.txt` - Then it fails - And it runs the scenarios: - | NAME | - | A - passing | - | A - failing | - | A - ambiguous | - | B - passing | - | B - pending | - | C - passing | - | C - undefined | + Then it passes + And it runs 0 scenarios Scenario: rerun with fail fast outputs all skipped scenarios When I run cucumber-js with `--fail-fast --format rerun:@rerun.txt` diff --git a/features/retry.feature b/features/retry.feature index 6cca5ccf5..6e114155c 100644 --- a/features/retry.feature +++ b/features/retry.feature @@ -12,27 +12,6 @@ Feature: Retry flaky tests """ And it fails - @spawn - Scenario: running Cucumber JS with --retryTagFilter in camel case will result in a warning - Given a file named "features/a.feature" with: - """ - Feature: - Scenario: - Given a step - """ - Given a file named "features/step_definitions/cucumber_steps.js" with: - """ - const {Given} = require('@cucumber/cucumber') - - Given(/^a step$/, function() {}) - """ - When I run cucumber-js with `--retry 1 --retryTagFilter @flaky` - Then the error output contains the text: - """ - the argument --retryTagFilter is deprecated and will be removed in a future release; please use --retry-tag-filter - """ - But it passes - Scenario: running Cucumber JS with negative --retry will fail When I run cucumber-js with `--retry -1` Then the error output contains the text: @@ -590,4 +569,4 @@ Feature: Retry flaky tests Then it fails And scenario "Failing" attempt 0 step "Given a failing step" has status "failed" And scenario "Failing" attempt 1 step "Given a failing step" has status "failed" - And scenario "Passing" step "Given a passing step" has status "skipped" \ No newline at end of file + And scenario "Passing" step "Given a passing step" has status "skipped" diff --git a/features/step_definition_snippets_custom_syntax.feature b/features/step_definition_snippets_custom_syntax.feature index 5a2ff8077..ece45ba61 100644 --- a/features/step_definition_snippets_custom_syntax.feature +++ b/features/step_definition_snippets_custom_syntax.feature @@ -45,7 +45,7 @@ Feature: step definition snippets custom syntax """ Scenario Outline: - When I run cucumber-js with `--format-options '{"snippetInterface": "", "snippetSyntax": "coffeescript_syntax.js"}'` + When I run cucumber-js with `--format-options '{"snippetInterface": "", "snippetSyntax": "./coffeescript_syntax.js"}'` Then it fails And the output contains the text: """ diff --git a/features/step_definition_snippets_interfaces.feature b/features/step_definition_snippets_interfaces.feature index 437bc8ae7..d0579ecff 100644 --- a/features/step_definition_snippets_interfaces.feature +++ b/features/step_definition_snippets_interfaces.feature @@ -23,9 +23,9 @@ Feature: step definition snippets custom syntax """ Examples: - | INTERFACE | SNIPPET_FUNCTION_KEYWORD_AND_PARAMETERS | SNIPPET_IMPLEMENTATION | - | callback | function (callback) | callback(null, 'pending') | - | generator | function *() | return 'pending' | - | promise | function () | return 'pending' | - | async-await | async function () | return 'pending' | - | synchronous | function () | return 'pending' | + | INTERFACE | SNIPPET_FUNCTION_KEYWORD_AND_PARAMETERS | SNIPPET_IMPLEMENTATION | + | callback | function (callback) | callback(null, 'pending') | + | generator | function *() | return 'pending' | + | promise | function () | return Promise.resolve('pending') | + | async-await | async function () | return 'pending' | + | synchronous | function () | return 'pending' | diff --git a/features/step_definition_timeouts.feature b/features/step_definition_timeouts.feature index 39a45864c..916af5be6 100644 --- a/features/step_definition_timeouts.feature +++ b/features/step_definition_timeouts.feature @@ -4,7 +4,6 @@ Feature: Step definition timeouts Given a file named "features/step_definitions/cucumber_steps.js" with: """ const {Given, setDefaultTimeout} = require('@cucumber/cucumber') - const Promise = require('bluebird') setDefaultTimeout(500) @@ -21,15 +20,21 @@ Feature: Step definition timeouts }) Given(/^a promise step runs slowly$/, function() { - return Promise.resolve().delay(1000) + return new Promise(resolve => { + setTimeout(resolve, 1000) + }) }) Given(/^a promise step runs slowly with an increased timeout$/, {timeout: 1500}, function() { - return Promise.resolve().delay(1000) + return new Promise(resolve => { + setTimeout(resolve, 1000) + }) }) Given(/^a promise step with a disabled timeout$/, {timeout: -1}, function() { - return Promise.resolve().delay(1000) + return new Promise(resolve => { + setTimeout(resolve, 1000) + }) }) """ diff --git a/features/step_definitions/cli_steps.ts b/features/step_definitions/cli_steps.ts index 1f35a0ea0..2431b422b 100644 --- a/features/step_definitions/cli_steps.ts +++ b/features/step_definitions/cli_steps.ts @@ -9,15 +9,18 @@ import { valueOrDefault, } from '../../src/value_checker' import { World } from '../support/world' - -const { version } = require('../../package.json') // eslint-disable-line @typescript-eslint/no-var-requires +import { version } from '../../src/version' When('my env includes {string}', function (this: World, envString: string) { this.sharedEnv = this.parseEnvString(envString) }) +When('I run cucumber-js', { timeout: 10000 }, async function (this: World) { + return await this.run(this.localExecutablePath, []) +}) + When( - /^I run cucumber-js(?: with `(|.+)`)?$/, + 'I run cucumber-js with `{}`', { timeout: 10000 }, async function (this: World, args: string) { const renderedArgs = Mustache.render(valueOrDefault(args, ''), this) @@ -27,7 +30,7 @@ When( ) When( - /^I run cucumber-js with arguments `(|.+)` and env `(|.+)`$/, + 'I run cucumber-js with arguments `{}` and env `{}`', { timeout: 10000 }, async function (this: World, args: string, envString: string) { const renderedArgs = Mustache.render(valueOrDefault(args, ''), this) @@ -38,7 +41,7 @@ When( ) When( - /^I run cucumber-js with env `(|.+)`$/, + 'I run cucumber-js with env `{}`', { timeout: 10000 }, async function (this: World, envString: string) { const env = this.parseEnvString(envString) @@ -47,7 +50,18 @@ When( ) When( - /^I run cucumber-js with all formatters(?: and `(|.+)`)?$/, + 'I run cucumber-js with all formatters', + { timeout: 10000 }, + async function (this: World) { + const args = '--format html:html.out --format json:json.out' + const renderedArgs = Mustache.render(args, this) + const stringArgs = stringArgv(renderedArgs) + return await this.run(this.localExecutablePath, stringArgs) + } +) + +When( + 'I run cucumber-js with all formatters and `{}`', { timeout: 10000 }, async function (this: World, args: string) { if (doesNotHaveValue(args)) { @@ -58,7 +72,7 @@ When( args += ' ' + formats.map((f) => `--format ${f}`).join(' ') const renderedArgs = Mustache.render(args, this) const stringArgs = stringArgv(renderedArgs) - return this.run(this.localExecutablePath, stringArgs) + return await this.run(this.localExecutablePath, stringArgs) } ) diff --git a/features/step_definitions/formatter_steps.ts b/features/step_definitions/formatter_steps.ts index 3d36fdc3d..f4bc18b7a 100644 --- a/features/step_definitions/formatter_steps.ts +++ b/features/step_definitions/formatter_steps.ts @@ -1,34 +1,65 @@ import { Then } from '../../' -import { expect } from 'chai' +import { expect, use } from 'chai' +import chaiExclude from 'chai-exclude' import { + ignorableKeys, normalizeJsonOutput, normalizeMessageOutput, stripMetaMessages, } from '../support/formatter_output_helpers' import fs from 'mz/fs' import path from 'path' -import { messages } from '@cucumber/messages' import { World } from '../support/world' -import Envelope = messages.Envelope + +use(chaiExclude) Then( - 'the {string} formatter output matches the fixture {string}', - async function (this: World, formatter: string, filePath: string) { - let actual: any - if (formatter === 'message') { - actual = this.lastRun.envelopes.map((e: Envelope) => e.toJSON()) - actual = normalizeMessageOutput(actual, this.tmpDir) - actual = stripMetaMessages(actual) - } else { - const actualPath = path.join(this.tmpDir, `${formatter}.out`) - actual = await fs.readFile(actualPath, 'utf8') - if (formatter === 'json') { - actual = normalizeJsonOutput(actual, this.tmpDir) + 'the message formatter output matches the fixture {string}', + async function (this: World, filePath: string) { + let actual = this.lastRun.envelopes // .map((e: Envelope) => JSON.stringify(e)) + actual = normalizeMessageOutput(actual, this.tmpDir) + actual = stripMetaMessages(actual) + const fixturePath = path.join(__dirname, '..', 'fixtures', filePath) + const expected = require(fixturePath) // eslint-disable-line @typescript-eslint/no-var-requires + try { + expect(actual).excludingEvery(ignorableKeys).to.deep.eq(expected) + } catch (e) { + if (process.env.GOLDEN) { + await fs.writeFile( + fixturePath + '.ts', + 'module.exports = ' + JSON.stringify(actual, null, 2), + 'utf-8' + ) + } else { + throw e } } + } +) + +Then( + 'the json formatter output matches the fixture {string}', + async function (this: World, filePath: string) { + const actualPath = path.join(this.tmpDir, `json.out`) + const actualJson = await fs.readFile(actualPath, 'utf8') + const actual = normalizeJsonOutput(actualJson, this.tmpDir) const fixturePath = path.join(__dirname, '..', 'fixtures', filePath) const expected = require(fixturePath) // eslint-disable-line @typescript-eslint/no-var-requires - expect(actual).to.eql(expected) + try { + expect(actual).to.eql(expected) + } catch (e) { + if (process.env.GOLDEN) { + await fs.writeFile( + fixturePath + '.ts', + 'module.exports = ' + JSON.stringify(actual, null, 2), + 'utf-8' + ) + } else { + // eslint-disable-next-line @typescript-eslint/restrict-template-expressions + e.message = `${e.message}\n\nTry running again with GOLDEN=1 if you believe the fixtures need to be overwritten with actual results` + throw e + } + } } ) diff --git a/features/step_definitions/message_steps.ts b/features/step_definitions/message_steps.ts index 1b021441e..b4b7c0eb2 100644 --- a/features/step_definitions/message_steps.ts +++ b/features/step_definitions/message_steps.ts @@ -1,4 +1,3 @@ -import { find, filter } from 'lodash' import { Then } from '../../' import { expect } from 'chai' import DataTable from '../../src/models/data_table' @@ -10,29 +9,17 @@ import { getTestStepAttachmentsForStep, getTestStepResults, } from '../support/message_helpers' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { World } from '../support/world' import semver from 'semver' -type StringifiedStatus = - | 'UNKNOWN' - | 'PASSED' - | 'SKIPPED' - | 'PENDING' - | 'UNDEFINED' - | 'AMBIGUOUS' - | 'FAILED' - -const { Status } = messages.TestStepFinished.TestStepResult - -const ENCODING_MAP: { [key: string]: messages.Attachment.ContentEncoding } = { - IDENTITY: messages.Attachment.ContentEncoding.IDENTITY, - BASE64: messages.Attachment.ContentEncoding.BASE64, +const ENCODING_MAP: { [key: string]: messages.AttachmentContentEncoding } = { + IDENTITY: messages.AttachmentContentEncoding.IDENTITY, + BASE64: messages.AttachmentContentEncoding.BASE64, } Then('it runs {int} scenarios', function (this: World, expectedCount: number) { - const testCaseStartedEvents = filter( - this.lastRun.envelopes, + const testCaseStartedEvents = this.lastRun.envelopes.filter( (e) => e.testCaseStarted ) expect(testCaseStartedEvents).to.have.lengthOf(expectedCount) @@ -62,7 +49,7 @@ Then( function (this: World, name: string, status: string) { const result = getTestCaseResult(this.lastRun.envelopes, name) expect(result.status).to.eql( - Status[status.toUpperCase() as StringifiedStatus] + status.toUpperCase() as messages.TestStepResultStatus ) } ) @@ -85,9 +72,9 @@ Then( this.lastRun.envelopes, pickleName ) - const testStepResult = find(testStepResults, ['text', stepText]) + const testStepResult = testStepResults.find((x) => x.text === stepText) expect(testStepResult.result.status).to.eql( - Status[status.toUpperCase() as StringifiedStatus] + status.toUpperCase() as messages.TestStepResultStatus ) } ) @@ -106,9 +93,9 @@ Then( pickleName, attempt ) - const testStepResult = find(testStepResults, ['text', stepText]) + const testStepResult = testStepResults.find((x) => x.text === stepText) expect(testStepResult.result.status).to.eql( - Status[status.toUpperCase() as StringifiedStatus] + status.toUpperCase() as messages.TestStepResultStatus ) } ) @@ -125,9 +112,9 @@ Then( this.lastRun.envelopes, pickleName ) - const testStepResult = find(testStepResults, ['text', hookKeyword]) + const testStepResult = testStepResults.find((x) => x.text === hookKeyword) expect(testStepResult.result.status).to.eql( - Status[status.toUpperCase() as StringifiedStatus] + status.toUpperCase() as messages.TestStepResultStatus ) } ) @@ -144,14 +131,16 @@ Then( this.lastRun.envelopes, pickleName ) - const testStepResult = find(testStepResults, ['text', stepText]) + const testStepResult = testStepResults.find((x) => x.text === stepText) if (semver.satisfies(process.version, '>=14.0.0')) { errorMessage = errorMessage.replace( '{ member: [Circular] }', ' { member: [Circular *1] }' ) } - expect(testStepResult.result.status).to.eql(Status.FAILED) + expect(testStepResult.result.status).to.eql( + messages.TestStepResultStatus.FAILED + ) expect(testStepResult.result.message).to.include(errorMessage) } ) @@ -170,8 +159,10 @@ Then( pickleName, attempt ) - const testStepResult = find(testStepResults, ['text', stepText]) - expect(testStepResult.result.status).to.eql(Status.FAILED) + const testStepResult = testStepResults.find((x) => x.text === stepText) + expect(testStepResult.result.status).to.eql( + messages.TestStepResultStatus.FAILED + ) expect(testStepResult.result.message).to.include(errorMessage) } ) @@ -249,7 +240,7 @@ Then( hookKeyword: string, table: DataTable ) { - const expectedAttachments: messages.IAttachment[] = table + const expectedAttachments: messages.Attachment[] = table .hashes() .map((x) => { return { diff --git a/features/step_definitions/parallel_steps.ts b/features/step_definitions/parallel_steps.ts index b8dd0725d..a93e927dd 100644 --- a/features/step_definitions/parallel_steps.ts +++ b/features/step_definitions/parallel_steps.ts @@ -1,14 +1,13 @@ import { Then } from '../../' import { World } from '../support/world' -import _, { Dictionary } from 'lodash' -import { messages } from '@cucumber/messages' +import messages from '@cucumber/messages' import { expect } from 'chai' interface TestCaseParser { - pickles: Dictionary - testCases: Dictionary + pickles: Record + testCases: Record running: Set - testStarts: Dictionary + testStarts: Record } function defaultHandlers({ @@ -18,7 +17,7 @@ function defaultHandlers({ testStarts, }: TestCaseParser): Record { return { - pickle: (p: messages.IPickle) => (pickles[p.id] = p), + pickle: (p: messages.Pickle) => (pickles[p.id] = p), testCase: (t: messages.TestCase) => (testCases[t.id] = t.pickleId), testCaseStarted: (t: messages.TestCaseStarted) => { running.add(t.testCaseId) @@ -30,24 +29,24 @@ function defaultHandlers({ } function parse( - envelopes: messages.IEnvelope[], + envelopes: messages.Envelope[], handlers: Record ): void { - _.each(envelopes, (envelope) => - _.forOwn(envelope, (value, key) => { - ;(handlers[key] || _.noop)(value) - }) - ) + envelopes.forEach((envelope) => { + for (const key in envelope) { + ;(handlers[key] || (() => {}))(envelope[key as keyof messages.Envelope]) + } + }) } function verifyTandem( - assertion: (p1: messages.IPickle, p2: messages.IPickle) => void + assertion: (p1: messages.Pickle, p2: messages.Pickle) => void ) { return function (this: World): void { const running = new Set() - const pickles: Dictionary = {} - const testCases: Dictionary = {} - const testStarts: Dictionary = {} + const pickles: Record = {} + const testCases: Record = {} + const testStarts: Record = {} const handlers = defaultHandlers({ pickles, @@ -55,24 +54,24 @@ function verifyTandem( testCases, testStarts, }) - handlers.testCaseStarted = _.wrap( - handlers.testCaseStarted, - (fn, t: messages.TestCaseStarted) => { - running.forEach((tcId) => - assertion(pickles[testCases[tcId]], pickles[testCases[t.testCaseId]]) - ) - fn(t) - } - ) + + const originalFn = handlers.testCaseStarted + handlers.testCaseStarted = (t: messages.TestCaseStarted) => { + running.forEach((tcId) => + assertion(pickles[testCases[tcId]], pickles[testCases[t.testCaseId]]) + ) + originalFn(t) + } + parse(this.lastRun.envelopes, handlers) } } Then(/^it runs tests in order (.+)$/, function (this: World, order: string) { const running = new Set() - const pickles: Dictionary = {} - const testCases: Dictionary = {} - const testStarts: Dictionary = {} + const pickles: Record = {} + const testCases: Record = {} + const testStarts: Record = {} const scenarioNames = order.split(/,\s*/) const handlers = defaultHandlers({ pickles, running, testCases, testStarts }) handlers.testCaseStarted = (t: messages.TestCaseStarted) => diff --git a/features/step_definitions/usage_json_steps.ts b/features/step_definitions/usage_json_steps.ts index 2b1c43910..1a559d1d9 100644 --- a/features/step_definitions/usage_json_steps.ts +++ b/features/step_definitions/usage_json_steps.ts @@ -1,14 +1,13 @@ -import _ from 'lodash' import { DataTable, Then } from '../../' import { expect } from 'chai' import path from 'path' import { World } from '../support/world' +import { IUsage } from '../../src/formatter/helpers/usage_helpers' Then('it outputs the usage data:', function (this: World, table: DataTable) { - const usageData = JSON.parse(this.lastRun.output) + const usageData: IUsage[] = JSON.parse(this.lastRun.output) table.hashes().forEach((row: any) => { - const rowUsage = _.find( - usageData, + const rowUsage = usageData.find( (datum) => datum.pattern === row.PATTERN && datum.patternType === row.PATTERN_TYPE ) diff --git a/features/support/formatter_output_helpers.ts b/features/support/formatter_output_helpers.ts index 2e977103b..f33da9ff3 100644 --- a/features/support/formatter_output_helpers.ts +++ b/features/support/formatter_output_helpers.ts @@ -1,4 +1,3 @@ -import _ from 'lodash' import { doesHaveValue, doesNotHaveValue, @@ -9,6 +8,7 @@ import { IJsonScenario, IJsonStep, } from '../../src/formatter/json_formatter' +import * as messages from '@cucumber/messages' // Converting windows stack trace to posix and removing cwd // C:\\project\\path\\features\\support/code.js @@ -19,9 +19,10 @@ function normalizeExceptionAndUri(exception: string, cwd: string): string { .replace(cwd, '') .replace(/\\/g, '/') .replace('/features', 'features') + .split('\n')[0] } -function normalizeProtobufObject(obj: any, cwd: string): void { +function normalizeMessage(obj: any, cwd: string): void { if (doesHaveValue(obj.uri)) { obj.uri = normalizeExceptionAndUri(obj.uri, cwd) } @@ -45,18 +46,20 @@ function normalizeProtobufObject(obj: any, cwd: string): void { } export function normalizeMessageOutput( - envelopeObjects: any[], + envelopeObjects: messages.Envelope[], cwd: string -): any[] { +): messages.Envelope[] { envelopeObjects.forEach((e: any) => { for (const key in e) { - normalizeProtobufObject(e[key], cwd) + normalizeMessage(e[key], cwd) } }) return envelopeObjects } -export function stripMetaMessages(envelopeObjects: any[]): any[] { +export function stripMetaMessages( + envelopeObjects: messages.Envelope[] +): messages.Envelope[] { return envelopeObjects.filter((e: any) => { // filter off meta objects, almost none of it predictable/useful for testing return doesNotHaveValue(e.meta) @@ -64,13 +67,13 @@ export function stripMetaMessages(envelopeObjects: any[]): any[] { } export function normalizeJsonOutput(str: string, cwd: string): IJsonFeature[] { - const json = JSON.parse(valueOrDefault(str, '[]')) - _.each(json, (feature: IJsonFeature) => { + const json: IJsonFeature[] = JSON.parse(valueOrDefault(str, '[]')) + json.forEach((feature: IJsonFeature) => { if (doesHaveValue(feature.uri)) { feature.uri = normalizeExceptionAndUri(feature.uri, cwd) } - _.each(feature.elements, (element: IJsonScenario) => { - _.each(element.steps, (step: IJsonStep) => { + feature.elements.forEach((element: IJsonScenario) => { + element.steps.forEach((step: IJsonStep) => { if (doesHaveValue(step.match) && doesHaveValue(step.match.location)) { step.match.location = normalizeExceptionAndUri( step.match.location, @@ -93,3 +96,26 @@ export function normalizeJsonOutput(str: string, cwd: string): IJsonFeature[] { }) return json } + +export const ignorableKeys = [ + 'meta', + // sources + 'uri', + 'line', + // ids + 'astNodeId', + 'astNodeIds', + 'hookId', + 'id', + 'pickleId', + 'pickleStepId', + 'stepDefinitionIds', + 'testCaseId', + 'testCaseStartedId', + 'testStepId', + // time + 'nanos', + 'seconds', + // errors + 'message', +] diff --git a/features/support/helpers.ts b/features/support/helpers.ts index 4fa7586f0..a17b1dc57 100644 --- a/features/support/helpers.ts +++ b/features/support/helpers.ts @@ -11,8 +11,10 @@ export function normalizeText(text: string): string { .replace(/\d+(.\d+)?ms/g, 'ms') .replace(/\//g, path.sep) .replace(/ +/g, ' ') + .replace(/─+/gu, '─') .split('\n') .map((line) => line.trim()) .join('\n') + return normalizeSummaryDuration(normalized) } diff --git a/features/support/hooks.ts b/features/support/hooks.ts index 04d5bee06..686822fbf 100644 --- a/features/support/hooks.ts +++ b/features/support/hooks.ts @@ -6,6 +6,7 @@ import tmp from 'tmp' import { doesHaveValue } from '../../src/value_checker' import { World } from './world' import { ITestCaseHookParameter } from '../../src/support_code_library_builder/types' +import { warnUserAboutEnablingDeveloperMode } from './warn_user_about_enabling_developer_mode' const projectPath = path.join(__dirname, '..', '..') @@ -13,7 +14,7 @@ Before('@debug', function (this: World) { this.debug = true }) -Before('@spawn', function (this: World) { +Before('@spawn or @esm', function (this: World) { this.spawn = true }) @@ -39,10 +40,21 @@ Before(function ( '@cucumber', 'cucumber' ) - fsExtra.ensureSymlinkSync(projectPath, tmpDirCucumberPath) + try { + fsExtra.ensureSymlinkSync(projectPath, tmpDirCucumberPath) + } catch (error) { + warnUserAboutEnablingDeveloperMode(error) + } this.localExecutablePath = path.join(projectPath, 'bin', 'cucumber-js') }) +Before('@esm', function (this: World) { + fsExtra.writeJSONSync(path.join(this.tmpDir, 'package.json'), { + name: 'feature-test-pickle', + type: 'module', + }) +}) + Before('@global-install', function (this: World) { const tmpObject = tmp.dirSync({ unsafeCleanup: true }) diff --git a/features/support/message_helpers.ts b/features/support/message_helpers.ts index 63e9ad4a6..8fd545675 100644 --- a/features/support/message_helpers.ts +++ b/features/support/message_helpers.ts @@ -1,62 +1,60 @@ -import _, { Dictionary } from 'lodash' import { getGherkinStepMap } from '../../src/formatter/helpers/gherkin_document_parser' import { getPickleStepMap, getStepKeyword, } from '../../src/formatter/helpers/pickle_parser' import util from 'util' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { Query } from '@cucumber/query' import { doesHaveValue, doesNotHaveValue } from '../../src/value_checker' +import { getWorstTestStepResult } from '@cucumber/messages' export interface IStepTextAndResult { text: string - result: messages.TestStepFinished.ITestStepResult + result: messages.TestStepResult } export function getPickleNamesInOrderOfExecution( - envelopes: messages.IEnvelope[] + envelopes: messages.Envelope[] ): string[] { - const pickleNameMap: Dictionary = _.chain(envelopes) - .filter((e) => doesHaveValue(e.pickle)) - .map((e) => [e.pickle.id, e.pickle.name]) - .fromPairs() - .value() - const testCaseToPickleNameMap: Dictionary = _.chain(envelopes) - .filter((e) => doesHaveValue(e.testCase)) - .map((e) => [e.testCase.id, pickleNameMap[e.testCase.pickleId]]) - .fromPairs() - .value() - return _.chain(envelopes) - .filter((e) => doesHaveValue(e.testCaseStarted)) - .map((e) => testCaseToPickleNameMap[e.testCaseStarted.testCaseId]) - .value() + const pickleNameMap: Record = {} + const testCaseToPickleNameMap: Record = {} + const result: string[] = [] + envelopes.forEach((e) => { + if (e.pickle != null) { + pickleNameMap[e.pickle.id] = e.pickle.name + } else if (e.testCase != null) { + testCaseToPickleNameMap[e.testCase.id] = + pickleNameMap[e.testCase.pickleId] + } else if (e.testCaseStarted != null) { + result.push(testCaseToPickleNameMap[e.testCaseStarted.testCaseId]) + } + }) + return result } export function getPickleStep( - envelopes: messages.IEnvelope[], + envelopes: messages.Envelope[], pickleName: string, stepText: string -): messages.Pickle.IPickleStep { +): messages.PickleStep { const pickle = getAcceptedPickle(envelopes, pickleName) const gherkinDocument = getGherkinDocument(envelopes, pickle.uri) return getPickleStepByStepText(pickle, gherkinDocument, stepText) } export function getTestCaseResult( - envelopes: messages.IEnvelope[], + envelopes: messages.Envelope[], pickleName: string -): messages.TestStepFinished.ITestStepResult { +): messages.TestStepResult { const query = new Query() envelopes.forEach((envelope) => query.update(envelope)) const pickle = getAcceptedPickle(envelopes, pickleName) - return query.getWorstTestStepResult( - query.getPickleTestStepResults([pickle.id]) - ) + return getWorstTestStepResult(query.getPickleTestStepResults([pickle.id])) } export function getTestStepResults( - envelopes: messages.IEnvelope[], + envelopes: messages.Envelope[], pickleName: string, attempt = 0 ): IStepTextAndResult[] { @@ -64,24 +62,22 @@ export function getTestStepResults( const gherkinDocument = getGherkinDocument(envelopes, pickle.uri) const testCase = getTestCase(envelopes, pickle.id) const testCaseStarted = getTestCaseStarted(envelopes, testCase.id, attempt) - const testStepIdToResultMap = _.chain(envelopes) - .filter( - (e) => - doesHaveValue(e.testStepFinished) && - e.testStepFinished.testCaseStartedId === testCaseStarted.id - ) - .map((e) => [ - e.testStepFinished.testStepId, - e.testStepFinished.testStepResult, - ]) - .fromPairs() - .value() + const testStepIdToResultMap: Record = {} + envelopes.forEach((e) => { + if ( + e.testStepFinished != null && + e.testStepFinished.testCaseStartedId === testCaseStarted.id + ) { + testStepIdToResultMap[e.testStepFinished.testStepId] = + e.testStepFinished.testStepResult + } + }) const gherkinStepMap = getGherkinStepMap(gherkinDocument) const pickleStepMap = getPickleStepMap(pickle) let isBeforeHook = true return testCase.testSteps.map((testStep) => { let text = '' - if (testStep.pickleStepId === '') { + if (!doesHaveValue(testStep.pickleStepId)) { text = isBeforeHook ? 'Before' : 'After' } else { isBeforeHook = false @@ -94,16 +90,15 @@ export function getTestStepResults( } export function getTestStepAttachmentsForStep( - envelopes: messages.IEnvelope[], + envelopes: messages.Envelope[], pickleName: string, stepText: string -): messages.IAttachment[] { +): messages.Attachment[] { const pickle = getAcceptedPickle(envelopes, pickleName) const gherkinDocument = getGherkinDocument(envelopes, pickle.uri) const testCase = getTestCase(envelopes, pickle.id) const pickleStep = getPickleStepByStepText(pickle, gherkinDocument, stepText) - const testStep = _.find( - testCase.testSteps, + const testStep = testCase.testSteps.find( (s) => s.pickleStepId === pickleStep.id ) const testCaseStarted = getTestCaseStarted(envelopes, testCase.id) @@ -111,10 +106,10 @@ export function getTestStepAttachmentsForStep( } export function getTestStepAttachmentsForHook( - envelopes: messages.IEnvelope[], + envelopes: messages.Envelope[], pickleName: string, isBeforeHook: boolean -): messages.IAttachment[] { +): messages.Attachment[] { const pickle = getAcceptedPickle(envelopes, pickleName) const testCase = getTestCase(envelopes, pickle.id) const testStepIndex = isBeforeHook ? 0 : testCase.testSteps.length - 1 @@ -124,11 +119,10 @@ export function getTestStepAttachmentsForHook( } function getAcceptedPickle( - envelopes: messages.IEnvelope[], + envelopes: messages.Envelope[], pickleName: string -): messages.IPickle { - const pickleEnvelope = _.find( - envelopes, +): messages.Pickle { + const pickleEnvelope = envelopes.find( (e) => doesHaveValue(e.pickle) && e.pickle.name === pickleName ) if (doesNotHaveValue(pickleEnvelope)) { @@ -142,11 +136,10 @@ function getAcceptedPickle( } function getGherkinDocument( - envelopes: messages.IEnvelope[], + envelopes: messages.Envelope[], uri: string -): messages.IGherkinDocument { - const gherkinDocumentEnvelope = _.find( - envelopes, +): messages.GherkinDocument { + const gherkinDocumentEnvelope = envelopes.find( (e) => doesHaveValue(e.gherkinDocument) && e.gherkinDocument.uri === uri ) if (doesNotHaveValue(gherkinDocumentEnvelope)) { @@ -160,11 +153,10 @@ function getGherkinDocument( } function getTestCase( - envelopes: messages.IEnvelope[], + envelopes: messages.Envelope[], pickleId: string -): messages.ITestCase { - const testCaseEnvelope = _.find( - envelopes, +): messages.TestCase { + const testCaseEnvelope = envelopes.find( (e) => doesHaveValue(e.testCase) && e.testCase.pickleId === pickleId ) if (doesNotHaveValue(testCaseEnvelope)) { @@ -178,12 +170,11 @@ function getTestCase( } function getTestCaseStarted( - envelopes: messages.IEnvelope[], + envelopes: messages.Envelope[], testCaseId: string, attempt = 0 -): messages.ITestCaseStarted { - const testCaseStartedEnvelope = _.find( - envelopes, +): messages.TestCaseStarted { + const testCaseStartedEnvelope = envelopes.find( (e) => doesHaveValue(e.testCaseStarted) && e.testCaseStarted.testCaseId === testCaseId && @@ -200,23 +191,23 @@ function getTestCaseStarted( } function getPickleStepByStepText( - pickle: messages.IPickle, - gherkinDocument: messages.IGherkinDocument, + pickle: messages.Pickle, + gherkinDocument: messages.GherkinDocument, stepText: string -): messages.Pickle.IPickleStep { +): messages.PickleStep { const gherkinStepMap = getGherkinStepMap(gherkinDocument) - return _.find(pickle.steps, (s) => { + return pickle.steps.find((s) => { const keyword = getStepKeyword({ pickleStep: s, gherkinStepMap }) return `${keyword}${s.text}` === stepText }) } function getTestStepAttachments( - envelopes: messages.IEnvelope[], + envelopes: messages.Envelope[], testCaseStartedId: string, testStepId: string -): messages.IAttachment[] { - return _.chain(envelopes) +): messages.Attachment[] { + return envelopes .filter( (e) => doesHaveValue(e.attachment) && @@ -224,5 +215,4 @@ function getTestStepAttachments( e.attachment.testStepId === testStepId ) .map((e) => e.attachment) - .value() } diff --git a/features/support/warn_user_about_enabling_developer_mode.ts b/features/support/warn_user_about_enabling_developer_mode.ts new file mode 100644 index 000000000..fc36d6ee5 --- /dev/null +++ b/features/support/warn_user_about_enabling_developer_mode.ts @@ -0,0 +1,25 @@ +import { reindent } from 'reindent-template-literals' +import chalk from 'chalk' + +export function warnUserAboutEnablingDeveloperMode(error: any): void { + if (!(error?.code === 'EPERM')) { + throw error + } + if (!(process.platform === 'win32')) { + throw error + } + + console.error( + chalk.red( + reindent(` + Error: Unable to run feature tests! + + You need to enable Developer Mode in Windows to run Cucumber JS's feature tests. + + See this link for more info: + https://docs.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging + `) + ) + ) + process.exit(1) +} diff --git a/features/support/world.ts b/features/support/world.ts index 0c3e54dc1..c4706d9ca 100644 --- a/features/support/world.ts +++ b/features/support/world.ts @@ -2,21 +2,23 @@ import { Cli, setWorldConstructor } from '../../' import { execFile } from 'child_process' import { expect } from 'chai' import toString from 'stream-to-string' -import { PassThrough } from 'stream' -import colors from 'colors/safe' +import { PassThrough, pipeline, Writable } from 'stream' +import stripAnsi from 'strip-ansi' import fs from 'fs' import path from 'path' import VError from 'verror' -import _ from 'lodash' -import ndjsonParse from 'ndjson-parse' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' +import * as messageStreams from '@cucumber/message-streams' import FakeReportServer from '../../test/fake_report_server' import { doesHaveValue } from '../../src/value_checker' +import util from 'util' + +const asyncPipeline = util.promisify(pipeline) interface ILastRun { error: any errorOutput: string - envelopes: messages.IEnvelope[] + envelopes: messages.Envelope[] output: string } @@ -56,11 +58,10 @@ export class World { const messageFilename = 'message.ndjson' const args = ['node', executablePath].concat(inputArgs, [ '--backtrace', - '--predictable-ids', '--format', `message:${messageFilename}`, ]) - const env = _.merge({}, process.env, this.sharedEnv, envOverride) + const env = { ...process.env, ...this.sharedEnv, ...envOverride } const cwd = this.tmpDir let result: IRunResult @@ -82,6 +83,7 @@ export class World { argv: args, cwd, stdout, + env, }) let error: any, stderr: string try { @@ -98,11 +100,20 @@ export class World { stdout.end() result = { error, stdout: await toString(stdout), stderr } } - let envelopes: messages.Envelope[] = [] + const envelopes: messages.Envelope[] = [] const messageOutputPath = path.join(cwd, messageFilename) if (fs.existsSync(messageOutputPath)) { - const data = fs.readFileSync(messageOutputPath, { encoding: 'utf-8' }) - envelopes = ndjsonParse(data).map(messages.Envelope.fromObject) + await asyncPipeline( + fs.createReadStream(messageOutputPath, { encoding: 'utf-8' }), + new messageStreams.NdjsonToMessageStream(), + new Writable({ + objectMode: true, + write(envelope: messages.Envelope, _: BufferEncoding, callback) { + envelopes.push(envelope) + callback() + }, + }) + ) } if (this.debug) { console.log(result.stdout + result.stderr) // eslint-disable-line no-console @@ -111,7 +122,7 @@ export class World { error: result.error, errorOutput: result.stderr, envelopes, - output: colors.strip(result.stdout), + output: stripAnsi(result.stdout), } this.verifiedLastRunError = false expect(this.lastRun.output).to.not.include('Unhandled rejection') diff --git a/features/target_specific_scenarios_by_line.feature b/features/target_specific_scenarios_by_line.feature index ae0945edf..8a7870f36 100644 --- a/features/target_specific_scenarios_by_line.feature +++ b/features/target_specific_scenarios_by_line.feature @@ -37,10 +37,15 @@ Feature: Target specific scenarios Then it fails And it runs the scenario "second scenario - X" - Scenario: run multiple scenarios - When I run cucumber-js with `features/a.feature:2:10` + Scenario Outline: run multiple scenarios + When I run cucumber-js with `` Then it fails And it runs the scenarios: | NAME | | first scenario | | second scenario - X | + + Examples: + | args | + | features/a.feature:2:10 | + | features/a.feature:2 features/a.feature:10 | diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..5f6846601 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,12621 @@ +{ + "name": "@cucumber/cucumber", + "version": "8.0.0-rc.2", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "@cucumber/cucumber", + "version": "8.0.0-rc.2", + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.7.0", + "@cucumber/ci-environment": "8.0.1", + "@cucumber/cucumber-expressions": "14.0.0", + "@cucumber/gherkin": "22.0.0", + "@cucumber/gherkin-streams": "4.0.0", + "@cucumber/html-formatter": "17.0.0", + "@cucumber/messages": "17.1.1", + "@cucumber/tag-expressions": "4.1.0", + "assertion-error-formatter": "^3.0.0", + "capital-case": "^1.0.4", + "chalk": "^4.1.2", + "cli-table3": "0.6.1", + "commander": "^8.0.0", + "duration": "^0.2.2", + "durations": "^3.4.2", + "figures": "^3.2.0", + "glob": "^7.1.6", + "indent-string": "^4.0.0", + "is-stream": "^2.0.0", + "knuth-shuffle-seeded": "^1.0.6", + "mz": "^2.7.0", + "progress": "^2.0.3", + "resolve": "^1.19.0", + "resolve-pkg": "^2.0.0", + "stack-chain": "^2.0.0", + "string-argv": "^0.3.1", + "tmp": "^0.2.1", + "util-arity": "^1.1.0", + "verror": "^1.10.0" + }, + "bin": { + "cucumber-js": "bin/cucumber-js" + }, + "devDependencies": { + "@cucumber/compatibility-kit": "9.1.2", + "@cucumber/message-streams": "3.0.0", + "@cucumber/query": "11.0.0", + "@sinonjs/fake-timers": "8.1.0", + "@types/chai": "4.3.0", + "@types/dirty-chai": "2.0.2", + "@types/express": "4.17.13", + "@types/fs-extra": "9.0.13", + "@types/glob": "7.2.0", + "@types/mocha": "9.0.0", + "@types/mustache": "4.1.2", + "@types/mz": "2.7.4", + "@types/node": "16.11.17", + "@types/progress": "2.0.5", + "@types/resolve": "1.20.1", + "@types/semver": "7.3.9", + "@types/sinon-chai": "3.2.8", + "@types/sinonjs__fake-timers": "8.1.1", + "@types/stream-buffers": "3.0.4", + "@types/tmp": "0.2.3", + "@types/verror": "1.10.5", + "@typescript-eslint/eslint-plugin": "5.6.0", + "@typescript-eslint/parser": "5.6.0", + "chai": "4.3.4", + "chai-exclude": "2.1.0", + "coffeescript": "2.6.1", + "dependency-lint": "7.1.0", + "dirty-chai": "2.0.1", + "eslint": "8.4.1", + "eslint-config-prettier": "8.3.0", + "eslint-plugin-import": "2.25.3", + "eslint-plugin-node": "11.1.0", + "eslint-plugin-prettier": "4.0.0", + "eslint-plugin-standard": "4.1.0", + "express": "4.17.2", + "fs-extra": "10.0.0", + "genversion": "3.0.2", + "mocha": "^9.2.0", + "mustache": "4.2.0", + "nyc": "15.1.0", + "prettier": "2.5.1", + "reindent-template-literals": "1.1.0", + "semver": "7.3.5", + "shx": "0.3.3", + "sinon": "12.0.1", + "sinon-chai": "3.7.0", + "stream-buffers": "3.0.2", + "stream-to-string": "1.2.0", + "strip-ansi": "^6.0.1", + "ts-node": "10.4.0", + "tsd": "0.19.1", + "typescript": "4.5.4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.16.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", + "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.7.tgz", + "integrity": "sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.7", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.7.tgz", + "integrity": "sha512-/ST3Sg8MLGY5HVYmrjOgL60ENux/HfO/CsUh7y4MalThufhE/Ff/6EibFDHi4jiDCaWfJKoqbE6oTh21c5hrRg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz", + "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz", + "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.7.tgz", + "integrity": "sha512-sR4eaSrnM7BV7QPzGfEX5paG/6wrZM3I0HDzfIAK06ESvo9oy3xBuVBxE3MbQaKNhvg8g/ixjMWo2CGpzpHsDA==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.7.tgz", + "integrity": "sha512-8KWJPIb8c2VvY8AJrydh6+fVRo2ODx1wYBU2398xJVq0JomuLBZmVQzLPBblJgHIGYG4znCpUZUZ0Pt2vdmVYQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.7.tgz", + "integrity": "sha512-E8HuV7FO9qLpx6OtoGfUQ2cjIYnbFwvZWYBS+87EwtdMvmUPJSwykpovFB+8insbpF0uJcpr8KMUi64XZntZcg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cucumber/ci-environment": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@cucumber/ci-environment/-/ci-environment-8.0.1.tgz", + "integrity": "sha512-oQ6nifJ5MRyHFyCsBQU+D0CERSPbxezOxlVpJXcSrcOdKbdqGojZcu17Ww13dyHUGN8c417pWUifIlOrxrsZTQ==" + }, + "node_modules/@cucumber/compatibility-kit": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@cucumber/compatibility-kit/-/compatibility-kit-9.1.2.tgz", + "integrity": "sha512-oB01JROFcwFfbqMV+jtJtj8bWU6mrLPUomuki/f9TvXsHMjYgqkBopeJqjcWWtgIfA7Y2CZEnTMWdLxoyBd4RA==", + "dev": true + }, + "node_modules/@cucumber/cucumber-expressions": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/cucumber-expressions/-/cucumber-expressions-14.0.0.tgz", + "integrity": "sha512-QiuFBrj4dZRc1Igvp2/nOjUNFyDtO7uHTrzgY9DbwzebYAYOvM6CKGOSxSuPUzxowuc1nuRkzJfFUI1kHaZgPQ==", + "dependencies": { + "regexp-match-indices": "1.0.2" + } + }, + "node_modules/@cucumber/gherkin": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-22.0.0.tgz", + "integrity": "sha512-D5OghXE8kkZm7pcwo8TvQMgrrXGMXEjERdKLU0T7dQIbc6k0BmMX8dTRh2cwAjH8c7vhwdd0qLU8FPQgGGj+bg==", + "dependencies": { + "@cucumber/message-streams": "^3.0.0", + "@cucumber/messages": "^17.1.1" + } + }, + "node_modules/@cucumber/gherkin-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin-streams/-/gherkin-streams-4.0.0.tgz", + "integrity": "sha512-b/guGNeuxr3ghoJOK47QpLhwa2BOdRq+cs2hBYulMLPTiVfwvRBiZlq7P6xdjR9dIpUKBSpzYR6NwaLMgV5DTg==", + "dependencies": { + "@cucumber/gherkin": "^21.0.0", + "@cucumber/message-streams": "^3.0.0", + "@cucumber/messages": "^17.1.0", + "commander": "8.1.0", + "source-map-support": "0.5.19" + }, + "bin": { + "gherkin-javascript": "bin/gherkin" + } + }, + "node_modules/@cucumber/gherkin-streams/node_modules/@cucumber/gherkin": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-21.0.0.tgz", + "integrity": "sha512-S6YFmTg56iEn563ReePL6Sygb77vwYrGHEr7NwuLIgg20Hi1pp7P80BAYVYNRgU7nK9vG2II9O6kaZbiOXF/5g==", + "dependencies": { + "@cucumber/message-streams": "^3.0.0", + "@cucumber/messages": "^17.1.0" + } + }, + "node_modules/@cucumber/gherkin-streams/node_modules/commander": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.1.0.tgz", + "integrity": "sha512-mf45ldcuHSYShkplHHGKWb4TrmwQadxOn7v4WuhDJy0ZVoY5JFajaRDKD0PNe5qXzBX0rhovjTnP6Kz9LETcuA==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cucumber/html-formatter": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/html-formatter/-/html-formatter-17.0.0.tgz", + "integrity": "sha512-yegA8LY1HYUONyMtTvAYj+aG4zc/6WRtKQxqJahjcdmjgXWcL1BTe8y0lw4BFVqFjaZNI9onOM5KDnMHDm3J/w==", + "dependencies": { + "@cucumber/messages": "^17.1.0", + "commander": "8.1.0", + "source-map-support": "0.5.19" + }, + "bin": { + "cucumber-html-formatter": "bin/cucumber-html-formatter.js" + } + }, + "node_modules/@cucumber/html-formatter/node_modules/commander": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.1.0.tgz", + "integrity": "sha512-mf45ldcuHSYShkplHHGKWb4TrmwQadxOn7v4WuhDJy0ZVoY5JFajaRDKD0PNe5qXzBX0rhovjTnP6Kz9LETcuA==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cucumber/message-streams": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/message-streams/-/message-streams-3.0.0.tgz", + "integrity": "sha512-ABx91nKUebV8mLmpf7BsB3bmQ57CDAfj2EIZswThz+nJHYPAFlZ1JewI6ykFsR9RzJ7/QhgQs0KHeQh7nH/u1Q==", + "dependencies": { + "@cucumber/messages": "^17.0.0" + } + }, + "node_modules/@cucumber/messages": { + "version": "17.1.1", + "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-17.1.1.tgz", + "integrity": "sha512-KQMn2Ag+1g1CXp/zKQ7LLqmuHjuQwuXw0N2u5SrDk8r72zPt36SxmDSJK7w6HiFTI+3p5ZuzwLi4S5jop3Tx4g==", + "dependencies": { + "@types/uuid": "8.3.1", + "class-transformer": "0.4.0", + "reflect-metadata": "0.1.13", + "uuid": "8.3.2" + } + }, + "node_modules/@cucumber/query": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/query/-/query-11.0.0.tgz", + "integrity": "sha512-GkjZX7p8h4OiajDrBXs/4E7qKhnW5gsqVXvJRI1Vv7bREpXc1W0Gc9S4UDgtx/YQ6djs0yBrjIbSHJRtEHYnIA==", + "dev": true, + "dependencies": { + "@cucumber/messages": "^17.0.0", + "@teppeis/multimaps": "2.0.0" + } + }, + "node_modules/@cucumber/tag-expressions": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@cucumber/tag-expressions/-/tag-expressions-4.1.0.tgz", + "integrity": "sha512-chTnjxV3vryL75N90wJIMdMafXmZoO2JgNJLYpsfcALL2/IQrRiny3vM9DgD5RDCSt1LNloMtb7rGey9YWxCsA==" + }, + "node_modules/@eslint/eslintrc": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", + "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.2.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz", + "integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.0.2.tgz", + "integrity": "sha512-jxPRPp9n93ci7b8hMfJOFDPRLFYadN6FSpeROFTR4UNF4i5b+EK6m4QXPO46BDhFgRy1JuS87zAnFOzCUwMJcQ==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "node_modules/@teppeis/multimaps": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@teppeis/multimaps/-/multimaps-2.0.0.tgz", + "integrity": "sha512-TL1adzq1HdxUf9WYduLcQ/DNGYiz71U31QRgbnr0Ef1cPyOUOsBojxHVWpFeOSUucB6Lrs0LxFRA14ntgtkc9w==", + "dev": true, + "engines": { + "node": ">=10.17" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "node_modules/@tsd/typescript": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-4.5.4.tgz", + "integrity": "sha512-iDlLkdg3sCjUSNdoUCsYM/SXheHrdxHsR6msIkbFDW4pV6gHTMwg/8te/paLtywDjGL4S4ByDdUKA3RbfdBX0g==", + "dev": true, + "bin": { + "tsc": "typescript/bin/tsc", + "tsserver": "typescript/bin/tsserver" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/chai": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz", + "integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==", + "dev": true + }, + "node_modules/@types/chai-as-promised": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.4.tgz", + "integrity": "sha512-1y3L1cHePcIm5vXkh1DSGf/zQq5n5xDKG1fpCvf18+uOkpce0Z1ozNFPkyWsVswK7ntN1sZBw3oU6gmN+pDUcA==", + "dev": true, + "dependencies": { + "@types/chai": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/dirty-chai": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/dirty-chai/-/dirty-chai-2.0.2.tgz", + "integrity": "sha512-BruwIN/UQEU0ePghxEX+OyjngpOfOUKJQh3cmfeq2h2Su/g001iljVi3+Y2y2EFp3IPgjf4sMrRU33Hxv1FUqw==", + "dev": true, + "dependencies": { + "@types/chai": "*", + "@types/chai-as-promised": "*" + } + }, + "node_modules/@types/eslint": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", + "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", + "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.27", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.27.tgz", + "integrity": "sha512-e/sVallzUTPdyOTiqi8O8pMdBBphscvI6E4JYaKlja4Lm+zh7UFSSdW5VMkRbhDtmrONqOUHOXRguPsDckzxNA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "node_modules/@types/mocha": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz", + "integrity": "sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==", + "dev": true + }, + "node_modules/@types/mustache": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-4.1.2.tgz", + "integrity": "sha512-c4OVMMcyodKQ9dpwBwh3ofK9P6U9ZktKU9S+p33UqwMNN1vlv2P0zJZUScTshnx7OEoIIRcCFNQ904sYxZz8kg==", + "dev": true + }, + "node_modules/@types/mz": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/@types/mz/-/mz-2.7.4.tgz", + "integrity": "sha512-Zs0imXxyWT20j3Z2NwKpr0IO2LmLactBblNyLua5Az4UHuqOQ02V3jPTgyKwDkuc33/ahw+C3O1PIZdrhFMuQA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "16.11.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.17.tgz", + "integrity": "sha512-C1vTZME8cFo8uxY2ui41xcynEotVkczIVI5AjLmy5pkpBv/FtG+jhtOlfcPysI8VRVwoOMv6NJm44LGnoMSWkw==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "node_modules/@types/progress": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/progress/-/progress-2.0.5.tgz", + "integrity": "sha512-ZYYVc/kSMkhH9W/4dNK/sLNra3cnkfT2nJyOAIDY+C2u6w72wa0s1aXAezVtbTsnN8HID1uhXCrLwDE2ZXpplg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.1.tgz", + "integrity": "sha512-Ku5+GPFa12S3W26Uwtw+xyrtIpaZsGYHH6zxNbZlstmlvMYSZRzOwzwsXbxlVUbHyUucctSyuFtu6bNxwYomIw==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz", + "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==", + "dev": true + }, + "node_modules/@types/serve-static": { + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/sinon": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.6.tgz", + "integrity": "sha512-6EF+wzMWvBNeGrfP3Nx60hhx+FfwSg1JJBLAAP/IdIUq0EYkqCYf70VT3PhuhPX9eLD+Dp+lNdpb/ZeHG8Yezg==", + "dev": true, + "dependencies": { + "@sinonjs/fake-timers": "^7.1.0" + } + }, + "node_modules/@types/sinon-chai": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.8.tgz", + "integrity": "sha512-d4ImIQbT/rKMG8+AXpmcan5T2/PNeSjrYhvkwet6z0p8kzYtfgA32xzOBlbU0yqJfq+/0Ml805iFoODO0LP5/g==", + "dev": true, + "dependencies": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "node_modules/@types/sinon/node_modules/@sinonjs/fake-timers": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", + "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", + "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", + "dev": true + }, + "node_modules/@types/stream-buffers": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/stream-buffers/-/stream-buffers-3.0.4.tgz", + "integrity": "sha512-qU/K1tb2yUdhXkLIATzsIPwbtX6BpZk0l3dPW6xqWyhfzzM1ECaQ/8faEnu3CNraLiQ9LHyQQPBGp7N9Fbs25w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-dDZH/tXzwjutnuk4UacGgFRwV+JSLaXL1ikvidfJprkb7L9Nx1njcRHHmi3Dsvt7pgqqTEeucQuOrWHPFgzVHA==", + "dev": true + }, + "node_modules/@types/uuid": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.1.tgz", + "integrity": "sha512-Y2mHTRAbqfFkpjldbkHGY8JIzRN6XqYRliG8/24FcHm2D2PwW24fl5xMRTVGdrb7iMrwCaIEbLWerGIkXuFWVg==" + }, + "node_modules/@types/verror": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.5.tgz", + "integrity": "sha512-9UjMCHK5GPgQRoNbqdLIAvAy0EInuiqbW0PBMtVP6B5B2HQJlvoJHM+KodPZMEjOa5VkSc+5LH7xy+cUzQdmHw==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.6.0.tgz", + "integrity": "sha512-MIbeMy5qfLqtgs1hWd088k1hOuRsN9JrHUPwVVKCD99EOUqScd7SrwoZl4Gso05EAP9w1kvLWUVGJOVpRPkDPA==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "5.6.0", + "@typescript-eslint/scope-manager": "5.6.0", + "debug": "^4.3.2", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/experimental-utils": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.6.0.tgz", + "integrity": "sha512-VDoRf3Qj7+W3sS/ZBXZh3LBzp0snDLEgvp6qj0vOAIiAPM07bd5ojQ3CTzF/QFl5AKh7Bh1ycgj6lFBJHUt/DA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.6.0", + "@typescript-eslint/types": "5.6.0", + "@typescript-eslint/typescript-estree": "5.6.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.6.0.tgz", + "integrity": "sha512-YVK49NgdUPQ8SpCZaOpiq1kLkYRPMv9U5gcMrywzI8brtwZjr/tG3sZpuHyODt76W/A0SufNjYt9ZOgrC4tLIQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.6.0", + "@typescript-eslint/types": "5.6.0", + "@typescript-eslint/typescript-estree": "5.6.0", + "debug": "^4.3.2" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.6.0.tgz", + "integrity": "sha512-1U1G77Hw2jsGWVsO2w6eVCbOg0HZ5WxL/cozVSTfqnL/eB9muhb8THsP0G3w+BB5xAHv9KptwdfYFAUfzcIh4A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.6.0", + "@typescript-eslint/visitor-keys": "5.6.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.6.0.tgz", + "integrity": "sha512-OIZffked7mXv4mXzWU5MgAEbCf9ecNJBKi+Si6/I9PpTaj+cf2x58h2oHW5/P/yTnPkKaayfjhLvx+crnl5ubA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.6.0.tgz", + "integrity": "sha512-92vK5tQaE81rK7fOmuWMrSQtK1IMonESR+RJR2Tlc7w4o0MeEdjgidY/uO2Gobh7z4Q1hhS94Cr7r021fMVEeA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.6.0", + "@typescript-eslint/visitor-keys": "5.6.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.6.0.tgz", + "integrity": "sha512-1p7hDp5cpRFUyE3+lvA74egs+RWSgumrBpzBCDzfTFv0aQ7lIeay80yU0hIxgAhwQ6PcasW35kaOCyDOv6O/Ng==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.6.0", + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "dev": true, + "dependencies": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/assertion-error-formatter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/assertion-error-formatter/-/assertion-error-formatter-3.0.0.tgz", + "integrity": "sha512-6YyAVLrEze0kQ7CmJfUgrLHb+Y7XghmL2Ie7ijVa2Y9ynP3LV+VDiwFk62Dn0qtqbmY0BT0ss6p1xxpiF2PYbQ==", + "dependencies": { + "diff": "^4.0.1", + "pad-right": "^0.2.2", + "repeat-string": "^1.6.1" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", + "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", + "dev": true, + "dependencies": { + "bytes": "3.1.1", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.6", + "raw-body": "2.4.2", + "type-is": "~1.6.18" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", + "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "dev": true, + "dependencies": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "node_modules/camel-case/node_modules/lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", + "dev": true + }, + "node_modules/camel-case/node_modules/no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "dependencies": { + "lower-case": "^1.1.1" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001296", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001296.tgz", + "integrity": "sha512-WfrtPEoNSoeATDlf4y3QvkwiELl9GyPLISV5GejTbbQRtQx4LhsXmc9IQ6XCL2d7UxCyEzToEZNMeqR79OUw8Q==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "node_modules/chai": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai-exclude": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chai-exclude/-/chai-exclude-2.1.0.tgz", + "integrity": "sha512-IBnm50Mvl3O1YhPpTgbU8MK0Gw7NHcb18WT2TxGdPKOMtdtZVKLHmQwdvOF7mTlHVQStbXuZKFwkevFtbHjpVg==", + "dev": true, + "dependencies": { + "fclone": "^1.0.11" + }, + "peerDependencies": { + "chai": ">= 4.0.0 < 5" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/class-transformer": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz", + "integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA==" + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-table3": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz", + "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "colors": "1.4.0" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/coffeescript": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.6.1.tgz", + "integrity": "sha512-GG5nkF93qII8HmHqnnibkgpp/SV7PSnSPiWsbinwya7nNOe95aE/x2xrKZJFks8Qpko3TNrC+/LahaKgrz5YCg==", + "dev": true, + "bin": { + "cake": "bin/cake", + "coffee": "bin/coffee" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "devOptional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/convert-source-map/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "dev": true, + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/dependency-lint": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/dependency-lint/-/dependency-lint-7.1.0.tgz", + "integrity": "sha512-N04kRN80zaiBxzOLVyvGANeaGQQuAI6Pkgse22BGjvtUFEMcD9j4ob4S8DcayMp8+BVXso9Z80pB88xQJKjcDw==", + "dev": true, + "dependencies": { + "bluebird": "^3.4.3", + "builtin-modules": "^3.0.0", + "camel-case": "^3.0.0", + "colors": "^1.0.3", + "detective": "^5.1.0", + "detective-es6": "^2.0.0", + "docopt": "^0.6.0", + "fs-extra": "^8.1.0", + "glob": "^7.0.0", + "js-yaml": "^3.3.1", + "lodash": "^4.2.1", + "minimatch": "^3.0.2", + "semver": "^6.0.0", + "sorted-object": "^2.0.0" + }, + "bin": { + "dependency-lint": "bin/dependency-lint" + } + }, + "node_modules/dependency-lint/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/dependency-lint/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/dependency-lint/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/dependency-lint/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "node_modules/detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "dev": true, + "dependencies": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + }, + "bin": { + "detective": "bin/detective.js" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/detective-es6": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/detective-es6/-/detective-es6-2.2.1.tgz", + "integrity": "sha512-22z7MblxkhsIQGuALeGwCKEfqNy4WmgDGmfJCwdXbfDkVYIiIDmY513hiIWBvX3kCmzvvWE7RR7kAYxs01wwKQ==", + "dev": true, + "dependencies": { + "node-source-walk": "^4.0.0" + }, + "engines": { + "node": ">= 6.0" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dirty-chai": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/dirty-chai/-/dirty-chai-2.0.1.tgz", + "integrity": "sha512-ys79pWKvDMowIDEPC6Fig8d5THiC0DJ2gmTeGzVAoEH18J8OzLud0Jh7I9IWg3NSk8x2UocznUuFmfHCXYZx9w==", + "dev": true, + "peerDependencies": { + "chai": ">=2.2.1 <5" + } + }, + "node_modules/docopt": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/docopt/-/docopt-0.6.2.tgz", + "integrity": "sha1-so6eIiDaXsSffqW7JKR3h0Be6xE=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/duration": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/duration/-/duration-0.2.2.tgz", + "integrity": "sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg==", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.46" + } + }, + "node_modules/durations": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/durations/-/durations-3.4.2.tgz", + "integrity": "sha512-V/lf7y33dGaypZZetVI1eu7BmvkbC4dItq12OElLRpKuaU5JxQstV2zHwLv8P7cNbQ+KL1WD80zMCTx5dNC4dg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.35", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.35.tgz", + "integrity": "sha512-wzTOMh6HGFWeALMI3bif0mzgRrVGyP1BdFRx7IvWukFrSC5QVQELENuy+Fm2dCrAdQH9T3nuqr07n94nPDFBWA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.4.1.tgz", + "integrity": "sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.0.5", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.1.0", + "espree": "^9.2.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.2.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", + "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-formatter-pretty": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-formatter-pretty/-/eslint-formatter-pretty-4.1.0.tgz", + "integrity": "sha512-IsUTtGxF1hrH6lMWiSl1WbGaiP01eT6kzywdY1U+zLc0MP+nwEnUiS9UI8IaOTUhTeQJLlCEWIbXINBH4YJbBQ==", + "dev": true, + "dependencies": { + "@types/eslint": "^7.2.13", + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "eslint-rule-docs": "^1.1.5", + "log-symbols": "^4.0.0", + "plur": "^4.0.0", + "string-width": "^4.2.0", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz", + "integrity": "sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.25.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz", + "integrity": "sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.1", + "has": "^1.0.3", + "is-core-module": "^2.8.0", + "is-glob": "^4.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.5", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.11.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", + "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "eslint": ">=7.28.0", + "prettier": ">=2.0.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-standard": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz", + "integrity": "sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peerDependencies": { + "eslint": ">=5.0.0" + } + }, + "node_modules/eslint-rule-docs": { + "version": "1.1.231", + "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.231.tgz", + "integrity": "sha512-egHz9A1WG7b8CS0x1P6P/Rj5FqZOjray/VjpJa14tMZalfRKvpE2ONJ3plCM7+PcinmU4tcmbPLv0VtwzSdLVA==", + "dev": true + }, + "node_modules/eslint-scope": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", + "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", + "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/eslint/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/espree": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", + "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", + "dev": true, + "dependencies": { + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.1.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/espree/node_modules/acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz", + "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==", + "dev": true, + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.4.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.9.6", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.17.2", + "serve-static": "1.14.2", + "setprototypeof": "1.2.0", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/ext": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", + "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", + "dependencies": { + "type": "^2.5.0" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", + "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==" + }, + "node_modules/extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fclone": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", + "integrity": "sha1-EOhdo4v+p/xZk0HClu4ddyZu5kA=", + "dev": true + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-package": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-package/-/find-package-1.0.0.tgz", + "integrity": "sha1-13ONpn48XwVcJNPhmqGu7QY8PoM=", + "dev": true, + "dependencies": { + "parents": "^1.0.1" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", + "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", + "dev": true + }, + "node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/fs-extra": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", + "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/genversion": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/genversion/-/genversion-3.0.2.tgz", + "integrity": "sha512-hto4m/V3DQOJbIH2nVNPhkScqwAzpYnmTLDOs+2AYxqGWVKsUW6Qxcz2FXRQlbAXgWpJxbxgnWqb1/s17lK2yg==", + "dev": true, + "dependencies": { + "commander": "^7.2.0", + "find-package": "^1.0.0" + }, + "bin": { + "genversion": "bin/genversion.js" + } + }, + "node_modules/genversion/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hosted-git-info": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", + "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/irregular-plurals": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.3.0.tgz", + "integrity": "sha512-MVBLKUTangM3EfRPFROhmWQQKRDsrgI83J8GS3jXy+OwYqiR2/aoWndYQ5416jLE3uaGgLH7ncme3X9y09gZ3g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "dev": true, + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", + "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/knuth-shuffle-seeded": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/knuth-shuffle-seeded/-/knuth-shuffle-seeded-1.0.6.tgz", + "integrity": "sha1-AfG2VzOqdUDuCNiwF0Fk0iCB5OE=", + "dependencies": { + "seed-random": "~2.2.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dev": true, + "dependencies": { + "mime-db": "1.51.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/mocha": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.0.tgz", + "integrity": "sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.2.0", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/mocha/node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "dev": true, + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", + "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "node_modules/nise": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.0.tgz", + "integrity": "sha512-W5WlHu+wvo3PaKLsJJkgPup2LrsXCcm7AWwyNZkUnn5rwPkuPBi3Iwk5SQtN0mv+K65k7nKKjwNQ30wg3wLAQQ==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^7.0.4", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "node_modules/nise/node_modules/@sinonjs/fake-timers": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", + "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/nise/node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", + "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "dev": true + }, + "node_modules/node-source-walk": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-4.2.0.tgz", + "integrity": "sha512-hPs/QMe6zS94f5+jG3kk9E7TNm4P2SulrKiLWMzKszBfNZvL/V6wseHlTd7IvfW0NZWqPtK3+9yYNr+3USGteA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/nyc/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pad-right": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/pad-right/-/pad-right-0.2.2.tgz", + "integrity": "sha1-b7ySQEXSRPKiokRQMGDTv8YAl3Q=", + "dependencies": { + "repeat-string": "^1.5.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "dependencies": { + "path-platform": "~0.11.15" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/plur": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", + "integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==", + "dev": true, + "dependencies": { + "irregular-plurals": "^3.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-polyfill": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-1.1.6.tgz", + "integrity": "sha1-zQTv9G9clcOn0EVZHXm14+AfEtc=", + "dev": true + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", + "dev": true, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", + "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", + "dev": true, + "dependencies": { + "bytes": "3.1.1", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + }, + "node_modules/regexp-match-indices": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regexp-match-indices/-/regexp-match-indices-1.0.2.tgz", + "integrity": "sha512-DwZuAkt8NF5mKwGGER1EGh2PRqyvhRhhLviH+R8y8dIuaQROlUfXjt4s9ZTXstIsSkptf06BSvwcEmmfheJJWQ==", + "dependencies": { + "regexp-tree": "^0.1.11" + } + }, + "node_modules/regexp-tree": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/reindent-template-literals": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reindent-template-literals/-/reindent-template-literals-1.1.0.tgz", + "integrity": "sha512-Zbf5y+QqimAwwPef+FrXdC+MCbpg0mo9YjSHhRMglfLJrqPXes5jXTnVZP8YCwLhVVne2ZMxu14/x+m8xkZr4w==", + "dev": true + }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz", + "integrity": "sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==", + "dependencies": { + "is-core-module": "^2.8.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-2.0.0.tgz", + "integrity": "sha512-+1lzwXehGCXSeryaISr6WujZzowloigEofRB+dj75y9RRa/obVcYgbHJd53tdYw8pvZj8GojXaaENws8Ktw/hQ==", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-pkg/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/seed-random": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/seed-random/-/seed-random-2.2.0.tgz", + "integrity": "sha1-KpsZ4lCoFwmSMaW5mk2vgLf77VQ=" + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "1.8.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-static": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shx": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.3.tgz", + "integrity": "sha512-nZJ3HFWVoTSyyB+evEKjJ1STiixGztlqwKLTUNV5KqMWtGey9fTd4KU1gdZ1X9BV6215pswQ/Jew9NsuS/fNDA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.3", + "shelljs": "^0.8.4" + }, + "bin": { + "shx": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "dev": true + }, + "node_modules/sinon": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-12.0.1.tgz", + "integrity": "sha512-iGu29Xhym33ydkAT+aNQFBINakjq69kKO6ByPvTsm3yyIACfyQttRTP03aBP/I8GfhFmLzrnKwNNkr0ORb1udg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.8.3", + "@sinonjs/fake-timers": "^8.1.0", + "@sinonjs/samsam": "^6.0.2", + "diff": "^5.0.0", + "nise": "^5.1.0", + "supports-color": "^7.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon-chai": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", + "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", + "dev": true, + "peerDependencies": { + "chai": "^4.0.0", + "sinon": ">=4.0.0" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sorted-object": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/sorted-object/-/sorted-object-2.0.1.tgz", + "integrity": "sha1-fWMfS9OnmKJK8d/8+/6DM3pd9fw=", + "dev": true + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/stack-chain": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-2.0.0.tgz", + "integrity": "sha512-GGrHXePi305aW7XQweYZZwiRwR7Js3MWoK/EHzzB9ROdc75nCnjSJVi21rdAGxFl+yCx2L2qdfl5y7NO4lTyqg==" + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-buffers": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz", + "integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/stream-to-string": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/stream-to-string/-/stream-to-string-1.2.0.tgz", + "integrity": "sha512-8drZlFIKBHSMdX9GCWv8V9AAWnQcTqw0iAI6/GC7UJ0H0SwKeFKjOoZfGY1tOU00GGU7FYZQoJ/ZCUEoXhD7yQ==", + "dev": true, + "dependencies": { + "promise-polyfill": "^1.1.6" + } + }, + "node_modules/string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-node": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ts-node/node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", + "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tsd": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/tsd/-/tsd-0.19.1.tgz", + "integrity": "sha512-pSwchclr+ADdxlahRUQXUrdAIOjXx1T1PQV+fLfVLuo/S4z+T00YU84fH8iPlZxyA2pWgJjo42BG1p9SDb4NOw==", + "dev": true, + "dependencies": { + "@tsd/typescript": "~4.5.2", + "eslint-formatter-pretty": "^4.1.0", + "globby": "^11.0.1", + "meow": "^9.0.0", + "path-exists": "^4.0.0", + "read-pkg-up": "^7.0.0" + }, + "bin": { + "tsd": "dist/cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/tsd/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", + "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", + "dev": true + }, + "node_modules/upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-arity": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/util-arity/-/util-arity-1.1.0.tgz", + "integrity": "sha1-WdAa8f2z/t4KxOYysKtfbOl8kzA=" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", + "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "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" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.7" + } + }, + "@babel/compat-data": { + "version": "7.16.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz", + "integrity": "sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==", + "dev": true + }, + "@babel/core": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.7.tgz", + "integrity": "sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.7", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.7.tgz", + "integrity": "sha512-/ST3Sg8MLGY5HVYmrjOgL60ENux/HfO/CsUh7y4MalThufhE/Ff/6EibFDHi4jiDCaWfJKoqbE6oTh21c5hrRg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-transforms": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-simple-access": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true + }, + "@babel/helpers": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz", + "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==", + "dev": true, + "requires": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/highlight": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz", + "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.7.tgz", + "integrity": "sha512-sR4eaSrnM7BV7QPzGfEX5paG/6wrZM3I0HDzfIAK06ESvo9oy3xBuVBxE3MbQaKNhvg8g/ixjMWo2CGpzpHsDA==", + "dev": true + }, + "@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/traverse": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.7.tgz", + "integrity": "sha512-8KWJPIb8c2VvY8AJrydh6+fVRo2ODx1wYBU2398xJVq0JomuLBZmVQzLPBblJgHIGYG4znCpUZUZ0Pt2vdmVYQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.7", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.7.tgz", + "integrity": "sha512-E8HuV7FO9qLpx6OtoGfUQ2cjIYnbFwvZWYBS+87EwtdMvmUPJSwykpovFB+8insbpF0uJcpr8KMUi64XZntZcg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + }, + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==" + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@cucumber/ci-environment": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@cucumber/ci-environment/-/ci-environment-8.0.1.tgz", + "integrity": "sha512-oQ6nifJ5MRyHFyCsBQU+D0CERSPbxezOxlVpJXcSrcOdKbdqGojZcu17Ww13dyHUGN8c417pWUifIlOrxrsZTQ==" + }, + "@cucumber/compatibility-kit": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@cucumber/compatibility-kit/-/compatibility-kit-9.1.2.tgz", + "integrity": "sha512-oB01JROFcwFfbqMV+jtJtj8bWU6mrLPUomuki/f9TvXsHMjYgqkBopeJqjcWWtgIfA7Y2CZEnTMWdLxoyBd4RA==", + "dev": true + }, + "@cucumber/cucumber-expressions": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/cucumber-expressions/-/cucumber-expressions-14.0.0.tgz", + "integrity": "sha512-QiuFBrj4dZRc1Igvp2/nOjUNFyDtO7uHTrzgY9DbwzebYAYOvM6CKGOSxSuPUzxowuc1nuRkzJfFUI1kHaZgPQ==", + "requires": { + "regexp-match-indices": "1.0.2" + } + }, + "@cucumber/gherkin": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-22.0.0.tgz", + "integrity": "sha512-D5OghXE8kkZm7pcwo8TvQMgrrXGMXEjERdKLU0T7dQIbc6k0BmMX8dTRh2cwAjH8c7vhwdd0qLU8FPQgGGj+bg==", + "requires": { + "@cucumber/message-streams": "^3.0.0", + "@cucumber/messages": "^17.1.1" + } + }, + "@cucumber/gherkin-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin-streams/-/gherkin-streams-4.0.0.tgz", + "integrity": "sha512-b/guGNeuxr3ghoJOK47QpLhwa2BOdRq+cs2hBYulMLPTiVfwvRBiZlq7P6xdjR9dIpUKBSpzYR6NwaLMgV5DTg==", + "requires": { + "@cucumber/gherkin": "^21.0.0", + "@cucumber/message-streams": "^3.0.0", + "@cucumber/messages": "^17.1.0", + "commander": "8.1.0", + "source-map-support": "0.5.19" + }, + "dependencies": { + "@cucumber/gherkin": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-21.0.0.tgz", + "integrity": "sha512-S6YFmTg56iEn563ReePL6Sygb77vwYrGHEr7NwuLIgg20Hi1pp7P80BAYVYNRgU7nK9vG2II9O6kaZbiOXF/5g==", + "requires": { + "@cucumber/message-streams": "^3.0.0", + "@cucumber/messages": "^17.1.0" + } + }, + "commander": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.1.0.tgz", + "integrity": "sha512-mf45ldcuHSYShkplHHGKWb4TrmwQadxOn7v4WuhDJy0ZVoY5JFajaRDKD0PNe5qXzBX0rhovjTnP6Kz9LETcuA==" + } + } + }, + "@cucumber/html-formatter": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/html-formatter/-/html-formatter-17.0.0.tgz", + "integrity": "sha512-yegA8LY1HYUONyMtTvAYj+aG4zc/6WRtKQxqJahjcdmjgXWcL1BTe8y0lw4BFVqFjaZNI9onOM5KDnMHDm3J/w==", + "requires": { + "@cucumber/messages": "^17.1.0", + "commander": "8.1.0", + "source-map-support": "0.5.19" + }, + "dependencies": { + "commander": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.1.0.tgz", + "integrity": "sha512-mf45ldcuHSYShkplHHGKWb4TrmwQadxOn7v4WuhDJy0ZVoY5JFajaRDKD0PNe5qXzBX0rhovjTnP6Kz9LETcuA==" + } + } + }, + "@cucumber/message-streams": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/message-streams/-/message-streams-3.0.0.tgz", + "integrity": "sha512-ABx91nKUebV8mLmpf7BsB3bmQ57CDAfj2EIZswThz+nJHYPAFlZ1JewI6ykFsR9RzJ7/QhgQs0KHeQh7nH/u1Q==", + "requires": { + "@cucumber/messages": "^17.0.0" + } + }, + "@cucumber/messages": { + "version": "17.1.1", + "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-17.1.1.tgz", + "integrity": "sha512-KQMn2Ag+1g1CXp/zKQ7LLqmuHjuQwuXw0N2u5SrDk8r72zPt36SxmDSJK7w6HiFTI+3p5ZuzwLi4S5jop3Tx4g==", + "requires": { + "@types/uuid": "8.3.1", + "class-transformer": "0.4.0", + "reflect-metadata": "0.1.13", + "uuid": "8.3.2" + } + }, + "@cucumber/query": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/query/-/query-11.0.0.tgz", + "integrity": "sha512-GkjZX7p8h4OiajDrBXs/4E7qKhnW5gsqVXvJRI1Vv7bREpXc1W0Gc9S4UDgtx/YQ6djs0yBrjIbSHJRtEHYnIA==", + "dev": true, + "requires": { + "@cucumber/messages": "^17.0.0", + "@teppeis/multimaps": "2.0.0" + } + }, + "@cucumber/tag-expressions": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@cucumber/tag-expressions/-/tag-expressions-4.1.0.tgz", + "integrity": "sha512-chTnjxV3vryL75N90wJIMdMafXmZoO2JgNJLYpsfcALL2/IQrRiny3vM9DgD5RDCSt1LNloMtb7rGey9YWxCsA==" + }, + "@eslint/eslintrc": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", + "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.2.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz", + "integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@sinonjs/samsam": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.0.2.tgz", + "integrity": "sha512-jxPRPp9n93ci7b8hMfJOFDPRLFYadN6FSpeROFTR4UNF4i5b+EK6m4QXPO46BDhFgRy1JuS87zAnFOzCUwMJcQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "@teppeis/multimaps": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@teppeis/multimaps/-/multimaps-2.0.0.tgz", + "integrity": "sha512-TL1adzq1HdxUf9WYduLcQ/DNGYiz71U31QRgbnr0Ef1cPyOUOsBojxHVWpFeOSUucB6Lrs0LxFRA14ntgtkc9w==", + "dev": true + }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "@tsd/typescript": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-4.5.4.tgz", + "integrity": "sha512-iDlLkdg3sCjUSNdoUCsYM/SXheHrdxHsR6msIkbFDW4pV6gHTMwg/8te/paLtywDjGL4S4ByDdUKA3RbfdBX0g==", + "dev": true + }, + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/chai": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.0.tgz", + "integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==", + "dev": true + }, + "@types/chai-as-promised": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.4.tgz", + "integrity": "sha512-1y3L1cHePcIm5vXkh1DSGf/zQq5n5xDKG1fpCvf18+uOkpce0Z1ozNFPkyWsVswK7ntN1sZBw3oU6gmN+pDUcA==", + "dev": true, + "requires": { + "@types/chai": "*" + } + }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/dirty-chai": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/dirty-chai/-/dirty-chai-2.0.2.tgz", + "integrity": "sha512-BruwIN/UQEU0ePghxEX+OyjngpOfOUKJQh3cmfeq2h2Su/g001iljVi3+Y2y2EFp3IPgjf4sMrRU33Hxv1FUqw==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/chai-as-promised": "*" + } + }, + "@types/eslint": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", + "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/estree": { + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", + "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", + "dev": true + }, + "@types/express": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.27", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.27.tgz", + "integrity": "sha512-e/sVallzUTPdyOTiqi8O8pMdBBphscvI6E4JYaKlja4Lm+zh7UFSSdW5VMkRbhDtmrONqOUHOXRguPsDckzxNA==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "@types/mocha": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz", + "integrity": "sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==", + "dev": true + }, + "@types/mustache": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-4.1.2.tgz", + "integrity": "sha512-c4OVMMcyodKQ9dpwBwh3ofK9P6U9ZktKU9S+p33UqwMNN1vlv2P0zJZUScTshnx7OEoIIRcCFNQ904sYxZz8kg==", + "dev": true + }, + "@types/mz": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/@types/mz/-/mz-2.7.4.tgz", + "integrity": "sha512-Zs0imXxyWT20j3Z2NwKpr0IO2LmLactBblNyLua5Az4UHuqOQ02V3jPTgyKwDkuc33/ahw+C3O1PIZdrhFMuQA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "16.11.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.17.tgz", + "integrity": "sha512-C1vTZME8cFo8uxY2ui41xcynEotVkczIVI5AjLmy5pkpBv/FtG+jhtOlfcPysI8VRVwoOMv6NJm44LGnoMSWkw==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "@types/progress": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/progress/-/progress-2.0.5.tgz", + "integrity": "sha512-ZYYVc/kSMkhH9W/4dNK/sLNra3cnkfT2nJyOAIDY+C2u6w72wa0s1aXAezVtbTsnN8HID1uhXCrLwDE2ZXpplg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "@types/resolve": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.1.tgz", + "integrity": "sha512-Ku5+GPFa12S3W26Uwtw+xyrtIpaZsGYHH6zxNbZlstmlvMYSZRzOwzwsXbxlVUbHyUucctSyuFtu6bNxwYomIw==", + "dev": true + }, + "@types/semver": { + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz", + "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==", + "dev": true + }, + "@types/serve-static": { + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/sinon": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.6.tgz", + "integrity": "sha512-6EF+wzMWvBNeGrfP3Nx60hhx+FfwSg1JJBLAAP/IdIUq0EYkqCYf70VT3PhuhPX9eLD+Dp+lNdpb/ZeHG8Yezg==", + "dev": true, + "requires": { + "@sinonjs/fake-timers": "^7.1.0" + }, + "dependencies": { + "@sinonjs/fake-timers": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", + "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + } + } + }, + "@types/sinon-chai": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.8.tgz", + "integrity": "sha512-d4ImIQbT/rKMG8+AXpmcan5T2/PNeSjrYhvkwet6z0p8kzYtfgA32xzOBlbU0yqJfq+/0Ml805iFoODO0LP5/g==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "@types/sinonjs__fake-timers": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", + "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", + "dev": true + }, + "@types/stream-buffers": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/stream-buffers/-/stream-buffers-3.0.4.tgz", + "integrity": "sha512-qU/K1tb2yUdhXkLIATzsIPwbtX6BpZk0l3dPW6xqWyhfzzM1ECaQ/8faEnu3CNraLiQ9LHyQQPBGp7N9Fbs25w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-dDZH/tXzwjutnuk4UacGgFRwV+JSLaXL1ikvidfJprkb7L9Nx1njcRHHmi3Dsvt7pgqqTEeucQuOrWHPFgzVHA==", + "dev": true + }, + "@types/uuid": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.1.tgz", + "integrity": "sha512-Y2mHTRAbqfFkpjldbkHGY8JIzRN6XqYRliG8/24FcHm2D2PwW24fl5xMRTVGdrb7iMrwCaIEbLWerGIkXuFWVg==" + }, + "@types/verror": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.5.tgz", + "integrity": "sha512-9UjMCHK5GPgQRoNbqdLIAvAy0EInuiqbW0PBMtVP6B5B2HQJlvoJHM+KodPZMEjOa5VkSc+5LH7xy+cUzQdmHw==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.6.0.tgz", + "integrity": "sha512-MIbeMy5qfLqtgs1hWd088k1hOuRsN9JrHUPwVVKCD99EOUqScd7SrwoZl4Gso05EAP9w1kvLWUVGJOVpRPkDPA==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "5.6.0", + "@typescript-eslint/scope-manager": "5.6.0", + "debug": "^4.3.2", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.6.0.tgz", + "integrity": "sha512-VDoRf3Qj7+W3sS/ZBXZh3LBzp0snDLEgvp6qj0vOAIiAPM07bd5ojQ3CTzF/QFl5AKh7Bh1ycgj6lFBJHUt/DA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.6.0", + "@typescript-eslint/types": "5.6.0", + "@typescript-eslint/typescript-estree": "5.6.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + } + } + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + } + } + }, + "@typescript-eslint/parser": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.6.0.tgz", + "integrity": "sha512-YVK49NgdUPQ8SpCZaOpiq1kLkYRPMv9U5gcMrywzI8brtwZjr/tG3sZpuHyODt76W/A0SufNjYt9ZOgrC4tLIQ==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.6.0", + "@typescript-eslint/types": "5.6.0", + "@typescript-eslint/typescript-estree": "5.6.0", + "debug": "^4.3.2" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.6.0.tgz", + "integrity": "sha512-1U1G77Hw2jsGWVsO2w6eVCbOg0HZ5WxL/cozVSTfqnL/eB9muhb8THsP0G3w+BB5xAHv9KptwdfYFAUfzcIh4A==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.6.0", + "@typescript-eslint/visitor-keys": "5.6.0" + } + }, + "@typescript-eslint/types": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.6.0.tgz", + "integrity": "sha512-OIZffked7mXv4mXzWU5MgAEbCf9ecNJBKi+Si6/I9PpTaj+cf2x58h2oHW5/P/yTnPkKaayfjhLvx+crnl5ubA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.6.0.tgz", + "integrity": "sha512-92vK5tQaE81rK7fOmuWMrSQtK1IMonESR+RJR2Tlc7w4o0MeEdjgidY/uO2Gobh7z4Q1hhS94Cr7r021fMVEeA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.6.0", + "@typescript-eslint/visitor-keys": "5.6.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.6.0.tgz", + "integrity": "sha512-1p7hDp5cpRFUyE3+lvA74egs+RWSgumrBpzBCDzfTFv0aQ7lIeay80yU0hIxgAhwQ6PcasW35kaOCyDOv6O/Ng==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.6.0", + "eslint-visitor-keys": "^3.0.0" + } + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "dev": true, + "requires": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + } + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "requires": { + "default-require-extensions": "^3.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "array-includes": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array.prototype.flat": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0" + } + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "assertion-error-formatter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/assertion-error-formatter/-/assertion-error-formatter-3.0.0.tgz", + "integrity": "sha512-6YyAVLrEze0kQ7CmJfUgrLHb+Y7XghmL2Ie7ijVa2Y9ynP3LV+VDiwFk62Dn0qtqbmY0BT0ss6p1xxpiF2PYbQ==", + "requires": { + "diff": "^4.0.1", + "pad-right": "^0.2.2", + "repeat-string": "^1.6.1" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "body-parser": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", + "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", + "dev": true, + "requires": { + "bytes": "3.1.1", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.6", + "raw-body": "2.4.2", + "type-is": "~1.6.18" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserslist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true + }, + "bytes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", + "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", + "dev": true + }, + "caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "requires": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "dev": true, + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + }, + "dependencies": { + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", + "dev": true + }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "requires": { + "lower-case": "^1.1.1" + } + } + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } + }, + "caniuse-lite": { + "version": "1.0.30001296", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001296.tgz", + "integrity": "sha512-WfrtPEoNSoeATDlf4y3QvkwiELl9GyPLISV5GejTbbQRtQx4LhsXmc9IQ6XCL2d7UxCyEzToEZNMeqR79OUw8Q==", + "dev": true + }, + "capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "chai": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, + "chai-exclude": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chai-exclude/-/chai-exclude-2.1.0.tgz", + "integrity": "sha512-IBnm50Mvl3O1YhPpTgbU8MK0Gw7NHcb18WT2TxGdPKOMtdtZVKLHmQwdvOF7mTlHVQStbXuZKFwkevFtbHjpVg==", + "dev": true, + "requires": { + "fclone": "^1.0.11" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "class-transformer": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.4.0.tgz", + "integrity": "sha512-ETWD/H2TbWbKEi7m9N4Km5+cw1hNcqJSxlSYhsLsNjQzWWiZIYA1zafxpK9PwVfaZ6AqR5rrjPVUBGESm5tQUA==" + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-table3": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz", + "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==", + "requires": { + "colors": "1.4.0", + "string-width": "^4.2.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "coffeescript": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.6.1.tgz", + "integrity": "sha512-GG5nkF93qII8HmHqnnibkgpp/SV7PSnSPiWsbinwya7nNOe95aE/x2xrKZJFks8Qpko3TNrC+/LahaKgrz5YCg==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "devOptional": true + }, + "commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "requires": { + "safe-buffer": "5.2.1" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + } + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "dev": true, + "requires": { + "strip-bom": "^4.0.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "dependency-lint": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/dependency-lint/-/dependency-lint-7.1.0.tgz", + "integrity": "sha512-N04kRN80zaiBxzOLVyvGANeaGQQuAI6Pkgse22BGjvtUFEMcD9j4ob4S8DcayMp8+BVXso9Z80pB88xQJKjcDw==", + "dev": true, + "requires": { + "bluebird": "^3.4.3", + "builtin-modules": "^3.0.0", + "camel-case": "^3.0.0", + "colors": "^1.0.3", + "detective": "^5.1.0", + "detective-es6": "^2.0.0", + "docopt": "^0.6.0", + "fs-extra": "^8.1.0", + "glob": "^7.0.0", + "js-yaml": "^3.3.1", + "lodash": "^4.2.1", + "minimatch": "^3.0.2", + "semver": "^6.0.0", + "sorted-object": "^2.0.0" + }, + "dependencies": { + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + } + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "dev": true, + "requires": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + } + }, + "detective-es6": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/detective-es6/-/detective-es6-2.2.1.tgz", + "integrity": "sha512-22z7MblxkhsIQGuALeGwCKEfqNy4WmgDGmfJCwdXbfDkVYIiIDmY513hiIWBvX3kCmzvvWE7RR7kAYxs01wwKQ==", + "dev": true, + "requires": { + "node-source-walk": "^4.0.0" + } + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "dirty-chai": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/dirty-chai/-/dirty-chai-2.0.1.tgz", + "integrity": "sha512-ys79pWKvDMowIDEPC6Fig8d5THiC0DJ2gmTeGzVAoEH18J8OzLud0Jh7I9IWg3NSk8x2UocznUuFmfHCXYZx9w==", + "dev": true, + "requires": {} + }, + "docopt": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/docopt/-/docopt-0.6.2.tgz", + "integrity": "sha1-so6eIiDaXsSffqW7JKR3h0Be6xE=", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "duration": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/duration/-/duration-0.2.2.tgz", + "integrity": "sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg==", + "requires": { + "d": "1", + "es5-ext": "~0.10.46" + } + }, + "durations": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/durations/-/durations-3.4.2.tgz", + "integrity": "sha512-V/lf7y33dGaypZZetVI1eu7BmvkbC4dItq12OElLRpKuaU5JxQstV2zHwLv8P7cNbQ+KL1WD80zMCTx5dNC4dg==" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "electron-to-chromium": { + "version": "1.4.35", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.35.tgz", + "integrity": "sha512-wzTOMh6HGFWeALMI3bif0mzgRrVGyP1BdFRx7IvWukFrSC5QVQELENuy+Fm2dCrAdQH9T3nuqr07n94nPDFBWA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.4.1.tgz", + "integrity": "sha512-TxU/p7LB1KxQ6+7aztTnO7K0i+h0tDi81YRY9VzB6Id71kNz+fFYnf5HD5UOQmxkzcoa0TlVZf9dpMtUv0GpWg==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.0.5", + "@humanwhocodes/config-array": "^0.9.2", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.0", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.1.0", + "espree": "^9.2.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.2.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } + } + }, + "eslint-config-prettier": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", + "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "dev": true, + "requires": {} + }, + "eslint-formatter-pretty": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-formatter-pretty/-/eslint-formatter-pretty-4.1.0.tgz", + "integrity": "sha512-IsUTtGxF1hrH6lMWiSl1WbGaiP01eT6kzywdY1U+zLc0MP+nwEnUiS9UI8IaOTUhTeQJLlCEWIbXINBH4YJbBQ==", + "dev": true, + "requires": { + "@types/eslint": "^7.2.13", + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "eslint-rule-docs": "^1.1.5", + "log-symbols": "^4.0.0", + "plur": "^4.0.0", + "string-width": "^4.2.0", + "supports-hyperlinks": "^2.0.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-module-utils": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz", + "integrity": "sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "find-up": "^2.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.25.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz", + "integrity": "sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg==", + "dev": true, + "requires": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.1", + "has": "^1.0.3", + "is-core-module": "^2.8.0", + "is-glob": "^4.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.5", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.11.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-plugin-prettier": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz", + "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-plugin-standard": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz", + "integrity": "sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ==", + "dev": true, + "requires": {} + }, + "eslint-rule-docs": { + "version": "1.1.231", + "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.231.tgz", + "integrity": "sha512-egHz9A1WG7b8CS0x1P6P/Rj5FqZOjray/VjpJa14tMZalfRKvpE2ONJ3plCM7+PcinmU4tcmbPLv0VtwzSdLVA==", + "dev": true + }, + "eslint-scope": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", + "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", + "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "dev": true + }, + "espree": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", + "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", + "dev": true, + "requires": { + "acorn": "^8.7.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^3.1.0" + }, + "dependencies": { + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "express": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz", + "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==", + "dev": true, + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.4.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.9.6", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.17.2", + "serve-static": "1.14.2", + "setprototypeof": "1.2.0", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "ext": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", + "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", + "requires": { + "type": "^2.5.0" + }, + "dependencies": { + "type": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", + "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==" + } + } + }, + "extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "fclone": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", + "integrity": "sha1-EOhdo4v+p/xZk0HClu4ddyZu5kA=", + "dev": true + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "requires": { + "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + } + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-package": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-package/-/find-package-1.0.0.tgz", + "integrity": "sha1-13ONpn48XwVcJNPhmqGu7QY8PoM=", + "dev": true, + "requires": { + "parents": "^1.0.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", + "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", + "dev": true + }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true + }, + "fs-extra": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", + "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "genversion": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/genversion/-/genversion-3.0.2.tgz", + "integrity": "sha512-hto4m/V3DQOJbIH2nVNPhkScqwAzpYnmTLDOs+2AYxqGWVKsUW6Qxcz2FXRQlbAXgWpJxbxgnWqb1/s17lK2yg==", + "dev": true, + "requires": { + "commander": "^7.2.0", + "find-package": "^1.0.0" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + } + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", + "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "requires": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hosted-git-info": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", + "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + }, + "irregular-plurals": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.3.0.tgz", + "integrity": "sha512-MVBLKUTangM3EfRPFROhmWQQKRDsrgI83J8GS3jXy+OwYqiR2/aoWndYQ5416jLE3uaGgLH7ncme3X9y09gZ3g==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, + "is-core-module": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "requires": { + "append-transform": "^2.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz", + "integrity": "sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "knuth-shuffle-seeded": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/knuth-shuffle-seeded/-/knuth-shuffle-seeded-1.0.6.tgz", + "integrity": "sha1-AfG2VzOqdUDuCNiwF0Fk0iCB5OE=", + "requires": { + "seed-random": "~2.2.0" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "requires": { + "tslib": "^2.0.3" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "dependencies": { + "type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true + } + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", + "dev": true + }, + "mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "dev": true, + "requires": { + "mime-db": "1.51.0" + } + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + } + }, + "mocha": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.0.tgz", + "integrity": "sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.2.0", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "dev": true + }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "nanoid": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", + "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "nise": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.0.tgz", + "integrity": "sha512-W5WlHu+wvo3PaKLsJJkgPup2LrsXCcm7AWwyNZkUnn5rwPkuPBi3Iwk5SQtN0mv+K65k7nKKjwNQ30wg3wLAQQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^7.0.4", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + }, + "dependencies": { + "@sinonjs/fake-timers": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", + "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + } + } + }, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "requires": { + "process-on-spawn": "^1.0.0" + } + }, + "node-releases": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", + "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "dev": true + }, + "node-source-walk": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-4.2.0.tgz", + "integrity": "sha512-hPs/QMe6zS94f5+jG3kk9E7TNm4P2SulrKiLWMzKszBfNZvL/V6wseHlTd7IvfW0NZWqPtK3+9yYNr+3USGteA==", + "dev": true, + "requires": { + "@babel/parser": "^7.0.0" + } + }, + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "requires": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "dependencies": { + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "pad-right": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/pad-right/-/pad-right-0.2.2.tgz", + "integrity": "sha1-b7ySQEXSRPKiokRQMGDTv8YAl3Q=", + "requires": { + "repeat-string": "^1.5.2" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "~0.11.15" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } + } + }, + "plur": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", + "integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==", + "dev": true, + "requires": { + "irregular-plurals": "^3.2.0" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "requires": { + "fromentries": "^1.2.0" + } + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "promise-polyfill": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-1.1.6.tgz", + "integrity": "sha1-zQTv9G9clcOn0EVZHXm14+AfEtc=", + "dev": true + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", + "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", + "dev": true, + "requires": { + "bytes": "3.1.1", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + }, + "regexp-match-indices": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regexp-match-indices/-/regexp-match-indices-1.0.2.tgz", + "integrity": "sha512-DwZuAkt8NF5mKwGGER1EGh2PRqyvhRhhLviH+R8y8dIuaQROlUfXjt4s9ZTXstIsSkptf06BSvwcEmmfheJJWQ==", + "requires": { + "regexp-tree": "^0.1.11" + } + }, + "regexp-tree": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==" + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "reindent-template-literals": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reindent-template-literals/-/reindent-template-literals-1.1.0.tgz", + "integrity": "sha512-Zbf5y+QqimAwwPef+FrXdC+MCbpg0mo9YjSHhRMglfLJrqPXes5jXTnVZP8YCwLhVVne2ZMxu14/x+m8xkZr4w==", + "dev": true + }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.21.0.tgz", + "integrity": "sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==", + "requires": { + "is-core-module": "^2.8.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "resolve-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-2.0.0.tgz", + "integrity": "sha512-+1lzwXehGCXSeryaISr6WujZzowloigEofRB+dj75y9RRa/obVcYgbHJd53tdYw8pvZj8GojXaaENws8Ktw/hQ==", + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + } + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "seed-random": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/seed-random/-/seed-random-2.2.0.tgz", + "integrity": "sha1-KpsZ4lCoFwmSMaW5mk2vgLf77VQ=" + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "send": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "1.8.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-static": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.2" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "shx": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.3.tgz", + "integrity": "sha512-nZJ3HFWVoTSyyB+evEKjJ1STiixGztlqwKLTUNV5KqMWtGey9fTd4KU1gdZ1X9BV6215pswQ/Jew9NsuS/fNDA==", + "dev": true, + "requires": { + "minimist": "^1.2.3", + "shelljs": "^0.8.4" + } + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "dev": true + }, + "sinon": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-12.0.1.tgz", + "integrity": "sha512-iGu29Xhym33ydkAT+aNQFBINakjq69kKO6ByPvTsm3yyIACfyQttRTP03aBP/I8GfhFmLzrnKwNNkr0ORb1udg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.8.3", + "@sinonjs/fake-timers": "^8.1.0", + "@sinonjs/samsam": "^6.0.2", + "diff": "^5.0.0", + "nise": "^5.1.0", + "supports-color": "^7.2.0" + }, + "dependencies": { + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + } + } + }, + "sinon-chai": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", + "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", + "dev": true, + "requires": {} + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "sorted-object": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/sorted-object/-/sorted-object-2.0.1.tgz", + "integrity": "sha1-fWMfS9OnmKJK8d/8+/6DM3pd9fw=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "requires": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "stack-chain": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-2.0.0.tgz", + "integrity": "sha512-GGrHXePi305aW7XQweYZZwiRwR7Js3MWoK/EHzzB9ROdc75nCnjSJVi21rdAGxFl+yCx2L2qdfl5y7NO4lTyqg==" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stream-buffers": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz", + "integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==", + "dev": true + }, + "stream-to-string": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/stream-to-string/-/stream-to-string-1.2.0.tgz", + "integrity": "sha512-8drZlFIKBHSMdX9GCWv8V9AAWnQcTqw0iAI6/GC7UJ0H0SwKeFKjOoZfGY1tOU00GGU7FYZQoJ/ZCUEoXhD7yQ==", + "dev": true, + "requires": { + "promise-polyfill": "^1.1.6" + } + }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==" + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "requires": { + "any-promise": "^1.0.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "requires": { + "thenify": ">= 3.1.0 < 4" + } + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "requires": { + "rimraf": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true + }, + "trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true + }, + "ts-node": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + }, + "dependencies": { + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + } + } + }, + "tsconfig-paths": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", + "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "tsd": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/tsd/-/tsd-0.19.1.tgz", + "integrity": "sha512-pSwchclr+ADdxlahRUQXUrdAIOjXx1T1PQV+fLfVLuo/S4z+T00YU84fH8iPlZxyA2pWgJjo42BG1p9SDb4NOw==", + "dev": true, + "requires": { + "@tsd/typescript": "~4.5.2", + "eslint-formatter-pretty": "^4.1.0", + "globby": "^11.0.1", + "meow": "^9.0.0", + "path-exists": "^4.0.0", + "read-pkg-up": "^7.0.0" + }, + "dependencies": { + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } + } + }, + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz", + "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", + "dev": true + }, + "upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "requires": { + "tslib": "^2.0.3" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-arity": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/util-arity/-/util-arity-1.1.0.tgz", + "integrity": "sha1-WdAa8f2z/t4KxOYysKtfbOl8kzA=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "verror": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", + "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "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": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + } + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/package.json b/package.json index 54cd7263d..bccb55430 100644 --- a/package.json +++ b/package.json @@ -8,11 +8,12 @@ "gherkin", "tests" ], - "version": "7.2.1", + "version": "8.0.0-rc.2", "homepage": "https://github.com/cucumber/cucumber-js", "author": "Julien Biezemans ", "contributors": [ "Aaron Garvey", + "abelalmeida ", "Adam Ark ", "Ádám Gólya ", "ahulab ", @@ -23,6 +24,7 @@ "Artur Neumann ", "Artur Pomadowski ", "Aslak Hellesøy ", + "Aurélien Reeves ", "basemmerink ", "Ben Van Treese ", "Benjamín Eidelman ", @@ -65,6 +67,7 @@ "Jayson Smith ", "Jesse Harlin ", "João Guilherme Farias Duda ", + "Joaquín Sorianello ", "Joey Jan ", "John Krull ", "John McLaughlin ", @@ -92,9 +95,11 @@ "Leonardo ", "lopesc ", "Lucas Cimon ", + "Ludek", "Lukas Degener ", "Łukasz Gandecki ", "M.P. Korstanje ", + "mannyluvstacos ", "Marat Dyatko ", "Marc Burton ", "Marcel Hoyer ", @@ -138,6 +143,7 @@ "temyers ", "Tim Perry ", "Tom V ", + "Tomer Ben-Rachel ", "Tristan Dunn ", "unknown ", "Valerio Innocenti Sedili ", @@ -163,117 +169,122 @@ "lib": "./lib" }, "main": "./lib/index.js", + "exports": { + ".": { + "import": "./lib/wrapper.mjs", + "require": "./lib/index.js" + }, + "./lib/*": { + "require": "./lib/*.js" + }, + "./package.json": "./package.json" + }, "types": "./lib/index.d.ts", "engines": { - "node": ">=10" + "node": ">=12" }, "dependencies": { - "@cucumber/create-meta": "4.0.0", - "@cucumber/cucumber-expressions": "12.0.1", - "@cucumber/gherkin": "18.0.0", - "@cucumber/gherkin-streams": "1.0.0", - "@cucumber/html-formatter": "13.0.0", - "@cucumber/messages": "15.0.0", - "@cucumber/query": "9.0.2", - "@cucumber/tag-expressions": "3.0.1", - "assertion-error-formatter": "3.0.0", - "bluebird": "^3.7.2", + "@cspotcode/source-map-support": "^0.7.0", + "@cucumber/ci-environment": "8.0.1", + "@cucumber/cucumber-expressions": "14.0.0", + "@cucumber/gherkin": "22.0.0", + "@cucumber/gherkin-streams": "4.0.0", + "@cucumber/html-formatter": "17.0.0", + "@cucumber/messages": "17.1.1", + "@cucumber/tag-expressions": "4.1.0", + "assertion-error-formatter": "^3.0.0", "capital-case": "^1.0.4", - "cli-table3": "^0.6.0", - "colors": "^1.4.0", - "commander": "^7.0.0", - "create-require": "^1.1.1", + "chalk": "^4.1.2", + "cli-table3": "0.6.1", + "commander": "^8.0.0", "duration": "^0.2.2", "durations": "^3.4.2", "figures": "^3.2.0", "glob": "^7.1.6", "indent-string": "^4.0.0", - "is-generator": "^1.0.3", "is-stream": "^2.0.0", "knuth-shuffle-seeded": "^1.0.6", - "lodash": "^4.17.21", "mz": "^2.7.0", "progress": "^2.0.3", "resolve": "^1.19.0", "resolve-pkg": "^2.0.0", "stack-chain": "^2.0.0", - "stacktrace-js": "^2.0.2", "string-argv": "^0.3.1", "tmp": "^0.2.1", "util-arity": "^1.1.0", "verror": "^1.10.0" }, "devDependencies": { - "@cucumber/compatibility-kit": "4.0.1", - "@sinonjs/fake-timers": "7.0.5", - "@types/bluebird": "3.5.33", - "@types/chai": "4.2.17", + "@cucumber/compatibility-kit": "9.1.2", + "@cucumber/message-streams": "3.0.0", + "@cucumber/query": "11.0.0", + "@sinonjs/fake-timers": "8.1.0", + "@types/chai": "4.3.0", "@types/dirty-chai": "2.0.2", - "@types/express": "4.17.11", - "@types/fs-extra": "9.0.11", - "@types/glob": "7.1.3", - "@types/lodash": "4.14.168", - "@types/mocha": "8.2.2", - "@types/mustache": "4.1.1", - "@types/mz": "2.7.3", - "@types/node": "14.14.43", - "@types/progress": "2.0.3", - "@types/resolve": "1.20.0", - "@types/semver": "7.3.5", - "@types/sinon-chai": "3.2.5", - "@types/sinonjs__fake-timers": "6.0.2", - "@types/stream-buffers": "3.0.3", - "@types/tmp": "0.2.0", - "@types/verror": "1.10.4", - "@typescript-eslint/eslint-plugin": "4.22.0", - "@typescript-eslint/parser": "4.22.0", + "@types/express": "4.17.13", + "@types/fs-extra": "9.0.13", + "@types/glob": "7.2.0", + "@types/mocha": "9.0.0", + "@types/mustache": "4.1.2", + "@types/mz": "2.7.4", + "@types/node": "16.11.17", + "@types/progress": "2.0.5", + "@types/resolve": "1.20.1", + "@types/semver": "7.3.9", + "@types/sinon-chai": "3.2.8", + "@types/sinonjs__fake-timers": "8.1.1", + "@types/stream-buffers": "3.0.4", + "@types/tmp": "0.2.3", + "@types/verror": "1.10.5", + "@typescript-eslint/eslint-plugin": "5.6.0", + "@typescript-eslint/parser": "5.6.0", "chai": "4.3.4", - "chai-exclude": "2.0.3", - "coffeescript": "2.5.1", - "dependency-lint": "6.0.0", + "chai-exclude": "2.1.0", + "coffeescript": "2.6.1", + "dependency-lint": "7.1.0", "dirty-chai": "2.0.1", - "eslint": "7.25.0", + "eslint": "8.4.1", "eslint-config-prettier": "8.3.0", - "eslint-config-standard-with-typescript": "20.0.0", - "eslint-plugin-import": "2.22.1", + "eslint-plugin-import": "2.25.3", "eslint-plugin-node": "11.1.0", - "eslint-plugin-prettier": "3.4.0", - "eslint-plugin-promise": "5.1.0", + "eslint-plugin-prettier": "4.0.0", "eslint-plugin-standard": "4.1.0", - "express": "4.17.1", - "fs-extra": "9.1.0", - "mocha": "8.3.2", + "express": "4.17.2", + "fs-extra": "10.0.0", + "genversion": "3.0.2", + "mocha": "^9.2.0", "mustache": "4.2.0", - "ndjson-parse": "1.0.4", "nyc": "15.1.0", - "prettier": "2.2.1", + "prettier": "2.5.1", + "reindent-template-literals": "1.1.0", "semver": "7.3.5", - "sinon": "10.0.0", - "sinon-chai": "3.6.0", + "shx": "0.3.3", + "sinon": "12.0.1", + "sinon-chai": "3.7.0", "stream-buffers": "3.0.2", "stream-to-string": "1.2.0", - "ts-node": "9.1.1", - "tsd": "0.14.0", - "typescript": "4.2.4" + "strip-ansi": "^6.0.1", + "ts-node": "10.4.0", + "tsd": "0.19.1", + "typescript": "4.5.4" }, "scripts": { - "build-local": "tsc -p tsconfig.node.json", + "build-local": "genversion --es6 src/version.ts && tsc --build tsconfig.node.json && shx cp src/importer.js lib/ && shx cp src/wrapper.mjs lib/", "cck-test": "mocha 'compatibility/**/*_spec.ts'", "feature-test": "node ./bin/cucumber-js", - "html-formatter": "node ./bin/cucumber-js --profile htmlFormatter", "lint-autofix": "eslint --fix \"{compatibility,example,features,scripts,src,test}/**/*.ts\"", "lint-code": "eslint \"{compatibility,example,features,scripts,src,test}/**/*.ts\"", "lint-dependencies": "dependency-lint", - "lint": "yarn run lint-code && yarn run lint-dependencies", - "prelint-autofix": "yarn build-local", - "prelint-code": "yarn build-local", - "precck-test": "yarn run build-local", - "prefeature-test": "yarn run build-local", + "lint": "npm run lint-code && npm run lint-dependencies", + "prelint-autofix": "npm run build-local", + "prelint-code": "npm run build-local", + "precck-test": "npm run build-local", + "prefeature-test": "npm run build-local", "prepublishOnly": "rm -rf lib && npm run build-local", - "pretest-coverage": "yarn build-local", - "pretypes-test": "yarn build-local", + "pretest-coverage": "npm run build-local", + "pretypes-test": "npm run build-local", "test-coverage": "nyc --silent mocha 'src/**/*_spec.ts' 'compatibility/**/*_spec.ts' && nyc --silent --no-clean node ./bin/cucumber-js && nyc report --reporter=lcov", - "test": "yarn run lint && yarn run types-test && yarn run unit-test && yarn run cck-test && yarn run feature-test", + "test": "npm run lint && npm run types-test && npm run unit-test && npm run cck-test && npm run feature-test", "types-test": "tsd", "unit-test": "mocha 'src/**/*_spec.ts'", "update-dependencies": "npx npm-check-updates --upgrade" diff --git a/renovate.json b/renovate.json index af8466653..68d1efec6 100644 --- a/renovate.json +++ b/renovate.json @@ -1,6 +1,7 @@ { "extends": [ - "config:base" + "config:base", + ":disableDependencyDashboard" ], "packageRules": [ { diff --git a/reports/.gitkeep b/reports/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/src/cli/argv_parser.ts b/src/cli/argv_parser.ts index 1a80381fc..f908dbf41 100644 --- a/src/cli/argv_parser.ts +++ b/src/cli/argv_parser.ts @@ -1,11 +1,11 @@ -import _ from 'lodash' import { Command } from 'commander' import path from 'path' import { dialects } from '@cucumber/gherkin' import { SnippetInterface } from '../formatter/step_definition_snippet_builder/snippet_syntax' - -// Using require instead of import so compiled typescript will have the desired folder structure -const { version } = require('../../package.json') // eslint-disable-line @typescript-eslint/no-var-requires +import { getKeywords, getLanguages } from './i18n' +import Formatters from '../formatter/helpers/formatters' +import { version } from '../version' +import { PickleOrder } from './helpers' export interface IParsedArgvFormatRerunOptions { separator?: string @@ -21,6 +21,7 @@ export interface IParsedArgvFormatOptions { export interface IParsedArgvOptions { backtrace: boolean + config: string dryRun: boolean exit: boolean failFast: boolean @@ -30,9 +31,8 @@ export interface IParsedArgvOptions { i18nLanguages: boolean language: string name: string[] - order: string + order: PickleOrder parallel: number - predictableIds: boolean profile: string[] publish: boolean publishQuiet: boolean @@ -65,10 +65,10 @@ const ArgvParser = { const e: Error = error throw new Error(`${option} passed invalid JSON: ${e.message}: ${str}`) } - if (!_.isPlainObject(val)) { + if (typeof val !== 'object' || Array.isArray(val)) { throw new Error(`${option} must be passed JSON of an object: ${str}`) } - return _.merge(memo, val) + return { ...memo, ...val } } }, @@ -85,7 +85,7 @@ const ArgvParser = { }, validateLanguage(value: string): string { - if (!_.includes(_.keys(dialects), value)) { + if (!Object.keys(dialects).includes(value)) { throw new Error(`Unsupported ISO 639-1: ${value}`) } return value @@ -107,6 +107,7 @@ const ArgvParser = { .usage('[options] [...]') .version(version, '-v, --version') .option('-b, --backtrace', 'show full backtrace for errors') + .option('-c, --config ', 'specify configuration file') .option( '-d, --dry-run', 'invoke formatters without executing steps', @@ -120,7 +121,8 @@ const ArgvParser = { .option('--fail-fast', 'abort the run on first failure', false) .option( '-f, --format ', - 'specify the output format, optionally supply PATH to redirect formatter output (repeatable)', + 'specify the output format, optionally supply PATH to redirect formatter output (repeatable). Available formats:\n' + + Formatters.buildFormattersDocumentationString(), ArgvParser.collect, [] ) @@ -166,11 +168,6 @@ const ArgvParser = { (val) => ArgvParser.validateCountOption(val, '--parallel'), 0 ) - .option( - '--predictable-ids', - 'Use predictable ids in messages (option ignored if using parallel)', - false - ) .option( '--publish', 'Publish a report to https://reports.cucumber.io', @@ -200,7 +197,7 @@ const ArgvParser = { 0 ) .option( - '--retryTagFilter, --retry-tag-filter ', + '--retry-tag-filter ', `only retries the features or scenarios with tags matching the expression (repeatable). This option requires '--retry' to be specified.`, ArgvParser.mergeTags, @@ -219,16 +216,23 @@ const ArgvParser = { {} ) - program.on('--help', () => { - /* eslint-disable no-console */ - console.log( - ' For more details please visit https://github.com/cucumber/cucumber-js/blob/master/docs/cli.md\n' - ) - /* eslint-enable no-console */ + program.on('option:i18n-languages', () => { + console.log(getLanguages()) + process.exit() + }) + + program.on('option:i18n-keywords', function (isoCode: string) { + console.log(getKeywords(isoCode)) + process.exit() }) + program.addHelpText( + 'afterAll', + 'For more details please visit https://github.com/cucumber/cucumber-js/blob/main/docs/cli.md' + ) + program.parse(argv) - const options = program.opts() as IParsedArgvOptions + const options: IParsedArgvOptions = program.opts() ArgvParser.validateRetryOptions(options) return { @@ -236,14 +240,6 @@ const ArgvParser = { args: program.args, } }, - - lint(fullArgv: string[]): void { - if (fullArgv.includes('--retryTagFilter')) { - console.warn( - 'the argument --retryTagFilter is deprecated and will be removed in a future release; please use --retry-tag-filter' - ) - } - }, } export default ArgvParser diff --git a/src/cli/configuration_builder.ts b/src/cli/configuration_builder.ts index e830b11c5..74827aaf2 100644 --- a/src/cli/configuration_builder.ts +++ b/src/cli/configuration_builder.ts @@ -1,224 +1,79 @@ -import _ from 'lodash' -import ArgvParser, { - IParsedArgvFormatOptions, - IParsedArgvOptions, -} from './argv_parser' -import fs from 'mz/fs' -import path from 'path' +import { IParsedArgv, IParsedArgvOptions } from './argv_parser' import OptionSplitter from './option_splitter' -import bluebird from 'bluebird' -import glob from 'glob' -import { promisify } from 'util' -import { IPickleFilterOptions } from '../pickle_filter' -import { IRuntimeOptions } from '../runtime' -import { valueOrDefault } from '../value_checker' - -export interface IConfigurationFormat { - outputTo: string - type: string -} - -export interface IConfiguration { - featureDefaultLanguage: string - featurePaths: string[] - formats: IConfigurationFormat[] - formatOptions: IParsedArgvFormatOptions - publishing: boolean - listI18nKeywordsFor: string - listI18nLanguages: boolean - order: string - parallel: number - pickleFilterOptions: IPickleFilterOptions - predictableIds: boolean - profiles: string[] - runtimeOptions: IRuntimeOptions - shouldExitImmediately: boolean - supportCodePaths: string[] - supportCodeRequiredModules: string[] - suppressPublishAdvertisement: boolean -} - -export interface INewConfigurationBuilderOptions { - argv: string[] - cwd: string -} - -const DEFAULT_CUCUMBER_PUBLISH_URL = 'https://messages.cucumber.io/api/reports' - -export default class ConfigurationBuilder { - static async build( - options: INewConfigurationBuilderOptions - ): Promise { - const builder = new ConfigurationBuilder(options) - return await builder.build() - } - - private readonly cwd: string - private readonly args: string[] - private readonly options: IParsedArgvOptions - - constructor({ argv, cwd }: INewConfigurationBuilderOptions) { - this.cwd = cwd - - ArgvParser.lint(argv) - const parsedArgv = ArgvParser.parse(argv) - this.args = parsedArgv.args - this.options = parsedArgv.options - } - - async build(): Promise { - const listI18nKeywordsFor = this.options.i18nKeywords - const listI18nLanguages = this.options.i18nLanguages - const unexpandedFeaturePaths = await this.getUnexpandedFeaturePaths() - let featurePaths: string[] = [] - let supportCodePaths: string[] = [] - if (listI18nKeywordsFor === '' && !listI18nLanguages) { - featurePaths = await this.expandFeaturePaths(unexpandedFeaturePaths) - let unexpandedSupportCodePaths = this.options.require - if (unexpandedSupportCodePaths.length === 0) { - unexpandedSupportCodePaths = this.getFeatureDirectoryPaths(featurePaths) - } - supportCodePaths = await this.expandPaths( - unexpandedSupportCodePaths, - '.js' - ) - } - return { - featureDefaultLanguage: this.options.language, - featurePaths, - formats: this.getFormats(), - formatOptions: this.options.formatOptions, - publishing: this.isPublishing(), - listI18nKeywordsFor, - listI18nLanguages, - order: this.options.order, - parallel: this.options.parallel, - pickleFilterOptions: { - cwd: this.cwd, - featurePaths: unexpandedFeaturePaths, - names: this.options.name, - tagExpression: this.options.tags, - }, - predictableIds: this.options.predictableIds, - profiles: this.options.profile, - runtimeOptions: { - dryRun: this.options.dryRun, - predictableIds: this.options.predictableIds, - failFast: this.options.failFast, - filterStacktraces: !this.options.backtrace, - retry: this.options.retry, - retryTagFilter: this.options.retryTagFilter, - strict: this.options.strict, - worldParameters: this.options.worldParameters, - }, - shouldExitImmediately: this.options.exit, - supportCodePaths, - supportCodeRequiredModules: this.options.requireModule, - suppressPublishAdvertisement: this.isPublishAdvertisementSuppressed(), - } - } - - async expandPaths( - unexpandedPaths: string[], - defaultExtension: string - ): Promise { - const expandedPaths = await bluebird.map( - unexpandedPaths, - async (unexpandedPath) => { - const matches = await promisify(glob)(unexpandedPath, { - absolute: true, - cwd: this.cwd, - }) - const expanded = await bluebird.map(matches, async (match) => { - if (path.extname(match) === '') { - return await promisify(glob)(`${match}/**/*${defaultExtension}`) +import { IRunConfiguration } from '../configuration' + +export async function buildConfiguration( + fromArgv: IParsedArgv, + env: NodeJS.ProcessEnv +): Promise { + const { args, options } = fromArgv + return { + sources: { + paths: args, + defaultDialect: options.language, + names: options.name, + tagExpression: options.tags, + order: options.order, + }, + support: { + transpileWith: options.requireModule, + paths: options.require, + }, + runtime: { + dryRun: options.dryRun, + failFast: options.failFast, + filterStacktraces: !options.backtrace, + parallel: options.parallel, + retry: options.retry, + retryTagFilter: options.retryTagFilter, + strict: options.strict, + worldParameters: options.worldParameters, + }, + formats: { + stdout: options.format.find((option) => !option.includes(':')), + files: options.format + .filter((option) => option.includes(':')) + .reduce((mapped, item) => { + const [type, target] = OptionSplitter.split(item) + return { + ...mapped, + [target]: type, } - return [match] - }) - return _.flatten(expanded) - } - ) - return _.flatten(expandedPaths).map((x) => path.normalize(x)) - } - - async expandFeaturePaths(featurePaths: string[]): Promise { - featurePaths = featurePaths.map((p) => p.replace(/(:\d+)*$/g, '')) // Strip line numbers - return this.expandPaths(featurePaths, '.feature') - } - - getFeatureDirectoryPaths(featurePaths: string[]): string[] { - const featureDirs = featurePaths.map((featurePath) => { - let featureDir = path.dirname(featurePath) - let childDir: string - let parentDir = featureDir - while (childDir !== parentDir) { - childDir = parentDir - parentDir = path.dirname(childDir) - if (path.basename(parentDir) === 'features') { - featureDir = parentDir - break - } - } - return path.relative(this.cwd, featureDir) - }) - return _.uniq(featureDirs) - } - - isPublishing(): boolean { - return ( - this.options.publish || - this.isTruthyString(process.env.CUCUMBER_PUBLISH_ENABLED) || - process.env.CUCUMBER_PUBLISH_TOKEN !== undefined - ) + }, {}), + publish: makePublishConfig(options, env), + options: options.formatOptions, + }, } +} - isPublishAdvertisementSuppressed(): boolean { - return ( - this.options.publishQuiet || - this.isTruthyString(process.env.CUCUMBER_PUBLISH_QUIET) - ) +export function isTruthyString(s: string | undefined): boolean { + if (s === undefined) { + return false } + return s.match(/^(false|no|0)$/i) === null +} - getFormats(): IConfigurationFormat[] { - const mapping: { [key: string]: string } = { '': 'progress' } - this.options.format.forEach((format) => { - const [type, outputTo] = OptionSplitter.split(format) - mapping[outputTo] = type - }) - if (this.isPublishing()) { - const publishUrl = valueOrDefault( - process.env.CUCUMBER_PUBLISH_URL, - DEFAULT_CUCUMBER_PUBLISH_URL - ) - - mapping[publishUrl] = 'message' - } - return _.map(mapping, (type, outputTo) => ({ outputTo, type })) - } +function isPublishing( + options: IParsedArgvOptions, + env: NodeJS.ProcessEnv +): boolean { + return ( + options.publish || + isTruthyString(env.CUCUMBER_PUBLISH_ENABLED) || + env.CUCUMBER_PUBLISH_TOKEN !== undefined + ) +} - isTruthyString(s: string | undefined): boolean { - if (s === undefined) { - return false - } - return s.match(/^(false|no|0)$/i) === null +function makePublishConfig( + options: IParsedArgvOptions, + env: NodeJS.ProcessEnv +): any { + const enabled = isPublishing(options, env) + if (!enabled) { + return false } - - async getUnexpandedFeaturePaths(): Promise { - if (this.args.length > 0) { - const nestedFeaturePaths = await bluebird.map(this.args, async (arg) => { - const filename = path.basename(arg) - if (filename[0] === '@') { - const filePath = path.join(this.cwd, arg) - const content = await fs.readFile(filePath, 'utf8') - return _.chain(content).split('\n').map(_.trim).compact().value() - } - return [arg] - }) - const featurePaths = _.flatten(nestedFeaturePaths) - if (featurePaths.length > 0) { - return featurePaths - } - } - return ['features/**/*.feature'] + return { + url: env.CUCUMBER_PUBLISH_URL, + token: env.CUCUMBER_PUBLISH_TOKEN, } } diff --git a/src/cli/configuration_builder_spec.ts b/src/cli/configuration_builder_spec.ts index 46138c50e..01e03772d 100644 --- a/src/cli/configuration_builder_spec.ts +++ b/src/cli/configuration_builder_spec.ts @@ -1,255 +1,66 @@ import { describe, it } from 'mocha' import { expect } from 'chai' -import ConfigurationBuilder from './configuration_builder' -import fsExtra from 'fs-extra' -import path from 'path' -import tmp, { DirOptions } from 'tmp' -import { promisify } from 'util' -import { SnippetInterface } from '../formatter/step_definition_snippet_builder/snippet_syntax' - -async function buildTestWorkingDirectory(): Promise { - const cwd = await promisify(tmp.dir)({ - unsafeCleanup: true, - }) - await fsExtra.mkdirp(path.join(cwd, 'features')) - return cwd -} - +import { buildConfiguration } from './configuration_builder' +import ArgvParser from './argv_parser' const baseArgv = ['/path/to/node', '/path/to/cucumber-js'] -describe('Configuration', () => { - describe('no argv', () => { - it('returns the default configuration', async function () { - // Arrange - const cwd = await buildTestWorkingDirectory() - const argv = baseArgv - - // Act - const result = await ConfigurationBuilder.build({ argv, cwd }) - - // Assert - expect(result).to.eql({ - featureDefaultLanguage: 'en', - featurePaths: [], - formatOptions: {}, - formats: [{ outputTo: '', type: 'progress' }], - publishing: false, - listI18nKeywordsFor: '', - listI18nLanguages: false, - order: 'defined', +describe('buildConfiguration', () => { + it('should derive correct defaults', async () => { + const result = await buildConfiguration(ArgvParser.parse([...baseArgv]), {}) + + expect(result).to.eql({ + formats: { + files: {}, + options: {}, + publish: false, + stdout: undefined, + }, + runtime: { + dryRun: false, + failFast: false, + filterStacktraces: true, parallel: 0, - pickleFilterOptions: { - cwd, - featurePaths: ['features/**/*.feature'], - names: [], - tagExpression: '', - }, - profiles: [], - predictableIds: false, - runtimeOptions: { - dryRun: false, - failFast: false, - filterStacktraces: true, - predictableIds: false, - retry: 0, - retryTagFilter: '', - strict: true, - worldParameters: {}, - }, - shouldExitImmediately: false, - supportCodePaths: [], - supportCodeRequiredModules: [], - suppressPublishAdvertisement: false, - }) - }) - }) - - describe('path to a feature', () => { - it('returns the appropriate feature and support code paths', async function () { - // Arrange - const cwd = await buildTestWorkingDirectory() - const relativeFeaturePath = path.join('features', 'a.feature') - const featurePath = path.join(cwd, relativeFeaturePath) - await fsExtra.outputFile(featurePath, '') - const supportCodePath = path.join(cwd, 'features', 'a.js') - await fsExtra.outputFile(supportCodePath, '') - const argv = baseArgv.concat([relativeFeaturePath]) - - // Act - const { - featurePaths, - pickleFilterOptions, - supportCodePaths, - } = await ConfigurationBuilder.build({ argv, cwd }) - - // Assert - expect(featurePaths).to.eql([featurePath]) - expect(pickleFilterOptions.featurePaths).to.eql([relativeFeaturePath]) - expect(supportCodePaths).to.eql([supportCodePath]) - }) - }) - - describe('path to a nested feature', () => { - it('returns the appropriate feature and support code paths', async function () { - // Arrange - const cwd = await buildTestWorkingDirectory() - const relativeFeaturePath = path.join('features', 'nested', 'a.feature') - const featurePath = path.join(cwd, relativeFeaturePath) - await fsExtra.outputFile(featurePath, '') - const supportCodePath = path.join(cwd, 'features', 'a.js') - await fsExtra.outputFile(supportCodePath, '') - const argv = baseArgv.concat([relativeFeaturePath]) - - // Act - const { - featurePaths, - pickleFilterOptions, - supportCodePaths, - } = await ConfigurationBuilder.build({ argv, cwd }) - - // Assert - expect(featurePaths).to.eql([featurePath]) - expect(pickleFilterOptions.featurePaths).to.eql([relativeFeaturePath]) - expect(supportCodePaths).to.eql([supportCodePath]) - }) - }) - - describe('formatters', () => { - it('adds a default', async function () { - // Arrange - const cwd = await buildTestWorkingDirectory() - const argv = baseArgv - - // Act - const { formats } = await ConfigurationBuilder.build({ argv, cwd }) - - // Assert - expect(formats).to.eql([{ outputTo: '', type: 'progress' }]) - }) - - it('adds a message formatter with reports URL when --publish specified', async function () { - // Arrange - const cwd = await buildTestWorkingDirectory() - const argv = baseArgv.concat(['--publish']) - - // Act - const { formats } = await ConfigurationBuilder.build({ argv, cwd }) - - // Assert - expect(formats).to.eql([ - { outputTo: '', type: 'progress' }, - { - outputTo: 'https://messages.cucumber.io/api/reports', - type: 'message', - }, - ]) - }) - - it('sets publishing to true when --publish is specified', async function () { - const cwd = await buildTestWorkingDirectory() - const argv = baseArgv.concat(['--publish']) - const configuration = await ConfigurationBuilder.build({ argv, cwd }) - - expect(configuration.publishing).to.eq(true) - }) - - it('sets suppressPublishAdvertisement to true when --publish-quiet is specified', async function () { - const cwd = await buildTestWorkingDirectory() - const argv = baseArgv.concat(['--publish-quiet']) - const configuration = await ConfigurationBuilder.build({ argv, cwd }) - - expect(configuration.suppressPublishAdvertisement).to.eq(true) - }) - - it('splits relative unix paths', async function () { - // Arrange - const cwd = await buildTestWorkingDirectory() - const argv = baseArgv.concat([ - '-f', - '../custom/formatter:../formatter/output.txt', - ]) - - // Act - const { formats } = await ConfigurationBuilder.build({ argv, cwd }) - - // Assert - expect(formats).to.eql([ - { outputTo: '', type: 'progress' }, - { outputTo: '../formatter/output.txt', type: '../custom/formatter' }, - ]) - }) - - it('splits absolute unix paths', async function () { - // Arrange - const cwd = await buildTestWorkingDirectory() - const argv = baseArgv.concat([ - '-f', - '/custom/formatter:/formatter/output.txt', - ]) - - // Act - const { formats } = await ConfigurationBuilder.build({ argv, cwd }) - - // Assert - expect(formats).to.eql([ - { outputTo: '', type: 'progress' }, - { outputTo: '/formatter/output.txt', type: '/custom/formatter' }, - ]) - }) - - it('splits absolute windows paths', async function () { - // Arrange - const cwd = await buildTestWorkingDirectory() - const argv = baseArgv.concat([ - '-f', - 'C:\\custom\\formatter:D:\\formatter\\output.txt', - ]) - - // Act - const { formats } = await ConfigurationBuilder.build({ argv, cwd }) - - // Assert - expect(formats).to.eql([ - { outputTo: '', type: 'progress' }, - { - outputTo: 'D:\\formatter\\output.txt', - type: 'C:\\custom\\formatter', - }, - ]) - }) - - it('does not split absolute windows paths without an output', async function () { - // Arrange - const cwd = await buildTestWorkingDirectory() - const argv = baseArgv.concat(['-f', 'C:\\custom\\formatter']) - - // Act - const { formats } = await ConfigurationBuilder.build({ argv, cwd }) - - // Assert - expect(formats).to.eql([{ outputTo: '', type: 'C:\\custom\\formatter' }]) + retry: 0, + retryTagFilter: '', + strict: true, + worldParameters: {}, + }, + sources: { + defaultDialect: 'en', + names: [], + order: 'defined', + paths: [], + tagExpression: '', + }, + support: { + paths: [], + transpileWith: [], + }, }) }) - describe('formatOptions', () => { - it('joins the objects', async function () { - // Arrange - const cwd = await buildTestWorkingDirectory() - const argv = baseArgv.concat([ - '--format-options', - '{"snippetInterface": "promise"}', - '--format-options', - '{"colorsEnabled": false}', - ]) - - // Act - const { formatOptions } = await ConfigurationBuilder.build({ argv, cwd }) - - // Assert - expect(formatOptions).to.eql({ - colorsEnabled: false, - snippetInterface: SnippetInterface.Promise, - }) + it('should map formatters', async () => { + const result = await buildConfiguration( + ArgvParser.parse([ + ...baseArgv, + '--format', + 'message', + '--format', + 'json:./report.json', + '--format', + 'html:./report.html', + ]), + {} + ) + + expect(result.formats).to.eql({ + stdout: 'message', + files: { + './report.html': 'html', + './report.json': 'json', + }, + publish: false, + options: {}, }) }) }) diff --git a/src/cli/helpers.ts b/src/cli/helpers.ts index c56414f22..d9bf265d0 100644 --- a/src/cli/helpers.ts +++ b/src/cli/helpers.ts @@ -1,23 +1,21 @@ -import _ from 'lodash' import ArgvParser from './argv_parser' import ProfileLoader from './profile_loader' import shuffle from 'knuth-shuffle-seeded' -import path from 'path' import { EventEmitter } from 'events' import PickleFilter from '../pickle_filter' import { EventDataCollector } from '../formatter/helpers' import { doesHaveValue } from '../value_checker' import OptionSplitter from './option_splitter' import { Readable } from 'stream' -import { IdGenerator, messages } from '@cucumber/messages' -import createMeta from '@cucumber/create-meta' +import os from 'os' +import * as messages from '@cucumber/messages' +import { IdGenerator } from '@cucumber/messages' +import detectCiEnvironment from '@cucumber/ci-environment' import { ISupportCodeLibrary } from '../support_code_library_builder/types' import TestCaseHookDefinition from '../models/test_case_hook_definition' import TestRunHookDefinition from '../models/test_run_hook_definition' import { builtinParameterTypes } from '../support_code_library_builder' - -const StepDefinitionPatternType = - messages.StepDefinition.StepDefinitionPattern.StepDefinitionPatternType +import { version } from '../version' export interface IGetExpandedArgvRequest { argv: string[] @@ -30,9 +28,12 @@ export async function getExpandedArgv({ }: IGetExpandedArgvRequest): Promise { const { options } = ArgvParser.parse(argv) let fullArgv = argv - const profileArgv = await new ProfileLoader(cwd).getArgv(options.profile) + const profileArgv = await new ProfileLoader(cwd).getArgv( + options.profile, + options.config + ) if (profileArgv.length > 0) { - fullArgv = _.concat(argv.slice(0, 2), profileArgv, argv.slice(2)) + fullArgv = argv.slice(0, 2).concat(profileArgv).concat(argv.slice(2)) } return fullArgv } @@ -42,10 +43,12 @@ interface IParseGherkinMessageStreamRequest { eventBroadcaster: EventEmitter eventDataCollector: EventDataCollector gherkinMessageStream: Readable - order: string + order: PickleOrder pickleFilter: PickleFilter } +export type PickleOrder = 'defined' | 'random' + export async function parseGherkinMessageStream({ cwd, eventBroadcaster, @@ -56,7 +59,7 @@ export async function parseGherkinMessageStream({ }: IParseGherkinMessageStreamRequest): Promise { return await new Promise((resolve, reject) => { const result: string[] = [] - gherkinMessageStream.on('data', (envelope: messages.IEnvelope) => { + gherkinMessageStream.on('data', (envelope: messages.Envelope) => { eventBroadcaster.emit('envelope', envelope) if (doesHaveValue(envelope.pickle)) { const pickle = envelope.pickle @@ -71,10 +74,7 @@ export async function parseGherkinMessageStream({ if (doesHaveValue(envelope.parseError)) { reject( new Error( - `Parse error in '${path.relative( - cwd, - envelope.parseError.source.uri - )}': ${envelope.parseError.message}` + `Parse error in '${envelope.parseError.source.uri}': ${envelope.parseError.message}` ) ) } @@ -88,17 +88,19 @@ export async function parseGherkinMessageStream({ } // Orders the pickleIds in place - morphs input -export function orderPickleIds(pickleIds: string[], order: string): void { - let [type, seed] = OptionSplitter.split(order) +export function orderPickleIds(pickleIds: string[], order: PickleOrder): void { + const [type, seed] = OptionSplitter.split(order) switch (type) { case 'defined': break case 'random': if (seed === '') { - seed = Math.floor(Math.random() * 1000 * 1000).toString() - console.warn(`Random order using seed: ${seed}`) + const newSeed = Math.floor(Math.random() * 1000 * 1000).toString() + console.warn(`Random order using seed: ${newSeed}`) + shuffle(pickleIds, newSeed) + } else { + shuffle(pickleIds, seed) } - shuffle(pickleIds, seed) break default: throw new Error( @@ -107,17 +109,40 @@ export function orderPickleIds(pickleIds: string[], order: string): void { } } +export function isJavaScript(filePath: string): boolean { + return ( + filePath.endsWith('.js') || + filePath.endsWith('.mjs') || + filePath.endsWith('.cjs') + ) +} + export async function emitMetaMessage( - eventBroadcaster: EventEmitter + eventBroadcaster: EventEmitter, + env: NodeJS.ProcessEnv ): Promise { - // eslint-disable-next-line @typescript-eslint/no-var-requires - const { version } = require('../../package.json') - eventBroadcaster.emit( - 'envelope', - new messages.Envelope({ - meta: createMeta('cucumber-js', version, process.env), - }) - ) + const meta: messages.Meta = { + protocolVersion: messages.version, + implementation: { + version, + name: 'cucumber-js', + }, + cpu: { + name: os.arch(), + }, + os: { + name: os.platform(), + version: os.release(), + }, + runtime: { + name: 'node.js', + version: process.versions.node, + }, + ci: detectCiEnvironment(env), + } + eventBroadcaster.emit('envelope', { + meta, + }) } function emitParameterTypes( @@ -130,18 +155,16 @@ function emitParameterTypes( if (builtinParameterTypes.includes(parameterType.name)) { continue } - eventBroadcaster.emit( - 'envelope', - messages.Envelope.fromObject({ - parameterType: { - id: newId(), - name: parameterType.name, - preferForRegularExpressionMatch: parameterType.preferForRegexpMatch, - regularExpressions: parameterType.regexpStrings, - useForSnippets: parameterType.useForSnippets, - }, - }) - ) + const envelope: messages.Envelope = { + parameterType: { + id: newId(), + name: parameterType.name, + preferForRegularExpressionMatch: parameterType.preferForRegexpMatch, + regularExpressions: parameterType.regexpStrings, + useForSnippets: parameterType.useForSnippets, + }, + } + eventBroadcaster.emit('envelope', envelope) } } @@ -150,12 +173,10 @@ function emitUndefinedParameterTypes( eventBroadcaster: EventEmitter ): void { for (const undefinedParameterType of supportCodeLibrary.undefinedParameterTypes) { - eventBroadcaster.emit( - 'envelope', - messages.Envelope.fromObject({ - undefinedParameterType, - }) - ) + const envelope: messages.Envelope = { + undefinedParameterType, + } + eventBroadcaster.emit('envelope', envelope) } } @@ -164,27 +185,25 @@ function emitStepDefinitions( eventBroadcaster: EventEmitter ): void { supportCodeLibrary.stepDefinitions.forEach((stepDefinition) => { - eventBroadcaster.emit( - 'envelope', - messages.Envelope.fromObject({ - stepDefinition: { - id: stepDefinition.id, - pattern: { - source: stepDefinition.pattern.toString(), - type: - typeof stepDefinition.pattern === 'string' - ? StepDefinitionPatternType.CUCUMBER_EXPRESSION - : StepDefinitionPatternType.REGULAR_EXPRESSION, - }, - sourceReference: { - uri: stepDefinition.uri, - location: { - line: stepDefinition.line, - }, + const envelope: messages.Envelope = { + stepDefinition: { + id: stepDefinition.id, + pattern: { + source: stepDefinition.pattern.toString(), + type: + typeof stepDefinition.pattern === 'string' + ? messages.StepDefinitionPatternType.CUCUMBER_EXPRESSION + : messages.StepDefinitionPatternType.REGULAR_EXPRESSION, + }, + sourceReference: { + uri: stepDefinition.uri, + location: { + line: stepDefinition.line, }, }, - }) - ) + }, + } + eventBroadcaster.emit('envelope', envelope) }) } @@ -198,21 +217,19 @@ function emitTestCaseHooks( supportCodeLibrary.afterTestCaseHookDefinitions ) .forEach((testCaseHookDefinition: TestCaseHookDefinition) => { - eventBroadcaster.emit( - 'envelope', - messages.Envelope.fromObject({ - hook: { - id: testCaseHookDefinition.id, - tagExpression: testCaseHookDefinition.tagExpression, - sourceReference: { - uri: testCaseHookDefinition.uri, - location: { - line: testCaseHookDefinition.line, - }, + const envelope: messages.Envelope = { + hook: { + id: testCaseHookDefinition.id, + tagExpression: testCaseHookDefinition.tagExpression, + sourceReference: { + uri: testCaseHookDefinition.uri, + location: { + line: testCaseHookDefinition.line, }, }, - }) - ) + }, + } + eventBroadcaster.emit('envelope', envelope) }) } @@ -226,20 +243,18 @@ function emitTestRunHooks( supportCodeLibrary.afterTestRunHookDefinitions ) .forEach((testRunHookDefinition: TestRunHookDefinition) => { - eventBroadcaster.emit( - 'envelope', - messages.Envelope.fromObject({ - hook: { - id: testRunHookDefinition.id, - sourceReference: { - uri: testRunHookDefinition.uri, - location: { - line: testRunHookDefinition.line, - }, + const envelope: messages.Envelope = { + hook: { + id: testRunHookDefinition.id, + sourceReference: { + uri: testRunHookDefinition.uri, + location: { + line: testRunHookDefinition.line, }, }, - }) - ) + }, + } + eventBroadcaster.emit('envelope', envelope) }) } diff --git a/src/cli/helpers_spec.ts b/src/cli/helpers_spec.ts index 26473a4a2..5e9e19af0 100644 --- a/src/cli/helpers_spec.ts +++ b/src/cli/helpers_spec.ts @@ -3,11 +3,14 @@ import { expect } from 'chai' import { emitMetaMessage, emitSupportCodeMessages, + isJavaScript, parseGherkinMessageStream, + PickleOrder, } from './helpers' import { EventEmitter } from 'events' import PickleFilter from '../pickle_filter' -import { messages, IdGenerator } from '@cucumber/messages' +import * as messages from '@cucumber/messages' +import { IdGenerator, SourceMediaType } from '@cucumber/messages' import { EventDataCollector } from '../formatter/helpers' import { GherkinStreams } from '@cucumber/gherkin-streams' import { Readable } from 'stream' @@ -29,19 +32,19 @@ const noopFunction = (): void => { interface ITestParseGherkinMessageStreamRequest { cwd: string gherkinMessageStream: Readable - order: string + order: PickleOrder pickleFilter: PickleFilter } interface ITestParseGherkinMessageStreamResponse { - envelopes: messages.IEnvelope[] + envelopes: messages.Envelope[] result: string[] } async function testParseGherkinMessageStream( options: ITestParseGherkinMessageStreamRequest ): Promise { - const envelopes: messages.IEnvelope[] = [] + const envelopes: messages.Envelope[] = [] const eventBroadcaster = new EventEmitter() eventBroadcaster.on('envelope', (e) => envelopes.push(e)) const eventDataCollector = new EventDataCollector(eventBroadcaster) @@ -58,8 +61,8 @@ async function testParseGherkinMessageStream( function testEmitSupportCodeMessages( supportCode: Partial -): messages.IEnvelope[] { - const envelopes: messages.IEnvelope[] = [] +): messages.Envelope[] { + const envelopes: messages.Envelope[] = [] const eventBroadcaster = new EventEmitter() eventBroadcaster.on('envelope', (e) => envelopes.push(e)) emitSupportCodeMessages({ @@ -87,12 +90,22 @@ function testEmitSupportCodeMessages( } describe('helpers', () => { + describe('isJavaScript', () => { + it('should identify a native javascript file path that can be `import()`ed', () => { + expect(isJavaScript('foo/bar.js')).to.be.true() + expect(isJavaScript('foo/bar.mjs')).to.be.true() + expect(isJavaScript('foo/bar.cjs')).to.be.true() + expect(isJavaScript('foo/bar.ts')).to.be.false() + expect(isJavaScript('foo/bar.coffee')).to.be.false() + }) + }) + describe('emitMetaMessage', () => { it('emits a meta message', async () => { - const envelopes: messages.IEnvelope[] = [] + const envelopes: messages.Envelope[] = [] const eventBroadcaster = new EventEmitter() eventBroadcaster.on('envelope', (e) => envelopes.push(e)) - await emitMetaMessage(eventBroadcaster) + await emitMetaMessage(eventBroadcaster, {}) expect(envelopes).to.have.length(1) expect(envelopes[0].meta.implementation.name).to.eq('cucumber-js') @@ -116,8 +129,8 @@ describe('helpers', () => { parameterTypeRegistry, }) - expect(envelopes).to.deep.eq([ - messages.Envelope.fromObject({ + const expectedEnvelopes: messages.Envelope[] = [ + { parameterType: { id: '0', name: 'flight', @@ -125,9 +138,11 @@ describe('helpers', () => { regularExpressions: ['([A-Z]{3})-([A-Z]{3})'], useForSnippets: true, }, - }), - ]) + }, + ] + expect(envelopes).to.deep.eq(expectedEnvelopes) }) + it('emits messages for step definitions using cucumber expressions', () => { const envelopes = testEmitSupportCodeMessages({ stepDefinitions: [ @@ -147,15 +162,13 @@ describe('helpers', () => { ], }) - expect(envelopes).to.deep.eq([ - messages.Envelope.fromObject({ + const expectedEnvelopes: messages.Envelope[] = [ + { stepDefinition: { id: '0', pattern: { source: 'I have {int} cukes in my belly', - type: - messages.StepDefinition.StepDefinitionPattern - .StepDefinitionPatternType.CUCUMBER_EXPRESSION, + type: messages.StepDefinitionPatternType.CUCUMBER_EXPRESSION, }, sourceReference: { uri: 'features/support/cukes.js', @@ -164,8 +177,9 @@ describe('helpers', () => { }, }, }, - }), - ]) + }, + ] + expect(envelopes).to.deep.eq(expectedEnvelopes) }) it('emits messages for step definitions using regular expressions', () => { const envelopes = testEmitSupportCodeMessages({ @@ -186,15 +200,13 @@ describe('helpers', () => { ], }) - expect(envelopes).to.deep.eq([ - messages.Envelope.fromObject({ + const expectedEnvelopes: messages.Envelope[] = [ + { stepDefinition: { id: '0', pattern: { source: '/I have (\\d+) cukes in my belly/', - type: - messages.StepDefinition.StepDefinitionPattern - .StepDefinitionPatternType.REGULAR_EXPRESSION, + type: messages.StepDefinitionPatternType.REGULAR_EXPRESSION, }, sourceReference: { uri: 'features/support/cukes.js', @@ -203,8 +215,9 @@ describe('helpers', () => { }, }, }, - }), - ]) + }, + ] + expect(envelopes).to.deep.eq(expectedEnvelopes) }) it('emits messages for test case level hooks', () => { const envelopes = testEmitSupportCodeMessages({ @@ -240,8 +253,8 @@ describe('helpers', () => { ], }) - expect(envelopes).to.deep.eq([ - messages.Envelope.fromObject({ + const expectedEnvelopes: messages.Envelope[] = [ + { hook: { id: '0', tagExpression: '@hooks-tho', @@ -252,10 +265,11 @@ describe('helpers', () => { }, }, }, - }), - messages.Envelope.fromObject({ + }, + { hook: { id: '1', + tagExpression: undefined, sourceReference: { uri: 'features/support/hooks.js', location: { @@ -263,10 +277,11 @@ describe('helpers', () => { }, }, }, - }), - messages.Envelope.fromObject({ + }, + { hook: { id: '2', + tagExpression: undefined, sourceReference: { uri: 'features/support/hooks.js', location: { @@ -274,8 +289,9 @@ describe('helpers', () => { }, }, }, - }), - ]) + }, + ] + expect(envelopes).to.deep.eq(expectedEnvelopes) }) it('emits messages for test run level hooks', () => { const envelopes = testEmitSupportCodeMessages({ @@ -309,8 +325,8 @@ describe('helpers', () => { ], }) - expect(envelopes).to.deep.eq([ - messages.Envelope.fromObject({ + const expectedEnvelopes: messages.Envelope[] = [ + { hook: { id: '0', sourceReference: { @@ -320,8 +336,8 @@ describe('helpers', () => { }, }, }, - }), - messages.Envelope.fromObject({ + }, + { hook: { id: '1', sourceReference: { @@ -331,8 +347,8 @@ describe('helpers', () => { }, }, }, - }), - messages.Envelope.fromObject({ + }, + { hook: { id: '2', sourceReference: { @@ -342,8 +358,9 @@ describe('helpers', () => { }, }, }, - }), - ]) + }, + ] + expect(envelopes).to.deep.eq(expectedEnvelopes) }) }) describe('parseGherkinMessageStream', () => { @@ -351,13 +368,13 @@ describe('helpers', () => { it('emits source and gherkinDocument events and returns an empty array', async function () { // Arrange const cwd = '/project' - const sourceEnvelope = messages.Envelope.create({ - source: messages.Source.fromObject({ + const sourceEnvelope: messages.Envelope = { + source: { data: '', - mediaType: 'text/x.cucumber.gherkin+plain', + mediaType: SourceMediaType.TEXT_X_CUCUMBER_GHERKIN_PLAIN, uri: '/project/features/a.feature', - }), - }) + }, + } const gherkinMessageStream = GherkinStreams.fromSources( [sourceEnvelope], {} @@ -378,7 +395,11 @@ describe('helpers', () => { expect(envelopes).to.have.lengthOf(2) expect(envelopes[0]).to.eql(sourceEnvelope) expect(envelopes[1].gherkinDocument).to.exist() - expect(envelopes[1].gherkinDocument).to.have.keys(['comments', 'uri']) + expect(envelopes[1].gherkinDocument).to.have.keys([ + 'comments', + 'feature', + 'uri', + ]) }) }) @@ -386,13 +407,13 @@ describe('helpers', () => { it('emits pickle event and returns an empty array', async function () { // Arrange const cwd = '/project' - const sourceEnvelope = messages.Envelope.create({ - source: messages.Source.fromObject({ + const sourceEnvelope: messages.Envelope = { + source: { data: '@tagA\nFeature: a\nScenario: b\nGiven a step', - mediaType: 'text/x.cucumber.gherkin+plain', + mediaType: SourceMediaType.TEXT_X_CUCUMBER_GHERKIN_PLAIN, uri: '/project/features/a.feature', - }), - }) + }, + } const gherkinMessageStream = GherkinStreams.fromSources( [sourceEnvelope], {} @@ -433,13 +454,13 @@ describe('helpers', () => { it('emits pickle and returns the pickleId', async function () { // Arrange const cwd = '/project' - const sourceEnvelope = messages.Envelope.create({ - source: messages.Source.fromObject({ + const sourceEnvelope: messages.Envelope = { + source: { data: 'Feature: a\nScenario: b\nGiven a step', - mediaType: 'text/x.cucumber.gherkin+plain', + mediaType: SourceMediaType.TEXT_X_CUCUMBER_GHERKIN_PLAIN, uri: '/project/features/a.feature', - }), - }) + }, + } const gherkinMessageStream = GherkinStreams.fromSources( [sourceEnvelope], {} diff --git a/src/cli/i18n.ts b/src/cli/i18n.ts index fe2bf4dfe..be243e9a1 100644 --- a/src/cli/i18n.ts +++ b/src/cli/i18n.ts @@ -1,10 +1,10 @@ -import _ from 'lodash' import { dialects } from '@cucumber/gherkin' import Table from 'cli-table3' import { capitalCase } from 'capital-case' const keywords = [ 'feature', + 'rule', 'background', 'scenario', 'scenarioOutline', @@ -47,18 +47,18 @@ function getAsTable(header: string[], rows: string[][]): string { } export function getLanguages(): string { - const rows = _.map(dialects, (data, isoCode) => [ + const rows = Object.keys(dialects).map((isoCode) => [ isoCode, - data.name, - data.native, + dialects[isoCode].name, + dialects[isoCode].native, ]) return getAsTable(['ISO 639-1', 'ENGLISH NAME', 'NATIVE NAME'], rows) } export function getKeywords(isoCode: string): string { const language = dialects[isoCode] - const rows = _.map(keywords, (keyword) => { - const words = _.map(language[keyword], (s) => `"${s}"`).join(', ') + const rows = keywords.map((keyword) => { + const words = language[keyword].map((s) => `"${s}"`).join(', ') return [capitalCase(keyword), words] }) return getAsTable(['ENGLISH KEYWORD', 'NATIVE KEYWORDS'], rows) diff --git a/src/cli/index.ts b/src/cli/index.ts index 25020be63..629eeb443 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -1,250 +1,59 @@ -import { EventDataCollector } from '../formatter/helpers' -import { - emitMetaMessage, - emitSupportCodeMessages, - getExpandedArgv, - parseGherkinMessageStream, -} from './helpers' +import { getExpandedArgv } from './helpers' import { validateInstall } from './install_validator' -import * as I18n from './i18n' -import ConfigurationBuilder, { - IConfiguration, - IConfigurationFormat, -} from './configuration_builder' -import { EventEmitter } from 'events' -import FormatterBuilder from '../formatter/builder' -import fs from 'mz/fs' -import path from 'path' -import PickleFilter from '../pickle_filter' -import bluebird from 'bluebird' -import ParallelRuntimeCoordinator from '../runtime/parallel/coordinator' -import Runtime from '../runtime' -import supportCodeLibraryBuilder from '../support_code_library_builder' -import { IdGenerator } from '@cucumber/messages' +import { buildConfiguration, isTruthyString } from './configuration_builder' import { IFormatterStream } from '../formatter' -import { WriteStream as TtyWriteStream } from 'tty' -import { doesNotHaveValue } from '../value_checker' -import { GherkinStreams } from '@cucumber/gherkin-streams' -import { ISupportCodeLibrary } from '../support_code_library_builder/types' -import { IParsedArgvFormatOptions } from './argv_parser' -import HttpStream from '../formatter/http_stream' -import { Writable } from 'stream' - -const { incrementing, uuid } = IdGenerator +import { runCucumber } from '../run' +import ArgvParser from './argv_parser' export interface ICliRunResult { + shouldAdvertisePublish: boolean shouldExitImmediately: boolean success: boolean } -interface IInitializeFormattersRequest { - eventBroadcaster: EventEmitter - eventDataCollector: EventDataCollector - formatOptions: IParsedArgvFormatOptions - formats: IConfigurationFormat[] - supportCodeLibrary: ISupportCodeLibrary -} - -interface IGetSupportCodeLibraryRequest { - newId: IdGenerator.NewId - supportCodeRequiredModules: string[] - supportCodePaths: string[] -} - export default class Cli { private readonly argv: string[] private readonly cwd: string private readonly stdout: IFormatterStream + private readonly env: NodeJS.ProcessEnv constructor({ argv, cwd, stdout, + env, }: { argv: string[] cwd: string stdout: IFormatterStream + env: NodeJS.ProcessEnv }) { this.argv = argv this.cwd = cwd this.stdout = stdout - } - - async getConfiguration(): Promise { - const fullArgv = await getExpandedArgv({ - argv: this.argv, - cwd: this.cwd, - }) - return await ConfigurationBuilder.build({ - argv: fullArgv, - cwd: this.cwd, - }) - } - - async initializeFormatters({ - eventBroadcaster, - eventDataCollector, - formatOptions, - formats, - supportCodeLibrary, - }: IInitializeFormattersRequest): Promise<() => Promise> { - const formatters = await bluebird.map( - formats, - async ({ type, outputTo }) => { - let stream: IFormatterStream = this.stdout - if (outputTo !== '') { - if (outputTo.match(/^https?:\/\//) !== null) { - const headers: { [key: string]: string } = {} - if (process.env.CUCUMBER_PUBLISH_TOKEN !== undefined) { - headers.Authorization = `Bearer ${process.env.CUCUMBER_PUBLISH_TOKEN}` - } - - stream = new HttpStream(outputTo, 'GET', headers) - const readerStream = new Writable({ - objectMode: true, - write: function (responseBody: string, encoding, writeCallback) { - console.error(responseBody) - writeCallback() - }, - }) - stream.pipe(readerStream) - } else { - const fd = await fs.open(path.resolve(this.cwd, outputTo), 'w') - stream = fs.createWriteStream(null, { fd }) - } - } - - stream.on('error', (error) => { - console.error(error.message) - process.exit(1) - }) - - const typeOptions = { - cwd: this.cwd, - eventBroadcaster, - eventDataCollector, - log: stream.write.bind(stream), - parsedArgvOptions: formatOptions, - stream, - cleanup: - stream === this.stdout - ? async () => await Promise.resolve() - : bluebird.promisify(stream.end.bind(stream)), - supportCodeLibrary, - } - if (doesNotHaveValue(formatOptions.colorsEnabled)) { - typeOptions.parsedArgvOptions.colorsEnabled = (stream as TtyWriteStream).isTTY - } - if (type === 'progress-bar' && !(stream as TtyWriteStream).isTTY) { - const outputToName = outputTo === '' ? 'stdout' : outputTo - console.warn( - `Cannot use 'progress-bar' formatter for output to '${outputToName}' as not a TTY. Switching to 'progress' formatter.` - ) - type = 'progress' - } - return FormatterBuilder.build(type, typeOptions) - } - ) - return async function () { - await bluebird.each(formatters, async (formatter) => { - await formatter.finished() - }) - } - } - - getSupportCodeLibrary({ - newId, - supportCodeRequiredModules, - supportCodePaths, - }: IGetSupportCodeLibraryRequest): ISupportCodeLibrary { - supportCodeRequiredModules.map((module) => require(module)) - supportCodeLibraryBuilder.reset(this.cwd, newId) - supportCodePaths.forEach((codePath) => require(codePath)) - return supportCodeLibraryBuilder.finalize() + this.env = env } async run(): Promise { await validateInstall(this.cwd) - const configuration = await this.getConfiguration() - if (configuration.listI18nLanguages) { - this.stdout.write(I18n.getLanguages()) - return { shouldExitImmediately: true, success: true } - } - if (configuration.listI18nKeywordsFor !== '') { - this.stdout.write(I18n.getKeywords(configuration.listI18nKeywordsFor)) - return { shouldExitImmediately: true, success: true } - } - const newId = - configuration.predictableIds && configuration.parallel <= 1 - ? incrementing() - : uuid() - const supportCodeLibrary = this.getSupportCodeLibrary({ - newId, - supportCodePaths: configuration.supportCodePaths, - supportCodeRequiredModules: configuration.supportCodeRequiredModules, - }) - const eventBroadcaster = new EventEmitter() - const eventDataCollector = new EventDataCollector(eventBroadcaster) - const cleanup = await this.initializeFormatters({ - eventBroadcaster, - eventDataCollector, - formatOptions: configuration.formatOptions, - formats: configuration.formats, - supportCodeLibrary, - }) - await emitMetaMessage(eventBroadcaster) - const gherkinMessageStream = GherkinStreams.fromPaths( - configuration.featurePaths, - { - defaultDialect: configuration.featureDefaultLanguage, - newId, - } + const fromArgv = ArgvParser.parse( + await getExpandedArgv({ + argv: this.argv, + cwd: this.cwd, + }) ) - const pickleIds = await parseGherkinMessageStream({ + const configuration = await buildConfiguration(fromArgv, this.env) + const { success } = await runCucumber(configuration, { cwd: this.cwd, - eventBroadcaster, - eventDataCollector, - gherkinMessageStream, - order: configuration.order, - pickleFilter: new PickleFilter(configuration.pickleFilterOptions), + stdout: this.stdout, + env: this.env, }) - emitSupportCodeMessages({ - eventBroadcaster, - supportCodeLibrary, - newId, - }) - let success - if (configuration.parallel > 1) { - const parallelRuntimeCoordinator = new ParallelRuntimeCoordinator({ - cwd: this.cwd, - eventBroadcaster, - eventDataCollector, - options: configuration.runtimeOptions, - pickleIds, - supportCodeLibrary, - supportCodePaths: configuration.supportCodePaths, - supportCodeRequiredModules: configuration.supportCodeRequiredModules, - }) - await new Promise((resolve) => { - parallelRuntimeCoordinator.run(configuration.parallel, (s) => { - success = s - resolve() - }) - }) - } else { - const runtime = new Runtime({ - eventBroadcaster, - eventDataCollector, - options: configuration.runtimeOptions, - newId, - pickleIds, - supportCodeLibrary, - }) - success = await runtime.start() - } - await cleanup() return { - shouldExitImmediately: configuration.shouldExitImmediately, + shouldAdvertisePublish: + !configuration.formats.publish && + !fromArgv.options.publishQuiet && + !isTruthyString(this.env.CUCUMBER_PUBLISH_QUIET), + shouldExitImmediately: fromArgv.options.exit, success, } } diff --git a/src/cli/option_splitter.ts b/src/cli/option_splitter.ts index 20f3eebe9..9b7371c7e 100644 --- a/src/cli/option_splitter.ts +++ b/src/cli/option_splitter.ts @@ -1,5 +1,7 @@ const OptionSplitter = { split(option: string): string[] { + option = option.replace(/"/g, '') + const parts = option.split(/([^A-Z]):(?!\\)/) const result = parts.reduce((memo: string[], part: string, i: number) => { diff --git a/src/cli/option_splitter_spec.ts b/src/cli/option_splitter_spec.ts index 19ec75c93..162f92e54 100644 --- a/src/cli/option_splitter_spec.ts +++ b/src/cli/option_splitter_spec.ts @@ -19,6 +19,11 @@ describe('OptionSplitter', () => { input: '/custom/formatter:/formatter/output.txt', output: ['/custom/formatter', '/formatter/output.txt'], }, + { + description: 'splits paths with quotes around them', + input: '/custom/formatter:"/formatter directory/output.txt"', + output: ['/custom/formatter', '/formatter directory/output.txt'], + }, { description: 'splits absolute windows paths', input: 'C:\\custom\\formatter:C:\\formatter\\output.txt', diff --git a/src/cli/profile_loader.ts b/src/cli/profile_loader.ts index 2a78ec323..8cd97d499 100644 --- a/src/cli/profile_loader.ts +++ b/src/cli/profile_loader.ts @@ -1,31 +1,41 @@ -import _ from 'lodash' import fs from 'mz/fs' import path from 'path' import stringArgv from 'string-argv' import { doesHaveValue, doesNotHaveValue } from '../value_checker' +const DEFAULT_FILENAMES = ['cucumber.cjs', 'cucumber.js'] + export default class ProfileLoader { - private readonly directory: string + constructor(private readonly directory: string) {} - constructor(directory: string) { - this.directory = directory - } + async getDefinitions(configFile?: string): Promise> { + if (configFile) { + return this.loadFile(configFile) + } + + const defaultFile = DEFAULT_FILENAMES.find((filename) => + fs.existsSync(path.join(this.directory, filename)) + ) - async getDefinitions(): Promise> { - const definitionsFilePath = path.join(this.directory, 'cucumber.js') - const exists = await fs.exists(definitionsFilePath) - if (!exists) { - return {} + if (defaultFile) { + return this.loadFile(defaultFile) } - const definitions = require(definitionsFilePath) // eslint-disable-line @typescript-eslint/no-var-requires + + return {} + } + + loadFile(configFile: string): Record { + const definitionsFilePath: string = path.join(this.directory, configFile) + // eslint-disable-next-line @typescript-eslint/no-var-requires + const definitions = require(definitionsFilePath) if (typeof definitions !== 'object') { throw new Error(`${definitionsFilePath} does not export an object`) } return definitions } - async getArgv(profiles: string[]): Promise { - const definitions = await this.getDefinitions() + async getArgv(profiles: string[], configFile?: string): Promise { + const definitions = await this.getDefinitions(configFile) if (profiles.length === 0 && doesHaveValue(definitions.default)) { profiles = ['default'] } @@ -35,6 +45,6 @@ export default class ProfileLoader { } return stringArgv(definitions[profile]) }) - return _.flatten(argvs) + return argvs.flat() } } diff --git a/src/cli/profile_loader_spec.ts b/src/cli/profile_loader_spec.ts index a57d52ccd..fcbe4c035 100644 --- a/src/cli/profile_loader_spec.ts +++ b/src/cli/profile_loader_spec.ts @@ -9,7 +9,9 @@ import { doesHaveValue, valueOrDefault } from '../value_checker' interface TestProfileLoaderOptions { definitionsFileContent?: string + definitionsFileName?: string profiles?: string[] + configOption?: string } async function testProfileLoader( @@ -18,14 +20,20 @@ async function testProfileLoader( const cwd = await promisify(tmp.dir)({ unsafeCleanup: true, }) + const definitionsFileName = opts.definitionsFileName ?? 'cucumber.js' + if (doesHaveValue(opts.definitionsFileContent)) { await fs.writeFile( - path.join(cwd, 'cucumber.js'), + path.join(cwd, definitionsFileName), opts.definitionsFileContent ) } + const profileLoader = new ProfileLoader(cwd) - return await profileLoader.getArgv(valueOrDefault(opts.profiles, [])) + return await profileLoader.getArgv( + valueOrDefault(opts.profiles, []), + opts.configOption + ) } describe('ProfileLoader', () => { @@ -150,5 +158,42 @@ describe('ProfileLoader', () => { }) }) }) + + describe('with non-default configuration file', () => { + it('returns the argv for the given profile', async function () { + // Arrange + const definitionsFileContent = + 'module.exports = {profile3: "--opt3 --opt4"}' + + // Act + const result = await testProfileLoader({ + definitionsFileContent, + definitionsFileName: '.cucumber-rc.js', + profiles: ['profile3'], + configOption: '.cucumber-rc.js', + }) + + // Assert + expect(result).to.eql(['--opt3', '--opt4']) + }) + + it('throws when the file doesnt exist', async () => { + // Arrange + const definitionsFileContent = + 'module.exports = {profile3: "--opt3 --opt4"}' + + // Act + try { + await testProfileLoader({ + definitionsFileContent, + profiles: [], + configOption: 'doesntexist.js', + }) + expect.fail('should throw') + } catch (e) { + expect(e.message).to.contain('Cannot find module') + } + }) + }) }) }) diff --git a/src/cli/publish_banner.ts b/src/cli/publish_banner.ts index 53a8eefca..123bcb96b 100644 --- a/src/cli/publish_banner.ts +++ b/src/cli/publish_banner.ts @@ -1,26 +1,26 @@ -import colors from 'colors/safe' +import chalk from 'chalk' import Table from 'cli-table3' const underlineBoldCyan = (x: string): string => - colors.underline(colors.bold(colors.cyan(x))) + chalk.underline(chalk.bold(chalk.cyan(x))) const formattedReportUrl = underlineBoldCyan('https://reports.cucumber.io') const formattedEnv = - colors.cyan('CUCUMBER_PUBLISH_ENABLED') + '=' + colors.cyan('true') + chalk.cyan('CUCUMBER_PUBLISH_ENABLED') + '=' + chalk.cyan('true') const formattedMoreInfoUrl = underlineBoldCyan( - 'https://reports.cucumber.io/docs/cucumber-js' + 'https://cucumber.io/docs/cucumber/environment-variables/' ) const text = `\ Share your Cucumber Report with your team at ${formattedReportUrl} -Command line option: ${colors.cyan('--publish')} +Command line option: ${chalk.cyan('--publish')} Environment variable: ${formattedEnv} More information at ${formattedMoreInfoUrl} -To disable this message, add this to your ${colors.bold('./cucumber.js')}: -${colors.bold("module.exports = { default: '--publish-quiet' }")}` +To disable this message, add this to your ${chalk.bold('./cucumber.js')}: +${chalk.bold("module.exports = { default: '--publish-quiet' }")}` const table = new Table({ style: { diff --git a/src/cli/run.ts b/src/cli/run.ts index c2253d0f2..508b71666 100644 --- a/src/cli/run.ts +++ b/src/cli/run.ts @@ -12,11 +12,11 @@ function displayPublishAdvertisementBanner(): void { } export default async function run(): Promise { - const cwd = process.cwd() const cli = new Cli({ argv: process.argv, - cwd, + cwd: process.cwd(), stdout: process.stdout, + env: process.env, }) let result: ICliRunResult @@ -26,8 +26,7 @@ export default async function run(): Promise { exitWithError(error) } - const config = await cli.getConfiguration() - if (!config.publishing && !config.suppressPublishAdvertisement) { + if (result.shouldAdvertisePublish) { displayPublishAdvertisementBanner() } diff --git a/src/configuration/index.ts b/src/configuration/index.ts new file mode 100644 index 000000000..c9f6f047d --- /dev/null +++ b/src/configuration/index.ts @@ -0,0 +1 @@ +export * from './types' diff --git a/src/configuration/types.ts b/src/configuration/types.ts new file mode 100644 index 000000000..c7fbd4453 --- /dev/null +++ b/src/configuration/types.ts @@ -0,0 +1,31 @@ +import { IRuntimeOptions } from '../runtime' +import { IParsedArgvFormatOptions } from '../cli/argv_parser' +import { PickleOrder } from '../cli/helpers' + +export interface IRunConfiguration { + sources: { + defaultDialect?: string + paths?: string[] + names?: string[] + tagExpression?: string + order?: PickleOrder + } + support: { + transpileWith: string[] + paths: string[] + } + runtime?: Partial & { parallel?: number } + formats?: IFormatterConfiguration +} + +export interface IFormatterConfiguration { + stdout?: string + files?: Record + publish?: + | { + url?: string + token?: string + } + | false + options?: IParsedArgvFormatOptions +} diff --git a/src/formatter/builder.ts b/src/formatter/builder.ts index 27da244eb..fcb20f5ff 100644 --- a/src/formatter/builder.ts +++ b/src/formatter/builder.ts @@ -1,16 +1,7 @@ import getColorFns from './get_color_fns' import JavascriptSnippetSyntax from './step_definition_snippet_builder/javascript_snippet_syntax' -import JsonFormatter from './json_formatter' -import MessageFormatter from './message_formatter' import path from 'path' -import ProgressBarFormatter from './progress_bar_formatter' -import ProgressFormatter from './progress_formatter' -import RerunFormatter from './rerun_formatter' -import SnippetsFormatter from './snippets_formatter' import StepDefinitionSnippetBuilder from './step_definition_snippet_builder' -import SummaryFormatter from './summary_formatter' -import UsageFormatter from './usage_formatter' -import UsageJsonFormatter from './usage_json_formatter' import { ISupportCodeLibrary } from '../support_code_library_builder/types' import Formatter, { IFormatterCleanupFn, IFormatterLogFn } from '.' import { doesHaveValue, doesNotHaveValue } from '../value_checker' @@ -19,8 +10,10 @@ import EventDataCollector from './helpers/event_data_collector' import { Writable as WritableStream } from 'stream' import { IParsedArgvFormatOptions } from '../cli/argv_parser' import { SnippetInterface } from './step_definition_snippet_builder/snippet_syntax' -import HtmlFormatter from './html_formatter' -import createRequire from 'create-require' +import { pathToFileURL } from 'url' +import Formatters from './helpers/formatters' +// eslint-disable-next-line @typescript-eslint/no-var-requires +const { importer } = require('../importer') interface IGetStepDefinitionSnippetBuilderOptions { cwd: string @@ -41,18 +34,19 @@ export interface IBuildOptions { } const FormatterBuilder = { - build(type: string, options: IBuildOptions): Formatter { - const FormatterConstructor = FormatterBuilder.getConstructorByType( + async build(type: string, options: IBuildOptions): Promise { + const FormatterConstructor = await FormatterBuilder.getConstructorByType( type, options.cwd ) const colorFns = getColorFns(options.parsedArgvOptions.colorsEnabled) - const snippetBuilder = FormatterBuilder.getStepDefinitionSnippetBuilder({ - cwd: options.cwd, - snippetInterface: options.parsedArgvOptions.snippetInterface, - snippetSyntax: options.parsedArgvOptions.snippetSyntax, - supportCodeLibrary: options.supportCodeLibrary, - }) + const snippetBuilder = + await FormatterBuilder.getStepDefinitionSnippetBuilder({ + cwd: options.cwd, + snippetInterface: options.parsedArgvOptions.snippetInterface, + snippetSyntax: options.parsedArgvOptions.snippetSyntax, + supportCodeLibrary: options.supportCodeLibrary, + }) return new FormatterConstructor({ colorFns, snippetBuilder, @@ -60,34 +54,19 @@ const FormatterBuilder = { }) }, - getConstructorByType(type: string, cwd: string): typeof Formatter { - switch (type) { - case 'json': - return JsonFormatter - case 'message': - return MessageFormatter - case 'html': - return HtmlFormatter - case 'progress': - return ProgressFormatter - case 'progress-bar': - return ProgressBarFormatter - case 'rerun': - return RerunFormatter - case 'snippets': - return SnippetsFormatter - case 'summary': - return SummaryFormatter - case 'usage': - return UsageFormatter - case 'usage-json': - return UsageJsonFormatter - default: - return FormatterBuilder.loadCustomFormatter(type, cwd) - } + async getConstructorByType( + type: string, + cwd: string + ): Promise { + const formatters: Record = + Formatters.getFormatters() + + return formatters[type] + ? formatters[type] + : await FormatterBuilder.loadCustomClass('formatter', type, cwd) }, - getStepDefinitionSnippetBuilder({ + async getStepDefinitionSnippetBuilder({ cwd, snippetInterface, snippetSyntax, @@ -98,8 +77,11 @@ const FormatterBuilder = { } let Syntax = JavascriptSnippetSyntax if (doesHaveValue(snippetSyntax)) { - const fullSyntaxPath = path.resolve(cwd, snippetSyntax) - Syntax = require(fullSyntaxPath) // eslint-disable-line @typescript-eslint/no-var-requires + Syntax = await FormatterBuilder.loadCustomClass( + 'syntax', + snippetSyntax, + cwd + ) } return new StepDefinitionSnippetBuilder({ snippetSyntax: new Syntax(snippetInterface), @@ -107,20 +89,34 @@ const FormatterBuilder = { }) }, - loadCustomFormatter(customFormatterPath: string, cwd: string) { - const CustomFormatter = createRequire(cwd)(customFormatterPath) + async loadCustomClass( + type: 'formatter' | 'syntax', + descriptor: string, + cwd: string + ) { + let CustomClass = descriptor.startsWith(`.`) + ? await importer(pathToFileURL(path.resolve(cwd, descriptor))) + : await importer(descriptor) + CustomClass = FormatterBuilder.resolveConstructor(CustomClass) + if (doesHaveValue(CustomClass)) { + return CustomClass + } else { + throw new Error( + `Custom ${type} (${descriptor}) does not export a function/class` + ) + } + }, - if (typeof CustomFormatter === 'function') { - return CustomFormatter + resolveConstructor(ImportedCode: any) { + if (typeof ImportedCode === 'function') { + return ImportedCode } else if ( - doesHaveValue(CustomFormatter) && - typeof CustomFormatter.default === 'function' + doesHaveValue(ImportedCode) && + typeof ImportedCode.default === 'function' ) { - return CustomFormatter.default + return ImportedCode.default } - throw new Error( - `Custom formatter (${customFormatterPath}) does not export a function` - ) + return null }, } diff --git a/src/formatter/get_color_fns.ts b/src/formatter/get_color_fns.ts index d7f783c51..d92ebafc3 100644 --- a/src/formatter/get_color_fns.ts +++ b/src/formatter/get_color_fns.ts @@ -1,44 +1,50 @@ -import _ from 'lodash' -import colors from 'colors/safe' -import Status from '../status' -import { messages } from '@cucumber/messages' - -colors.enable() +import chalk from 'chalk' +import { TestStepResultStatus } from '@cucumber/messages' export type IColorFn = (text: string) => string export interface IColorFns { - forStatus: ( - status: messages.TestStepFinished.TestStepResult.Status - ) => IColorFn + forStatus: (status: TestStepResultStatus) => IColorFn location: IColorFn tag: IColorFn + diffAdded: IColorFn + diffRemoved: IColorFn + errorMessage: IColorFn + errorStack: IColorFn } export default function getColorFns(enabled: boolean): IColorFns { if (enabled) { return { - forStatus(status: messages.TestStepFinished.TestStepResult.Status) { + forStatus(status: TestStepResultStatus) { return { - [Status.AMBIGUOUS]: colors.red.bind(colors), - [Status.FAILED]: colors.red.bind(colors), - [Status.PASSED]: colors.green.bind(colors), - [Status.PENDING]: colors.yellow.bind(colors), - [Status.SKIPPED]: colors.cyan.bind(colors), - [Status.UNDEFINED]: colors.yellow.bind(colors), - [Status.UNKNOWN]: colors.yellow.bind(colors), + AMBIGUOUS: chalk.red.bind(chalk), + FAILED: chalk.red.bind(chalk), + PASSED: chalk.green.bind(chalk), + PENDING: chalk.yellow.bind(chalk), + SKIPPED: chalk.cyan.bind(chalk), + UNDEFINED: chalk.yellow.bind(chalk), + UNKNOWN: chalk.yellow.bind(chalk), }[status] }, - location: colors.gray.bind(colors), - tag: colors.cyan.bind(colors), + location: chalk.gray.bind(chalk), + tag: chalk.cyan.bind(chalk), + diffAdded: chalk.green.bind(chalk), + diffRemoved: chalk.red.bind(chalk), + errorMessage: chalk.red.bind(chalk), + errorStack: chalk.grey.bind(chalk), } } else { return { - forStatus(status: messages.TestStepFinished.TestStepResult.Status) { - return _.identity + forStatus(status: TestStepResultStatus) { + return (x) => x }, - location: _.identity, - tag: _.identity, + location: (x) => x, + tag: (x) => x, + diffAdded: (x) => x, + diffRemoved: (x) => x, + errorMessage: (x) => x, + errorStack: (x) => x, } } } diff --git a/src/formatter/helpers/event_data_collector.ts b/src/formatter/helpers/event_data_collector.ts index c9af1aa3d..d976d1417 100644 --- a/src/formatter/helpers/event_data_collector.ts +++ b/src/formatter/helpers/event_data_collector.ts @@ -1,49 +1,48 @@ -import _, { values } from 'lodash' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { doesHaveValue, doesNotHaveValue } from '../../value_checker' import { EventEmitter } from 'events' -import { Query } from '@cucumber/query' interface ITestCaseAttemptData { attempt: number + willBeRetried: boolean testCaseId: string - stepAttachments: Record - stepResults: Record - worstTestStepResult: messages.TestStepFinished.ITestStepResult + stepAttachments: Record + stepResults: Record + worstTestStepResult: messages.TestStepResult } export interface ITestCaseAttempt { attempt: number - gherkinDocument: messages.IGherkinDocument - pickle: messages.IPickle - stepAttachments: Record - stepResults: Record - testCase: messages.ITestCase - worstTestStepResult: messages.TestStepFinished.ITestStepResult + willBeRetried: boolean + gherkinDocument: messages.GherkinDocument + pickle: messages.Pickle + stepAttachments: Record + stepResults: Record + testCase: messages.TestCase + worstTestStepResult: messages.TestStepResult } export default class EventDataCollector { - private gherkinDocumentMap: Record = {} - private pickleMap: Record = {} - private testCaseMap: Record = {} + private gherkinDocumentMap: Record = {} + private pickleMap: Record = {} + private testCaseMap: Record = {} private testCaseAttemptDataMap: Record = {} - readonly undefinedParameterTypes: messages.IUndefinedParameterType[] = [] - readonly query = new Query() + readonly undefinedParameterTypes: messages.UndefinedParameterType[] = [] constructor(eventBroadcaster: EventEmitter) { eventBroadcaster.on('envelope', this.parseEnvelope.bind(this)) } - getGherkinDocument(uri: string): messages.IGherkinDocument { + getGherkinDocument(uri: string): messages.GherkinDocument { return this.gherkinDocumentMap[uri] } - getPickle(pickleId: string): messages.IPickle { + getPickle(pickleId: string): messages.Pickle { return this.pickleMap[pickleId] } getTestCaseAttempts(): ITestCaseAttempt[] { - return _.keys(this.testCaseAttemptDataMap).map((testCaseStartedId) => { + return Object.keys(this.testCaseAttemptDataMap).map((testCaseStartedId) => { return this.getTestCaseAttempt(testCaseStartedId) }) } @@ -57,6 +56,7 @@ export default class EventDataCollector { pickle, testCase, attempt: testCaseAttemptData.attempt, + willBeRetried: testCaseAttemptData.willBeRetried, stepAttachments: testCaseAttemptData.stepAttachments, stepResults: testCaseAttemptData.stepResults, worstTestStepResult: testCaseAttemptData.worstTestStepResult, @@ -64,7 +64,6 @@ export default class EventDataCollector { } parseEnvelope(envelope: messages.Envelope): void { - this.query.update(envelope) if (doesHaveValue(envelope.gherkinDocument)) { this.gherkinDocumentMap[envelope.gherkinDocument.uri] = envelope.gherkinDocument @@ -85,28 +84,29 @@ export default class EventDataCollector { } } - initTestCaseAttempt(testCaseStarted: messages.ITestCaseStarted): void { + private initTestCaseAttempt(testCaseStarted: messages.TestCaseStarted): void { this.testCaseAttemptDataMap[testCaseStarted.id] = { attempt: testCaseStarted.attempt, + willBeRetried: false, testCaseId: testCaseStarted.testCaseId, stepAttachments: {}, stepResults: {}, - worstTestStepResult: {}, + worstTestStepResult: { + duration: { seconds: 0, nanos: 0 }, + status: messages.TestStepResultStatus.UNKNOWN, + }, } } - storeAttachment({ - testCaseStartedId, - testStepId, - body, - mediaType, - }: messages.IAttachment): void { + storeAttachment(attachment: messages.Attachment): void { + const { testCaseStartedId, testStepId } = attachment + // TODO: we shouldn't have to check if these properties have values - they are non-nullable if (doesHaveValue(testCaseStartedId) && doesHaveValue(testStepId)) { const { stepAttachments } = this.testCaseAttemptDataMap[testCaseStartedId] if (doesNotHaveValue(stepAttachments[testStepId])) { stepAttachments[testStepId] = [] } - stepAttachments[testStepId].push({ body, mediaType }) + stepAttachments[testStepId].push(attachment) } } @@ -114,18 +114,20 @@ export default class EventDataCollector { testCaseStartedId, testStepId, testStepResult, - }: messages.ITestStepFinished): void { - this.testCaseAttemptDataMap[testCaseStartedId].stepResults[ - testStepId - ] = testStepResult + }: messages.TestStepFinished): void { + this.testCaseAttemptDataMap[testCaseStartedId].stepResults[testStepId] = + testStepResult } - storeTestCaseResult({ testCaseStartedId }: messages.ITestCaseFinished): void { - const stepResults = values( + storeTestCaseResult({ + testCaseStartedId, + willBeRetried, + }: messages.TestCaseFinished): void { + const stepResults = Object.values( this.testCaseAttemptDataMap[testCaseStartedId].stepResults ) - this.testCaseAttemptDataMap[ - testCaseStartedId - ].worstTestStepResult = this.query.getWorstTestStepResult(stepResults) + this.testCaseAttemptDataMap[testCaseStartedId].worstTestStepResult = + messages.getWorstTestStepResult(stepResults) + this.testCaseAttemptDataMap[testCaseStartedId].willBeRetried = willBeRetried } } diff --git a/src/formatter/helpers/formatters.ts b/src/formatter/helpers/formatters.ts new file mode 100644 index 000000000..d5a2698f5 --- /dev/null +++ b/src/formatter/helpers/formatters.ts @@ -0,0 +1,39 @@ +import Formatter from '../.' +import JsonFormatter from '../json_formatter' +import MessageFormatter from '../message_formatter' +import ProgressBarFormatter from '../progress_bar_formatter' +import ProgressFormatter from '../progress_formatter' +import RerunFormatter from '../rerun_formatter' +import SnippetsFormatter from '../snippets_formatter' +import SummaryFormatter from '../summary_formatter' +import UsageFormatter from '../usage_formatter' +import UsageJsonFormatter from '../usage_json_formatter' +import HtmlFormatter from '../html_formatter' + +const Formatters = { + getFormatters(): Record { + return { + json: JsonFormatter, + message: MessageFormatter, + html: HtmlFormatter, + progress: ProgressFormatter, + 'progress-bar': ProgressBarFormatter, + rerun: RerunFormatter, + snippets: SnippetsFormatter, + summary: SummaryFormatter, + usage: UsageFormatter, + 'usage-json': UsageJsonFormatter, + } + }, + buildFormattersDocumentationString(): string { + let concatanatedFormattersDocumentation: string = '' + const formatters = this.getFormatters() + for (const formatterName in formatters) { + concatanatedFormattersDocumentation += ` ${formatterName}: ${formatters[formatterName].documentation}\n` + } + + return concatanatedFormattersDocumentation + }, +} + +export default Formatters diff --git a/src/formatter/helpers/gherkin_document_parser.ts b/src/formatter/helpers/gherkin_document_parser.ts index 72624edf9..8b4763181 100644 --- a/src/formatter/helpers/gherkin_document_parser.ts +++ b/src/formatter/helpers/gherkin_document_parser.ts @@ -1,26 +1,22 @@ -import _ from 'lodash' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { doesHaveValue } from '../../value_checker' export function getGherkinStepMap( - gherkinDocument: messages.IGherkinDocument -): Record { - return _.chain(gherkinDocument.feature.children) + gherkinDocument: messages.GherkinDocument +): Record { + const result: Record = {} + gherkinDocument.feature.children .map(extractStepContainers) - .flatten() - .map('steps') - .flatten() - .map((step: messages.GherkinDocument.Feature.IStep) => [step.id, step]) - .fromPairs() - .value() + .flat() + .forEach((x) => + x.steps.forEach((step: messages.Step) => (result[step.id] = step)) + ) + return result } function extractStepContainers( - child: messages.GherkinDocument.Feature.IFeatureChild -): Array< - | messages.GherkinDocument.Feature.IScenario - | messages.GherkinDocument.Feature.IBackground -> { + child: messages.FeatureChild +): Array { if (doesHaveValue(child.background)) { return [child.background] } else if (doesHaveValue(child.rule)) { @@ -34,63 +30,55 @@ function extractStepContainers( } export function getGherkinScenarioMap( - gherkinDocument: messages.IGherkinDocument -): Record { - return _.chain(gherkinDocument.feature.children) - .map((child: messages.GherkinDocument.Feature.IFeatureChild) => { + gherkinDocument: messages.GherkinDocument +): Record { + const result: Record = {} + gherkinDocument.feature.children + .map((child: messages.FeatureChild) => { if (doesHaveValue(child.rule)) { return child.rule.children } return [child] }) - .flatten() - .filter('scenario') - .map('scenario') - .map((scenario: messages.GherkinDocument.Feature.IScenario) => [ - scenario.id, - scenario, - ]) - .fromPairs() - .value() + .flat() + .forEach((x) => { + if (x.scenario != null) { + result[x.scenario.id] = x.scenario + } + }) + return result } export function getGherkinExampleRuleMap( - gherkinDocument: messages.IGherkinDocument -): Record { - return _.chain(gherkinDocument.feature.children) - .filter('rule') - .map('rule') - .map((rule) => { - return rule.children + gherkinDocument: messages.GherkinDocument +): Record { + const result: Record = {} + gherkinDocument.feature.children + .filter((x) => x.rule != null) + .forEach((x) => + x.rule.children .filter((child) => doesHaveValue(child.scenario)) - .map((child) => [child.scenario.id, rule]) - }) - .flatten() - .fromPairs() - .value() + .forEach((child) => (result[child.scenario.id] = x.rule)) + ) + return result } export function getGherkinScenarioLocationMap( - gherkinDocument: messages.IGherkinDocument -): Record { - const locationMap: Record = {} - const scenarioMap: Record< - string, - messages.GherkinDocument.Feature.IScenario - > = getGherkinScenarioMap(gherkinDocument) - _.entries(scenarioMap).forEach( - ([id, scenario]) => { - locationMap[id] = scenario.location - if (doesHaveValue(scenario.examples)) { - _.chain(scenario.examples) - .map('tableBody') - .flatten() - .forEach((tableRow) => { - locationMap[tableRow.id] = tableRow.location - }) - .value() - } + gherkinDocument: messages.GherkinDocument +): Record { + const locationMap: Record = {} + const scenarioMap: Record = + getGherkinScenarioMap(gherkinDocument) + Object.keys(scenarioMap).forEach((id) => { + const scenario = scenarioMap[id] + locationMap[id] = scenario.location + if (doesHaveValue(scenario.examples)) { + scenario.examples.forEach((x) => + x.tableBody.forEach( + (tableRow) => (locationMap[tableRow.id] = tableRow.location) + ) + ) } - ) + }) return locationMap } diff --git a/src/formatter/helpers/gherkin_document_parser_spec.ts b/src/formatter/helpers/gherkin_document_parser_spec.ts index 584743c22..8bea18ee7 100644 --- a/src/formatter/helpers/gherkin_document_parser_spec.ts +++ b/src/formatter/helpers/gherkin_document_parser_spec.ts @@ -10,8 +10,9 @@ import { IParsedSourceWithEnvelopes, parse, } from '../../../test/gherkin_helpers' -import { messages } from '@cucumber/messages' -import IGherkinDocument = messages.IGherkinDocument +import * as messages from '@cucumber/messages' +import IGherkinDocument = messages.GherkinDocument +import { reindent } from 'reindent-template-literals' describe('GherkinDocumentParser', () => { describe('getGherkinStepMap', () => { @@ -78,7 +79,8 @@ describe('GherkinDocumentParser', () => { it('works for a Background and Rule with its own Background and Examples', async () => { // Arrange - const gherkinDocument = await withBackgroundAndRuleWithBackgroundAndExamples() + const gherkinDocument = + await withBackgroundAndRuleWithBackgroundAndExamples() // Act const output = getGherkinStepMap(gherkinDocument) @@ -156,7 +158,8 @@ describe('GherkinDocumentParser', () => { it('works for a Background and Rule with its own Background and Examples', async () => { // Arrange - const gherkinDocument = await withBackgroundAndRuleWithBackgroundAndExamples() + const gherkinDocument = + await withBackgroundAndRuleWithBackgroundAndExamples() // Act const output = getGherkinScenarioMap(gherkinDocument) @@ -215,7 +218,8 @@ describe('GherkinDocumentParser', () => { it('works for a Background and Rule with its own Background and Examples', async () => { // Arrange - const gherkinDocument = await withBackgroundAndRuleWithBackgroundAndExamples() + const gherkinDocument = + await withBackgroundAndRuleWithBackgroundAndExamples() // Act const output = await getGherkinExampleRuleMap(gherkinDocument) @@ -284,7 +288,8 @@ describe('GherkinDocumentParser', () => { it('works for a Background and Rule with its own Background and Examples', async () => { // Arrange - const gherkinDocument = await withBackgroundAndRuleWithBackgroundAndExamples() + const gherkinDocument = + await withBackgroundAndRuleWithBackgroundAndExamples() // Act const output = await getGherkinScenarioLocationMap(gherkinDocument) @@ -311,64 +316,72 @@ async function parseGherkinDocument(data: string): Promise { } async function withBackgroundAndScenario(): Promise { - return await parseGherkinDocument(`\ -Feature: a feature - Background: - Given a setup step - - Scenario: - When a regular step -`) + return await parseGherkinDocument( + reindent(` + Feature: a feature + Background: + Given a setup step + + Scenario: + When a regular step + `) + ) } async function withBackgroundAndScenarioOutline(): Promise { - return await parseGherkinDocument(`\ -Feature: a feature - Background: - Given a setup step - - Scenario Outline: - When a templated step with - Examples: - | word | - | foo | - | bar | -`) + return await parseGherkinDocument( + reindent(` + Feature: a feature + Background: + Given a setup step + + Scenario Outline: + When a templated step with + Examples: + | word | + | foo | + | bar | + `) + ) } async function withBackgroundAndRuleWithExamples(): Promise { - return await parseGherkinDocument(`\ -Feature: a feature - Background: - Given a setup step - - Rule: a rule - Example: an example - When a regular step - Then an assertion - - Example: another example - When a regular step - Then an assertion -`) + return await parseGherkinDocument( + reindent(` + Feature: a feature + Background: + Given a setup step + + Rule: a rule + Example: an example + When a regular step + Then an assertion + + Example: another example + When a regular step + Then an assertion + `) + ) } async function withBackgroundAndRuleWithBackgroundAndExamples(): Promise { - return await parseGherkinDocument(`\ -Feature: a feature - Background: - Given a feature-level setup step - - Rule: a rule - Background: - Given a rule-level setup step - - Example: an example - When a regular step - Then an assertion - - Example: another example - When a regular step - Then an assertion -`) + return await parseGherkinDocument( + reindent(` + Feature: a feature + Background: + Given a feature-level setup step + + Rule: a rule + Background: + Given a rule-level setup step + + Example: an example + When a regular step + Then an assertion + + Example: another example + When a regular step + Then an assertion + `) + ) } diff --git a/src/formatter/helpers/issue_helpers.ts b/src/formatter/helpers/issue_helpers.ts index b2610c741..02fa6f419 100644 --- a/src/formatter/helpers/issue_helpers.ts +++ b/src/formatter/helpers/issue_helpers.ts @@ -1,34 +1,32 @@ import indentString from 'indent-string' -import Status from '../../status' import { formatTestCaseAttempt } from './test_case_attempt_formatter' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { IColorFns } from '../get_color_fns' import StepDefinitionSnippetBuilder from '../step_definition_snippet_builder' import { ISupportCodeLibrary } from '../../support_code_library_builder/types' import { ITestCaseAttempt } from './event_data_collector' export function isFailure( - result: messages.TestStepFinished.ITestStepResult + result: messages.TestStepResult, + willBeRetried: boolean = false ): boolean { return ( - result.status === Status.AMBIGUOUS || - result.status === Status.UNDEFINED || - (result.status === Status.FAILED && !result.willBeRetried) + result.status === 'AMBIGUOUS' || + result.status === 'UNDEFINED' || + (result.status === 'FAILED' && !willBeRetried) ) } export function isWarning( - result: messages.TestStepFinished.ITestStepResult + result: messages.TestStepResult, + willBeRetried: boolean = false ): boolean { return ( - result.status === Status.PENDING || - (result.status === Status.FAILED && result.willBeRetried) + result.status === 'PENDING' || (result.status === 'FAILED' && willBeRetried) ) } -export function isIssue( - result: messages.TestStepFinished.ITestStepResult -): boolean { +export function isIssue(result: messages.TestStepResult): boolean { return isFailure(result) || isWarning(result) } @@ -68,10 +66,10 @@ export function formatIssue({ } export function formatUndefinedParameterTypes( - undefinedParameterTypes: messages.IUndefinedParameterType[] + undefinedParameterTypes: messages.UndefinedParameterType[] ): string { const output = [`Undefined parameter types:\n\n`] - const withLatest: Record = {} + const withLatest: Record = {} undefinedParameterTypes.forEach((parameterType) => { withLatest[parameterType.name] = parameterType }) @@ -87,7 +85,7 @@ export function formatUndefinedParameterTypes( } export function formatUndefinedParameterType( - parameterType: messages.IUndefinedParameterType + parameterType: messages.UndefinedParameterType ): string { return `"${parameterType.name}" e.g. \`${parameterType.expression}\`` } diff --git a/src/formatter/helpers/issue_helpers_spec.ts b/src/formatter/helpers/issue_helpers_spec.ts index ddae29f74..f60cfed10 100644 --- a/src/formatter/helpers/issue_helpers_spec.ts +++ b/src/formatter/helpers/issue_helpers_spec.ts @@ -4,6 +4,7 @@ import getColorFns from '../get_color_fns' import { formatIssue } from './issue_helpers' import figures from 'figures' import { getTestCaseAttempts } from '../../../test/formatter_helpers' +import { reindent } from 'reindent-template-literals' import { getBaseSupportCodeLibrary } from '../../../test/fixtures/steps' import FormatterBuilder from '../builder' @@ -11,7 +12,7 @@ async function testFormatIssue(sourceData: string): Promise { const sources = [ { data: sourceData, - uri: 'project/a.feature', + uri: 'a.feature', }, ] const supportCodeLibrary = getBaseSupportCodeLibrary() @@ -23,7 +24,7 @@ async function testFormatIssue(sourceData: string): Promise { cwd: 'project/', colorFns: getColorFns(false), number: 1, - snippetBuilder: FormatterBuilder.getStepDefinitionSnippetBuilder({ + snippetBuilder: await FormatterBuilder.getStepDefinitionSnippetBuilder({ cwd: 'project/', supportCodeLibrary, }), @@ -37,211 +38,233 @@ describe('IssueHelpers', () => { describe('with a failed step', () => { it('prints the scenario', async () => { // Arrange - const sourceData = `\ -Feature: my feature - Scenario: my scenario - Given a passing step - When a failing step - Then a passing step -` + const sourceData = reindent(` + Feature: my feature + Scenario: my scenario + Given a passing step + When a failing step + Then a passing step + `) // Act const output = await testFormatIssue(sourceData) // Assert - expect(output).to.eql(`\ -1) Scenario: my scenario # a.feature:2 - ${figures.tick} Given a passing step # steps.ts:29 - ${figures.cross} When a failing step # steps.ts:9 - error - - Then a passing step # steps.ts:29 - -`) + expect(output).to.eql( + reindent(` + 1) Scenario: my scenario # a.feature:2 + ${figures.tick} Given a passing step # steps.ts:29 + ${figures.cross} When a failing step # steps.ts:9 + error + - Then a passing step # steps.ts:29 + + + `) + ) }) }) describe('with an ambiguous step', () => { it('returns the formatted scenario', async () => { // Arrange - const sourceData = `\ -Feature: my feature - Scenario: my scenario - Given a passing step - When an ambiguous step - Then a passing step -` + const sourceData = reindent(` + Feature: my feature + Scenario: my scenario + Given a passing step + When an ambiguous step + Then a passing step + `) // Act const output = await testFormatIssue(sourceData) // Assert - expect(output).to.eql(`\ -1) Scenario: my scenario # a.feature:2 - ${figures.tick} Given a passing step # steps.ts:29 - ${figures.cross} When an ambiguous step - Multiple step definitions match: - an ambiguous step - steps.ts:13 - /an? ambiguous step/ - steps.ts:14 - - Then a passing step # steps.ts:29 - -`) + expect(output).to.eql( + reindent(` + 1) Scenario: my scenario # a.feature:2 + ${figures.tick} Given a passing step # steps.ts:29 + ${figures.cross} When an ambiguous step + Multiple step definitions match: + an ambiguous step - steps.ts:13 + /an? ambiguous step/ - steps.ts:14 + - Then a passing step # steps.ts:29 + + + `) + ) }) }) describe('with an undefined step', () => { it('returns the formatted scenario', async () => { // Arrange - const sourceData = `\ -Feature: my feature - Scenario: my scenario - Given a passing step - When an undefined step - Then a passing step -` + const sourceData = reindent(` + Feature: my feature + Scenario: my scenario + Given a passing step + When an undefined step + Then a passing step + `) // Act const output = await testFormatIssue(sourceData) // Assert - expect(output).to.eql(`\ -1) Scenario: my scenario # a.feature:2 - ${figures.tick} Given a passing step # steps.ts:29 - ? When an undefined step - Undefined. Implement with the following snippet: + expect(output).to.eql( + reindent(` + 1) Scenario: my scenario # a.feature:2 + ${figures.tick} Given a passing step # steps.ts:29 + ? When an undefined step + Undefined. Implement with the following snippet: + + When('an undefined step', function () { + // Write code here that turns the phrase above into concrete actions + return 'pending'; + }); - When('an undefined step', function () { - // Write code here that turns the phrase above into concrete actions - return 'pending'; - }); + - Then a passing step # steps.ts:29 - - Then a passing step # steps.ts:29 -`) + `) + ) }) }) describe('with a pending step', () => { it('returns the formatted scenario', async () => { // Arrange - const sourceData = `\ -Feature: my feature - Scenario: my scenario - Given a passing step - When a pending step - Then a passing step -` + const sourceData = reindent(` + Feature: my feature + Scenario: my scenario + Given a passing step + When a pending step + Then a passing step + `) // Act const output = await testFormatIssue(sourceData) // Assert - expect(output).to.eql(`\ -1) Scenario: my scenario # a.feature:2 - ${figures.tick} Given a passing step # steps.ts:29 - ? When a pending step # steps.ts:16 - Pending - - Then a passing step # steps.ts:29 - -`) + expect(output).to.eql( + reindent(` + 1) Scenario: my scenario # a.feature:2 + ${figures.tick} Given a passing step # steps.ts:29 + ? When a pending step # steps.ts:16 + Pending + - Then a passing step # steps.ts:29 + + + `) + ) }) }) describe('step with data table', () => { it('returns the formatted scenario', async () => { // Arrange - const sourceData = `\ -Feature: my feature - Scenario: my scenario - Given a passing step - When a pending step - Then a passing step - |aaa|b|c| - |d|e|ff| - |gg|h|iii| -` + const sourceData = reindent(` + Feature: my feature + Scenario: my scenario + Given a passing step + When a pending step + Then a passing step + |aaa|b|c| + |d|e|ff| + |gg|h|iii| + `) // Act const output = await testFormatIssue(sourceData) // Assert - expect(output).to.eql(`\ -1) Scenario: my scenario # a.feature:2 - ${figures.tick} Given a passing step # steps.ts:29 - ? When a pending step # steps.ts:16 - Pending - - Then a passing step # steps.ts:29 - | aaa | b | c | - | d | e | ff | - | gg | h | iii | - -`) + expect(output).to.eql( + reindent(` + 1) Scenario: my scenario # a.feature:2 + ${figures.tick} Given a passing step # steps.ts:29 + ? When a pending step # steps.ts:16 + Pending + - Then a passing step # steps.ts:29 + | aaa | b | c | + | d | e | ff | + | gg | h | iii | + + + `) + ) }) }) describe('step with doc string', () => { it('returns the formatted scenario', async () => { // Arrange - const sourceData = `\ -Feature: my feature - Scenario: my scenario - Given a passing step - When a pending step - Then a passing step - """ - this is a multiline - doc string - - :-) - """ -` + const sourceData = reindent(` + Feature: my feature + Scenario: my scenario + Given a passing step + When a pending step + Then a passing step + """ + this is a multiline + doc string + + :-) + """ + `) // Act const output = await testFormatIssue(sourceData) // Assert - expect(output).to.eql(`\ -1) Scenario: my scenario # a.feature:2 - ${figures.tick} Given a passing step # steps.ts:29 - ? When a pending step # steps.ts:16 - Pending - - Then a passing step # steps.ts:29 - """ - this is a multiline - doc string - - :-) - """ - -`) + expect(output).to.eql( + reindent(` + 1) Scenario: my scenario # a.feature:2 + ${figures.tick} Given a passing step # steps.ts:29 + ? When a pending step # steps.ts:16 + Pending + - Then a passing step # steps.ts:29 + """ + this is a multiline + doc string + + :-) + """ + + + `) + ) }) }) describe('step with attachment text', () => { it('prints the scenario', async () => { // Arrange - const sourceData = `\ -Feature: my feature - Scenario: my scenario - Given attachment step1 - When attachment step2 - Then a passing step -` + const sourceData = reindent(` + Feature: my feature + Scenario: my scenario + Given attachment step1 + When attachment step2 + Then a passing step + `) + // Act const output = await testFormatIssue(sourceData) // Assert - expect(output).to.eql(`\ -1) Scenario: my scenario # a.feature:2 - ${figures.tick} Given attachment step1 # steps.ts:35 - Attachment (text/plain): Some info - Attachment (application/json) - Attachment (image/png) - ${figures.cross} When attachment step2 # steps.ts:41 - Attachment (text/plain): Other info - error - - Then a passing step # steps.ts:29 - -`) + expect(output).to.eql( + reindent(` + 1) Scenario: my scenario # a.feature:2 + ${figures.tick} Given attachment step1 # steps.ts:35 + Attachment (text/plain): Some info + Attachment (application/json) + Attachment (image/png) + ${figures.cross} When attachment step2 # steps.ts:41 + Attachment (text/plain): Other info + error + - Then a passing step # steps.ts:29 + + + `) + ) }) }) }) diff --git a/src/formatter/helpers/keyword_type.ts b/src/formatter/helpers/keyword_type.ts index 19be3650e..59be776d0 100644 --- a/src/formatter/helpers/keyword_type.ts +++ b/src/formatter/helpers/keyword_type.ts @@ -1,4 +1,3 @@ -import _ from 'lodash' import { Dialect, dialects } from '@cucumber/gherkin' import { doesHaveValue } from '../../value_checker' @@ -21,7 +20,7 @@ export function getStepKeywordType({ }: IGetStepKeywordTypeOptions): KeywordType { const dialect: Dialect = dialects[language] const stepKeywords = ['given', 'when', 'then', 'and', 'but'] as const - const type = _.find(stepKeywords, (key) => _.includes(dialect[key], keyword)) + const type = stepKeywords.find((key) => dialect[key].includes(keyword)) switch (type) { case 'when': return KeywordType.Event diff --git a/src/formatter/helpers/pickle_parser.ts b/src/formatter/helpers/pickle_parser.ts index cd4b75c32..166ee3144 100644 --- a/src/formatter/helpers/pickle_parser.ts +++ b/src/formatter/helpers/pickle_parser.ts @@ -1,59 +1,54 @@ -import _ from 'lodash' import { getGherkinScenarioLocationMap } from './gherkin_document_parser' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' export interface IGetPickleLocationRequest { - gherkinDocument: messages.IGherkinDocument - pickle: messages.IPickle + gherkinDocument: messages.GherkinDocument + pickle: messages.Pickle } export interface IGetStepKeywordRequest { - pickleStep: messages.Pickle.IPickleStep - gherkinStepMap: Record + pickleStep: messages.PickleStep + gherkinStepMap: Record } export interface IGetScenarioDescriptionRequest { - pickle: messages.IPickle - gherkinScenarioMap: Record + pickle: messages.Pickle + gherkinScenarioMap: Record } export function getScenarioDescription({ pickle, gherkinScenarioMap, }: IGetScenarioDescriptionRequest): string { - return _.chain(pickle.astNodeIds) + return pickle.astNodeIds .map((id) => gherkinScenarioMap[id]) - .compact() - .first() - .value().description + .filter((x) => x != null)[0].description } export function getStepKeyword({ pickleStep, gherkinStepMap, }: IGetStepKeywordRequest): string { - return _.chain(pickleStep.astNodeIds) + return pickleStep.astNodeIds .map((id) => gherkinStepMap[id]) - .compact() - .first() - .value().keyword + .filter((x) => x != null)[0].keyword } export function getPickleStepMap( - pickle: messages.IPickle -): Record { - return _.chain(pickle.steps) - .map((pickleStep) => [pickleStep.id, pickleStep]) - .fromPairs() - .value() + pickle: messages.Pickle +): Record { + const result: Record = {} + pickle.steps.forEach((pickleStep) => (result[pickleStep.id] = pickleStep)) + return result } export function getPickleLocation({ gherkinDocument, pickle, -}: IGetPickleLocationRequest): messages.ILocation { - const gherkinScenarioLocationMap = getGherkinScenarioLocationMap( - gherkinDocument - ) - return gherkinScenarioLocationMap[_.last(pickle.astNodeIds)] +}: IGetPickleLocationRequest): messages.Location { + const gherkinScenarioLocationMap = + getGherkinScenarioLocationMap(gherkinDocument) + return gherkinScenarioLocationMap[ + pickle.astNodeIds[pickle.astNodeIds.length - 1] + ] } diff --git a/src/formatter/helpers/step_argument_formatter.ts b/src/formatter/helpers/step_argument_formatter.ts index 1146e8cbf..7381056cc 100644 --- a/src/formatter/helpers/step_argument_formatter.ts +++ b/src/formatter/helpers/step_argument_formatter.ts @@ -1,10 +1,8 @@ import Table from 'cli-table3' import { parseStepArgument } from '../../step_arguments' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' -function formatDataTable( - dataTable: messages.PickleStepArgument.IPickleTable -): string { +function formatDataTable(dataTable: messages.PickleTable): string { const table = new Table({ chars: { bottom: '', @@ -38,13 +36,11 @@ function formatDataTable( return table.toString() } -function formatDocString( - docString: messages.PickleStepArgument.IPickleDocString -): string { +function formatDocString(docString: messages.PickleDocString): string { return `"""\n${docString.content}\n"""` } -export function formatStepArgument(arg: messages.IPickleStepArgument): string { +export function formatStepArgument(arg: messages.PickleStepArgument): string { return parseStepArgument(arg, { dataTable: formatDataTable, docString: formatDocString, diff --git a/src/formatter/helpers/summary_helpers.ts b/src/formatter/helpers/summary_helpers.ts index c0dc0c3b3..e18bfb9d9 100644 --- a/src/formatter/helpers/summary_helpers.ts +++ b/src/formatter/helpers/summary_helpers.ts @@ -1,24 +1,22 @@ -import _ from 'lodash' import Duration from 'duration' -import Status from '../../status' -import { addDurations, getZeroDuration } from '../../time' import { IColorFns } from '../get_color_fns' import { ITestCaseAttempt } from './event_data_collector' -import { messages, TimeConversion } from '@cucumber/messages' +import * as messages from '@cucumber/messages' +import { doesHaveValue } from '../../value_checker' const STATUS_REPORT_ORDER = [ - Status.FAILED, - Status.AMBIGUOUS, - Status.UNDEFINED, - Status.PENDING, - Status.SKIPPED, - Status.PASSED, + messages.TestStepResultStatus.FAILED, + messages.TestStepResultStatus.AMBIGUOUS, + messages.TestStepResultStatus.UNDEFINED, + messages.TestStepResultStatus.PENDING, + messages.TestStepResultStatus.SKIPPED, + messages.TestStepResultStatus.PASSED, ] export interface IFormatSummaryRequest { colorFns: IColorFns testCaseAttempts: ITestCaseAttempt[] - testRunDuration: messages.IDuration + testRunDuration: messages.Duration } export function formatSummary({ @@ -26,22 +24,27 @@ export function formatSummary({ testCaseAttempts, testRunDuration, }: IFormatSummaryRequest): string { - const testCaseResults: messages.TestStepFinished.ITestStepResult[] = [] - const testStepResults: messages.TestStepFinished.ITestStepResult[] = [] - let totalStepDuration = getZeroDuration() - testCaseAttempts.forEach(({ testCase, worstTestStepResult, stepResults }) => { - Object.values(stepResults).forEach((stepResult) => { - totalStepDuration = addDurations(totalStepDuration, stepResult.duration) - }) - if (!worstTestStepResult.willBeRetried) { - testCaseResults.push(worstTestStepResult) - _.each(testCase.testSteps, (testStep) => { - if (testStep.pickleStepId !== '') { - testStepResults.push(stepResults[testStep.id]) - } + const testCaseResults: messages.TestStepResult[] = [] + const testStepResults: messages.TestStepResult[] = [] + let totalStepDuration = messages.TimeConversion.millisecondsToDuration(0) + testCaseAttempts.forEach( + ({ testCase, willBeRetried, worstTestStepResult, stepResults }) => { + Object.values(stepResults).forEach((stepResult) => { + totalStepDuration = messages.TimeConversion.addDurations( + totalStepDuration, + stepResult.duration + ) }) + if (!willBeRetried) { + testCaseResults.push(worstTestStepResult) + testCase.testSteps.forEach((testStep) => { + if (doesHaveValue(testStep.pickleStepId)) { + testStepResults.push(stepResults[testStep.id]) + } + }) + } } - }) + ) const scenarioSummary = getCountSummary({ colorFns, objects: testCaseResults, @@ -60,7 +63,7 @@ export function formatSummary({ interface IGetCountSummaryRequest { colorFns: IColorFns - objects: messages.TestStepFinished.ITestStepResult[] + objects: messages.TestStepResult[] type: string } @@ -69,8 +72,10 @@ function getCountSummary({ objects, type, }: IGetCountSummaryRequest): string { - const counts = _.chain(objects).groupBy('status').mapValues('length').value() - const total = _.chain(counts).values().sum().value() + const counts: Record = {} + STATUS_REPORT_ORDER.forEach((x) => (counts[x] = 0)) + objects.forEach((x) => (counts[x.status] += 1)) + const total = Object.values(counts).reduce((acc, x) => acc + x, 0) let text = `${total.toString()} ${type}${total === 1 ? '' : 's'}` if (total > 0) { const details: string[] = [] @@ -78,7 +83,7 @@ function getCountSummary({ if (counts[status] > 0) { details.push( colorFns.forStatus(status)( - `${counts[status].toString()} ${Status[status].toLowerCase()}` + `${counts[status].toString()} ${status.toLowerCase()}` ) ) } @@ -88,9 +93,11 @@ function getCountSummary({ return text } -function getDurationSummary(durationMsg: messages.IDuration): string { +function getDurationSummary(durationMsg: messages.Duration): string { const start = new Date(0) - const end = new Date(TimeConversion.durationToMilliseconds(durationMsg)) + const end = new Date( + messages.TimeConversion.durationToMilliseconds(durationMsg) + ) const duration = new Duration(start, end) // Use spaces in toString method for readability and to avoid %Ls which is a format return duration.toString('%Ms m %S . %L s').replace(/ /g, '') diff --git a/src/formatter/helpers/summary_helpers_spec.ts b/src/formatter/helpers/summary_helpers_spec.ts index 79c6957b3..bc3dba4be 100644 --- a/src/formatter/helpers/summary_helpers_spec.ts +++ b/src/formatter/helpers/summary_helpers_spec.ts @@ -10,14 +10,14 @@ import { buildSupportCodeLibrary } from '../../../test/runtime_helpers' import { IRuntimeOptions } from '../../runtime' import { ISupportCodeLibrary } from '../../support_code_library_builder/types' import { doesNotHaveValue } from '../../value_checker' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' interface ITestFormatSummaryOptions { runtimeOptions?: Partial sourceData: string supportCodeLibrary?: ISupportCodeLibrary - testRunStarted?: messages.ITestRunStarted - testRunFinished?: messages.ITestRunFinished + testRunStarted?: messages.TestRunStarted + testRunFinished?: messages.TestRunFinished } async function testFormatSummary({ @@ -37,20 +37,15 @@ async function testFormatSummary({ supportCodeLibrary = getBaseSupportCodeLibrary() } if (doesNotHaveValue(testRunStarted)) { - testRunStarted = messages.TestRunStarted.fromObject({ - timestamp: { - nanos: 0, - seconds: 0, - }, - }) + testRunStarted = { + timestamp: messages.TimeConversion.millisecondsSinceEpochToTimestamp(0), + } } if (doesNotHaveValue(testRunFinished)) { - testRunFinished = messages.TestRunFinished.fromObject({ - timestamp: { - nanos: 0, - seconds: 0, - }, - }) + testRunFinished = { + timestamp: messages.TimeConversion.millisecondsSinceEpochToTimestamp(0), + success: true, + } } const testCaseAttempts = await getTestCaseAttempts({ runtimeOptions, @@ -255,18 +250,19 @@ describe('SummaryHelpers', () => { const output = await testFormatSummary({ sourceData, supportCodeLibrary, - testRunStarted: messages.TestRunStarted.fromObject({ + testRunStarted: { timestamp: { nanos: 0, seconds: 3, }, - }), - testRunFinished: messages.TestRunFinished.fromObject({ + }, + testRunFinished: { timestamp: { nanos: 124000000, seconds: 3, }, - }), + success: true, + }, }) // Assert @@ -298,12 +294,13 @@ describe('SummaryHelpers', () => { const output = await testFormatSummary({ sourceData, supportCodeLibrary, - testRunFinished: messages.TestRunFinished.fromObject({ + testRunFinished: { timestamp: { nanos: 400000000, seconds: 12, }, - }), + success: true, + }, }) // Assert @@ -335,12 +332,13 @@ describe('SummaryHelpers', () => { const output = await testFormatSummary({ sourceData, supportCodeLibrary, - testRunFinished: messages.TestRunFinished.fromObject({ + testRunFinished: { timestamp: { nanos: 0, seconds: 124, }, - }), + success: true, + }, }) // Assert @@ -378,12 +376,13 @@ describe('SummaryHelpers', () => { const output = await testFormatSummary({ sourceData, supportCodeLibrary, - testRunFinished: messages.TestRunFinished.fromObject({ + testRunFinished: { timestamp: { nanos: 0, seconds: 24, }, - }), + success: true, + }, }) // Assert diff --git a/src/formatter/helpers/test_case_attempt_formatter.ts b/src/formatter/helpers/test_case_attempt_formatter.ts index bbacf5095..3c67c3cb0 100644 --- a/src/formatter/helpers/test_case_attempt_formatter.ts +++ b/src/formatter/helpers/test_case_attempt_formatter.ts @@ -1,5 +1,5 @@ import indentString from 'indent-string' -import Status from '../../status' +import * as messages from '@cucumber/messages' import figures from 'figures' import { formatLocation } from './location_helpers' import { @@ -13,25 +13,25 @@ import { ITestCaseAttempt } from './event_data_collector' import StepDefinitionSnippetBuilder from '../step_definition_snippet_builder' import { ISupportCodeLibrary } from '../../support_code_library_builder/types' -const CHARACTERS: { [status: number]: string } = { - [Status.AMBIGUOUS]: figures.cross, - [Status.FAILED]: figures.cross, - [Status.PASSED]: figures.tick, - [Status.PENDING]: '?', - [Status.SKIPPED]: '-', - [Status.UNDEFINED]: '?', -} +const CHARACTERS: Map = new Map([ + [messages.TestStepResultStatus.AMBIGUOUS, figures.cross], + [messages.TestStepResultStatus.FAILED, figures.cross], + [messages.TestStepResultStatus.PASSED, figures.tick], + [messages.TestStepResultStatus.PENDING, '?'], + [messages.TestStepResultStatus.SKIPPED, '-'], + [messages.TestStepResultStatus.UNDEFINED, '?'], +]) function getStepMessage(testStep: IParsedTestStep): string { switch (testStep.result.status) { - case Status.AMBIGUOUS: - case Status.FAILED: + case messages.TestStepResultStatus.AMBIGUOUS: + case messages.TestStepResultStatus.FAILED: return testStep.result.message - case Status.UNDEFINED: + case messages.TestStepResultStatus.UNDEFINED: return `${ 'Undefined. Implement with the following snippet:' + '\n\n' }${indentString(testStep.snippet, 2)}\n` - case Status.PENDING: + case messages.TestStepResultStatus.PENDING: return 'Pending' } return '' @@ -50,7 +50,7 @@ function formatStep({ colorFns, testStep }: IFormatStepRequest): string { } = testStep const colorFn = colorFns.forStatus(status) const identifier = testStep.keyword + valueOrDefault(testStep.text, '') - let text = colorFn(`${CHARACTERS[status]} ${identifier}`) + let text = colorFn(`${CHARACTERS.get(status)} ${identifier}`) if (doesHaveValue(actionLocation)) { text += ` # ${colorFns.location(formatLocation(actionLocation))}` } @@ -92,10 +92,7 @@ export function formatTestCaseAttempt({ supportCodeLibrary, }) let text = `Scenario: ${parsed.testCase.name}` - text += getAttemptText( - parsed.testCase.attempt, - parsed.testCase.worstTestStepResult.willBeRetried - ) + text += getAttemptText(parsed.testCase.attempt, testCaseAttempt.willBeRetried) text += ` # ${colorFns.location( formatLocation(parsed.testCase.sourceLocation) )}\n` diff --git a/src/formatter/helpers/test_case_attempt_parser.ts b/src/formatter/helpers/test_case_attempt_parser.ts index 4b5548dc9..886eb75cd 100644 --- a/src/formatter/helpers/test_case_attempt_parser.ts +++ b/src/formatter/helpers/test_case_attempt_parser.ts @@ -1,26 +1,24 @@ -import _ from 'lodash' -import Status from '../../status' import { getStepKeywordType, KeywordType } from './keyword_type' import { getGherkinScenarioLocationMap, getGherkinStepMap, } from './gherkin_document_parser' import { getPickleStepMap, getStepKeyword } from './pickle_parser' -import path from 'path' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { ITestCaseAttempt } from './event_data_collector' import StepDefinitionSnippetBuilder from '../step_definition_snippet_builder' import { ISupportCodeLibrary } from '../../support_code_library_builder/types' import { doesHaveValue, valueOrDefault } from '../../value_checker' import TestCaseHookDefinition from '../../models/test_case_hook_definition' import { ILineAndUri } from '../../types' +import { TestStepResult } from '@cucumber/messages' export interface IParsedTestStep { actionLocation?: ILineAndUri - argument?: messages.IPickleStepArgument - attachments: messages.IAttachment[] + argument?: messages.PickleStepArgument + attachments: messages.Attachment[] keyword: string - result: messages.TestStepFinished.ITestStepResult + result: messages.TestStepResult snippet?: string sourceLocation?: ILineAndUri text?: string @@ -30,7 +28,7 @@ export interface IParsedTestCase { attempt: number name: string sourceLocation?: ILineAndUri - worstTestStepResult: messages.TestStepFinished.ITestStepResult + worstTestStepResult: messages.TestStepResult } export interface IParsedTestCaseAttempt { @@ -40,16 +38,16 @@ export interface IParsedTestCaseAttempt { interface IParseStepRequest { isBeforeHook: boolean - gherkinStepMap: Record + gherkinStepMap: Record keyword: string keywordType: KeywordType - pickleStep: messages.Pickle.IPickleStep + pickleStep: messages.PickleStep pickleUri: string snippetBuilder: StepDefinitionSnippetBuilder supportCodeLibrary: ISupportCodeLibrary - testStep: messages.TestCase.ITestStep - testStepResult: messages.TestStepFinished.ITestStepResult - testStepAttachments: messages.IAttachment[] + testStep: messages.TestStep + testStepResult: messages.TestStepResult + testStepAttachments: messages.Attachment[] } function parseStep({ @@ -67,15 +65,14 @@ function parseStep({ }: IParseStepRequest): IParsedTestStep { const out: IParsedTestStep = { attachments: testStepAttachments, - keyword: - testStep.pickleStepId !== '' - ? keyword - : isBeforeHook - ? 'Before' - : 'After', + keyword: doesHaveValue(testStep.pickleStepId) + ? keyword + : isBeforeHook + ? 'Before' + : 'After', result: testStepResult, } - if (testStep.hookId !== '') { + if (doesHaveValue(testStep.hookId)) { let hookDefinition: TestCaseHookDefinition if (isBeforeHook) { hookDefinition = supportCodeLibrary.beforeTestCaseHookDefinitions.find( @@ -103,7 +100,7 @@ function parseStep({ line: stepDefinition.line, } } - if (testStep.pickleStepId !== '') { + if (doesHaveValue(testStep.pickleStepId)) { out.sourceLocation = { uri: pickleUri, line: gherkinStepMap[pickleStep.astNodeIds[0]].location.line, @@ -113,7 +110,7 @@ function parseStep({ out.argument = pickleStep.argument } } - if (testStepResult.status === Status.UNDEFINED) { + if (testStepResult.status === messages.TestStepResultStatus.UNDEFINED) { out.snippet = snippetBuilder.build({ keywordType, pickleStep }) } return out @@ -136,28 +133,33 @@ export function parseTestCaseAttempt({ }: IParseTestCaseAttemptRequest): IParsedTestCaseAttempt { const { testCase, pickle, gherkinDocument } = testCaseAttempt const gherkinStepMap = getGherkinStepMap(gherkinDocument) - const gherkinScenarioLocationMap = getGherkinScenarioLocationMap( - gherkinDocument - ) + const gherkinScenarioLocationMap = + getGherkinScenarioLocationMap(gherkinDocument) const pickleStepMap = getPickleStepMap(pickle) - const relativePickleUri = path.relative(cwd, pickle.uri) + const relativePickleUri = pickle.uri const parsedTestCase: IParsedTestCase = { attempt: testCaseAttempt.attempt, name: pickle.name, sourceLocation: { uri: relativePickleUri, - line: gherkinScenarioLocationMap[_.last(pickle.astNodeIds)].line, + line: gherkinScenarioLocationMap[ + pickle.astNodeIds[pickle.astNodeIds.length - 1] + ].line, }, worstTestStepResult: testCaseAttempt.worstTestStepResult, } const parsedTestSteps: IParsedTestStep[] = [] let isBeforeHook = true let previousKeywordType = KeywordType.Precondition - _.each(testCase.testSteps, (testStep) => { - const testStepResult = testCaseAttempt.stepResults[testStep.id] - isBeforeHook = isBeforeHook && testStep.hookId !== '' + + testCase.testSteps.forEach((testStep) => { + const testStepResult = + testCaseAttempt.stepResults[testStep.id] || new TestStepResult() + + isBeforeHook = isBeforeHook && doesHaveValue(testStep.hookId) + let keyword, keywordType, pickleStep - if (testStep.pickleStepId !== '') { + if (doesHaveValue(testStep.pickleStepId)) { pickleStep = pickleStepMap[testStep.pickleStepId] keyword = getStepKeyword({ pickleStep, gherkinStepMap }) keywordType = getStepKeywordType({ diff --git a/src/formatter/helpers/test_case_attempt_parser_spec.ts b/src/formatter/helpers/test_case_attempt_parser_spec.ts new file mode 100644 index 000000000..796ddbde4 --- /dev/null +++ b/src/formatter/helpers/test_case_attempt_parser_spec.ts @@ -0,0 +1,81 @@ +import { describe, it } from 'mocha' +import { expect } from 'chai' +import * as messages from '@cucumber/messages' +import { parseTestCaseAttempt } from '.' +import { getBaseSupportCodeLibrary } from '../../../test/fixtures/steps' +import StepDefinitionSnippetBuilder from '../step_definition_snippet_builder' +import { ParameterTypeRegistry } from '@cucumber/cucumber-expressions' +import { reindent } from 'reindent-template-literals' +import { getTestCaseAttempts } from '../../../test/formatter_helpers' + +describe('TestCaseAttemptParser', () => { + describe('parseTestCaseAttempt', () => { + const cwd = '' + const supportCodeLibrary = getBaseSupportCodeLibrary() + const snippetSyntax = { + build: () => 'snippet', + } + + const snippetBuilder = new StepDefinitionSnippetBuilder({ + snippetSyntax, + parameterTypeRegistry: new ParameterTypeRegistry(), + }) + + const source = { + data: reindent(` + Feature: my feature + Scenario: my scenario + Given a passing step + `), + uri: 'a.feature', + } + + describe('with no test step result', () => { + it('initialize step result with status UNKNOWN', async () => { + // Arrange + const [testCaseAttempt] = await getTestCaseAttempts({ + sources: [source], + supportCodeLibrary, + }) + + testCaseAttempt.stepResults = {} + + // Act + const output = parseTestCaseAttempt({ + cwd, + testCaseAttempt, + snippetBuilder, + supportCodeLibrary, + }) + + // Assert + expect(output.testSteps[0].result.status).to.eq( + messages.TestStepResultStatus.UNKNOWN + ) + }) + }) + + describe('with test step result', () => { + it('uses the parsed step result', async () => { + // Arrange + const [testCaseAttempt] = await getTestCaseAttempts({ + sources: [source], + supportCodeLibrary, + }) + + // Act + const output = parseTestCaseAttempt({ + cwd, + testCaseAttempt, + snippetBuilder, + supportCodeLibrary, + }) + + // Assert + expect(output.testSteps[0].result.status).to.eq( + messages.TestStepResultStatus.PASSED + ) + }) + }) + }) +}) diff --git a/src/formatter/helpers/usage_helpers/index.ts b/src/formatter/helpers/usage_helpers/index.ts index 80f9f277d..cfd327948 100644 --- a/src/formatter/helpers/usage_helpers/index.ts +++ b/src/formatter/helpers/usage_helpers/index.ts @@ -1,15 +1,12 @@ -import _ from 'lodash' import { getPickleStepMap } from '../pickle_parser' -import path from 'path' import { getGherkinStepMap } from '../gherkin_document_parser' -import { durationToMilliseconds, millisecondsToDuration } from '../../../time' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import StepDefinition from '../../../models/step_definition' import { doesHaveValue } from '../../../value_checker' import EventDataCollector from '../event_data_collector' export interface IUsageMatch { - duration?: messages.IDuration + duration?: messages.Duration line: number text: string uri: string @@ -19,7 +16,7 @@ export interface IUsage { code: string line: number matches: IUsageMatch[] - meanDuration?: messages.IDuration + meanDuration?: messages.Duration pattern: string patternType: string uri: string @@ -48,18 +45,24 @@ function buildEmptyMapping( return mapping } +const unexecutedStatuses: readonly messages.TestStepResultStatus[] = [ + messages.TestStepResultStatus.AMBIGUOUS, + messages.TestStepResultStatus.SKIPPED, + messages.TestStepResultStatus.UNDEFINED, +] + function buildMapping({ cwd, stepDefinitions, eventDataCollector, }: IGetUsageRequest): Record { const mapping = buildEmptyMapping(stepDefinitions) - _.each(eventDataCollector.getTestCaseAttempts(), (testCaseAttempt) => { + eventDataCollector.getTestCaseAttempts().forEach((testCaseAttempt) => { const pickleStepMap = getPickleStepMap(testCaseAttempt.pickle) const gherkinStepMap = getGherkinStepMap(testCaseAttempt.gherkinDocument) testCaseAttempt.testCase.testSteps.forEach((testStep) => { if ( - testStep.pickleStepId !== '' && + doesHaveValue(testStep.pickleStepId) && testStep.stepDefinitionIds.length === 1 ) { const stepDefinitionId = testStep.stepDefinitionIds[0] @@ -68,17 +71,10 @@ function buildMapping({ const match: IUsageMatch = { line: gherkinStep.location.line, text: pickleStep.text, - uri: path.relative(cwd, testCaseAttempt.pickle.uri), + uri: testCaseAttempt.pickle.uri, } const { duration, status } = testCaseAttempt.stepResults[testStep.id] - if ( - ![ - messages.TestStepFinished.TestStepResult.Status.AMBIGUOUS, - messages.TestStepFinished.TestStepResult.Status.SKIPPED, - messages.TestStepFinished.TestStepResult.Status.UNDEFINED, - ].includes(status) && - doesHaveValue(duration) - ) { + if (!unexecutedStatuses.includes(status) && doesHaveValue(duration)) { match.duration = duration } if (doesHaveValue(mapping[stepDefinitionId])) { @@ -90,36 +86,42 @@ function buildMapping({ return mapping } -function invertDuration(duration: messages.IDuration): number { - if (doesHaveValue(duration)) { - return -1 * durationToMilliseconds(duration) +function normalizeDuration(duration?: messages.Duration): number { + if (duration == null) { + return Number.MIN_SAFE_INTEGER } - return 1 + return messages.TimeConversion.durationToMilliseconds(duration) } function buildResult(mapping: Record): IUsage[] { - return _.chain(mapping) - .map(({ matches, ...rest }: IUsage) => { - const sortedMatches = _.sortBy(matches, [ - (match: IUsageMatch) => invertDuration(match.duration), - 'text', - ]) + return Object.keys(mapping) + .map((stepDefinitionId) => { + const { matches, ...rest } = mapping[stepDefinitionId] + const sortedMatches = matches.sort((a: IUsageMatch, b: IUsageMatch) => { + if (a.duration === b.duration) { + return a.text < b.text ? -1 : 1 + } + return normalizeDuration(b.duration) - normalizeDuration(a.duration) + }) const result = { matches: sortedMatches, ...rest } - const durations: messages.IDuration[] = _.chain(matches) - .map((m: IUsageMatch) => m.duration) - .compact() - .value() + const durations: messages.Duration[] = matches + .filter((m) => m.duration != null) + .map((m) => m.duration) if (durations.length > 0) { - result.meanDuration = millisecondsToDuration( - _.meanBy(durations, (d: messages.IDuration) => - durationToMilliseconds(d) - ) + const totalMilliseconds = durations.reduce( + (acc, x) => acc + messages.TimeConversion.durationToMilliseconds(x), + 0 + ) + result.meanDuration = messages.TimeConversion.millisecondsToDuration( + totalMilliseconds / durations.length ) } return result }) - .sortBy((usage: IUsage) => invertDuration(usage.meanDuration)) - .value() + .sort( + (a: IUsage, b: IUsage) => + normalizeDuration(b.meanDuration) - normalizeDuration(a.meanDuration) + ) } export function getUsage({ diff --git a/src/formatter/helpers/usage_helpers/index_spec.ts b/src/formatter/helpers/usage_helpers/index_spec.ts index b6305dc71..081224a2a 100644 --- a/src/formatter/helpers/usage_helpers/index_spec.ts +++ b/src/formatter/helpers/usage_helpers/index_spec.ts @@ -16,9 +16,8 @@ describe('Usage Helpers', () => { const supportCodeLibrary = buildSupportCodeLibrary(({ Given }) => { Given('a step', code) }) - const { - eventDataCollector, - } = await getEnvelopesAndEventDataCollector({ supportCodeLibrary }) + const { eventDataCollector } = + await getEnvelopesAndEventDataCollector({ supportCodeLibrary }) // Act const output = getUsage({ @@ -53,9 +52,8 @@ describe('Usage Helpers', () => { ) } ) - const { - eventDataCollector, - } = await getEnvelopesAndEventDataCollector({ supportCodeLibrary }) + const { eventDataCollector } = + await getEnvelopesAndEventDataCollector({ supportCodeLibrary }) // Act const output = getUsage({ diff --git a/src/formatter/html_formatter.ts b/src/formatter/html_formatter.ts index af2e2ab62..458e76fae 100644 --- a/src/formatter/html_formatter.ts +++ b/src/formatter/html_formatter.ts @@ -1,5 +1,5 @@ import Formatter, { IFormatterOptions } from '.' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import resolvePkg from 'resolve-pkg' import CucumberHtmlStream from '@cucumber/html-formatter' import { doesHaveValue } from '../value_checker' @@ -8,12 +8,13 @@ import { promisify } from 'util' export default class HtmlFormatter extends Formatter { private readonly _finished: Promise + public static readonly documentation: string = 'Outputs HTML report' constructor(options: IFormatterOptions) { super(options) const cucumberHtmlStream = new CucumberHtmlStream( resolvePkg('@cucumber/html-formatter', { cwd: __dirname }) + - '/dist/cucumber-react.css', + '/dist/main.css', resolvePkg('@cucumber/html-formatter', { cwd: __dirname }) + '/dist/main.js' ) diff --git a/src/formatter/index.ts b/src/formatter/index.ts index 91f77a27c..16ff0ad28 100644 --- a/src/formatter/index.ts +++ b/src/formatter/index.ts @@ -39,6 +39,7 @@ export default class Formatter { protected stream: WritableStream protected supportCodeLibrary: ISupportCodeLibrary private readonly cleanup: IFormatterCleanupFn + static readonly documentation: string constructor(options: IFormatterOptions) { this.colorFns = options.colorFns diff --git a/src/formatter/json_formatter.ts b/src/formatter/json_formatter.ts index f5e752176..cb1396f1a 100644 --- a/src/formatter/json_formatter.ts +++ b/src/formatter/json_formatter.ts @@ -1,10 +1,6 @@ -import _ from 'lodash' import Formatter, { IFormatterOptions } from './' -import Status from '../status' import { formatLocation, GherkinDocumentParser, PickleParser } from './helpers' -import { durationToNanoseconds } from '../time' -import path from 'path' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { getGherkinExampleRuleMap, getGherkinScenarioLocationMap, @@ -12,21 +8,11 @@ import { import { ITestCaseAttempt } from './helpers/event_data_collector' import { doesHaveValue, doesNotHaveValue } from '../value_checker' import { parseStepArgument } from '../step_arguments' -import ITag = messages.GherkinDocument.Feature.ITag -import IFeature = messages.GherkinDocument.IFeature -import IPickle = messages.IPickle -import IScenario = messages.GherkinDocument.Feature.IScenario -import IPickleTag = messages.Pickle.IPickleTag -import IEnvelope = messages.IEnvelope -import IRule = messages.GherkinDocument.Feature.FeatureChild.IRule const { getGherkinStepMap, getGherkinScenarioMap } = GherkinDocumentParser -const { - getScenarioDescription, - getPickleStepMap, - getStepKeyword, -} = PickleParser +const { getScenarioDescription, getPickleStepMap, getStepKeyword } = + PickleParser export interface IJsonFeature { description: string @@ -67,27 +53,27 @@ export interface IJsonTag { } interface IBuildJsonFeatureOptions { - feature: messages.GherkinDocument.IFeature + feature: messages.Feature elements: IJsonScenario[] uri: string } interface IBuildJsonScenarioOptions { - feature: messages.GherkinDocument.IFeature - gherkinScenarioMap: Record - gherkinExampleRuleMap: Record - gherkinScenarioLocationMap: Record - pickle: messages.IPickle + feature: messages.Feature + gherkinScenarioMap: Record + gherkinExampleRuleMap: Record + gherkinScenarioLocationMap: Record + pickle: messages.Pickle steps: IJsonStep[] } interface IBuildJsonStepOptions { isBeforeHook: boolean - gherkinStepMap: Record - pickleStepMap: Record - testStep: messages.TestCase.ITestStep - testStepAttachments: messages.IAttachment[] - testStepResult: messages.TestStepFinished.ITestStepResult + gherkinStepMap: Record + pickleStepMap: Record + testStep: messages.TestStep + testStepAttachments: messages.Attachment[] + testStepResult: messages.TestStepResult } interface UriToTestCaseAttemptsMap { @@ -95,28 +81,33 @@ interface UriToTestCaseAttemptsMap { } export default class JsonFormatter extends Formatter { + public static readonly documentation: string = + 'Prints the feature as JSON. The JSON format is in maintenance mode. Please consider using the message formatter with the standalone json-formatter (https://github.com/cucumber/cucumber/tree/master/json-formatter).' + constructor(options: IFormatterOptions) { super(options) - options.eventBroadcaster.on('envelope', (envelope: IEnvelope) => { + options.eventBroadcaster.on('envelope', (envelope: messages.Envelope) => { if (doesHaveValue(envelope.testRunFinished)) { this.onTestRunFinished() } }) } - convertNameToId(obj: IFeature | IPickle): string { + convertNameToId(obj: messages.Feature | messages.Pickle): string { return obj.name.replace(/ /g, '-').toLowerCase() } - formatDataTable(dataTable: messages.PickleStepArgument.IPickleTable): any { + formatDataTable(dataTable: messages.PickleTable): any { return { - rows: dataTable.rows.map((row) => ({ cells: _.map(row.cells, 'value') })), + rows: dataTable.rows.map((row) => ({ + cells: row.cells.map((x) => x.value), + })), } } formatDocString( - docString: messages.PickleStepArgument.IPickleDocString, - gherkinStep: messages.GherkinDocument.Feature.IStep + docString: messages.PickleDocString, + gherkinStep: messages.Step ): any { return { content: docString.content, @@ -125,8 +116,8 @@ export default class JsonFormatter extends Formatter { } formatStepArgument( - stepArgument: messages.IPickleStepArgument, - gherkinStep: messages.GherkinDocument.Feature.IStep + stepArgument: messages.PickleStepArgument, + gherkinStep: messages.Step ): any { if (doesNotHaveValue(stepArgument)) { return [] @@ -141,32 +132,31 @@ export default class JsonFormatter extends Formatter { onTestRunFinished(): void { const groupedTestCaseAttempts: UriToTestCaseAttemptsMap = {} - _.each( - this.eventDataCollector.getTestCaseAttempts(), - (testCaseAttempt: ITestCaseAttempt) => { - if (!testCaseAttempt.worstTestStepResult.willBeRetried) { - const uri = path.relative(this.cwd, testCaseAttempt.pickle.uri) + this.eventDataCollector + .getTestCaseAttempts() + .forEach((testCaseAttempt: ITestCaseAttempt) => { + if (!testCaseAttempt.willBeRetried) { + const uri = testCaseAttempt.pickle.uri if (doesNotHaveValue(groupedTestCaseAttempts[uri])) { groupedTestCaseAttempts[uri] = [] } groupedTestCaseAttempts[uri].push(testCaseAttempt) } - } - ) - const features = _.map(groupedTestCaseAttempts, (group, uri) => { + }) + const features = Object.keys(groupedTestCaseAttempts).map((uri) => { + const group = groupedTestCaseAttempts[uri] const { gherkinDocument } = group[0] const gherkinStepMap = getGherkinStepMap(gherkinDocument) const gherkinScenarioMap = getGherkinScenarioMap(gherkinDocument) const gherkinExampleRuleMap = getGherkinExampleRuleMap(gherkinDocument) - const gherkinScenarioLocationMap = getGherkinScenarioLocationMap( - gherkinDocument - ) + const gherkinScenarioLocationMap = + getGherkinScenarioLocationMap(gherkinDocument) const elements = group.map((testCaseAttempt: ITestCaseAttempt) => { const { pickle } = testCaseAttempt const pickleStepMap = getPickleStepMap(pickle) let isBeforeHook = true const steps = testCaseAttempt.testCase.testSteps.map((testStep) => { - isBeforeHook = isBeforeHook && testStep.pickleStepId === '' + isBeforeHook = isBeforeHook && !doesHaveValue(testStep.pickleStepId) return this.getStepData({ isBeforeHook, gherkinStepMap, @@ -240,9 +230,9 @@ export default class JsonFormatter extends Formatter { pickle, gherkinExampleRuleMap, }: { - feature: IFeature - pickle: IPickle - gherkinExampleRuleMap: Record + feature: messages.Feature + pickle: messages.Pickle + gherkinExampleRuleMap: Record }): string { let parts: any[] const rule = gherkinExampleRuleMap[pickle.astNodeIds[0]] @@ -263,7 +253,7 @@ export default class JsonFormatter extends Formatter { testStepResult, }: IBuildJsonStepOptions): IJsonStep { const data: IJsonStep = {} - if (testStep.pickleStepId !== '') { + if (doesHaveValue(testStep.pickleStepId)) { const pickleStep = pickleStepMap[testStep.pickleStepId] data.arguments = this.formatStepArgument( pickleStep.argument, @@ -276,21 +266,32 @@ export default class JsonFormatter extends Formatter { data.keyword = isBeforeHook ? 'Before' : 'After' data.hidden = true } - if (testStep.stepDefinitionIds.length === 1) { + if ( + doesHaveValue(testStep.stepDefinitionIds) && + testStep.stepDefinitionIds.length === 1 + ) { const stepDefinition = this.supportCodeLibrary.stepDefinitions.find( (s) => s.id === testStep.stepDefinitionIds[0] ) data.match = { location: formatLocation(stepDefinition) } } const { message, status } = testStepResult - data.result = { status: Status[status].toLowerCase() } + data.result = { + status: messages.TestStepResultStatus[status].toLowerCase(), + } if (doesHaveValue(testStepResult.duration)) { - data.result.duration = durationToNanoseconds(testStepResult.duration) + data.result.duration = + messages.TimeConversion.durationToMilliseconds( + testStepResult.duration + ) * 1000000 } - if (status === Status.FAILED && doesHaveValue(message)) { + if ( + status === messages.TestStepResultStatus.FAILED && + doesHaveValue(message) + ) { data.result.error_message = message } - if (_.size(testStepAttachments) > 0) { + if (testStepAttachments?.length > 0) { data.embeddings = testStepAttachments.map((attachment) => ({ data: attachment.body, mime_type: attachment.mediaType, @@ -299,8 +300,8 @@ export default class JsonFormatter extends Formatter { return data } - getFeatureTags(feature: IFeature): IJsonTag[] { - return _.map(feature.tags, (tagData) => ({ + getFeatureTags(feature: messages.Feature): IJsonTag[] { + return feature.tags.map((tagData) => ({ name: tagData.name, line: tagData.location.line, })) @@ -311,25 +312,29 @@ export default class JsonFormatter extends Formatter { pickle, gherkinScenarioMap, }: { - feature: IFeature - pickle: IPickle - gherkinScenarioMap: Record + feature: messages.Feature + pickle: messages.Pickle + gherkinScenarioMap: Record }): IJsonTag[] { const scenario = gherkinScenarioMap[pickle.astNodeIds[0]] return pickle.tags.map( - (tagData: IPickleTag): IJsonTag => + (tagData: messages.PickleTag): IJsonTag => this.getScenarioTag(tagData, feature, scenario) ) } private getScenarioTag( - tagData: IPickleTag, - feature: IFeature, - scenario: IScenario + tagData: messages.PickleTag, + feature: messages.Feature, + scenario: messages.Scenario ): IJsonTag { - const byAstNodeId = (tag: ITag): Boolean => tag.id === tagData.astNodeId - const flatten = (acc: ITag[], val: ITag[]): ITag[] => acc.concat(val) + const byAstNodeId = (tag: messages.Tag): Boolean => + tag.id === tagData.astNodeId + const flatten = ( + acc: messages.Tag[], + val: messages.Tag[] + ): messages.Tag[] => acc.concat(val) const tag = feature.tags.find(byAstNodeId) || diff --git a/src/formatter/json_formatter_spec.ts b/src/formatter/json_formatter_spec.ts index b2ea144ed..de84daedc 100644 --- a/src/formatter/json_formatter_spec.ts +++ b/src/formatter/json_formatter_spec.ts @@ -228,22 +228,36 @@ describe('JsonFormatter', () => { // Assert const steps = JSON.parse(output)[0].elements[0].steps - expect(steps[0]).to.eql({ + const expectedBefore = { hidden: true, keyword: 'Before', result: { duration: 0, status: 'passed', }, - }) - expect(steps[2]).to.eql({ + } + const expectedAfter = { hidden: true, keyword: 'After', result: { duration: 0, status: 'passed', }, - }) + } + const expectedStep = { + arguments: [] as any[], + keyword: 'Given ', + line: 3, + match: { + location: 'json_formatter_steps.ts:39', + }, + name: 'a passing step', + result: { + duration: 0, + status: 'passed', + }, + } + expect(steps).to.eql([expectedBefore, expectedStep, expectedAfter]) }) }) @@ -307,8 +321,8 @@ describe('JsonFormatter', () => { }) // Assert - const stepArguments = JSON.parse(output)[0].elements[0].steps[0] - .arguments + const stepArguments = + JSON.parse(output)[0].elements[0].steps[0].arguments expect(stepArguments).to.eql([ { content: 'This is a DocString', @@ -345,8 +359,8 @@ describe('JsonFormatter', () => { }) // Assert - const stepArguments = JSON.parse(output)[0].elements[0].steps[0] - .arguments + const stepArguments = + JSON.parse(output)[0].elements[0].steps[0].arguments expect(stepArguments).to.eql([ { rows: [ diff --git a/src/formatter/message_formatter.ts b/src/formatter/message_formatter.ts index c76453d9c..15f47b0e0 100644 --- a/src/formatter/message_formatter.ts +++ b/src/formatter/message_formatter.ts @@ -1,11 +1,12 @@ import Formatter, { IFormatterOptions } from '.' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' export default class MessageFormatter extends Formatter { + public static readonly documentation: string = 'Outputs protobuf messages' constructor(options: IFormatterOptions) { super(options) options.eventBroadcaster.on('envelope', (envelope: messages.Envelope) => - this.log(JSON.stringify(envelope.toJSON()) + '\n') + this.log(JSON.stringify(envelope) + '\n') ) } } diff --git a/src/formatter/progress_bar_formatter.ts b/src/formatter/progress_bar_formatter.ts index 9bbffa0c1..660b3994f 100644 --- a/src/formatter/progress_bar_formatter.ts +++ b/src/formatter/progress_bar_formatter.ts @@ -2,7 +2,7 @@ import { formatIssue, formatSummary, isIssue } from './helpers' import Formatter, { IFormatterOptions } from './' import ProgressBar from 'progress' import { WriteStream as TtyWriteStream } from 'tty' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { doesHaveValue, valueOrDefault } from '../value_checker' import { formatUndefinedParameterType } from './helpers/issue_helpers' import { durationBetweenTimestamps } from '../time' @@ -10,9 +10,11 @@ import { durationBetweenTimestamps } from '../time' // Inspired by https://github.com/thekompanee/fuubar and https://github.com/martinciu/fuubar-cucumber export default class ProgressBarFormatter extends Formatter { private numberOfSteps: number - private testRunStarted: messages.ITestRunStarted + private testRunStarted: messages.TestRunStarted private issueCount: number public progressBar: ProgressBar + public static readonly documentation: string = + 'Similar to the Progress Formatter, but provides a real-time updating progress bar based on the total number of steps to be executed in the test run' constructor(options: IFormatterOptions) { super(options) @@ -42,18 +44,17 @@ export default class ProgressBarFormatter extends Formatter { logProgress({ testStepId, testCaseStartedId, - }: messages.ITestStepFinished): void { - const { testCase } = this.eventDataCollector.getTestCaseAttempt( - testCaseStartedId - ) + }: messages.TestStepFinished): void { + const { testCase } = + this.eventDataCollector.getTestCaseAttempt(testCaseStartedId) const testStep = testCase.testSteps.find((s) => s.id === testStepId) - if (testStep.pickleStepId !== '') { + if (doesHaveValue(testStep.pickleStepId)) { this.progressBar.tick() } } logUndefinedParametertype( - parameterType: messages.IUndefinedParameterType + parameterType: messages.UndefinedParameterType ): void { this.log( `Undefined parameter type: ${formatUndefinedParameterType( @@ -62,7 +63,7 @@ export default class ProgressBarFormatter extends Formatter { ) } - logErrorIfNeeded(testCaseFinished: messages.ITestCaseFinished): void { + logErrorIfNeeded(testCaseFinished: messages.TestCaseFinished): void { const { worstTestStepResult } = this.eventDataCollector.getTestCaseAttempt( testCaseFinished.testCaseStartedId ) @@ -81,14 +82,14 @@ export default class ProgressBarFormatter extends Formatter { testCaseAttempt, }) ) - if (worstTestStepResult.willBeRetried) { + if (testCaseFinished.willBeRetried) { const stepsToRetry = testCaseAttempt.pickle.steps.length this.progressBar.tick(-stepsToRetry) } } } - logSummary(testRunFinished: messages.ITestRunFinished): void { + logSummary(testRunFinished: messages.TestRunFinished): void { const testRunDuration = durationBetweenTimestamps( this.testRunStarted.timestamp, testRunFinished.timestamp @@ -102,11 +103,11 @@ export default class ProgressBarFormatter extends Formatter { ) } - parseEnvelope(envelope: messages.IEnvelope): void { + parseEnvelope(envelope: messages.Envelope): void { if (doesHaveValue(envelope.undefinedParameterType)) { this.logUndefinedParametertype(envelope.undefinedParameterType) - } else if (doesHaveValue(envelope.pickle)) { - this.incrementStepCount(envelope.pickle.id) + } else if (doesHaveValue(envelope.testCase)) { + this.incrementStepCount(envelope.testCase.pickleId) } else if (doesHaveValue(envelope.testStepStarted)) { this.initializeProgressBar() } else if (doesHaveValue(envelope.testStepFinished)) { diff --git a/src/formatter/progress_bar_formatter_spec.ts b/src/formatter/progress_bar_formatter_spec.ts index 9ff6712f4..c0709331a 100644 --- a/src/formatter/progress_bar_formatter_spec.ts +++ b/src/formatter/progress_bar_formatter_spec.ts @@ -14,19 +14,20 @@ import { getBaseSupportCodeLibrary } from '../../test/fixtures/steps' import FakeTimers, { InstalledClock } from '@sinonjs/fake-timers' import timeMethods from '../time' import { IRuntimeOptions } from '../runtime' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { ISupportCodeLibrary } from '../support_code_library_builder/types' import ProgressBarFormatter from './progress_bar_formatter' import { doesHaveValue, doesNotHaveValue } from '../value_checker' import { PassThrough } from 'stream' import ProgressBar from 'progress' -import bluebird from 'bluebird' +import { promisify } from 'util' interface ITestProgressBarFormatterOptions { runtimeOptions?: Partial - shouldStopFn: (envelope: messages.IEnvelope) => boolean + shouldStopFn: (envelope: messages.Envelope) => boolean sources?: ITestSource[] supportCodeLibrary?: ISupportCodeLibrary + pickleFilter?: (pickle: messages.Pickle) => boolean } interface ITestProgressBarFormatterOutput { @@ -39,6 +40,7 @@ async function testProgressBarFormatter({ shouldStopFn, sources, supportCodeLibrary, + pickleFilter = () => true, }: ITestProgressBarFormatterOptions): Promise { if (doesNotHaveValue(supportCodeLibrary)) { supportCodeLibrary = buildSupportCodeLibrary() @@ -48,6 +50,7 @@ async function testProgressBarFormatter({ runtimeOptions, sources, supportCodeLibrary, + pickleFilter, }) let output = '' @@ -55,16 +58,16 @@ async function testProgressBarFormatter({ output += data } const passThrough = new PassThrough() - const progressBarFormatter = FormatterBuilder.build('progress-bar', { + const progressBarFormatter = (await FormatterBuilder.build('progress-bar', { cwd: '', eventBroadcaster, eventDataCollector: new EventDataCollector(eventBroadcaster), log: logFn, parsedArgvOptions: {}, stream: passThrough, - cleanup: bluebird.promisify(passThrough.end.bind(passThrough)), + cleanup: promisify(passThrough.end.bind(passThrough)), supportCodeLibrary, - }) as ProgressBarFormatter + })) as ProgressBarFormatter let mocked = false for (const envelope of envelopes) { eventBroadcaster.emit('envelope', envelope) @@ -98,8 +101,7 @@ describe('ProgressBarFormatter', () => { uri: 'a.feature', }, { - data: - 'Feature: a\nScenario: b\nGiven a step\nWhen a step\nThen a step', + data: 'Feature: a\nScenario: b\nGiven a step\nWhen a step\nThen a step', uri: 'b.feature', }, ] @@ -122,8 +124,7 @@ describe('ProgressBarFormatter', () => { uri: 'a.feature', }, { - data: - 'Feature: a\nRule: b\nExample: c\nGiven a step\nWhen a step\nThen a step', + data: 'Feature: a\nRule: b\nExample: c\nGiven a step\nWhen a step\nThen a step', uri: 'b.feature', }, ] @@ -137,6 +138,31 @@ describe('ProgressBarFormatter', () => { // Assert expect(progressBarFormatter.progressBar.total).to.eql(5) }) + + it('initializes a progress bar with the total number of steps when some pickles filtered out', async () => { + // Arrange + const sources = [ + { + data: '@yep\nFeature: a\nScenario: b\nGiven a step\nThen a step', + uri: 'a.feature', + }, + { + data: 'Feature: a\nScenario: b\nGiven a step\nWhen a step\nThen a step', + uri: 'b.feature', + }, + ] + + // Act + const { progressBarFormatter } = await testProgressBarFormatter({ + shouldStopFn: (envelope) => doesHaveValue(envelope.testStepStarted), + sources, + pickleFilter: (pickle) => + pickle.tags.some((tag) => tag.name === '@yep'), + }) + + // Assert + expect(progressBarFormatter.progressBar.total).to.eql(2) + }) }) describe('testStepFinished', () => { @@ -341,8 +367,7 @@ describe('ProgressBarFormatter', () => { // Arrange const sources = [ { - data: - 'Feature: a\nScenario: b\nGiven a passing step\n When a flaky step\nThen a passing step', + data: 'Feature: a\nScenario: b\nGiven a passing step\n When a flaky step\nThen a passing step', uri: 'a.feature', }, ] @@ -355,7 +380,8 @@ describe('ProgressBarFormatter', () => { sources, supportCodeLibrary, }) - const progressBar = progressBarFormatter.progressBar as sinon.SinonStubbedInstance + const progressBar = + progressBarFormatter.progressBar as sinon.SinonStubbedInstance // Assert expect(progressBar.interrupt).to.have.callCount(1) diff --git a/src/formatter/progress_formatter.ts b/src/formatter/progress_formatter.ts index 37f380a41..cc6198c6c 100644 --- a/src/formatter/progress_formatter.ts +++ b/src/formatter/progress_formatter.ts @@ -1,21 +1,24 @@ import SummaryFormatter from './summary_formatter' -import Status from '../status' import { doesHaveValue } from '../value_checker' import { IFormatterOptions } from './index' -import { messages } from '@cucumber/messages' -import IEnvelope = messages.IEnvelope -import ITestStepFinished = messages.ITestStepFinished +import * as messages from '@cucumber/messages' +import IEnvelope = messages.Envelope +import ITestStepFinished = messages.TestStepFinished -const STATUS_CHARACTER_MAPPING: { [key: number]: string } = { - [Status.AMBIGUOUS]: 'A', - [Status.FAILED]: 'F', - [Status.PASSED]: '.', - [Status.PENDING]: 'P', - [Status.SKIPPED]: '-', - [Status.UNDEFINED]: 'U', -} +const STATUS_CHARACTER_MAPPING: Map = + new Map([ + [messages.TestStepResultStatus.AMBIGUOUS, 'A'], + [messages.TestStepResultStatus.FAILED, 'F'], + [messages.TestStepResultStatus.PASSED, '.'], + [messages.TestStepResultStatus.PENDING, 'P'], + [messages.TestStepResultStatus.SKIPPED, '-'], + [messages.TestStepResultStatus.UNDEFINED, 'U'], + ]) export default class ProgressFormatter extends SummaryFormatter { + public static readonly documentation: string = + 'Prints one character per scenario.' + constructor(options: IFormatterOptions) { options.eventBroadcaster.on('envelope', (envelope: IEnvelope) => { if (doesHaveValue(envelope.testRunFinished)) { @@ -29,7 +32,7 @@ export default class ProgressFormatter extends SummaryFormatter { logProgress({ testStepResult: { status } }: ITestStepFinished): void { const character = this.colorFns.forStatus(status)( - STATUS_CHARACTER_MAPPING[status] + STATUS_CHARACTER_MAPPING.get(status) ) this.log(character) } diff --git a/src/formatter/progress_formatter_spec.ts b/src/formatter/progress_formatter_spec.ts index 6786f6c19..b7581f2cd 100644 --- a/src/formatter/progress_formatter_spec.ts +++ b/src/formatter/progress_formatter_spec.ts @@ -2,6 +2,7 @@ import { afterEach, beforeEach, describe, it } from 'mocha' import { expect } from 'chai' import { getBaseSupportCodeLibrary } from '../../test/fixtures/steps' import { testFormatter } from '../../test/formatter_helpers' +import { reindent } from 'reindent-template-literals' import figures from 'figures' import FakeTimers, { InstalledClock } from '@sinonjs/fake-timers' import timeMethods from '../time' @@ -21,21 +22,21 @@ describe('ProgressFormatter', () => { // Arrange const sources = [ { - data: `\ -Feature: a - Scenario: a1 - Given an ambiguous step - Scenario: a2 - Given a failing step - Scenario: a3 - Given a pending step - Scenario: a4 - Given a passing step - Scenario: a5 - Given a skipped step - Scenario: a6 - Given an undefined step -`, + data: reindent(` + Feature: a + Scenario: a1 + Given an ambiguous step + Scenario: a2 + Given a failing step + Scenario: a3 + Given a pending step + Scenario: a4 + Given a passing step + Scenario: a5 + Given a skipped step + Scenario: a6 + Given an undefined step + `), uri: 'a.feature', }, ] @@ -49,60 +50,63 @@ Feature: a }) // Assert - expect(output).to.eql(`\ -AFP.-U + expect(output).to.eql( + reindent(` + AFP.-U -Failures: + Failures: -1) Scenario: a1 # a.feature:2 - ${figures.cross} Given an ambiguous step - Multiple step definitions match: - an ambiguous step - steps.ts:13 - /an? ambiguous step/ - steps.ts:14 + 1) Scenario: a1 # a.feature:2 + ${figures.cross} Given an ambiguous step + Multiple step definitions match: + an ambiguous step - steps.ts:13 + /an? ambiguous step/ - steps.ts:14 -2) Scenario: a2 # a.feature:4 - ${figures.cross} Given a failing step # steps.ts:9 - error + 2) Scenario: a2 # a.feature:4 + ${figures.cross} Given a failing step # steps.ts:9 + error -3) Scenario: a6 # a.feature:12 - ? Given an undefined step - Undefined. Implement with the following snippet: + 3) Scenario: a6 # a.feature:12 + ? Given an undefined step + Undefined. Implement with the following snippet: - Given('an undefined step', function () { - // Write code here that turns the phrase above into concrete actions - return 'pending'; - }); + Given('an undefined step', function () { + // Write code here that turns the phrase above into concrete actions + return 'pending'; + }); -Warnings: + Warnings: -1) Scenario: a3 # a.feature:6 - ? Given a pending step # steps.ts:16 - Pending + 1) Scenario: a3 # a.feature:6 + ? Given a pending step # steps.ts:16 + Pending -6 scenarios (1 failed, 1 ambiguous, 1 undefined, 1 pending, 1 skipped, 1 passed) -6 steps (1 failed, 1 ambiguous, 1 undefined, 1 pending, 1 skipped, 1 passed) - -`) + 6 scenarios (1 failed, 1 ambiguous, 1 undefined, 1 pending, 1 skipped, 1 passed) + 6 steps (1 failed, 1 ambiguous, 1 undefined, 1 pending, 1 skipped, 1 passed) + + + `) + ) }) it('handles rule/example results', async () => { // Arrange const sources = [ { - data: `\ -Feature: feature - Rule: rule1 - Example: example1 - Given a passing step - - Example: example2 - Given a passing step - - Rule: rule2 - Example: example1 - Given a passing step -`, + data: reindent(` + Feature: feature + Rule: rule1 + Example: example1 + Given a passing step + + Example: example2 + Given a passing step + + Rule: rule2 + Example: example1 + Given a passing step + `), uri: 'a.feature', }, ] @@ -116,12 +120,15 @@ Feature: feature }) // Assert - expect(output).to.eql(`\ -... + expect(output).to.eql( + reindent(` + ... + + 3 scenarios (3 passed) + 3 steps (3 passed) + -3 scenarios (3 passed) -3 steps (3 passed) - -`) + `) + ) }) }) diff --git a/src/formatter/publish.ts b/src/formatter/publish.ts new file mode 100644 index 000000000..ca16d98c3 --- /dev/null +++ b/src/formatter/publish.ts @@ -0,0 +1,2 @@ +export const DEFAULT_CUCUMBER_PUBLISH_URL = + 'https://messages.cucumber.io/api/reports' diff --git a/src/formatter/rerun_formatter.ts b/src/formatter/rerun_formatter.ts index 5da4d2784..ad840e14d 100644 --- a/src/formatter/rerun_formatter.ts +++ b/src/formatter/rerun_formatter.ts @@ -1,14 +1,11 @@ -import _ from 'lodash' import Formatter, { IFormatterOptions } from './' -import Status from '../status' -import path from 'path' import { getGherkinScenarioLocationMap } from './helpers/gherkin_document_parser' import { doesHaveValue, doesNotHaveValue, valueOrDefault, } from '../value_checker' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' const DEFAULT_SEPARATOR = '\n' @@ -18,10 +15,12 @@ interface UriToLinesMap { export default class RerunFormatter extends Formatter { private readonly separator: string + public static readonly documentation: string = + 'Prints failing files with line numbers.' constructor(options: IFormatterOptions) { super(options) - options.eventBroadcaster.on('envelope', (envelope: messages.IEnvelope) => { + options.eventBroadcaster.on('envelope', (envelope: messages.Envelope) => { if (doesHaveValue(envelope.testRunFinished)) { this.logFailedTestCases() } @@ -32,25 +31,29 @@ export default class RerunFormatter extends Formatter { logFailedTestCases(): void { const mapping: UriToLinesMap = {} - _.each( - this.eventDataCollector.getTestCaseAttempts(), - ({ gherkinDocument, pickle, worstTestStepResult }) => { - if (worstTestStepResult.status !== Status.PASSED) { - const relativeUri = path.relative(this.cwd, pickle.uri) - const line = getGherkinScenarioLocationMap(gherkinDocument)[ - _.last(pickle.astNodeIds) - ].line + this.eventDataCollector + .getTestCaseAttempts() + .forEach(({ gherkinDocument, pickle, worstTestStepResult }) => { + if ( + worstTestStepResult.status !== messages.TestStepResultStatus.PASSED + ) { + const relativeUri = pickle.uri + const line = + getGherkinScenarioLocationMap(gherkinDocument)[ + pickle.astNodeIds[pickle.astNodeIds.length - 1] + ].line if (doesNotHaveValue(mapping[relativeUri])) { mapping[relativeUri] = [] } mapping[relativeUri].push(line) } - } - ) - const text = _.chain(mapping) - .map((lines, uri) => `${uri}:${lines.join(':')}`) + }) + const text = Object.keys(mapping) + .map((uri) => { + const lines = mapping[uri] + return `${uri}:${lines.join(':')}` + }) .join(this.separator) - .value() this.log(text) } } diff --git a/src/formatter/rerun_formatter_spec.ts b/src/formatter/rerun_formatter_spec.ts index 5791d209a..fd9e1c5bf 100644 --- a/src/formatter/rerun_formatter_spec.ts +++ b/src/formatter/rerun_formatter_spec.ts @@ -1,6 +1,5 @@ import { describe, it } from 'mocha' import { expect } from 'chai' -import _ from 'lodash' import { buildSupportCodeLibrary } from '../../test/runtime_helpers' import { testFormatter } from '../../test/formatter_helpers' @@ -148,8 +147,7 @@ describe('RerunFormatter', () => { // Arrange const sources = [ { - data: - 'Feature: a\nScenario: b\nGiven a step\nScenario: c\nGiven a step', + data: 'Feature: a\nScenario: b\nGiven a step\nScenario: c\nGiven a step', uri: 'a.feature', }, ] @@ -163,65 +161,63 @@ describe('RerunFormatter', () => { }) describe('with two failing scenarios in different files', () => { - _.each( - [ - { separator: { opt: undefined, expected: '\n' }, label: 'default' }, - { separator: { opt: '\n', expected: '\n' }, label: 'newline' }, - { separator: { opt: ' ', expected: ' ' }, label: 'space' }, - ], - ({ separator, label }) => { - describe(`using ${label} separator`, () => { - it('outputs the reference needed to run the scenario again', async () => { - // Arrange - const parsedArgvOptions = { rerun: { separator: separator.opt } } - const sources = [ - { - data: 'Feature: a\nScenario: b\nGiven a step', - uri: 'a.feature', - }, - { - data: 'Feature: a\n\nScenario: b\nGiven a step', - uri: 'b.feature', - }, - ] - - // Act - const output = await testFormatter({ - parsedArgvOptions, - sources, - type: 'rerun', - }) - - // Assert - expect(output).to.eql(`a.feature:2${separator.expected}b.feature:3`) + const examples = [ + { separator: { opt: undefined, expected: '\n' }, label: 'default' }, + { separator: { opt: '\n', expected: '\n' }, label: 'newline' }, + { separator: { opt: ' ', expected: ' ' }, label: 'space' }, + ] + examples.forEach(({ separator, label }) => { + describe(`using ${label} separator`, () => { + it('outputs the reference needed to run the scenario again', async () => { + // Arrange + const parsedArgvOptions = { rerun: { separator: separator.opt } } + const sources = [ + { + data: 'Feature: a\nScenario: b\nGiven a step', + uri: 'a.feature', + }, + { + data: 'Feature: a\n\nScenario: b\nGiven a step', + uri: 'b.feature', + }, + ] + + // Act + const output = await testFormatter({ + parsedArgvOptions, + sources, + type: 'rerun', }) - it('outputs the reference needed to run the rule example again', async () => { - // Arrange - const parsedArgvOptions = { rerun: { separator: separator.opt } } - const sources = [ - { - data: 'Feature: a\nRule: b\nExample: c\nGiven a step', - uri: 'a.feature', - }, - { - data: 'Feature: a\n\nRule: b\nExample: c\nGiven a step', - uri: 'b.feature', - }, - ] - - // Act - const output = await testFormatter({ - parsedArgvOptions, - sources, - type: 'rerun', - }) - - // Assert - expect(output).to.eql(`a.feature:3${separator.expected}b.feature:4`) + // Assert + expect(output).to.eql(`a.feature:2${separator.expected}b.feature:3`) + }) + + it('outputs the reference needed to run the rule example again', async () => { + // Arrange + const parsedArgvOptions = { rerun: { separator: separator.opt } } + const sources = [ + { + data: 'Feature: a\nRule: b\nExample: c\nGiven a step', + uri: 'a.feature', + }, + { + data: 'Feature: a\n\nRule: b\nExample: c\nGiven a step', + uri: 'b.feature', + }, + ] + + // Act + const output = await testFormatter({ + parsedArgvOptions, + sources, + type: 'rerun', }) + + // Assert + expect(output).to.eql(`a.feature:3${separator.expected}b.feature:4`) }) - } - ) + }) + }) }) }) diff --git a/src/formatter/snippets_formatter.ts b/src/formatter/snippets_formatter.ts index ee2a3b10f..bbc936d37 100644 --- a/src/formatter/snippets_formatter.ts +++ b/src/formatter/snippets_formatter.ts @@ -1,11 +1,13 @@ import Formatter, { IFormatterOptions } from './' -import Status from '../status' import { parseTestCaseAttempt } from './helpers' import { doesHaveValue } from '../value_checker' -import { messages } from '@cucumber/messages' -import IEnvelope = messages.IEnvelope +import * as messages from '@cucumber/messages' +import IEnvelope = messages.Envelope export default class SnippetsFormatter extends Formatter { + public static readonly documentation: string = + "The Snippets Formatter doesn't output anything regarding the test run; it just prints snippets to implement any undefined steps" + constructor(options: IFormatterOptions) { super(options) options.eventBroadcaster.on('envelope', (envelope: IEnvelope) => { @@ -25,7 +27,9 @@ export default class SnippetsFormatter extends Formatter { testCaseAttempt, }) parsed.testSteps.forEach((testStep) => { - if (testStep.result.status === Status.UNDEFINED) { + if ( + testStep.result.status === messages.TestStepResultStatus.UNDEFINED + ) { snippets.push(testStep.snippet) } }) diff --git a/src/formatter/step_definition_snippet_builder/index.ts b/src/formatter/step_definition_snippet_builder/index.ts index a123b8ab1..ce7065d1e 100644 --- a/src/formatter/step_definition_snippet_builder/index.ts +++ b/src/formatter/step_definition_snippet_builder/index.ts @@ -5,7 +5,7 @@ import { CucumberExpressionGenerator, ParameterTypeRegistry, } from '@cucumber/cucumber-expressions' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { doesHaveValue } from '../../value_checker' export interface INewStepDefinitionSnippetBuilderOptions { @@ -15,7 +15,7 @@ export interface INewStepDefinitionSnippetBuilderOptions { export interface IBuildRequest { keywordType: KeywordType - pickleStep: messages.Pickle.IPickleStep + pickleStep: messages.PickleStep } export default class StepDefinitionSnippetBuilder { @@ -36,9 +36,8 @@ export default class StepDefinitionSnippetBuilder { const comment = 'Write code here that turns the phrase above into concrete actions' const functionName = this.getFunctionName(keywordType) - const generatedExpressions = this.cucumberExpressionGenerator.generateExpressions( - pickleStep.text - ) + const generatedExpressions = + this.cucumberExpressionGenerator.generateExpressions(pickleStep.text) const stepParameterNames = this.getStepParameterNames(pickleStep) return this.snippetSyntax.build({ comment, @@ -59,7 +58,7 @@ export default class StepDefinitionSnippetBuilder { } } - getStepParameterNames(step: messages.Pickle.IPickleStep): string[] { + getStepParameterNames(step: messages.PickleStep): string[] { if (doesHaveValue(step.argument)) { const argumentName = parseStepArgument(step.argument, { dataTable: () => 'dataTable', diff --git a/src/formatter/step_definition_snippet_builder/javascript_snippet_syntax.ts b/src/formatter/step_definition_snippet_builder/javascript_snippet_syntax.ts index e230b9ebd..128904e96 100644 --- a/src/formatter/step_definition_snippet_builder/javascript_snippet_syntax.ts +++ b/src/formatter/step_definition_snippet_builder/javascript_snippet_syntax.ts @@ -29,6 +29,8 @@ export default class JavaScriptSnippetSyntax implements ISnippetSnytax { let implementation: string if (this.snippetInterface === SnippetInterface.Callback) { implementation = `${CALLBACK_NAME}(null, 'pending');` + } else if (this.snippetInterface === SnippetInterface.Promise) { + implementation = "return Promise.resolve('pending');" } else { implementation = "return 'pending';" } @@ -36,9 +38,8 @@ export default class JavaScriptSnippetSyntax implements ISnippetSnytax { const definitionChoices = generatedExpressions.map( (generatedExpression, index) => { const prefix = index === 0 ? '' : '// ' - const allParameterNames = generatedExpression.parameterNames.concat( - stepParameterNames - ) + const allParameterNames = + generatedExpression.parameterNames.concat(stepParameterNames) if (this.snippetInterface === SnippetInterface.Callback) { allParameterNames.push(CALLBACK_NAME) } diff --git a/src/formatter/step_definition_snippet_builder/javascript_snippet_syntax_spec.ts b/src/formatter/step_definition_snippet_builder/javascript_snippet_syntax_spec.ts index 17978db03..7d76edb94 100644 --- a/src/formatter/step_definition_snippet_builder/javascript_snippet_syntax_spec.ts +++ b/src/formatter/step_definition_snippet_builder/javascript_snippet_syntax_spec.ts @@ -3,11 +3,12 @@ import { expect } from 'chai' import JavascriptSnippetSyntax from './javascript_snippet_syntax' import { SnippetInterface } from './snippet_syntax' import { ISnippetSyntaxBuildOptions } from '../../../lib/formatter/step_definition_snippet_builder/snippet_syntax' -import GeneratedExpression from '@cucumber/cucumber-expressions/dist/src/GeneratedExpression' import { CucumberExpressionGenerator, + GeneratedExpression, ParameterTypeRegistry, } from '@cucumber/cucumber-expressions' +import { reindent } from 'reindent-template-literals' function generateExpressions(text: string): readonly GeneratedExpression[] { const parameterTypeRegistry = new ParameterTypeRegistry() @@ -34,11 +35,13 @@ describe('JavascriptSnippetSyntax', () => { const result = syntax.build(buildOptions) // Assert - expect(result).to.eql(`\ -functionName('{string} def {string}', function (string, string2, callback) { - // comment - callback(null, 'pending'); -});`) + expect(result).to.eql( + reindent(` + functionName('{string} def {string}', function (string, string2, callback) { + // comment + callback(null, 'pending'); + });`) + ) }) }) @@ -57,11 +60,13 @@ functionName('{string} def {string}', function (string, string2, callback) { const result = syntax.build(buildOptions) // Assert - expect(result).to.eql(`\ -functionName('{string} def {string}', function *(string, string2) { - // comment - return 'pending'; -});`) + expect(result).to.eql( + reindent(` + functionName('{string} def {string}', function *(string, string2) { + // comment + return 'pending'; + });`) + ) }) }) @@ -80,11 +85,13 @@ functionName('{string} def {string}', function *(string, string2) { const result = syntax.build(buildOptions) // Assert - expect(result).to.eql(`\ -functionName('{string} def {string}', function (string, string2) { - // comment - return 'pending'; -});`) + expect(result).to.eql( + reindent(` + functionName('{string} def {string}', function (string, string2) { + // comment + return Promise.resolve('pending'); + });`) + ) }) }) @@ -103,11 +110,13 @@ functionName('{string} def {string}', function (string, string2) { const result = syntax.build(buildOptions) // Assert - expect(result).to.eql(`\ -functionName('{string} def {string}', function (string, string2) { - // comment - return 'pending'; -});`) + expect(result).to.eql( + reindent(` + functionName('{string} def {string}', function (string, string2) { + // comment + return 'pending'; + });`) + ) }) }) @@ -126,11 +135,13 @@ functionName('{string} def {string}', function (string, string2) { const result = syntax.build(buildOptions) // Assert - expect(result).to.eql(`\ -functionName('pattern\\'', function () { - // comment - return 'pending'; -});`) + expect(result).to.eql( + reindent(` + functionName('pattern\\'', function () { + // comment + return 'pending'; + });`) + ) }) }) @@ -149,14 +160,16 @@ functionName('pattern\\'', function () { const result = syntax.build(buildOptions) // Assert - expect(result).to.eql(`\ -functionName('{int} {int}', function (int, int2) { -// functionName('{int} {float}', function (int, float) { -// functionName('{float} {int}', function (float, int) { -// functionName('{float} {float}', function (float, float2) { - // comment - return 'pending'; -});`) + expect(result).to.eql( + reindent(` + functionName('{int} {int}', function (int, int2) { + // functionName('{int} {float}', function (int, float) { + // functionName('{float} {int}', function (float, int) { + // functionName('{float} {float}', function (float, float2) { + // comment + return 'pending'; + });`) + ) }) }) }) diff --git a/src/formatter/step_definition_snippet_builder/snippet_syntax.ts b/src/formatter/step_definition_snippet_builder/snippet_syntax.ts index 264ec3ab2..ca25a8f2c 100644 --- a/src/formatter/step_definition_snippet_builder/snippet_syntax.ts +++ b/src/formatter/step_definition_snippet_builder/snippet_syntax.ts @@ -1,4 +1,4 @@ -import GeneratedExpression from '@cucumber/cucumber-expressions/dist/src/GeneratedExpression' +import { GeneratedExpression } from '@cucumber/cucumber-expressions' export enum SnippetInterface { AsyncAwait = 'async-await', diff --git a/src/formatter/summary_formatter.ts b/src/formatter/summary_formatter.ts index c4932cb94..f91034a3d 100644 --- a/src/formatter/summary_formatter.ts +++ b/src/formatter/summary_formatter.ts @@ -1,8 +1,7 @@ -import _ from 'lodash' import { formatIssue, formatSummary, isFailure, isWarning } from './helpers' import Formatter, { IFormatterOptions } from './' import { doesHaveValue } from '../value_checker' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { ITestCaseAttempt } from './helpers/event_data_collector' import { formatUndefinedParameterTypes } from './helpers/issue_helpers' import { durationBetweenTimestamps } from '../time' @@ -13,10 +12,13 @@ interface ILogIssuesRequest { } export default class SummaryFormatter extends Formatter { + public static readonly documentation: string = + 'Summary output of feature and scenarios' + constructor(options: IFormatterOptions) { super(options) - let testRunStartedTimestamp: messages.ITimestamp - options.eventBroadcaster.on('envelope', (envelope: messages.IEnvelope) => { + let testRunStartedTimestamp: messages.Timestamp + options.eventBroadcaster.on('envelope', (envelope: messages.Envelope) => { if (doesHaveValue(envelope.testRunStarted)) { testRunStartedTimestamp = envelope.testRunStarted.timestamp } @@ -32,14 +34,24 @@ export default class SummaryFormatter extends Formatter { }) } - logSummary(testRunDuration: messages.IDuration): void { + logSummary(testRunDuration: messages.Duration): void { const failures: ITestCaseAttempt[] = [] const warnings: ITestCaseAttempt[] = [] const testCaseAttempts = this.eventDataCollector.getTestCaseAttempts() - _.each(testCaseAttempts, (testCaseAttempt) => { - if (isFailure(testCaseAttempt.worstTestStepResult)) { + testCaseAttempts.forEach((testCaseAttempt) => { + if ( + isFailure( + testCaseAttempt.worstTestStepResult, + testCaseAttempt.willBeRetried + ) + ) { failures.push(testCaseAttempt) - } else if (isWarning(testCaseAttempt.worstTestStepResult)) { + } else if ( + isWarning( + testCaseAttempt.worstTestStepResult, + testCaseAttempt.willBeRetried + ) + ) { warnings.push(testCaseAttempt) } }) diff --git a/src/formatter/usage_formatter.ts b/src/formatter/usage_formatter.ts index f99d4807c..0776d3656 100644 --- a/src/formatter/usage_formatter.ts +++ b/src/formatter/usage_formatter.ts @@ -1,13 +1,14 @@ -import _ from 'lodash' import { formatLocation, getUsage } from './helpers' import Formatter, { IFormatterOptions } from './' import Table from 'cli-table3' -import { durationToMilliseconds } from '../time' import { doesHaveValue } from '../value_checker' -import { messages } from '@cucumber/messages' -import IEnvelope = messages.IEnvelope +import * as messages from '@cucumber/messages' +import IEnvelope = messages.Envelope export default class UsageFormatter extends Formatter { + public static readonly documentation: string = + 'Prints where step definitions are used. The slowest step definitions (with duration) are listed first. If --dry-run is used the duration is not shown, and step definitions are sorted by filename instead.' + constructor(options: IFormatterOptions) { super(options) options.eventBroadcaster.on('envelope', (envelope: IEnvelope) => { @@ -44,7 +45,11 @@ export default class UsageFormatter extends Formatter { const col2 = [] if (matches.length > 0) { if (doesHaveValue(meanDuration)) { - col2.push(`${durationToMilliseconds(meanDuration).toFixed(2)}ms`) + col2.push( + `${messages.TimeConversion.durationToMilliseconds( + meanDuration + ).toFixed(2)}ms` + ) } else { col2.push('-') } @@ -52,10 +57,14 @@ export default class UsageFormatter extends Formatter { col2.push('UNUSED') } const col3 = [formatLocation({ line, uri })] - _.take(matches, 5).forEach((match) => { + matches.slice(0, 5).forEach((match) => { col1.push(` ${match.text}`) if (doesHaveValue(match.duration)) { - col2.push(`${durationToMilliseconds(match.duration).toString()}ms`) + col2.push( + `${messages.TimeConversion.durationToMilliseconds( + match.duration + ).toFixed(2)}ms` + ) } else { col2.push('-') } diff --git a/src/formatter/usage_formatter_spec.ts b/src/formatter/usage_formatter_spec.ts index b394f347f..5c8545124 100644 --- a/src/formatter/usage_formatter_spec.ts +++ b/src/formatter/usage_formatter_spec.ts @@ -4,6 +4,7 @@ import FakeTimers, { InstalledClock } from '@sinonjs/fake-timers' import timeMethods from '../time' import { getUsageSupportCodeLibrary } from '../../test/fixtures/usage_steps' import { testFormatter } from '../../test/formatter_helpers' +import { reindent } from 'reindent-template-literals' describe('UsageFormatter', () => { let clock: InstalledClock @@ -41,17 +42,20 @@ describe('UsageFormatter', () => { }) // Assert - expect(output).to.eql(`\ -┌────────────────┬──────────┬───────────────────┐ -│ Pattern / Text │ Duration │ Location │ -├────────────────┼──────────┼───────────────────┤ -│ abc │ UNUSED │ usage_steps.ts:11 │ -├────────────────┼──────────┼───────────────────┤ -│ /def?/ │ UNUSED │ usage_steps.ts:16 │ -├────────────────┼──────────┼───────────────────┤ -│ ghi │ UNUSED │ usage_steps.ts:25 │ -└────────────────┴──────────┴───────────────────┘ -`) + expect(output).to.eql( + reindent(` + ┌────────────────┬──────────┬───────────────────┐ + │ Pattern / Text │ Duration │ Location │ + ├────────────────┼──────────┼───────────────────┤ + │ abc │ UNUSED │ usage_steps.ts:11 │ + ├────────────────┼──────────┼───────────────────┤ + │ /def?/ │ UNUSED │ usage_steps.ts:16 │ + ├────────────────┼──────────┼───────────────────┤ + │ ghi │ UNUSED │ usage_steps.ts:25 │ + └────────────────┴──────────┴───────────────────┘ + + `) + ) }) }) @@ -77,19 +81,22 @@ describe('UsageFormatter', () => { }) // Assert - expect(output).to.eql(`\ -┌────────────────┬──────────┬───────────────────┐ -│ Pattern / Text │ Duration │ Location │ -├────────────────┼──────────┼───────────────────┤ -│ abc │ UNUSED │ usage_steps.ts:11 │ -├────────────────┼──────────┼───────────────────┤ -│ /def?/ │ - │ usage_steps.ts:16 │ -│ de │ - │ a.feature:4 │ -│ def │ - │ a.feature:3 │ -├────────────────┼──────────┼───────────────────┤ -│ ghi │ UNUSED │ usage_steps.ts:25 │ -└────────────────┴──────────┴───────────────────┘ -`) + expect(output).to.eql( + reindent(` + ┌────────────────┬──────────┬───────────────────┐ + │ Pattern / Text │ Duration │ Location │ + ├────────────────┼──────────┼───────────────────┤ + │ abc │ UNUSED │ usage_steps.ts:11 │ + ├────────────────┼──────────┼───────────────────┤ + │ /def?/ │ - │ usage_steps.ts:16 │ + │ de │ - │ a.feature:4 │ + │ def │ - │ a.feature:3 │ + ├────────────────┼──────────┼───────────────────┤ + │ ghi │ UNUSED │ usage_steps.ts:25 │ + └────────────────┴──────────┴───────────────────┘ + + `) + ) }) }) @@ -112,19 +119,22 @@ describe('UsageFormatter', () => { }) // Assert - expect(output).to.eql(`\ -┌────────────────┬──────────┬───────────────────┐ -│ Pattern / Text │ Duration │ Location │ -├────────────────┼──────────┼───────────────────┤ -│ /def?/ │ 1.50ms │ usage_steps.ts:16 │ -│ def │ 2ms │ a.feature:3 │ -│ de │ 1ms │ a.feature:4 │ -├────────────────┼──────────┼───────────────────┤ -│ abc │ UNUSED │ usage_steps.ts:11 │ -├────────────────┼──────────┼───────────────────┤ -│ ghi │ UNUSED │ usage_steps.ts:25 │ -└────────────────┴──────────┴───────────────────┘ -`) + expect(output).to.eql( + reindent(` + ┌────────────────┬──────────┬───────────────────┐ + │ Pattern / Text │ Duration │ Location │ + ├────────────────┼──────────┼───────────────────┤ + │ /def?/ │ 1.50ms │ usage_steps.ts:16 │ + │ def │ 2.00ms │ a.feature:3 │ + │ de │ 1.00ms │ a.feature:4 │ + ├────────────────┼──────────┼───────────────────┤ + │ abc │ UNUSED │ usage_steps.ts:11 │ + ├────────────────┼──────────┼───────────────────┤ + │ ghi │ UNUSED │ usage_steps.ts:25 │ + └────────────────┴──────────┴───────────────────┘ + + `) + ) }) }) }) diff --git a/src/formatter/usage_json_formatter.ts b/src/formatter/usage_json_formatter.ts index 60f32c118..c2b522429 100644 --- a/src/formatter/usage_json_formatter.ts +++ b/src/formatter/usage_json_formatter.ts @@ -1,10 +1,13 @@ import { getUsage } from './helpers' import Formatter, { IFormatterOptions } from './' import { doesHaveValue } from '../value_checker' -import { messages } from '@cucumber/messages' -import IEnvelope = messages.IEnvelope +import * as messages from '@cucumber/messages' +import IEnvelope = messages.Envelope export default class UsageJsonFormatter extends Formatter { + public static readonly documentation: string = + 'Does what the Usage Formatter does, but outputs JSON, which can be output to a file and then consumed by other tools.' + constructor(options: IFormatterOptions) { super(options) options.eventBroadcaster.on('envelope', (envelope: IEnvelope) => { diff --git a/src/importer.js b/src/importer.js new file mode 100644 index 000000000..5347a38ca --- /dev/null +++ b/src/importer.js @@ -0,0 +1,13 @@ +/** + * Provides the async `import()` function to source code that needs it, + * without having it transpiled down to commonjs `require()` by TypeScript. + * See https://github.com/microsoft/TypeScript/issues/43329. + * + * @param {any} descriptor - A URL or path for the module to load + * @return {Promise} Promise that resolves to the loaded module + */ +async function importer(descriptor) { + return await import(descriptor) +} + +module.exports = { importer } diff --git a/src/index.ts b/src/index.ts index 0f878c416..5db98a80d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,17 +1,22 @@ import * as formatterHelpers from './formatter/helpers' import supportCodeLibraryBuilder from './support_code_library_builder' +import * as messages from '@cucumber/messages' // Top level export { default as Cli } from './cli' export { parseGherkinMessageStream } from './cli/helpers' export { default as PickleFilter } from './pickle_filter' -export { default as Runtime } from './runtime' +export { + default as Runtime, + INewRuntimeOptions, + IRuntimeOptions, +} from './runtime' export { default as supportCodeLibraryBuilder } from './support_code_library_builder' -export { default as Status } from './status' export { default as DataTable } from './models/data_table' +export { version } from './version' // Formatters -export { default as Formatter } from './formatter' +export { default as Formatter, IFormatterOptions } from './formatter' export { default as FormatterBuilder } from './formatter/builder' export { default as JsonFormatter } from './formatter/json_formatter' export { default as ProgressFormatter } from './formatter/progress_formatter' @@ -41,5 +46,15 @@ export const Then = methods.Then export const When = methods.When export { default as World, + IWorld, IWorldOptions, } from './support_code_library_builder/world' + +export { + ITestCaseHookParameter, + ITestStepHookParameter, +} from './support_code_library_builder/types' +export const Status = messages.TestStepResultStatus + +// Time helpers +export { wrapPromiseWithTimeout } from './time' diff --git a/src/models/data_table.ts b/src/models/data_table.ts index c274759a7..419384283 100644 --- a/src/models/data_table.ts +++ b/src/models/data_table.ts @@ -1,12 +1,9 @@ -import _ from 'lodash' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' export default class DataTable { private readonly rawTable: string[][] - constructor( - sourceTable: messages.PickleStepArgument.IPickleTable | string[][] - ) { + constructor(sourceTable: messages.PickleTable | string[][]) { if (sourceTable instanceof Array) { this.rawTable = sourceTable } else { @@ -20,7 +17,11 @@ export default class DataTable { const copy = this.raw() const keys = copy[0] const valuesArray = copy.slice(1) - return valuesArray.map((values) => _.zipObject(keys, values)) + return valuesArray.map((values) => { + const rowObject: Record = {} + keys.forEach((key, index) => (rowObject[key] = values[index])) + return rowObject + }) } raw(): string[][] { @@ -35,13 +36,15 @@ export default class DataTable { rowsHash(): Record { const rows = this.raw() - const everyRowHasTwoColumns = _.every(rows, (row) => row.length === 2) + const everyRowHasTwoColumns = rows.every((row) => row.length === 2) if (!everyRowHasTwoColumns) { throw new Error( 'rowsHash can only be called on a data table where all rows have exactly two columns' ) } - return _.fromPairs(rows) + const result: Record = {} + rows.forEach((x) => (result[x[0]] = x[1])) + return result } transpose(): DataTable { diff --git a/src/models/data_table_spec.ts b/src/models/data_table_spec.ts index abf633290..8be0c3ee7 100644 --- a/src/models/data_table_spec.ts +++ b/src/models/data_table_spec.ts @@ -1,25 +1,42 @@ import { describe, it } from 'mocha' import { expect } from 'chai' import DataTable from './data_table' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' + +const id = 'id' +const location: messages.Location = { line: 0 } describe('DataTable', () => { describe('table with headers', () => { - const dataTable = messages.GherkinDocument.Feature.Step.DataTable.fromObject( - { - rows: [ - { - cells: [{ value: 'header 1' }, { value: 'header 2' }], - }, - { - cells: [{ value: 'row 1 col 1' }, { value: 'row 1 col 2' }], - }, - { - cells: [{ value: 'row 2 col 1' }, { value: 'row 2 col 2' }], - }, - ], - } - ) + const dataTable: messages.DataTable = { + location, + rows: [ + { + id, + location, + cells: [ + { value: 'header 1', location }, + { value: 'header 2', location }, + ], + }, + { + id, + location, + cells: [ + { value: 'row 1 col 1', location }, + { value: 'row 1 col 2', location }, + ], + }, + { + id, + location, + cells: [ + { value: 'row 2 col 1', location }, + { value: 'row 2 col 2', location }, + ], + }, + ], + } describe('rows', () => { it('returns a 2-D array without the header', () => { @@ -50,18 +67,27 @@ describe('DataTable', () => { }) describe('table without headers', () => { - const dataTable = messages.GherkinDocument.Feature.Step.DataTable.fromObject( - { - rows: [ - { - cells: [{ value: 'row 1 col 1' }, { value: 'row 1 col 2' }], - }, - { - cells: [{ value: 'row 2 col 1' }, { value: 'row 2 col 2' }], - }, - ], - } - ) + const dataTable: messages.DataTable = { + location, + rows: [ + { + id, + location, + cells: [ + { value: 'row 1 col 1', location }, + { value: 'row 1 col 2', location }, + ], + }, + { + id, + location, + cells: [ + { value: 'row 2 col 1', location }, + { value: 'row 2 col 2', location }, + ], + }, + ], + } describe('raw', () => { it('returns a 2-D array', () => { @@ -83,21 +109,24 @@ describe('DataTable', () => { }) describe('table with something other than 2 columns', () => { - const dataTable = messages.GherkinDocument.Feature.Step.DataTable.fromObject( - { - rows: [ - { - cells: [{ value: 'row 1 col 1' }], - }, - { - cells: [{ value: 'row 2 col 1' }], - }, - ], - } - ) - describe('rowsHash', () => { it('throws an error if not all rows have two columns', function () { + const dataTable: messages.DataTable = { + location, + rows: [ + { + id, + location, + cells: [{ value: 'row 1 col 1', location }], + }, + { + id, + location, + cells: [{ value: 'row 2 col 1', location }], + }, + ], + } + expect(() => new DataTable(dataTable).rowsHash()).to.throw( 'rowsHash can only be called on a data table where all rows have exactly two columns' ) diff --git a/src/models/definition.ts b/src/models/definition.ts index 3fd3d2fb5..171e89648 100644 --- a/src/models/definition.ts +++ b/src/models/definition.ts @@ -1,10 +1,10 @@ -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { ITestCaseHookParameter } from '../support_code_library_builder/types' import { Expression } from '@cucumber/cucumber-expressions' export interface IGetInvocationDataRequest { hookParameter: ITestCaseHookParameter - step: messages.Pickle.IPickleStep + step: messages.PickleStep world: any } diff --git a/src/models/step_definition.ts b/src/models/step_definition.ts index 2789e2741..42b7ae111 100644 --- a/src/models/step_definition.ts +++ b/src/models/step_definition.ts @@ -7,7 +7,6 @@ import Definition, { } from './definition' import { parseStepArgument } from '../step_arguments' import { Expression } from '@cucumber/cucumber-expressions' -import bluebird from 'bluebird' import { doesHaveValue } from '../value_checker' export default class StepDefinition extends Definition implements IDefinition { @@ -24,7 +23,7 @@ export default class StepDefinition extends Definition implements IDefinition { step, world, }: IGetInvocationDataRequest): Promise { - const parameters = await bluebird.all( + const parameters = await Promise.all( this.expression.match(step.text).map((arg) => arg.getValue(world)) ) if (doesHaveValue(step.argument)) { diff --git a/src/models/test_case_hook_definition.ts b/src/models/test_case_hook_definition.ts index c0d2db479..21d8b47e7 100644 --- a/src/models/test_case_hook_definition.ts +++ b/src/models/test_case_hook_definition.ts @@ -6,11 +6,12 @@ import Definition, { IGetInvocationDataResponse, IHookDefinitionOptions, } from './definition' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' export default class TestCaseHookDefinition extends Definition - implements IDefinition { + implements IDefinition +{ public readonly tagExpression: string private readonly pickleTagFilter: PickleTagFilter @@ -20,7 +21,7 @@ export default class TestCaseHookDefinition this.pickleTagFilter = new PickleTagFilter(data.options.tags) } - appliesToTestCase(pickle: messages.IPickle): boolean { + appliesToTestCase(pickle: messages.Pickle): boolean { return this.pickleTagFilter.matchesAllTagExpressions(pickle) } diff --git a/src/models/test_step_hook_definition.ts b/src/models/test_step_hook_definition.ts index ff31da134..32aa03367 100644 --- a/src/models/test_step_hook_definition.ts +++ b/src/models/test_step_hook_definition.ts @@ -6,11 +6,12 @@ import Definition, { IDefinitionParameters, IHookDefinitionOptions, } from './definition' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' export default class TestStepHookDefinition extends Definition - implements IDefinition { + implements IDefinition +{ public readonly tagExpression: string private readonly pickleTagFilter: PickleTagFilter @@ -20,7 +21,7 @@ export default class TestStepHookDefinition this.pickleTagFilter = new PickleTagFilter(data.options.tags) } - appliesToTestCase(pickle: messages.IPickle): boolean { + appliesToTestCase(pickle: messages.Pickle): boolean { return this.pickleTagFilter.matchesAllTagExpressions(pickle) } diff --git a/src/pickle_filter.ts b/src/pickle_filter.ts index 5364edfe6..0b7bc24cd 100644 --- a/src/pickle_filter.ts +++ b/src/pickle_filter.ts @@ -1,11 +1,10 @@ -import _ from 'lodash' import path from 'path' import parse from '@cucumber/tag-expressions' import { getGherkinScenarioLocationMap } from './formatter/helpers/gherkin_document_parser' import { doesHaveValue, doesNotHaveValue } from './value_checker' -import { messages } from '@cucumber/messages' -import IGherkinDocument = messages.IGherkinDocument -import IPickle = messages.IPickle +import * as messages from '@cucumber/messages' +import IGherkinDocument = messages.GherkinDocument +import IPickle = messages.Pickle const FEATURE_LINENUM_REGEXP = /^(.*?)((?::[\d]+)+)?$/ @@ -17,8 +16,8 @@ export interface IPickleFilterOptions { } export interface IMatchesAnyLineRequest { - gherkinDocument: messages.IGherkinDocument - pickle: messages.IPickle + gherkinDocument: messages.GherkinDocument + pickle: messages.Pickle } export default class PickleFilter { @@ -57,23 +56,20 @@ export class PickleLineFilter { constructor(cwd: string, featurePaths: string[] = []) { this.featureUriToLinesMapping = this.getFeatureUriToLinesMapping({ - cwd, featurePaths, }) } getFeatureUriToLinesMapping({ - cwd, featurePaths, }: { - cwd: string featurePaths: string[] }): Record { const mapping: Record = {} featurePaths.forEach((featurePath) => { const match = FEATURE_LINENUM_REGEXP.exec(featurePath) if (doesHaveValue(match)) { - const uri = path.resolve(cwd, match[1]) + const uri = path.normalize(match[1]) const linesExpression = match[2] if (doesHaveValue(linesExpression)) { if (doesNotHaveValue(mapping[uri])) { @@ -92,15 +88,18 @@ export class PickleLineFilter { } matchesAnyLine({ gherkinDocument, pickle }: IMatchesAnyLineRequest): boolean { - const linesToMatch = this.featureUriToLinesMapping[pickle.uri] + const uri = path.normalize(pickle.uri) + const linesToMatch = this.featureUriToLinesMapping[uri] if (doesHaveValue(linesToMatch)) { - const gherkinScenarioLocationMap = getGherkinScenarioLocationMap( - gherkinDocument - ) - const pickleLines = pickle.astNodeIds.map( - (sourceId) => gherkinScenarioLocationMap[sourceId].line + const gherkinScenarioLocationMap = + getGherkinScenarioLocationMap(gherkinDocument) + const pickleLines = new Set( + pickle.astNodeIds.map( + (sourceId) => gherkinScenarioLocationMap[sourceId].line + ) ) - return _.size(_.intersection(linesToMatch, pickleLines)) > 0 + const linesIntersection = linesToMatch.filter((x) => pickleLines.has(x)) + return linesIntersection.length > 0 } return true } @@ -113,11 +112,11 @@ export class PickleNameFilter { this.names = names } - matchesAnyName(pickle: messages.IPickle): boolean { + matchesAnyName(pickle: messages.Pickle): boolean { if (this.names.length === 0) { return true } - return _.some(this.names, (name) => pickle.name.match(name)) + return this.names.some((name) => pickle.name.match(name)) } } @@ -130,10 +129,10 @@ export class PickleTagFilter { } } - matchesAllTagExpressions(pickle: messages.IPickle): boolean { + matchesAllTagExpressions(pickle: messages.Pickle): boolean { if (doesNotHaveValue(this.tagExpressionNode)) { return true } - return this.tagExpressionNode.evaluate(_.map(pickle.tags, 'name')) + return this.tagExpressionNode.evaluate(pickle.tags.map((x) => x.name)) } } diff --git a/src/pickle_filter_spec.ts b/src/pickle_filter_spec.ts index 392283514..23529cd7a 100644 --- a/src/pickle_filter_spec.ts +++ b/src/pickle_filter_spec.ts @@ -1,7 +1,6 @@ import { beforeEach, describe, it } from 'mocha' import { expect } from 'chai' import PickleFilter from './pickle_filter' -import path from 'path' import { parse } from '../test/gherkin_helpers' describe('PickleFilter', () => { @@ -26,7 +25,7 @@ describe('PickleFilter', () => { gherkinDocument, } = await parse({ data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -55,7 +54,7 @@ describe('PickleFilter', () => { gherkinDocument, } = await parse({ data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -74,7 +73,7 @@ describe('PickleFilter', () => { gherkinDocument, } = await parse({ data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), - uri: path.resolve(cwd, 'features/b.feature'), + uri: 'features/b.feature', }) // Act @@ -84,14 +83,14 @@ describe('PickleFilter', () => { expect(result).to.eql(true) }) - it('returns true if pickle line does not match', async function () { + it('returns false if pickle line does not match', async function () { // Arrange const { pickles: [pickle], gherkinDocument, } = await parse({ data: ['Feature: a', '', 'Scenario: b', 'Given a step'].join('\n'), - uri: path.resolve(cwd, 'features/b.feature'), + uri: 'features/b.feature', }) // Act @@ -125,7 +124,7 @@ describe('PickleFilter', () => { 'Scenario: nameA descriptionA', 'Given a step', ].join('\n'), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -147,7 +146,7 @@ describe('PickleFilter', () => { 'Example: nameA descriptionA', 'Given a step', ].join('\n'), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -168,7 +167,7 @@ describe('PickleFilter', () => { 'Scenario: nameB descriptionB', 'Given a step', ].join('\n'), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -200,7 +199,7 @@ describe('PickleFilter', () => { 'Scenario: startA descriptionA endA', 'Given a step', ].join('\n'), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -232,7 +231,7 @@ describe('PickleFilter', () => { 'Scenario: nameA descriptionA', 'Given a step', ].join('\n'), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -253,7 +252,7 @@ describe('PickleFilter', () => { 'Scenario: nameB descriptionB', 'Given a step', ].join('\n'), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -274,7 +273,7 @@ describe('PickleFilter', () => { 'Scenario: nameC descriptionC', 'Given a step', ].join('\n'), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -306,7 +305,7 @@ describe('PickleFilter', () => { data: ['Feature: a', '@tagA', 'Scenario: a', 'Given a step'].join( '\n' ), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -323,7 +322,7 @@ describe('PickleFilter', () => { gherkinDocument, } = await parse({ data: ['Feature: a', 'Scenario: a', 'Given a step'].join('\n'), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -353,7 +352,7 @@ describe('PickleFilter', () => { data: ['Feature: a', '@tagA', 'Scenario: a', 'Given a step'].join( '\n' ), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -370,7 +369,7 @@ describe('PickleFilter', () => { gherkinDocument, } = await parse({ data: ['Feature: a', 'Scenario: a', 'Given a step'].join('\n'), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -403,7 +402,7 @@ describe('PickleFilter', () => { 'Scenario: a', 'Given a step', ].join('\n'), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -422,7 +421,7 @@ describe('PickleFilter', () => { data: ['Feature: a', '@tagA', 'Scenario: a', 'Given a step'].join( '\n' ), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -441,7 +440,7 @@ describe('PickleFilter', () => { data: ['Feature: a', '@tagB', 'Scenario: a', 'Given a step'].join( '\n' ), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -458,7 +457,7 @@ describe('PickleFilter', () => { gherkinDocument, } = await parse({ data: ['Feature: a', 'Scenario: a', 'Given a step'].join('\n'), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -491,7 +490,7 @@ describe('PickleFilter', () => { 'Scenario: a', 'Given a step', ].join('\n'), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -510,7 +509,7 @@ describe('PickleFilter', () => { data: ['Feature: a', '@tagA', 'Scenario: a', 'Given a step'].join( '\n' ), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -529,7 +528,7 @@ describe('PickleFilter', () => { data: ['Feature: a', '@tagB', 'Scenario: a', 'Given a step'].join( '\n' ), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -546,7 +545,7 @@ describe('PickleFilter', () => { gherkinDocument, } = await parse({ data: ['Feature: a', 'Scenario: a', 'Given a step'].join('\n'), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act @@ -580,7 +579,7 @@ describe('PickleFilter', () => { 'Scenario: nameA descriptionA', 'Given a step', ].join('\n'), - uri: path.resolve(cwd, 'features/b.feature'), + uri: 'features/b.feature', }) // Act @@ -602,7 +601,7 @@ describe('PickleFilter', () => { 'Scenario: nameA descriptionA', 'Given a step', ].join('\n'), - uri: path.resolve(cwd, 'features/b.feature'), + uri: 'features/b.feature', }) // Act @@ -619,7 +618,7 @@ describe('PickleFilter', () => { gherkinDocument, } = await parse({ data: ['Feature: a', 'Scenario: a', 'Given a step'].join('\n'), - uri: path.resolve(cwd, 'features/a.feature'), + uri: 'features/a.feature', }) // Act diff --git a/src/run/formatters.ts b/src/run/formatters.ts new file mode 100644 index 000000000..9da8cf5e2 --- /dev/null +++ b/src/run/formatters.ts @@ -0,0 +1,107 @@ +import Formatter, { IFormatterStream } from '../formatter' +import { EventEmitter } from 'events' +import { EventDataCollector } from '../formatter/helpers' +import { ISupportCodeLibrary } from '../support_code_library_builder/types' +import { promisify } from 'util' +import { doesNotHaveValue } from '../value_checker' +import { WriteStream as TtyWriteStream } from 'tty' +import FormatterBuilder from '../formatter/builder' +import fs from 'mz/fs' +import path from 'path' +import { DEFAULT_CUCUMBER_PUBLISH_URL } from '../formatter/publish' +import HttpStream from '../formatter/http_stream' +import { Writable } from 'stream' +import { IFormatterConfiguration } from '../configuration' + +export async function initializeFormatters({ + cwd, + stdout, + eventBroadcaster, + eventDataCollector, + configuration = {}, + supportCodeLibrary, +}: { + cwd: string + stdout: IFormatterStream + eventBroadcaster: EventEmitter + eventDataCollector: EventDataCollector + configuration: IFormatterConfiguration + supportCodeLibrary: ISupportCodeLibrary +}): Promise<() => Promise> { + async function initializeFormatter( + stream: IFormatterStream, + target: string, + type: string + ): Promise { + stream.on('error', (error) => { + console.error(error.message) + process.exit(1) + }) + const typeOptions = { + cwd, + eventBroadcaster, + eventDataCollector, + log: stream.write.bind(stream), + parsedArgvOptions: configuration.options ?? {}, + stream, + cleanup: + stream === stdout + ? async () => await Promise.resolve() + : promisify(stream.end.bind(stream)), + supportCodeLibrary, + } + if (doesNotHaveValue(configuration.options?.colorsEnabled)) { + typeOptions.parsedArgvOptions.colorsEnabled = ( + stream as TtyWriteStream + ).isTTY + } + if (type === 'progress-bar' && !(stream as TtyWriteStream).isTTY) { + console.warn( + `Cannot use 'progress-bar' formatter for output to '${target}' as not a TTY. Switching to 'progress' formatter.` + ) + type = 'progress' + } + return await FormatterBuilder.build(type, typeOptions) + } + + const formatters: Formatter[] = [] + + formatters.push( + await initializeFormatter( + stdout, + 'stdout', + configuration.stdout ?? 'progress' + ) + ) + + if (configuration.files) { + for (const [target, type] of Object.entries(configuration.files)) { + const stream: IFormatterStream = fs.createWriteStream(null, { + fd: await fs.open(path.resolve(cwd, target), 'w'), + }) + formatters.push(await initializeFormatter(stream, target, type)) + } + } + + if (configuration.publish) { + const { url = DEFAULT_CUCUMBER_PUBLISH_URL, token } = configuration.publish + const headers: { [key: string]: string } = {} + if (token !== undefined) { + headers.Authorization = `Bearer ${token}` + } + const stream = new HttpStream(url, 'GET', headers) + const readerStream = new Writable({ + objectMode: true, + write: function (responseBody: string, encoding, writeCallback) { + console.error(responseBody) + writeCallback() + }, + }) + stream.pipe(readerStream) + formatters.push(await initializeFormatter(stream, url, 'message')) + } + + return async function () { + await Promise.all(formatters.map(async (f) => await f.finished())) + } +} diff --git a/src/run/index.ts b/src/run/index.ts new file mode 100644 index 000000000..ac2fd9083 --- /dev/null +++ b/src/run/index.ts @@ -0,0 +1,2 @@ +export * from './runCucumber' +export * from './types' diff --git a/src/run/paths.ts b/src/run/paths.ts new file mode 100644 index 000000000..ab91f3354 --- /dev/null +++ b/src/run/paths.ts @@ -0,0 +1,116 @@ +import { promisify } from 'util' +import glob from 'glob' +import path from 'path' +import fs from 'mz/fs' +import { IRunConfiguration } from '../configuration' + +export async function resolvePaths( + cwd: string, + configuration: Pick +): Promise<{ + unexpandedFeaturePaths: string[] + featurePaths: string[] + supportCodePaths: string[] +}> { + const unexpandedFeaturePaths = await getUnexpandedFeaturePaths( + cwd, + configuration.sources.paths + ) + const featurePaths: string[] = await expandFeaturePaths( + cwd, + unexpandedFeaturePaths + ) + let unexpandedSupportCodePaths = configuration.support.paths ?? [] + if (unexpandedSupportCodePaths.length === 0) { + unexpandedSupportCodePaths = getFeatureDirectoryPaths(cwd, featurePaths) + } + const supportCodePaths = await expandPaths( + cwd, + unexpandedSupportCodePaths, + '.@(js|mjs)' + ) + return { + unexpandedFeaturePaths, + featurePaths, + supportCodePaths, + } +} + +async function expandPaths( + cwd: string, + unexpandedPaths: string[], + defaultExtension: string +): Promise { + const expandedPaths = await Promise.all( + unexpandedPaths.map(async (unexpandedPath) => { + const matches = await promisify(glob)(unexpandedPath, { + absolute: true, + cwd, + }) + const expanded = await Promise.all( + matches.map(async (match) => { + if (path.extname(match) === '') { + return await promisify(glob)(`${match}/**/*${defaultExtension}`) + } + return [match] + }) + ) + return expanded.flat() + }) + ) + return expandedPaths.flat().map((x) => path.normalize(x)) +} + +async function getUnexpandedFeaturePaths( + cwd: string, + args: string[] +): Promise { + if (args.length > 0) { + const nestedFeaturePaths = await Promise.all( + args.map(async (arg) => { + const filename = path.basename(arg) + if (filename[0] === '@') { + const filePath = path.join(cwd, arg) + const content = await fs.readFile(filePath, 'utf8') + return content.split('\n').map((x) => x.trim()) + } + return [arg] + }) + ) + const featurePaths = nestedFeaturePaths.flat() + if (featurePaths.length > 0) { + return featurePaths.filter((x) => x !== '') + } + } + return ['features/**/*.{feature,feature.md}'] +} + +function getFeatureDirectoryPaths( + cwd: string, + featurePaths: string[] +): string[] { + const featureDirs = featurePaths.map((featurePath) => { + let featureDir = path.dirname(featurePath) + let childDir: string + let parentDir = featureDir + while (childDir !== parentDir) { + childDir = parentDir + parentDir = path.dirname(childDir) + if (path.basename(parentDir) === 'features') { + featureDir = parentDir + break + } + } + return path.relative(cwd, featureDir) + }) + return [...new Set(featureDirs)] +} + +async function expandFeaturePaths( + cwd: string, + featurePaths: string[] +): Promise { + featurePaths = featurePaths.map((p) => p.replace(/(:\d+)*$/g, '')) // Strip line numbers + featurePaths = [...new Set(featurePaths)] // Deduplicate the feature files + return await expandPaths(cwd, featurePaths, '.feature') +} diff --git a/src/run/paths_spec.ts b/src/run/paths_spec.ts new file mode 100644 index 000000000..37d81eefb --- /dev/null +++ b/src/run/paths_spec.ts @@ -0,0 +1,226 @@ +import { promisify } from 'util' +import tmp, { DirOptions } from 'tmp' +import fsExtra from 'fs-extra' +import path from 'path' +import { describe, it } from 'mocha' +import { expect } from 'chai' +import { resolvePaths } from './paths' + +async function buildTestWorkingDirectory(): Promise { + const cwd = await promisify(tmp.dir)({ + unsafeCleanup: true, + }) + await fsExtra.mkdirp(path.join(cwd, 'features')) + return cwd +} + +describe('resolvePaths', () => { + describe('path to a feature', () => { + it('returns the appropriate .feature and support code paths', async function () { + // Arrange + const cwd = await buildTestWorkingDirectory() + const relativeFeaturePath = path.join('features', 'a.feature') + const featurePath = path.join(cwd, relativeFeaturePath) + await fsExtra.outputFile(featurePath, '') + const jsSupportCodePath = path.join(cwd, 'features', 'a.js') + await fsExtra.outputFile(jsSupportCodePath, '') + const esmSupportCodePath = path.join(cwd, 'features', 'a.mjs') + await fsExtra.outputFile(esmSupportCodePath, '') + + // Act + const { featurePaths, unexpandedFeaturePaths, supportCodePaths } = + await resolvePaths(cwd, { + sources: { + paths: [relativeFeaturePath], + }, + support: { + paths: [], + transpileWith: [], + }, + }) + + // Assert + expect(featurePaths).to.eql([featurePath]) + expect(unexpandedFeaturePaths).to.eql([relativeFeaturePath]) + expect(supportCodePaths).to.eql([jsSupportCodePath, esmSupportCodePath]) + }) + + it('deduplicates the .feature files before returning', async function () { + // Arrange + const cwd = await buildTestWorkingDirectory() + const relativeFeaturePath = path.join('features', 'a.feature') + const featurePath = path.join(cwd, relativeFeaturePath) + await fsExtra.outputFile(featurePath, '') + // Act + const { featurePaths } = await resolvePaths(cwd, { + sources: { + paths: [`${relativeFeaturePath}:3`, `${relativeFeaturePath}:4`], + }, + support: { + paths: [], + transpileWith: [], + }, + }) + + // Assert + expect(featurePaths).to.eql([featurePath]) + }) + + it('returns the appropriate .md and support code paths', async function () { + // Arrange + const cwd = await buildTestWorkingDirectory() + const relativeFeaturePath = path.join('features', 'a.feature.md') + const featurePath = path.join(cwd, relativeFeaturePath) + await fsExtra.outputFile(featurePath, '') + const supportCodePath = path.join(cwd, 'features', 'a.js') + await fsExtra.outputFile(supportCodePath, '') + + // Act + const { featurePaths, unexpandedFeaturePaths, supportCodePaths } = + await resolvePaths(cwd, { + sources: { paths: [relativeFeaturePath] }, + support: { + paths: [], + transpileWith: [], + }, + }) + + // Assert + expect(featurePaths).to.eql([featurePath]) + expect(unexpandedFeaturePaths).to.eql([relativeFeaturePath]) + expect(supportCodePaths).to.eql([supportCodePath]) + }) + }) + + describe('path to a nested feature', () => { + it('returns the appropriate .feature and support code paths', async function () { + // Arrange + const cwd = await buildTestWorkingDirectory() + const relativeFeaturePath = path.join('features', 'nested', 'a.feature') + const featurePath = path.join(cwd, relativeFeaturePath) + await fsExtra.outputFile(featurePath, '') + const supportCodePath = path.join(cwd, 'features', 'a.js') + await fsExtra.outputFile(supportCodePath, '') + + // Act + const { featurePaths, unexpandedFeaturePaths, supportCodePaths } = + await resolvePaths(cwd, { + sources: { paths: [relativeFeaturePath] }, + support: { + paths: [], + transpileWith: [], + }, + }) + + // Assert + expect(featurePaths).to.eql([featurePath]) + expect(unexpandedFeaturePaths).to.eql([relativeFeaturePath]) + expect(supportCodePaths).to.eql([supportCodePath]) + }) + + it('returns the appropriate .md and support code paths', async function () { + // Arrange + const cwd = await buildTestWorkingDirectory() + const relativeFeaturePath = path.join( + 'features', + 'nested', + 'a.feature.md' + ) + const featurePath = path.join(cwd, relativeFeaturePath) + await fsExtra.outputFile(featurePath, '') + const supportCodePath = path.join(cwd, 'features', 'a.js') + await fsExtra.outputFile(supportCodePath, '') + + // Act + const { featurePaths, unexpandedFeaturePaths, supportCodePaths } = + await resolvePaths(cwd, { + sources: { paths: [relativeFeaturePath] }, + support: { + paths: [], + transpileWith: [], + }, + }) + + // Assert + expect(featurePaths).to.eql([featurePath]) + expect(unexpandedFeaturePaths).to.eql([relativeFeaturePath]) + expect(supportCodePaths).to.eql([supportCodePath]) + }) + }) + + describe('path to an empty rerun file', () => { + it('returns empty featurePaths and support code paths', async function () { + // Arrange + const cwd = await buildTestWorkingDirectory() + + const relativeRerunPath = '@empty_rerun.txt' + const rerunPath = path.join(cwd, '@empty_rerun.txt') + await fsExtra.outputFile(rerunPath, '') + // Act + const { featurePaths, unexpandedFeaturePaths, supportCodePaths } = + await resolvePaths(cwd, { + sources: { paths: [relativeRerunPath] }, + support: { + paths: [], + transpileWith: [], + }, + }) + + // Assert + expect(featurePaths).to.eql([]) + expect(unexpandedFeaturePaths).to.eql([]) + expect(supportCodePaths).to.eql([]) + }) + }) + + describe('path to an rerun file with new line', () => { + it('returns empty featurePaths and support code paths', async function () { + // Arrange + const cwd = await buildTestWorkingDirectory() + + const relativeRerunPath = '@empty_rerun.txt' + const rerunPath = path.join(cwd, '@empty_rerun.txt') + await fsExtra.outputFile(rerunPath, '\n') + // Act + const { featurePaths, unexpandedFeaturePaths, supportCodePaths } = + await resolvePaths(cwd, { + sources: { paths: [relativeRerunPath] }, + support: { + paths: [], + transpileWith: [], + }, + }) + + // Assert + expect(featurePaths).to.eql([]) + expect(unexpandedFeaturePaths).to.eql([]) + expect(supportCodePaths).to.eql([]) + }) + }) + + describe('path to a rerun file with one new line character', () => { + it('returns empty featurePaths and support code paths', async function () { + // Arrange + const cwd = await buildTestWorkingDirectory() + + const relativeRerunPath = '@empty_rerun.txt' + const rerunPath = path.join(cwd, '@empty_rerun.txt') + await fsExtra.outputFile(rerunPath, '\n\n') + + // Act + const { featurePaths, unexpandedFeaturePaths, supportCodePaths } = + await resolvePaths(cwd, { + sources: { paths: [relativeRerunPath] }, + support: { + paths: [], + transpileWith: [], + }, + }) + + // Assert + expect(featurePaths).to.eql([]) + expect(unexpandedFeaturePaths).to.eql([]) + expect(supportCodePaths).to.eql([]) + }) + }) +}) diff --git a/src/run/runCucumber.ts b/src/run/runCucumber.ts new file mode 100644 index 000000000..cbd7f8aa9 --- /dev/null +++ b/src/run/runCucumber.ts @@ -0,0 +1,98 @@ +import { IdGenerator } from '@cucumber/messages' +import { EventEmitter } from 'events' +import { EventDataCollector } from '../formatter/helpers' +import { + emitMetaMessage, + emitSupportCodeMessages, + parseGherkinMessageStream, +} from '../cli/helpers' +import { GherkinStreams } from '@cucumber/gherkin-streams' +import PickleFilter from '../pickle_filter' +import { IRunConfiguration } from '../configuration' +import { IRunEnvironment, IRunResult } from './types' +import { resolvePaths } from './paths' +import { makeRuntime } from './runtime' +import { initializeFormatters } from './formatters' +import { getSupportCodeLibrary } from './support' + +export async function runCucumber( + configuration: IRunConfiguration, + environment: IRunEnvironment = { + cwd: process.cwd(), + stdout: process.stdout, + env: process.env, + } +): Promise { + const { cwd, stdout, env } = environment + const newId = IdGenerator.uuid() + + const { unexpandedFeaturePaths, featurePaths, supportCodePaths } = + await resolvePaths(cwd, configuration) + + const supportCodeLibrary = await getSupportCodeLibrary({ + cwd, + newId, + supportCodePaths, + supportCodeRequiredModules: configuration.support.transpileWith, + }) + + const eventBroadcaster = new EventEmitter() + const eventDataCollector = new EventDataCollector(eventBroadcaster) + + const cleanup = await initializeFormatters({ + cwd, + stdout, + eventBroadcaster, + eventDataCollector, + configuration: configuration.formats, + supportCodeLibrary, + }) + await emitMetaMessage(eventBroadcaster, env) + + const gherkinMessageStream = GherkinStreams.fromPaths(featurePaths, { + defaultDialect: configuration.sources.defaultDialect, + newId, + relativeTo: cwd, + }) + let pickleIds: string[] = [] + + if (featurePaths.length > 0) { + pickleIds = await parseGherkinMessageStream({ + cwd, + eventBroadcaster, + eventDataCollector, + gherkinMessageStream, + order: configuration.sources.order ?? 'defined', + pickleFilter: new PickleFilter({ + cwd, + featurePaths: unexpandedFeaturePaths, + names: configuration.sources.names, + tagExpression: configuration.sources.tagExpression, + }), + }) + } + emitSupportCodeMessages({ + eventBroadcaster, + supportCodeLibrary, + newId, + }) + + const runtime = makeRuntime({ + cwd, + eventBroadcaster, + eventDataCollector, + pickleIds, + newId, + supportCodeLibrary, + supportCodePaths, + supportCodeRequiredModules: configuration.support.transpileWith, + options: configuration.runtime, + }) + const success = await runtime.start() + await cleanup() + + return { + success, + support: supportCodeLibrary, + } +} diff --git a/src/run/runtime.ts b/src/run/runtime.ts new file mode 100644 index 000000000..6f827fb46 --- /dev/null +++ b/src/run/runtime.ts @@ -0,0 +1,60 @@ +import Runtime, { + DEFAULT_RUNTIME_OPTIONS, + IRuntime, + IRuntimeOptions, +} from '../runtime' +import { EventEmitter } from 'events' +import { EventDataCollector } from '../formatter/helpers' +import { IdGenerator } from '@cucumber/messages' +import { ISupportCodeLibrary } from '../support_code_library_builder/types' +import Coordinator from '../runtime/parallel/coordinator' + +export function makeRuntime({ + cwd, + eventBroadcaster, + eventDataCollector, + pickleIds, + newId, + supportCodeLibrary, + supportCodePaths, + supportCodeRequiredModules, + options: { parallel = 0, ...runtimeOptions } = {}, +}: { + cwd: string + eventBroadcaster: EventEmitter + eventDataCollector: EventDataCollector + newId: IdGenerator.NewId + pickleIds: string[] + supportCodeLibrary: ISupportCodeLibrary + supportCodePaths: string[] + supportCodeRequiredModules: string[] + options: Partial & { parallel?: number } +}): IRuntime { + // sprinkle specified runtime options over the defaults + const options = { + ...DEFAULT_RUNTIME_OPTIONS, + ...runtimeOptions, + } + if (parallel > 0) { + return new Coordinator({ + cwd, + eventBroadcaster, + eventDataCollector, + pickleIds, + options, + newId, + supportCodeLibrary, + supportCodePaths, + supportCodeRequiredModules, + numberOfWorkers: parallel, + }) + } + return new Runtime({ + eventBroadcaster, + eventDataCollector, + newId, + pickleIds, + supportCodeLibrary, + options, + }) +} diff --git a/src/run/support.ts b/src/run/support.ts new file mode 100644 index 000000000..599497ae6 --- /dev/null +++ b/src/run/support.ts @@ -0,0 +1,31 @@ +import { IdGenerator } from '@cucumber/messages' +import { ISupportCodeLibrary } from '../support_code_library_builder/types' +import supportCodeLibraryBuilder from '../support_code_library_builder' +import { pathToFileURL } from 'url' +import { isJavaScript } from '../cli/helpers' + +// eslint-disable-next-line @typescript-eslint/no-var-requires +const { importer } = require('../importer') + +export async function getSupportCodeLibrary({ + cwd, + newId, + supportCodeRequiredModules, + supportCodePaths, +}: { + cwd: string + newId: IdGenerator.NewId + supportCodeRequiredModules: string[] + supportCodePaths: string[] +}): Promise { + supportCodeLibraryBuilder.reset(cwd, newId) + supportCodeRequiredModules.map((module) => require(module)) + for (const codePath of supportCodePaths) { + if (supportCodeRequiredModules.length || !isJavaScript(codePath)) { + require(codePath) + } else { + await importer(pathToFileURL(codePath)) + } + } + return supportCodeLibraryBuilder.finalize() +} diff --git a/src/run/types.ts b/src/run/types.ts new file mode 100644 index 000000000..a3f36b8fc --- /dev/null +++ b/src/run/types.ts @@ -0,0 +1,13 @@ +import { ISupportCodeLibrary } from '../support_code_library_builder/types' +import { IFormatterStream } from '../formatter' + +export interface IRunEnvironment { + cwd: string + stdout: IFormatterStream + env: NodeJS.ProcessEnv +} + +export interface IRunResult { + success: boolean + support: ISupportCodeLibrary +} diff --git a/src/runtime/assemble_test_cases.ts b/src/runtime/assemble_test_cases.ts new file mode 100644 index 000000000..a07921309 --- /dev/null +++ b/src/runtime/assemble_test_cases.ts @@ -0,0 +1,135 @@ +import { EventEmitter } from 'events' +import * as messages from '@cucumber/messages' +import { IdGenerator } from '@cucumber/messages' +import { ISupportCodeLibrary } from '../support_code_library_builder/types' +import { Group } from '@cucumber/cucumber-expressions' +import { doesHaveValue } from '../value_checker' + +export declare type IAssembledTestCases = Record + +export interface IAssembleTestCasesOptions { + eventBroadcaster: EventEmitter + newId: IdGenerator.NewId + pickles: messages.Pickle[] + supportCodeLibrary: ISupportCodeLibrary +} + +export async function assembleTestCases({ + eventBroadcaster, + newId, + pickles, + supportCodeLibrary, +}: IAssembleTestCasesOptions): Promise { + const result: IAssembledTestCases = {} + for (const pickle of pickles) { + const { id: pickleId } = pickle + const testCaseId = newId() + const fromBeforeHooks: messages.TestStep[] = makeBeforeHookSteps({ + supportCodeLibrary, + pickle, + newId, + }) + const fromStepDefinitions: messages.TestStep[] = makeSteps({ + pickle, + supportCodeLibrary, + newId, + }) + const fromAfterHooks: messages.TestStep[] = makeAfterHookSteps({ + supportCodeLibrary, + pickle, + newId, + }) + const testCase: messages.TestCase = { + pickleId, + id: testCaseId, + testSteps: [ + ...fromBeforeHooks, + ...fromStepDefinitions, + ...fromAfterHooks, + ], + } + eventBroadcaster.emit('envelope', { testCase }) + result[pickleId] = testCase + } + return result +} + +function makeAfterHookSteps({ + supportCodeLibrary, + pickle, + newId, +}: { + supportCodeLibrary: ISupportCodeLibrary + pickle: messages.Pickle + newId: IdGenerator.NewId +}): messages.TestStep[] { + return supportCodeLibrary.afterTestCaseHookDefinitions + .slice(0) + .reverse() + .filter((hookDefinition) => hookDefinition.appliesToTestCase(pickle)) + .map((hookDefinition) => ({ + id: newId(), + hookId: hookDefinition.id, + })) +} + +function makeBeforeHookSteps({ + supportCodeLibrary, + pickle, + newId, +}: { + supportCodeLibrary: ISupportCodeLibrary + pickle: messages.Pickle + newId: IdGenerator.NewId +}): messages.TestStep[] { + return supportCodeLibrary.beforeTestCaseHookDefinitions + .filter((hookDefinition) => hookDefinition.appliesToTestCase(pickle)) + .map((hookDefinition) => ({ + id: newId(), + hookId: hookDefinition.id, + })) +} + +function makeSteps({ + pickle, + supportCodeLibrary, + newId, +}: { + pickle: messages.Pickle + supportCodeLibrary: ISupportCodeLibrary + newId: () => string +}): messages.TestStep[] { + return pickle.steps.map((pickleStep) => { + const stepDefinitions = supportCodeLibrary.stepDefinitions.filter( + (stepDefinition) => stepDefinition.matchesStepName(pickleStep.text) + ) + return { + id: newId(), + pickleStepId: pickleStep.id, + stepDefinitionIds: stepDefinitions.map( + (stepDefinition) => stepDefinition.id + ), + stepMatchArgumentsLists: stepDefinitions.map((stepDefinition) => { + const result = stepDefinition.expression.match(pickleStep.text) + return { + stepMatchArguments: result.map((arg) => { + return { + group: mapArgumentGroup(arg.group), + parameterTypeName: arg.parameterType.name, + } + }), + } + }), + } + }) +} + +function mapArgumentGroup(group: Group): messages.Group { + return { + start: group.start, + value: group.value, + children: doesHaveValue(group.children) + ? group.children.map((child) => mapArgumentGroup(child)) + : undefined, + } +} diff --git a/src/runtime/assemble_test_cases_spec.ts b/src/runtime/assemble_test_cases_spec.ts new file mode 100644 index 000000000..1e72bfe22 --- /dev/null +++ b/src/runtime/assemble_test_cases_spec.ts @@ -0,0 +1,296 @@ +import { IdGenerator } from '@cucumber/messages' +import * as messages from '@cucumber/messages' +import { ISupportCodeLibrary } from '../support_code_library_builder/types' +import { EventEmitter } from 'events' +import { assembleTestCases, IAssembledTestCases } from './assemble_test_cases' +import { afterEach, beforeEach, describe, it } from 'mocha' +import FakeTimers, { InstalledClock } from '@sinonjs/fake-timers' +import timeMethods from '../time' +import { buildSupportCodeLibrary } from '../../test/runtime_helpers' +import { parse } from '../../test/gherkin_helpers' +import { expect } from 'chai' + +interface IRequest { + gherkinDocument: messages.GherkinDocument + pickles: messages.Pickle[] + supportCodeLibrary: ISupportCodeLibrary +} + +interface IResponse { + envelopes: messages.Envelope[] + result: IAssembledTestCases +} + +async function testAssembleTestCases(options: IRequest): Promise { + const envelopes: messages.Envelope[] = [] + const eventBroadcaster = new EventEmitter() + eventBroadcaster.on('envelope', (e) => envelopes.push(e)) + const result = await assembleTestCases({ + eventBroadcaster, + newId: IdGenerator.incrementing(), + pickles: options.pickles, + supportCodeLibrary: options.supportCodeLibrary, + }) + return { envelopes, result } +} + +describe('assembleTestCases', () => { + let clock: InstalledClock + + beforeEach(() => { + clock = FakeTimers.withGlobal(timeMethods).install() + }) + + afterEach(() => { + clock.uninstall() + }) + + describe('assembleTestCases()', () => { + it('emits testCase messages', async () => { + // Arrange + const supportCodeLibrary = buildSupportCodeLibrary(({ Given }) => { + Given('a step', function () { + clock.tick(1) + }) + }) + const { gherkinDocument, pickles } = await parse({ + data: [ + 'Feature: a', + 'Scenario: b', + 'Given a step', + 'Scenario: c', + 'Given a step', + ].join('\n'), + uri: 'a.feature', + }) + + // Act + const { envelopes, result } = await testAssembleTestCases({ + gherkinDocument, + pickles, + supportCodeLibrary, + }) + + const testCase1: messages.TestCase = { + id: '0', + pickleId: pickles[0].id, + testSteps: [ + { + id: '1', + pickleStepId: pickles[0].steps[0].id, + stepDefinitionIds: [supportCodeLibrary.stepDefinitions[0].id], + stepMatchArgumentsLists: [ + { + stepMatchArguments: [], + }, + ], + }, + ], + } + + const testCase2: messages.TestCase = { + id: '2', + pickleId: pickles[1].id, + testSteps: [ + { + id: '3', + pickleStepId: pickles[1].steps[0].id, + stepDefinitionIds: [supportCodeLibrary.stepDefinitions[0].id], + stepMatchArgumentsLists: [ + { + stepMatchArguments: [], + }, + ], + }, + ], + } + + // Assert + expect(envelopes).to.eql([ + { + testCase: testCase1, + }, + { + testCase: testCase2, + }, + ]) + + expect(Object.keys(result)).to.eql([pickles[0].id, pickles[1].id]) + expect(Object.values(result)).to.eql([testCase1, testCase2]) + }) + + describe('with a parameterised step', () => { + it('emits stepMatchArgumentLists correctly within the testCase message', async () => { + // Arrange + const supportCodeLibrary = buildSupportCodeLibrary(({ Given }) => { + Given('a step with {int} and {string} parameters', function () { + clock.tick(1) + }) + }) + const { gherkinDocument, pickles } = await parse({ + data: [ + 'Feature: a', + 'Scenario: b', + 'Given a step with 1 and "foo" parameters', + ].join('\n'), + uri: 'a.feature', + }) + + // Act + const { envelopes } = await testAssembleTestCases({ + gherkinDocument, + pickles, + supportCodeLibrary, + }) + + expect( + envelopes[0].testCase.testSteps[0].stepMatchArgumentsLists + ).to.deep.eq([ + { + stepMatchArguments: [ + { + group: { + children: [], + start: 12, + value: '1', + }, + parameterTypeName: 'int', + }, + { + group: { + children: [ + { + children: [ + { + start: undefined, + value: undefined, + children: [], + }, + ], + start: 19, + value: 'foo', + }, + { + start: undefined, + value: undefined, + children: [ + { + start: undefined, + value: undefined, + children: [], + }, + ], + }, + ], + start: 18, + value: '"foo"', + }, + parameterTypeName: 'string', + }, + ], + }, + ]) + }) + }) + + describe('with test case hooks', () => { + it('emits the expected envelopes and returns a skipped result', async () => { + // Arrange + const supportCodeLibrary = buildSupportCodeLibrary( + ({ Given, Before, After }) => { + Given('a step', function () { + clock.tick(1) + }) + Before(function () {}) // eslint-disable-line @typescript-eslint/no-empty-function + After(function () {}) // eslint-disable-line @typescript-eslint/no-empty-function + } + ) + const { gherkinDocument, pickles } = await parse({ + data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), + uri: 'a.feature', + }) + + // Act + const { envelopes } = await testAssembleTestCases({ + gherkinDocument, + pickles, + supportCodeLibrary, + }) + + // Assert + expect(envelopes[0]).to.eql({ + testCase: { + id: '0', + pickleId: pickles[0].id, + testSteps: [ + { + id: '1', + hookId: supportCodeLibrary.beforeTestCaseHookDefinitions[0].id, + }, + { + id: '2', + pickleStepId: pickles[0].steps[0].id, + stepDefinitionIds: [supportCodeLibrary.stepDefinitions[0].id], + stepMatchArgumentsLists: [ + { + stepMatchArguments: [], + }, + ], + }, + { + id: '3', + hookId: supportCodeLibrary.afterTestCaseHookDefinitions[0].id, + }, + ], + }, + }) + }) + }) + + describe('with step hooks', () => { + it('emits the expected envelopes and returns a skipped result', async () => { + // Arrange + const supportCodeLibrary = buildSupportCodeLibrary( + ({ Given, BeforeStep, AfterStep }) => { + Given('a step', function () { + clock.tick(1) + }) + BeforeStep(function () {}) // eslint-disable-line @typescript-eslint/no-empty-function + AfterStep(function () {}) // eslint-disable-line @typescript-eslint/no-empty-function + } + ) + const { gherkinDocument, pickles } = await parse({ + data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), + uri: 'a.feature', + }) + + // Act + const { envelopes } = await testAssembleTestCases({ + gherkinDocument, + pickles, + supportCodeLibrary, + }) + + // Assert + expect(envelopes[0]).to.eql({ + testCase: { + id: '0', + pickleId: pickles[0].id, + testSteps: [ + { + id: '1', + pickleStepId: pickles[0].steps[0].id, + stepDefinitionIds: [supportCodeLibrary.stepDefinitions[0].id], + stepMatchArgumentsLists: [ + { + stepMatchArguments: [], + }, + ], + }, + ], + }, + }) + }) + }) + }) +}) diff --git a/src/runtime/attachment_manager/index.ts b/src/runtime/attachment_manager/index.ts index 8c4a4967c..d3ea34255 100644 --- a/src/runtime/attachment_manager/index.ts +++ b/src/runtime/attachment_manager/index.ts @@ -1,10 +1,10 @@ import isStream from 'is-stream' import { Readable } from 'stream' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { doesHaveValue, doesNotHaveValue } from '../../value_checker' export interface IAttachmentMedia { - encoding: messages.Attachment.ContentEncoding + encoding: messages.AttachmentContentEncoding contentType: string } @@ -53,12 +53,12 @@ export default class AttachmentManager { } if (mediaType.startsWith('base64:')) { this.createStringAttachment(data, { - encoding: messages.Attachment.ContentEncoding.BASE64, + encoding: messages.AttachmentContentEncoding.BASE64, contentType: mediaType.replace('base64:', ''), }) } else { this.createStringAttachment(data, { - encoding: messages.Attachment.ContentEncoding.IDENTITY, + encoding: messages.AttachmentContentEncoding.IDENTITY, contentType: mediaType, }) } @@ -71,7 +71,7 @@ export default class AttachmentManager { createBufferAttachment(data: Buffer, mediaType: string): void { this.createStringAttachment(data.toString('base64'), { - encoding: messages.Attachment.ContentEncoding.BASE64, + encoding: messages.AttachmentContentEncoding.BASE64, contentType: mediaType, }) } diff --git a/src/runtime/attachment_manager/index_spec.ts b/src/runtime/attachment_manager/index_spec.ts index 482cd8f84..ecf2c45f3 100644 --- a/src/runtime/attachment_manager/index_spec.ts +++ b/src/runtime/attachment_manager/index_spec.ts @@ -2,7 +2,6 @@ import { describe, it } from 'mocha' import { expect } from 'chai' import AttachmentManager, { IAttachment } from './' import stream, { Readable } from 'stream' -import { messages } from '@cucumber/messages' describe('AttachmentManager', () => { describe('create()', () => { @@ -28,7 +27,7 @@ describe('AttachmentManager', () => { data: 'bXkgc3RyaW5n', media: { contentType: 'text/special', - encoding: messages.Attachment.ContentEncoding.BASE64, + encoding: 'BASE64', }, }, ]) @@ -99,7 +98,7 @@ describe('AttachmentManager', () => { data: 'bXkgc3RyaW5n', media: { contentType: 'text/special', - encoding: messages.Attachment.ContentEncoding.BASE64, + encoding: 'BASE64', }, }, ]) @@ -137,7 +136,7 @@ describe('AttachmentManager', () => { data: 'bXkgc3RyaW5n', media: { contentType: 'text/special', - encoding: messages.Attachment.ContentEncoding.BASE64, + encoding: 'BASE64', }, }, ]) @@ -197,7 +196,7 @@ describe('AttachmentManager', () => { data: 'my string', media: { contentType: 'text/special', - encoding: messages.Attachment.ContentEncoding.IDENTITY, + encoding: 'IDENTITY', }, }, ]) @@ -225,7 +224,7 @@ describe('AttachmentManager', () => { data: 'bXkgc3RyaW5n', media: { contentType: 'text/special', - encoding: messages.Attachment.ContentEncoding.BASE64, + encoding: 'BASE64', }, }, ]) @@ -250,7 +249,7 @@ describe('AttachmentManager', () => { data: 'my string', media: { contentType: 'text/plain', - encoding: messages.Attachment.ContentEncoding.IDENTITY, + encoding: 'IDENTITY', }, }, ]) @@ -276,7 +275,7 @@ describe('AttachmentManager', () => { data: 'stuff happened', media: { contentType: 'text/x.cucumber.log+plain', - encoding: messages.Attachment.ContentEncoding.IDENTITY, + encoding: 'IDENTITY', }, }, ]) diff --git a/src/runtime/helpers.ts b/src/runtime/helpers.ts index 5d9ac90d7..2b5c00643 100644 --- a/src/runtime/helpers.ts +++ b/src/runtime/helpers.ts @@ -3,7 +3,7 @@ import Table from 'cli-table3' import indentString from 'indent-string' import { PickleTagFilter } from '../pickle_filter' import StepDefinition from '../models/step_definition' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { IRuntimeOptions } from '.' export function getAmbiguousStepException( @@ -46,15 +46,18 @@ export function getAmbiguousStepException( } export function retriesForPickle( - pickle: messages.IPickle, + pickle: messages.Pickle, options: IRuntimeOptions ): number { + if (!options.retry) { + return 0 + } const retries = options.retry if (retries === 0) { return 0 } const retryTagFilter = options.retryTagFilter - if (retryTagFilter === '') { + if (!retryTagFilter) { return retries } const pickleTagFilter = new PickleTagFilter(retryTagFilter) @@ -63,3 +66,21 @@ export function retriesForPickle( } return 0 } + +export function shouldCauseFailure( + status: messages.TestStepResultStatus, + options: IRuntimeOptions +): boolean { + if (options.dryRun) { + return false + } + const failureStatuses: messages.TestStepResultStatus[] = [ + messages.TestStepResultStatus.AMBIGUOUS, + messages.TestStepResultStatus.FAILED, + messages.TestStepResultStatus.UNDEFINED, + ] + if (options.strict) { + failureStatuses.push(messages.TestStepResultStatus.PENDING) + } + return failureStatuses.includes(status) +} diff --git a/src/runtime/helpers_spec.ts b/src/runtime/helpers_spec.ts index 484342138..3aae88fe8 100644 --- a/src/runtime/helpers_spec.ts +++ b/src/runtime/helpers_spec.ts @@ -70,7 +70,10 @@ describe('Helpers', () => { it('returns options.retry is set and the pickle tags match options.retryTagFilter', async () => { // Arrange const pickle = await getPickleWithTags(['@retry']) - const options = buildOptions({ retry: 1, retryTagFilter: '@retry' }) + const options = buildOptions({ + retry: 1, + retryTagFilter: '@retry', + }) // Act const result = retriesForPickle(pickle, options) @@ -82,7 +85,10 @@ describe('Helpers', () => { it('returns 0 if options.retry is set but the pickle tags do not match options.retryTagFilter', async () => { // Arrange const pickle = await getPickleWithTags([]) - const options = buildOptions({ retry: 1, retryTagFilter: '@retry' }) + const options = buildOptions({ + retry: 1, + retryTagFilter: '@retry', + }) // Act const result = retriesForPickle(pickle, options) diff --git a/src/runtime/index.ts b/src/runtime/index.ts index 3f0ed5e21..675b46553 100644 --- a/src/runtime/index.ts +++ b/src/runtime/index.ts @@ -1,22 +1,21 @@ -import _, { clone } from 'lodash' import { EventDataCollector, formatLocation } from '../formatter/helpers' -import bluebird from 'bluebird' import StackTraceFilter from '../stack_trace_filter' -import Status from '../status' import UserCodeRunner from '../user_code_runner' import VError from 'verror' -import { retriesForPickle } from './helpers' -import { IdGenerator, messages } from '@cucumber/messages' -import PickleRunner from './pickle_runner' +import { retriesForPickle, shouldCauseFailure } from './helpers' +import { IdGenerator } from '@cucumber/messages' +import * as messages from '@cucumber/messages' +import TestCaseRunner from './test_case_runner' import { EventEmitter } from 'events' import { ISupportCodeLibrary } from '../support_code_library_builder/types' import TestRunHookDefinition from '../models/test_run_hook_definition' import { doesHaveValue, valueOrDefault } from '../value_checker' -import { - ITestRunStopwatch, - PredictableTestRunStopwatch, - RealTestRunStopwatch, -} from './stopwatch' +import { ITestRunStopwatch, RealTestRunStopwatch } from './stopwatch' +import { assembleTestCases } from './assemble_test_cases' + +export interface IRuntime { + start: () => Promise +} export interface INewRuntimeOptions { eventBroadcaster: EventEmitter @@ -29,7 +28,6 @@ export interface INewRuntimeOptions { export interface IRuntimeOptions { dryRun: boolean - predictableIds: boolean failFast: boolean filterStacktraces: boolean retry: number @@ -38,7 +36,17 @@ export interface IRuntimeOptions { worldParameters: any } -export default class Runtime { +export const DEFAULT_RUNTIME_OPTIONS: IRuntimeOptions = { + dryRun: false, + failFast: false, + filterStacktraces: true, + retry: 0, + retryTagFilter: '', + strict: true, + worldParameters: {}, +} + +export default class Runtime implements IRuntime { private readonly eventBroadcaster: EventEmitter private readonly eventDataCollector: EventDataCollector private readonly stopwatch: ITestRunStopwatch @@ -59,9 +67,7 @@ export default class Runtime { }: INewRuntimeOptions) { this.eventBroadcaster = eventBroadcaster this.eventDataCollector = eventDataCollector - this.stopwatch = options.predictableIds - ? new PredictableTestRunStopwatch() - : new RealTestRunStopwatch() + this.stopwatch = new RealTestRunStopwatch() this.newId = newId this.options = options this.pickleIds = pickleIds @@ -77,46 +83,47 @@ export default class Runtime { if (this.options.dryRun) { return } - await bluebird.each( - definitions, - async (hookDefinition: TestRunHookDefinition) => { - const { error } = await UserCodeRunner.run({ - argsArray: [], - fn: hookDefinition.code, - thisArg: null, - timeoutInMilliseconds: valueOrDefault( - hookDefinition.options.timeout, - this.supportCodeLibrary.defaultTimeout - ), - }) - if (doesHaveValue(error)) { - const location = formatLocation(hookDefinition) - throw new VError( - error, - `${name} hook errored, process exiting: ${location}` - ) - } + for (const hookDefinition of definitions) { + const { error } = await UserCodeRunner.run({ + argsArray: [], + fn: hookDefinition.code, + thisArg: null, + timeoutInMilliseconds: valueOrDefault( + hookDefinition.options.timeout, + this.supportCodeLibrary.defaultTimeout + ), + }) + if (doesHaveValue(error)) { + const location = formatLocation(hookDefinition) + throw new VError( + error, + `${name} hook errored, process exiting: ${location}` + ) } - ) + } } - async runPickle(pickleId: string): Promise { + async runTestCase( + pickleId: string, + testCase: messages.TestCase + ): Promise { const pickle = this.eventDataCollector.getPickle(pickleId) const retries = retriesForPickle(pickle, this.options) const skip = this.options.dryRun || (this.options.failFast && !this.success) - const pickleRunner = new PickleRunner({ + const testCaseRunner = new TestCaseRunner({ eventBroadcaster: this.eventBroadcaster, stopwatch: this.stopwatch, gherkinDocument: this.eventDataCollector.getGherkinDocument(pickle.uri), newId: this.newId, pickle, + testCase, retries, skip, supportCodeLibrary: this.supportCodeLibrary, worldParameters: this.options.worldParameters, }) - const status = await pickleRunner.run() - if (this.shouldCauseFailure(status)) { + const status = await testCaseRunner.run() + if (shouldCauseFailure(status, this.options)) { this.success = false } } @@ -125,45 +132,43 @@ export default class Runtime { if (this.options.filterStacktraces) { this.stackTraceFilter.filter() } - this.eventBroadcaster.emit( - 'envelope', - new messages.Envelope({ - testRunStarted: { - timestamp: this.stopwatch.timestamp(), - }, - }) - ) + const testRunStarted: messages.Envelope = { + testRunStarted: { + timestamp: this.stopwatch.timestamp(), + }, + } + this.eventBroadcaster.emit('envelope', testRunStarted) this.stopwatch.start() await this.runTestRunHooks( this.supportCodeLibrary.beforeTestRunHookDefinitions, 'a BeforeAll' ) - await bluebird.each(this.pickleIds, this.runPickle.bind(this)) + const assembledTestCases = await assembleTestCases({ + eventBroadcaster: this.eventBroadcaster, + newId: this.newId, + pickles: this.pickleIds.map((pickleId) => + this.eventDataCollector.getPickle(pickleId) + ), + supportCodeLibrary: this.supportCodeLibrary, + }) + for (const pickleId of this.pickleIds) { + await this.runTestCase(pickleId, assembledTestCases[pickleId]) + } await this.runTestRunHooks( - clone(this.supportCodeLibrary.afterTestRunHookDefinitions).reverse(), + this.supportCodeLibrary.afterTestRunHookDefinitions.slice(0).reverse(), 'an AfterAll' ) this.stopwatch.stop() - this.eventBroadcaster.emit( - 'envelope', - messages.Envelope.fromObject({ - testRunFinished: { - timestamp: this.stopwatch.timestamp(), - }, - }) - ) + const testRunFinished: messages.Envelope = { + testRunFinished: { + timestamp: this.stopwatch.timestamp(), + success: this.success, + }, + } + this.eventBroadcaster.emit('envelope', testRunFinished) if (this.options.filterStacktraces) { this.stackTraceFilter.unfilter() } return this.success } - - shouldCauseFailure( - status: messages.TestStepFinished.TestStepResult.Status - ): boolean { - return ( - _.includes([Status.AMBIGUOUS, Status.FAILED, Status.UNDEFINED], status) || - (status === Status.PENDING && this.options.strict) - ) - } } diff --git a/src/runtime/parallel/command_types.ts b/src/runtime/parallel/command_types.ts index b8759b247..3a884550d 100644 --- a/src/runtime/parallel/command_types.ts +++ b/src/runtime/parallel/command_types.ts @@ -1,4 +1,4 @@ -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { IRuntimeOptions } from '../index' // Messages from Coordinator to Worker @@ -13,15 +13,23 @@ export interface IWorkerCommandInitialize { filterStacktraces: boolean supportCodePaths: string[] supportCodeRequiredModules: string[] + supportCodeIds?: ICanonicalSupportCodeIds options: IRuntimeOptions } +export interface ICanonicalSupportCodeIds { + stepDefinitionIds: string[] + beforeTestCaseHookDefinitionIds: string[] + afterTestCaseHookDefinitionIds: string[] +} + export interface IWorkerCommandRun { retries: number skip: boolean elapsed: number - pickle: messages.IPickle - gherkinDocument: messages.IGherkinDocument + pickle: messages.Pickle + testCase: messages.TestCase + gherkinDocument: messages.GherkinDocument } // Messages from Worker to Coordinator @@ -29,11 +37,4 @@ export interface IWorkerCommandRun { export interface ICoordinatorReport { jsonEnvelope?: string ready?: boolean - supportCodeIds?: ICoordinatorReportSupportCodeIds -} - -export interface ICoordinatorReportSupportCodeIds { - stepDefinitionIds: string[] - beforeTestCaseHookDefinitionIds: string[] - afterTestCaseHookDefinitionIds: string[] } diff --git a/src/runtime/parallel/coordinator.ts b/src/runtime/parallel/coordinator.ts index 04b813c82..2dc8255ef 100644 --- a/src/runtime/parallel/coordinator.ts +++ b/src/runtime/parallel/coordinator.ts @@ -1,24 +1,16 @@ -import _ from 'lodash' import { ChildProcess, fork } from 'child_process' import path from 'path' -import Status from '../../status' -import { retriesForPickle } from '../helpers' -import { messages } from '@cucumber/messages' +import { retriesForPickle, shouldCauseFailure } from '../helpers' +import * as messages from '@cucumber/messages' import { EventEmitter } from 'events' import { EventDataCollector } from '../../formatter/helpers' -import { IRuntimeOptions } from '..' +import { IRuntime, IRuntimeOptions } from '..' import { ISupportCodeLibrary } from '../../support_code_library_builder/types' -import { - ICoordinatorReport, - ICoordinatorReportSupportCodeIds, - IWorkerCommand, -} from './command_types' +import { ICoordinatorReport, IWorkerCommand } from './command_types' import { doesHaveValue } from '../../value_checker' -import { - ITestRunStopwatch, - PredictableTestRunStopwatch, - RealTestRunStopwatch, -} from '../stopwatch' +import { ITestRunStopwatch, RealTestRunStopwatch } from '../stopwatch' +import { assembleTestCases, IAssembledTestCases } from '../assemble_test_cases' +import { IdGenerator } from '@cucumber/messages' const runWorkerPath = path.resolve(__dirname, 'run_worker.js') @@ -27,10 +19,12 @@ export interface INewCoordinatorOptions { eventBroadcaster: EventEmitter eventDataCollector: EventDataCollector options: IRuntimeOptions + newId: IdGenerator.NewId pickleIds: string[] supportCodeLibrary: ISupportCodeLibrary supportCodePaths: string[] supportCodeRequiredModules: string[] + numberOfWorkers: number } const enum WorkerState { @@ -48,23 +42,25 @@ interface IWorker { interface IPicklePlacement { index: number - pickle: messages.IPickle + pickle: messages.Pickle } -export default class Coordinator { +export default class Coordinator implements IRuntime { private readonly cwd: string private readonly eventBroadcaster: EventEmitter private readonly eventDataCollector: EventDataCollector private readonly stopwatch: ITestRunStopwatch private onFinish: (success: boolean) => void private readonly options: IRuntimeOptions + private readonly newId: IdGenerator.NewId private readonly pickleIds: string[] - private inProgressPickles: Record + private assembledTestCases: IAssembledTestCases + private inProgressPickles: Record private workers: Record - private supportCodeIdMap: Record private readonly supportCodeLibrary: ISupportCodeLibrary private readonly supportCodePaths: string[] private readonly supportCodeRequiredModules: string[] + private readonly numberOfWorkers: number private success: boolean private idleInterventions: number @@ -74,44 +70,38 @@ export default class Coordinator { eventDataCollector, pickleIds, options, + newId, supportCodeLibrary, supportCodePaths, supportCodeRequiredModules, + numberOfWorkers, }: INewCoordinatorOptions) { this.cwd = cwd this.eventBroadcaster = eventBroadcaster this.eventDataCollector = eventDataCollector - this.stopwatch = options.predictableIds - ? new PredictableTestRunStopwatch() - : new RealTestRunStopwatch() + this.stopwatch = new RealTestRunStopwatch() this.options = options + this.newId = newId this.supportCodeLibrary = supportCodeLibrary this.supportCodePaths = supportCodePaths this.supportCodeRequiredModules = supportCodeRequiredModules this.pickleIds = Array.from(pickleIds) + this.numberOfWorkers = numberOfWorkers this.success = true this.workers = {} this.inProgressPickles = {} - this.supportCodeIdMap = {} this.idleInterventions = 0 } parseWorkerMessage(worker: IWorker, message: ICoordinatorReport): void { - if (doesHaveValue(message.supportCodeIds)) { - this.saveDefinitionIdMapping(message.supportCodeIds) - } else if (message.ready) { + if (message.ready) { worker.state = WorkerState.idle this.awakenWorkers(worker) } else if (doesHaveValue(message.jsonEnvelope)) { - const envelope = messages.Envelope.fromObject( - JSON.parse(message.jsonEnvelope) - ) + const envelope = messages.parseEnvelope(message.jsonEnvelope) this.eventBroadcaster.emit('envelope', envelope) - if (doesHaveValue(envelope.testCase)) { - this.remapDefinitionIds(envelope.testCase) - } if (doesHaveValue(envelope.testCaseFinished)) { - this.inProgressPickles = _.omit(this.inProgressPickles, worker.id) + delete this.inProgressPickles[worker.id] this.parseTestCaseResult(envelope.testCaseFinished) } } else { @@ -121,52 +111,21 @@ export default class Coordinator { } } - saveDefinitionIdMapping(message: ICoordinatorReportSupportCodeIds): void { - _.each(message.stepDefinitionIds, (id: string, index: number) => { - this.supportCodeIdMap[id] = this.supportCodeLibrary.stepDefinitions[ - index - ].id - }) - _.each( - message.beforeTestCaseHookDefinitionIds, - (id: string, index: number) => { - this.supportCodeIdMap[ - id - ] = this.supportCodeLibrary.beforeTestCaseHookDefinitions[index].id - } - ) - _.each( - message.afterTestCaseHookDefinitionIds, - (id: string, index: number) => { - this.supportCodeIdMap[ - id - ] = this.supportCodeLibrary.afterTestCaseHookDefinitions[index].id - } - ) - } - - remapDefinitionIds(testCase: messages.ITestCase): void { - for (const testStep of testCase.testSteps) { - if (testStep.hookId !== '') { - testStep.hookId = this.supportCodeIdMap[testStep.hookId] - } - if (doesHaveValue(testStep.stepDefinitionIds)) { - testStep.stepDefinitionIds = testStep.stepDefinitionIds.map( - (id) => this.supportCodeIdMap[id] - ) - } - } - } - awakenWorkers(triggeringWorker: IWorker): void { - _.each(this.workers, (worker): boolean => { + Object.values(this.workers).forEach((worker) => { if (worker.state === WorkerState.idle) { this.giveWork(worker) } return worker.state !== WorkerState.idle }) - if (_.isEmpty(this.inProgressPickles) && this.pickleIds.length > 0) { + let wip: Boolean = false + for (const p in this.inProgressPickles) { + wip = true + break + } + + if (!wip && this.pickleIds.length > 0) { this.giveWork(triggeringWorker, true) this.idleInterventions++ } @@ -175,11 +134,12 @@ export default class Coordinator { startWorker(id: string, total: number): void { const workerProcess = fork(runWorkerPath, [], { cwd: this.cwd, - env: _.assign({}, process.env, { + env: { + ...process.env, CUCUMBER_PARALLEL: 'true', - CUCUMBER_TOTAL_WORKERS: total, + CUCUMBER_TOTAL_WORKERS: total.toString(), CUCUMBER_WORKER_ID: id, - }), + }, stdio: ['inherit', 'inherit', 'inherit', 'ipc'], }) const worker = { state: WorkerState.new, process: workerProcess, id } @@ -196,6 +156,19 @@ export default class Coordinator { filterStacktraces: this.options.filterStacktraces, supportCodePaths: this.supportCodePaths, supportCodeRequiredModules: this.supportCodeRequiredModules, + supportCodeIds: { + stepDefinitionIds: this.supportCodeLibrary.stepDefinitions.map( + (s) => s.id + ), + beforeTestCaseHookDefinitionIds: + this.supportCodeLibrary.beforeTestCaseHookDefinitions.map( + (h) => h.id + ), + afterTestCaseHookDefinitionIds: + this.supportCodeLibrary.afterTestCaseHookDefinitions.map( + (h) => h.id + ), + }, options: this.options, }, } @@ -203,56 +176,67 @@ export default class Coordinator { } onWorkerProcessClose(exitCode: number): void { - if (exitCode !== 0) { + const success = exitCode === 0 + if (!success) { this.success = false } - if (_.every(this.workers, ({ state }) => state === WorkerState.closed)) { - this.eventBroadcaster.emit( - 'envelope', - messages.Envelope.fromObject({ - testRunFinished: { - timestamp: this.stopwatch.timestamp(), - }, - }) - ) + + if ( + Object.values(this.workers).every((x) => x.state === WorkerState.closed) + ) { + const envelope: messages.Envelope = { + testRunFinished: { + timestamp: this.stopwatch.timestamp(), + success, + }, + } + this.eventBroadcaster.emit('envelope', envelope) this.onFinish(this.success) } } - parseTestCaseResult(testCaseFinished: messages.ITestCaseFinished): void { + parseTestCaseResult(testCaseFinished: messages.TestCaseFinished): void { const { worstTestStepResult } = this.eventDataCollector.getTestCaseAttempt( testCaseFinished.testCaseStartedId ) if ( - !worstTestStepResult.willBeRetried && - this.shouldCauseFailure(worstTestStepResult.status) + !testCaseFinished.willBeRetried && + shouldCauseFailure(worstTestStepResult.status, this.options) ) { this.success = false } } - run(numberOfWorkers: number, done: (success: boolean) => void): void { - this.eventBroadcaster.emit( - 'envelope', - new messages.Envelope({ - testRunStarted: { - timestamp: this.stopwatch.timestamp(), - }, - }) - ) + async start(): Promise { + const envelope: messages.Envelope = { + testRunStarted: { + timestamp: this.stopwatch.timestamp(), + }, + } + this.eventBroadcaster.emit('envelope', envelope) this.stopwatch.start() - _.times(numberOfWorkers, (id) => - this.startWorker(id.toString(), numberOfWorkers) - ) - this.onFinish = (status) => { - if (this.idleInterventions > 0) { - console.warn( - `WARNING: All workers went idle ${this.idleInterventions} time(s). Consider revising handler passed to setParallelCanAssign.` - ) + this.assembledTestCases = await assembleTestCases({ + eventBroadcaster: this.eventBroadcaster, + newId: this.newId, + pickles: this.pickleIds.map((pickleId) => + this.eventDataCollector.getPickle(pickleId) + ), + supportCodeLibrary: this.supportCodeLibrary, + }) + return await new Promise((resolve) => { + for (let i = 0; i <= this.numberOfWorkers; i++) { + this.startWorker(i.toString(), this.numberOfWorkers) } + this.onFinish = (status) => { + if (this.idleInterventions > 0) { + console.warn( + `WARNING: All workers went idle ${this.idleInterventions} time(s). Consider revising handler passed to setParallelCanAssign.` + ) + } - done(status) - } + resolve(status) + } + }) } nextPicklePlacement(): IPicklePlacement { @@ -261,7 +245,7 @@ export default class Coordinator { if ( this.supportCodeLibrary.parallelCanAssign( placement.pickle, - _.values(this.inProgressPickles) + Object.values(this.inProgressPickles) ) ) { return placement @@ -298,6 +282,7 @@ export default class Coordinator { this.pickleIds.splice(nextPickleIndex, 1) this.inProgressPickles[worker.id] = pickle + const testCase = this.assembledTestCases[pickle.id] const gherkinDocument = this.eventDataCollector.getGherkinDocument( pickle.uri ) @@ -309,19 +294,11 @@ export default class Coordinator { skip, elapsed: this.stopwatch.duration().nanos(), pickle, + testCase, gherkinDocument, }, } worker.state = WorkerState.running worker.process.send(runCommand) } - - shouldCauseFailure( - status: messages.TestStepFinished.TestStepResult.Status - ): boolean { - return ( - _.includes([Status.AMBIGUOUS, Status.FAILED, Status.UNDEFINED], status) || - (status === Status.PENDING && this.options.strict) - ) - } } diff --git a/src/runtime/parallel/worker.ts b/src/runtime/parallel/worker.ts index 481484ab7..6fd1db60c 100644 --- a/src/runtime/parallel/worker.ts +++ b/src/runtime/parallel/worker.ts @@ -6,19 +6,23 @@ import { IWorkerCommandRun, } from './command_types' import { EventEmitter } from 'events' -import bluebird from 'bluebird' import StackTraceFilter from '../../stack_trace_filter' import supportCodeLibraryBuilder from '../../support_code_library_builder' -import PickleRunner from '../pickle_runner' +import TestCaseRunner from '../test_case_runner' import UserCodeRunner from '../../user_code_runner' -import { IdGenerator, messages } from '@cucumber/messages' +import { IdGenerator } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import TestRunHookDefinition from '../../models/test_run_hook_definition' import { ISupportCodeLibrary } from '../../support_code_library_builder/types' import { doesHaveValue, valueOrDefault } from '../../value_checker' import { IRuntimeOptions } from '../index' -import { PredictableTestRunStopwatch, RealTestRunStopwatch } from '../stopwatch' +import { RealTestRunStopwatch } from '../stopwatch' import { duration } from 'durations' +import { pathToFileURL } from 'url' +import { isJavaScript } from '../../cli/helpers' +// eslint-disable-next-line @typescript-eslint/no-var-requires +const { importer } = require('../../importer') const { uuid } = IdGenerator type IExitFunction = (exitCode: number, error?: Error, message?: string) => void @@ -58,7 +62,7 @@ export default class Worker { this.stackTraceFilter = new StackTraceFilter() this.eventBroadcaster.on('envelope', (envelope: messages.Envelope) => { this.sendMessage({ - jsonEnvelope: JSON.stringify(envelope.toJSON()), + jsonEnvelope: JSON.stringify(envelope), }) }) } @@ -67,25 +71,20 @@ export default class Worker { filterStacktraces, supportCodeRequiredModules, supportCodePaths, + supportCodeIds, options, }: IWorkerCommandInitialize): Promise { supportCodeRequiredModules.map((module) => require(module)) supportCodeLibraryBuilder.reset(this.cwd, this.newId) - supportCodePaths.forEach((codePath) => require(codePath)) - this.supportCodeLibrary = supportCodeLibraryBuilder.finalize() - this.sendMessage({ - supportCodeIds: { - stepDefinitionIds: this.supportCodeLibrary.stepDefinitions.map( - (s) => s.id - ), - beforeTestCaseHookDefinitionIds: this.supportCodeLibrary.beforeTestCaseHookDefinitions.map( - (h) => h.id - ), - afterTestCaseHookDefinitionIds: this.supportCodeLibrary.afterTestCaseHookDefinitions.map( - (h) => h.id - ), - }, - }) + for (const codePath of supportCodePaths) { + if (supportCodeRequiredModules.length || !isJavaScript(codePath)) { + require(codePath) + } else { + await importer(pathToFileURL(codePath)) + } + } + this.supportCodeLibrary = supportCodeLibraryBuilder.finalize(supportCodeIds) + this.worldParameters = options.worldParameters this.options = options this.filterStacktraces = filterStacktraces @@ -123,26 +122,26 @@ export default class Worker { async runTestCase({ gherkinDocument, pickle, + testCase, elapsed, retries, skip, }: IWorkerCommandRun): Promise { - const stopwatch = this.options.predictableIds - ? new PredictableTestRunStopwatch() - : new RealTestRunStopwatch() + const stopwatch = new RealTestRunStopwatch() stopwatch.from(duration(elapsed)) - const pickleRunner = new PickleRunner({ + const testCaseRunner = new TestCaseRunner({ eventBroadcaster: this.eventBroadcaster, stopwatch, gherkinDocument, newId: this.newId, pickle, + testCase, retries, skip, supportCodeLibrary: this.supportCodeLibrary, worldParameters: this.worldParameters, }) - await pickleRunner.run() + await testCaseRunner.run() this.sendMessage({ ready: true }) } @@ -153,7 +152,7 @@ export default class Worker { if (this.options.dryRun) { return } - await bluebird.each(testRunHookDefinitions, async (hookDefinition) => { + for (const hookDefinition of testRunHookDefinitions) { const { error } = await UserCodeRunner.run({ argsArray: [], fn: hookDefinition.code, @@ -171,6 +170,6 @@ export default class Worker { `${name} hook errored on worker ${this.id}, process exiting: ${location}` ) } - }) + } } } diff --git a/src/runtime/pickle_runner.ts b/src/runtime/pickle_runner.ts deleted file mode 100644 index b27ac2e10..000000000 --- a/src/runtime/pickle_runner.ts +++ /dev/null @@ -1,443 +0,0 @@ -import { clone } from 'lodash' -import { getAmbiguousStepException } from './helpers' -import AttachmentManager from './attachment_manager' -import StepRunner from './step_runner' -import { IdGenerator, messages } from '@cucumber/messages' -import { addDurations, getZeroDuration } from '../time' -import { EventEmitter } from 'events' -import { - ISupportCodeLibrary, - ITestCaseHookParameter, - ITestStepHookParameter, -} from '../support_code_library_builder/types' -import TestCaseHookDefinition from '../models/test_case_hook_definition' -import TestStepHookDefinition from '../models/test_step_hook_definition' -import StepDefinition from '../models/step_definition' -import { IDefinition } from '../models/definition' -import { doesHaveValue, doesNotHaveValue } from '../value_checker' -import { ITestRunStopwatch } from './stopwatch' -import { Group } from '@cucumber/cucumber-expressions' -import { Query } from '@cucumber/query' - -const { Status } = messages.TestStepFinished.TestStepResult - -interface ITestStep { - id: string - isBeforeHook?: boolean - isHook: boolean - hookDefinition?: TestCaseHookDefinition - stepHookDefinition?: TestStepHookDefinition - pickleStep?: messages.Pickle.IPickleStep - stepDefinitions?: StepDefinition[] -} - -export interface INewPickleRunnerOptions { - eventBroadcaster: EventEmitter - stopwatch: ITestRunStopwatch - gherkinDocument: messages.IGherkinDocument - newId: IdGenerator.NewId - pickle: messages.IPickle - retries: number - skip: boolean - supportCodeLibrary: ISupportCodeLibrary - worldParameters: any -} - -export default class PickleRunner { - private readonly attachmentManager: AttachmentManager - private currentTestCaseStartedId: string - private currentTestStepId: string - private readonly eventBroadcaster: EventEmitter - private readonly stopwatch: ITestRunStopwatch - private readonly gherkinDocument: messages.IGherkinDocument - private readonly newId: IdGenerator.NewId - private readonly pickle: messages.IPickle - private readonly maxAttempts: number - private readonly skip: boolean - private readonly supportCodeLibrary: ISupportCodeLibrary - private readonly testCaseId: string - private readonly testSteps: ITestStep[] - private testStepResults: messages.TestStepFinished.ITestStepResult[] - private world: any - private readonly worldParameters: any - - constructor({ - eventBroadcaster, - stopwatch, - gherkinDocument, - newId, - pickle, - retries = 0, - skip, - supportCodeLibrary, - worldParameters, - }: INewPickleRunnerOptions) { - this.attachmentManager = new AttachmentManager(({ data, media }) => { - if (doesNotHaveValue(this.currentTestStepId)) { - throw new Error( - 'Cannot attach when a step/hook is not running. Ensure your step/hook waits for the attach to finish.' - ) - } - this.eventBroadcaster.emit( - 'envelope', - messages.Envelope.fromObject({ - attachment: { - body: data, - contentEncoding: media.encoding, - mediaType: media.contentType, - testCaseStartedId: this.currentTestCaseStartedId, - testStepId: this.currentTestStepId, - }, - }) - ) - }) - this.eventBroadcaster = eventBroadcaster - this.stopwatch = stopwatch - this.gherkinDocument = gherkinDocument - this.maxAttempts = 1 + (skip ? 0 : retries) - this.newId = newId - this.pickle = pickle - this.skip = skip - this.supportCodeLibrary = supportCodeLibrary - this.worldParameters = worldParameters - this.testCaseId = this.newId() - this.testSteps = this.buildTestSteps() - this.resetTestProgressData() - } - - resetTestProgressData(): void { - this.world = new this.supportCodeLibrary.World({ - attach: this.attachmentManager.create.bind(this.attachmentManager), - log: this.attachmentManager.log.bind(this.attachmentManager), - parameters: this.worldParameters, - }) - this.testStepResults = [] - } - - buildTestSteps(): ITestStep[] { - const testSteps: ITestStep[] = [] - this.getBeforeHookDefinitions().forEach((hookDefinition) => { - testSteps.push({ - id: this.newId(), - hookDefinition, - isHook: true, - isBeforeHook: true, - }) - }) - this.pickle.steps.forEach((pickleStep) => { - const stepDefinitions = this.getStepDefinitions(pickleStep) - testSteps.push({ - id: this.newId(), - pickleStep, - stepDefinitions, - isHook: false, - }) - }) - this.getAfterHookDefinitions().forEach((hookDefinition) => { - testSteps.push({ - id: this.newId(), - hookDefinition, - isHook: true, - }) - }) - return testSteps - } - - emitTestCase(): void { - const testCase = { - pickleId: this.pickle.id, - id: this.testCaseId, - testSteps: this.testSteps.map((testStep) => { - if (testStep.isHook) { - return { - id: testStep.id, - hookId: testStep.hookDefinition.id, - } - } else { - return { - id: testStep.id, - pickleStepId: testStep.pickleStep.id, - stepDefinitionIds: testStep.stepDefinitions.map((x) => x.id), - stepMatchArgumentsLists: testStep.stepDefinitions.map((x) => { - const result = x.expression.match(testStep.pickleStep.text) - return { - stepMatchArguments: result.map((arg) => { - return { - group: this.mapArgumentGroup(arg.group), - parameterTypeName: arg.parameterType.name, - } - }), - } - }), - } - } - }), - } - this.eventBroadcaster.emit( - 'envelope', - messages.Envelope.fromObject({ testCase }) - ) - } - - private mapArgumentGroup( - group: Group - ): messages.TestCase.TestStep.StepMatchArgumentsList.StepMatchArgument.IGroup { - return { - start: group.start, - value: group.value, - children: doesHaveValue(group.children) - ? group.children.map((child) => this.mapArgumentGroup(child)) - : undefined, - } - } - - getAfterHookDefinitions(): TestCaseHookDefinition[] { - return clone(this.supportCodeLibrary.afterTestCaseHookDefinitions) - .reverse() - .filter((hookDefinition) => hookDefinition.appliesToTestCase(this.pickle)) - } - - getBeforeHookDefinitions(): TestCaseHookDefinition[] { - return this.supportCodeLibrary.beforeTestCaseHookDefinitions.filter( - (hookDefinition) => hookDefinition.appliesToTestCase(this.pickle) - ) - } - - getBeforeStepHookDefinitions(): TestStepHookDefinition[] { - return this.supportCodeLibrary.beforeTestStepHookDefinitions.filter( - (hookDefinition) => hookDefinition.appliesToTestCase(this.pickle) - ) - } - - getAfterStepHookDefinitions(): TestStepHookDefinition[] { - return clone(this.supportCodeLibrary.afterTestStepHookDefinitions) - .reverse() - .filter((hookDefinition) => hookDefinition.appliesToTestCase(this.pickle)) - } - - getStepDefinitions( - pickleStep: messages.Pickle.IPickleStep - ): StepDefinition[] { - return this.supportCodeLibrary.stepDefinitions.filter((stepDefinition) => - stepDefinition.matchesStepName(pickleStep.text) - ) - } - - getWorstStepResult(): messages.TestStepFinished.ITestStepResult { - if (this.testStepResults.length === 0) { - return messages.TestStepFinished.TestStepResult.fromObject({ - status: this.skip ? Status.SKIPPED : Status.PASSED, - }) - } - return new Query().getWorstTestStepResult(this.testStepResults) - } - - async invokeStep( - step: messages.Pickle.IPickleStep, - stepDefinition: IDefinition, - hookParameter?: any - ): Promise { - return await StepRunner.run({ - defaultTimeout: this.supportCodeLibrary.defaultTimeout, - hookParameter, - step, - stepDefinition, - world: this.world, - }) - } - - isSkippingSteps(): boolean { - return this.getWorstStepResult().status !== Status.PASSED - } - - shouldSkipHook(isBeforeHook: boolean): boolean { - return this.skip || (this.isSkippingSteps() && isBeforeHook) - } - - async aroundTestStep( - testStepId: string, - attempt: number, - runStepFn: () => Promise - ): Promise { - this.eventBroadcaster.emit( - 'envelope', - messages.Envelope.fromObject({ - testStepStarted: { - testCaseStartedId: this.currentTestCaseStartedId, - testStepId, - timestamp: this.stopwatch.timestamp(), - }, - }) - ) - this.currentTestStepId = testStepId - const testStepResult = await runStepFn() - this.currentTestStepId = null - this.testStepResults.push(testStepResult) - if ( - testStepResult.status === Status.FAILED && - attempt + 1 < this.maxAttempts - ) { - /* - TODO dont rely on `testStepResult.willBeRetried`, it will be moved or removed - see https://github.com/cucumber/cucumber/issues/902 - */ - testStepResult.willBeRetried = true - } - this.eventBroadcaster.emit( - 'envelope', - messages.Envelope.fromObject({ - testStepFinished: { - testCaseStartedId: this.currentTestCaseStartedId, - testStepId, - testStepResult, - timestamp: this.stopwatch.timestamp(), - }, - }) - ) - } - - async run(): Promise { - this.emitTestCase() - for (let attempt = 0; attempt < this.maxAttempts; attempt++) { - this.currentTestCaseStartedId = this.newId() - this.eventBroadcaster.emit( - 'envelope', - messages.Envelope.fromObject({ - testCaseStarted: { - attempt, - testCaseId: this.testCaseId, - id: this.currentTestCaseStartedId, - timestamp: this.stopwatch.timestamp(), - }, - }) - ) - for (const testStep of this.testSteps) { - await this.aroundTestStep(testStep.id, attempt, async () => { - if (testStep.isHook) { - const hookParameter: ITestCaseHookParameter = { - gherkinDocument: this.gherkinDocument, - pickle: this.pickle, - testCaseStartedId: this.currentTestCaseStartedId, - } - if (!testStep.isBeforeHook) { - hookParameter.result = this.getWorstStepResult() - } - return await this.runHook( - testStep.hookDefinition, - hookParameter, - testStep.isBeforeHook - ) - } else { - return await this.runStep(testStep) - } - }) - } - this.eventBroadcaster.emit( - 'envelope', - messages.Envelope.fromObject({ - testCaseFinished: { - testCaseStartedId: this.currentTestCaseStartedId, - timestamp: this.stopwatch.timestamp(), - }, - }) - ) - if (!this.getWorstStepResult().willBeRetried) { - break - } - this.resetTestProgressData() - } - return this.getWorstStepResult().status - } - - async runHook( - hookDefinition: TestCaseHookDefinition, - hookParameter: ITestCaseHookParameter, - isBeforeHook: boolean - ): Promise { - if (this.shouldSkipHook(isBeforeHook)) { - return messages.TestStepFinished.TestStepResult.fromObject({ - status: Status.SKIPPED, - }) - } - return await this.invokeStep(null, hookDefinition, hookParameter) - } - - async runStepHooks( - stepHooks: TestStepHookDefinition[], - stepResult?: messages.TestStepFinished.ITestStepResult - ): Promise { - const stepHooksResult = [] - const hookParameter: ITestStepHookParameter = { - gherkinDocument: this.gherkinDocument, - pickle: this.pickle, - testCaseStartedId: this.currentTestCaseStartedId, - testStepId: this.currentTestStepId, - result: stepResult, - } - for (const stepHookDefinition of stepHooks) { - stepHooksResult.push( - await this.invokeStep(null, stepHookDefinition, hookParameter) - ) - } - return stepHooksResult - } - - async runStep( - testStep: ITestStep - ): Promise { - if (testStep.stepDefinitions.length === 0) { - return messages.TestStepFinished.TestStepResult.fromObject({ - status: Status.UNDEFINED, - duration: { - seconds: '0', - nanos: 0, - }, - }) - } else if (testStep.stepDefinitions.length > 1) { - return messages.TestStepFinished.TestStepResult.fromObject({ - message: getAmbiguousStepException(testStep.stepDefinitions), - status: Status.AMBIGUOUS, - duration: { - seconds: '0', - nanos: 0, - }, - }) - } else if (this.isSkippingSteps()) { - return messages.TestStepFinished.TestStepResult.fromObject({ - status: Status.SKIPPED, - duration: { - seconds: '0', - nanos: 0, - }, - }) - } - - let stepResult - let stepResults = await this.runStepHooks( - this.getBeforeStepHookDefinitions(), - stepResult - ) - if ( - new Query().getWorstTestStepResult(stepResults).status !== Status.FAILED - ) { - stepResult = await this.invokeStep( - testStep.pickleStep, - testStep.stepDefinitions[0] - ) - stepResults.push(stepResult) - } - const afterStepHookResults = await this.runStepHooks( - this.getAfterStepHookDefinitions(), - stepResult - ) - stepResults = stepResults.concat(afterStepHookResults) - - const finalStepResult = new Query().getWorstTestStepResult(stepResults) - let finalDuration = getZeroDuration() - for (const result of stepResults) { - finalDuration = addDurations(finalDuration, result.duration) - } - finalStepResult.duration = finalDuration - return finalStepResult - } -} diff --git a/src/runtime/step_runner.ts b/src/runtime/step_runner.ts index b104cd958..14e765bfd 100644 --- a/src/runtime/step_runner.ts +++ b/src/runtime/step_runner.ts @@ -1,8 +1,6 @@ -import _ from 'lodash' -import Status from '../status' -import Time, { millisecondsToDuration } from '../time' +import Time from '../time' import UserCodeRunner from '../user_code_runner' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { format } from 'assertion-error-formatter' import { ITestCaseHookParameter } from '../support_code_library_builder/types' import { IDefinition, IGetInvocationDataResponse } from '../models/definition' @@ -17,7 +15,7 @@ const { beginTiming, endTiming } = Time export interface IRunOptions { defaultTimeout: number hookParameter: ITestCaseHookParameter - step: messages.Pickle.IPickleStep + step: messages.PickleStep stepDefinition: IDefinition world: any } @@ -28,11 +26,9 @@ export async function run({ step, stepDefinition, world, -}: IRunOptions): Promise { +}: IRunOptions): Promise { beginTiming() - let error: any, - result: messages.TestStepFinished.ITestStepResult, - invocationData: IGetInvocationDataResponse + let error: any, result: any, invocationData: IGetInvocationDataResponse try { invocationData = await stepDefinition.getInvocationParameters({ @@ -50,9 +46,7 @@ export async function run({ defaultTimeout ) - if ( - _.includes(invocationData.validCodeLengths, stepDefinition.code.length) - ) { + if (invocationData.validCodeLengths.includes(stepDefinition.code.length)) { const data = await UserCodeRunner.run({ argsArray: invocationData.parameters, fn: stepDefinition.code, @@ -66,22 +60,25 @@ export async function run({ } } - const testStepResult = messages.TestStepFinished.TestStepResult.fromObject({ - duration: millisecondsToDuration(endTiming()), - }) - + const duration = messages.TimeConversion.millisecondsToDuration(endTiming()) + let status: messages.TestStepResultStatus + let message: string if (result === 'skipped') { - testStepResult.status = Status.SKIPPED + status = messages.TestStepResultStatus.SKIPPED } else if (result === 'pending') { - testStepResult.status = Status.PENDING + status = messages.TestStepResultStatus.PENDING } else if (doesHaveValue(error)) { - testStepResult.message = format(error) - testStepResult.status = Status.FAILED + message = format(error) + status = messages.TestStepResultStatus.FAILED } else { - testStepResult.status = Status.PASSED + status = messages.TestStepResultStatus.PASSED } - return testStepResult + return { + duration, + status, + message, + } } export default { run } diff --git a/src/runtime/stopwatch.ts b/src/runtime/stopwatch.ts index 34f83d5e1..592e20e04 100644 --- a/src/runtime/stopwatch.ts +++ b/src/runtime/stopwatch.ts @@ -1,4 +1,4 @@ -import { messages, TimeConversion } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { stopwatch, Stopwatch, duration, Duration } from 'durations' export interface ITestRunStopwatch { @@ -6,7 +6,7 @@ export interface ITestRunStopwatch { start: () => ITestRunStopwatch stop: () => ITestRunStopwatch duration: () => Duration - timestamp: () => messages.ITimestamp + timestamp: () => messages.Timestamp } export class RealTestRunStopwatch implements ITestRunStopwatch { @@ -36,8 +36,8 @@ export class RealTestRunStopwatch implements ITestRunStopwatch { return current } - timestamp(): messages.ITimestamp { - return TimeConversion.millisecondsSinceEpochToTimestamp(Date.now()) + timestamp(): messages.Timestamp { + return messages.TimeConversion.millisecondsSinceEpochToTimestamp(Date.now()) } } @@ -66,14 +66,14 @@ export class PredictableTestRunStopwatch implements ITestRunStopwatch { return current } - timestamp(): messages.ITimestamp { + timestamp(): messages.Timestamp { const fakeTimestamp = this.convertToTimestamp(this.duration()) this.count++ return fakeTimestamp } // TODO: Remove. It's impossible to convert timestamps to durations and vice-versa - private convertToTimestamp(duration: Duration): messages.ITimestamp { + private convertToTimestamp(duration: Duration): messages.Timestamp { const seconds = Math.floor(duration.seconds()) const nanos = Math.floor((duration.seconds() - seconds) * 1000000000) return { diff --git a/src/runtime/test_case_runner.ts b/src/runtime/test_case_runner.ts new file mode 100644 index 000000000..9b77ce904 --- /dev/null +++ b/src/runtime/test_case_runner.ts @@ -0,0 +1,347 @@ +import { getAmbiguousStepException } from './helpers' +import AttachmentManager from './attachment_manager' +import StepRunner from './step_runner' +import * as messages from '@cucumber/messages' +import { getWorstTestStepResult, IdGenerator } from '@cucumber/messages' +import { EventEmitter } from 'events' +import { + ISupportCodeLibrary, + ITestCaseHookParameter, + ITestStepHookParameter, +} from '../support_code_library_builder/types' +import TestCaseHookDefinition from '../models/test_case_hook_definition' +import TestStepHookDefinition from '../models/test_step_hook_definition' +import { IDefinition } from '../models/definition' +import { doesHaveValue, doesNotHaveValue } from '../value_checker' +import { ITestRunStopwatch } from './stopwatch' +import StepDefinition from '../models/step_definition' + +export interface INewTestCaseRunnerOptions { + eventBroadcaster: EventEmitter + stopwatch: ITestRunStopwatch + gherkinDocument: messages.GherkinDocument + newId: IdGenerator.NewId + pickle: messages.Pickle + testCase: messages.TestCase + retries: number + skip: boolean + supportCodeLibrary: ISupportCodeLibrary + worldParameters: any +} + +export default class TestCaseRunner { + private readonly attachmentManager: AttachmentManager + private currentTestCaseStartedId: string + private currentTestStepId: string + private readonly eventBroadcaster: EventEmitter + private readonly stopwatch: ITestRunStopwatch + private readonly gherkinDocument: messages.GherkinDocument + private readonly newId: IdGenerator.NewId + private readonly pickle: messages.Pickle + private readonly testCase: messages.TestCase + private readonly maxAttempts: number + private readonly skip: boolean + private readonly supportCodeLibrary: ISupportCodeLibrary + private testStepResults: messages.TestStepResult[] + private world: any + private readonly worldParameters: any + + constructor({ + eventBroadcaster, + stopwatch, + gherkinDocument, + newId, + pickle, + testCase, + retries = 0, + skip, + supportCodeLibrary, + worldParameters, + }: INewTestCaseRunnerOptions) { + this.attachmentManager = new AttachmentManager(({ data, media }) => { + if (doesNotHaveValue(this.currentTestStepId)) { + throw new Error( + 'Cannot attach when a step/hook is not running. Ensure your step/hook waits for the attach to finish.' + ) + } + const attachment: messages.Envelope = { + attachment: { + body: data, + contentEncoding: media.encoding, + mediaType: media.contentType, + testCaseStartedId: this.currentTestCaseStartedId, + testStepId: this.currentTestStepId, + }, + } + this.eventBroadcaster.emit('envelope', attachment) + }) + this.eventBroadcaster = eventBroadcaster + this.stopwatch = stopwatch + this.gherkinDocument = gherkinDocument + this.maxAttempts = 1 + (skip ? 0 : retries) + this.newId = newId + this.pickle = pickle + this.testCase = testCase + this.skip = skip + this.supportCodeLibrary = supportCodeLibrary + this.worldParameters = worldParameters + this.resetTestProgressData() + } + + resetTestProgressData(): void { + this.world = new this.supportCodeLibrary.World({ + attach: this.attachmentManager.create.bind(this.attachmentManager), + log: this.attachmentManager.log.bind(this.attachmentManager), + parameters: this.worldParameters, + }) + this.testStepResults = [] + } + + getBeforeStepHookDefinitions(): TestStepHookDefinition[] { + return this.supportCodeLibrary.beforeTestStepHookDefinitions.filter( + (hookDefinition) => hookDefinition.appliesToTestCase(this.pickle) + ) + } + + getAfterStepHookDefinitions(): TestStepHookDefinition[] { + return this.supportCodeLibrary.afterTestStepHookDefinitions + .slice(0) + .reverse() + .filter((hookDefinition) => hookDefinition.appliesToTestCase(this.pickle)) + } + + getWorstStepResult(): messages.TestStepResult { + if (this.testStepResults.length === 0) { + return { + status: this.skip + ? messages.TestStepResultStatus.SKIPPED + : messages.TestStepResultStatus.PASSED, + duration: messages.TimeConversion.millisecondsToDuration(0), + } + } + return getWorstTestStepResult(this.testStepResults) + } + + async invokeStep( + step: messages.PickleStep, + stepDefinition: IDefinition, + hookParameter?: any + ): Promise { + return await StepRunner.run({ + defaultTimeout: this.supportCodeLibrary.defaultTimeout, + hookParameter, + step, + stepDefinition, + world: this.world, + }) + } + + isSkippingSteps(): boolean { + return ( + this.getWorstStepResult().status !== messages.TestStepResultStatus.PASSED + ) + } + + shouldSkipHook(isBeforeHook: boolean): boolean { + return this.skip || (this.isSkippingSteps() && isBeforeHook) + } + + async aroundTestStep( + testStepId: string, + runStepFn: () => Promise + ): Promise { + const testStepStarted: messages.Envelope = { + testStepStarted: { + testCaseStartedId: this.currentTestCaseStartedId, + testStepId, + timestamp: this.stopwatch.timestamp(), + }, + } + this.eventBroadcaster.emit('envelope', testStepStarted) + this.currentTestStepId = testStepId + const testStepResult = await runStepFn() + this.currentTestStepId = null + this.testStepResults.push(testStepResult) + const testStepFinished: messages.Envelope = { + testStepFinished: { + testCaseStartedId: this.currentTestCaseStartedId, + testStepId, + testStepResult, + timestamp: this.stopwatch.timestamp(), + }, + } + this.eventBroadcaster.emit('envelope', testStepFinished) + } + + async run(): Promise { + for (let attempt = 0; attempt < this.maxAttempts; attempt++) { + this.currentTestCaseStartedId = this.newId() + const testCaseStarted: messages.Envelope = { + testCaseStarted: { + attempt, + testCaseId: this.testCase.id, + id: this.currentTestCaseStartedId, + timestamp: this.stopwatch.timestamp(), + }, + } + this.eventBroadcaster.emit('envelope', testCaseStarted) + // used to determine whether a hook is a Before or After + let didWeRunStepsYet = false + for (const testStep of this.testCase.testSteps) { + await this.aroundTestStep(testStep.id, async () => { + if (doesHaveValue(testStep.hookId)) { + const hookParameter: ITestCaseHookParameter = { + gherkinDocument: this.gherkinDocument, + pickle: this.pickle, + testCaseStartedId: this.currentTestCaseStartedId, + } + if (didWeRunStepsYet) { + hookParameter.result = this.getWorstStepResult() + } + return await this.runHook( + findHookDefinition(testStep.hookId, this.supportCodeLibrary), + hookParameter, + !didWeRunStepsYet + ) + } else { + const pickleStep = this.pickle.steps.find( + (pickleStep) => pickleStep.id === testStep.pickleStepId + ) + const testStepResult = await this.runStep(pickleStep, testStep) + didWeRunStepsYet = true + return testStepResult + } + }) + } + const willBeRetried = + this.getWorstStepResult().status === + messages.TestStepResultStatus.FAILED && attempt + 1 < this.maxAttempts + const testCaseFinished: messages.Envelope = { + testCaseFinished: { + testCaseStartedId: this.currentTestCaseStartedId, + timestamp: this.stopwatch.timestamp(), + willBeRetried, + }, + } + this.eventBroadcaster.emit('envelope', testCaseFinished) + if (!willBeRetried) { + break + } + this.resetTestProgressData() + } + return this.getWorstStepResult().status + } + + async runHook( + hookDefinition: TestCaseHookDefinition, + hookParameter: ITestCaseHookParameter, + isBeforeHook: boolean + ): Promise { + if (this.shouldSkipHook(isBeforeHook)) { + return { + status: messages.TestStepResultStatus.SKIPPED, + duration: messages.TimeConversion.millisecondsToDuration(0), + } + } + return await this.invokeStep(null, hookDefinition, hookParameter) + } + + async runStepHooks( + stepHooks: TestStepHookDefinition[], + pickleStep: messages.PickleStep, + stepResult?: messages.TestStepResult + ): Promise { + const stepHooksResult = [] + const hookParameter: ITestStepHookParameter = { + gherkinDocument: this.gherkinDocument, + pickle: this.pickle, + pickleStep, + testCaseStartedId: this.currentTestCaseStartedId, + testStepId: this.currentTestStepId, + result: stepResult, + } + for (const stepHookDefinition of stepHooks) { + stepHooksResult.push( + await this.invokeStep(null, stepHookDefinition, hookParameter) + ) + } + return stepHooksResult + } + + async runStep( + pickleStep: messages.PickleStep, + testStep: messages.TestStep + ): Promise { + const stepDefinitions = testStep.stepDefinitionIds.map( + (stepDefinitionId) => { + return findStepDefinition(stepDefinitionId, this.supportCodeLibrary) + } + ) + if (stepDefinitions.length === 0) { + return { + status: messages.TestStepResultStatus.UNDEFINED, + duration: messages.TimeConversion.millisecondsToDuration(0), + } + } else if (stepDefinitions.length > 1) { + return { + message: getAmbiguousStepException(stepDefinitions), + status: messages.TestStepResultStatus.AMBIGUOUS, + duration: messages.TimeConversion.millisecondsToDuration(0), + } + } else if (this.isSkippingSteps()) { + return { + status: messages.TestStepResultStatus.SKIPPED, + duration: messages.TimeConversion.millisecondsToDuration(0), + } + } + + let stepResult + let stepResults = await this.runStepHooks( + this.getBeforeStepHookDefinitions(), + pickleStep + ) + if ( + getWorstTestStepResult(stepResults).status !== + messages.TestStepResultStatus.FAILED + ) { + stepResult = await this.invokeStep(pickleStep, stepDefinitions[0]) + stepResults.push(stepResult) + } + const afterStepHookResults = await this.runStepHooks( + this.getAfterStepHookDefinitions(), + pickleStep, + stepResult + ) + stepResults = stepResults.concat(afterStepHookResults) + + const finalStepResult = getWorstTestStepResult(stepResults) + let finalDuration = messages.TimeConversion.millisecondsToDuration(0) + for (const result of stepResults) { + finalDuration = messages.TimeConversion.addDurations( + finalDuration, + result.duration + ) + } + finalStepResult.duration = finalDuration + return finalStepResult + } +} + +function findHookDefinition( + id: string, + supportCodeLibrary: ISupportCodeLibrary +): TestCaseHookDefinition { + return [ + ...supportCodeLibrary.beforeTestCaseHookDefinitions, + ...supportCodeLibrary.afterTestCaseHookDefinitions, + ].find((definition) => definition.id === id) +} + +function findStepDefinition( + id: string, + supportCodeLibrary: ISupportCodeLibrary +): StepDefinition { + return supportCodeLibrary.stepDefinitions.find( + (definition) => definition.id === id + ) +} diff --git a/src/runtime/pickle_runner_spec.ts b/src/runtime/test_case_runner_spec.ts similarity index 51% rename from src/runtime/pickle_runner_spec.ts rename to src/runtime/test_case_runner_spec.ts index 7c5746530..1d5b1594d 100644 --- a/src/runtime/pickle_runner_spec.ts +++ b/src/runtime/test_case_runner_spec.ts @@ -1,65 +1,75 @@ import { afterEach, beforeEach, describe, it } from 'mocha' import { expect } from 'chai' -import PickleRunner from './pickle_runner' -import Status from '../status' +import sinon from 'sinon' +import TestCaseRunner from './test_case_runner' import { EventEmitter } from 'events' -import { IdGenerator, messages } from '@cucumber/messages' +import { IdGenerator } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { parse } from '../../test/gherkin_helpers' import { buildSupportCodeLibrary } from '../../test/runtime_helpers' import FakeTimers, { InstalledClock } from '@sinonjs/fake-timers' -import timeMethods, { millisecondsToDuration } from '../time' +import timeMethods from '../time' import { getBaseSupportCodeLibrary } from '../../test/fixtures/steps' import { ISupportCodeLibrary } from '../support_code_library_builder/types' import { valueOrDefault } from '../value_checker' import { PredictableTestRunStopwatch } from './stopwatch' -import IEnvelope = messages.IEnvelope +import { assembleTestCases } from './assemble_test_cases' +import IEnvelope = messages.Envelope -interface ITestPickleRunnerRequest { - gherkinDocument: messages.IGherkinDocument - pickle: messages.IPickle +interface ITestRunnerRequest { + gherkinDocument: messages.GherkinDocument + pickle: messages.Pickle retries?: number skip?: boolean supportCodeLibrary: ISupportCodeLibrary } -interface ITestPickleRunnerResponse { - envelopes: messages.IEnvelope[] - result: messages.TestStepFinished.TestStepResult.Status +interface ITestRunnerResponse { + envelopes: messages.Envelope[] + result: messages.TestStepResultStatus } -async function testPickleRunner( - options: ITestPickleRunnerRequest -): Promise { +async function testRunner( + options: ITestRunnerRequest +): Promise { const envelopes: IEnvelope[] = [] const eventBroadcaster = new EventEmitter() + const newId = IdGenerator.incrementing() + const testCase = ( + await assembleTestCases({ + eventBroadcaster, + newId, + pickles: [options.pickle], + supportCodeLibrary: options.supportCodeLibrary, + }) + )[options.pickle.id] + + // listen for envelopers _after_ we've assembled test cases eventBroadcaster.on('envelope', (e) => envelopes.push(e)) - const pickleRunner = new PickleRunner({ + const runner = new TestCaseRunner({ eventBroadcaster, stopwatch: new PredictableTestRunStopwatch(), gherkinDocument: options.gherkinDocument, - newId: IdGenerator.incrementing(), + newId, pickle: options.pickle, + testCase, retries: valueOrDefault(options.retries, 0), skip: valueOrDefault(options.skip, false), supportCodeLibrary: options.supportCodeLibrary, worldParameters: {}, }) - const result = await pickleRunner.run() + const result = await runner.run() return { envelopes, result } } -function predictableTimestamp(counter: number): any { +function predictableTimestamp(counter: number): messages.Timestamp { return { nanos: 1000000 * counter, - seconds: { - high: 0, - low: 0, - unsigned: false, - }, + seconds: 0, } } -describe('PickleRunner', () => { +describe('TestCaseRunner', () => { let clock: InstalledClock beforeEach(() => { @@ -86,142 +96,54 @@ describe('PickleRunner', () => { data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), uri: 'a.feature', }) - const passedTestResult = messages.TestStepFinished.TestStepResult.fromObject( - { - duration: millisecondsToDuration(1), - status: Status.PASSED, - } - ) + const passedTestResult: messages.TestStepResult = { + duration: messages.TimeConversion.millisecondsToDuration(1), + status: messages.TestStepResultStatus.PASSED, + message: undefined, + } // Act - const { envelopes, result } = await testPickleRunner({ + const { envelopes, result } = await testRunner({ gherkinDocument, pickle, supportCodeLibrary, }) // Assert - expect(envelopes).to.eql([ - messages.Envelope.fromObject({ - testCase: { - id: '0', - pickleId: pickle.id, - testSteps: [ - { - id: '1', - pickleStepId: pickle.steps[0].id, - stepDefinitionIds: [supportCodeLibrary.stepDefinitions[0].id], - stepMatchArgumentsLists: [ - { - stepMatchArguments: [], - }, - ], - }, - ], - }, - }), - messages.Envelope.fromObject({ + const expectedtEnvelopes: messages.Envelope[] = [ + { testCaseStarted: { attempt: 0, id: '2', testCaseId: '0', timestamp: predictableTimestamp(0), }, - }), - messages.Envelope.fromObject({ + }, + { testStepStarted: { testCaseStartedId: '2', testStepId: '1', timestamp: predictableTimestamp(1), }, - }), - messages.Envelope.fromObject({ + }, + { testStepFinished: { testCaseStartedId: '2', testStepResult: passedTestResult, testStepId: '1', timestamp: predictableTimestamp(2), }, - }), - messages.Envelope.fromObject({ + }, + { testCaseFinished: { testCaseStartedId: '2', timestamp: predictableTimestamp(3), + willBeRetried: false, }, - }), - ]) - expect(result).to.eql(Status.PASSED) - }) - }) - - describe('with a parameterised step', () => { - it('emits stepMatchArgumentLists correctly within the testCase message', async () => { - // Arrange - const supportCodeLibrary = buildSupportCodeLibrary(({ Given }) => { - Given('a step with {int} and {string} parameters', function () { - clock.tick(1) - }) - }) - const { - gherkinDocument, - pickles: [pickle], - } = await parse({ - data: [ - 'Feature: a', - 'Scenario: b', - 'Given a step with 1 and "foo" parameters', - ].join('\n'), - uri: 'a.feature', - }) - - // Act - const { envelopes } = await testPickleRunner({ - gherkinDocument, - pickle, - supportCodeLibrary, - }) - - expect( - envelopes[0].testCase.testSteps[0].stepMatchArgumentsLists - ).to.deep.eq([ - messages.TestCase.TestStep.StepMatchArgumentsList.fromObject({ - stepMatchArguments: [ - { - group: { - children: [], - start: 12, - value: '1', - }, - parameterTypeName: 'int', - }, - { - group: { - children: [ - { - children: [ - { - children: [], - }, - ], - start: 19, - value: 'foo', - }, - { - children: [ - { - children: [], - }, - ], - }, - ], - start: 18, - value: '"foo"', - }, - parameterTypeName: 'string', - }, - ], - }), - ]) + }, + ] + expect(envelopes).to.eql(expectedtEnvelopes) + expect(result).to.eql(messages.TestStepResultStatus.PASSED) }) }) @@ -240,27 +162,25 @@ describe('PickleRunner', () => { data: ['Feature: a', 'Scenario: b', 'Given a step'].join('\n'), uri: 'a.feature', }) - const failingTestResult = messages.TestStepFinished.TestStepResult.fromObject( - { - duration: millisecondsToDuration(0), - status: Status.FAILED, - message: 'fail', - } - ) + const failingTestResult: messages.TestStepResult = { + duration: messages.TimeConversion.millisecondsToDuration(0), + status: messages.TestStepResultStatus.FAILED, + message: 'fail', + } // Act - const { envelopes, result } = await testPickleRunner({ + const { envelopes, result } = await testRunner({ gherkinDocument, pickle, supportCodeLibrary, }) // Assert - expect(envelopes).to.have.lengthOf(5) - expect(envelopes[3].testStepFinished.testStepResult).to.eql( + expect(envelopes).to.have.lengthOf(4) + expect(envelopes[2].testStepFinished.testStepResult).to.eql( failingTestResult ) - expect(result).to.eql(Status.FAILED) + expect(result).to.eql(messages.TestStepResultStatus.FAILED) }) }) @@ -284,26 +204,22 @@ describe('PickleRunner', () => { ].join('\n') // Act - const { envelopes, result } = await testPickleRunner({ + const { envelopes, result } = await testRunner({ gherkinDocument, pickle, supportCodeLibrary, }) // Assert - expect(envelopes).to.have.lengthOf(5) - expect(envelopes[3].testStepFinished.testStepResult).to.eql( - messages.TestStepFinished.TestStepResult.fromObject({ - message, - status: Status.AMBIGUOUS, - duration: { - seconds: '0', - nanos: 0, - }, - }) - ) + expect(envelopes).to.have.lengthOf(4) + const expected: messages.TestStepResult = { + message, + status: messages.TestStepResultStatus.AMBIGUOUS, + duration: messages.TimeConversion.millisecondsToDuration(0), + } + expect(envelopes[2].testStepFinished.testStepResult).to.eql(expected) expect(result).to.eql( - envelopes[3].testStepFinished.testStepResult.status + envelopes[2].testStepFinished.testStepResult.status ) }) }) @@ -321,25 +237,21 @@ describe('PickleRunner', () => { }) // Act - const { envelopes, result } = await testPickleRunner({ + const { envelopes, result } = await testRunner({ gherkinDocument, pickle, supportCodeLibrary, }) // Assert - expect(envelopes).to.have.lengthOf(5) - expect(envelopes[3].testStepFinished.testStepResult).to.eql( - messages.TestStepFinished.TestStepResult.fromObject({ - status: Status.UNDEFINED, - duration: { - seconds: '0', - nanos: 0, - }, - }) - ) + expect(envelopes).to.have.lengthOf(4) + const expected: messages.TestStepResult = { + status: messages.TestStepResultStatus.UNDEFINED, + duration: messages.TimeConversion.millisecondsToDuration(0), + } + expect(envelopes[2].testStepFinished.testStepResult).to.eql(expected) expect(result).to.eql( - envelopes[3].testStepFinished.testStepResult.status + envelopes[2].testStepFinished.testStepResult.status ) }) }) @@ -366,7 +278,7 @@ describe('PickleRunner', () => { }) // Act - const { envelopes, result } = await testPickleRunner({ + const { envelopes, result } = await testRunner({ gherkinDocument, pickle, retries: 1, @@ -374,93 +286,78 @@ describe('PickleRunner', () => { }) // Assert - expect(envelopes).to.eql([ - messages.Envelope.fromObject({ - testCase: { - id: '0', - pickleId: pickle.id, - testSteps: [ - { - id: '1', - pickleStepId: pickle.steps[0].id, - stepDefinitionIds: [supportCodeLibrary.stepDefinitions[0].id], - stepMatchArgumentsLists: [ - { - stepMatchArguments: [], - }, - ], - }, - ], - }, - }), - messages.Envelope.fromObject({ + const expected: messages.Envelope[] = [ + { testCaseStarted: { attempt: 0, id: '2', testCaseId: '0', timestamp: predictableTimestamp(0), }, - }), - messages.Envelope.fromObject({ + }, + { testStepStarted: { testCaseStartedId: '2', testStepId: '1', timestamp: predictableTimestamp(1), }, - }), - messages.Envelope.fromObject({ + }, + { testStepFinished: { testCaseStartedId: '2', testStepResult: { - duration: millisecondsToDuration(0), + duration: messages.TimeConversion.millisecondsToDuration(0), message: 'error', - status: Status.FAILED, - willBeRetried: true, + status: messages.TestStepResultStatus.FAILED, }, testStepId: '1', timestamp: predictableTimestamp(2), }, - }), - messages.Envelope.fromObject({ + }, + { testCaseFinished: { testCaseStartedId: '2', timestamp: predictableTimestamp(3), + willBeRetried: true, }, - }), - messages.Envelope.fromObject({ + }, + { testCaseStarted: { attempt: 1, id: '3', testCaseId: '0', timestamp: predictableTimestamp(4), }, - }), - messages.Envelope.fromObject({ + }, + { testStepStarted: { testCaseStartedId: '3', testStepId: '1', timestamp: predictableTimestamp(5), }, - }), - messages.Envelope.fromObject({ + }, + { testStepFinished: { testCaseStartedId: '3', testStepResult: { - duration: millisecondsToDuration(0), - status: Status.PASSED, + duration: messages.TimeConversion.millisecondsToDuration(0), + message: undefined, + status: messages.TestStepResultStatus.PASSED, }, testStepId: '1', timestamp: predictableTimestamp(6), }, - }), - messages.Envelope.fromObject({ + }, + { testCaseFinished: { testCaseStartedId: '3', timestamp: predictableTimestamp(7), + willBeRetried: false, }, - }), - ]) - expect(result).to.eql(Status.PASSED) + }, + ] + expect(envelopes).to.eql(expected) + expect(result).to.eql(messages.TestStepResultStatus.PASSED) }) }) @@ -481,7 +378,7 @@ describe('PickleRunner', () => { }) // Act - const { envelopes, result } = await testPickleRunner({ + const { envelopes, result } = await testRunner({ gherkinDocument, pickle, skip: true, @@ -489,18 +386,14 @@ describe('PickleRunner', () => { }) // Assert - expect(envelopes).to.have.lengthOf(5) - expect(envelopes[3].testStepFinished.testStepResult).to.eql( - messages.TestStepFinished.TestStepResult.fromObject({ - status: Status.SKIPPED, - duration: { - seconds: '0', - nanos: 0, - }, - }) - ) + expect(envelopes).to.have.lengthOf(4) + const expected: messages.TestStepResult = { + status: messages.TestStepResultStatus.SKIPPED, + duration: messages.TimeConversion.millisecondsToDuration(0), + } + expect(envelopes[2].testStepFinished.testStepResult).to.eql(expected) expect(result).to.eql( - envelopes[3].testStepFinished.testStepResult.status + envelopes[2].testStepFinished.testStepResult.status ) }) }) @@ -526,62 +419,33 @@ describe('PickleRunner', () => { }) // Act - const { envelopes, result } = await testPickleRunner({ + const { envelopes, result } = await testRunner({ gherkinDocument, pickle, supportCodeLibrary, }) // Assert - expect(envelopes).to.have.lengthOf(9) - expect(envelopes[0]).to.eql( - messages.Envelope.fromObject({ - testCase: { - id: '0', - pickleId: pickle.id, - testSteps: [ - { - id: '1', - hookId: [ - supportCodeLibrary.beforeTestCaseHookDefinitions[0].id, - ], - }, - { - id: '2', - pickleStepId: pickle.steps[0].id, - stepDefinitionIds: [supportCodeLibrary.stepDefinitions[0].id], - stepMatchArgumentsLists: [ - { - stepMatchArguments: [], - }, - ], - }, - { - id: '3', - hookId: [ - supportCodeLibrary.afterTestCaseHookDefinitions[0].id, - ], - }, - ], - }, - }) - ) + expect(envelopes).to.have.lengthOf(8) expect(result).to.eql( - envelopes[7].testStepFinished.testStepResult.status + envelopes[6].testStepFinished.testStepResult.status ) }) }) describe('with step hooks', () => { it('emits the expected envelopes and returns a skipped result', async () => { + const beforeStep = sinon.stub() + const afterStep = sinon.stub() + // Arrange const supportCodeLibrary = buildSupportCodeLibrary( ({ Given, BeforeStep, AfterStep }) => { Given('a step', function () { clock.tick(1) }) - BeforeStep(function () {}) // eslint-disable-line @typescript-eslint/no-empty-function - AfterStep(function () {}) // eslint-disable-line @typescript-eslint/no-empty-function + BeforeStep(beforeStep) // eslint-disable-line @typescript-eslint/no-empty-function + AfterStep(afterStep) // eslint-disable-line @typescript-eslint/no-empty-function } ) const { @@ -593,37 +457,33 @@ describe('PickleRunner', () => { }) // Act - const { envelopes, result } = await testPickleRunner({ + const { envelopes, result } = await testRunner({ gherkinDocument, pickle, supportCodeLibrary, }) // Assert - expect(envelopes).to.have.lengthOf(5) - expect(envelopes[0]).to.eql( - messages.Envelope.fromObject({ - testCase: { - id: '0', - pickleId: pickle.id, - testSteps: [ - { - id: '1', - pickleStepId: pickle.steps[0].id, - stepDefinitionIds: [supportCodeLibrary.stepDefinitions[0].id], - stepMatchArgumentsLists: [ - { - stepMatchArguments: [], - }, - ], - }, - ], - }, - }) - ) + expect(envelopes).to.have.lengthOf(4) expect(result).to.eql( - envelopes[3].testStepFinished.testStepResult.status + envelopes[2].testStepFinished.testStepResult.status ) + expect(beforeStep).to.have.been.calledOnceWith({ + gherkinDocument, + pickle, + pickleStep: pickle.steps[0], + testCaseStartedId: envelopes[1].testStepStarted.testCaseStartedId, + testStepId: envelopes[1].testStepStarted.testStepId, + result: undefined, + }) + expect(afterStep).to.have.been.calledOnceWith({ + gherkinDocument, + pickle, + pickleStep: pickle.steps[0], + testCaseStartedId: envelopes[2].testStepFinished.testCaseStartedId, + testStepId: envelopes[2].testStepFinished.testStepId, + result: envelopes[2].testStepFinished.testStepResult, + }) }) }) }) diff --git a/src/stack_trace_filter.ts b/src/stack_trace_filter.ts index f3b45b11b..2275d4685 100644 --- a/src/stack_trace_filter.ts +++ b/src/stack_trace_filter.ts @@ -1,4 +1,3 @@ -import _ from 'lodash' import stackChain from 'stack-chain' import path from 'path' import { valueOrDefault } from './value_checker' @@ -8,8 +7,8 @@ const projectRootPath = path.join(__dirname, '..') const projectChildDirs = ['src', 'lib', 'node_modules'] export function isFileNameInCucumber(fileName: string): boolean { - return _.some(projectChildDirs, (dir) => - _.startsWith(fileName, path.join(projectRootPath, dir)) + return projectChildDirs.some((dir) => + fileName.startsWith(path.join(projectRootPath, dir)) ) } @@ -22,7 +21,7 @@ export default class StackTraceFilter { if (this.isErrorInCucumber(frames)) { return frames } - const index = _.findIndex(frames, this.isFrameInCucumber.bind(this)) + const index = frames.findIndex((x) => this.isFrameInCucumber(x)) if (index === -1) { return frames } @@ -32,7 +31,7 @@ export default class StackTraceFilter { } isErrorInCucumber(frames: CallSite[]): boolean { - const filteredFrames = _.reject(frames, this.isFrameInNode.bind(this)) + const filteredFrames = frames.filter((x) => !this.isFrameInNode(x)) return ( filteredFrames.length > 0 && this.isFrameInCucumber(filteredFrames[0]) ) @@ -45,7 +44,7 @@ export default class StackTraceFilter { isFrameInNode(frame: CallSite): boolean { const fileName = valueOrDefault(frame.getFileName(), '') - return !_.includes(fileName, path.sep) + return !fileName.includes(path.sep) } unfilter(): void { diff --git a/src/status.ts b/src/status.ts deleted file mode 100644 index 2ea433e15..000000000 --- a/src/status.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { messages } from '@cucumber/messages' - -export default messages.TestStepFinished.TestStepResult.Status diff --git a/src/step_arguments.ts b/src/step_arguments.ts index 28c12a177..18fa0ee54 100644 --- a/src/step_arguments.ts +++ b/src/step_arguments.ts @@ -1,14 +1,14 @@ import util from 'util' -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { doesHaveValue } from './value_checker' export interface IPickleStepArgumentFunctionMap { - dataTable: (arg: messages.PickleStepArgument.IPickleTable) => T - docString: (arg: messages.PickleStepArgument.IPickleDocString) => T + dataTable: (arg: messages.PickleTable) => T + docString: (arg: messages.PickleDocString) => T } export function parseStepArgument( - arg: messages.IPickleStepArgument, + arg: messages.PickleStepArgument, mapping: IPickleStepArgumentFunctionMap ): T { if (doesHaveValue(arg.dataTable)) { diff --git a/src/support_code_library_builder/build_helpers.ts b/src/support_code_library_builder/build_helpers.ts deleted file mode 100644 index dc31aaf59..000000000 --- a/src/support_code_library_builder/build_helpers.ts +++ /dev/null @@ -1,47 +0,0 @@ -import _ from 'lodash' -import { ParameterType } from '@cucumber/cucumber-expressions' -import path from 'path' -import StackTrace from 'stacktrace-js' -import { isFileNameInCucumber } from '../stack_trace_filter' -import { doesHaveValue, valueOrDefault } from '../value_checker' -import { ILineAndUri } from '../types' -import { IParameterTypeDefinition } from './types' - -export function getDefinitionLineAndUri(cwd: string): ILineAndUri { - let line: number - let uri: string - const stackframes = StackTrace.getSync() - const stackframe = _.find(stackframes, (frame) => { - return !isFileNameInCucumber(frame.getFileName()) - }) - if (doesHaveValue(stackframe)) { - line = stackframe.getLineNumber() - uri = stackframe.getFileName() - if (doesHaveValue(uri)) { - uri = path.relative(cwd, uri) - } - } - return { - line: valueOrDefault(line, 0), - uri: valueOrDefault(uri, 'unknown'), - } -} - -export function buildParameterType({ - name, - regexp, - transformer, - useForSnippets, - preferForRegexpMatch, -}: IParameterTypeDefinition): ParameterType { - if (typeof useForSnippets !== 'boolean') useForSnippets = true - if (typeof preferForRegexpMatch !== 'boolean') preferForRegexpMatch = false - return new ParameterType( - name, - regexp, - null, - transformer, - useForSnippets, - preferForRegexpMatch - ) -} diff --git a/src/support_code_library_builder/build_parameter_type.ts b/src/support_code_library_builder/build_parameter_type.ts new file mode 100644 index 000000000..a05258370 --- /dev/null +++ b/src/support_code_library_builder/build_parameter_type.ts @@ -0,0 +1,21 @@ +import { ParameterType } from '@cucumber/cucumber-expressions' +import { IParameterTypeDefinition } from './types' + +export function buildParameterType({ + name, + regexp, + transformer, + useForSnippets, + preferForRegexpMatch, +}: IParameterTypeDefinition): ParameterType { + if (typeof useForSnippets !== 'boolean') useForSnippets = true + if (typeof preferForRegexpMatch !== 'boolean') preferForRegexpMatch = false + return new ParameterType( + name, + regexp, + null, + transformer, + useForSnippets, + preferForRegexpMatch + ) +} diff --git a/src/support_code_library_builder/finalize_helpers.ts b/src/support_code_library_builder/finalize_helpers.ts deleted file mode 100644 index 83b39dacb..000000000 --- a/src/support_code_library_builder/finalize_helpers.ts +++ /dev/null @@ -1,41 +0,0 @@ -import isGenerator from 'is-generator' -import path from 'path' - -export interface IDefinitionConfig { - code: any - line: number - uri: string -} - -export interface IValidateNoGeneratorFunctionsRequest { - cwd: string - definitionConfigs: IDefinitionConfig[] -} - -export function validateNoGeneratorFunctions({ - cwd, - definitionConfigs, -}: IValidateNoGeneratorFunctionsRequest): void { - const generatorDefinitionConfigs = definitionConfigs.filter( - (definitionConfig) => isGenerator.fn(definitionConfig.code) - ) - if (generatorDefinitionConfigs.length > 0) { - const references = generatorDefinitionConfigs - .map( - (definitionConfig) => - `${path.relative( - cwd, - definitionConfig.uri - )}:${definitionConfig.line.toString()}` - ) - .join('\n ') - const message = ` - The following hook/step definitions use generator functions: - - ${references} - - Use 'this.setDefinitionFunctionWrapper(fn)' to wrap them in a function that returns a promise. - ` - throw new Error(message) - } -} diff --git a/src/support_code_library_builder/get_definition_line_and_uri.ts b/src/support_code_library_builder/get_definition_line_and_uri.ts new file mode 100644 index 000000000..583319e6a --- /dev/null +++ b/src/support_code_library_builder/get_definition_line_and_uri.ts @@ -0,0 +1,33 @@ +import path from 'path' +import { wrapCallSite } from '@cspotcode/source-map-support' +import stackChain from 'stack-chain' +import { isFileNameInCucumber } from '../stack_trace_filter' +import { doesHaveValue, valueOrDefault } from '../value_checker' +import { ILineAndUri } from '../types' +import CallSite = NodeJS.CallSite + +export function getDefinitionLineAndUri( + cwd: string, + isExcluded = isFileNameInCucumber +): ILineAndUri { + let line: number + let uri: string + + const stackframes: CallSite[] = stackChain.callSite().map(wrapCallSite) + const stackframe = stackframes.find( + (frame: CallSite) => + frame.getFileName() !== __filename && !isExcluded(frame.getFileName()) + ) + if (stackframe != null) { + line = stackframe.getLineNumber() + uri = stackframe.getFileName() + if (doesHaveValue(uri)) { + uri = path.relative(cwd, uri) + } + } + + return { + line: valueOrDefault(line, 0), + uri: valueOrDefault(uri, 'unknown'), + } +} diff --git a/src/support_code_library_builder/get_definition_line_and_uri_spec.ts b/src/support_code_library_builder/get_definition_line_and_uri_spec.ts new file mode 100644 index 000000000..81956f255 --- /dev/null +++ b/src/support_code_library_builder/get_definition_line_and_uri_spec.ts @@ -0,0 +1,17 @@ +import assert from 'assert' +import { getDefinitionLineAndUri } from './get_definition_line_and_uri' +import path from 'path' + +describe(getDefinitionLineAndUri.name, () => { + it('correctly gets the filename of the caller', () => { + const includeAnyFile = (): boolean => false + const { uri, line } = getDefinitionLineAndUri('.', includeAnyFile) + assert.strictEqual( + path.normalize(uri), + path.normalize( + 'src/support_code_library_builder/get_definition_line_and_uri_spec.ts' + ) + ) + assert.strictEqual(line, 8) + }) +}) diff --git a/src/support_code_library_builder/index.ts b/src/support_code_library_builder/index.ts index c6cbff046..e80abedfb 100644 --- a/src/support_code_library_builder/index.ts +++ b/src/support_code_library_builder/index.ts @@ -1,6 +1,7 @@ -import _ from 'lodash' -import { buildParameterType, getDefinitionLineAndUri } from './build_helpers' -import { IdGenerator, messages } from '@cucumber/messages' +import { buildParameterType } from './build_parameter_type' +import { getDefinitionLineAndUri } from './get_definition_line_and_uri' +import { IdGenerator } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import TestCaseHookDefinition from '../models/test_case_hook_definition' import TestStepHookDefinition from '../models/test_step_hook_definition' import TestRunHookDefinition from '../models/test_run_hook_definition' @@ -14,8 +15,7 @@ import { ParameterTypeRegistry, RegularExpression, } from '@cucumber/cucumber-expressions' -import { doesHaveValue, doesNotHaveValue } from '../value_checker' -import { validateNoGeneratorFunctions } from './finalize_helpers' +import { doesHaveValue } from '../value_checker' import { DefineStepPattern, IDefineStepOptions, @@ -30,6 +30,7 @@ import { ParallelAssignmentValidator, } from './types' import World from './world' +import { ICanonicalSupportCodeIds } from '../runtime/parallel/command_types' interface IStepDefinitionConfig { code: any @@ -152,13 +153,19 @@ export class SupportCodeLibraryBuilder { defineTestCaseHook( getCollection: () => ITestCaseHookDefinitionConfig[] - ): ( - options: string | IDefineTestCaseHookOptions | TestCaseHookFunction, - code?: TestCaseHookFunction + ): ( + options: + | string + | IDefineTestCaseHookOptions + | TestCaseHookFunction, + code?: TestCaseHookFunction ) => void { - return ( - options: string | IDefineTestCaseHookOptions | TestCaseHookFunction, - code?: TestCaseHookFunction + return ( + options: + | string + | IDefineTestCaseHookOptions + | TestCaseHookFunction, + code?: TestCaseHookFunction ) => { if (typeof options === 'string') { options = { tags: options } @@ -183,13 +190,19 @@ export class SupportCodeLibraryBuilder { defineTestStepHook( getCollection: () => ITestStepHookDefinitionConfig[] - ): ( - options: string | IDefineTestStepHookOptions | TestStepHookFunction, - code?: TestStepHookFunction + ): ( + options: + | string + | IDefineTestStepHookOptions + | TestStepHookFunction, + code?: TestStepHookFunction ) => void { - return ( - options: string | IDefineTestStepHookOptions | TestStepHookFunction, - code?: TestStepHookFunction + return ( + options: + | string + | IDefineTestStepHookOptions + | TestStepHookFunction, + code?: TestStepHookFunction ) => { if (typeof options === 'string') { options = { tags: options } @@ -254,16 +267,17 @@ export class SupportCodeLibraryBuilder { } buildTestCaseHookDefinitions( - configs: ITestCaseHookDefinitionConfig[] + configs: ITestCaseHookDefinitionConfig[], + canonicalIds?: string[] ): TestCaseHookDefinition[] { - return configs.map(({ code, line, options, uri }) => { + return configs.map(({ code, line, options, uri }, index) => { const wrappedCode = this.wrapCode({ code, wrapperOptions: options.wrapperOptions, }) return new TestCaseHookDefinition({ code: wrappedCode, - id: this.newId(), + id: canonicalIds ? canonicalIds[index] : this.newId(), line, options, unwrappedCode: code, @@ -310,14 +324,14 @@ export class SupportCodeLibraryBuilder { }) } - buildStepDefinitions(): { + buildStepDefinitions(canonicalIds?: string[]): { stepDefinitions: StepDefinition[] - undefinedParameterTypes: messages.IUndefinedParameterType[] + undefinedParameterTypes: messages.UndefinedParameterType[] } { const stepDefinitions: StepDefinition[] = [] - const undefinedParameterTypes: messages.IUndefinedParameterType[] = [] + const undefinedParameterTypes: messages.UndefinedParameterType[] = [] this.stepDefinitionConfigs.forEach( - ({ code, line, options, pattern, uri }) => { + ({ code, line, options, pattern, uri }, index) => { let expression if (typeof pattern === 'string') { try { @@ -350,7 +364,7 @@ export class SupportCodeLibraryBuilder { new StepDefinition({ code: wrappedCode, expression, - id: this.newId(), + id: canonicalIds ? canonicalIds[index] : this.newId(), line, options, pattern, @@ -363,23 +377,14 @@ export class SupportCodeLibraryBuilder { return { stepDefinitions, undefinedParameterTypes } } - finalize(): ISupportCodeLibrary { - if (doesNotHaveValue(this.definitionFunctionWrapper)) { - const definitionConfigs = _.chain([ - this.afterTestCaseHookDefinitionConfigs, - this.afterTestRunHookDefinitionConfigs, - this.beforeTestCaseHookDefinitionConfigs, - this.beforeTestRunHookDefinitionConfigs, - this.stepDefinitionConfigs, - ]) - .flatten() - .value() - validateNoGeneratorFunctions({ cwd: this.cwd, definitionConfigs }) - } - const stepDefinitionsResult = this.buildStepDefinitions() + finalize(canonicalIds?: ICanonicalSupportCodeIds): ISupportCodeLibrary { + const stepDefinitionsResult = this.buildStepDefinitions( + canonicalIds?.stepDefinitionIds + ) return { afterTestCaseHookDefinitions: this.buildTestCaseHookDefinitions( - this.afterTestCaseHookDefinitionConfigs + this.afterTestCaseHookDefinitionConfigs, + canonicalIds?.afterTestCaseHookDefinitionIds ), afterTestRunHookDefinitions: this.buildTestRunHookDefinitions( this.afterTestRunHookDefinitionConfigs @@ -388,7 +393,8 @@ export class SupportCodeLibraryBuilder { this.afterTestStepHookDefinitionConfigs ), beforeTestCaseHookDefinitions: this.buildTestCaseHookDefinitions( - this.beforeTestCaseHookDefinitionConfigs + this.beforeTestCaseHookDefinitionConfigs, + canonicalIds?.beforeTestCaseHookDefinitionIds ), beforeTestRunHookDefinitions: this.buildTestRunHookDefinitions( this.beforeTestRunHookDefinitionConfigs diff --git a/src/support_code_library_builder/index_spec.ts b/src/support_code_library_builder/index_spec.ts index f9df5446b..6485741a5 100644 --- a/src/support_code_library_builder/index_spec.ts +++ b/src/support_code_library_builder/index_spec.ts @@ -54,6 +54,27 @@ describe('supportCodeLibraryBuilder', () => { expect(stepDefinition.code).to.eql(step) expect(stepDefinition.unwrappedCode).to.eql(step) }) + + it('uses the canonical ids provided in order', function () { + // Arrange + const step = function (): void {} // eslint-disable-line @typescript-eslint/no-empty-function + supportCodeLibraryBuilder.reset('path/to/project', uuid()) + supportCodeLibraryBuilder.methods.defineStep('I do a thing', step) + supportCodeLibraryBuilder.methods.defineStep('I do another thing', step) + + // Act + const options = supportCodeLibraryBuilder.finalize({ + stepDefinitionIds: ['one', 'two'], + beforeTestCaseHookDefinitionIds: [], + afterTestCaseHookDefinitionIds: [], + }) + + // Assert + expect(options.stepDefinitions).to.have.lengthOf(2) + expect( + options.stepDefinitions.map((stepDefinition) => stepDefinition.id) + ).to.deep.eq(['one', 'two']) + }) }) describe('with definition function wrapper', () => { @@ -96,6 +117,29 @@ describe('supportCodeLibraryBuilder', () => { const testCaseHookDefinition = options.afterTestCaseHookDefinitions[0] expect(testCaseHookDefinition.code).to.eql(hook) }) + + it('uses the canonical ids provided in order', function () { + // Arrange + const hook = function (): void {} // eslint-disable-line @typescript-eslint/no-empty-function + supportCodeLibraryBuilder.reset('path/to/project', uuid()) + supportCodeLibraryBuilder.methods.After(hook) + supportCodeLibraryBuilder.methods.After(hook) + + // Act + const options = supportCodeLibraryBuilder.finalize({ + stepDefinitionIds: [], + beforeTestCaseHookDefinitionIds: [], + afterTestCaseHookDefinitionIds: ['one', 'two'], + }) + + // Assert + expect(options.afterTestCaseHookDefinitions).to.have.lengthOf(2) + expect( + options.afterTestCaseHookDefinitions.map( + (definition) => definition.id + ) + ).to.deep.eq(['one', 'two']) + }) }) describe('tag and function', () => { @@ -168,7 +212,7 @@ describe('supportCodeLibraryBuilder', () => { }) }) - describe('this.Before', () => { + describe('Before', () => { describe('function only', () => { it('adds a scenario hook definition', function () { // Arrange @@ -184,6 +228,29 @@ describe('supportCodeLibraryBuilder', () => { const testCaseHookDefinition = options.beforeTestCaseHookDefinitions[0] expect(testCaseHookDefinition.code).to.eql(hook) }) + + it('uses the canonical ids provided in order', function () { + // Arrange + const hook = function (): void {} // eslint-disable-line @typescript-eslint/no-empty-function + supportCodeLibraryBuilder.reset('path/to/project', uuid()) + supportCodeLibraryBuilder.methods.Before(hook) + supportCodeLibraryBuilder.methods.Before(hook) + + // Act + const options = supportCodeLibraryBuilder.finalize({ + stepDefinitionIds: [], + beforeTestCaseHookDefinitionIds: ['one', 'two'], + afterTestCaseHookDefinitionIds: [], + }) + + // Assert + expect(options.beforeTestCaseHookDefinitions).to.have.lengthOf(2) + expect( + options.beforeTestCaseHookDefinitions.map( + (definition) => definition.id + ) + ).to.deep.eq(['one', 'two']) + }) }) describe('tag and function', () => { diff --git a/src/support_code_library_builder/types.ts b/src/support_code_library_builder/types.ts index 93d550e47..9caf8b99c 100644 --- a/src/support_code_library_builder/types.ts +++ b/src/support_code_library_builder/types.ts @@ -1,45 +1,46 @@ -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import TestCaseHookDefinition from '../models/test_case_hook_definition' import TestStepHookDefinition from '../models/test_step_hook_definition' import TestRunHookDefinition from '../models/test_run_hook_definition' import StepDefinition from '../models/step_definition' import { ParameterTypeRegistry } from '@cucumber/cucumber-expressions' +import { IWorld } from './world' export type DefineStepPattern = string | RegExp export type ParallelAssignmentValidator = ( - pickle: messages.IPickle, - runningPickles: messages.IPickle[] + pickle: messages.Pickle, + runningPickles: messages.Pickle[] ) => boolean export interface ITestCaseHookParameter { - gherkinDocument: messages.IGherkinDocument - pickle: messages.IPickle - result?: messages.TestStepFinished.ITestStepResult + gherkinDocument: messages.GherkinDocument + pickle: messages.Pickle + result?: messages.TestStepResult testCaseStartedId: string } export interface ITestStepHookParameter { - gherkinDocument: messages.IGherkinDocument - pickle: messages.IPickle - result: messages.TestStepFinished.ITestStepResult + gherkinDocument: messages.GherkinDocument + pickle: messages.Pickle + pickleStep: messages.PickleStep + result: messages.TestStepResult testCaseStartedId: string testStepId: string } -export type TestCaseHookFunctionWithoutParameter = () => any | Promise -export type TestCaseHookFunctionWithParameter = ( +export type TestCaseHookFunction = ( + this: WorldType, arg: ITestCaseHookParameter ) => any | Promise -export type TestCaseHookFunction = - | TestCaseHookFunctionWithoutParameter - | TestCaseHookFunctionWithParameter -export type TestStepHookFunctionWithoutParameter = () => void -export type TestStepHookFunctionWithParameter = ( +export type TestStepHookFunction = ( + this: WorldType, arg: ITestStepHookParameter ) => void -export type TestStepHookFunction = - | TestStepHookFunctionWithoutParameter - | TestStepHookFunctionWithParameter + +export type TestStepFunction = ( + this: WorldType, + ...args: any[] +) => any | Promise export interface IDefineStepOptions { timeout?: number @@ -62,7 +63,7 @@ export interface IDefineTestRunHookOptions { export interface IParameterTypeDefinition { name: string - regexp: RegExp + regexp: readonly RegExp[] | readonly string[] | RegExp | string transformer: (...match: string[]) => T useForSnippets?: boolean preferForRegexpMatch?: boolean @@ -70,49 +71,91 @@ export interface IParameterTypeDefinition { export interface IDefineSupportCodeMethods { defineParameterType: (options: IParameterTypeDefinition) => void - defineStep: ((pattern: DefineStepPattern, code: Function) => void) & - (( + defineStep: (( + pattern: DefineStepPattern, + code: TestStepFunction + ) => void) & + (( pattern: DefineStepPattern, options: IDefineStepOptions, - code: Function + code: TestStepFunction ) => void) setDefaultTimeout: (milliseconds: number) => void setDefinitionFunctionWrapper: (fn: Function) => void setParallelCanAssign: (fn: ParallelAssignmentValidator) => void setWorldConstructor: (fn: any) => void - After: ((code: TestCaseHookFunction) => void) & - ((tags: string, code: TestCaseHookFunction) => void) & - ((options: IDefineTestCaseHookOptions, code: TestCaseHookFunction) => void) - AfterStep: ((code: TestStepHookFunction) => void) & - ((tags: string, code: TestStepHookFunction) => void) & - ((options: IDefineTestStepHookOptions, code: TestStepHookFunction) => void) + After: ((code: TestCaseHookFunction) => void) & + (( + tags: string, + code: TestCaseHookFunction + ) => void) & + (( + options: IDefineTestCaseHookOptions, + code: TestCaseHookFunction + ) => void) + AfterStep: (( + code: TestStepHookFunction + ) => void) & + (( + tags: string, + code: TestStepHookFunction + ) => void) & + (( + options: IDefineTestStepHookOptions, + code: TestStepHookFunction + ) => void) AfterAll: ((code: Function) => void) & ((options: IDefineTestRunHookOptions, code: Function) => void) - Before: ((code: TestCaseHookFunction) => void) & - ((tags: string, code: TestCaseHookFunction) => void) & - ((options: IDefineTestCaseHookOptions, code: TestCaseHookFunction) => void) - BeforeStep: ((code: TestStepHookFunction) => void) & - ((tags: string, code: TestStepHookFunction) => void) & - ((options: IDefineTestStepHookOptions, code: TestStepHookFunction) => void) + Before: (( + code: TestCaseHookFunction + ) => void) & + (( + tags: string, + code: TestCaseHookFunction + ) => void) & + (( + options: IDefineTestCaseHookOptions, + code: TestCaseHookFunction + ) => void) + BeforeStep: (( + code: TestStepHookFunction + ) => void) & + (( + tags: string, + code: TestStepHookFunction + ) => void) & + (( + options: IDefineTestStepHookOptions, + code: TestStepHookFunction + ) => void) BeforeAll: ((code: Function) => void) & ((options: IDefineTestRunHookOptions, code: Function) => void) - Given: ((pattern: DefineStepPattern, code: Function) => void) & - (( + Given: (( + pattern: DefineStepPattern, + code: TestStepFunction + ) => void) & + (( pattern: DefineStepPattern, options: IDefineStepOptions, - code: Function + code: TestStepFunction ) => void) - Then: ((pattern: DefineStepPattern, code: Function) => void) & - (( + Then: (( + pattern: DefineStepPattern, + code: TestStepFunction + ) => void) & + (( pattern: DefineStepPattern, options: IDefineStepOptions, - code: Function + code: TestStepFunction ) => void) - When: ((pattern: DefineStepPattern, code: Function) => void) & - (( + When: (( + pattern: DefineStepPattern, + code: TestStepFunction + ) => void) & + (( pattern: DefineStepPattern, options: IDefineStepOptions, - code: Function + code: TestStepFunction ) => void) } @@ -125,7 +168,7 @@ export interface ISupportCodeLibrary { readonly beforeTestRunHookDefinitions: TestRunHookDefinition[] readonly defaultTimeout: number readonly stepDefinitions: StepDefinition[] - readonly undefinedParameterTypes: messages.IUndefinedParameterType[] + readonly undefinedParameterTypes: messages.UndefinedParameterType[] readonly parameterTypeRegistry: ParameterTypeRegistry readonly World: any readonly parallelCanAssign: ParallelAssignmentValidator diff --git a/src/support_code_library_builder/validate_arguments.ts b/src/support_code_library_builder/validate_arguments.ts index 0b2322f6d..808845a11 100644 --- a/src/support_code_library_builder/validate_arguments.ts +++ b/src/support_code_library_builder/validate_arguments.ts @@ -1,5 +1,3 @@ -import _ from 'lodash' -import { doesNotHaveValue } from '../value_checker' import { DefineStepPattern, IDefineStepOptions } from './types' interface IValidation { @@ -17,7 +15,7 @@ interface IDefineStepArguments { const optionsValidation = { expectedType: 'object or function', predicate({ options }: IDefineStepArguments) { - return _.isPlainObject(options) + return typeof options === 'object' }, } @@ -25,14 +23,14 @@ const optionsTimeoutValidation = { identifier: '"options.timeout"', expectedType: 'integer', predicate({ options }: IDefineStepArguments) { - return doesNotHaveValue(options.timeout) || _.isInteger(options.timeout) + return options.timeout == null || typeof options.timeout === 'number' }, } const fnValidation = { expectedType: 'function', predicate({ code }: IDefineStepArguments) { - return _.isFunction(code) + return typeof code === 'function' }, } @@ -48,7 +46,7 @@ const validations: Record = { identifier: '"options.tags"', expectedType: 'string', predicate({ options }) { - return doesNotHaveValue(options.tags) || _.isString(options.tags) + return options.tags == null || typeof options.tags === 'string' }, }, optionsTimeoutValidation, @@ -60,7 +58,7 @@ const validations: Record = { identifier: '"options.tags"', expectedType: 'string', predicate({ options }) { - return doesNotHaveValue(options.tags) || _.isString(options.tags) + return options.tags == null || typeof options.tags === 'string' }, }, optionsTimeoutValidation, @@ -71,7 +69,7 @@ const validations: Record = { identifier: 'first argument', expectedType: 'string or regular expression', predicate({ pattern }) { - return _.isRegExp(pattern) || _.isString(pattern) + return pattern instanceof RegExp || typeof pattern === 'string' }, }, { identifier: 'second argument', ...optionsValidation }, diff --git a/src/support_code_library_builder/world.ts b/src/support_code_library_builder/world.ts index e918c63fb..1d142c4ac 100644 --- a/src/support_code_library_builder/world.ts +++ b/src/support_code_library_builder/world.ts @@ -6,7 +6,14 @@ export interface IWorldOptions { parameters: any } -export default class World { +export interface IWorld { + readonly attach: ICreateAttachment + readonly log: ICreateLog + readonly parameters: any + [key: string]: any +} + +export default class World implements IWorld { public readonly attach: ICreateAttachment public readonly log: ICreateLog public readonly parameters: any diff --git a/src/time.ts b/src/time.ts index 3dd0d5031..32ec1c9ed 100644 --- a/src/time.ts +++ b/src/time.ts @@ -1,10 +1,5 @@ -import { messages, TimeConversion } from '@cucumber/messages' -import { doesNotHaveValue } from './value_checker' -import Long from 'long' - -export const NANOSECONDS_IN_MILLISECOND = 1e6 -export const MILLISECONDS_IN_SECOND = 1e3 -export const NANOSECONDS_IN_SECOND = 1e9 +import { performance } from 'perf_hooks' +import * as messages from '@cucumber/messages' let previousTimestamp: number @@ -20,6 +15,7 @@ const methods: any = { }, setInterval: setInterval.bind(global), setTimeout: setTimeout.bind(global), + performance, } if (typeof setImmediate !== 'undefined') { @@ -28,63 +24,38 @@ if (typeof setImmediate !== 'undefined') { } function getTimestamp(): number { - return new methods.Date().getTime() -} - -function toNumber(x: number | Long): number { - return typeof x === 'number' ? x : x.toNumber() -} - -export function addDurations( - a: messages.IDuration, - b: messages.IDuration -): messages.IDuration { - if (doesNotHaveValue(b)) { - return a - } - let seconds = toNumber(a.seconds) + toNumber(b.seconds) - let nanos = a.nanos + b.nanos - if (nanos > NANOSECONDS_IN_SECOND) { - seconds += 1 - nanos -= NANOSECONDS_IN_SECOND - } - return new messages.Duration({ seconds, nanos }) -} - -// TODO use TimeConversion methods in cucumber-messages -// dependent on https://github.com/cucumber/cucumber/pull/832 -export function millisecondsToDuration( - milliseconds: number -): messages.IDuration { - const seconds = Math.floor(milliseconds / MILLISECONDS_IN_SECOND) - const nanos = - (milliseconds - seconds * MILLISECONDS_IN_SECOND) * - NANOSECONDS_IN_MILLISECOND - return new messages.Duration({ seconds, nanos }) -} - -export function durationToMilliseconds(duration: messages.IDuration): number { - const secondMillis = toNumber(duration.seconds) * MILLISECONDS_IN_SECOND - const nanoMillis = duration.nanos / NANOSECONDS_IN_MILLISECOND - return secondMillis + nanoMillis -} - -export function durationToNanoseconds(duration: messages.IDuration): number { - return toNumber(duration.seconds) * NANOSECONDS_IN_SECOND + duration.nanos + return methods.performance.now() } export function durationBetweenTimestamps( - startedTimestamp: messages.ITimestamp, - finishedTimestamp: messages.ITimestamp -): messages.IDuration { + startedTimestamp: messages.Timestamp, + finishedTimestamp: messages.Timestamp +): messages.Duration { const durationMillis = - TimeConversion.timestampToMillisecondsSinceEpoch(finishedTimestamp) - - TimeConversion.timestampToMillisecondsSinceEpoch(startedTimestamp) - return TimeConversion.millisecondsToDuration(durationMillis) -} - -export function getZeroDuration(): messages.IDuration { - return new messages.Duration({ seconds: 0, nanos: 0 }) + messages.TimeConversion.timestampToMillisecondsSinceEpoch( + finishedTimestamp + ) - + messages.TimeConversion.timestampToMillisecondsSinceEpoch(startedTimestamp) + return messages.TimeConversion.millisecondsToDuration(durationMillis) +} + +export async function wrapPromiseWithTimeout( + promise: Promise, + timeoutInMilliseconds: number, + timeoutMessage: string = '' +): Promise { + let timeoutId: NodeJS.Timeout + if (timeoutMessage === '') { + timeoutMessage = `Action did not complete within ${timeoutInMilliseconds} milliseconds` + } + const timeoutPromise = new Promise((resolve, reject) => { + timeoutId = methods.setTimeout(() => { + reject(new Error(timeoutMessage)) + }, timeoutInMilliseconds) + }) + return await Promise.race([promise, timeoutPromise]).finally(() => + methods.clearTimeout(timeoutId) + ) } export default methods diff --git a/src/time_spec.ts b/src/time_spec.ts new file mode 100644 index 000000000..2fe66e793 --- /dev/null +++ b/src/time_spec.ts @@ -0,0 +1,64 @@ +import { describe, it } from 'mocha' +import { expect } from 'chai' +import { wrapPromiseWithTimeout } from './time' + +describe('wrapPromiseWithTimeout()', () => { + describe('promise times out (default timeout message)', () => { + it('rejects the promise', async () => { + // Arrange + const promise = new Promise((resolve) => { + setTimeout(resolve, 50) + }) + + // Act + let error: Error = null + try { + await wrapPromiseWithTimeout(promise, 25) + } catch (e) { + error = e + } + + // Assert + expect(error).to.exist() + expect(error.message).to.eql( + 'Action did not complete within 25 milliseconds' + ) + }) + }) + + describe('promise times out (supplied timeout message)', () => { + it('rejects the promise', async () => { + // Arrange + const promise = new Promise((resolve) => { + setTimeout(resolve, 50) + }) + + // Act + let error: Error = null + try { + await wrapPromiseWithTimeout(promise, 25, 'custom timeout message') + } catch (e) { + error = e + } + + // Assert + expect(error).to.exist() + expect(error.message).to.eql('custom timeout message') + }) + }) + + describe('promise does not time out', () => { + it('resolves the promise', async () => { + // Arrange + const promise = new Promise((resolve) => { + setTimeout(() => resolve('value'), 10) + }) + + // Act + const result = await wrapPromiseWithTimeout(promise, 25) + + // Assert + expect(result).to.eql('value') + }) + }) +}) diff --git a/src/types/ndjson-parse/index.d.ts b/src/types/ndjson-parse/index.d.ts deleted file mode 100644 index fa7fae7fd..000000000 --- a/src/types/ndjson-parse/index.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module 'ndjson-parse' { - export default function parse(input: string): any[] -} diff --git a/src/user_code_runner.ts b/src/user_code_runner.ts index 274c80017..99d05ab93 100644 --- a/src/user_code_runner.ts +++ b/src/user_code_runner.ts @@ -1,5 +1,4 @@ -import bluebird from 'bluebird' -import Time from './time' +import { wrapPromiseWithTimeout } from './time' import UncaughtExceptionManager from './uncaught_exception_manager' import util from 'util' import { doesHaveValue } from './value_checker' @@ -69,23 +68,22 @@ const UserCodeRunner = { }) racingPromises.push(uncaughtExceptionPromise) - let timeoutId + let finalPromise = Promise.race(racingPromises) if (timeoutInMilliseconds >= 0) { - const timeoutPromise = new Promise((resolve, reject) => { - timeoutId = Time.setTimeout(() => { - const timeoutMessage = - 'function timed out, ensure the ' + - (callbackInterface ? 'callback is executed' : 'promise resolves') + - ` within ${timeoutInMilliseconds.toString()} milliseconds` - reject(new Error(timeoutMessage)) - }, timeoutInMilliseconds) - }) - racingPromises.push(timeoutPromise) + const timeoutMessage = + 'function timed out, ensure the ' + + (callbackInterface ? 'callback is executed' : 'promise resolves') + + ` within ${timeoutInMilliseconds.toString()} milliseconds` + finalPromise = wrapPromiseWithTimeout( + finalPromise, + timeoutInMilliseconds, + timeoutMessage + ) } let error, result try { - result = await bluebird.race(racingPromises) + result = await finalPromise } catch (e) { if (e instanceof Error) { error = e @@ -96,7 +94,6 @@ const UserCodeRunner = { } } - Time.clearTimeout(timeoutId) UncaughtExceptionManager.unregisterHandler(exceptionHandler) return { error, result } diff --git a/src/user_code_runner_spec.ts b/src/user_code_runner_spec.ts index f40bd4973..fe028ddee 100644 --- a/src/user_code_runner_spec.ts +++ b/src/user_code_runner_spec.ts @@ -1,7 +1,6 @@ import { describe, it } from 'mocha' import { expect } from 'chai' import UserCodeRunner, { IRunRequest, IRunResponse } from './user_code_runner' -import bluebird from 'bluebird' import semver from 'semver' async function testUserCodeRunner( @@ -242,7 +241,9 @@ describe('UserCodeRunner', () => { it('returns timeout as an error', async function () { // Arrange const fn = async function (): Promise { - return await bluebird.resolve('result').delay(200) + return await new Promise((resolve) => { + setTimeout(() => resolve('result'), 200) + }) } // Act @@ -261,7 +262,9 @@ describe('UserCodeRunner', () => { it('disables timeout protection', async function () { // Arrange const fn = async function (): Promise { - return await bluebird.resolve('result').delay(200) + return await new Promise((resolve) => { + setTimeout(() => resolve('result'), 200) + }) } // Act diff --git a/src/value_checker.ts b/src/value_checker.ts index 238577974..7aa7a25c7 100644 --- a/src/value_checker.ts +++ b/src/value_checker.ts @@ -1,8 +1,8 @@ -export function doesHaveValue(value: any): boolean { +export function doesHaveValue(value: T): boolean { return !doesNotHaveValue(value) } -export function doesNotHaveValue(value: any): boolean { +export function doesNotHaveValue(value: T): boolean { return value === null || value === undefined } diff --git a/src/wrapper.mjs b/src/wrapper.mjs new file mode 100644 index 000000000..360d5eee7 --- /dev/null +++ b/src/wrapper.mjs @@ -0,0 +1,38 @@ +import cucumber from './index.js' + +export const Cli = cucumber.Cli +export const parseGherkinMessageStream = cucumber.parseGherkinMessageStream +export const PickleFilter = cucumber.PickleFilter +export const Runtime = cucumber.Runtime +export const supportCodeLibraryBuilder = cucumber.supportCodeLibraryBuilder +export const Status = cucumber.Status +export const DataTable = cucumber.DataTable + +export const Formatter = cucumber.Formatter +export const FormatterBuilder = cucumber.FormatterBuilder +export const JsonFormatter = cucumber.JsonFormatter +export const ProgressFormatter = cucumber.ProgressFormatter +export const RerunFormatter = cucumber.RerunFormatter +export const SnippetsFormatter = cucumber.SnippetsFormatter +export const SummaryFormatter = cucumber.SummaryFormatter +export const UsageFormatter = cucumber.UsageFormatter +export const UsageJsonFormatter = cucumber.UsageJsonFormatter +export const formatterHelpers = cucumber.formatterHelpers + +export const After = cucumber.After +export const AfterAll = cucumber.AfterAll +export const AfterStep = cucumber.AfterStep +export const Before = cucumber.Before +export const BeforeAll = cucumber.BeforeAll +export const BeforeStep = cucumber.BeforeStep +export const defineParameterType = cucumber.defineParameterType +export const defineStep = cucumber.defineStep +export const Given = cucumber.Given +export const setDefaultTimeout = cucumber.setDefaultTimeout +export const setDefinitionFunctionWrapper = cucumber.setDefinitionFunctionWrapper +export const setWorldConstructor = cucumber.setWorldConstructor +export const Then = cucumber.Then +export const When = cucumber.When + +export const World = cucumber.World + diff --git a/test-d/hooks.ts b/test-d/hooks.ts index e85bff491..3446f3bbe 100644 --- a/test-d/hooks.ts +++ b/test-d/hooks.ts @@ -1,9 +1,32 @@ -import { After, Before } from '../' +import { + After, + AfterAll, + AfterStep, + Before, + BeforeAll, + BeforeStep, + ITestCaseHookParameter, + ITestStepHookParameter, +} from '../' +// should allow argument-less hooks +BeforeAll(function () {}) +AfterAll(function () {}) +Before(function () {}) +After(function () {}) +BeforeStep(function () {}) +AfterStep(function () {}) + +// should allow typed arguments in hooks +Before(function (param: ITestCaseHookParameter) {}) +After(function (param: ITestCaseHookParameter) {}) +BeforeStep(function (param: ITestStepHookParameter) {}) +AfterStep(function (param: ITestStepHookParameter) {}) + +// should allow us to return 'skipped' from a test case hook Before(async function () { return 'skipped' }) - After(async function () { return 'skipped' }) diff --git a/test-d/world.ts b/test-d/world.ts new file mode 100644 index 000000000..45bc75cb6 --- /dev/null +++ b/test-d/world.ts @@ -0,0 +1,46 @@ +import { Before, setWorldConstructor, When, World } from '../' +import { expectError } from 'tsd' + +// should allow us to read parameters and add attachments +Before(async function () { + await this.attach(this.parameters.foo) +}) +When('stuff happens', async function () { + await this.attach(this.parameters.foo) +}) + +// should prevent reassignment of parameters +expectError( + Before(async function () { + this.parameters = null + }) +) +expectError( + When('stuff happens', async function () { + this.parameters = null + }) +) + +// should allow us to set and get arbitrary properties +Before(async function () { + this.bar = 'baz' + await this.log(this.baz) +}) +When('stuff happens', async function () { + this.bar = 'baz' + await this.log(this.baz) +}) + +// should allow us to use a custom world class +class CustomWorld extends World { + doThing(): string { + return 'foo' + } +} +setWorldConstructor(CustomWorld) +Before(async function (this: CustomWorld) { + this.doThing() +}) +When('stuff happens', async function (this: CustomWorld) { + this.doThing() +}) diff --git a/test/fake_report_server.ts b/test/fake_report_server.ts index d554b30f0..9fc459e85 100644 --- a/test/fake_report_server.ts +++ b/test/fake_report_server.ts @@ -90,7 +90,7 @@ export default class FakeReportServer { }) ) ) - return new Promise((resolve, reject) => { + return await new Promise((resolve, reject) => { this.server.close((err) => { if (doesHaveValue(err)) return reject(err) resolve(this.receivedBodies) @@ -113,6 +113,7 @@ function extractAuthorizationToken( } function isValidUUID(token: string): boolean { - const v4 = /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i + const v4 = + /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i return v4.test(token) } diff --git a/test/formatter_helpers.ts b/test/formatter_helpers.ts index b12246b6b..8e2825529 100644 --- a/test/formatter_helpers.ts +++ b/test/formatter_helpers.ts @@ -4,15 +4,15 @@ import Runtime, { IRuntimeOptions } from '../src/runtime' import { EventEmitter } from 'events' import { EventDataCollector } from '../src/formatter/helpers' import FormatterBuilder from '../src/formatter/builder' -import { IdGenerator, messages } from '@cucumber/messages' +import { IdGenerator } from '@cucumber/messages' +import * as messages from '@cucumber/messages' import { ISupportCodeLibrary } from '../src/support_code_library_builder/types' import { ITestCaseAttempt } from '../src/formatter/helpers/event_data_collector' import { doesNotHaveValue } from '../src/value_checker' import { IParsedArgvFormatOptions } from '../src/cli/argv_parser' import { PassThrough } from 'stream' import { emitSupportCodeMessages } from '../src/cli/helpers' -import bluebird from 'bluebird' -import IEnvelope = messages.IEnvelope +import { promisify } from 'util' const { uuid } = IdGenerator @@ -25,6 +25,7 @@ export interface ITestRunOptions { runtimeOptions?: Partial supportCodeLibrary?: ISupportCodeLibrary sources?: ITestSource[] + pickleFilter?: (pickle: messages.Pickle) => boolean } export interface ITestFormatterOptions extends ITestRunOptions { @@ -33,7 +34,7 @@ export interface ITestFormatterOptions extends ITestRunOptions { } export interface IEnvelopesAndEventDataCollector { - envelopes: messages.IEnvelope[] + envelopes: messages.Envelope[] eventDataCollector: EventDataCollector } @@ -59,14 +60,14 @@ export async function testFormatter({ output += data } const passThrough = new PassThrough() - FormatterBuilder.build(type, { + await FormatterBuilder.build(type, { cwd: '', eventBroadcaster, eventDataCollector, log: logFn, parsedArgvOptions, stream: passThrough, - cleanup: bluebird.promisify(passThrough.end.bind(passThrough)), + cleanup: promisify(passThrough.end.bind(passThrough)), supportCodeLibrary, }) let pickleIds: string[] = [] @@ -129,13 +130,14 @@ export async function getEnvelopesAndEventDataCollector({ runtimeOptions = {}, supportCodeLibrary, sources = [], + pickleFilter = () => true, }: ITestRunOptions): Promise { if (doesNotHaveValue(supportCodeLibrary)) { supportCodeLibrary = buildSupportCodeLibrary() } const eventBroadcaster = new EventEmitter() const eventDataCollector = new EventDataCollector(eventBroadcaster) - const envelopes: IEnvelope[] = [] + const envelopes: messages.Envelope[] = [] eventBroadcaster.on('envelope', (envelope) => envelopes.push(envelope)) emitSupportCodeMessages({ supportCodeLibrary, @@ -149,7 +151,7 @@ export async function getEnvelopesAndEventDataCollector({ eventBroadcaster, uri: source.uri, }) - pickleIds = pickleIds.concat(pickles.map((p) => p.id)) + pickleIds = pickleIds.concat(pickles.filter(pickleFilter).map((p) => p.id)) } const runtime = new Runtime({ eventBroadcaster, diff --git a/test/gherkin_helpers.ts b/test/gherkin_helpers.ts index 394f77917..a0b94e187 100644 --- a/test/gherkin_helpers.ts +++ b/test/gherkin_helpers.ts @@ -1,17 +1,18 @@ -import { messages } from '@cucumber/messages' +import * as messages from '@cucumber/messages' +import { SourceMediaType } from '@cucumber/messages' import { doesHaveValue } from '../src/value_checker' import { IGherkinOptions } from '@cucumber/gherkin' import { GherkinStreams } from '@cucumber/gherkin-streams' import { EventEmitter } from 'events' export interface IParsedSource { - pickles: messages.IPickle[] - source: messages.ISource - gherkinDocument: messages.IGherkinDocument + pickles: messages.Pickle[] + source: messages.Source + gherkinDocument: messages.GherkinDocument } export interface IParsedSourceWithEnvelopes extends IParsedSource { - envelopes: messages.IEnvelope[] + envelopes: messages.Envelope[] } export interface IParseRequest { @@ -25,22 +26,22 @@ export async function parse({ uri, options, }: IParseRequest): Promise { - const sources = [ + const sources: messages.Envelope[] = [ { source: { uri, data: data, - mediaType: 'text/x.cucumber.gherkin+plain', + mediaType: SourceMediaType.TEXT_X_CUCUMBER_GHERKIN_PLAIN, }, }, ] return await new Promise((resolve, reject) => { - let source: messages.ISource - let gherkinDocument: messages.IGherkinDocument - const pickles: messages.IPickle[] = [] - const envelopes: messages.IEnvelope[] = [] + let source: messages.Source + let gherkinDocument: messages.GherkinDocument + const pickles: messages.Pickle[] = [] + const envelopes: messages.Envelope[] = [] const messageStream = GherkinStreams.fromSources(sources, options) - messageStream.on('data', (envelope: messages.IEnvelope) => { + messageStream.on('data', (envelope: messages.Envelope) => { envelopes.push(envelope) if (doesHaveValue(envelope.source)) { source = envelope.source @@ -90,7 +91,7 @@ export async function generateEvents({ export async function getPickleWithTags( tags: string[] -): Promise { +): Promise { const { pickles: [pickle], } = await parse({ @@ -107,7 +108,7 @@ Feature: a export async function getPickleStepWithText( text: string -): Promise { +): Promise { const { pickles: [pickle], } = await parse({ diff --git a/test/runtime_helpers.ts b/test/runtime_helpers.ts index a4f2a6e63..90ba04816 100644 --- a/test/runtime_helpers.ts +++ b/test/runtime_helpers.ts @@ -12,7 +12,6 @@ export function buildOptions( ): IRuntimeOptions { return { dryRun: false, - predictableIds: false, failFast: false, filterStacktraces: false, retry: 0, diff --git a/tsconfig.json b/tsconfig.json index fdb94c5fc..b9d4b64ad 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "esModuleInterop": true, - "lib": ["es2017"], + "lib": ["es2019"], "module": "commonjs", "noImplicitAny": true, "noImplicitReturns": true, @@ -9,7 +9,7 @@ "resolveJsonModule": true, "sourceMap": true, "inlineSources": true, - "target": "es2017", + "target": "es2018", "typeRoots": [ "./node_modules/@types", "./src/types" diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index 73836db90..000000000 --- a/yarn.lock +++ /dev/null @@ -1,4623 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" - integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/core@^7.7.5": - version "7.11.6" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.6.tgz#3a9455dc7387ff1bac45770650bc13ba04a15651" - integrity sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.6" - "@babel/helper-module-transforms" "^7.11.0" - "@babel/helpers" "^7.10.4" - "@babel/parser" "^7.11.5" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.11.5" - "@babel/types" "^7.11.5" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.2" - lodash "^4.17.19" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - -"@babel/generator@^7.11.5", "@babel/generator@^7.11.6": - version "7.11.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.6.tgz#b868900f81b163b4d464ea24545c61cbac4dc620" - integrity sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA== - dependencies: - "@babel/types" "^7.11.5" - jsesc "^2.5.1" - source-map "^0.5.0" - -"@babel/helper-function-name@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" - integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== - dependencies: - "@babel/helper-get-function-arity" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-get-function-arity@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" - integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-member-expression-to-functions@^7.10.4": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz#ae69c83d84ee82f4b42f96e2a09410935a8f26df" - integrity sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q== - dependencies: - "@babel/types" "^7.11.0" - -"@babel/helper-module-imports@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" - integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-module-transforms@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz#b16f250229e47211abdd84b34b64737c2ab2d359" - integrity sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg== - dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - "@babel/helper-simple-access" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/template" "^7.10.4" - "@babel/types" "^7.11.0" - lodash "^4.17.19" - -"@babel/helper-optimise-call-expression@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" - integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== - dependencies: - "@babel/types" "^7.10.4" - -"@babel/helper-replace-supers@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz#d585cd9388ea06e6031e4cd44b6713cbead9e6cf" - integrity sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.10.4" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-simple-access@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461" - integrity sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw== - dependencies: - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-split-export-declaration@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" - integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== - dependencies: - "@babel/types" "^7.11.0" - -"@babel/helper-validator-identifier@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" - integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== - -"@babel/helpers@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044" - integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA== - dependencies: - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/highlight@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" - integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.0.0", "@babel/parser@^7.10.4", "@babel/parser@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" - integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== - -"@babel/polyfill@^7.2.3": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.11.5.tgz#df550b2ec53abbc2ed599367ec59e64c7a707bb5" - integrity sha512-FunXnE0Sgpd61pKSj2OSOs1D44rKTD3pGOfGilZ6LGrrIH0QEtJlTjqOqdF8Bs98JmjfGhni2BBkTfv9KcKJ9g== - dependencies: - core-js "^2.6.5" - regenerator-runtime "^0.13.4" - -"@babel/template@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" - integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/parser" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3" - integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.5" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.11.5" - "@babel/types" "^7.11.5" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.19" - -"@babel/types@^7.10.4", "@babel/types@^7.11.0", "@babel/types@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d" - integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - lodash "^4.17.19" - to-fast-properties "^2.0.0" - -"@cucumber/compatibility-kit@4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@cucumber/compatibility-kit/-/compatibility-kit-4.0.1.tgz#566f95f2b1ca9f9b8c10ef463e9558ee03a393a4" - integrity sha512-M6UPb4wnrk8Ue2tb0rH89kddFPO0Ccsp7Gkz1ruytQaFvIWqnlyjpadY3YdXjH3bkIisbGXK+djSh3PfwRZ8ew== - -"@cucumber/create-meta@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@cucumber/create-meta/-/create-meta-4.0.0.tgz#ef97070640475e6e1480be93dc1042d361516ea6" - integrity sha512-I2GWC9PoIGmpc0w/vz2YYeGl/eog1oFogYKUjgflDjhECo1mpD/WQjMRPNOsZnd859S8fPgVByKzGQAWjfjGyQ== - dependencies: - "@cucumber/messages" "^15.0.0" - -"@cucumber/cucumber-expressions@12.0.1": - version "12.0.1" - resolved "https://registry.yarnpkg.com/@cucumber/cucumber-expressions/-/cucumber-expressions-12.0.1.tgz#7ab8936adb82d2bb45b86baa494e4e6e3dc9839f" - integrity sha512-ANzu80Mw9GzTQ5ImuLdBtHnQfG8MghVvvtud4GHBvlQ4Wzu1SvkUj3RsdtW9w3p7mATSw8SiSFj6Jel3cEWN6Q== - dependencies: - becke-ch--regex--s0-0-v1--base--pl--lib "^1.4.0" - -"@cucumber/gherkin-streams@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@cucumber/gherkin-streams/-/gherkin-streams-1.0.0.tgz#e4938ba130fceec8ebc641298557c2a21dcabd5f" - integrity sha512-ZGUvkwj8DnMozii+8YqWtiWuKqU+Opt50dWVeJzv2e+4GDh0P1Nc04RGMZkFf8WTl2sgBJq5waPUKCQVPaw6iQ== - dependencies: - "@cucumber/gherkin" "^18.0.0" - "@cucumber/message-streams" "^1.0.0" - "@cucumber/messages" "^15.0.0" - commander "^7.2.0" - protobufjs "^6.10.2" - source-map-support "^0.5.19" - -"@cucumber/gherkin@18.0.0", "@cucumber/gherkin@^18.0.0": - version "18.0.0" - resolved "https://registry.yarnpkg.com/@cucumber/gherkin/-/gherkin-18.0.0.tgz#af51ca7173aa7818ed1aa50e3477d9bbe9d1c954" - integrity sha512-Az+VD2NyOM2ZjzuVGrpJTl1VDv1j50graLtjUp7GfGYN+wMMV+jPgKV5fGYQeocjDnJYYlKymiUZzxcxvStJmg== - dependencies: - "@cucumber/message-streams" "^1.0.0" - "@cucumber/messages" "^15.0.0" - -"@cucumber/html-formatter@13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@cucumber/html-formatter/-/html-formatter-13.0.0.tgz#ac6abe30813e455efe5e19e01daa00cf2d9fe32b" - integrity sha512-+gNLbgeti/5UXm2bVYvtjgdlEiY6r1WsNWChezXE6LJsviy7HrA6WWbwFWFSxs3CLgee5Us5Pe8JonQAnFEiBw== - dependencies: - "@cucumber/messages" "^15.0.0" - commander "^7.2.0" - source-map-support "^0.5.19" - -"@cucumber/message-streams@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@cucumber/message-streams/-/message-streams-1.0.0.tgz#5162e65df51eb51e0aa484ef0ed46200b19a699a" - integrity sha512-i1Jx0EDnE+3Na82UxJ2VqE6aWWJJ+1H+3ax+SYgHmCmlUDJiJzx9dHxAAO3GISrM/RYUAuqMGHNAMnIcxkL3Pw== - dependencies: - "@cucumber/messages" "^15.0.0" - protobufjs "^6.10.2" - -"@cucumber/messages@15.0.0", "@cucumber/messages@^15.0.0": - version "15.0.0" - resolved "https://registry.yarnpkg.com/@cucumber/messages/-/messages-15.0.0.tgz#58e6541a6c21c4f0d3d4a82c24bbbfe72a6ff94c" - integrity sha512-LtxzSCRmYZTAKO6ucAcMflz0u90l2fev539OG+EioJ26F14KmmtxZwGabfjTxLf8NgyKeWsO8TGI2G3z4Kjr+A== - dependencies: - "@types/uuid" "^8.3.0" - protobufjs "^6.10.2" - uuid "^8.3.2" - -"@cucumber/query@9.0.2": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@cucumber/query/-/query-9.0.2.tgz#2b7ef65df4bba58f14d9415b5eb167fde10e670e" - integrity sha512-YrOSZQzWWVle+8B57zaSFfQt9jYTPDamBnwdc1EGKI1sXyALjHnGgCLXUFH/HjDieQkXIh2y+MHJ51t2u9ys1A== - dependencies: - "@cucumber/messages" "^15.0.0" - "@teppeis/multimaps" "^2.0.0" - -"@cucumber/tag-expressions@3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@cucumber/tag-expressions/-/tag-expressions-3.0.1.tgz#ca0702342bc4234ad73d9de3f1bf97461c3b5eb7" - integrity sha512-OGCXaJ1BQXmQ5b9pw+JYsBGumK2/LPZiLmbj1o1JFVeSNs2PY8WPQFSyXrskhrHz5Nd/6lYg7lvGMtFHOncC4w== - -"@eslint/eslintrc@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.0.tgz#99cc0a0584d72f1df38b900fb062ba995f395547" - integrity sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog== - dependencies: - ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.2.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" - strip-json-comments "^3.1.1" - -"@istanbuljs/load-nyc-config@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" - integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== - dependencies: - camelcase "^5.3.1" - find-up "^4.1.0" - get-package-type "^0.1.0" - js-yaml "^3.13.1" - resolve-from "^5.0.0" - -"@istanbuljs/schema@^0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" - integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== - -"@nodelib/fs.scandir@2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" - integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw== - dependencies: - "@nodelib/fs.stat" "2.0.3" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" - integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" - integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ== - dependencies: - "@nodelib/fs.scandir" "2.1.3" - fastq "^1.6.0" - -"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" - integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= - -"@protobufjs/base64@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" - integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== - -"@protobufjs/codegen@^2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" - integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== - -"@protobufjs/eventemitter@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" - integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= - -"@protobufjs/fetch@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" - integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= - dependencies: - "@protobufjs/aspromise" "^1.1.1" - "@protobufjs/inquire" "^1.1.0" - -"@protobufjs/float@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" - integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= - -"@protobufjs/inquire@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" - integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= - -"@protobufjs/path@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" - integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= - -"@protobufjs/pool@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" - integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= - -"@protobufjs/utf8@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" - integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= - -"@sindresorhus/is@^0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" - integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== - -"@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.8.1": - version "1.8.1" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.1.tgz#e7df00f98a203324f6dc7cc606cad9d4a8ab2217" - integrity sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw== - dependencies: - type-detect "4.0.8" - -"@sinonjs/fake-timers@7.0.5": - version "7.0.5" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.0.5.tgz#558a7f8145a01366c44b3dcbdd7172c05c461564" - integrity sha512-fUt6b15bjV/VW93UP5opNXJxdwZSbK1EdiwnhN7XrQrcpaOhMJpZ/CjwFpM3THpxwA+YviBUJKSuEqKlCK5alw== - dependencies: - "@sinonjs/commons" "^1.7.0" - -"@sinonjs/fake-timers@^6.0.0", "@sinonjs/fake-timers@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40" - integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA== - dependencies: - "@sinonjs/commons" "^1.7.0" - -"@sinonjs/samsam@^5.3.1": - version "5.3.1" - resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-5.3.1.tgz#375a45fe6ed4e92fca2fb920e007c48232a6507f" - integrity sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg== - dependencies: - "@sinonjs/commons" "^1.6.0" - lodash.get "^4.4.2" - type-detect "^4.0.8" - -"@sinonjs/text-encoding@^0.7.1": - version "0.7.1" - resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5" - integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ== - -"@szmarczak/http-timer@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" - integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== - dependencies: - defer-to-connect "^1.0.1" - -"@teppeis/multimaps@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@teppeis/multimaps/-/multimaps-2.0.0.tgz#2114ee964b702f9777d0e07899087ad9cd89a0de" - integrity sha512-TL1adzq1HdxUf9WYduLcQ/DNGYiz71U31QRgbnr0Ef1cPyOUOsBojxHVWpFeOSUucB6Lrs0LxFRA14ntgtkc9w== - -"@types/bluebird@3.5.33": - version "3.5.33" - resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.33.tgz#d79c020f283bd50bd76101d7d300313c107325fc" - integrity sha512-ndEo1xvnYeHxm7I/5sF6tBvnsA4Tdi3zj1keRKRs12SP+2ye2A27NDJ1B6PqkfMbGAcT+mqQVqbZRIrhfOp5PQ== - -"@types/body-parser@*": - version "1.19.0" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" - integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/chai-as-promised@*": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.3.tgz#779166b90fda611963a3adbfd00b339d03b747bd" - integrity sha512-FQnh1ohPXJELpKhzjuDkPLR2BZCAqed+a6xV4MI/T3XzHfd2FlarfUGUdZYgqYe8oxkYn0fchHEeHfHqdZ96sg== - dependencies: - "@types/chai" "*" - -"@types/chai@*": - version "4.2.12" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.12.tgz#6160ae454cd89dae05adc3bb97997f488b608201" - integrity sha512-aN5IAC8QNtSUdQzxu7lGBgYAOuU1tmRU4c9dIq5OKGf/SBVjXo+ffM2wEjudAWbgpOhy60nLoAGH1xm8fpCKFQ== - -"@types/chai@4.2.17": - version "4.2.17" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.17.tgz#85f9f0610f514b22a94125d441f73eef65bde5cc" - integrity sha512-LaiwWNnYuL8xJlQcE91QB2JoswWZckq9A4b+nMPq8dt8AP96727Nb3X4e74u+E3tm4NLTILNI9MYFsyVc30wSA== - -"@types/color-name@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" - integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== - -"@types/connect@*": - version "3.4.34" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.34.tgz#170a40223a6d666006d93ca128af2beb1d9b1901" - integrity sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ== - dependencies: - "@types/node" "*" - -"@types/dirty-chai@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/dirty-chai/-/dirty-chai-2.0.2.tgz#eeac4802329a41ed7815ac0c1a6360335bf77d0c" - integrity sha512-BruwIN/UQEU0ePghxEX+OyjngpOfOUKJQh3cmfeq2h2Su/g001iljVi3+Y2y2EFp3IPgjf4sMrRU33Hxv1FUqw== - dependencies: - "@types/chai" "*" - "@types/chai-as-promised" "*" - -"@types/express-serve-static-core@^4.17.18": - version "4.17.18" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz#8371e260f40e0e1ca0c116a9afcd9426fa094c40" - integrity sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - -"@types/express@4.17.11": - version "4.17.11" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.11.tgz#debe3caa6f8e5fcda96b47bd54e2f40c4ee59545" - integrity sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.18" - "@types/qs" "*" - "@types/serve-static" "*" - -"@types/fs-extra@9.0.11": - version "9.0.11" - resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.11.tgz#8cc99e103499eab9f347dbc6ca4e99fb8d2c2b87" - integrity sha512-mZsifGG4QeQ7hlkhO56u7zt/ycBgGxSVsFI/6lGTU34VtwkiqrrSDgw0+ygs8kFGWcXnFQWMrzF2h7TtDFNixA== - dependencies: - "@types/node" "*" - -"@types/glob@7.1.3": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" - integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - -"@types/json-schema@^7.0.3": - version "7.0.6" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" - integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= - -"@types/lodash@4.14.168": - version "4.14.168" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008" - integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q== - -"@types/long@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" - integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== - -"@types/mime@*": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.3.tgz#c893b73721db73699943bfc3653b1deb7faa4a3a" - integrity sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q== - -"@types/minimatch@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" - integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== - -"@types/minimist@^1.2.0": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256" - integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg== - -"@types/mocha@8.2.2": - version "8.2.2" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.2.tgz#91daa226eb8c2ff261e6a8cbf8c7304641e095e0" - integrity sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw== - -"@types/mustache@4.1.1": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@types/mustache/-/mustache-4.1.1.tgz#fcfa2db0cee6261e66f2437dc2fe71e26c7856b4" - integrity sha512-Sm0NWeLhS2QL7NNGsXvO+Fgp7e3JLHCO6RS3RCnfjAnkw6Y1bsji/AGfISdQZDIR/AeOyzkrxRk9jBkl55zdJw== - -"@types/mz@2.7.3": - version "2.7.3" - resolved "https://registry.yarnpkg.com/@types/mz/-/mz-2.7.3.tgz#e42a21e73f5f9340fe4a176981fafb1eb8cc6c12" - integrity sha512-Zp1NUJ4Alh3gaun0a5rkF3DL7b2j1WB6rPPI5h+CJ98sQnxe9qwskClvupz/4bqChGR3L/BRhTjlaOwR+uiZJg== - dependencies: - "@types/node" "*" - -"@types/node@*": - version "14.10.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.10.1.tgz#cc323bad8e8a533d4822f45ce4e5326f36e42177" - integrity sha512-aYNbO+FZ/3KGeQCEkNhHFRIzBOUgc7QvcVNKXbfnhDkSfwUv91JsQQa10rDgKSTSLkXZ1UIyPe4FJJNVgw1xWQ== - -"@types/node@14.14.43": - version "14.14.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.43.tgz#26bcbb0595b305400e8ceaf9a127a7f905ae49c8" - integrity sha512-3pwDJjp1PWacPTpH0LcfhgjvurQvrZFBrC6xxjaUEZ7ifUtT32jtjPxEMMblpqd2Mvx+k8haqQJLQxolyGN/cQ== - -"@types/node@^13.7.0": - version "13.13.19" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.19.tgz#f4165496e66e3da37b9e136887db446795e00c5b" - integrity sha512-IVsULCpTdafcHhBDLYEPnV5l15xV0q065zvOHC1ZmzFYaBCMzku078eXnazoSG8907vZjRgEN/EQjku7GwwFyQ== - -"@types/normalize-package-data@^2.4.0": - version "2.4.0" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" - integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== - -"@types/progress@2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/progress/-/progress-2.0.3.tgz#7ccbd9c6d4d601319126c469e73b5bb90dfc8ccc" - integrity sha512-bPOsfCZ4tsTlKiBjBhKnM8jpY5nmIll166IPD58D92hR7G7kZDfx5iB9wGF4NfZrdKolebjeAr3GouYkSGoJ/A== - dependencies: - "@types/node" "*" - -"@types/qs@*": - version "6.9.5" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.5.tgz#434711bdd49eb5ee69d90c1d67c354a9a8ecb18b" - integrity sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ== - -"@types/range-parser@*": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" - integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== - -"@types/resolve@1.20.0": - version "1.20.0" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.0.tgz#11325a379b6f63b858fed49552fd4178495ee087" - integrity sha512-SFT3jdUNlLkjxUWwH/0QjLiEsV38hjdDX8oMcX9jZAD8KWNzRLdg6INZE7UMz9O86b2BOHzA3dR8nF+DbonX2Q== - -"@types/semver@7.3.5": - version "7.3.5" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.5.tgz#74deebbbcb1e86634dbf10a5b5e8798626f5a597" - integrity sha512-iotVxtCCsPLRAvxMFFgxL8HD2l4mAZ2Oin7/VJ2ooWO0VOK4EGOGmZWZn1uCq7RofR3I/1IOSjCHlFT71eVK0Q== - -"@types/serve-static@*": - version "1.13.8" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.8.tgz#851129d434433c7082148574ffec263d58309c46" - integrity sha512-MoJhSQreaVoL+/hurAZzIm8wafFR6ajiTM1m4A0kv6AGeVBl4r4pOV8bGFrjjq1sGxDTnCoF8i22o0/aE5XCyA== - dependencies: - "@types/mime" "*" - "@types/node" "*" - -"@types/sinon-chai@3.2.5": - version "3.2.5" - resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.5.tgz#df21ae57b10757da0b26f512145c065f2ad45c48" - integrity sha512-bKQqIpew7mmIGNRlxW6Zli/QVyc3zikpGzCa797B/tRnD9OtHvZ/ts8sYXV+Ilj9u3QRaUEM8xrjgd1gwm1BpQ== - dependencies: - "@types/chai" "*" - "@types/sinon" "*" - -"@types/sinon@*": - version "9.0.5" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-9.0.5.tgz#56b2a12662dd8c7d081cdc511af5f872cb37377f" - integrity sha512-4CnkGdM/5/FXDGqL32JQ1ttVrGvhOoesLLF7VnTh4KdjK5N5VQOtxaylFqqTjnHx55MnD9O02Nbk5c1ELC8wlQ== - dependencies: - "@types/sinonjs__fake-timers" "*" - -"@types/sinonjs__fake-timers@*": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.1.tgz#681df970358c82836b42f989188d133e218c458e" - integrity sha512-yYezQwGWty8ziyYLdZjwxyMb0CZR49h8JALHGrxjQHWlqGgc8kLdHEgWrgL0uZ29DMvEVBDnHU2Wg36zKSIUtA== - -"@types/sinonjs__fake-timers@6.0.2": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz#3a84cf5ec3249439015e14049bd3161419bf9eae" - integrity sha512-dIPoZ3g5gcx9zZEszaxLSVTvMReD3xxyyDnQUjA6IYDG9Ba2AV0otMPs+77sG9ojB4Qr2N2Vk5RnKeuA0X/0bg== - -"@types/stream-buffers@3.0.3": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/stream-buffers/-/stream-buffers-3.0.3.tgz#34e565bf64e3e4bdeee23fd4aa58d4636014a02b" - integrity sha512-NeFeX7YfFZDYsCfbuaOmFQ0OjSmHreKBpp7MQ4alWQBHeh2USLsj7qyMyn9t82kjqIX516CR/5SRHnARduRtbQ== - dependencies: - "@types/node" "*" - -"@types/tmp@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.2.0.tgz#e3f52b4d7397eaa9193592ef3fdd44dc0af4298c" - integrity sha512-flgpHJjntpBAdJD43ShRosQvNC0ME97DCfGvZEDlAThQmnerRXrLbX6YgzRBQCZTthET9eAWFAMaYP0m0Y4HzQ== - -"@types/uuid@^8.3.0": - version "8.3.0" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.0.tgz#215c231dff736d5ba92410e6d602050cce7e273f" - integrity sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ== - -"@types/verror@1.10.4": - version "1.10.4" - resolved "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.4.tgz#805c0612b3a0c124cf99f517364142946b74ba3b" - integrity sha512-OjJdqx6QlbyZw9LShPwRW+Kmiegeg3eWNI41MQQKaG3vjdU2L9SRElntM51HmHBY1cu7izxQJ1lMYioQh3XMBg== - -"@typescript-eslint/eslint-plugin@4.22.0": - version "4.22.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.22.0.tgz#3d5f29bb59e61a9dba1513d491b059e536e16dbc" - integrity sha512-U8SP9VOs275iDXaL08Ln1Fa/wLXfj5aTr/1c0t0j6CdbOnxh+TruXu1p4I0NAvdPBQgoPjHsgKn28mOi0FzfoA== - dependencies: - "@typescript-eslint/experimental-utils" "4.22.0" - "@typescript-eslint/scope-manager" "4.22.0" - debug "^4.1.1" - functional-red-black-tree "^1.0.1" - lodash "^4.17.15" - regexpp "^3.0.0" - semver "^7.3.2" - tsutils "^3.17.1" - -"@typescript-eslint/experimental-utils@4.22.0": - version "4.22.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.22.0.tgz#68765167cca531178e7b650a53456e6e0bef3b1f" - integrity sha512-xJXHHl6TuAxB5AWiVrGhvbGL8/hbiCQ8FiWwObO3r0fnvBdrbWEDy1hlvGQOAWc6qsCWuWMKdVWlLAEMpxnddg== - dependencies: - "@types/json-schema" "^7.0.3" - "@typescript-eslint/scope-manager" "4.22.0" - "@typescript-eslint/types" "4.22.0" - "@typescript-eslint/typescript-estree" "4.22.0" - eslint-scope "^5.0.0" - eslint-utils "^2.0.0" - -"@typescript-eslint/parser@4.22.0": - version "4.22.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.22.0.tgz#e1637327fcf796c641fe55f73530e90b16ac8fe8" - integrity sha512-z/bGdBJJZJN76nvAY9DkJANYgK3nlRstRRi74WHm3jjgf2I8AglrSY+6l7ogxOmn55YJ6oKZCLLy+6PW70z15Q== - dependencies: - "@typescript-eslint/scope-manager" "4.22.0" - "@typescript-eslint/types" "4.22.0" - "@typescript-eslint/typescript-estree" "4.22.0" - debug "^4.1.1" - -"@typescript-eslint/parser@^4.0.0": - version "4.8.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.8.2.tgz#78dccbe5124de2b8dea2d4c363dee9f769151ca8" - integrity sha512-u0leyJqmclYr3KcXOqd2fmx6SDGBO0MUNHHAjr0JS4Crbb3C3d8dwAdlazy133PLCcPn+aOUFiHn72wcuc5wYw== - dependencies: - "@typescript-eslint/scope-manager" "4.8.2" - "@typescript-eslint/types" "4.8.2" - "@typescript-eslint/typescript-estree" "4.8.2" - debug "^4.1.1" - -"@typescript-eslint/scope-manager@4.22.0": - version "4.22.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.22.0.tgz#ed411545e61161a8d702e703a4b7d96ec065b09a" - integrity sha512-OcCO7LTdk6ukawUM40wo61WdeoA7NM/zaoq1/2cs13M7GyiF+T4rxuA4xM+6LeHWjWbss7hkGXjFDRcKD4O04Q== - dependencies: - "@typescript-eslint/types" "4.22.0" - "@typescript-eslint/visitor-keys" "4.22.0" - -"@typescript-eslint/scope-manager@4.8.2": - version "4.8.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.8.2.tgz#a18388c63ae9c17adde519384f539392f2c4f0d9" - integrity sha512-qHQ8ODi7mMin4Sq2eh/6eu03uVzsf5TX+J43xRmiq8ujng7ViQSHNPLOHGw/Wr5dFEoxq/ubKhzClIIdQy5q3g== - dependencies: - "@typescript-eslint/types" "4.8.2" - "@typescript-eslint/visitor-keys" "4.8.2" - -"@typescript-eslint/types@4.22.0": - version "4.22.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.22.0.tgz#0ca6fde5b68daf6dba133f30959cc0688c8dd0b6" - integrity sha512-sW/BiXmmyMqDPO2kpOhSy2Py5w6KvRRsKZnV0c4+0nr4GIcedJwXAq+RHNK4lLVEZAJYFltnnk1tJSlbeS9lYA== - -"@typescript-eslint/types@4.8.2": - version "4.8.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.8.2.tgz#c862dd0e569d9478eb82d6aee662ea53f5661a36" - integrity sha512-z1/AVcVF8ju5ObaHe2fOpZYEQrwHyZ7PTOlmjd3EoFeX9sv7UekQhfrCmgUO7PruLNfSHrJGQvrW3Q7xQ8EoAw== - -"@typescript-eslint/typescript-estree@4.22.0": - version "4.22.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.22.0.tgz#b5d95d6d366ff3b72f5168c75775a3e46250d05c" - integrity sha512-TkIFeu5JEeSs5ze/4NID+PIcVjgoU3cUQUIZnH3Sb1cEn1lBo7StSV5bwPuJQuoxKXlzAObjYTilOEKRuhR5yg== - dependencies: - "@typescript-eslint/types" "4.22.0" - "@typescript-eslint/visitor-keys" "4.22.0" - debug "^4.1.1" - globby "^11.0.1" - is-glob "^4.0.1" - semver "^7.3.2" - tsutils "^3.17.1" - -"@typescript-eslint/typescript-estree@4.8.2": - version "4.8.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.8.2.tgz#eeec34707d8577600fb21661b5287226cc8b3bed" - integrity sha512-HToGNwI6fekH0dOw3XEVESUm71Onfam0AKin6f26S2FtUmO7o3cLlWgrIaT1q3vjB3wCTdww3Dx2iGq5wtUOCg== - dependencies: - "@typescript-eslint/types" "4.8.2" - "@typescript-eslint/visitor-keys" "4.8.2" - debug "^4.1.1" - globby "^11.0.1" - is-glob "^4.0.1" - lodash "^4.17.15" - semver "^7.3.2" - tsutils "^3.17.1" - -"@typescript-eslint/visitor-keys@4.22.0": - version "4.22.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.22.0.tgz#169dae26d3c122935da7528c839f42a8a42f6e47" - integrity sha512-nnMu4F+s4o0sll6cBSsTeVsT4cwxB7zECK3dFxzEjPBii9xLpq4yqqsy/FU5zMfan6G60DKZSCXAa3sHJZrcYw== - dependencies: - "@typescript-eslint/types" "4.22.0" - eslint-visitor-keys "^2.0.0" - -"@typescript-eslint/visitor-keys@4.8.2": - version "4.8.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.8.2.tgz#62cd3fbbbf65f8eccfbe6f159eb1b84a243a3f77" - integrity sha512-Vg+/SJTMZJEKKGHW7YC21QxgKJrSbxoYYd3MEUGtW7zuytHuEcksewq0DUmo4eh/CTNrVJGSdIY9AtRb6riWFw== - dependencies: - "@typescript-eslint/types" "4.8.2" - eslint-visitor-keys "^2.0.0" - -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - -accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - -acorn-jsx@^5.2.0, acorn-jsx@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" - integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== - -acorn-node@^1.6.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8" - integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A== - dependencies: - acorn "^7.0.0" - acorn-walk "^7.0.0" - xtend "^4.0.2" - -acorn-walk@^7.0.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" - integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== - -acorn@^7.0.0, acorn@^7.4.0: - version "7.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c" - integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w== - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv@^6.10.0, ajv@^6.12.4: - version "6.12.5" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.5.tgz#19b0e8bae8f476e5ba666300387775fb1a00a4da" - integrity sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-align@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" - integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw== - dependencies: - string-width "^3.0.0" - -ansi-colors@4.1.1, ansi-colors@^4.1.1: - version "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@^4.2.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" - integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== - dependencies: - type-fest "^0.11.0" - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== - -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: - version "4.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" - integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== - dependencies: - "@types/color-name" "^1.1.1" - color-convert "^2.0.1" - -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= - -anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -append-transform@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-2.0.0.tgz#99d9d29c7b38391e6f428d28ce136551f0b77e12" - integrity sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg== - dependencies: - default-require-extensions "^3.0.0" - -archy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= - -array-includes@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" - integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0" - is-string "^1.0.5" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array.prototype.flat@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" - integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= - -assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assertion-error-formatter@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/assertion-error-formatter/-/assertion-error-formatter-3.0.0.tgz#be9c8825dee6a8a6c72183d915912d9b57d5d265" - integrity sha512-6YyAVLrEze0kQ7CmJfUgrLHb+Y7XghmL2Ie7ijVa2Y9ynP3LV+VDiwFk62Dn0qtqbmY0BT0ss6p1xxpiF2PYbQ== - dependencies: - diff "^4.0.1" - pad-right "^0.2.2" - repeat-string "^1.6.1" - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - -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== - -at-least-node@^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== - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -becke-ch--regex--s0-0-v1--base--pl--lib@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/becke-ch--regex--s0-0-v1--base--pl--lib/-/becke-ch--regex--s0-0-v1--base--pl--lib-1.4.0.tgz#429ceebbfa5f7e936e78d73fbdc7da7162b20e20" - integrity sha1-Qpzuu/pffpNueNc/vcfacWKyDiA= - -binary-extensions@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" - integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== - -bluebird@^3.4.3, bluebird@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -body-parser@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== - dependencies: - bytes "3.1.0" - content-type "~1.0.4" - debug "2.6.9" - depd "~1.1.2" - http-errors "1.7.2" - iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.7.0" - raw-body "2.4.0" - type-is "~1.6.17" - -boxen@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64" - integrity sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ== - dependencies: - ansi-align "^3.0.0" - camelcase "^5.3.1" - chalk "^3.0.0" - cli-boxes "^2.2.0" - string-width "^4.1.0" - term-size "^2.1.0" - type-fest "^0.8.1" - widest-line "^3.1.0" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^3.0.1, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -builtin-modules@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.1.0.tgz#aad97c15131eb76b65b50ef208e7584cd76a7484" - integrity sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw== - -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== - -cacheable-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" - integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^3.0.0" - lowercase-keys "^2.0.0" - normalize-url "^4.1.0" - responselike "^1.0.2" - -caching-transform@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-4.0.0.tgz#00d297a4206d71e2163c39eaffa8157ac0651f0f" - integrity sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA== - dependencies: - hasha "^5.0.0" - make-dir "^3.0.0" - package-hash "^4.0.0" - write-file-atomic "^3.0.0" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camel-case@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" - integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= - dependencies: - no-case "^2.2.0" - upper-case "^1.1.1" - -camelcase-keys@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" - integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg== - dependencies: - camelcase "^5.3.1" - map-obj "^4.0.0" - quick-lru "^4.0.1" - -camelcase@^5.0.0, camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.0.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" - integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== - -capital-case@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/capital-case/-/capital-case-1.0.4.tgz#9d130292353c9249f6b00fa5852bee38a717e669" - integrity sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - upper-case-first "^2.0.2" - -chai-exclude@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/chai-exclude/-/chai-exclude-2.0.3.tgz#38c159a5e098971b795cafd492d48ae58d651a23" - integrity sha512-6VuTQX25rsh4hKPdLzsOtL20k9+tszksLQrLtsu6szTmSVJP9+gUkqYUsyM+xqCeGZKeRJCsamCMRUQJhWsQ+g== - dependencies: - fclone "^1.0.11" - -chai@4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49" - integrity sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA== - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^3.0.1" - get-func-name "^2.0.0" - pathval "^1.1.1" - type-detect "^4.0.5" - -chalk@^2.0.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^4.0.0, chalk@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= - -chokidar@3.5.1: - version "3.5.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" - integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.5.0" - optionalDependencies: - fsevents "~2.3.1" - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cli-boxes@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" - integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== - -cli-table3@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.0.tgz#b7b1bc65ca8e7b5cef9124e13dc2b21e2ce4faee" - integrity sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ== - dependencies: - object-assign "^4.1.0" - string-width "^4.2.0" - optionalDependencies: - colors "^1.1.2" - -cliui@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" - integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^6.2.0" - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -clone-response@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" - integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= - dependencies: - mimic-response "^1.0.0" - -coffeescript@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-2.5.1.tgz#b2442a1f2c806139669534a54adc35010559d16a" - integrity sha512-J2jRPX0eeFh5VKyVnoLrfVFgLZtnnmp96WQSLAS8OrLm2wtQLcnikYKe1gViJKDH7vucjuhHvBKKBP3rKcD1tQ== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -colors@^1.0.3, colors@^1.1.2, colors@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -commander@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.0.0.tgz#3e2bbfd8bb6724760980988fb5b22b7ee6b71ab2" - integrity sha512-ovx/7NkTrnPuIV8sqk/GjUIIM1+iUQeqA3ye2VNpq9sVoiZsooObWlQy+OPWGI17GDaEoybuAGJm6U8yC077BA== - -commander@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -configstore@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" - integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== - dependencies: - dot-prop "^5.2.0" - graceful-fs "^4.1.2" - make-dir "^3.0.0" - unique-string "^2.0.0" - write-file-atomic "^3.0.0" - xdg-basedir "^4.0.0" - -contains-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= - -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== - dependencies: - safe-buffer "5.1.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== - -convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== - dependencies: - safe-buffer "~5.1.1" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= - -cookie@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== - -core-js@^2.6.5: - version "2.6.11" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" - integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -create-require@^1.1.0, create-require@^1.1.1: - 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-spawn@^7.0.0, cross-spawn@^7.0.2: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -crypto-random-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" - integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== - -d@1, d@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" - integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== - dependencies: - es5-ext "^0.10.50" - type "^1.0.1" - -debug@2.6.9, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== - dependencies: - ms "2.1.2" - -debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== - dependencies: - ms "^2.1.1" - -decamelize-keys@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" - integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= - dependencies: - decamelize "^1.1.0" - map-obj "^1.0.0" - -decamelize@^1.1.0, decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= - dependencies: - mimic-response "^1.0.0" - -deep-eql@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" - integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== - dependencies: - type-detect "^4.0.0" - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deep-is@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - -default-require-extensions@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-3.0.0.tgz#e03f93aac9b2b6443fc52e5e4a37b3ad9ad8df96" - integrity sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg== - dependencies: - strip-bom "^4.0.0" - -defer-to-connect@^1.0.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" - integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== - -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -defined@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -dependency-lint@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/dependency-lint/-/dependency-lint-6.0.0.tgz#c990b6e7ccd67d6511c76aef1c83c1b3037afb1b" - integrity sha512-7IHBSIo7OLBlmpilApueGTaCDhjbUfaLtmunGsYHUGBWWoe6e8HJ1aSv1ShCiT/WFgiYC1NSUnJ/Yh0up8fflQ== - dependencies: - "@babel/polyfill" "^7.2.3" - bluebird "^3.4.3" - builtin-modules "^3.0.0" - camel-case "^3.0.0" - colors "^1.0.3" - detective "^5.1.0" - detective-es6 "^2.0.0" - docopt "^0.6.0" - fs-extra "^7.0.1" - glob "^7.0.0" - js-yaml "^3.3.1" - lodash "^4.2.1" - minimatch "^3.0.2" - semver "^6.0.0" - sorted-object "^2.0.0" - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - -detective-es6@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/detective-es6/-/detective-es6-2.2.0.tgz#8f2baba3f8cd90a5cfd748f5ac436f0158ed2585" - integrity sha512-fSpNY0SLER7/sVgQZ1NxJPwmc9uCTzNgdkQDhAaj8NPYwr7Qji9QBcmbNvtMCnuuOGMuKn3O7jv0An+/WRWJZQ== - dependencies: - node-source-walk "^4.0.0" - -detective@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.0.tgz#feb2a77e85b904ecdea459ad897cc90a99bd2a7b" - integrity sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg== - dependencies: - acorn-node "^1.6.1" - defined "^1.0.0" - minimist "^1.1.1" - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -diff@^4.0.1, diff@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -dirty-chai@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/dirty-chai/-/dirty-chai-2.0.1.tgz#6b2162ef17f7943589da840abc96e75bda01aff3" - integrity sha512-ys79pWKvDMowIDEPC6Fig8d5THiC0DJ2gmTeGzVAoEH18J8OzLud0Jh7I9IWg3NSk8x2UocznUuFmfHCXYZx9w== - -docopt@^0.6.0: - version "0.6.2" - resolved "https://registry.yarnpkg.com/docopt/-/docopt-0.6.2.tgz#b28e9e2220da5ec49f7ea5bb24a47787405eeb11" - integrity sha1-so6eIiDaXsSffqW7JKR3h0Be6xE= - -doctrine@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dot-prop@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" - integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== - dependencies: - is-obj "^2.0.0" - -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= - -duration@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/duration/-/duration-0.2.2.tgz#ddf149bc3bc6901150fe9017111d016b3357f529" - integrity sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg== - dependencies: - d "1" - es5-ext "~0.10.46" - -durations@^3.4.2: - version "3.4.2" - resolved "https://registry.yarnpkg.com/durations/-/durations-3.4.2.tgz#1de230454373cccfecab927de0bebae2295301db" - integrity sha512-V/lf7y33dGaypZZetVI1eu7BmvkbC4dItq12OElLRpKuaU5JxQstV2zHwLv8P7cNbQ+KL1WD80zMCTx5dNC4dg== - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -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== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -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== - dependencies: - once "^1.4.0" - -enquirer@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -error-ex@^1.2.0, error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -error-stack-parser@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.6.tgz#5a99a707bd7a4c58a797902d48d82803ede6aad8" - integrity sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ== - dependencies: - stackframe "^1.1.1" - -es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.5: - version "1.17.6" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" - integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.0" - is-regex "^1.1.0" - object-inspect "^1.7.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" - -es-abstract@^1.18.0-next.0: - version "1.18.0-next.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.0.tgz#b302834927e624d8e5837ed48224291f2c66e6fc" - integrity sha512-elZXTZXKn51hUBdJjSZGYRujuzilgXo8vSPQzjGYXLvSlGiCo8VO8ZGV3kjo9a0WNJJ57hENagwbtlRuHuzkcQ== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.0" - is-negative-zero "^2.0.0" - is-regex "^1.1.1" - object-inspect "^1.8.0" - object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" - -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" - -es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@~0.10.46: - version "0.10.53" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" - integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== - dependencies: - es6-iterator "~2.0.3" - es6-symbol "~3.1.3" - next-tick "~1.0.0" - -es6-error@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" - integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== - -es6-iterator@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-symbol@^3.1.1, es6-symbol@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" - integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== - dependencies: - d "^1.0.1" - ext "^1.1.2" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-goat@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" - integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-string-regexp@4.0.0: - version "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.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-config-prettier@8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" - integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== - -eslint-config-standard-with-typescript@20.0.0: - version "20.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-20.0.0.tgz#0c550eca0a216cbf8da9013eb6e311acd3102d87" - integrity sha512-IoySf3r0a2+P3Z6GMjv8p1HuOQ6GWQbMpdt9G8uEbkGpnNWAGBXpgaiutbZHbaQAvG5pkVtYepCfHUxYbVDLCA== - dependencies: - "@typescript-eslint/parser" "^4.0.0" - eslint-config-standard "^16.0.0" - -eslint-config-standard@^16.0.0: - version "16.0.2" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-16.0.2.tgz#71e91727ac7a203782d0a5ca4d1c462d14e234f6" - integrity sha512-fx3f1rJDsl9bY7qzyX8SAtP8GBSk6MfXFaTfaGgk12aAYW4gJSyRm7dM790L6cbXv63fvjY4XeSzXnb4WM+SKw== - -eslint-formatter-pretty@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eslint-formatter-pretty/-/eslint-formatter-pretty-4.0.0.tgz#dc15f3bf4fb51b7ba5fbedb77f57ba8841140ce2" - integrity sha512-QgdeZxQwWcN0TcXXNZJiS6BizhAANFhCzkE7Yl9HKB7WjElzwED6+FbbZB2gji8ofgJTGPqKm6VRCNT3OGCeEw== - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.0" - eslint-rule-docs "^1.1.5" - log-symbols "^4.0.0" - plur "^4.0.0" - string-width "^4.2.0" - supports-hyperlinks "^2.0.0" - -eslint-import-resolver-node@^0.3.4: - version "0.3.4" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717" - integrity sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA== - dependencies: - debug "^2.6.9" - resolve "^1.13.1" - -eslint-module-utils@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6" - integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== - dependencies: - debug "^2.6.9" - pkg-dir "^2.0.0" - -eslint-plugin-es@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" - integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== - dependencies: - eslint-utils "^2.0.0" - regexpp "^3.0.0" - -eslint-plugin-import@2.22.1: - version "2.22.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz#0896c7e6a0cf44109a2d97b95903c2bb689d7702" - integrity sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw== - dependencies: - array-includes "^3.1.1" - array.prototype.flat "^1.2.3" - contains-path "^0.1.0" - debug "^2.6.9" - doctrine "1.5.0" - eslint-import-resolver-node "^0.3.4" - eslint-module-utils "^2.6.0" - has "^1.0.3" - minimatch "^3.0.4" - object.values "^1.1.1" - read-pkg-up "^2.0.0" - resolve "^1.17.0" - tsconfig-paths "^3.9.0" - -eslint-plugin-node@11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" - integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== - dependencies: - eslint-plugin-es "^3.0.0" - eslint-utils "^2.0.0" - ignore "^5.1.1" - minimatch "^3.0.4" - resolve "^1.10.1" - semver "^6.1.0" - -eslint-plugin-prettier@3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz#cdbad3bf1dbd2b177e9825737fe63b476a08f0c7" - integrity sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw== - dependencies: - prettier-linter-helpers "^1.0.0" - -eslint-plugin-promise@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-5.1.0.tgz#fb2188fb734e4557993733b41aa1a688f46c6f24" - integrity sha512-NGmI6BH5L12pl7ScQHbg7tvtk4wPxxj8yPHH47NvSmMtFneC077PSeY3huFj06ZWZvtbfxSPt3RuOQD5XcR4ng== - -eslint-plugin-standard@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.1.0.tgz#0c3bf3a67e853f8bbbc580fb4945fbf16f41b7c5" - integrity sha512-ZL7+QRixjTR6/528YNGyDotyffm5OQst/sGxKDwGb9Uqs4In5Egi4+jbobhqJoyoCM6/7v/1A5fhQ7ScMtDjaQ== - -eslint-rule-docs@^1.1.5: - version "1.1.218" - resolved "https://registry.yarnpkg.com/eslint-rule-docs/-/eslint-rule-docs-1.1.218.tgz#089482e87918995f51f86c5412b30c9cb46a1ea1" - integrity sha512-oGT85qE8VvBEUuW1/9NjCye9+1kY5zjjiJgkzPHPDhwS3k3GwEN9NfflKW+eDM+lYB18EVuXUDiubNcdgabEQA== - -eslint-scope@^5.0.0, eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-utils@^2.0.0, eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint-visitor-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" - integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== - -eslint@7.25.0: - version "7.25.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.25.0.tgz#1309e4404d94e676e3e831b3a3ad2b050031eb67" - integrity sha512-TVpSovpvCNpLURIScDRB6g5CYu/ZFq9GfX2hLNIV4dSBKxIWojeDODvYl3t0k0VtMxYeR8OXPCFE5+oHMlGfhw== - dependencies: - "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.0" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.0.1" - doctrine "^3.0.0" - enquirer "^2.3.5" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^2.0.0" - espree "^7.3.1" - esquery "^1.4.0" - esutils "^2.0.2" - file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^13.6.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash "^4.17.21" - minimatch "^3.0.4" - natural-compare "^1.4.0" - optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" - strip-json-comments "^3.1.0" - table "^6.0.4" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - -espree@^7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.0.tgz#dc30437cf67947cf576121ebd780f15eeac72348" - integrity sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw== - dependencies: - acorn "^7.4.0" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.3.0" - -espree@^7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" - integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== - dependencies: - acorn "^7.4.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^1.3.0" - -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== - -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== - -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== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -express@4.17.1: - version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== - dependencies: - accepts "~1.3.7" - array-flatten "1.1.1" - body-parser "1.19.0" - content-disposition "0.5.3" - content-type "~1.0.4" - cookie "0.4.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "~1.1.2" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.1.2" - fresh "0.5.2" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.5" - qs "6.7.0" - range-parser "~1.2.1" - safe-buffer "5.1.2" - send "0.17.1" - serve-static "1.14.1" - setprototypeof "1.1.1" - statuses "~1.5.0" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -ext@^1.1.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244" - integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A== - dependencies: - type "^2.0.0" - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -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-diff@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" - integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== - -fast-glob@^3.1.1: - version "3.2.4" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" - integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.0" - merge2 "^1.3.0" - micromatch "^4.0.2" - picomatch "^2.2.1" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fastq@^1.6.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.9.0.tgz#e16a72f338eaca48e91b5c23593bcc2ef66b7947" - integrity sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w== - dependencies: - reusify "^1.0.4" - -fclone@^1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/fclone/-/fclone-1.0.11.tgz#10e85da38bfea7fc599341c296ee1d77266ee640" - integrity sha1-EOhdo4v+p/xZk0HClu4ddyZu5kA= - -figures@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - -find-cache-dir@^3.2.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" - integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - -find-up@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067" - integrity sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA== - -foreground-child@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-2.0.0.tgz#71b32800c9f15aa8f2f83f4a6bd9bff35d861a53" - integrity sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^3.0.2" - -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -fromentries@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.2.1.tgz#64c31665630479bc993cd800d53387920dc61b4d" - integrity sha512-Xu2Qh8yqYuDhQGOhD5iJGninErSfI9A3FrriD3tjUgV5VbJFeH8vfgZ9HnC6jWN80QDVNQK5vmxRAmEAp7Mevw== - -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-extra@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@~2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -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== - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -gensync@^1.0.0-beta.1: - version "1.0.0-beta.1" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" - integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== - -get-caller-file@^2.0.1, get-caller-file@^2.0.5: - version "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-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= - -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-stream@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - -glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== - dependencies: - is-glob "^4.0.1" - -glob@7.1.6, glob@^7.0.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -global-dirs@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.1.0.tgz#e9046a49c806ff04d6c1825e196c8f0091e8df4d" - integrity sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ== - dependencies: - ini "1.3.7" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^12.1.0: - version "12.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" - integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== - dependencies: - type-fest "^0.8.1" - -globals@^13.6.0: - version "13.7.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.7.0.tgz#aed3bcefd80ad3ec0f0be2cf0c895110c0591795" - integrity sha512-Aipsz6ZKRxa/xQkZhNg0qIWXT6x6rD46f6x/PCnBomlttdIyAPak4YD9jTmKpZ72uROSMU87qJtcgpgHaVchiA== - dependencies: - type-fest "^0.20.2" - -globby@^11.0.1: - version "11.0.1" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357" - integrity sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" - slash "^3.0.0" - -got@^9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" - integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== - dependencies: - "@sindresorhus/is" "^0.14.0" - "@szmarczak/http-timer" "^1.1.2" - cacheable-request "^6.0.0" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^4.1.0" - lowercase-keys "^1.0.1" - mimic-response "^1.0.1" - p-cancelable "^1.0.0" - to-readable-stream "^1.0.0" - url-parse-lax "^3.0.0" - -graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: - version "4.2.4" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -hard-rejection@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" - integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== - -has-yarn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" - integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== - -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.0" - resolved "https://registry.yarnpkg.com/hasha/-/hasha-5.2.0.tgz#33094d1f69c40a4a6ac7be53d5fe3ff95a269e0c" - integrity sha512-2W+jKdQbAdSIrggA8Q35Br8qKadTrqCTC8+XZvBWepKDK6m9XkX6Iz1a2yh2KP01kzAR/dpuMeUnocoLYDcskw== - dependencies: - is-stream "^2.0.0" - type-fest "^0.8.0" - -he@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -hosted-git-info@^2.1.4: - version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" - integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== - -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: - 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-errors@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.1.1, ignore@^5.1.4: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== - -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" - integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - -ini@1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84" - integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ== - -ini@~1.3.0: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -irregular-plurals@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-3.2.0.tgz#b19c490a0723798db51b235d7e39add44dab0822" - integrity sha512-YqTdPLfwP7YFN0SsD3QUVCkm9ZG2VzOXv3DOrw5G5mkMbVwptTwVcFv7/C0vOpBmgTxAeTG19XpUs1E522LW9Q== - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -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" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-callable@^1.1.4, is-callable@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.1.tgz#4d1e21a4f437509d25ce55f8184350771421c96d" - integrity sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg== - -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - -is-core-module@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" - integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -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 sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -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" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-generator@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-generator/-/is-generator-1.0.3.tgz#c14c21057ed36e328db80347966c693f886389f3" - integrity sha1-wUwhBX7TbjKNuANHlmxpP4hjifM= - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-installed-globally@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" - integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g== - dependencies: - global-dirs "^2.0.1" - is-path-inside "^3.0.1" - -is-negative-zero@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461" - integrity sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE= - -is-npm@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d" - integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig== - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" - integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== - -is-path-inside@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" - integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== - -is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-regex@^1.1.0, is-regex@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" - integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== - dependencies: - has-symbols "^1.0.1" - -is-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" - integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== - -is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== - dependencies: - has-symbols "^1.0.1" - -is-typedarray@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -is-yarn-global@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" - integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - -isarray@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.0.0-alpha.1: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" - integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== - -istanbul-lib-hook@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz#8f84c9434888cc6b1d0a9d7092a76d239ebf0cc6" - integrity sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ== - dependencies: - append-transform "^2.0.0" - -istanbul-lib-instrument@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" - integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== - dependencies: - "@babel/core" "^7.7.5" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.0.0" - semver "^6.3.0" - -istanbul-lib-processinfo@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz#e1426514662244b2f25df728e8fd1ba35fe53b9c" - integrity sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw== - dependencies: - archy "^1.0.0" - cross-spawn "^7.0.0" - istanbul-lib-coverage "^3.0.0-alpha.1" - make-dir "^3.0.0" - p-map "^3.0.0" - rimraf "^3.0.0" - uuid "^3.3.3" - -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== - dependencies: - istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" - supports-color "^7.1.0" - -istanbul-lib-source-maps@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz#75743ce6d96bb86dc7ee4352cf6366a23f0b1ad9" - integrity sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" - -istanbul-reports@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b" - integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw== - dependencies: - html-escaper "^2.0.0" - istanbul-lib-report "^3.0.0" - -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.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f" - integrity sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q== - dependencies: - argparse "^2.0.1" - -js-yaml@^3.13.1, js-yaml@^3.3.1: - version "3.14.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" - integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -json-buffer@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" - integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= - -json-parse-even-better-errors@^2.3.0: - version "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-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== - dependencies: - minimist "^1.2.0" - -json5@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" - integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== - dependencies: - minimist "^1.2.5" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.0.1.tgz#98966cba214378c8c84b82e085907b40bf614179" - integrity sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg== - dependencies: - universalify "^1.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -just-extend@^4.0.2: - version "4.1.1" - resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.1.1.tgz#158f1fdb01f128c411dc8b286a7b4837b3545282" - integrity sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA== - -keyv@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" - integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== - dependencies: - json-buffer "3.0.0" - -kind-of@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -knuth-shuffle-seeded@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/knuth-shuffle-seeded/-/knuth-shuffle-seeded-1.0.6.tgz#01f1b65733aa7540ee08d8b0174164d22081e4e1" - integrity sha1-AfG2VzOqdUDuCNiwF0Fk0iCB5OE= - dependencies: - seed-random "~2.2.0" - -latest-version@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" - integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== - dependencies: - package-json "^6.3.0" - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -lines-and-columns@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" - integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= - -load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.flattendeep@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" - integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= - -lodash.get@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= - -lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.2.1: - version "4.17.20" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" - integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== - -lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-symbols@4.0.0, log-symbols@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920" - integrity sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA== - dependencies: - chalk "^4.0.0" - -long@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== - -lower-case@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" - integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= - -lower-case@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" - integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== - dependencies: - tslib "^2.0.3" - -lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== - -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -make-dir@^3.0.0, make-dir@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -map-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= - -map-obj@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.1.0.tgz#b91221b542734b9f14256c0132c897c5d7256fd5" - integrity sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g== - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= - -meow@^7.0.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/meow/-/meow-7.1.1.tgz#7c01595e3d337fcb0ec4e8eed1666ea95903d306" - integrity sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA== - dependencies: - "@types/minimist" "^1.2.0" - camelcase-keys "^6.2.2" - decamelize-keys "^1.1.0" - hard-rejection "^2.1.0" - minimist-options "4.1.0" - normalize-package-data "^2.5.0" - read-pkg-up "^7.0.1" - redent "^3.0.0" - trim-newlines "^3.0.0" - type-fest "^0.13.1" - yargs-parser "^18.1.3" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= - -merge2@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= - -micromatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" - integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== - dependencies: - braces "^3.0.1" - picomatch "^2.0.5" - -mime-db@1.44.0: - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== - -mime-types@~2.1.24: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== - dependencies: - mime-db "1.44.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mimic-response@^1.0.0, mimic-response@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -min-indent@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" - integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== - -minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist-options@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" - integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== - dependencies: - arrify "^1.0.1" - is-plain-obj "^1.1.0" - kind-of "^6.0.3" - -minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== - -mocha@8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.3.2.tgz#53406f195fa86fbdebe71f8b1c6fb23221d69fcc" - integrity sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg== - dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.1" - debug "4.3.1" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.1.6" - growl "1.10.5" - he "1.2.0" - js-yaml "4.0.0" - log-symbols "4.0.0" - minimatch "3.0.4" - ms "2.1.3" - nanoid "3.1.20" - serialize-javascript "5.0.1" - strip-json-comments "3.1.1" - supports-color "8.1.1" - which "2.0.2" - wide-align "1.1.3" - workerpool "6.1.0" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - -ms@2.1.2, ms@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -mustache@4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64" - integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ== - -mz@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" - integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - -nanoid@3.1.20: - version "3.1.20" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" - integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -ndjson-parse@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/ndjson-parse/-/ndjson-parse-1.0.4.tgz#65c031147ea1b5fa6f692e4fd63ab75f89dbf648" - integrity sha512-xwglvz2dMbxvX4NAVKnww8xEJ4kp4+CKVseQQdtkA79yI3abPqyBYqk6A6HvNci5oS0cUsSHheMEV1c+9MWlEw== - -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== - -next-tick@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" - integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= - -nise@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/nise/-/nise-4.1.0.tgz#8fb75a26e90b99202fa1e63f448f58efbcdedaf6" - integrity sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA== - dependencies: - "@sinonjs/commons" "^1.7.0" - "@sinonjs/fake-timers" "^6.0.0" - "@sinonjs/text-encoding" "^0.7.1" - just-extend "^4.0.2" - path-to-regexp "^1.7.0" - -no-case@^2.2.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" - integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== - dependencies: - lower-case "^1.1.1" - -no-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" - integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== - dependencies: - lower-case "^2.0.2" - tslib "^2.0.3" - -node-preload@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/node-preload/-/node-preload-0.2.1.tgz#c03043bb327f417a18fee7ab7ee57b408a144301" - integrity sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ== - dependencies: - process-on-spawn "^1.0.0" - -node-source-walk@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/node-source-walk/-/node-source-walk-4.2.0.tgz#c2efe731ea8ba9c03c562aa0a9d984e54f27bc2c" - integrity sha512-hPs/QMe6zS94f5+jG3kk9E7TNm4P2SulrKiLWMzKszBfNZvL/V6wseHlTd7IvfW0NZWqPtK3+9yYNr+3USGteA== - dependencies: - "@babel/parser" "^7.0.0" - -normalize-package-data@^2.3.2, 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" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -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" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -normalize-url@^4.1.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" - integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== - -nyc@15.1.0: - version "15.1.0" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-15.1.0.tgz#1335dae12ddc87b6e249d5a1994ca4bdaea75f02" - integrity sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A== - dependencies: - "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.2" - caching-transform "^4.0.0" - convert-source-map "^1.7.0" - decamelize "^1.2.0" - find-cache-dir "^3.2.0" - find-up "^4.1.0" - foreground-child "^2.0.0" - get-package-type "^0.1.0" - glob "^7.1.6" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-hook "^3.0.0" - istanbul-lib-instrument "^4.0.0" - istanbul-lib-processinfo "^2.0.2" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.0.2" - make-dir "^3.0.0" - node-preload "^0.2.1" - p-map "^3.0.0" - process-on-spawn "^1.0.0" - resolve-from "^5.0.0" - rimraf "^3.0.0" - signal-exit "^3.0.2" - spawn-wrap "^2.0.0" - test-exclude "^6.0.0" - yargs "^15.0.2" - -object-assign@^4.0.1, object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-inspect@^1.7.0, object-inspect@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" - integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== - -object-keys@^1.0.12, 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.assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.1.tgz#303867a666cdd41936ecdedfb1f8f3e32a478cdd" - integrity sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.18.0-next.0" - has-symbols "^1.0.1" - object-keys "^1.1.1" - -object.values@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" - integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - has "^1.0.3" - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - -p-cancelable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" - integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.0.2.tgz#1664e010af3cadc681baafd3e2a437be7b0fb5fe" - integrity sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg== - dependencies: - p-try "^2.0.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-map@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" - integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== - dependencies: - aggregate-error "^3.0.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -package-hash@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-4.0.0.tgz#3537f654665ec3cc38827387fc904c163c54f506" - integrity sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ== - dependencies: - graceful-fs "^4.1.15" - hasha "^5.0.0" - lodash.flattendeep "^4.4.0" - release-zalgo "^1.0.0" - -package-json@^6.3.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" - integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== - dependencies: - got "^9.6.0" - registry-auth-token "^4.0.0" - registry-url "^5.0.0" - semver "^6.2.0" - -pad-right@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/pad-right/-/pad-right-0.2.2.tgz#6fbc924045d244f2a2a244503060d3bfc6009774" - integrity sha1-b7ySQEXSRPKiokRQMGDTv8YAl3Q= - dependencies: - repeat-string "^1.5.2" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - -parse-json@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.1.0.tgz#f96088cdf24a8faa9aea9a009f2d9d942c999646" - integrity sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= - -path-to-regexp@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" - integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== - dependencies: - isarray "0.0.1" - -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= - dependencies: - pify "^2.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" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -pathval@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" - integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== - -picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" - integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= - dependencies: - find-up "^2.1.0" - -pkg-dir@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -plur@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/plur/-/plur-4.0.0.tgz#729aedb08f452645fe8c58ef115bf16b0a73ef84" - integrity sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg== - dependencies: - irregular-plurals "^3.2.0" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= - -prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" - integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== - dependencies: - fast-diff "^1.1.2" - -prettier@2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" - integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== - -process-on-spawn@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/process-on-spawn/-/process-on-spawn-1.0.0.tgz#95b05a23073d30a17acfdc92a440efd2baefdc93" - integrity sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg== - dependencies: - fromentries "^1.2.0" - -progress@^2.0.0, progress@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -promise-polyfill@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-1.1.6.tgz#cd04eff46f5c95c3a7d045591d79b5e3e01f12d7" - integrity sha1-zQTv9G9clcOn0EVZHXm14+AfEtc= - -protobufjs@^6.10.2: - version "6.10.2" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.2.tgz#b9cb6bd8ec8f87514592ba3fdfd28e93f33a469b" - integrity sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ== - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/long" "^4.0.1" - "@types/node" "^13.7.0" - long "^4.0.0" - -proxy-addr@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" - integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== - dependencies: - forwarded "~0.1.2" - ipaddr.js "1.9.1" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -pupa@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" - integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== - dependencies: - escape-goat "^2.0.0" - -qs@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== - -quick-lru@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" - integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== - dependencies: - bytes "3.1.0" - http-errors "1.7.2" - iconv-lite "0.4.24" - unpipe "1.0.0" - -rc@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - -read-pkg-up@^7.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" - integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== - dependencies: - find-up "^4.1.0" - read-pkg "^5.2.0" - type-fest "^0.8.1" - -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - -read-pkg@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" - integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== - dependencies: - "@types/normalize-package-data" "^2.4.0" - normalize-package-data "^2.5.0" - parse-json "^5.0.0" - type-fest "^0.6.0" - -readdirp@~3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" - integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== - dependencies: - picomatch "^2.2.1" - -redent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" - integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== - dependencies: - indent-string "^4.0.0" - strip-indent "^3.0.0" - -regenerator-runtime@^0.13.4: - version "0.13.7" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" - integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== - -regexpp@^3.0.0, regexpp@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" - integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== - -registry-auth-token@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" - integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== - dependencies: - rc "^1.2.8" - -registry-url@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" - integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== - dependencies: - rc "^1.2.8" - -release-zalgo@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" - integrity sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA= - dependencies: - es6-error "^4.0.1" - -repeat-string@^1.5.2, repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-pkg/-/resolve-pkg-2.0.0.tgz#ac06991418a7623edc119084edc98b0e6bf05a41" - integrity sha512-+1lzwXehGCXSeryaISr6WujZzowloigEofRB+dj75y9RRa/obVcYgbHJd53tdYw8pvZj8GojXaaENws8Ktw/hQ== - dependencies: - resolve-from "^5.0.0" - -resolve@^1.10.0, resolve@^1.10.1, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== - dependencies: - path-parse "^1.0.6" - -resolve@^1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" - integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== - dependencies: - is-core-module "^2.1.0" - path-parse "^1.0.6" - -responselike@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= - dependencies: - lowercase-keys "^1.0.0" - -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.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" - -run-parallel@^1.1.9: - version "1.1.10" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.10.tgz#60a51b2ae836636c81377df16cb107351bcd13ef" - integrity sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw== - -safe-buffer@5.1.2, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@^5.1.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== - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -seed-random@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/seed-random/-/seed-random-2.2.0.tgz#2a9b19e250a817099231a5b99a4daf80b7fbed54" - integrity sha1-KpsZ4lCoFwmSMaW5mk2vgLf77VQ= - -semver-diff@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" - integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== - dependencies: - semver "^6.3.0" - -"semver@2 || 3 || 4 || 5", semver@^5.4.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - -semver@^6.0.0, semver@^6.1.0, semver@^6.2.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@^7.2.1, semver@^7.3.2: - version "7.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== - -send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "~1.7.2" - mime "1.6.0" - ms "2.1.1" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" - -serialize-javascript@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" - integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== - dependencies: - randombytes "^2.1.0" - -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.1" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -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== - -signal-exit@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" - integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== - -sinon-chai@3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-3.6.0.tgz#25bd59a37ef8990245e085a40f1f79d6bf023b7a" - integrity sha512-bk2h+0xyKnmvazAnc7HE5esttqmCerSMcBtuB2PS2T4tG6x8woXAxZeJaOJWD+8reXHngnXn0RtIbfEW9OTHFg== - -sinon@10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-10.0.0.tgz#52279f97e35646ff73d23207d0307977c9b81430" - integrity sha512-XAn5DxtGVJBlBWYrcYKEhWCz7FLwZGdyvANRyK06419hyEpdT0dMc5A8Vcxg5SCGHc40CsqoKsc1bt1CbJPfNw== - dependencies: - "@sinonjs/commons" "^1.8.1" - "@sinonjs/fake-timers" "^6.0.1" - "@sinonjs/samsam" "^5.3.1" - diff "^4.0.2" - nise "^4.1.0" - supports-color "^7.1.0" - -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" - -sorted-object@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/sorted-object/-/sorted-object-2.0.1.tgz#7d631f4bd3a798a24af1dffcfbfe83337a5df5fc" - integrity sha1-fWMfS9OnmKJK8d/8+/6DM3pd9fw= - -source-map-support@^0.5.17, source-map-support@^0.5.19: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@0.5.6: - version "0.5.6" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" - integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= - -source-map@^0.5.0: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, 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-wrap@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-2.0.0.tgz#103685b8b8f9b79771318827aa78650a610d457e" - integrity sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg== - dependencies: - foreground-child "^2.0.0" - is-windows "^1.0.2" - make-dir "^3.0.0" - rimraf "^3.0.0" - signal-exit "^3.0.2" - 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== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.5" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" - integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -stack-chain@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-2.0.0.tgz#d73d1172af89565f07438b5bcc086831b6689b2d" - integrity sha512-GGrHXePi305aW7XQweYZZwiRwR7Js3MWoK/EHzzB9ROdc75nCnjSJVi21rdAGxFl+yCx2L2qdfl5y7NO4lTyqg== - -stack-generator@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36" - integrity sha512-/t1ebrbHkrLrDuNMdeAcsvynWgoH/i4o8EGGfX7dEYDoTXOYVAkEpFdtshlvabzc6JlJ8Kf9YdFEoz7JkzGN9Q== - dependencies: - stackframe "^1.1.1" - -stackframe@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303" - integrity sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA== - -stacktrace-gps@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.4.tgz#7688dc2fc09ffb3a13165ebe0dbcaf41bcf0c69a" - integrity sha512-qIr8x41yZVSldqdqe6jciXEaSCKw1U8XTXpjDuy0ki/apyTn/r3w9hDAAQOhZdxvsC93H+WwwEu5cq5VemzYeg== - dependencies: - source-map "0.5.6" - stackframe "^1.1.1" - -stacktrace-js@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-2.0.2.tgz#4ca93ea9f494752d55709a081d400fdaebee897b" - integrity sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg== - dependencies: - error-stack-parser "^2.0.6" - stack-generator "^2.0.5" - stacktrace-gps "^3.0.4" - -"statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -stream-buffers@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-3.0.2.tgz#5249005a8d5c2d00b3a32e6e0a6ea209dc4f3521" - integrity sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ== - -stream-to-string@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/stream-to-string/-/stream-to-string-1.2.0.tgz#3ca506a097ecbf78b0e0aee0b6fa5c4565412a15" - integrity sha512-8drZlFIKBHSMdX9GCWv8V9AAWnQcTqw0iAI6/GC7UJ0H0SwKeFKjOoZfGY1tOU00GGU7FYZQoJ/ZCUEoXhD7yQ== - dependencies: - promise-polyfill "^1.1.6" - -string-argv@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" - integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== - -"string-width@^1.0.2 || 2": - 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-width@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -string.prototype.trimend@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" - integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -string.prototype.trimstart@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" - integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== - dependencies: - ansi-regex "^5.0.0" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - -strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - -strip-indent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" - integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== - dependencies: - min-indent "^1.0.0" - -strip-json-comments@3.1.1, strip-json-comments@^3.1.0, 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== - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -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@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.0.0, supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-hyperlinks@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz#f663df252af5f37c5d49bbd7eeefa9e0b9e59e47" - integrity sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA== - dependencies: - has-flag "^4.0.0" - supports-color "^7.0.0" - -table@^6.0.4: - version "6.0.4" - resolved "https://registry.yarnpkg.com/table/-/table-6.0.4.tgz#c523dd182177e926c723eb20e1b341238188aa0d" - integrity sha512-sBT4xRLdALd+NFBvwOz8bw4b15htyythha+q+DVZqy2RS08PPC8O2sZFgJYEY7bJvbCFKccs+WIZ/cd+xxTWCw== - dependencies: - ajv "^6.12.4" - lodash "^4.17.20" - slice-ansi "^4.0.0" - string-width "^4.2.0" - -term-size@^2.1.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54" - integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg== - -test-exclude@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" - integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== - dependencies: - "@istanbuljs/schema" "^0.1.2" - glob "^7.1.4" - minimatch "^3.0.4" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -thenify-all@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" - integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.1" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" - integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== - dependencies: - any-promise "^1.0.0" - -tmp@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-readable-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" - integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== - -trim-newlines@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.0.tgz#79726304a6a898aa8373427298d54c2ee8b1cb30" - integrity sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA== - -ts-node@9.1.1: - version "9.1.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" - integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== - dependencies: - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - source-map-support "^0.5.17" - yn "3.1.1" - -tsconfig-paths@^3.9.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" - integrity sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.0" - strip-bom "^3.0.0" - -tsd@0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/tsd/-/tsd-0.14.0.tgz#9bd1c93e925408846949d59fe4754655749a5f2b" - integrity sha512-fl1gS5orAwqIb0P2xMdppgCrwv1BfCJn67wBzRBCV9OUaWHVXHqiIqL6yX/519xFgT1ZOaLMhr5W9XDo8kuuRA== - dependencies: - eslint-formatter-pretty "^4.0.0" - globby "^11.0.1" - meow "^7.0.1" - path-exists "^4.0.0" - read-pkg-up "^7.0.0" - update-notifier "^4.1.0" - -tslib@^1.8.1: - version "1.13.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" - integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== - -tslib@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" - integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== - -tsutils@^3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" - integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== - dependencies: - tslib "^1.8.1" - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5, type-detect@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" - integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== - -type-fest@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934" - integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" - integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== - -type-fest@^0.8.0, type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -type-is@~1.6.17, type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -type@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" - integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== - -type@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.1.0.tgz#9bdc22c648cf8cf86dd23d32336a41cfb6475e3f" - integrity sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA== - -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - -typescript@4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" - integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== - -unique-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" - integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== - dependencies: - crypto-random-string "^2.0.0" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -universalify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" - integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug== - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -update-notifier@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.3.tgz#be86ee13e8ce48fb50043ff72057b5bd598e1ea3" - integrity sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A== - dependencies: - boxen "^4.2.0" - chalk "^3.0.0" - configstore "^5.0.1" - has-yarn "^2.1.0" - import-lazy "^2.1.0" - is-ci "^2.0.0" - is-installed-globally "^0.3.1" - is-npm "^4.0.0" - is-yarn-global "^0.3.0" - latest-version "^5.0.0" - pupa "^2.0.1" - semver-diff "^3.1.1" - xdg-basedir "^4.0.0" - -upper-case-first@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-2.0.2.tgz#992c3273f882abd19d1e02894cc147117f844324" - integrity sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg== - dependencies: - tslib "^2.0.3" - -upper-case@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" - integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= - -uri-js@^4.2.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602" - integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g== - dependencies: - punycode "^2.1.0" - -url-parse-lax@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" - integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= - dependencies: - prepend-http "^2.0.0" - -util-arity@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/util-arity/-/util-arity-1.1.0.tgz#59d01af1fdb3fede0ac4e632b0ab5f6ce97c9330" - integrity sha1-WdAa8f2z/t4KxOYysKtfbOl8kzA= - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - -uuid@^3.3.3: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -v8-compile-cache@^2.0.3: - version "2.1.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" - integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ== - -validate-npm-package-license@^3.0.1: - 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== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - -verror@^1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@2.0.2, which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wide-align@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== - dependencies: - string-width "^4.0.0" - -word-wrap@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -workerpool@6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.0.tgz#a8e038b4c94569596852de7a8ea4228eefdeb37b" - integrity sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg== - -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== - dependencies: - ansi-styles "^4.0.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== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write-file-atomic@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== - dependencies: - imurmurhash "^0.1.4" - is-typedarray "^1.0.0" - signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" - -xdg-basedir@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" - integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== - -xtend@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== - -y18n@^5.0.5: - version "5.0.5" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18" - integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg== - -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== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^18.1.2, yargs-parser@^18.1.3: - version "18.1.3" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" - integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^20.2.2: - version "20.2.6" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.6.tgz#69f920addf61aafc0b8b89002f5d66e28f2d8b20" - integrity sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA== - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yargs@^15.0.2: - version "15.4.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" - integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== - dependencies: - cliui "^6.0.0" - decamelize "^1.2.0" - find-up "^4.1.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^4.2.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^18.1.2" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==