From 06c83bc69117b566636ccdcda650e8e75f16318b Mon Sep 17 00:00:00 2001 From: Pascal Jufer Date: Fri, 24 Jun 2022 13:18:15 +0200 Subject: [PATCH] Code Style & Performance Optimizations (#334) --- .eslintrc.json | 2 + .github/actions/setup-npm-cache/action.yml | 14 + .github/workflows/ci.yml | 104 +++ .github/workflows/test.yml | 68 -- README.md | 32 +- bin/concurrently.spec.ts | 19 +- bin/fixtures/read-echo.js | 1 + jest.config.js | 11 + package-lock.json | 951 ++++++++++++--------- package.json | 29 +- src/command-parser/expand-arguments.ts | 6 +- src/command-parser/expand-npm-shortcut.ts | 5 +- src/command-parser/expand-npm-wildcard.ts | 13 +- src/command-parser/strip-quotes.ts | 4 +- src/concurrently.spec.ts | 10 + src/concurrently.ts | 30 +- src/flow-control/input-handler.spec.ts | 11 + src/flow-control/kill-on-signal.ts | 2 +- src/flow-control/kill-others.spec.ts | 11 +- src/flow-control/log-error.spec.ts | 21 +- src/get-spawn-opts.spec.ts | 2 +- src/get-spawn-opts.ts | 25 +- src/logger.spec.ts | 14 + src/logger.ts | 4 +- src/output-writer.spec.ts | 14 +- tsconfig.json | 1 - 26 files changed, 830 insertions(+), 574 deletions(-) create mode 100644 .github/actions/setup-npm-cache/action.yml create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/test.yml create mode 100644 jest.config.js diff --git a/.eslintrc.json b/.eslintrc.json index c11b34d4..ed8182c2 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -17,7 +17,9 @@ "curly": "error", "eqeqeq": ["error", "always", { "null": "ignore" }], "no-var": "error", + "no-console": "error", "prefer-const": "error", + "prefer-object-spread": "error", "prettier/prettier": ["error"] } } diff --git a/.github/actions/setup-npm-cache/action.yml b/.github/actions/setup-npm-cache/action.yml new file mode 100644 index 00000000..1b1d1e5b --- /dev/null +++ b/.github/actions/setup-npm-cache/action.yml @@ -0,0 +1,14 @@ +# See https://github.com/actions/cache/blob/main/examples.md#node---npm +name: Setup NPM cache +runs: + using: composite + steps: + - id: npm-cache-dir + run: echo "::set-output name=dir::$(npm config get cache)" + shell: bash + - uses: actions/cache@v3 + with: + path: ${{ steps.npm-cache-dir.outputs.dir }} + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..558d8c15 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,104 @@ +# Continuous Integration +name: CI + +on: + push: + branches: + - main + pull_request: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + lint-format: + name: Lint & Format + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node }} + + - name: Setup NPM cache + uses: ./.github/actions/setup-npm-cache + + - name: Install dependencies + run: npm ci + + - name: Lint + run: npm run lint + + - name: Format + run: npm run format + + test: + name: Test (Node.js ${{ matrix.node }} on ${{ matrix.os.name }}) + runs-on: ${{ matrix.os.version }} + strategy: + fail-fast: false + matrix: + node: + - 12 + - 14 + - 16 + - 17 + os: + - name: Ubuntu + version: ubuntu-latest + - name: Windows + version: windows-latest + - name: macOS + version: macOS-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node }} + + - name: Setup NPM cache + uses: ./.github/actions/setup-npm-cache + + - name: Print versions + run: | + node --version + npm --version + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + + - name: Test + run: npm test + shell: bash + env: + SHELL: '/bin/bash' + + - name: Submit coverage + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.github_token }} + flag-name: Node.js ${{ matrix.node }} on ${{ matrix.os.name }} + parallel: true + + coverage: + name: Coverage + needs: test + runs-on: ubuntu-latest + steps: + - name: Finish coverage + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.github_token }} + parallel-finished: true diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index ee4c75ee..00000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: Tests - -on: - push: - branches: - - main - pull_request: - branches: - - main - -env: - CI: true - -jobs: - run: - name: Node ${{ matrix.node }} on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - matrix: - node: [12, 14, 16, 17] - os: [ubuntu-latest, windows-latest, macOS-latest] - - steps: - - name: Clone repository - uses: actions/checkout@v3 - - - name: Set Node.js version - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node }} - cache: npm - - - run: node --version - - run: npm --version - - - name: Install npm dependencies - run: npm ci - - - name: Compile - run: npm run build - - - name: Run tests - run: npm test - shell: bash - env: - SHELL: '/bin/bash' - - - name: Lint - run: npm run lint - - - name: Submit coverage - uses: coverallsapp/github-action@master - with: - github-token: ${{ secrets.github_token }} - flag-name: Node.js ${{ matrix.node }} - parallel: true - teardown: - needs: run - name: Submitting coverage - runs-on: ubuntu-latest - steps: - - name: Coveralls Finished - uses: coverallsapp/github-action@master - with: - github-token: ${{ secrets.github_token }} - parallel-finished: true diff --git a/README.md b/README.md index bd0fa638..d5edcc41 100644 --- a/README.md +++ b/README.md @@ -85,15 +85,15 @@ package.json: ```jsonc { - //... - "scripts": { - // ... - "watch-js": "...", - "watch-css": "...", - "watch-node": "...", - // ... - }, + //... + "scripts": { + // ... + "watch-js": "...", + "watch-css": "...", + "watch-node": "..." // ... + } + // ... } ``` @@ -115,15 +115,15 @@ Exclusion is also supported. Given the following scripts in package.json: ```jsonc { + // ... + "scripts": { + "lint:js": "...", + "lint:ts": "...", + "lint:fix:js": "...", + "lint:fix:ts": "..." // ... - "scripts": { - "lint:js": "...", - "lint:ts": "...", - "lint:fix:js": "...", - "lint:fix:ts": "...", - // ... - } - // ... + } + // ... } ``` diff --git a/bin/concurrently.spec.ts b/bin/concurrently.spec.ts index 11fb5068..2cde5e5b 100644 --- a/bin/concurrently.spec.ts +++ b/bin/concurrently.spec.ts @@ -2,11 +2,7 @@ import * as readline from 'readline'; import _ from 'lodash'; import * as Rx from 'rxjs'; import { buffer, map } from 'rxjs/operators'; -import spawn from 'spawn-command'; - -// Increasing timeout for these tests as sometimes it exceeded -// in the CI when running on macOS / Windows (default is 5000ms) -jest.setTimeout(10000); +import { spawn } from 'child_process'; const isWindows = process.platform === 'win32'; const createKillMessage = (prefix: string) => @@ -17,14 +13,17 @@ const createKillMessage = (prefix: string) => * Returns observables for its combined stdout + stderr output, close events, pid, and stdin stream. */ const run = (args: string) => { - // TODO: This should only be transpiled once. Tests become 2.5x slower doing it in every `it`. - const child = spawn('ts-node --transpile-only ./concurrently.ts ' + args, { + // TODO: Optimally, this should only be transpiled once, + // e.g. bundle in `beforeAll` and then reuse here. + const child = spawn(`node -r @swc-node/register ./concurrently.ts ${args}`, { + shell: true, cwd: __dirname, - env: Object.assign({}, process.env, { + env: { + ...process.env, // When upgrading from jest 23 -> 24, colors started printing in the test output. // They are forcibly disabled here - FORCE_COLOR: 0, - }), + FORCE_COLOR: '0', + }, }); const stdout = readline.createInterface({ diff --git a/bin/fixtures/read-echo.js b/bin/fixtures/read-echo.js index 87b288e2..07e3a594 100644 --- a/bin/fixtures/read-echo.js +++ b/bin/fixtures/read-echo.js @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ process.stdin.on('data', chunk => { const line = chunk.toString().trim(); console.log(line); diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000..1b259a68 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,11 @@ +/** @type {import('@jest/types').Config.InitialOptions} */ +const config = { + transform: { + '^.+\\.(t|j)sx?$': ['@swc/jest'], + }, + collectCoverage: true, + collectCoverageFrom: ['src/**/*.ts', '!src/index.ts'], + testPathIgnorePatterns: ['/node_modules/', '/dist'], +}; + +module.exports = config; diff --git a/package-lock.json b/package-lock.json index 9f3148d6..901419c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,9 @@ "concurrently": "dist/bin/concurrently.js" }, "devDependencies": { + "@swc-node/register": "^1.5.1", + "@swc/core": "^1.2.204", + "@swc/jest": "^0.2.21", "@types/jest": "^27.0.3", "@types/lodash": "^4.14.178", "@types/node": "^17.0.0", @@ -40,8 +43,6 @@ "lint-staged": "^12.4.1", "prettier": "^2.6.2", "simple-git-hooks": "^2.7.0", - "ts-jest": "^27.1.4", - "ts-node": "^10.4.0", "typescript": "^4.5.4" }, "engines": { @@ -628,28 +629,6 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@eslint/eslintrc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", @@ -810,6 +789,18 @@ } } }, + "node_modules/@jest/create-cache-key-function": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-27.5.1.tgz", + "integrity": "sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, "node_modules/@jest/environment": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", @@ -1095,6 +1086,306 @@ "@sinonjs/commons": "^1.7.0" } }, + "node_modules/@swc-node/core": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@swc-node/core/-/core-1.9.0.tgz", + "integrity": "sha512-vRnvsMtL9OxybA/Wun1ZhlDvB6MNs4Zujnina0VKdGk+yI6s87KUhdTcbAY6dQMZhQTLFiC1Lnv/BuwCKcCEug==", + "dev": true, + "dependencies": { + "@swc/core": "^1.2.172" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } + }, + "node_modules/@swc-node/register": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@swc-node/register/-/register-1.5.1.tgz", + "integrity": "sha512-6IL5s4QShKGs08qAeNou3rDA3gbp2WHk6fo0XnJXQn/aC9k6FnVBbj/thGOIEDtgNhC/DKpZT8tCY1LpQnOZFg==", + "dev": true, + "dependencies": { + "@swc-node/core": "^1.9.0", + "@swc-node/sourcemap-support": "^0.2.0", + "colorette": "^2.0.16", + "debug": "^4.3.4", + "pirates": "^4.0.5", + "tslib": "^2.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "typescript": ">= 4.3" + } + }, + "node_modules/@swc-node/sourcemap-support": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@swc-node/sourcemap-support/-/sourcemap-support-0.2.0.tgz", + "integrity": "sha512-FNrxdI6XMYfoNt81L8eFKEm1d8P82I1nPwS3MrnBGzZoMWB+seQhQK+iN6M5RreJxXbfZw5lF86LRjHEQeGMqg==", + "dev": true, + "dependencies": { + "source-map-support": "^0.5.21" + } + }, + "node_modules/@swc/core": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.2.205.tgz", + "integrity": "sha512-evq0/tFyYdYgOhKb//+G93fxe9zwFxtme7NL7wSiEF8+4/ON4Y5AI9eHLoqddXqs3W8Y0HQi+rJmlrkCibrseA==", + "dev": true, + "bin": { + "swcx": "run_swcx.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-android-arm-eabi": "1.2.205", + "@swc/core-android-arm64": "1.2.205", + "@swc/core-darwin-arm64": "1.2.205", + "@swc/core-darwin-x64": "1.2.205", + "@swc/core-freebsd-x64": "1.2.205", + "@swc/core-linux-arm-gnueabihf": "1.2.205", + "@swc/core-linux-arm64-gnu": "1.2.205", + "@swc/core-linux-arm64-musl": "1.2.205", + "@swc/core-linux-x64-gnu": "1.2.205", + "@swc/core-linux-x64-musl": "1.2.205", + "@swc/core-win32-arm64-msvc": "1.2.205", + "@swc/core-win32-ia32-msvc": "1.2.205", + "@swc/core-win32-x64-msvc": "1.2.205" + } + }, + "node_modules/@swc/core-android-arm-eabi": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-android-arm-eabi/-/core-android-arm-eabi-1.2.205.tgz", + "integrity": "sha512-HfiuVA1JDHMSRQ8nE1DcemUgZ1PKaPwit4i7q3xin0NVbVHY1xkJyQFuLVh3VxTvGKKkF3hi8GJMVQgOXWL6kg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-android-arm64": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-android-arm64/-/core-android-arm64-1.2.205.tgz", + "integrity": "sha512-sRGZBV2dOnmh8gWWFo9HVOHdKa33zIsF8/8oYEGtq+2/s96UlAKltO2AA7HH9RaO/fT1tzBZStp+fEMUhDk/FA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.2.205.tgz", + "integrity": "sha512-JwVDfKS7vp7zzOQXWNwwcF41h4r3DWEpK6DQjz18WJyS1VVOcpVQGyuE7kSPjcnG01ZxBL9JPwwT353i/8IwDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.2.205.tgz", + "integrity": "sha512-malz2I+w6xFF1QyTmPGt0Y0NEMbUcrvfr5gUfZDGjxMhPPlS7k6fXucuZxVr9VVaM+JGq1SidVODmZ84jb1qHg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-freebsd-x64": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-freebsd-x64/-/core-freebsd-x64-1.2.205.tgz", + "integrity": "sha512-/nZrG1z0T7h97AsOb/wOtYlnh4WEuNppv3XKQIMPj32YNQdMBVgpybVTVRIs1GQGZMd1/7jAy5BVQcwQjUbrLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.2.205.tgz", + "integrity": "sha512-mTA3vETMdBmpecUyI9waZYsp7FABhew4e81psspmFpDyfty0SLISWZDnvPAn0pSnb2fWhzKwDC5kdXHKUmLJuA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.2.205.tgz", + "integrity": "sha512-qGzFGryeQE+O5SFK7Nn2ESqCEnv00rnzhf11WZF9V71EZ15amIhmbcwHqvFpoRSDw8hZnqoGqfPRfoJbouptnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.2.205.tgz", + "integrity": "sha512-uLJoX9L/4Xg3sLMjAbIhzbTe5gD/MBA8VETBeEkLtgb7a0ys1kvn9xQ6qLw6A71amEPlI+VABnoTRdUEaBSV9Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.2.205.tgz", + "integrity": "sha512-gQsjcYlkWKP1kceQIsoHGrOrG7ygW3ojNsSnYoZ5DG5PipRA4eeUfO9YIfrmoa29LiVNjmRPfUJa8O1UHDG5ew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.2.205.tgz", + "integrity": "sha512-LR5ukqBltQc++2eX3qEj/H8KtOt0V3CmtgXNOiNCUxvPDT8mYz/8MJhYOrofonND0RKfXyyPW7dRxg62ceTLSQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.2.205.tgz", + "integrity": "sha512-NjcLWm4mOy78LAEt7pqFl+SLcCyqnSlUP729XRd1uRvKwt1Cwch5SQRdoaFqwf1DaEQy4H4iuGPynkfarlb1kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.2.205.tgz", + "integrity": "sha512-+6byrRxIXgZ0zmLL6ZeX1HBBrAqvCy8MR5Yz0SO26jR8OPZXJCgZXL9BTsZO+YEG4f32ZOlZh3nnHCl6Dcb4GA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.2.205.tgz", + "integrity": "sha512-RRSkyAol0c7sU9gejtrpF8TLmdYdBjLutcmQHtLKbWTm74ZLidZpF28G0J2tD7HNmzQnMpLzyoT1jW9JgLwzVg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/jest": { + "version": "0.2.21", + "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.21.tgz", + "integrity": "sha512-/+NcExiZbxXANNhNPnIdFuGq62CeumulLS1bngwqIXd8H7d96LFUfrYzdt8tlTwLMel8tFtQ5aRjzVkyOTyPDw==", + "dev": true, + "dependencies": { + "@jest/create-cache-key-function": "^27.4.2" + }, + "engines": { + "npm": ">= 7.0.0" + }, + "peerDependencies": { + "@swc/core": "*" + } + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -1104,30 +1395,6 @@ "node": ">= 6" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true - }, "node_modules/@types/babel__core": { "version": "7.1.19", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", @@ -1614,12 +1881,6 @@ "node": ">= 8" } }, - "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": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1777,9 +2038,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.20.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.4.tgz", - "integrity": "sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.0.tgz", + "integrity": "sha512-UQxE0DIhRB5z/zDz9iA03BOfxaN2+GQdBYH/2WrSIWEUrnpzTPJbhqt+umq6r3acaPRTW1FNTkrcp0PXgtFkvA==", "dev": true, "funding": [ { @@ -1792,11 +2053,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001349", - "electron-to-chromium": "^1.4.147", - "escalade": "^3.1.1", + "caniuse-lite": "^1.0.30001358", + "electron-to-chromium": "^1.4.164", "node-releases": "^2.0.5", - "picocolors": "^1.0.0" + "update-browserslist-db": "^1.0.0" }, "bin": { "browserslist": "cli.js" @@ -1805,18 +2065,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/bser": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", @@ -1851,9 +2099,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001358", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001358.tgz", - "integrity": "sha512-hvp8PSRymk85R20bsDra7ZTCpSVGN/PAz9pSAjPSjKC+rNmnUk5vCRgJwiTT/O4feQ/yu/drvZYpKxxhbFuChw==", + "version": "1.0.30001359", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001359.tgz", + "integrity": "sha512-Xln/BAsPzEuiVLgJ2/45IaqD9jShtk3Y33anKb4+yLwQzws3+v6odKfpgES/cDEaZMLzSChpIGdbOYtH9MyuHw==", "dev": true, "funding": [ { @@ -2079,12 +2327,6 @@ "node": ">=12" } }, - "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", @@ -2211,15 +2453,6 @@ "node": ">=8" } }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/diff-sequences": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", @@ -2281,9 +2514,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.163", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.163.tgz", - "integrity": "sha512-c9q94pUVqIdc8hyr7jZDB4bNEoNF3QJ7y35lnddMD+mXtiv5GsL1bT/RmfW/KEOmvlNg5Oy1qioiy4tA7e864Q==", + "version": "1.4.169", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.169.tgz", + "integrity": "sha512-Yb7UFva1sLlAaRyCkgoFF3qWvwZacFDtsGKi44rZsk8vnhL0DMhsUdhI4Dz9CCJQfftncDMGSI3AYiDtg8mD/w==", "dev": true }, "node_modules/emittery": { @@ -3488,6 +3721,15 @@ "node": ">=10" } }, + "node_modules/jest-cli/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/jest-config": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", @@ -4310,12 +4552,6 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -4445,12 +4681,6 @@ "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/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -5532,101 +5762,6 @@ "tree-kill": "cli.js" } }, - "node_modules/ts-jest": { - "version": "27.1.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.5.tgz", - "integrity": "sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==", - "dev": true, - "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@types/jest": "^27.0.0", - "babel-jest": ">=27.0.0 <28", - "jest": "^27.0.0", - "typescript": ">=3.8 <5.0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@types/jest": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/ts-node": { - "version": "10.8.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.1.tgz", - "integrity": "sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.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", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.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-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/tslib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", @@ -5717,6 +5852,32 @@ "node": ">= 4.0.0" } }, + "node_modules/update-browserslist-db": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.4.tgz", + "integrity": "sha512-jnmO2BEGUjsMOe/Fg9u0oczOe/ppIDZPebzccl1yDWGLFP16Pa1/RM5wEoKYPG2zstNcDuAStejyxsOuKINdGA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -5732,12 +5893,6 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, "node_modules/v8-to-istanbul": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", @@ -5987,12 +6142,11 @@ } }, "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs/node_modules/emoji-regex": { @@ -6020,23 +6174,6 @@ "engines": { "node": ">=8" } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", - "engines": { - "node": ">=12" - } - }, - "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" - } } }, "dependencies": { @@ -6482,27 +6619,6 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } - } - }, "@eslint/eslintrc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", @@ -6633,6 +6749,15 @@ "strip-ansi": "^6.0.0" } }, + "@jest/create-cache-key-function": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-27.5.1.tgz", + "integrity": "sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1" + } + }, "@jest/environment": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", @@ -6867,34 +6992,163 @@ "@sinonjs/commons": "^1.7.0" } }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true + "@swc-node/core": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@swc-node/core/-/core-1.9.0.tgz", + "integrity": "sha512-vRnvsMtL9OxybA/Wun1ZhlDvB6MNs4Zujnina0VKdGk+yI6s87KUhdTcbAY6dQMZhQTLFiC1Lnv/BuwCKcCEug==", + "dev": true, + "requires": { + "@swc/core": "^1.2.172" + } }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "@swc-node/register": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@swc-node/register/-/register-1.5.1.tgz", + "integrity": "sha512-6IL5s4QShKGs08qAeNou3rDA3gbp2WHk6fo0XnJXQn/aC9k6FnVBbj/thGOIEDtgNhC/DKpZT8tCY1LpQnOZFg==", + "dev": true, + "requires": { + "@swc-node/core": "^1.9.0", + "@swc-node/sourcemap-support": "^0.2.0", + "colorette": "^2.0.16", + "debug": "^4.3.4", + "pirates": "^4.0.5", + "tslib": "^2.4.0" + } }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "@swc-node/sourcemap-support": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@swc-node/sourcemap-support/-/sourcemap-support-0.2.0.tgz", + "integrity": "sha512-FNrxdI6XMYfoNt81L8eFKEm1d8P82I1nPwS3MrnBGzZoMWB+seQhQK+iN6M5RreJxXbfZw5lF86LRjHEQeGMqg==", + "dev": true, + "requires": { + "source-map-support": "^0.5.21" + } }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "@swc/core": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.2.205.tgz", + "integrity": "sha512-evq0/tFyYdYgOhKb//+G93fxe9zwFxtme7NL7wSiEF8+4/ON4Y5AI9eHLoqddXqs3W8Y0HQi+rJmlrkCibrseA==", + "dev": true, + "requires": { + "@swc/core-android-arm-eabi": "1.2.205", + "@swc/core-android-arm64": "1.2.205", + "@swc/core-darwin-arm64": "1.2.205", + "@swc/core-darwin-x64": "1.2.205", + "@swc/core-freebsd-x64": "1.2.205", + "@swc/core-linux-arm-gnueabihf": "1.2.205", + "@swc/core-linux-arm64-gnu": "1.2.205", + "@swc/core-linux-arm64-musl": "1.2.205", + "@swc/core-linux-x64-gnu": "1.2.205", + "@swc/core-linux-x64-musl": "1.2.205", + "@swc/core-win32-arm64-msvc": "1.2.205", + "@swc/core-win32-ia32-msvc": "1.2.205", + "@swc/core-win32-x64-msvc": "1.2.205" + } }, - "@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "@swc/core-android-arm-eabi": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-android-arm-eabi/-/core-android-arm-eabi-1.2.205.tgz", + "integrity": "sha512-HfiuVA1JDHMSRQ8nE1DcemUgZ1PKaPwit4i7q3xin0NVbVHY1xkJyQFuLVh3VxTvGKKkF3hi8GJMVQgOXWL6kg==", + "dev": true, + "optional": true + }, + "@swc/core-android-arm64": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-android-arm64/-/core-android-arm64-1.2.205.tgz", + "integrity": "sha512-sRGZBV2dOnmh8gWWFo9HVOHdKa33zIsF8/8oYEGtq+2/s96UlAKltO2AA7HH9RaO/fT1tzBZStp+fEMUhDk/FA==", + "dev": true, + "optional": true + }, + "@swc/core-darwin-arm64": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.2.205.tgz", + "integrity": "sha512-JwVDfKS7vp7zzOQXWNwwcF41h4r3DWEpK6DQjz18WJyS1VVOcpVQGyuE7kSPjcnG01ZxBL9JPwwT353i/8IwDg==", + "dev": true, + "optional": true + }, + "@swc/core-darwin-x64": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.2.205.tgz", + "integrity": "sha512-malz2I+w6xFF1QyTmPGt0Y0NEMbUcrvfr5gUfZDGjxMhPPlS7k6fXucuZxVr9VVaM+JGq1SidVODmZ84jb1qHg==", + "dev": true, + "optional": true + }, + "@swc/core-freebsd-x64": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-freebsd-x64/-/core-freebsd-x64-1.2.205.tgz", + "integrity": "sha512-/nZrG1z0T7h97AsOb/wOtYlnh4WEuNppv3XKQIMPj32YNQdMBVgpybVTVRIs1GQGZMd1/7jAy5BVQcwQjUbrLg==", + "dev": true, + "optional": true + }, + "@swc/core-linux-arm-gnueabihf": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.2.205.tgz", + "integrity": "sha512-mTA3vETMdBmpecUyI9waZYsp7FABhew4e81psspmFpDyfty0SLISWZDnvPAn0pSnb2fWhzKwDC5kdXHKUmLJuA==", + "dev": true, + "optional": true + }, + "@swc/core-linux-arm64-gnu": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.2.205.tgz", + "integrity": "sha512-qGzFGryeQE+O5SFK7Nn2ESqCEnv00rnzhf11WZF9V71EZ15amIhmbcwHqvFpoRSDw8hZnqoGqfPRfoJbouptnA==", + "dev": true, + "optional": true + }, + "@swc/core-linux-arm64-musl": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.2.205.tgz", + "integrity": "sha512-uLJoX9L/4Xg3sLMjAbIhzbTe5gD/MBA8VETBeEkLtgb7a0ys1kvn9xQ6qLw6A71amEPlI+VABnoTRdUEaBSV9Q==", + "dev": true, + "optional": true + }, + "@swc/core-linux-x64-gnu": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.2.205.tgz", + "integrity": "sha512-gQsjcYlkWKP1kceQIsoHGrOrG7ygW3ojNsSnYoZ5DG5PipRA4eeUfO9YIfrmoa29LiVNjmRPfUJa8O1UHDG5ew==", + "dev": true, + "optional": true + }, + "@swc/core-linux-x64-musl": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.2.205.tgz", + "integrity": "sha512-LR5ukqBltQc++2eX3qEj/H8KtOt0V3CmtgXNOiNCUxvPDT8mYz/8MJhYOrofonND0RKfXyyPW7dRxg62ceTLSQ==", + "dev": true, + "optional": true + }, + "@swc/core-win32-arm64-msvc": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.2.205.tgz", + "integrity": "sha512-NjcLWm4mOy78LAEt7pqFl+SLcCyqnSlUP729XRd1uRvKwt1Cwch5SQRdoaFqwf1DaEQy4H4iuGPynkfarlb1kQ==", + "dev": true, + "optional": true + }, + "@swc/core-win32-ia32-msvc": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.2.205.tgz", + "integrity": "sha512-+6byrRxIXgZ0zmLL6ZeX1HBBrAqvCy8MR5Yz0SO26jR8OPZXJCgZXL9BTsZO+YEG4f32ZOlZh3nnHCl6Dcb4GA==", + "dev": true, + "optional": true + }, + "@swc/core-win32-x64-msvc": { + "version": "1.2.205", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.2.205.tgz", + "integrity": "sha512-RRSkyAol0c7sU9gejtrpF8TLmdYdBjLutcmQHtLKbWTm74ZLidZpF28G0J2tD7HNmzQnMpLzyoT1jW9JgLwzVg==", + "dev": true, + "optional": true + }, + "@swc/jest": { + "version": "0.2.21", + "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.21.tgz", + "integrity": "sha512-/+NcExiZbxXANNhNPnIdFuGq62CeumulLS1bngwqIXd8H7d96LFUfrYzdt8tlTwLMel8tFtQ5aRjzVkyOTyPDw==", + "dev": true, + "requires": { + "@jest/create-cache-key-function": "^27.4.2" + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true }, "@types/babel__core": { @@ -7247,12 +7501,6 @@ "picomatch": "^2.0.4" } }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -7380,25 +7628,15 @@ "dev": true }, "browserslist": { - "version": "4.20.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.4.tgz", - "integrity": "sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.0.tgz", + "integrity": "sha512-UQxE0DIhRB5z/zDz9iA03BOfxaN2+GQdBYH/2WrSIWEUrnpzTPJbhqt+umq6r3acaPRTW1FNTkrcp0PXgtFkvA==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001349", - "electron-to-chromium": "^1.4.147", - "escalade": "^3.1.1", + "caniuse-lite": "^1.0.30001358", + "electron-to-chromium": "^1.4.164", "node-releases": "^2.0.5", - "picocolors": "^1.0.0" - } - }, - "bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "requires": { - "fast-json-stable-stringify": "2.x" + "update-browserslist-db": "^1.0.0" } }, "bser": { @@ -7429,9 +7667,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001358", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001358.tgz", - "integrity": "sha512-hvp8PSRymk85R20bsDra7ZTCpSVGN/PAz9pSAjPSjKC+rNmnUk5vCRgJwiTT/O4feQ/yu/drvZYpKxxhbFuChw==", + "version": "1.0.30001359", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001359.tgz", + "integrity": "sha512-Xln/BAsPzEuiVLgJ2/45IaqD9jShtk3Y33anKb4+yLwQzws3+v6odKfpgES/cDEaZMLzSChpIGdbOYtH9MyuHw==", "dev": true }, "chalk": { @@ -7602,12 +7840,6 @@ "minimist": "1.2.6" } }, - "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", @@ -7703,12 +7935,6 @@ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, "diff-sequences": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", @@ -7757,9 +7983,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.163", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.163.tgz", - "integrity": "sha512-c9q94pUVqIdc8hyr7jZDB4bNEoNF3QJ7y35lnddMD+mXtiv5GsL1bT/RmfW/KEOmvlNg5Oy1qioiy4tA7e864Q==", + "version": "1.4.169", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.169.tgz", + "integrity": "sha512-Yb7UFva1sLlAaRyCkgoFF3qWvwZacFDtsGKi44rZsk8vnhL0DMhsUdhI4Dz9CCJQfftncDMGSI3AYiDtg8mD/w==", "dev": true }, "emittery": { @@ -8650,6 +8876,12 @@ "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true } } }, @@ -9297,12 +9529,6 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true - }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -9400,12 +9626,6 @@ } } }, - "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 - }, "makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -10184,51 +10404,6 @@ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" }, - "ts-jest": { - "version": "27.1.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.5.tgz", - "integrity": "sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==", - "dev": true, - "requires": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - } - }, - "ts-node": { - "version": "10.8.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.8.1.tgz", - "integrity": "sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.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", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "dependencies": { - "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 - } - } - }, "tslib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", @@ -10293,6 +10468,16 @@ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, + "update-browserslist-db": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.4.tgz", + "integrity": "sha512-jnmO2BEGUjsMOe/Fg9u0oczOe/ppIDZPebzccl1yDWGLFP16Pa1/RM5wEoKYPG2zstNcDuAStejyxsOuKINdGA==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -10308,12 +10493,6 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, "v8-to-istanbul": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", @@ -10526,25 +10705,13 @@ "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } - }, - "yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==" } } }, "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==" } } } diff --git a/package.json b/package.json index 6a312365..759ed056 100644 --- a/package.json +++ b/package.json @@ -21,8 +21,8 @@ "build": "tsc --build", "postbuild": "chmod +x dist/bin/concurrently.js", "clean": "tsc --build --clean", - "format": "prettier --ignore-path .gitignore --check .", - "format:fix": "prettier --ignore-path .gitignore --write .", + "format": "prettier --ignore-path .gitignore --check '**/{!(package-lock).json,*.y?(a)ml,*.md}'", + "format:fix": "npm run format -- --write", "lint": "eslint . --ext js,ts --ignore-path .gitignore", "lint:fix": "npm run lint -- --fix", "prepublishOnly": "npm run build", @@ -55,6 +55,9 @@ "yargs": "^17.3.1" }, "devDependencies": { + "@swc-node/register": "^1.5.1", + "@swc/core": "^1.2.204", + "@swc/jest": "^0.2.21", "@types/jest": "^27.0.3", "@types/lodash": "^4.14.178", "@types/node": "^17.0.0", @@ -72,8 +75,6 @@ "lint-staged": "^12.4.1", "prettier": "^2.6.2", "simple-git-hooks": "^2.7.0", - "ts-jest": "^27.1.4", - "ts-node": "^10.4.0", "typescript": "^4.5.4" }, "files": [ @@ -84,29 +85,11 @@ "!**/*.spec.js", "!**/*.spec.d.ts" ], - "jest": { - "preset": "ts-jest", - "collectCoverage": true, - "collectCoverageFrom": [ - "src/**/*.ts", - "!src/index.ts" - ], - "coveragePathIgnorePatterns": [ - "/fixtures/", - "/node_modules/" - ], - "testEnvironment": "node", - "testPathIgnorePatterns": [ - "/node_modules/", - "/dist" - ] - }, "simple-git-hooks": { "pre-commit": "npx lint-staged" }, "lint-staged": { "*.{js,ts}": "eslint --fix", - "!(package-lock).json": "prettier --write", - "*.{y?(a)ml,md}": "prettier --write" + "{!(package-lock).json,*.y?(a)ml,*.md}": "prettier --write" } } diff --git a/src/command-parser/expand-arguments.ts b/src/command-parser/expand-arguments.ts index 9726e7e3..99b1bd39 100644 --- a/src/command-parser/expand-arguments.ts +++ b/src/command-parser/expand-arguments.ts @@ -14,7 +14,7 @@ export class ExpandArguments implements CommandParser { (match, placeholderTarget) => { // Don't replace the placeholder if it is escaped by a backslash. if (match.startsWith('\\')) { - return match.substring(1); + return match.slice(1); } // Replace numeric placeholder if value exists in additional arguments. if ( @@ -37,8 +37,6 @@ export class ExpandArguments implements CommandParser { } ); - return Object.assign({}, commandInfo, { - command, - }); + return { ...commandInfo, command }; } } diff --git a/src/command-parser/expand-npm-shortcut.ts b/src/command-parser/expand-npm-shortcut.ts index bbee7936..623b8296 100644 --- a/src/command-parser/expand-npm-shortcut.ts +++ b/src/command-parser/expand-npm-shortcut.ts @@ -12,9 +12,10 @@ export class ExpandNpmShortcut implements CommandParser { return commandInfo; } - return Object.assign({}, commandInfo, { + return { + ...commandInfo, name: commandInfo.name || cmdName, command: `${npmCmd} run ${cmdName}${args}`, - }); + }; } } diff --git a/src/command-parser/expand-npm-wildcard.ts b/src/command-parser/expand-npm-wildcard.ts index b4a729db..73e744f9 100644 --- a/src/command-parser/expand-npm-wildcard.ts +++ b/src/command-parser/expand-npm-wildcard.ts @@ -1,5 +1,5 @@ -import * as fs from 'fs'; -import * as _ from 'lodash'; +import fs from 'fs'; +import _ from 'lodash'; import { CommandInfo } from '../command'; import { CommandParser } from './command-parser'; @@ -40,8 +40,8 @@ export class ExpandNpmWildcard implements CommandParser { const omissionRegex = cmdName.match(OMISSION); const cmdNameSansOmission = cmdName.replace(OMISSION, ''); - const preWildcard = _.escapeRegExp(cmdNameSansOmission.substr(0, wildcardPosition)); - const postWildcard = _.escapeRegExp(cmdNameSansOmission.substr(wildcardPosition + 1)); + const preWildcard = _.escapeRegExp(cmdNameSansOmission.slice(0, wildcardPosition)); + const postWildcard = _.escapeRegExp(cmdNameSansOmission.slice(wildcardPosition + 1)); const wildcardRegex = new RegExp(`^${preWildcard}(.*?)${postWildcard}$`); const currentName = commandInfo.name || ''; @@ -58,12 +58,13 @@ export class ExpandNpmWildcard implements CommandParser { } if (match) { - return Object.assign({}, commandInfo, { + return { + ...commandInfo, command: `${npmCmd} run ${script}${args}`, // Will use an empty command name if command has no name and the wildcard match is empty, // e.g. if `npm:watch-*` matches `npm run watch-`. name: currentName + match[1], - }); + }; } }) .filter((commandInfo): commandInfo is CommandInfo => !!commandInfo); diff --git a/src/command-parser/strip-quotes.ts b/src/command-parser/strip-quotes.ts index 1a13c911..b3ce74b7 100644 --- a/src/command-parser/strip-quotes.ts +++ b/src/command-parser/strip-quotes.ts @@ -10,9 +10,9 @@ export class StripQuotes implements CommandParser { // Removes the quotes surrounding a command. if (/^"(.+?)"$/.test(command) || /^'(.+?)'$/.test(command)) { - command = command.substring(1, command.length - 1); + command = command.slice(1, command.length - 1); } - return Object.assign({}, commandInfo, { command }); + return { ...commandInfo, command }; } } diff --git a/src/concurrently.spec.ts b/src/concurrently.spec.ts index edc5fd0f..6eba78a4 100644 --- a/src/concurrently.spec.ts +++ b/src/concurrently.spec.ts @@ -2,6 +2,10 @@ import { ChildProcess, KillProcess, SpawnCommand } from './command'; import { concurrently, ConcurrentlyCommandInput, ConcurrentlyOptions } from './concurrently'; import { createFakeProcess, FakeCommand } from './fixtures/fake-command'; import { FlowController } from './flow-control/flow-controller'; +import { Logger } from './logger'; +import { OutputWriter } from './output-writer'; + +jest.mock('./output-writer'); let spawn: SpawnCommand; let kill: KillProcess; @@ -44,6 +48,12 @@ it('spawns all commands', () => { expect(spawn).toHaveBeenCalledWith('kill', expect.objectContaining({})); }); +it('output writer is created if logger is passed in options', () => { + const logger = new Logger({ hide: [] }); + create(['foo'], { logger }); + expect(OutputWriter).toHaveBeenCalledTimes(1); +}); + it('spawns commands up to configured limit at once', () => { create(['foo', 'bar', 'baz', 'qux'], { maxProcesses: 2 }); expect(spawn).toHaveBeenCalledTimes(2); diff --git a/src/concurrently.ts b/src/concurrently.ts index 99a27873..8cff159e 100644 --- a/src/concurrently.ts +++ b/src/concurrently.ts @@ -148,13 +148,11 @@ export function concurrently( // Use documented behaviour of repeating last color when specifying more commands than colors lastColor = (options.prefixColors && options.prefixColors[index]) || lastColor; return new Command( - Object.assign( - { - index, - prefixColor: lastColor, - }, - command - ), + { + index, + prefixColor: lastColor, + ...command, + }, getSpawnOpts({ raw: options.raw, env: command.env, @@ -215,19 +213,17 @@ function mapToCommandInfo(command: ConcurrentlyCommandInput): CommandInfo { }; } - return Object.assign( - { - command: command.command, - name: command.name || '', - env: command.env || {}, - cwd: command.cwd || '', - }, - command.prefixColor + return { + command: command.command, + name: command.name || '', + env: command.env || {}, + cwd: command.cwd || '', + ...(command.prefixColor ? { prefixColor: command.prefixColor, } - : {} - ); + : {}), + }; } function parseCommand(command: CommandInfo, parsers: CommandParser[]) { diff --git a/src/flow-control/input-handler.spec.ts b/src/flow-control/input-handler.spec.ts index 44190aa0..cb3e0835 100644 --- a/src/flow-control/input-handler.spec.ts +++ b/src/flow-control/input-handler.spec.ts @@ -28,6 +28,17 @@ it('returns same commands', () => { expect(controller.handle(commands)).toMatchObject({ commands }); }); +it('does nothing if called without input stream', () => { + new InputHandler({ + defaultInputTarget: 0, + inputStream: undefined, + logger, + }).handle(commands); + inputStream.write('something'); + + expect(commands[0].stdin.write).not.toHaveBeenCalled(); +}); + it('forwards input stream to default target ID', () => { controller.handle(commands); diff --git a/src/flow-control/kill-on-signal.ts b/src/flow-control/kill-on-signal.ts index e94d16db..8e3c0d3b 100644 --- a/src/flow-control/kill-on-signal.ts +++ b/src/flow-control/kill-on-signal.ts @@ -28,7 +28,7 @@ export class KillOnSignal implements FlowController { const closeStream = command.close.pipe( map(exitInfo => { const exitCode = caughtSignal === 'SIGINT' ? 0 : exitInfo.exitCode; - return Object.assign({}, exitInfo, { exitCode }); + return { ...exitInfo, exitCode }; }) ); return new Proxy(command, { diff --git a/src/flow-control/kill-others.spec.ts b/src/flow-control/kill-others.spec.ts index 8d2619df..d928e3af 100644 --- a/src/flow-control/kill-others.spec.ts +++ b/src/flow-control/kill-others.spec.ts @@ -7,7 +7,6 @@ let commands: FakeCommand[]; let logger: Logger; beforeEach(() => { commands = [new FakeCommand(), new FakeCommand()]; - logger = createMockInstance(Logger); }); @@ -43,6 +42,16 @@ it('kills other killable processes on success', () => { expect(commands[1].kill).toHaveBeenCalled(); }); +it('does nothing if called without conditions', () => { + createWithConditions([]).handle(commands); + commands[1].isKillable = true; + commands[0].close.next(createFakeCloseEvent({ exitCode: 0 })); + + expect(logger.logGlobalEvent).not.toHaveBeenCalled(); + expect(commands[0].kill).not.toHaveBeenCalled(); + expect(commands[1].kill).not.toHaveBeenCalled(); +}); + it('kills other killable processes on failure', () => { createWithConditions(['failure']).handle(commands); commands[1].isKillable = true; diff --git a/src/flow-control/log-error.spec.ts b/src/flow-control/log-error.spec.ts index 86a2a417..4ae9891a 100644 --- a/src/flow-control/log-error.spec.ts +++ b/src/flow-control/log-error.spec.ts @@ -7,7 +7,7 @@ let controller: LogError; let logger: Logger; let commands: FakeCommand[]; beforeEach(() => { - commands = [new FakeCommand(), new FakeCommand()]; + commands = [new FakeCommand(), new FakeCommand(), new FakeCommand()]; logger = createMockInstance(Logger); controller = new LogError({ logger }); @@ -21,10 +21,15 @@ it('logs the error event of each command', () => { controller.handle(commands); commands[0].error.next('error from command 0'); - const error = new Error('some error message'); - commands[1].error.next(error); + const error1 = new Error('some error message'); + commands[1].error.next(error1); - expect(logger.logCommandEvent).toHaveBeenCalledTimes(4); + // Testing Error without stack + const error2 = new Error(); + error2.stack = ''; + commands[2].error.next(error2); + + expect(logger.logCommandEvent).toHaveBeenCalledTimes(6); expect(logger.logCommandEvent).toHaveBeenCalledWith( `Error occurred when executing command: ${commands[0].command}`, commands[0] @@ -35,5 +40,11 @@ it('logs the error event of each command', () => { `Error occurred when executing command: ${commands[1].command}`, commands[1] ); - expect(logger.logCommandEvent).toHaveBeenCalledWith(error.stack, commands[1]); + expect(logger.logCommandEvent).toHaveBeenCalledWith(error1.stack, commands[1]); + + expect(logger.logCommandEvent).toHaveBeenCalledWith( + `Error occurred when executing command: ${commands[2].command}`, + commands[2] + ); + expect(logger.logCommandEvent).toHaveBeenCalledWith(String(error2), commands[2]); }); diff --git a/src/get-spawn-opts.spec.ts b/src/get-spawn-opts.spec.ts index 596cc2a0..935ddd85 100644 --- a/src/get-spawn-opts.spec.ts +++ b/src/get-spawn-opts.spec.ts @@ -18,7 +18,7 @@ it('merges FORCE_COLOR into env vars if color supported', () => { const process = { ...baseProcess, env: { foo: 'bar' } }; expect(getSpawnOpts({ process, colorSupport: false }).env).toEqual(process.env); expect(getSpawnOpts({ process, colorSupport: { level: 1 } }).env).toEqual({ - FORCE_COLOR: 1, + FORCE_COLOR: '1', foo: 'bar', }); }); diff --git a/src/get-spawn-opts.ts b/src/get-spawn-opts.ts index 1586e170..a65d6faa 100644 --- a/src/get-spawn-opts.ts +++ b/src/get-spawn-opts.ts @@ -37,18 +37,13 @@ export const getSpawnOpts = ({ * Map of custom environment variables to include in the spawn options. */ env?: Record; -}): SpawnOptions => - Object.assign( - { - cwd: cwd || process.cwd(), - }, - raw && { stdio: 'inherit' as const }, - /^win/.test(process.platform) && { detached: false }, - { - env: Object.assign( - colorSupport ? { FORCE_COLOR: colorSupport.level } : {}, - process.env, - env - ), - } - ); +}): SpawnOptions => ({ + cwd: cwd || process.cwd(), + ...(raw && { stdio: 'inherit' as const }), + ...(/^win/.test(process.platform) && { detached: false }), + env: { + ...(colorSupport ? { FORCE_COLOR: colorSupport.level.toString() } : {}), + ...process.env, + ...env, + }, +}); diff --git a/src/logger.spec.ts b/src/logger.spec.ts index db14b3bb..62cd6727 100644 --- a/src/logger.spec.ts +++ b/src/logger.spec.ts @@ -315,6 +315,20 @@ describe('#logTable()', () => { ); }); + it("logs each items's values with empty column", () => { + const logger = createLogger({}); + logger.logTable([{ foo: 123 }, { foo: null }]); + + expect(logger.log).toHaveBeenCalledWith( + chalk.reset('-->') + ' ', + chalk.reset('│ 123 │') + '\n' + ); + expect(logger.log).toHaveBeenCalledWith( + chalk.reset('-->') + ' ', + chalk.reset('│ │') + '\n' + ); + }); + it("logs each items's values padded according to longest column's value", () => { const logger = createLogger({}); logger.logTable([{ foo: 1 }, { foo: 123 }]); diff --git a/src/logger.ts b/src/logger.ts index 956527d7..e8c4780a 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -82,8 +82,8 @@ export class Logger { const endLength = Math.floor(prefixLength / 2); const beginningLength = prefixLength - endLength; - const beginnning = text.substring(0, beginningLength); - const end = text.substring(text.length - endLength, text.length); + const beginnning = text.slice(0, beginningLength); + const end = text.slice(text.length - endLength, text.length); return beginnning + ellipsis + end; } diff --git a/src/output-writer.spec.ts b/src/output-writer.spec.ts index cb95df59..a63300fa 100644 --- a/src/output-writer.spec.ts +++ b/src/output-writer.spec.ts @@ -4,14 +4,12 @@ import { OutputWriter } from './output-writer'; import { createFakeCloseEvent, FakeCommand } from './fixtures/fake-command'; function createWriter(overrides?: { group: boolean }) { - const options = Object.assign( - { - outputStream, - group: false, - commands, - }, - overrides - ); + const options = { + outputStream, + group: false, + commands, + ...overrides, + }; return new OutputWriter(options); } diff --git a/tsconfig.json b/tsconfig.json index 5bf29aff..79241db7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,6 @@ "outDir": "./dist", "declaration": true, "target": "ES2019", - "lib": ["ES2019"], "module": "CommonJS", "moduleResolution": "node", "noImplicitAny": true,