diff --git a/.eslintrc b/.eslintrc index 24e8d90..2bf4cff 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,11 +1,20 @@ { + "parserOptions": { + "project": "./tsconfig.json" + }, "extends": [ - "airbnb-base" + "airbnb-typescript/base", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking" ], "plugins": [ - "promise" + "promise", + "import" ], "rules": { - "no-param-reassign": 0 + "no-param-reassign": "off", + "lines-between-class-members": "off", + "@typescript-eslint/lines-between-class-members": "off", + "@typescript-eslint/require-await": "off" } } diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 08b513b..3ad28d8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -24,8 +24,8 @@ jobs: - run: npm ci - run: npm run lint - run: npm run test - - run: npm run coverage - name: Coveralls + if: matrix.node-version == '16.x' uses: coverallsapp/github-action@master with: github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 2b27c46..f6ab3ca 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ node_modules coverage */config/local.js .nyc_output +build diff --git a/README.md b/README.md index 513f56e..3592b15 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,13 @@ A small rule engine for Node. ![main workflow](https://github.com/frankthelen/rools/actions/workflows/main.yml/badge.svg) [![Coverage Status](https://coveralls.io/repos/github/frankthelen/rools/badge.svg?branch=master)](https://coveralls.io/github/frankthelen/rools?branch=master) -[![dependencies Status](https://david-dm.org/frankthelen/rools/status.svg)](https://david-dm.org/frankthelen/rools) +![Dependency Status](https://img.shields.io/librariesio/release/npm/rools) [![Maintainability](https://api.codeclimate.com/v1/badges/d1f858c321b03000fc63/maintainability)](https://codeclimate.com/github/frankthelen/rools/maintainability) [![node](https://img.shields.io/node/v/rools.svg)](https://nodejs.org) [![code style](https://img.shields.io/badge/code_style-airbnb-brightgreen.svg)](https://github.com/airbnb/javascript) -[![Types](https://img.shields.io/npm/types/rools.svg)](https://www.npmjs.com/package/rools) -[![License Status](http://img.shields.io/npm/l/rools.svg)]() +![Types](https://img.shields.io/npm/types/rools) +![Module](https://img.shields.io/badge/module-hybrid%20cjs%2Fesm-blue) +![License Status](https://img.shields.io/npm/l/rools) *Primary goal* was to provide a nice and state-of-the-art interface for modern JavaScript (ES6). *Facts* are plain JavaScript or JSON objects or objects from ES6 classes with getters and setters. @@ -19,7 +20,11 @@ A small rule engine for Node. Mission accomplished! JavaScript rocks! -See [migration info](#migration) for breaking changes between major versions 1.x.x and 2.x.x. +* TypeScript -- types included +* CommonsJS (cjs) -- supporting Node 12+ +* ES Modules (esm) -- supporting Node 14+ + +See [migration info](#migration) for breaking changes from previous major versions. ## Install @@ -500,6 +505,25 @@ For this module to work, your **TypeScript compiler options** must include ## Migration +### Version 2.x.x to Version 3.x.x + +Dropped Node 10 support. + +Everything was converted from ES6 to TypeScript. +All tests were converted from Mocha/Chai/Sinon to Jest. +Both, mostly just for the fun of it. + +The goal was to provide Rools as a *hybrid package* +utilizing multiple TypeScript targets and conditional exports: + +* TypeScript -- types included (as before) +* CommonsJS (cjs) -- supporting Node 12+ (as before -- but dropping Node 10) +* ES Modules (esm) -- supporting Node 14+ (new) + +Everything should work as before -- *no breaking changes*. +But since nearly everything was touched, as a precaution, +I have created a new major version. + ### Version 1.x.x to Version 2.x.x There are a few breaking changes that require changes to your code. diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 0000000..db17c8f --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,22 @@ +export default { + clearMocks: true, + collectCoverage: true, + coverageDirectory: 'coverage', + coveragePathIgnorePatterns: [ + '/node_modules/', + '/config/', + '/test/', + ], + coverageProvider: 'v8', + coverageThreshold: { + global: { + statements: 80, + branches: 80, + functions: 80, + lines: 80, + }, + }, + preset: 'ts-jest', + testEnvironment: 'node', + testRegex: '/test/.*\\.test\\.ts$', +}; diff --git a/package-lock.json b/package-lock.json index c684123..d54df44 100644 --- a/package-lock.json +++ b/package-lock.json @@ -128,6 +128,12 @@ "@babel/types": "^7.12.10" } }, + "@babel/helper-plugin-utils": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "dev": true + }, "@babel/helper-replace-supers": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", @@ -205,6 +211,123 @@ "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", "dev": true }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", + "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, "@babel/template": { "version": "7.12.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", @@ -252,6 +375,12 @@ "to-fast-properties": "^2.0.0" } }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, "@cspotcode/source-map-consumer": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", @@ -388,39 +517,271 @@ "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", "dev": true }, - "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "@jest/console": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.3.1.tgz", + "integrity": "sha512-RkFNWmv0iui+qsOr/29q9dyfKTTT5DCuP31kUwg7rmOKPT/ozLeGLKJKVIiOfbiKyleUZKIrHwhmiZWVe8IMdw==", "dev": true, "requires": { - "type-detect": "4.0.8" + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.3.1", + "jest-util": "^27.3.1", + "slash": "^3.0.0" } }, - "@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==", + "@jest/core": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.3.1.tgz", + "integrity": "sha512-DMNE90RR5QKx0EA+wqe3/TNEwiRpOkhshKNxtLxd4rt3IZpCt+RSL+FoJsGeblRZmqdK4upHA/mKKGPPRAifhg==", "dev": true, "requires": { - "@sinonjs/commons": "^1.7.0" + "@jest/console": "^27.3.1", + "@jest/reporters": "^27.3.1", + "@jest/test-result": "^27.3.1", + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^27.3.0", + "jest-config": "^27.3.1", + "jest-haste-map": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.3.1", + "jest-resolve-dependencies": "^27.3.1", + "jest-runner": "^27.3.1", + "jest-runtime": "^27.3.1", + "jest-snapshot": "^27.3.1", + "jest-util": "^27.3.1", + "jest-validate": "^27.3.1", + "jest-watcher": "^27.3.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" } }, - "@sinonjs/samsam": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.0.2.tgz", - "integrity": "sha512-jxPRPp9n93ci7b8hMfJOFDPRLFYadN6FSpeROFTR4UNF4i5b+EK6m4QXPO46BDhFgRy1JuS87zAnFOzCUwMJcQ==", + "@jest/environment": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.3.1.tgz", + "integrity": "sha512-BCKCj4mOVLme6Tanoyc9k0ultp3pnmuyHw73UHRPeeZxirsU/7E3HC4le/VDb/SMzE1JcPnto+XBKFOcoiJzVw==", + "dev": true, + "requires": { + "@jest/fake-timers": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.3.0" + } + }, + "@jest/fake-timers": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.3.1.tgz", + "integrity": "sha512-M3ZFgwwlqJtWZ+QkBG5NmC23A9w+A6ZxNsO5nJxJsKYt4yguBd3i8TpjQz5NfCX91nEve1KqD9RA2Q+Q1uWqoA==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.3.1", + "jest-mock": "^27.3.0", + "jest-util": "^27.3.1" + }, + "dependencies": { + "@sinonjs/fake-timers": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.0.1.tgz", + "integrity": "sha512-AU7kwFxreVd6OAXcAFlKSmZquiRUU0FvYm44k1Y1QbK7Co4m0aqfGMhjykIeQp/H6rcl+nFmj0zfdUcGVs9Dew==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + } + } + }, + "@jest/globals": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.3.1.tgz", + "integrity": "sha512-Q651FWiWQAIFiN+zS51xqhdZ8g9b88nGCobC87argAxA7nMfNQq0Q0i9zTfQYgLa6qFXk2cGANEqfK051CZ8Pg==", + "dev": true, + "requires": { + "@jest/environment": "^27.3.1", + "@jest/types": "^27.2.5", + "expect": "^27.3.1" + } + }, + "@jest/reporters": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.3.1.tgz", + "integrity": "sha512-m2YxPmL9Qn1emFVgZGEiMwDntDxRRQ2D58tiDQlwYTg5GvbFOKseYCcHtn0WsI8CG4vzPglo3nqbOiT8ySBT/w==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.3.1", + "@jest/test-result": "^27.3.1", + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^27.3.1", + "jest-resolve": "^27.3.1", + "jest-util": "^27.3.1", + "jest-worker": "^27.3.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.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==", + "dev": true + } + } + }, + "@jest/source-map": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", + "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "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==", + "dev": true + } + } + }, + "@jest/test-result": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.3.1.tgz", + "integrity": "sha512-mLn6Thm+w2yl0opM8J/QnPTqrfS4FoXsXF2WIWJb2O/GBSyResL71BRuMYbYRsGt7ELwS5JGcEcGb52BNrumgg==", + "dev": true, + "requires": { + "@jest/console": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.3.1.tgz", + "integrity": "sha512-siySLo07IMEdSjA4fqEnxfIX8lB/lWYsBPwNFtkOvsFQvmBrL3yj3k3uFNZv/JDyApTakRpxbKLJ3CT8UGVCrA==", + "dev": true, + "requires": { + "@jest/test-result": "^27.3.1", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.3.1", + "jest-runtime": "^27.3.1" + } + }, + "@jest/transform": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.3.1.tgz", + "integrity": "sha512-3fSvQ02kuvjOI1C1ssqMVBKJpZf6nwoCiSu00zAKh5nrp3SptNtZy/8s5deayHnqxhjD9CWDJ+yqQwuQ0ZafXQ==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.2.5", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.3.1", + "jest-regex-util": "^27.0.6", + "jest-util": "^27.3.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.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==", + "dev": true + } + } + }, + "@jest/types": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", + "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + } + }, + "@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": { - "@sinonjs/commons": "^1.6.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" + "@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/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==", + "@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 }, "@tsconfig/node10": { @@ -447,141 +808,426 @@ "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", "dev": true }, - "@types/chai": { - "version": "4.2.22", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz", - "integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==", - "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/mocha": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz", - "integrity": "sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==", - "dev": true - }, - "@types/node": { - "version": "16.11.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz", - "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==", - "dev": true - }, - "@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 - }, - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "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 + "@types/babel__core": { + "version": "7.1.16", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", + "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } }, - "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 + "@types/babel__generator": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", + "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "@types/babel__traverse": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", "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" + "@babel/types": "^7.3.0" } }, - "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 + "@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "dev": true, + "requires": { + "@types/node": "*" + } }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", "dev": true }, - "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==", + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "@types/istanbul-lib-coverage": "*" } }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "@types/istanbul-lib-report": "*" } }, - "append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "@types/jest": { + "version": "27.0.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.2.tgz", + "integrity": "sha512-4dRxkS/AFX0c5XW6IPMNOydLn2tEhNhJV7DnYK+0bjoJZ+QTmfucBlihX7aoEsh/ocYtkLC73UbnBXBXIxsULA==", "dev": true, "requires": { - "default-require-extensions": "^3.0.0" + "jest-diff": "^27.0.0", + "pretty-format": "^27.0.0" } }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "@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 }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "@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 }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "@types/lodash": { + "version": "4.14.176", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.176.tgz", + "integrity": "sha512-xZmuPTa3rlZoIbtDUyJKZQimJV3bxCmzMIO2c9Pz9afyDro6kr7R79GwcB6mRhuoPmV2p1Vb66WOJH7F886WKQ==", + "dev": true + }, + "@types/md5": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@types/md5/-/md5-2.3.1.tgz", + "integrity": "sha512-OK3oe+ALIoPSo262lnhAYwpqFNXbiwH2a+0+Z5YBnkQEwWD8fk5+PIeRhYA48PzvX9I4SGNpWy+9bLj8qz92RQ==", "dev": true, "requires": { - "sprintf-js": "~1.0.2" + "@types/node": "*" } }, - "array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "@types/node": { + "version": "16.11.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.4.tgz", + "integrity": "sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ==", + "dev": true + }, + "@types/prettier": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.1.0.tgz", + "integrity": "sha512-bekODL3Tqf36Yz8u+ilha4zGxL9mdB6LIsIoMAvvC5FAuWo4NpZYXtCbv7B2CeR1LhI/lLtLk+q4tbtxuoVuCg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "5.1.0", + "@typescript-eslint/scope-manager": "5.1.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": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.1.0.tgz", + "integrity": "sha512-ovE9qUiZMOMgxQAESZsdBT+EXIfx/YUYAbwGUI6V03amFdOOxI9c6kitkgRvLkJaLusgMZ2xBhss+tQ0Y1HWxA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.1.0", + "@typescript-eslint/types": "5.1.0", + "@typescript-eslint/typescript-estree": "5.1.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "dependencies": { + "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" + } + }, + "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.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.1.0.tgz", + "integrity": "sha512-vx1P+mhCtYw3+bRHmbalq/VKP2Y3gnzNgxGxfEWc6OFpuEL7iQdAeq11Ke3Rhy8NjgB+AHsIWEwni3e+Y7djKA==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.1.0", + "@typescript-eslint/types": "5.1.0", + "@typescript-eslint/typescript-estree": "5.1.0", + "debug": "^4.3.2" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + } + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.1.0.tgz", + "integrity": "sha512-yYlyVjvn5lvwCL37i4hPsa1s0ORsjkauhTqbb8MnpvUs7xykmcjGqwlNZ2Q5QpoqkJ1odlM2bqHqJwa28qV6Tw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.1.0", + "@typescript-eslint/visitor-keys": "5.1.0" + } + }, + "@typescript-eslint/types": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.1.0.tgz", + "integrity": "sha512-sEwNINVxcB4ZgC6Fe6rUyMlvsB2jvVdgxjZEjQUQVlaSPMNamDOwO6/TB98kFt4sYYfNhdhTPBEQqNQZjMMswA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.1.0.tgz", + "integrity": "sha512-SSz+l9YrIIsW4s0ZqaEfnjl156XQ4VRmJsbA0ZE1XkXrD3cRpzuZSVCyqeCMR3EBjF27IisWakbBDGhGNIOvfQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.1.0", + "@typescript-eslint/visitor-keys": "5.1.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.1.0.tgz", + "integrity": "sha512-uqNXepKBg81JVwjuqAxYrXa1Ql/YDzM+8g/pS+TCPxba0wZttl8m5DkrasbfnmJGHs4lQ2jTbcZ5azGhI7kK+w==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.1.0", + "eslint-visitor-keys": "^3.0.0" + } + }, + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "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 + } + } + }, + "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 + }, + "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 + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "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.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "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-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", @@ -692,6 +1338,12 @@ } } }, + "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", @@ -824,12 +1476,6 @@ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, - "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 - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -848,6 +1494,104 @@ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, + "babel-jest": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.3.1.tgz", + "integrity": "sha512-SjIF8hh/ir0peae2D6S6ZKRhUy7q/DnpH7k/V6fT4Bgs/LXXUztOpX4G2tCgq8mLo5HA9mN6NmlFMeYtKmIsTQ==", + "dev": true, + "requires": { + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^27.2.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "dependencies": { + "@babel/parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.0.4.tgz", + "integrity": "sha512-W6jJF9rLGEISGoCyXRqa/JCGQGmmxPO10TMu7izaUTynxvBvTjqzAIIGCK9USBmIbQAaSWD6XJPrM9Pv5INknw==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.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 + } + } + }, + "babel-plugin-jest-hoist": { + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", + "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", + "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^27.2.0", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -863,12 +1607,6 @@ "tweetnacl": "^0.14.3" } }, - "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 - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -888,24 +1626,36 @@ "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==", + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", "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==", + "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": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" + "fast-json-stable-stringify": "2.x" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.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==", + "dev": true + }, "call-bind": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", @@ -934,29 +1684,6 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, - "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-as-promised": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", - "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", - "dev": true, - "requires": { - "check-error": "^1.0.2" - } - }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1008,48 +1735,27 @@ } } }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, "charenc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", "dev": true }, - "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "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" - } - } - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, "cliui": { @@ -1063,6 +1769,18 @@ "wrap-ansi": "^7.0.0" } }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1087,12 +1805,6 @@ "delayed-stream": "~1.0.0" } }, - "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", @@ -1163,6 +1875,29 @@ "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } + } + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -1172,6 +1907,17 @@ "assert-plus": "^1.0.0" } }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -1187,14 +1933,17 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "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" - } + "decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "dev": true + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true }, "deep-is": { "version": "0.1.4", @@ -1202,22 +1951,11 @@ "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" - }, - "dependencies": { - "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 - } - } + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true }, "define-properties": { "version": "1.1.3", @@ -1234,12 +1972,33 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "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==", + "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.0.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", + "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", + "dev": true + }, + "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" + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -1249,6 +2008,23 @@ "esutils": "^2.0.2" } }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "requires": { + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true + } + } + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -1259,6 +2035,12 @@ "safer-buffer": "^2.1.0" } }, + "emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "dev": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -1305,12 +2087,6 @@ "is-symbol": "^1.0.2" } }, - "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 - }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -1323,10 +2099,71 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "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, + "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + } + } + }, "eslint": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.0.1.tgz", - "integrity": "sha512-LsgcwZgQ72vZ+SMp4K6pAnk2yFDWL7Ti4pJaRvsZ0Hsw2h8ZjUIW38a9AFn2cZXdBMlScMFYYgsSp4ttFI/0bA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.1.0.tgz", + "integrity": "sha512-JZvNneArGSUsluHWJ8g8MMs3CfIEzwaLx9KyH4tZ2i+R2/rPWzL8c0zg3rHdwYVpN/1sB9gqnjHwz9HoeJpGHw==", "dev": true, "requires": { "@eslint/eslintrc": "^1.0.3", @@ -1412,6 +2249,15 @@ "object.entries": "^1.1.2" } }, + "eslint-config-airbnb-typescript": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-14.0.1.tgz", + "integrity": "sha512-tF4GwC3sRrw8kEj4/yxX8F7AcLzj/1IESBnsCiFMplzYmxre459qm2z9DFkCpqBVQFSH6j2K4+VKVteX4m0GsQ==", + "dev": true, + "requires": { + "eslint-config-airbnb-base": "14.2.1" + } + }, "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", @@ -1503,9 +2349,9 @@ } }, "eslint-plugin-promise": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.0.tgz", - "integrity": "sha512-NGmI6BH5L12pl7ScQHbg7tvtk4wPxxj8yPHH47NvSmMtFneC077PSeY3huFj06ZWZvtbfxSPt3RuOQD5XcR4ng==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.1.tgz", + "integrity": "sha512-XgdcdyNzHfmlQyweOPTxmc7pIsS6dE4MvwhXWMQ2Dxs1XAL2GJDilUsjWen6TWik0aSI+zD/PqocZBblcm9rdA==", "dev": true }, "eslint-plugin-should-promised": { @@ -1594,6 +2440,51 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expect": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.3.1.tgz", + "integrity": "sha512-MrNXV2sL9iDRebWPGOGFdPQRl2eDQNu/uhxIMShjjx74T6kC6jFIkmQ6OqXDtevjGUkyB2IT56RzDBqXf/QPCg==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "ansi-styles": "^5.0.0", + "jest-get-type": "^27.3.1", + "jest-matcher-utils": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-regex-util": "^27.0.6" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -1612,6 +2503,30 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "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", @@ -1624,6 +2539,24 @@ "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" + } + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -1642,77 +2575,6 @@ "to-regex-range": "^5.0.1" } }, - "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.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 - }, - "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" - } - } - } - }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", @@ -1722,12 +2584,6 @@ "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", @@ -1744,16 +2600,6 @@ "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", "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" - } - }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -1771,12 +2617,6 @@ "mime-types": "^2.1.12" } }, - "fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1814,12 +2654,6 @@ "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.0.2", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz", @@ -1837,6 +2671,12 @@ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, "get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -1909,12 +2749,26 @@ "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" }, "dependencies": { - "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==", + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true } } @@ -1925,12 +2779,6 @@ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "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 - }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -1991,28 +2839,32 @@ } } }, - "hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", "dev": true, "requires": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" + "whatwg-encoding": "^1.0.5" } }, - "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 - }, "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-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -2024,6 +2876,31 @@ "sshpk": "^1.7.0" } }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "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": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -2040,18 +2917,82 @@ "resolve-from": "^4.0.0" } }, + "import-local": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", + "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.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 + }, + "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" + } + } + } + }, "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==", - "dev": true - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2101,15 +3042,6 @@ "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", @@ -2144,9 +3076,9 @@ "dev": true }, "is-core-module": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz", - "integrity": "sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", "dev": true, "requires": { "has": "^1.0.3" @@ -2170,6 +3102,12 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -2200,10 +3138,10 @@ "has-tostringtag": "^1.0.0" } }, - "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==", + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, "is-regex": { @@ -2251,12 +3189,6 @@ "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.1", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", @@ -2266,18 +3198,6 @@ "call-bind": "^1.0.0" } }, - "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", @@ -2296,15 +3216,6 @@ "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", "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", @@ -2325,21 +3236,6 @@ } } }, - "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" - } - }, "istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", @@ -2397,585 +3293,893 @@ "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==", + "jest": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.3.1.tgz", + "integrity": "sha512-U2AX0AgQGd5EzMsiZpYt8HyZ+nSVIh5ujQ9CPp9EQZJMjXIiSZpJNweZl0swatKRoqHWgGKM3zaSwm4Zaz87ng==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "@jest/core": "^27.3.1", + "import-local": "^3.0.2", + "jest-cli": "^27.3.1" + }, + "dependencies": { + "jest-cli": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.3.1.tgz", + "integrity": "sha512-WHnCqpfK+6EvT62me6WVs8NhtbjAS4/6vZJnk7/2+oOr50cwAzG4Wxt6RXX0hu6m1169ZGMlhYYUNeKBXCph/Q==", + "dev": true, + "requires": { + "@jest/core": "^27.3.1", + "@jest/test-result": "^27.3.1", + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "jest-config": "^27.3.1", + "jest-util": "^27.3.1", + "jest-validate": "^27.3.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + } + } } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "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 - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "jest-changed-files": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.3.0.tgz", + "integrity": "sha512-9DJs9garMHv4RhylUMZgbdCJ3+jHSkpL9aaVKp13xtXAD80qLTLrqcDZL1PHA9dYA0bCI86Nv2BhkLpLhrBcPg==", "dev": true, "requires": { - "minimist": "^1.2.0" + "@jest/types": "^27.2.5", + "execa": "^5.0.0", + "throat": "^6.0.1" } }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "jest-circus": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.3.1.tgz", + "integrity": "sha512-v1dsM9II6gvXokgqq6Yh2jHCpfg7ZqV4jWY66u7npz24JnhP3NHxI0sKT7+ZMQ7IrOWHYAaeEllOySbDbWsiXw==", "dev": true, "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" + "@jest/environment": "^27.3.1", + "@jest/test-result": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.3.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.3.1", + "jest-matcher-utils": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-runtime": "^27.3.1", + "jest-snapshot": "^27.3.1", + "jest-util": "^27.3.1", + "pretty-format": "^27.3.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + } + }, + "jest-config": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.3.1.tgz", + "integrity": "sha512-KY8xOIbIACZ/vdYCKSopL44I0xboxC751IX+DXL2+Wx6DKNycyEfV3rryC3BPm5Uq/BBqDoMrKuqLEUNJmMKKg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^27.3.1", + "@jest/types": "^27.2.5", + "babel-jest": "^27.3.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-circus": "^27.3.1", + "jest-environment-jsdom": "^27.3.1", + "jest-environment-node": "^27.3.1", + "jest-get-type": "^27.3.1", + "jest-jasmine2": "^27.3.1", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.3.1", + "jest-runner": "^27.3.1", + "jest-util": "^27.3.1", + "jest-validate": "^27.3.1", + "micromatch": "^4.0.4", + "pretty-format": "^27.3.1" + } + }, + "jest-diff": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.1.tgz", + "integrity": "sha512-PCeuAH4AWUo2O5+ksW4pL9v5xJAcIKPUPfIhZBcG1RKv/0+dvaWTQK1Nrau8d67dp65fOqbeMdoil+6PedyEPQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^27.0.6", + "jest-get-type": "^27.3.1", + "pretty-format": "^27.3.1" } }, - "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 - }, - "lcov-parse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", - "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", - "dev": true - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "jest-docblock": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", + "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", "dev": true, "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "detect-newline": "^3.0.0" } }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "jest-each": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.3.1.tgz", + "integrity": "sha512-E4SwfzKJWYcvOYCjOxhZcxwL+AY0uFMvdCOwvzgutJiaiodFjkxQQDxHm8FQBeTqDnSmKsQWn7ldMRzTn2zJaQ==", "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", + "jest-get-type": "^27.3.1", + "jest-util": "^27.3.1", + "pretty-format": "^27.3.1" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "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 + "jest-environment-jsdom": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.3.1.tgz", + "integrity": "sha512-3MOy8qMzIkQlfb3W1TfrD7uZHj+xx8Olix5vMENkj5djPmRqndMaXtpnaZkxmxM+Qc3lo+yVzJjzuXbCcZjAlg==", + "dev": true, + "requires": { + "@jest/environment": "^27.3.1", + "@jest/fake-timers": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.3.0", + "jest-util": "^27.3.1", + "jsdom": "^16.6.0" + } }, - "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 + "jest-environment-node": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.3.1.tgz", + "integrity": "sha512-T89F/FgkE8waqrTSA7/ydMkcc52uYPgZZ6q8OaZgyiZkJb5QNNCF6oPZjH9IfPFfcc9uBWh1574N0kY0pSvTXw==", + "dev": true, + "requires": { + "@jest/environment": "^27.3.1", + "@jest/fake-timers": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.3.0", + "jest-util": "^27.3.1" + } }, - "log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "jest-get-type": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.3.1.tgz", + "integrity": "sha512-+Ilqi8hgHSAdhlQ3s12CAVNd8H96ZkQBfYoXmArzZnOfAtVAJEiPDBirjByEblvG/4LPJmkL+nBqPO3A1YJAEg==", "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==", + "jest-haste-map": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.3.1.tgz", + "integrity": "sha512-lYfNZIzwPccDJZIyk9Iz5iQMM/MH56NIIcGj7AFU1YyA4ewWFBl8z+YPJuSCRML/ee2cCt2y3W4K3VXPT6Nhzg==", "dev": true, "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" + "@jest/types": "^27.2.5", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^27.0.6", + "jest-serializer": "^27.0.6", + "jest-util": "^27.3.1", + "jest-worker": "^27.3.1", + "micromatch": "^4.0.4", + "walker": "^1.0.7" } }, - "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==", + "jest-jasmine2": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.3.1.tgz", + "integrity": "sha512-WK11ZUetDQaC09w4/j7o4FZDUIp+4iYWH/Lik34Pv7ukL+DuXFGdnmmi7dT58J2ZYKFB5r13GyE0z3NPeyJmsg==", "dev": true, "requires": { - "yallist": "^4.0.0" + "@babel/traverse": "^7.1.0", + "@jest/environment": "^27.3.1", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.3.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.3.1", + "jest-matcher-utils": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-runtime": "^27.3.1", + "jest-snapshot": "^27.3.1", + "jest-util": "^27.3.1", + "pretty-format": "^27.3.1", + "throat": "^6.0.1" } }, - "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==", + "jest-leak-detector": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.3.1.tgz", + "integrity": "sha512-78QstU9tXbaHzwlRlKmTpjP9k4Pvre5l0r8Spo4SbFFVy/4Abg9I6ZjHwjg2QyKEAMg020XcjP+UgLZIY50yEg==", "dev": true, "requires": { - "semver": "^6.0.0" + "jest-get-type": "^27.3.1", + "pretty-format": "^27.3.1" + } + }, + "jest-matcher-utils": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.3.1.tgz", + "integrity": "sha512-hX8N7zXS4k+8bC1Aj0OWpGb7D3gIXxYvPNK1inP5xvE4ztbz3rc4AkI6jGVaerepBnfWB17FL5lWFJT3s7qo8w==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^27.3.1", + "jest-get-type": "^27.3.1", + "pretty-format": "^27.3.1" + } + }, + "jest-message-util": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.3.1.tgz", + "integrity": "sha512-bh3JEmxsTZ/9rTm0jQrPElbY2+y48Rw2t47uMfByNyUVR+OfPh4anuyKsGqsNkXk/TI4JbLRZx+7p7Hdt6q1yg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.2.5", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.4", + "pretty-format": "^27.3.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "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" + } + } + } } } }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "jest-mock": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.3.0.tgz", + "integrity": "sha512-ziZiLk0elZOQjD08bLkegBzv5hCABu/c8Ytx45nJKkysQwGaonvmTxwjLqEA4qGdasq9o2I8/HtdGMNnVsMTGw==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "@types/node": "*" + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", "dev": true }, - "md5": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "jest-regex-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", + "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", + "dev": true + }, + "jest-resolve": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.3.1.tgz", + "integrity": "sha512-Dfzt25CFSPo3Y3GCbxynRBZzxq9AdyNN+x/v2IqYx6KVT5Z6me2Z/PsSGFSv3cOSUZqJ9pHxilao/I/m9FouLw==", + "dev": true, "requires": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.3.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.3.1", + "jest-validate": "^27.3.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" } }, - "mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", - "dev": true + "jest-resolve-dependencies": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.3.1.tgz", + "integrity": "sha512-X7iLzY8pCiYOnvYo2YrK3P9oSE8/3N2f4pUZMJ8IUcZnT81vlSonya1KTO9ZfKGuC+svE6FHK/XOb8SsoRUV1A==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "jest-regex-util": "^27.0.6", + "jest-snapshot": "^27.3.1" + } }, - "mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", + "jest-runner": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.3.1.tgz", + "integrity": "sha512-r4W6kBn6sPr3TBwQNmqE94mPlYVn7fLBseeJfo4E2uCTmAyDFm2O5DYAQAFP7Q3YfiA/bMwg8TVsciP7k0xOww==", "dev": true, "requires": { - "mime-db": "1.50.0" + "@jest/console": "^27.3.1", + "@jest/environment": "^27.3.1", + "@jest/test-result": "^27.3.1", + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-docblock": "^27.0.6", + "jest-environment-jsdom": "^27.3.1", + "jest-environment-node": "^27.3.1", + "jest-haste-map": "^27.3.1", + "jest-leak-detector": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-resolve": "^27.3.1", + "jest-runtime": "^27.3.1", + "jest-util": "^27.3.1", + "jest-worker": "^27.3.1", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + } + }, + "jest-runtime": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.3.1.tgz", + "integrity": "sha512-qtO6VxPbS8umqhEDpjA4pqTkKQ1Hy4ZSi9mDVeE9Za7LKBo2LdW2jmT+Iod3XFaJqINikZQsn2wEi0j9wPRbLg==", + "dev": true, + "requires": { + "@jest/console": "^27.3.1", + "@jest/environment": "^27.3.1", + "@jest/globals": "^27.3.1", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.3.1", + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-mock": "^27.3.0", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.3.1", + "jest-snapshot": "^27.3.1", + "jest-util": "^27.3.1", + "jest-validate": "^27.3.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^16.2.0" + }, + "dependencies": { + "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 + } } }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "jest-serializer": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", + "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "@types/node": "*", + "graceful-fs": "^4.2.4" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "jest-snapshot": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.3.1.tgz", + "integrity": "sha512-APZyBvSgQgOT0XumwfFu7X3G5elj6TGhCBLbBdn3R1IzYustPGPE38F51dBWMQ8hRXa9je0vAdeVDtqHLvB6lg==", + "dev": true, + "requires": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/parser": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.3.1", + "graceful-fs": "^4.2.4", + "jest-diff": "^27.3.1", + "jest-get-type": "^27.3.1", + "jest-haste-map": "^27.3.1", + "jest-matcher-utils": "^27.3.1", + "jest-message-util": "^27.3.1", + "jest-resolve": "^27.3.1", + "jest-util": "^27.3.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.3.1", + "semver": "^7.3.2" + } }, - "mocha": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", - "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.2", - "debug": "4.3.2", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.7", - "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.1.25", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.1.5", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" + "jest-util": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.3.1.tgz", + "integrity": "sha512-8fg+ifEH3GDryLQf/eKZck1DEs2YuVPBCMOaHQxVVLmQwl/CDhWzrvChTX4efLZxGrw+AA0mSXv78cyytBt/uw==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.4", + "picomatch": "^2.2.3" + } + }, + "jest-validate": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.3.1.tgz", + "integrity": "sha512-3H0XCHDFLA9uDII67Bwi1Vy7AqwA5HqEEjyy934lgVhtJ3eisw6ShOF1MDmRPspyikef5MyExvIm0/TuLzZ86Q==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.3.1", + "leven": "^3.1.0", + "pretty-format": "^27.3.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 - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "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 - } - } - }, - "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==", + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "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" - } - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "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" - } - }, + } + } + }, + "jest-watcher": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.3.1.tgz", + "integrity": "sha512-9/xbV6chABsGHWh9yPaAGYVVKurWoP3ZMCv6h+O1v9/+pkOroigs6WzZ0e9gLP/njokUwM7yQhr01LKJVMkaZA==", + "dev": true, + "requires": { + "@jest/test-result": "^27.3.1", + "@jest/types": "^27.2.5", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.3.1", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.1.tgz", + "integrity": "sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "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" - } - }, - "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==", + "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": { - "yocto-queue": "^0.1.0" + "has-flag": "^4.0.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==", + } + } + }, + "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" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "dev": true, + "requires": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "dev": true, "requires": { - "p-limit": "^3.0.2" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" } }, - "path-exists": { + "tough-cookie": { "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==", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" } } } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, - "nanoid": { - "version": "3.1.25", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", - "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "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=", + "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 }, - "nise": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.0.tgz", - "integrity": "sha512-W5WlHu+wvo3PaKLsJJkgPup2LrsXCcm7AWwyNZkUnn5rwPkuPBi3Iwk5SQtN0mv+K65k7nKKjwNQ30wg3wLAQQ==", + "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 + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "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": { - "@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" + "minimist": "^1.2.0" } }, - "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==", + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "dev": true, "requires": { - "process-on-spawn": "^1.0.0" + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" } }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "lcov-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", + "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", "dev": true }, - "nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "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": { - "@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" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "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==" + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "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-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "dev": true + }, + "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": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "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" - } - }, - "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==", - "dev": true, - "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==", - "dev": true - }, - "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" - } - }, - "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" - } + "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 + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, + "md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "requires": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "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 + }, + "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-db": { + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", + "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", + "dev": true + }, + "mime-types": { + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", + "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", + "dev": true, + "requires": { + "mime-db": "1.50.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "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 + }, + "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 + }, + "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-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "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 + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -3139,6 +4343,15 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -3171,33 +4384,12 @@ "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" - } - }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -3207,6 +4399,12 @@ "callsites": "^3.0.0" } }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -3231,19 +4429,10 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "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" - } - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "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 }, "performance-now": { @@ -3258,6 +4447,15 @@ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, "pkg-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", @@ -3273,13 +4471,30 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, - "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==", + "pretty-format": { + "version": "27.3.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz", + "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==", "dev": true, "requires": { - "fromentries": "^1.2.0" + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } } }, "progress": { @@ -3288,6 +4503,16 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -3306,23 +4531,17 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "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" - } + "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 }, - "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" - } + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true }, "regexpp": { "version": "3.2.0", @@ -3330,13 +4549,154 @@ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "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=", + "replace": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/replace/-/replace-1.2.1.tgz", + "integrity": "sha512-KZCBe/tPanwBlbjSMQby4l+zjSiFi3CLEP/6VLClnRYgJ46DZ5u9tmA6ceWeFS8coaUnU4ZdGNb/puUGMHNSRg==", "dev": true, "requires": { - "es6-error": "^4.0.1" + "chalk": "2.4.2", + "minimatch": "3.0.4", + "yargs": "^15.3.1" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "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 + }, + "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" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + } + } + }, + "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" + } + } } }, "request": { @@ -3389,12 +4749,41 @@ "path-parse": "^1.0.6" } }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "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==", + "dev": true + } + } + }, "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.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "dev": true + }, + "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", @@ -3404,6 +4793,15 @@ "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", @@ -3416,6 +4814,15 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -3425,15 +4832,6 @@ "lru-cache": "^6.0.0" } }, - "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" - } - }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -3472,41 +4870,16 @@ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, - "sinon": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-11.1.2.tgz", - "integrity": "sha512-59237HChms4kg7/sXhiRcUzdSkKuydDeTiamT/jesUVHshBgL8XAmhgFo0GfK6RruMDM/iRSij1EybmMog9cJw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": "^7.1.2", - "@sinonjs/samsam": "^6.0.2", - "diff": "^5.0.0", - "nise": "^5.1.0", - "supports-color": "^7.2.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "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==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "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==", + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "source-map": { @@ -3515,18 +4888,22 @@ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, - "spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "source-map-support": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", "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" + "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==", + "dev": true + } } }, "sprintf-js": { @@ -3552,6 +4929,33 @@ "tweetnacl": "~0.14.0" } }, + "stack-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } + }, + "string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", @@ -3598,6 +5002,12 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -3613,6 +5023,49 @@ "has-flag": "^3.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" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "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==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -3630,6 +5083,18 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "dev": true + }, + "tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -3655,10 +5120,46 @@ "punycode": "^2.1.1" } }, + "tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, + "ts-jest": { + "version": "27.0.7", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.0.7.tgz", + "integrity": "sha512-O41shibMqzdafpuP+CkrOL7ykbmLh+FqQrXEmV9CydQ5JBk0Sj0uAEF5TNNe94fZWKm3yYvWa/IbyV4Yg1zK2Q==", + "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" + }, + "dependencies": { + "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" + } + } + } + }, "ts-node": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.3.0.tgz", - "integrity": "sha512-RYIy3i8IgpFH45AX4fQHExrT8BxDeKTdC83QFJkNzkvt8uFB6QJ8XMyhynYiKMLxt9a7yuXaDBZNOYS3XjDcYw==", + "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", @@ -3673,14 +5174,6 @@ "diff": "^4.0.1", "make-error": "^1.1.1", "yn": "3.1.1" - }, - "dependencies": { - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - } } }, "tsconfig-paths": { @@ -3695,6 +5188,21 @@ "strip-bom": "^3.0.0" } }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "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" + } + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -3726,9 +5234,9 @@ "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==", + "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 }, "typedarray-to-buffer": { @@ -3771,6 +5279,12 @@ "resolved": "https://registry.npmjs.org/uniqueid/-/uniqueid-1.0.0.tgz", "integrity": "sha1-5O0Xg5XHaMi4CmZnO4HP4RZTwx0=" }, + "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 + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -3792,6 +5306,25 @@ "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "v8-to-istanbul": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", + "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -3803,6 +5336,65 @@ "extsprintf": "^1.2.0" } }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dev": true, + "requires": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3837,12 +5429,6 @@ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, - "workerpool": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", - "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", - "dev": true - }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -3898,10 +5484,28 @@ "typedarray-to-buffer": "^3.1.5" } }, + "ws": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", + "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", + "dev": true + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, "yallist": { @@ -3939,43 +5543,11 @@ "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.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "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 - } - } - }, "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 5414cd8..8e14a33 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,21 @@ "name": "rools", "version": "2.3.0", "description": "A small rule engine for Node.", - "main": "src/index.js", + "main": "build/cjs/index.js", + "module": "build/esm/index.js", "types": "src/index.d.ts", + "type": "module", + "exports": { + ".": { + "import": "./build/esm/index.js", + "require": "./build/cjs/index.js", + "types": "./src/index.d.ts" + } + }, + "files": [ + "build", + "src/index.d.ts" + ], "author": "Frank Thelen", "license": "MIT", "repository": { @@ -19,33 +32,38 @@ "rules engine" ], "scripts": { + "build:clear": "rm -rf ./build && mkdir -p build", + "build:tsc": "npm run build:tsc:cjs && npm run build:tsc:esm", + "build:tsc:cjs": "tsc --project tsconfig.build.cjs.json", + "build:tsc:esm": "tsc --project tsconfig.build.esm.json", + "build": "npm run build:clear && npm run build:tsc && ./postbuild.sh", "lint": "eslint . --ignore-path ./.eslintignore", - "test": "npm run test:unit && npm run test:typescript", - "test:unit": "nyc --reporter=lcov --reporter=text-summary mocha --exit --recursive test/**/*.spec.js", - "test:typescript": "mocha -r ts-node/register test/typescript/**/*.spec.ts", - "coverage": "nyc report --reporter=lcovonly", - "preversion": "npm run lint && npm test" + "test": "npm run test:unit", + "test:unit": "jest --runInBand", + "preversion": "npm run lint && npm test", + "prepublishOnly": "npm run lint && npm test && npm run build" }, "engines": { - "node": ">=10.x.x" + "node": ">=12.x.x" }, "devDependencies": { - "@types/chai": "^4.2.22", - "@types/mocha": "^9.0.0", - "@types/node": "^16.11.1", - "chai": "^4.3.4", - "chai-as-promised": "^7.1.1", + "@types/jest": "^27.0.2", + "@types/lodash": "^4.14.176", + "@types/md5": "^2.3.1", + "@types/node": "^16.11.4", + "@typescript-eslint/eslint-plugin": "^5.1.0", + "@typescript-eslint/parser": "^5.1.0", "coveralls": "^3.1.1", - "eslint": "^8.0.1", + "eslint": "^8.1.0", "eslint-config-airbnb-base": "^14.2.1", + "eslint-config-airbnb-typescript": "^14.0.1", "eslint-plugin-import": "^2.25.2", - "eslint-plugin-promise": "^5.1.0", + "eslint-plugin-promise": "^5.1.1", "eslint-plugin-should-promised": "^2.0.0", - "mocha": "^9.1.3", - "nyc": "^15.1.0", - "sinon": "^11.1.2", - "sinon-chai": "^3.7.0", - "ts-node": "^10.3.0", + "jest": "^27.3.1", + "replace": "^1.2.1", + "ts-jest": "^27.0.7", + "ts-node": "^10.4.0", "typescript": "^4.4.4" }, "dependencies": { diff --git a/postbuild.sh b/postbuild.sh new file mode 100755 index 0000000..4317238 --- /dev/null +++ b/postbuild.sh @@ -0,0 +1,23 @@ +# Add local package.json for the builds. +# Many thanks to +# https://www.sensedeep.com/blog/posts/2021/how-to-create-single-source-npm-module.html + +cat >build/cjs/package.json <build/esm/package.json <>> fire action! - return thenable && thenable.then ? thenable : undefined; - } -} - -module.exports = Action; diff --git a/src/Action.ts b/src/Action.ts new file mode 100644 index 0000000..3d6fce0 --- /dev/null +++ b/src/Action.ts @@ -0,0 +1,43 @@ +import Premise from './Premise'; + +import { Action as ActionFunc, Facts } from './index.d'; + +interface ActionOptions { + id: string; + name: string; + then: ActionFunc; + priority?: number; + final?: boolean; + activationGroup?: string; +} + +export default class Action { + id: string; + name: string; + then: ActionFunc; + priority: number; + final: boolean; + activationGroup?: string; + premises: Premise[]; + + constructor({ + id, name, then, priority = 0, final = false, activationGroup, + }: ActionOptions) { + this.id = id; + this.name = name; // for logging only + this.then = then; + this.priority = priority; + this.final = final; + this.activationGroup = activationGroup; + this.premises = []; + } + + add(premise: Premise): void { + this.premises.push(premise); + } + + async fire(facts: Facts): Promise { + const thenable = this.then(facts); // >>> fire action! + return thenable && thenable.then ? thenable : undefined; + } +} diff --git a/src/ConflictResolution.js b/src/ConflictResolution.ts similarity index 68% rename from src/ConflictResolution.js rename to src/ConflictResolution.ts index aa70c27..be95ff7 100644 --- a/src/ConflictResolution.js +++ b/src/ConflictResolution.ts @@ -1,7 +1,17 @@ -const intersection = require('lodash/intersection'); +import _ from 'lodash'; +import Action from './Action'; +import Logger from './Logger'; -class ConflictResolution { - constructor({ strategy = 'ps', logger }) { +interface ConflictResolutionOptions { + strategy?: 'ps' | 'sp'; + logger: Logger; +} + +export default class ConflictResolution { + strategy: Array<(actions: Action[]) => Action[]>; + logger: Logger; + + constructor({ strategy = 'ps', logger }: ConflictResolutionOptions) { if (strategy === 'ps') { this.strategy = [ this.resolveByPriority.bind(this), @@ -21,7 +31,7 @@ class ConflictResolution { this.logger.debug({ message: `conflict resolution strategy "${strategy}"` }); } - select(actions) { + select(actions: Action[]): Action | undefined { if (actions.length === 0) { return undefined; // none } @@ -38,7 +48,7 @@ class ConflictResolution { return resolved[0]; } - resolveByPriority(actions) { + resolveByPriority(actions: Action[]): Action[] { const prios = actions.map((action) => action.priority); const highestPrio = Math.max(...prios); const selected = actions.filter((action) => action.priority === highestPrio); @@ -48,10 +58,12 @@ class ConflictResolution { return selected; } - resolveBySpecificity(actions) { - const isMoreSpecific = (action, rhs) => action.premises.length > rhs.premises.length - && intersection(action.premises, rhs.premises).length === rhs.premises.length; - const isMostSpecific = (action, all) => all.reduce((acc, other) => acc + resolveBySpecificity(actions: Action[]): Action[] { + const isMoreSpecific = (action: Action, rhs: Action) => ( + action.premises.length > rhs.premises.length + && _.intersection(action.premises, rhs.premises).length === rhs.premises.length + ); + const isMostSpecific = (action: Action, all: Action[]) => all.reduce((acc, other) => acc && !isMoreSpecific(other, action), true); const selected = actions.filter((action) => isMostSpecific(action, actions)); this.logger.debug({ @@ -60,7 +72,7 @@ class ConflictResolution { return selected; } - resolveByOrderOfRegistration(actions) { + resolveByOrderOfRegistration(actions: Action[]): Action[] { const selected = [actions[0]]; this.logger.debug({ message: `conflict resolution by order of registration ${actions.length} -> 1`, @@ -68,5 +80,3 @@ class ConflictResolution { return selected; } } - -module.exports = ConflictResolution; diff --git a/src/Delegator.js b/src/Delegator.js deleted file mode 100644 index 3f90ae7..0000000 --- a/src/Delegator.js +++ /dev/null @@ -1,19 +0,0 @@ -class Delegator { - constructor() { - this.to = null; - } - - delegate(...args) { - return this.to ? this.to(...args) : undefined; - } - - set(to) { - this.to = to; - } - - unset() { - this.to = null; - } -} - -module.exports = Delegator; diff --git a/src/Delegator.ts b/src/Delegator.ts new file mode 100644 index 0000000..54771b5 --- /dev/null +++ b/src/Delegator.ts @@ -0,0 +1,21 @@ +type Func = (...args: T[]) => S; + +export default class Delegator { + to: Func | null; + + constructor() { + this.to = null; + } + + delegate(...args: T[]): S | undefined { + return this.to ? this.to(...args) : undefined; + } + + set(to: Func): void { + this.to = to; + } + + unset(): void { + this.to = null; + } +} diff --git a/src/Logger.js b/src/Logger.js deleted file mode 100644 index a17563f..0000000 --- a/src/Logger.js +++ /dev/null @@ -1,34 +0,0 @@ -class Logger { - constructor({ - error = true, debug = false, delegate = null, - } = { error: true, debug: false, delegate: null }) { - this.filter = { error, debug }; - this.delegate = delegate; - } - - debug(options) { - if (!this.filter.debug) return; - this.log({ ...options, level: 'debug' }); - } - - error(options) { - if (!this.filter.error) return; - this.log({ ...options, level: 'error' }); - } - - log(options) { - const out = this.delegate ? this.delegate : Logger.logDefault; - out(options); - } - - static logDefault({ message, rule, error }) { - const msg = rule ? `# ${message} - "${rule}"` : `# ${message}`; - if (error) { - console.error(msg, error); // eslint-disable-line no-console - } else { - console.log(msg); // eslint-disable-line no-console - } - } -} - -module.exports = Logger; diff --git a/src/Logger.ts b/src/Logger.ts new file mode 100644 index 0000000..5d90e5f --- /dev/null +++ b/src/Logger.ts @@ -0,0 +1,52 @@ +export interface LogItem { + message: string; + rule?: string; + error?: Error; +} + +export interface LogItemWithLevel extends LogItem { + level: 'debug' | 'error'; +} + +export interface LoggerOptions { + error?: boolean; + debug?: boolean; + delegate?: (item: LogItemWithLevel) => void; +} + +export default class Logger { + filter: { error: boolean, debug: boolean }; + delegate?: (item: LogItemWithLevel) => void; + + constructor({ + error = true, debug = false, delegate, + }: LoggerOptions = { error: true, debug: false }) { + this.filter = { error, debug }; + this.delegate = delegate; + } + + debug(item: LogItem): void { + if (!this.filter.debug) return; + this.log({ ...item, level: 'debug' }); + } + + error(item: LogItem): void { + if (!this.filter.error) return; + this.log({ ...item, level: 'error' }); + } + + log(item: LogItemWithLevel): void { + // eslint-disable-next-line @typescript-eslint/unbound-method + const out = this.delegate ? this.delegate : Logger.logDefault; + out(item); + } + + static logDefault({ message, rule, error }: LogItemWithLevel): void { + const msg = rule ? `# ${message} - "${rule}"` : `# ${message}`; + if (error) { + console.error(msg, error); // eslint-disable-line no-console + } else { + console.log(msg); // eslint-disable-line no-console + } + } +} diff --git a/src/Premise.js b/src/Premise.js deleted file mode 100644 index a20cc7c..0000000 --- a/src/Premise.js +++ /dev/null @@ -1,16 +0,0 @@ -class Premise { - constructor({ - id, name, when, - }) { - this.id = id; - this.name = name; // for logging only - this.when = when; - this.actions = []; - } - - add(action) { - this.actions.push(action); - } -} - -module.exports = Premise; diff --git a/src/Premise.ts b/src/Premise.ts new file mode 100644 index 0000000..01c7aa2 --- /dev/null +++ b/src/Premise.ts @@ -0,0 +1,29 @@ +import Action from './Action'; + +import { Premise as PremiseFunc } from './index.d'; + +interface PremiseOptions { + id: string; + name: string; + when: PremiseFunc; +} + +export default class Premise { + id: string; + name: string; + when: PremiseFunc; + actions: Action[]; + + constructor({ + id, name, when, + }: PremiseOptions) { + this.id = id; + this.name = name; // for logging only + this.when = when; + this.actions = []; + } + + add(action: Action): void { + this.actions.push(action); + } +} diff --git a/src/Rools.js b/src/Rools.ts similarity index 66% rename from src/Rools.js rename to src/Rools.ts index caf4ea8..625e095 100644 --- a/src/Rools.js +++ b/src/Rools.ts @@ -1,23 +1,35 @@ -const RuleSet = require('./RuleSet'); -const Logger = require('./Logger'); -const Delegator = require('./Delegator'); -const WorkingMemory = require('./WorkingMemory'); -const ConflictResolution = require('./ConflictResolution'); -const observe = require('./observe'); -const RuleError = require('./RuleError'); +import Rule from './Rule'; +import RuleSet from './RuleSet'; +import Logger from './Logger'; +import Delegator from './Delegator'; +import WorkingMemory from './WorkingMemory'; +import ConflictResolution from './ConflictResolution'; +import observe from './observe'; +import RuleError from './RuleError'; -class Rools { - constructor({ logging } = {}) { +import { + Facts, RoolsOptions, EvaluateOptions, EvaluateResult, SegmentType, +} from './index.d'; +import Action from './Action'; + +type DelegatorType = Delegator; + +export default class Rools { + rules: RuleSet; + maxPasses: number; + logger: Logger; + + constructor({ logging }: RoolsOptions = {}) { this.rules = new RuleSet(); this.maxPasses = 1000; // emergency stop this.logger = new Logger(logging); } - async register(rules) { + async register(rules: Rule[]): Promise { rules.forEach((rule) => this.rules.register(rule)); } - async evaluate(facts, { strategy } = {}) { + async evaluate(facts: Facts, { strategy }: EvaluateOptions = {}): Promise { const startDate = new Date(); // init const memory = new WorkingMemory({ @@ -25,14 +37,14 @@ class Rools { premises: this.rules.premises, }); const conflictResolution = new ConflictResolution({ strategy, logger: this.logger }); - const delegator = new Delegator(); - const proxy = observe(facts, (segment) => delegator.delegate(segment)); + const delegator: DelegatorType = new Delegator(); + const proxy = observe(facts as object, (segment: SegmentType) => delegator.delegate(segment)); // match-resolve-act cycle - let pass = 0; /* eslint-disable no-await-in-loop */ - for (; pass < this.maxPasses; pass += 1) { + let pass = 0; + for (; pass < this.maxPasses; pass += 1) { // eslint-disable-next-line no-await-in-loop const next = await this.pass(proxy, delegator, memory, conflictResolution, pass); if (!next) break; // for - } /* eslint-enable no-await-in-loop */ + } // return info const endDate = new Date(); return { @@ -44,7 +56,10 @@ class Rools { }; } - async pass(facts, delegator, memory, conflictResolution, pass) { + async pass( + facts: Facts, delegator: DelegatorType, memory: WorkingMemory, + conflictResolution: ConflictResolution, pass: number, + ): Promise { this.logger.debug({ message: `evaluate pass ${pass}` }); // create agenda for premises const premisesAgenda = pass === 0 ? memory.premises : memory.getDirtyPremises(); @@ -52,35 +67,35 @@ class Rools { // evaluate premises premisesAgenda.forEach((premise) => { try { - delegator.set((segment) => { // listen to reading fact segments + delegator.set((segment: SegmentType) => { // listen to reading fact segments const segmentName = (typeof segment === 'symbol') ? segment.toString() : segment; this.logger.debug({ message: `access fact segment "${segmentName}" in premise`, rule: premise.name }); memory.segmentInPremise(segment, premise); }); - memory.getState(premise).value = premise.when(facts); // >>> evaluate premise! + memory.getPremiseState(premise).value = premise.when(facts); // >>> evaluate premise! } catch (error) { // ignore error! - memory.getState(premise).value = undefined; - this.logger.error({ message: 'error in premise (when)', rule: premise.name, error }); + memory.getPremiseState(premise).value = undefined; + this.logger.error({ message: 'error in premise (when)', rule: premise.name, error: error as Error }); } finally { delegator.unset(); } }); // create agenda for actions const actionsAgenda = pass === 0 ? memory.actions : premisesAgenda - .reduce((acc, premise) => [...new Set([...acc, ...premise.actions])], []) + .reduce((acc, premise) => [...new Set([...acc, ...premise.actions])], [] as Action[]) .filter((action) => { - const { fired, discarded } = memory.getState(action); + const { fired, discarded } = memory.getActionState(action); return !fired && !discarded; }); this.logger.debug({ message: `actions agenda length ${actionsAgenda.length}` }); // evaluate actions actionsAgenda.forEach((action) => { - memory.getState(action).ready = action.premises.reduce((acc, premise) => acc - && memory.getState(premise).value, true); + memory.getActionState(action).ready = action.premises + .reduce((acc, premise) => acc && !!memory.getPremiseState(premise).value, true); }); // create conflict set const conflictSet = memory.actions.filter((action) => { // all actions not only actionsAgenda! - const { fired, ready, discarded } = memory.getState(action); + const { fired, ready, discarded } = memory.getActionState(action); return ready && !fired && !discarded; }); this.logger.debug({ message: `conflict set length ${conflictSet.length}` }); @@ -92,7 +107,7 @@ class Rools { } // fire action this.logger.debug({ message: 'fire action', rule: action.name }); - memory.getState(action).fired = true; // mark fired first + memory.getActionState(action).fired = true; // mark fired first try { memory.clearDirtySegments(); delegator.set((segment) => { // listen to writing fact segments @@ -102,8 +117,8 @@ class Rools { }); await action.fire(facts); // >>> fire action! } catch (error) { // re-throw error! - this.logger.error({ message: 'error in action (then)', rule: action.name, error }); - throw new RuleError(`error in action (then): ${action.name}`, error); + this.logger.error({ message: 'error in action (then)', rule: action.name, error: error as Error }); + throw new RuleError(`error in action (then): ${action.name}`, error as Error); } finally { delegator.unset(); } @@ -119,7 +134,7 @@ class Rools { rule: action.name, }); this.rules.actionsByActivationGroup[action.activationGroup].forEach((other) => { - const state = memory.getState(other); + const state = memory.getActionState(other); state.discarded = !state.fired; }); } @@ -127,5 +142,3 @@ class Rools { return true; } } - -module.exports = Rools; diff --git a/src/Rule.js b/src/Rule.ts similarity index 57% rename from src/Rule.js rename to src/Rule.ts index 01803dc..35ac9ac 100644 --- a/src/Rule.js +++ b/src/Rule.ts @@ -1,14 +1,31 @@ -const isBoolean = require('lodash/isBoolean'); -const isFunction = require('lodash/isFunction'); -const isInteger = require('lodash/isInteger'); -const isString = require('lodash/isString'); -const assert = require('assert'); -const arrify = require('arrify'); +import _ from 'lodash'; +import assert from 'assert'; +import arrify from 'arrify'; + +import { Premise as PremiseFunc, Action as ActionFunc } from './index.d'; + +interface RuleOptions { + name: string; + when: PremiseFunc | PremiseFunc[]; + then: ActionFunc; + priority?: number; + final?: boolean; + extend?: Rule | Rule[]; + activationGroup?: string; +} + +export default class Rule { + name: string; + when: PremiseFunc[]; + then: ActionFunc; + priority: number; + final: boolean; + extend: Rule[]; + activationGroup?: string; -class Rule { constructor({ name, when, then, priority = 0, final = false, extend, activationGroup, - }) { + }: RuleOptions) { this.name = name; this.when = arrify(when); this.then = then; @@ -25,7 +42,7 @@ class Rule { '"name" is required', ); assert( - isString(this.name), + _.isString(this.name), '"name" must be a string', ); assert( @@ -33,7 +50,7 @@ class Rule { '"when" is required with at least one premise', ); assert( - this.when.reduce((acc, premise) => acc && isFunction(premise), true), + this.when.reduce((acc, premise) => acc && _.isFunction(premise), true), '"when" must be a function or an array of functions', ); assert( @@ -41,15 +58,15 @@ class Rule { '"then" is required', ); assert( - isFunction(this.then), + _.isFunction(this.then), '"then" must be a function', ); assert( - isInteger(this.priority), + _.isInteger(this.priority), '"priority" must be an integer', ); assert( - isBoolean(this.final), + _.isBoolean(this.final), '"final" must be a boolean', ); assert( @@ -57,10 +74,8 @@ class Rule { '"extend" must be a Rule or an array of Rules', ); assert( - !this.activationGroup || isString(this.activationGroup), + !this.activationGroup || _.isString(this.activationGroup), '"activationGroup" must be a string', ); } } - -module.exports = Rule; diff --git a/src/RuleError.js b/src/RuleError.js deleted file mode 100644 index 1d409ec..0000000 --- a/src/RuleError.js +++ /dev/null @@ -1,8 +0,0 @@ -class RuleError extends Error { - constructor(message, error) { - super(message); - this.cause = error; - } -} - -module.exports = RuleError; diff --git a/src/RuleError.ts b/src/RuleError.ts new file mode 100644 index 0000000..cb017f9 --- /dev/null +++ b/src/RuleError.ts @@ -0,0 +1,8 @@ +export default class RuleError extends Error { + cause: Error; + + constructor(message: string, error: Error) { + super(message); + this.cause = error; + } +} diff --git a/src/RuleSet.js b/src/RuleSet.ts similarity index 71% rename from src/RuleSet.js rename to src/RuleSet.ts index e557a56..082eeff 100644 --- a/src/RuleSet.js +++ b/src/RuleSet.ts @@ -1,11 +1,20 @@ -const assert = require('assert'); -const md5 = require('md5'); -const uniqueid = require('uniqueid'); -const Action = require('./Action'); -const Premise = require('./Premise'); -const Rule = require('./Rule'); +import assert from 'assert'; +import md5 from 'md5'; +import uniqueid from 'uniqueid'; +import Action from './Action'; +import Premise from './Premise'; +import Rule from './Rule'; + +import { Premise as PremiseFunc } from './index.d'; + +export default class RuleSet { + actions: Action[]; + premises: Premise[]; + premisesByHash: Record; + nextActionId: () => string; + nextPremiseId: () => string; + actionsByActivationGroup: Record; -class RuleSet { constructor() { this.actions = []; this.premises = []; @@ -15,7 +24,7 @@ class RuleSet { this.actionsByActivationGroup = {}; // hash } - register(rule) { + register(rule: Rule): void { assert(rule instanceof Rule, 'rule must be an instance of "Rule"'); // action const action = new Action({ @@ -24,9 +33,9 @@ class RuleSet { }); this.actions.push(action); // extend - const walked = new Set(); // cycle check - const whens = new Set(); - const walker = (node) => { + const walked = new Set(); // cycle check + const whens = new Set(); + const walker = (node: Rule): void => { if (walked.has(node)) return; // cycle walked.add(node); node.when.forEach((w) => { whens.add(w); }); @@ -62,5 +71,3 @@ class RuleSet { } } } - -module.exports = RuleSet; diff --git a/src/WorkingMemory.js b/src/WorkingMemory.js deleted file mode 100644 index f7de3b2..0000000 --- a/src/WorkingMemory.js +++ /dev/null @@ -1,57 +0,0 @@ -const Action = require('./Action'); - -class WorkingMemory { - constructor({ actions, premises }) { - this.actions = actions; - this.premises = premises; - this.actionsById = {}; // hash - this.premisesById = {}; // hash - this.actions.forEach((action) => { - this.actionsById[action.id] = { ready: false, fired: false, discarded: false }; - }); - this.premises.forEach((premise) => { - this.premisesById[premise.id] = { value: undefined }; - }); - this.dirtySegments = new Set(); - this.premisesBySegment = {}; // hash - this.accessedByActions = new Set(); // total - this.accessedByPremises = new Set(); // total - } - - getState(object) { - const { id } = object; - return object instanceof Action ? this.actionsById[id] : this.premisesById[id]; - } - - clearDirtySegments() { - this.dirtySegments.clear(); - } - - getDirtyPremises() { - const premises = new Set(); - this.dirtySegments.forEach((segment) => { - const dirtyPremises = this.premisesBySegment[segment] || []; - dirtyPremises.forEach((premise) => { - premises.add(premise); - }); - }); - return [...premises]; - } - - segmentInAction(segment) { - this.dirtySegments.add(segment); - this.accessedByActions.add(segment); - } - - segmentInPremise(segment, premise) { - this.accessedByPremises.add(segment); - let premises = this.premisesBySegment[segment]; - if (!premises) { - premises = new Set(); - this.premisesBySegment[segment] = premises; - } - premises.add(premise); // might grow over time with "hidden" conditions - } -} - -module.exports = WorkingMemory; diff --git a/src/WorkingMemory.ts b/src/WorkingMemory.ts new file mode 100644 index 0000000..d098224 --- /dev/null +++ b/src/WorkingMemory.ts @@ -0,0 +1,87 @@ +import Action from './Action'; +import Premise from './Premise'; + +import { SegmentType } from './index.d'; + +interface ActionState { + ready: boolean; + fired: boolean; + discarded: boolean; +} + +interface PremiseState { + value: boolean | undefined; +} + +interface WorkingMemoryOptions { + actions: Action[]; + premises: Premise[]; +} + +export default class WorkingMemory { + actions: Action[]; + premises: Premise[]; + actionsById: Record; + premisesById: Record; + dirtySegments: Set; + premisesBySegment: Record>; + accessedByActions: Set; + accessedByPremises: Set; + + constructor({ actions, premises }: WorkingMemoryOptions) { + this.actions = actions; + this.premises = premises; + this.actionsById = {}; // hash + this.premisesById = {}; // hash + this.actions.forEach((action) => { + this.actionsById[action.id] = { ready: false, fired: false, discarded: false }; + }); + this.premises.forEach((premise) => { + this.premisesById[premise.id] = { value: undefined }; + }); + this.dirtySegments = new Set(); + this.premisesBySegment = {}; // hash + this.accessedByActions = new Set(); // total + this.accessedByPremises = new Set(); // total + } + + getActionState(action: Action): ActionState { + const { id } = action; + return this.actionsById[id]; + } + + getPremiseState(premise: Premise): PremiseState { + const { id } = premise; + return this.premisesById[id]; + } + + clearDirtySegments(): void { + this.dirtySegments.clear(); + } + + getDirtyPremises(): Premise[] { + const premises = new Set(); + this.dirtySegments.forEach((segment) => { + const dirtyPremises = this.premisesBySegment[segment] || []; + dirtyPremises.forEach((premise) => { + premises.add(premise); + }); + }); + return [...premises]; + } + + segmentInAction(segment: SegmentType): void { + this.dirtySegments.add(segment); + this.accessedByActions.add(segment); + } + + segmentInPremise(segment: SegmentType, premise: Premise): void { + this.accessedByPremises.add(segment); + let premises = this.premisesBySegment[segment]; + if (!premises) { + premises = new Set(); + this.premisesBySegment[segment] = premises; + } + premises.add(premise); // might grow over time with "hidden" conditions + } +} diff --git a/src/index.d.ts b/src/index.d.ts index de0622f..4fc129f 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -1,32 +1,34 @@ export class Rools { constructor(opts?: RoolsOptions); register(rules: Rule[]): Promise; - evaluate(facts: any, opts?: EvaluateOptions): Promise; + evaluate(facts: Facts, opts?: EvaluateOptions): Promise; } export interface RoolsOptions { logging?: { error?: boolean; debug?: boolean; - delegate?: (params: { level: string, message: string, rule?: string, error?: Error }) => void; + delegate?: (item: { level: string, message: string, rule?: string, error?: Error }) => void; }; } export interface EvaluateOptions { - strategy?: "ps" | "sp"; + strategy?: 'ps' | 'sp'; } export interface EvaluateResult { /** * @deprecated Please use `accessedByActions` instead. */ - updated: string[]; // deprecated - accessedByPremises: string[]; - accessedByActions: string[]; + updated: SegmentType[]; // deprecated + accessedByPremises: SegmentType[]; + accessedByActions: SegmentType[]; fired: number; elapsed: number; } +export type SegmentType = string | symbol; + export class Rule { constructor(opts: RuleOptions); } @@ -41,5 +43,7 @@ export interface RuleOptions { activationGroup?: string; } -export type Premise = (facts: any) => boolean; -export type Action = (facts: any) => void | Promise; +export type Premise = (facts: Facts) => boolean; +export type Action = (facts: Facts) => void | Promise; + +export type Facts = any; // eslint-disable-line @typescript-eslint/no-explicit-any diff --git a/src/index.js b/src/index.js deleted file mode 100644 index b3ef07a..0000000 --- a/src/index.js +++ /dev/null @@ -1,4 +0,0 @@ -const Rools = require('./Rools'); -const Rule = require('./Rule'); - -module.exports = { Rools, Rule }; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..40c7bc8 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,2 @@ +export { default as Rools } from './Rools'; +export { default as Rule } from './Rule'; diff --git a/src/observe.js b/src/observe.ts similarity index 56% rename from src/observe.js rename to src/observe.ts index ac5acb5..5fd8bd7 100644 --- a/src/observe.js +++ b/src/observe.ts @@ -1,8 +1,10 @@ -const observe = (object, onAccess) => { - const handler = { +type AccessHandler = (property: string | symbol) => void; + +export default (object: object, onAccess: AccessHandler) => { + const handler: ProxyHandler = { get(target, property, receiver) { onAccess(property); - return Reflect.get(target, property, receiver); + return Reflect.get(target, property, receiver) as unknown; }, defineProperty(target, property, descriptor) { onAccess(property); @@ -13,7 +15,5 @@ const observe = (object, onAccess) => { return Reflect.deleteProperty(target, property); }, }; - return new Proxy(object, handler); + return new Proxy(object, handler); }; - -module.exports = observe; diff --git a/test/.eslintrc b/test/.eslintrc index a27b0df..dab875f 100644 --- a/test/.eslintrc +++ b/test/.eslintrc @@ -1,15 +1,8 @@ { "extends": "../.eslintrc", - "env": { - "mocha": true - }, - "globals" : { - "assert": false, - "expect": false, - "should": false, - "sinon": false - }, - "plugins": [ - "should-promised" - ] + "rules": { + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/no-unsafe-member-access": "off", + "@typescript-eslint/no-explicit-any": "off" + } } diff --git a/test/Rule.spec.js b/test/Rule.test.ts similarity index 83% rename from test/Rule.spec.js rename to test/Rule.test.ts index 6694eb3..c84b650 100644 --- a/test/Rule.spec.js +++ b/test/Rule.test.ts @@ -1,25 +1,22 @@ -const assert = require('assert'); -const { Rule } = require('..'); -require('./setup'); - -/* eslint-disable no-unused-vars */ +import { strict as assert } from 'assert'; +import { Rule } from '../src'; describe('new Rule()', () => { it('should not fail if properties are correct / minimum', async () => { try { - const rule = new Rule({ + new Rule({ name: 'bla', when: () => true, then: () => {}, }); } catch (error) { - assert.fail(error); + assert.fail(); } }); it('should not fail if properties are correct / maximum', async () => { try { - const rule = new Rule({ + new Rule({ name: 'bla', when: () => true, then: () => {}, @@ -27,13 +24,14 @@ describe('new Rule()', () => { extend: [new Rule({ name: 'blub', when: () => false, then: () => {} })], }); } catch (error) { - assert.fail(error); + assert.fail(); } }); it('should fail if rule has no "name"', async () => { try { - const rule = new Rule({ + // @ts-ignore + new Rule({ when: () => true, then: () => {}, }); @@ -45,7 +43,8 @@ describe('new Rule()', () => { it('should fail if "name" is not a string', async () => { try { - const rule = new Rule({ + new Rule({ + // @ts-ignore name: () => {}, when: () => true, then: () => {}, @@ -58,7 +57,8 @@ describe('new Rule()', () => { it('should fail if rule has no "when"', async () => { try { - const rule = new Rule({ + // @ts-ignore + new Rule({ name: 'bla', then: () => {}, }); @@ -70,7 +70,8 @@ describe('new Rule()', () => { it('should fail if rule has no "then"', async () => { try { - const rule = new Rule({ + // @ts-ignore + new Rule({ name: 'bla', when: () => true, }); @@ -82,7 +83,8 @@ describe('new Rule()', () => { it('should fail if rule "when" is empty', async () => { try { - const rule = new Rule({ + // @ts-ignore + new Rule({ name: 'bla', when: [], then: () => {}, @@ -95,8 +97,9 @@ describe('new Rule()', () => { it('should fail if rule "when" is neither function nor array', async () => { try { - const rule = new Rule({ + new Rule({ name: 'bla', + // @ts-ignore when: 'not a function', then: () => {}, }); @@ -108,8 +111,9 @@ describe('new Rule()', () => { it('should fail if rule "when" is an array with a non-function element', async () => { try { - const rule = new Rule({ + new Rule({ name: 'bla', + // @ts-ignore when: ['not a function'], then: () => {}, }); @@ -121,9 +125,10 @@ describe('new Rule()', () => { it('should fail if rule "then" is not a function', async () => { try { - const rule = new Rule({ + new Rule({ name: 'bla', when: () => true, + // @ts-ignore then: 'not a function', }); assert.fail(); @@ -134,10 +139,11 @@ describe('new Rule()', () => { it('should fail if rule "extend" contains not a Rule', async () => { try { - const rule = new Rule({ + new Rule({ name: 'bla', when: () => true, then: () => {}, + // @ts-ignore extend: {}, }); assert.fail(); diff --git a/test/activationGroup.spec.js b/test/activationGroup.test.ts similarity index 80% rename from test/activationGroup.spec.js rename to test/activationGroup.test.ts index f8f61d9..c17b0b0 100644 --- a/test/activationGroup.spec.js +++ b/test/activationGroup.test.ts @@ -1,31 +1,30 @@ -const { Rools, Rule } = require('..'); -require('./setup'); +import { Rools, Rule } from '../src'; describe('Rools.evaluate() / activation group', () => { - const sequence = []; + const sequence: number[] = []; const rule1 = new Rule({ name: 'rule1', - when: (facts) => facts.fact1, + when: (facts: any) => facts.fact1 as boolean, then: () => { sequence.push(1); }, }); const rule2 = new Rule({ name: 'rule2', extend: rule1, - when: (facts) => facts.fact2, + when: (facts: any) => facts.fact2 as boolean, then: () => { sequence.push(2); }, }); const rule3 = new Rule({ name: 'rule3', - extens: rule2, + extend: rule2, activationGroup: 'groupX', - when: (facts) => facts.fact3, + when: (facts: any) => facts.fact3 as boolean, then: () => { sequence.push(3); }, }); const rule4 = new Rule({ name: 'rule4', extend: rule2, activationGroup: 'groupX', - when: (facts) => facts.fact4, + when: (facts: any) => facts.fact4 as boolean, then: () => { sequence.push(4); }, }); const facts = { @@ -45,7 +44,7 @@ describe('Rools.evaluate() / activation group', () => { rule4, ]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([3, 2, 1]); + expect(sequence).toEqual([3, 2, 1]); }); it('should fire only one rule in activation group / priority', async () => { @@ -58,7 +57,7 @@ describe('Rools.evaluate() / activation group', () => { new Rule({ ...rule4, priority: 10 }), ]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([4, 2, 1]); + expect(sequence).toEqual([4, 2, 1]); }); it('should fire only one rule in activation group / specificity', async () => { @@ -71,7 +70,7 @@ describe('Rools.evaluate() / activation group', () => { rule4, ]); await rools.evaluate(facts, { strategy: 'sp' }); - expect(sequence).to.be.deep.equal([3, 2, 1]); + expect(sequence).toEqual([3, 2, 1]); }); it('should fire only one rule in activation group / specificity 2', async () => { @@ -84,6 +83,6 @@ describe('Rools.evaluate() / activation group', () => { new Rule({ ...rule4, priority: 2 }), ]); await rools.evaluate(facts, { strategy: 'sp' }); - expect(sequence).to.be.deep.equal([4, 2, 1]); + expect(sequence).toEqual([4, 2, 1]); }); }); diff --git a/test/async.spec.js b/test/async.spec.js deleted file mode 100644 index 1691e55..0000000 --- a/test/async.spec.js +++ /dev/null @@ -1,22 +0,0 @@ -const { Rools } = require('..'); -const { frank } = require('./facts/users')(); -const { rule1, rule2 } = require('./rules/availability'); -require('./setup'); - -describe('Rools.evaluate() / async', () => { - it('should call async action / action with async/await', async () => { - const facts = { user: frank }; - const rools = new Rools(); - await rools.register([rule1]); - await rools.evaluate(facts); - expect(facts.products).to.deep.equal(['dsl', 'm4g', 'm3g']); - }); - - it('should call async action / action with promises', async () => { - const facts = { user: frank }; - const rools = new Rools(); - await rools.register([rule2]); - await rools.evaluate(facts); - expect(facts.products).to.deep.equal(['dsl', 'm4g', 'm3g']); - }); -}); diff --git a/test/async.test.ts b/test/async.test.ts new file mode 100644 index 0000000..c6be9ca --- /dev/null +++ b/test/async.test.ts @@ -0,0 +1,25 @@ +import { Rools } from '../src'; +import { frank } from './facts/users'; +import { rule1, rule2 } from './rules/availability'; + +describe('Rools.evaluate() / async', () => { + it('should call async action / action with async/await', async () => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const facts = { user: frank() }; + const rools = new Rools(); + await rools.register([rule1]); + await rools.evaluate(facts); + // @ts-ignore + expect(facts.products).toEqual(['dsl', 'm4g', 'm3g']); + }); + + it('should call async action / action with promises', async () => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const facts = { user: frank() }; + const rools = new Rools(); + await rools.register([rule2]); + await rools.evaluate(facts); + // @ts-ignore + expect(facts.products).toEqual(['dsl', 'm4g', 'm3g']); + }); +}); diff --git a/test/classes.spec.js b/test/classes.test.ts similarity index 55% rename from test/classes.spec.js rename to test/classes.test.ts index d3bbc3c..9a8c22b 100644 --- a/test/classes.spec.js +++ b/test/classes.test.ts @@ -1,43 +1,58 @@ -const { Rools, Rule } = require('..'); -require('./setup'); +import { Rools, Rule } from '../src'; + +interface PersonOptions { + name: string; + stars: number; + salery: number; +} class Person { - constructor({ name, stars, salery }) { + name: string; + mood: string; + stars: number; + salery: number; + + constructor({ name, stars, salery }: PersonOptions) { this.name = name; this.mood = 'unknown'; this.stars = stars; this.salery = salery; } - getStars() { + getStars(): number { return this.stars; } - setStars(stars) { + setStars(stars: number): void { this.stars = stars; } - getSalery() { + getSalery(): number { return this.salery; } - setSalery(salery) { + setSalery(salery: number): void { this.salery = salery; } - getMood() { + getMood(): string { return this.mood; } - setMood(mood) { + setMood(mood: string): void { this.mood = mood; } } +interface Facts { + user: Person; + result?: boolean; +} + const rule1 = new Rule({ name: 'mood is great if 200 stars or more', - when: (facts) => facts.user.getStars() >= 200, - then: (facts) => { + when: (facts: Facts) => facts.user.getStars() >= 200, + then: (facts: Facts) => { facts.user.setMood('great'); }, }); @@ -45,35 +60,33 @@ const rule1 = new Rule({ const rule2 = new Rule({ name: 'mark applicable if mood is great and salery greater 1000', when: [ - (facts) => facts.user.getMood() === 'great', - (facts) => facts.user.getSalery() > 1000, + (facts: Facts) => facts.user.getMood() === 'great', + (facts: Facts) => facts.user.getSalery() > 1000, ], - then: (facts) => { + then: (facts: Facts) => { facts.result = true; }, }); describe('Rools.evaluate() / classes with getters and setters', () => { it('should set mood in 1 pass', async () => { - const facts = { + const facts: Facts = { user: new Person({ name: 'frank', stars: 347, salery: 1234 }), }; const rools = new Rools(); await rools.register([rule1]); await rools.evaluate(facts); - // console.log(result); // eslint-disable-line no-console - expect(facts.user.mood).to.be.equal('great'); + expect(facts.user.mood).toEqual('great'); }); it('should set result in 2 passes', async () => { - const facts = { + const facts: Facts = { user: new Person({ name: 'frank', stars: 347, salery: 1234 }), }; const rools = new Rools(); await rools.register([rule1, rule2]); await rools.evaluate(facts); - // console.log(result); // eslint-disable-line no-console - expect(facts.user.mood).to.be.equal('great'); - expect(facts.result).to.be.equal(true); + expect(facts.user.mood).toEqual('great'); + expect(facts.result).toEqual(true); }); }); diff --git a/test/cycle.spec.js b/test/cycle.test.ts similarity index 61% rename from test/cycle.spec.js rename to test/cycle.test.ts index dc50dd7..abce446 100644 --- a/test/cycle.spec.js +++ b/test/cycle.test.ts @@ -1,22 +1,21 @@ -const { Rools, Rule } = require('../src'); -require('./setup'); +import { Rools, Rule } from '../src'; describe('Rools.evaluate() / cycle', () => { - let rools; + let rools: Rools; - before(async () => { + beforeAll(async () => { rools = new Rools(); const rule1 = new Rule({ name: 'rule 1', - when: (facts) => facts.foo, - then: (facts) => { + when: (facts: any) => facts.foo as boolean, + then: (facts: any) => { facts.foo = false; }, }); const rule2 = new Rule({ name: 'rule 2', - when: (facts) => !facts.foo, - then: (facts) => { + when: (facts: any) => !facts.foo, + then: (facts: any) => { facts.foo = true; }, }); @@ -28,8 +27,8 @@ describe('Rools.evaluate() / cycle', () => { foo: true, }; const result = await rools.evaluate(facts); - expect(facts).to.be.deep.equal({ foo: true }); - expect(result.fired).to.be.equal(2); + expect(facts).toEqual({ foo: true }); + expect(result.fired).toEqual(2); }); it('should evaluate without cycle / scenario 2', async () => { @@ -37,7 +36,7 @@ describe('Rools.evaluate() / cycle', () => { foo: false, }; const result = await rools.evaluate(facts); - expect(facts).to.be.deep.equal({ foo: false }); - expect(result.fired).to.be.equal(2); + expect(facts).toEqual({ foo: false }); + expect(result.fired).toEqual(2); }); }); diff --git a/test/deep.spec.js b/test/deep.spec.js deleted file mode 100644 index 95bfd69..0000000 --- a/test/deep.spec.js +++ /dev/null @@ -1,30 +0,0 @@ -const { Rools } = require('../src'); -const { frank, michael } = require('./facts/users')(); -const { good, bad } = require('./facts/weather')(); -const { - ruleTeamMoodGreat, ruleTeamGoWalking, ruleTeamStayAtHome, -} = require('./rules/deep'); -require('./setup'); - -describe('Rools.evaluate() / deep facts + array', () => { - let rools; - - before(async () => { - rools = new Rools(); - await rools.register([ruleTeamMoodGreat, ruleTeamGoWalking, ruleTeamStayAtHome]); - }); - - it('should evaluate scenario 1', async () => { - const facts = { team: { members: [frank, michael] }, weather: good }; - await rools.evaluate(facts); - expect(facts.team.mood).to.be.equal('great'); - expect(facts.team.goWalking).to.be.equal(true); - }); - - it('should evaluate scenario 2', async () => { - const facts = { team: { members: [frank, michael] }, weather: bad }; - await rools.evaluate(facts); - expect(facts.team.mood).to.be.equal('great'); - expect(facts.team.stayAtHome).to.be.equal(true); - }); -}); diff --git a/test/deep.test.ts b/test/deep.test.ts new file mode 100644 index 0000000..ec65461 --- /dev/null +++ b/test/deep.test.ts @@ -0,0 +1,33 @@ +import { Rools } from '../src'; +import { frank, michael } from './facts/users'; +import { good, bad } from './facts/weather'; +import { + ruleTeamMoodGreat, ruleTeamGoWalking, ruleTeamStayAtHome, +} from './rules/deep'; + +describe('Rools.evaluate() / deep facts + array', () => { + let rools: Rools; + + beforeAll(async () => { + rools = new Rools(); + await rools.register([ruleTeamMoodGreat, ruleTeamGoWalking, ruleTeamStayAtHome]); + }); + + it('should evaluate scenario 1', async () => { + const facts = { team: { members: [frank(), michael()] }, weather: good() }; + await rools.evaluate(facts); + // @ts-ignore + expect(facts.team.mood).toEqual('great'); + // @ts-ignore + expect(facts.team.goWalking).toEqual(true); + }); + + it('should evaluate scenario 2', async () => { + const facts = { team: { members: [frank(), michael()] }, weather: bad() }; + await rools.evaluate(facts); + // @ts-ignore + expect(facts.team.mood).toEqual('great'); + // @ts-ignore + expect(facts.team.stayAtHome).toEqual(true); + }); +}); diff --git a/test/delegate.spec.js b/test/delegate.test.ts similarity index 61% rename from test/delegate.spec.js rename to test/delegate.test.ts index 396243a..481e491 100644 --- a/test/delegate.spec.js +++ b/test/delegate.test.ts @@ -1,21 +1,20 @@ -const Delegator = require('../src/Delegator'); -require('./setup'); +import Delegator from '../src/Delegator'; describe('Delegator', () => { it('should delegate call', () => { const delegator = new Delegator(); - const spy = sinon.spy(); + const spy = jest.fn(); delegator.set(spy); delegator.delegate('bla'); - expect(spy.calledWith('bla')).to.be.equal(true); + expect(spy).toHaveBeenCalledWith('bla'); }); it('should not delegate call if unset', () => { const delegator = new Delegator(); - const spy = sinon.spy(); + const spy = jest.fn(); delegator.set(spy); delegator.unset(); delegator.delegate('bla'); - expect(spy.called).to.be.equal(false); + expect(spy).not.toHaveBeenCalled(); }); }); diff --git a/test/errors.spec.js b/test/errors.test.ts similarity index 59% rename from test/errors.spec.js rename to test/errors.test.ts index 324a6df..5f4848b 100644 --- a/test/errors.spec.js +++ b/test/errors.test.ts @@ -1,41 +1,49 @@ -const assert = require('assert'); -const { Rools, Rule } = require('..'); -const { frank } = require('./facts/users')(); -const { good } = require('./facts/weather')(); -const { +import { strict as assert } from 'assert'; +import { Rools, Rule } from '../src'; +import { frank } from './facts/users'; +import { good } from './facts/weather'; +import { ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome, -} = require('./rules/mood'); -require('./setup'); +} from './rules/mood'; + +interface Facts { + user: any; + weather: any; + goWalking?: any; +} describe('Rools.evaluate() / errors', () => { it('should not fail if `when` throws error', async () => { const brokenRule = new Rule({ name: 'broken rule #1', - when: (facts) => facts.bla.blub === 'blub', // TypeError: Cannot read property 'blub' of undefined + // @ts-ignore + when: (facts: Facts) => facts.bla.blub === 'blub', // TypeError: Cannot read property 'blub' of undefined then: () => {}, }); const rools = new Rools({ logging: { error: false } }); - const facts = { user: frank, weather: good }; + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const facts: Facts = { user: frank(), weather: good() }; await rools.register([brokenRule, ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome]); try { await rools.evaluate(facts); } catch (error) { assert.fail(); } - expect(facts.user.mood).to.be.equal('great'); - expect(facts.goWalking).to.be.equal(true); + expect(facts.user.mood).toEqual('great'); + expect(facts.goWalking).toEqual(true); }); it('should fail if `then` throws error', async () => { const brokenRule = new Rule({ name: 'broken rule #2', when: () => true, // fire immediately - then: (facts) => { + then: (facts: Facts) => { + // @ts-ignore facts.bla.blub = 'blub'; // TypeError: Cannot read property 'blub' of undefined }, }); const rools = new Rools({ logging: { error: false } }); - const facts = { user: frank, weather: good }; + const facts = { user: frank(), weather: good() }; await rools.register([brokenRule, ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome]); try { await rools.evaluate(facts); diff --git a/test/extend.spec.js b/test/extend.test.ts similarity index 80% rename from test/extend.spec.js rename to test/extend.test.ts index 5bce5e9..383c6e4 100644 --- a/test/extend.spec.js +++ b/test/extend.test.ts @@ -1,35 +1,35 @@ -const { Rools, Rule } = require('..'); -require('./setup'); +import { Rools, Rule } from '../src'; + describe('Rools.evaluate() / extend', () => { - const sequence = []; + const sequence: number[] = []; const rule1 = new Rule({ name: 'rule1', - when: (facts) => facts.fact1, + when: (facts) => facts.fact1 as boolean, then: () => { sequence.push(1); }, }); const rule2 = new Rule({ name: 'rule2', extend: rule1, - when: (facts) => facts.fact2, + when: (facts) => facts.fact2 as boolean, then: () => { sequence.push(2); }, }); const rule3 = new Rule({ name: 'rule3', extend: rule2, - when: (facts) => facts.fact3, + when: (facts) => facts.fact3 as boolean, then: () => { sequence.push(3); }, }); const rule4 = new Rule({ name: 'rule4', extend: rule2, - when: (facts) => facts.fact4, + when: (facts) => facts.fact4 as boolean, then: () => { sequence.push(4); }, }); const rule5 = new Rule({ name: 'rule5', extend: [rule3, rule4], - when: (facts) => facts.fact5, + when: (facts) => facts.fact5 as boolean, then: () => { sequence.push(5); }, }); const facts = { @@ -45,7 +45,7 @@ describe('Rools.evaluate() / extend', () => { const rools = new Rools(); await rools.register([rule1, rule2]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([2, 1]); + expect(sequence).toEqual([2, 1]); }); it('should fire rule with higher specificity first / 2 extended rules', async () => { @@ -53,7 +53,7 @@ describe('Rools.evaluate() / extend', () => { const rools = new Rools(); await rools.register([rule1, rule2, rule3]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([3, 2, 1]); + expect(sequence).toEqual([3, 2, 1]); }); it('should fire rule with higher specificity, then order of registration / 3 extended rules', async () => { @@ -61,7 +61,7 @@ describe('Rools.evaluate() / extend', () => { const rools = new Rools(); await rools.register([rule1, rule2, rule3, rule4]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([3, 4, 2, 1]); + expect(sequence).toEqual([3, 4, 2, 1]); }); it('should fire rule with highest prio, then higher specificity / 2 extended rules / 1', async () => { @@ -69,7 +69,7 @@ describe('Rools.evaluate() / extend', () => { const rools = new Rools(); await rools.register([new Rule({ ...rule1, priority: 10 }), rule2, rule3]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([1, 3, 2]); + expect(sequence).toEqual([1, 3, 2]); }); it('should fire rule with highest prio, then higher specificity / 2 extended rules / 2', async () => { @@ -77,7 +77,7 @@ describe('Rools.evaluate() / extend', () => { const rools = new Rools(); await rools.register([rule1, new Rule({ ...rule2, priority: 10 }), rule3]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([2, 3, 1]); + expect(sequence).toEqual([2, 3, 1]); }); it('should fire rule with highest prio, then higher specificity / 3 extended rules', async () => { @@ -85,7 +85,7 @@ describe('Rools.evaluate() / extend', () => { const rools = new Rools(); await rools.register([rule1, rule2, rule3, new Rule({ ...rule4, priority: 10 })]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([4, 3, 2, 1]); + expect(sequence).toEqual([4, 3, 2, 1]); }); it('should fire rule with highest specificity, then order of registration / 4 extended rules', async () => { @@ -93,6 +93,6 @@ describe('Rools.evaluate() / extend', () => { const rools = new Rools(); await rools.register([rule1, rule2, rule3, rule4, rule5]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([5, 3, 4, 2, 1]); + expect(sequence).toEqual([5, 3, 4, 2, 1]); }); }); diff --git a/test/facts/users.js b/test/facts/users.ts similarity index 67% rename from test/facts/users.js rename to test/facts/users.ts index c7237c1..9fa55e6 100644 --- a/test/facts/users.js +++ b/test/facts/users.ts @@ -1,4 +1,4 @@ -const frank = { +export const frank = () => ({ name: 'frank', stars: 347, dateOfBirth: new Date('1995-01-01'), @@ -7,9 +7,9 @@ const frank = { street: 'redderkoppel', country: 'germany', }, -}; +}); -const michael = { +export const michael = () => ({ name: 'michael', stars: 156, dateOfBirth: new Date('1999-08-08'), @@ -18,9 +18,4 @@ const michael = { street: 'willard', country: 'usa', }, -}; - -module.exports = () => ({ - frank: JSON.parse(JSON.stringify(frank)), - michael: JSON.parse(JSON.stringify(michael)), }); diff --git a/test/facts/weather.js b/test/facts/weather.ts similarity index 54% rename from test/facts/weather.js rename to test/facts/weather.ts index 30bc0b6..d7d0c94 100644 --- a/test/facts/weather.js +++ b/test/facts/weather.ts @@ -1,20 +1,15 @@ -const good = { +export const good = () => ({ temperature: 20, humidity: 39, pressure: 1319, windy: true, rainy: false, -}; +}); -const bad = { +export const bad = () => ({ temperature: 9, humidity: 89, pressure: 1013, windy: true, rainy: true, -}; - -module.exports = () => ({ - good: JSON.parse(JSON.stringify(good)), - bad: JSON.parse(JSON.stringify(bad)), }); diff --git a/test/final.spec.js b/test/final.spec.js deleted file mode 100644 index abf9cfe..0000000 --- a/test/final.spec.js +++ /dev/null @@ -1,29 +0,0 @@ -const { Rools, Rule } = require('..'); -const { frank } = require('./facts/users')(); -const { good } = require('./facts/weather')(); -const { - ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome, -} = require('./rules/mood'); -require('./setup'); - -describe('Rools.evaluate() / final', () => { - let rools; - - before(async () => { - rools = new Rools(); - await rools.register([ - ruleGoWalking, - ruleStayAtHome, - new Rule({ ...ruleMoodGreat, final: true }), - new Rule({ ...ruleMoodSad, final: true }), - ]); - }); - - it('should terminate after final rule', async () => { - const facts = { user: frank, weather: good }; - await rools.evaluate(facts); - expect(facts.user.mood).to.be.equal('great'); - expect(facts.goWalking).to.be.equal(undefined); - expect(facts.stayAtHome).to.be.equal(undefined); - }); -}); diff --git a/test/final.test.ts b/test/final.test.ts new file mode 100644 index 0000000..14d0f8f --- /dev/null +++ b/test/final.test.ts @@ -0,0 +1,28 @@ +import { Rools, Rule } from '../src'; +import { frank } from './facts/users'; +import { good } from './facts/weather'; +import { + ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome, +} from './rules/mood'; + +describe('Rools.evaluate() / final', () => { + let rools: Rools; + + beforeAll(async () => { + rools = new Rools(); + await rools.register([ + ruleGoWalking, + ruleStayAtHome, + new Rule({ ...ruleMoodGreat, final: true }), + new Rule({ ...ruleMoodSad, final: true }), + ]); + }); + + it('should terminate after final rule', async () => { + const facts: any = { user: frank(), weather: good() }; + await rools.evaluate(facts); + expect(facts.user.mood).toEqual('great'); + expect(facts.goWalking).toEqual(undefined); + expect(facts.stayAtHome).toEqual(undefined); + }); +}); diff --git a/test/logging.spec.js b/test/logging.test.ts similarity index 72% rename from test/logging.spec.js rename to test/logging.test.ts index 1633106..e0a33af 100644 --- a/test/logging.spec.js +++ b/test/logging.test.ts @@ -1,10 +1,9 @@ -const { Rools, Rule } = require('..'); -const { frank } = require('./facts/users')(); -const { good } = require('./facts/weather')(); -const { +import { Rools, Rule } from '../src'; +import { frank } from './facts/users'; +import { good } from './facts/weather'; +import { ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome, -} = require('./rules/mood'); -require('./setup'); +} from './rules/mood'; describe('Rools.evaluate() / delegate logging', () => { it('should log debug', async () => { @@ -14,8 +13,8 @@ describe('Rools.evaluate() / delegate logging', () => { }; const rools = new Rools({ logging: { error: false, debug: true, delegate: spy } }); await rools.register([ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome]); - await rools.evaluate({ user: frank, weather: good }); - expect(counter).to.not.be.equals(0); + await rools.evaluate({ user: frank(), weather: good() }); + expect(counter).not.toEqual(0); }); it('should log errors', async () => { @@ -33,11 +32,11 @@ describe('Rools.evaluate() / delegate logging', () => { const rools = new Rools({ logging: { error: true, debug: false, delegate: spy } }); await rools.register([brokenRule, ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome]); try { - await rools.evaluate({ user: frank, weather: good }); + await rools.evaluate({ user: frank(), weather: good() }); } catch (error) { // ignore } - expect(counter).to.not.be.equals(0); + expect(counter).not.toEqual(0); }); it('should log errors by default', async () => { @@ -55,30 +54,33 @@ describe('Rools.evaluate() / delegate logging', () => { const rools = new Rools({ logging: { delegate: spy } }); await rools.register([brokenRule, ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome]); try { - await rools.evaluate({ user: frank, weather: good }); + await rools.evaluate({ user: frank(), weather: good() }); } catch (error) { // ignore } - expect(counter).to.not.be.equals(0); + expect(counter).not.toEqual(0); }); }); describe('Rools.evaluate() / console logging', () => { + let consoleLogMock: jest.SpyInstance; + let consoleErrorMock: jest.SpyInstance; + beforeEach(() => { - sinon.spy(console, 'log'); - sinon.spy(console, 'error'); + consoleLogMock = jest.spyOn(global.console, 'log').mockImplementation(); + consoleErrorMock = jest.spyOn(global.console, 'error').mockImplementation(); }); afterEach(() => { - console.log.restore(); // eslint-disable-line no-console - console.error.restore(); // eslint-disable-line no-console + consoleLogMock.mockRestore(); + consoleErrorMock.mockRestore(); }); it('should log debug', async () => { const rools = new Rools({ logging: { error: false, debug: true } }); await rools.register([ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome]); - await rools.evaluate({ user: frank, weather: good }); - expect(console.log).to.be.called; // eslint-disable-line no-unused-expressions, no-console + await rools.evaluate({ user: frank(), weather: good() }); + expect(console.log).toHaveBeenCalled(); }); it('should log errors', async () => { @@ -92,11 +94,11 @@ describe('Rools.evaluate() / console logging', () => { const rools = new Rools({ logging: { error: true, debug: false } }); await rools.register([brokenRule, ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome]); try { - await rools.evaluate({ user: frank, weather: good }); + await rools.evaluate({ user: frank(), weather: good() }); } catch (error) { // ignore } - expect(console.error).to.be.called; // eslint-disable-line no-unused-expressions, no-console + expect(consoleErrorMock).toHaveBeenCalled(); }); it('should log errors by default / 1', async () => { @@ -110,11 +112,11 @@ describe('Rools.evaluate() / console logging', () => { const rools = new Rools(); await rools.register([brokenRule, ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome]); try { - await rools.evaluate({ user: frank, weather: good }); + await rools.evaluate({ user: frank(), weather: good() }); } catch (error) { // ignore } - expect(console.error).to.be.called; // eslint-disable-line no-unused-expressions, no-console + expect(consoleErrorMock).toHaveBeenCalled(); }); it('should log errors by default / 2', async () => { @@ -128,10 +130,10 @@ describe('Rools.evaluate() / console logging', () => { const rools = new Rools({}); await rools.register([brokenRule, ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome]); try { - await rools.evaluate({ user: frank, weather: good }); + await rools.evaluate({ user: frank(), weather: good() }); } catch (error) { // ignore } - expect(console.error).to.be.called; // eslint-disable-line no-unused-expressions, no-console + expect(consoleErrorMock).toHaveBeenCalled(); }); }); diff --git a/test/longer.spec.js b/test/longer.test.ts similarity index 93% rename from test/longer.spec.js rename to test/longer.test.ts index 869c918..de3a2a7 100644 --- a/test/longer.spec.js +++ b/test/longer.test.ts @@ -1,10 +1,9 @@ -const { Rools, Rule } = require('..'); -require('./setup'); +import { Rools, Rule } from '../src'; describe('Rools.evaluate() / longer cycle', () => { - let rools; + let rools: Rools; - before(async () => { + beforeAll(async () => { const rule0 = new Rule({ name: 'rule0', when: (facts) => facts.user.stars === 0, @@ -85,6 +84,6 @@ describe('Rools.evaluate() / longer cycle', () => { stars: 0, }; await rools.evaluate({ user: frank }); - expect(frank.stars).to.be.equal(10); + expect(frank.stars).toEqual(10); }); }); diff --git a/test/observe.spec.js b/test/observe.test.ts similarity index 51% rename from test/observe.spec.js rename to test/observe.test.ts index 87a9d52..1dc8cc6 100644 --- a/test/observe.spec.js +++ b/test/observe.test.ts @@ -1,5 +1,4 @@ -const observe = require('../src/observe'); -require('./setup'); +import observe from '../src/observe'; const object = { prop: true, @@ -10,46 +9,55 @@ const object = { }, }; +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ + describe('observe', () => { it('should notify on reading property', () => { - const spy = sinon.spy(); + const spy = jest.fn(); const proxy = observe(object, spy); - const temp = proxy.prop; // eslint-disable-line no-unused-vars - expect(spy.calledWith('prop')).to.be.equal(true); + // @ts-ignore + const temp = proxy.prop; + expect(spy).toHaveBeenCalledWith('prop'); }); it('should notify on writing property', () => { - const spy = sinon.spy(); + const spy = jest.fn(); const proxy = observe(object, spy); + // @ts-ignore proxy.prop = false; - expect(spy.calledWith('prop')).to.be.equal(true); + expect(spy).toHaveBeenCalledWith('prop'); }); it('should notify on deleting property', () => { - const spy = sinon.spy(); + const spy = jest.fn(); const proxy = observe(object, spy); + // @ts-ignore delete proxy.prop; - expect(spy.calledWith('prop')).to.be.equal(true); + expect(spy).toHaveBeenCalledWith('prop'); }); it('should notify on reading sub-property', () => { - const spy = sinon.spy(); + const spy = jest.fn(); const proxy = observe(object, spy); - const temp = proxy.sub.subsub.bla; // eslint-disable-line no-unused-vars - expect(spy.calledWith('sub')).to.be.equal(true); + // @ts-ignore + const temp = proxy.sub.subsub.bla; + expect(spy).toHaveBeenCalledWith('sub'); }); it('should notify on writing sub-property', () => { - const spy = sinon.spy(); + const spy = jest.fn(); const proxy = observe(object, spy); + // @ts-ignore proxy.sub.subsub.bla = false; - expect(spy.calledWith('sub')).to.be.equal(true); + expect(spy).toHaveBeenCalledWith('sub'); }); it('should notify on deleting sub-property', () => { - const spy = sinon.spy(); + const spy = jest.fn(); const proxy = observe(object, spy); + // @ts-ignore delete proxy.sub.subsub.bla; - expect(spy.calledWith('sub')).to.be.equal(true); + expect(spy).toHaveBeenCalledWith('sub'); }); }); diff --git a/test/premises.spec.js b/test/premises.test.ts similarity index 62% rename from test/premises.spec.js rename to test/premises.test.ts index f867d3b..f19c52b 100644 --- a/test/premises.spec.js +++ b/test/premises.test.ts @@ -1,26 +1,26 @@ -const md5 = require('md5'); -const { Rools, Rule } = require('..'); -require('./setup'); +import md5 from 'md5'; +import { Rools, Rule } from '../src'; describe('Rools.register() / optimization of premises', () => { it('should not merge premises if not identical', async () => { const rule1 = new Rule({ name: 'rule1', - when: (facts) => facts.user.name === 'frank', + when: (facts: any) => facts.user.name === 'frank', then: () => {}, }); const rule2 = new Rule({ name: 'rule2', - when: (facts) => facts.user.name === 'michael', + when: (facts: any) => facts.user.name === 'michael', then: () => {}, }); const rools = new Rools(); await rools.register([rule1, rule2]); - expect(rools.rules.premises.length).to.be.equal(2); + // @ts-ignore + expect(rools.rules.premises.length).toEqual(2); }); it('should merge premises if identical / reference / arrow function', async () => { - const isFrank = (facts) => facts.user.name === 'frank'; + const isFrank = (facts: any) => facts.user.name === 'frank'; const rule1 = new Rule({ name: 'rule1', when: isFrank, @@ -33,11 +33,12 @@ describe('Rools.register() / optimization of premises', () => { }); const rools = new Rools(); await rools.register([rule1, rule2]); - expect(rools.rules.premises.length).to.be.equal(1); + // @ts-ignore + expect(rools.rules.premises.length).toEqual(1); }); it('should merge premises if identical / reference / classic function', async () => { - function isFrank(facts) { + function isFrank(facts: any) { return facts.user.name === 'frank'; } const rule1 = new Rule({ @@ -52,59 +53,63 @@ describe('Rools.register() / optimization of premises', () => { }); const rools = new Rools(); await rools.register([rule1, rule2]); - expect(rools.rules.premises.length).to.be.equal(1); + // @ts-ignore + expect(rools.rules.premises.length).toEqual(1); }); it('should merge premises if identical / hash / arrow function', async () => { const rule1 = new Rule({ name: 'rule1', - when: (facts) => facts.user.name === 'frank', + when: (facts: any) => facts.user.name === 'frank', then: () => {}, }); const rule2 = new Rule({ name: 'rule2', - when: (facts) => facts.user.name === 'frank', + when: (facts: any) => facts.user.name === 'frank', then: () => {}, }); const rools = new Rools(); await rools.register([rule1, rule2]); - expect(rools.rules.premises.length).to.be.equal(1); + // @ts-ignore + expect(rools.rules.premises.length).toEqual(1); }); it('should merge premises if identical / hash / classic function()', async () => { const rule1 = new Rule({ name: 'rule1', - when: function p(facts) { + when: function p(facts: any) { return facts.user.name === 'frank'; }, then: () => {}, }); const rule2 = new Rule({ name: 'rule2', - when: function p(facts) { + when: function p(facts: any) { return facts.user.name === 'frank'; }, then: () => {}, }); const rools = new Rools(); await rools.register([rule1, rule2]); - expect(rools.rules.premises.length).to.be.equal(1); + // @ts-ignore + expect(rools.rules.premises.length).toEqual(1); }); it('should not merge premises if identical / hash / slightly different (unfortunately)', async () => { const rule1 = new Rule({ name: 'rule1', - when: (facts) => facts.user.name === 'frank', + when: (facts: any) => facts.user.name === 'frank', then: () => {}, }); const rule2 = new Rule({ name: 'rule2', - when: (facts) => facts.user.name === "frank", // eslint-disable-line quotes + when: (facts: any) => facts.user.name === "frank", // eslint-disable-line @typescript-eslint/quotes then: () => {}, }); const rools = new Rools(); await rools.register([rule1, rule2]); - expect(rools.rules.premises.length).to.be.equal(2); + // @ts-ignore + expect(rools.rules.premises.length).toEqual(2); }); it('should not merge premises if not identical / with Date object', async () => { @@ -112,62 +117,64 @@ describe('Rools.register() / optimization of premises', () => { const date2 = new Date('1990-01-01'); const rule1 = new Rule({ name: 'rule1', - when: (facts) => facts.user.birthdate > date1, + when: (facts: any) => facts.user.birthdate > date1, then: () => {}, }); const rule2 = new Rule({ name: 'rule2', - when: (facts) => facts.user.birthdate > date2, + when: (facts: any) => facts.user.birthdate > date2, then: () => {}, }); const rools = new Rools(); await rools.register([rule1, rule2]); - expect(rools.rules.premises.length).to.be.equal(2); + // @ts-ignore + expect(rools.rules.premises.length).toEqual(2); }); it('should merge premises if identical / with Date object', async () => { const date = new Date('2000-01-01'); const rule1 = new Rule({ name: 'rule1', - when: (facts) => facts.user.birthdate > date, + when: (facts: any) => facts.user.birthdate > date, then: () => {}, }); const rule2 = new Rule({ name: 'rule2', - when: (facts) => facts.user.birthdate > date, + when: (facts: any) => facts.user.birthdate > date, then: () => {}, }); const rools = new Rools(); await rools.register([rule1, rule2]); - expect(rools.rules.premises.length).to.be.equal(1); + // @ts-ignore + expect(rools.rules.premises.length).toEqual(1); }); it('should merge premises if identical / fn.toString() / 1', async () => { - const foo = ({ context }) => context.bar === 'buz0'; + const foo = ({ context }: any) => context.bar === 'buz0'; const fns = [ - ({ context }) => context.bar === 'buz0', - ({ context }) => context.bar === 'buz 0', - ({ context }) => context.bar === 'buz 0', - ({ context }) => context.bar === 'buz10', - ({ context }) => context.bar === 'buz00', + ({ context }: any) => context.bar === 'buz0', + ({ context }: any) => context.bar === 'buz 0', + ({ context }: any) => context.bar === 'buz 0', + ({ context }: any) => context.bar === 'buz10', + ({ context }: any) => context.bar === 'buz00', foo, foo, - ({ context }) => context.bar === 'buz0', + ({ context }: any) => context.bar === 'buz0', ]; const set = new Set(); fns.forEach((f) => set.add(md5(f.toString()))); - expect(set.size).to.be.equal(4); + expect(set.size).toEqual(4); }); it('should merge premises if identical / fn.toString() / 2', async () => { - const foo = ({ context }) => context.bar === Math.abs(3); + const foo = ({ context }: any) => context.bar === Math.abs(3); const fns = [ - ({ context }) => context.bar === Math.abs(0), - ({ context }) => context.bar === Math.abs(1), + ({ context }: any) => context.bar === Math.abs(0), + ({ context }: any) => context.bar === Math.abs(1), foo, ]; const set = new Set(); fns.forEach((f) => set.add(md5(f.toString()))); - expect(set.size).to.be.equal(3); + expect(set.size).toEqual(3); }); }); diff --git a/test/priority.spec.js b/test/priority.test.ts similarity index 79% rename from test/priority.spec.js rename to test/priority.test.ts index ae1ab1f..ad74fc8 100644 --- a/test/priority.spec.js +++ b/test/priority.test.ts @@ -1,24 +1,27 @@ -const { Rools, Rule } = require('..'); -require('./setup'); +import { Rools, Rule } from '../src'; + +interface Facts { + fact1: boolean; +} describe('Rools.evaluate() / priority', () => { - const sequence = []; + const sequence: number[] = []; const rule1 = new Rule({ name: 'rule1', - when: (facts) => facts.fact1, + when: (facts: Facts) => facts.fact1, then: () => { sequence.push(1); }, }); const rule2 = new Rule({ name: 'rule2', - when: (facts) => facts.fact1, + when: (facts: Facts) => facts.fact1, then: () => { sequence.push(2); }, }); const rule3 = new Rule({ name: 'rule3', - when: (facts) => facts.fact1, + when: (facts: Facts) => facts.fact1, then: () => { sequence.push(3); }, }); @@ -35,7 +38,7 @@ describe('Rools.evaluate() / priority', () => { rule3, ]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([2, 1, 3]); + expect(sequence).toEqual([2, 1, 3]); }); it('should fire in order of registration, finally negative priority -10', async () => { @@ -47,7 +50,7 @@ describe('Rools.evaluate() / priority', () => { rule3, ]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([2, 3, 1]); + expect(sequence).toEqual([2, 3, 1]); }); it('should fire in order of priority 10, 0, -10', async () => { @@ -59,7 +62,7 @@ describe('Rools.evaluate() / priority', () => { new Rule({ ...rule3, priority: 10 }), ]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([3, 2, 1]); + expect(sequence).toEqual([3, 2, 1]); }); it('should fire in order of registration if equal priorities', async () => { @@ -71,6 +74,6 @@ describe('Rools.evaluate() / priority', () => { new Rule({ ...rule3, priority: 10 }), ]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([1, 2, 3]); + expect(sequence).toEqual([1, 2, 3]); }); }); diff --git a/test/reevaluate.spec.js b/test/reevaluate.test.ts similarity index 80% rename from test/reevaluate.spec.js rename to test/reevaluate.test.ts index c6c734b..7b89c0e 100644 --- a/test/reevaluate.spec.js +++ b/test/reevaluate.test.ts @@ -1,10 +1,11 @@ -const { Rools, Rule } = require('..'); -require('./setup'); +import { Rools, Rule } from '../src'; + +/* eslint-disable @typescript-eslint/no-unsafe-return */ describe('Rools.evaluate() / re-evaluate', () => { it('should re-evaluate premises only if facts are changed / row', async () => { - const premisesEvaluated = []; - const actionsFired = []; + const premisesEvaluated: any[] = []; + const actionsFired: any[] = []; const rule1 = new Rule({ name: 'rule1', when: (facts) => { premisesEvaluated.push(1); return facts.fact1; }, @@ -28,13 +29,13 @@ describe('Rools.evaluate() / re-evaluate', () => { const rools = new Rools(); await rools.register([rule1, rule2, rule3]); await rools.evaluate(facts); - expect(premisesEvaluated).to.be.deep.equal([1, 2, 3, 2, 3]); - expect(actionsFired).to.be.deep.equal([1, 2, 3]); + expect(premisesEvaluated).toEqual([1, 2, 3, 2, 3]); + expect(actionsFired).toEqual([1, 2, 3]); }); it('should re-evaluate premises only if facts are changed / complex', async () => { - const premisesEvaluated = []; - const actionsFired = []; + const premisesEvaluated: any[] = []; + const actionsFired: any[] = []; const rule1 = new Rule({ name: 'rule1', when: (facts) => { premisesEvaluated.push(1); return facts.fact1; }, @@ -58,7 +59,7 @@ describe('Rools.evaluate() / re-evaluate', () => { const rools = new Rools(); await rools.register([rule1, rule2, rule3]); await rools.evaluate(facts); - expect(premisesEvaluated).to.be.deep.equal([1, 2, 3, 2, 1, 3, 2]); - expect(actionsFired).to.be.deep.equal([1, 2, 3]); + expect(premisesEvaluated).toEqual([1, 2, 3, 2, 1, 3, 2]); + expect(actionsFired).toEqual([1, 2, 3]); }); }); diff --git a/test/refraction.spec.js b/test/refraction.test.ts similarity index 71% rename from test/refraction.spec.js rename to test/refraction.test.ts index 38051c7..9ff5a3f 100644 --- a/test/refraction.spec.js +++ b/test/refraction.test.ts @@ -1,19 +1,18 @@ -const { Rools, Rule } = require('..'); -require('./setup'); +import { Rools, Rule } from '../src'; describe('Rools.evaluate() / refraction', () => { - const spy = sinon.spy(); + const spy = jest.fn(); const rule1 = new Rule({ name: 'rule1', - when: (facts) => facts.fact1, + when: (facts) => facts.fact1 as boolean, then: (facts) => { facts.fact1 = false; facts.fact1 = true; spy(); }, priority: 10, }); const rule2 = new Rule({ name: 'rule2', - when: (facts) => facts.fact2, + when: (facts) => facts.fact2 as boolean, then: (facts) => { facts.fact1 = false; facts.fact1 = true; }, }); @@ -23,18 +22,18 @@ describe('Rools.evaluate() / refraction', () => { }; it('should fire each rule only once / recursive', async () => { - spy.resetHistory(); + spy.mockClear(); const rools = new Rools(); await rools.register([rule1]); await rools.evaluate(facts); - expect(spy.calledOnce).to.be.equal(true); + expect(spy).toHaveBeenCalledTimes(1); }); it('should fire each rule only once / transitive', async () => { - spy.resetHistory(); + spy.mockClear(); const rools = new Rools(); await rools.register([rule1, rule2]); await rools.evaluate(facts); - expect(spy.calledOnce).to.be.equal(true); + expect(spy).toHaveBeenCalledTimes(1); }); }); diff --git a/test/result.spec.js b/test/result.spec.js deleted file mode 100644 index cdc883d..0000000 --- a/test/result.spec.js +++ /dev/null @@ -1,31 +0,0 @@ -const { Rools } = require('..'); -const { frank } = require('./facts/users')(); -const { good } = require('./facts/weather')(); -const { - ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome, -} = require('./rules/mood'); -require('./setup'); - -describe('Rools.evaluate() / result', () => { - let rools; - - before(async () => { - rools = new Rools(); - await rools.register([ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome]); - }); - - it('should return evaluation details', async () => { - const facts = { user: frank, weather: good }; - const result = await rools.evaluate(facts); - expect(result).to.have.property('updated'); - expect(result).to.have.property('accessedByActions'); - expect(result).to.have.property('accessedByPremises'); - expect(result).to.have.property('fired'); - expect(result).to.have.property('elapsed'); - expect(result.updated).to.be.deep.equal(['user', 'goWalking']); - expect(result.accessedByActions).to.be.deep.equal(['user', 'goWalking']); - expect(result.accessedByPremises).to.be.deep.equal(['user', 'weather']); - expect(result.fired).to.be.equal(2); - expect(result.elapsed).to.be.gte(0); - }); -}); diff --git a/test/result.test.ts b/test/result.test.ts new file mode 100644 index 0000000..c2d0226 --- /dev/null +++ b/test/result.test.ts @@ -0,0 +1,30 @@ +import { Rools } from '../src'; +import { frank } from './facts/users'; +import { good } from './facts/weather'; +import { + ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome, +} from './rules/mood'; + +describe('Rools.evaluate() / result', () => { + let rools: Rools; + + beforeAll(async () => { + rools = new Rools(); + await rools.register([ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome]); + }); + + it('should return evaluation details', async () => { + const facts = { user: frank(), weather: good() }; + const result = await rools.evaluate(facts); + expect(result).toHaveProperty('updated'); + expect(result).toHaveProperty('accessedByActions'); + expect(result).toHaveProperty('accessedByPremises'); + expect(result).toHaveProperty('fired'); + expect(result).toHaveProperty('elapsed'); + expect(result.updated).toEqual(['user', 'goWalking']); + expect(result.accessedByActions).toEqual(['user', 'goWalking']); + expect(result.accessedByPremises).toEqual(['user', 'weather']); + expect(result.fired).toEqual(2); + expect(result.elapsed).toBeGreaterThanOrEqual(0); + }); +}); diff --git a/test/rules/availability.js b/test/rules/availability.ts similarity index 70% rename from test/rules/availability.js rename to test/rules/availability.ts index 8b3d630..3e5a095 100644 --- a/test/rules/availability.js +++ b/test/rules/availability.ts @@ -1,6 +1,6 @@ -const { Rule } = require('../..'); +import { Rule } from '../../src'; -const availabilityCheck = (address) => { // eslint-disable-line arrow-body-style +const availabilityCheck = (address: any): Promise => { return new Promise((resolve) => { setTimeout(() => { if (address.country === 'germany') { @@ -13,20 +13,20 @@ const availabilityCheck = (address) => { // eslint-disable-line arrow-body-style }); }; -const rule1 = new Rule({ +export const rule1 = new Rule({ name: 'check availability of products (async await)', when: (facts) => facts.user.address.country === 'germany', then: async (facts) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment facts.products = await availabilityCheck(facts.user.address); }, }); -const rule2 = new Rule({ +export const rule2 = new Rule({ name: 'check availability of products (promises)', when: (facts) => facts.user.address.country === 'germany', then: (facts) => availabilityCheck(facts.user.address).then((result) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment facts.products = result; }), }); - -module.exports = { rule1, rule2 }; diff --git a/test/rules/deep.js b/test/rules/deep.ts similarity index 58% rename from test/rules/deep.js rename to test/rules/deep.ts index 58878c6..c1c4392 100644 --- a/test/rules/deep.js +++ b/test/rules/deep.ts @@ -1,17 +1,21 @@ -const { Rule } = require('../../src'); +import { Rule } from '../../src'; -const ruleTeamMoodGreat = new Rule({ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable @typescript-eslint/no-unsafe-call */ + +export const ruleTeamMoodGreat = new Rule({ name: 'mood is great if all have 100 stars or more', - when: (facts) => { + when: (facts: any) => { const { members } = facts.team; - return members.reduce((acc, { stars }) => acc && stars >= 100, true); + return members.reduce((acc: any, { stars }: any) => acc && stars >= 100, true); }, then: (facts) => { facts.team.mood = 'great'; }, }); -const ruleTeamGoWalking = new Rule({ +export const ruleTeamGoWalking = new Rule({ name: 'go for a walk if mood is great and the weather is fine', when: [ (facts) => facts.team.mood === 'great', @@ -23,7 +27,7 @@ const ruleTeamGoWalking = new Rule({ }, }); -const ruleTeamStayAtHome = new Rule({ +export const ruleTeamStayAtHome = new Rule({ name: 'stay at home if mood is sad or the weather is bad', when: [ (facts) => facts.weather.rainy || facts.team.mood !== 'great', @@ -32,7 +36,3 @@ const ruleTeamStayAtHome = new Rule({ facts.team.stayAtHome = true; }, }); - -module.exports = { - ruleTeamMoodGreat, ruleTeamGoWalking, ruleTeamStayAtHome, -}; diff --git a/test/rules/mood.js b/test/rules/mood.ts similarity index 69% rename from test/rules/mood.js rename to test/rules/mood.ts index 38e6c72..969ac7c 100644 --- a/test/rules/mood.js +++ b/test/rules/mood.ts @@ -1,6 +1,6 @@ -const { Rule } = require('../..'); +import { Rule } from '../../src'; -const ruleMoodGreat = new Rule({ +export const ruleMoodGreat = new Rule({ name: 'mood is great if 200 stars or more', when: (facts) => facts.user.stars >= 200, then: (facts) => { @@ -8,7 +8,7 @@ const ruleMoodGreat = new Rule({ }, }); -const ruleMoodSad = new Rule({ +export const ruleMoodSad = new Rule({ name: 'mood is sad if less than 200 stars', when: (facts) => facts.user.stars < 200, then: (facts) => { @@ -16,7 +16,7 @@ const ruleMoodSad = new Rule({ }, }); -const ruleGoWalking = new Rule({ +export const ruleGoWalking = new Rule({ name: 'go for a walk if mood is great and the weather is fine', when: [ (facts) => facts.user.mood === 'great', @@ -28,16 +28,12 @@ const ruleGoWalking = new Rule({ }, }); -const ruleStayAtHome = new Rule({ +export const ruleStayAtHome = new Rule({ name: 'stay at home if mood is sad or the weather is bad', when: [ - (facts) => facts.weather.rainy || facts.user.mood === 'sad', + (facts) => (facts.weather.rainy || facts.user.mood === 'sad') as boolean, ], then: (facts) => { facts.stayAtHome = true; }, }); - -module.exports = { - ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome, -}; diff --git a/test/setup.js b/test/setup.js deleted file mode 100644 index 7389f34..0000000 --- a/test/setup.js +++ /dev/null @@ -1,12 +0,0 @@ -const chai = require('chai'); -const chaiAsPromised = require('chai-as-promised'); -const sinon = require('sinon'); -const sinonChai = require('sinon-chai'); - -chai.use(chaiAsPromised); -chai.use(sinonChai); - -global.chai = chai; -global.sinon = sinon; -global.expect = chai.expect; -global.should = chai.should(); diff --git a/test/simple.spec.js b/test/simple.spec.js deleted file mode 100644 index 287da3d..0000000 --- a/test/simple.spec.js +++ /dev/null @@ -1,40 +0,0 @@ -const { Rools } = require('..'); -const { frank, michael } = require('./facts/users')(); -const { good, bad } = require('./facts/weather')(); -const { - ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome, -} = require('./rules/mood'); -require('./setup'); - -describe('Rools.evaluate() / simple', () => { - let rools; - - before(async () => { - rools = new Rools(); - await rools.register([ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome]); - }); - - it('should evaluate scenario 1', async () => { - const facts = { user: frank, weather: good }; - await rools.evaluate(facts); - expect(facts.user.mood).to.be.equal('great'); - expect(facts.goWalking).to.be.equal(true); - expect(facts.stayAtHome).to.be.equal(undefined); - }); - - it('should evaluate scenario 2', async () => { - const facts = { user: michael, weather: good }; - await rools.evaluate(facts); - expect(facts.user.mood).to.be.equal('sad'); - expect(facts.goWalking).to.be.equal(undefined); - expect(facts.stayAtHome).to.be.equal(true); - }); - - it('should evaluate scenario 3', async () => { - const facts = { user: frank, weather: bad }; - await rools.evaluate(facts); - expect(facts.user.mood).to.be.equal('great'); - expect(facts.goWalking).to.be.equal(undefined); - expect(facts.stayAtHome).to.be.equal(true); - }); -}); diff --git a/test/simple.test.ts b/test/simple.test.ts new file mode 100644 index 0000000..4ebf732 --- /dev/null +++ b/test/simple.test.ts @@ -0,0 +1,39 @@ +import { Rools } from '../src'; +import { frank, michael } from './facts/users'; +import { good, bad } from './facts/weather'; +import { + ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome, +} from './rules/mood'; + +describe('Rools.evaluate() / simple', () => { + let rools: Rools; + + beforeAll(async () => { + rools = new Rools(); + await rools.register([ruleMoodGreat, ruleMoodSad, ruleGoWalking, ruleStayAtHome]); + }); + + it('should evaluate scenario 1', async () => { + const facts: any = { user: frank(), weather: good() }; + await rools.evaluate(facts); + expect(facts.user.mood).toEqual('great'); + expect(facts.goWalking).toEqual(true); + expect(facts.stayAtHome).toEqual(undefined); + }); + + it('should evaluate scenario 2', async () => { + const facts: any = { user: michael(), weather: good() }; + await rools.evaluate(facts); + expect(facts.user.mood).toEqual('sad'); + expect(facts.goWalking).toEqual(undefined); + expect(facts.stayAtHome).toEqual(true); + }); + + it('should evaluate scenario 3', async () => { + const facts: any = { user: frank(), weather: bad() }; + await rools.evaluate(facts); + expect(facts.user.mood).toEqual('great'); + expect(facts.goWalking).toEqual(undefined); + expect(facts.stayAtHome).toEqual(true); + }); +}); diff --git a/test/specificity.spec.js b/test/specificity.test.ts similarity index 75% rename from test/specificity.spec.js rename to test/specificity.test.ts index 1407dd7..38465f6 100644 --- a/test/specificity.spec.js +++ b/test/specificity.test.ts @@ -1,36 +1,35 @@ -const { Rools, Rule } = require('..'); -require('./setup'); +import { Rools, Rule } from '../src'; describe('Rools.evaluate() / specificity', () => { - const sequence = []; + const sequence: number[] = []; const rule1 = new Rule({ name: 'rule1', - when: (facts) => facts.fact1, + when: (facts) => facts.fact1 as boolean, then: () => { sequence.push(1); }, }); const rule2 = new Rule({ name: 'rule2', when: [ - (facts) => facts.fact1, - (facts) => facts.fact2, + (facts) => facts.fact1 as boolean, + (facts) => facts.fact2 as boolean, ], then: () => { sequence.push(2); }, }); const rule3 = new Rule({ name: 'rule3', when: [ - (facts) => facts.fact1, - (facts) => facts.fact2, - (facts) => facts.fact3, + (facts) => facts.fact1 as boolean, + (facts) => facts.fact2 as boolean, + (facts) => facts.fact3 as boolean, ], then: () => { sequence.push(3); }, }); const rule4 = new Rule({ name: 'rule4', when: [ - (facts) => facts.fact1, - (facts) => facts.fact2, - (facts) => facts.fact4, + (facts) => facts.fact1 as boolean, + (facts) => facts.fact2 as boolean, + (facts) => facts.fact4 as boolean, ], then: () => { sequence.push(4); }, }); @@ -46,7 +45,7 @@ describe('Rools.evaluate() / specificity', () => { const rools = new Rools(); await rools.register([rule1, rule2]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([2, 1]); + expect(sequence).toEqual([2, 1]); }); it('should fire rule with higher specificity first / three levels', async () => { @@ -54,7 +53,7 @@ describe('Rools.evaluate() / specificity', () => { const rools = new Rools(); await rools.register([rule1, rule2, rule3]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([3, 2, 1]); + expect(sequence).toEqual([3, 2, 1]); }); it('should fire rule with higher specificity, then order of registration', async () => { @@ -62,7 +61,7 @@ describe('Rools.evaluate() / specificity', () => { const rools = new Rools(); await rools.register([rule1, rule2, rule3, rule4]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([3, 4, 2, 1]); + expect(sequence).toEqual([3, 4, 2, 1]); }); it('should fire rule with highest prio, then higher specificity', async () => { @@ -70,7 +69,7 @@ describe('Rools.evaluate() / specificity', () => { const rools = new Rools(); await rools.register([new Rule({ ...rule1, priority: 10 }), rule2, rule3]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([1, 3, 2]); + expect(sequence).toEqual([1, 3, 2]); }); it('should fire rule with highest prio, then higher specificity / 2', async () => { @@ -78,7 +77,7 @@ describe('Rools.evaluate() / specificity', () => { const rools = new Rools(); await rools.register([rule1, new Rule({ ...rule2, priority: 10 }), rule3]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([2, 3, 1]); + expect(sequence).toEqual([2, 3, 1]); }); it('should fire rule with highest prio, then higher specificity / 3', async () => { @@ -86,6 +85,6 @@ describe('Rools.evaluate() / specificity', () => { const rools = new Rools(); await rools.register([rule1, rule2, rule3, new Rule({ ...rule4, priority: 10 })]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([4, 3, 2, 1]); + expect(sequence).toEqual([4, 3, 2, 1]); }); }); diff --git a/test/strategy.spec.js b/test/strategy.test.ts similarity index 78% rename from test/strategy.spec.js rename to test/strategy.test.ts index 264d679..0df5987 100644 --- a/test/strategy.spec.js +++ b/test/strategy.test.ts @@ -1,36 +1,36 @@ -const { Rools, Rule } = require('..'); -require('./setup'); +import { strict as assert } from 'assert'; +import { Rools, Rule } from '../src'; describe('Rools.evaluate() / strategy', () => { - const sequence = []; + const sequence: number[] = []; const rule1 = new Rule({ name: 'rule1', - when: (facts) => facts.fact1, + when: (facts) => facts.fact1 as boolean, then: () => { sequence.push(1); }, }); const rule2 = new Rule({ name: 'rule2', when: [ - (facts) => facts.fact1, - (facts) => facts.fact2, + (facts) => facts.fact1 as boolean, + (facts) => facts.fact2 as boolean, ], then: () => { sequence.push(2); }, }); const rule3 = new Rule({ name: 'rule3', when: [ - (facts) => facts.fact1, - (facts) => facts.fact2, - (facts) => facts.fact3, + (facts) => facts.fact1 as boolean, + (facts) => facts.fact2 as boolean, + (facts) => facts.fact3 as boolean, ], then: () => { sequence.push(3); }, }); const rule4 = new Rule({ name: 'rule4', when: [ - (facts) => facts.fact1, - (facts) => facts.fact2, - (facts) => facts.fact4, + (facts) => facts.fact1 as boolean, + (facts) => facts.fact2 as boolean, + (facts) => facts.fact4 as boolean, ], then: () => { sequence.push(4); }, }); @@ -45,6 +45,7 @@ describe('Rools.evaluate() / strategy', () => { try { const rools = new Rools(); await rools.register([rule1, rule2, rule3]); + // @ts-ignore await rools.evaluate(facts, { strategy: 'xx' }); assert.fail(); } catch (error) { @@ -57,7 +58,7 @@ describe('Rools.evaluate() / strategy', () => { const rools = new Rools(); await rools.register([new Rule({ ...rule1, priority: 10 }), rule2, rule3]); await rools.evaluate(facts); - expect(sequence).to.be.deep.equal([1, 3, 2]); + expect(sequence).toEqual([1, 3, 2]); }); it('should fire rule with highest prio, then higher specificity / strategy "ps" / 2', async () => { @@ -65,7 +66,7 @@ describe('Rools.evaluate() / strategy', () => { const rools = new Rools(); await rools.register([new Rule({ ...rule1, priority: 10 }), rule2, rule3]); await rools.evaluate(facts, { strategy: 'ps' }); - expect(sequence).to.be.deep.equal([1, 3, 2]); + expect(sequence).toEqual([1, 3, 2]); }); it('should fire rule with highest prio, then higher specificity / strategy "ps" / 3', async () => { @@ -73,7 +74,7 @@ describe('Rools.evaluate() / strategy', () => { const rools = new Rools(); await rools.register([new Rule({ ...rule1, priority: 10 }), rule2, rule3]); await rools.evaluate(facts, {}); - expect(sequence).to.be.deep.equal([1, 3, 2]); + expect(sequence).toEqual([1, 3, 2]); }); it('should fire rule with higher specificity, then highest prio / strategy "sp" / 1', async () => { @@ -81,7 +82,7 @@ describe('Rools.evaluate() / strategy', () => { const rools = new Rools(); await rools.register([new Rule({ ...rule1, priority: 10 }), rule2, rule3]); await rools.evaluate(facts, { strategy: 'sp' }); - expect(sequence).to.be.deep.equal([3, 2, 1]); + expect(sequence).toEqual([3, 2, 1]); }); it('should fire rule with higher specificity, then highest prio / strategy "sp" / 2', async () => { @@ -89,7 +90,7 @@ describe('Rools.evaluate() / strategy', () => { const rools = new Rools(); await rools.register([rule1, new Rule({ ...rule2, priority: 10 }), rule3]); await rools.evaluate(facts, { strategy: 'sp' }); - expect(sequence).to.be.deep.equal([3, 2, 1]); + expect(sequence).toEqual([3, 2, 1]); }); it('should fire rule with higher specificity, then highest prio / strategy "sp" / 3', async () => { @@ -97,7 +98,7 @@ describe('Rools.evaluate() / strategy', () => { const rools = new Rools(); await rools.register([rule1, rule2, rule3, rule4]); await rools.evaluate(facts, { strategy: 'sp' }); - expect(sequence).to.be.deep.equal([3, 4, 2, 1]); + expect(sequence).toEqual([3, 4, 2, 1]); }); it('should fire rule with higher specificity, then highest prio / strategy "sp" / 4', async () => { @@ -105,6 +106,6 @@ describe('Rools.evaluate() / strategy', () => { const rools = new Rools(); await rools.register([rule1, rule2, rule3, new Rule({ ...rule4, priority: 10 })]); await rools.evaluate(facts, { strategy: 'sp' }); - expect(sequence).to.be.deep.equal([4, 3, 2, 1]); + expect(sequence).toEqual([4, 3, 2, 1]); }); }); diff --git a/test/symbol.spec.js b/test/symbol.test.ts similarity index 77% rename from test/symbol.spec.js rename to test/symbol.test.ts index 850fb82..c339814 100644 --- a/test/symbol.spec.js +++ b/test/symbol.test.ts @@ -1,15 +1,14 @@ -const { Rools, Rule } = require('../src'); -require('./setup'); +import { Rools, Rule } from '../src'; describe('Rools.evaluate() / facts with symbol properties', () => { - let rools; + let rools: Rools; - before(async () => { + beforeAll(async () => { rools = new Rools(); const foo = Symbol.for('foo'); const rule1 = new Rule({ name: 'symbol test rule 1', - when: (facts) => facts[foo].bar, + when: (facts) => facts[foo].bar as boolean, then: (facts) => { facts[foo].baz = 'great'; }, @@ -33,7 +32,7 @@ describe('Rools.evaluate() / facts with symbol properties', () => { }, }; const { updated, fired } = await rools.evaluate(facts); - expect(facts).to.be.deep.equal({ + expect(facts).toEqual({ [foo]: { bar: true, quux: false, @@ -41,7 +40,7 @@ describe('Rools.evaluate() / facts with symbol properties', () => { qux: 'great', }, }); - expect(updated).to.be.deep.equal([foo]); - expect(fired).to.be.equal(2); + expect(updated).toEqual([foo]); + expect(fired).toEqual(2); }); }); diff --git a/test/typescript/typescript.spec.ts b/test/typescript.test.ts similarity index 58% rename from test/typescript/typescript.spec.ts rename to test/typescript.test.ts index 7ce2df4..ed6120a 100644 --- a/test/typescript/typescript.spec.ts +++ b/test/typescript.test.ts @@ -1,6 +1,4 @@ -import 'mocha'; -import { expect } from 'chai'; -import { Rools, Rule } from "../.."; +import { Rools, Rule } from '../src'; describe('Integration TypeScript', () => { it('should work', async () => { @@ -11,15 +9,15 @@ describe('Integration TypeScript', () => { const rools = new Rools(); const rule = new Rule({ name: 'rule', - when: (facts: any) => { - return true + when: () => { + return true; }, - then: (facts: any) => { - facts.foo = true; + then: (f: any) => { + f.foo = true; }, }); await rools.register([rule]); await rools.evaluate(facts); - expect(facts.foo).to.be.equal(true); + expect(facts.foo).toEqual(true); }); }); diff --git a/test/withdraw.spec.js b/test/withdraw.test.ts similarity index 72% rename from test/withdraw.spec.js rename to test/withdraw.test.ts index 9eeca17..43560fa 100644 --- a/test/withdraw.spec.js +++ b/test/withdraw.test.ts @@ -1,18 +1,17 @@ -const { Rools, Rule } = require('..'); -require('./setup'); +import { Rools, Rule } from '../src'; describe('Rools.evaluate() / withdraw', () => { - const spy = sinon.spy(); + const spy = jest.fn(); const rule1 = new Rule({ name: 'rule1', - when: (facts) => facts.fact1, + when: (facts) => facts.fact1 as boolean, then: (facts) => { facts.fact2 = false; }, }); const rule2 = new Rule({ name: 'rule2', - when: (facts) => facts.fact2, + when: (facts) => facts.fact2 as boolean, then: () => { spy(); }, }); @@ -25,6 +24,6 @@ describe('Rools.evaluate() / withdraw', () => { const rools = new Rools(); await rools.register([rule1, rule2]); await rools.evaluate(facts); - expect(spy.called).to.be.equal(false); + expect(spy).not.toHaveBeenCalled(); }); }); diff --git a/tsconfig.build.cjs.json b/tsconfig.build.cjs.json new file mode 100644 index 0000000..ea97376 --- /dev/null +++ b/tsconfig.build.cjs.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "lib": ["ES2019"], + "module": "commonjs", + "outDir": "build/cjs", + "rootDir": "./src", + "target": "ES2019" + }, + "extends": "./tsconfig.json", + "exclude": [ + "node_modules" + ], + "include": [ + "./src/**/*.ts" + ] +} diff --git a/tsconfig.build.esm.json b/tsconfig.build.esm.json new file mode 100644 index 0000000..e72423a --- /dev/null +++ b/tsconfig.build.esm.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "lib": ["ES2020"], + "module": "ES2020", + "outDir": "build/esm", + "rootDir": "./src", + "target": "ES2020" + }, + "extends": "./tsconfig.json", + "exclude": [ + "node_modules" + ], + "include": [ + "./src/**/*.ts" + ] +} diff --git a/tsconfig.json b/tsconfig.json index 089173b..da18058 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,29 @@ { "compilerOptions": { - "target": "ES2015", /* 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ - "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - } + "esModuleInterop": true, + "lib": ["ES2019"], + "module": "commonjs", + "moduleResolution": "node", + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "resolveJsonModule": true, + "sourceMap": true, + "strict": true, + "target": "ES2019" + }, + "ts-node": { + "moduleTypes": { + "jest.config.ts": "cjs" // workaround https://github.com/facebook/jest/issues/11453 + } + }, + "exclude": [ + "build", + "node_modules" + ], + "include": [ + "./src/**/*.ts", "./test/**/*.ts", "*.ts", + ] }