From d93cfcd55a1d91664f32a3b1893877fce78f3e49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miquel=20Mart=C3=ADn?= Date: Sun, 29 Oct 2023 22:55:58 +0100 Subject: [PATCH] migrate to ts --- .babelrc | 3 +- .editorconfig | 16 + .eslintignore | 11 + .huskyrc | 4 + .mocharc.json | 10 + package-lock.json | 2343 ++++++++++++----- package.json | 33 +- src/constants.js | 69 - src/constants.ts | 64 + src/index.js | 1 - src/index.ts | 5 + src/push-notifications.js | 191 -- src/push-notifications.ts | 217 ++ src/{sendADM.js => sendADM.ts} | 32 +- src/{sendAPN.js => sendAPN.ts} | 121 +- src/sendGCM.js | 188 -- src/sendGCM.ts | 204 ++ src/{sendWNS.js => sendWNS.ts} | 49 +- src/{sendWeb.js => sendWeb.ts} | 23 +- src/types.ts | 205 ++ src/typesInternal.ts | 6 + .../push-notifications/{basic.js => basic.ts} | 146 +- .../{regIds.js => regIds.ts} | 106 +- test/send/{sendADM.js => sendADM.ts} | 30 +- test/send/{sendAPN.js => sendAPN.ts} | 333 +-- test/send/{sendGCM.js => sendGCM.ts} | 214 +- test/send/{sendWEB.js => sendWEB.ts} | 60 +- ...-accessToken.js => sendWNS-accessToken.ts} | 22 +- test/send/{sendWNS.js => sendWNS.ts} | 68 +- test/{util.js => util.ts} | 10 +- tsconfig.test.json | 16 + 31 files changed, 3072 insertions(+), 1728 deletions(-) create mode 100644 .editorconfig create mode 100644 .eslintignore create mode 100644 .huskyrc create mode 100644 .mocharc.json delete mode 100644 src/constants.js create mode 100644 src/constants.ts delete mode 100644 src/index.js create mode 100644 src/index.ts delete mode 100644 src/push-notifications.js create mode 100644 src/push-notifications.ts rename src/{sendADM.js => sendADM.ts} (57%) rename src/{sendAPN.js => sendAPN.ts} (50%) delete mode 100644 src/sendGCM.js create mode 100644 src/sendGCM.ts rename src/{sendWNS.js => sendWNS.ts} (68%) rename src/{sendWeb.js => sendWeb.ts} (60%) create mode 100644 src/types.ts create mode 100644 src/typesInternal.ts rename test/push-notifications/{basic.js => basic.ts} (72%) rename test/push-notifications/{regIds.js => regIds.ts} (67%) rename test/send/{sendADM.js => sendADM.ts} (93%) rename test/send/{sendAPN.js => sendAPN.ts} (70%) rename test/send/{sendGCM.js => sendGCM.ts} (91%) rename test/send/{sendWEB.js => sendWEB.ts} (79%) rename test/send/{sendWNS-accessToken.js => sendWNS-accessToken.ts} (95%) rename test/send/{sendWNS.js => sendWNS.ts} (87%) rename test/{util.js => util.ts} (96%) create mode 100644 tsconfig.test.json diff --git a/.babelrc b/.babelrc index 2547b5b..0fa1885 100644 --- a/.babelrc +++ b/.babelrc @@ -1,10 +1,11 @@ { "presets": [ + "@babel/preset-typescript", [ "@babel/preset-env", { "targets": { - "node": "6" + "node": "current" } } ] diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..1512ccc --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# http://editorconfig.org + +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true +quote_type = single + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..ac65f4c --- /dev/null +++ b/.eslintignore @@ -0,0 +1,11 @@ +# don't ever lint node_modules +node_modules +**/node_modules/**/* +build +# don't lint build output (make sure it's set to your correct build folder name) +lib +logs +typings +# don't lint nyc coverage output +coverage +.eslintrc.js \ No newline at end of file diff --git a/.huskyrc b/.huskyrc new file mode 100644 index 0000000..f9664d6 --- /dev/null +++ b/.huskyrc @@ -0,0 +1,4 @@ +# ~/.huskyrc +# This loads nvm.sh and sets the correct PATH before running hook +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" \ No newline at end of file diff --git a/.mocharc.json b/.mocharc.json new file mode 100644 index 0000000..7d19ce1 --- /dev/null +++ b/.mocharc.json @@ -0,0 +1,10 @@ +{ + "extension": ["ts"], + "spec": "test/**/*.ts", + "require": [ + "@babel/register", + "ts-node/register", + "source-map-support/register" + ], + "recursive": true +} diff --git a/package-lock.json b/package-lock.json index 452fa4e..b2b992c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "node-pushnotifications", - "version": "2.1.0", + "version": "3.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "node-pushnotifications", - "version": "2.1.0", + "version": "3.0.0", "license": "MIT", "dependencies": { "@parse/node-apn": "5.1.3", @@ -17,12 +17,22 @@ "wns": "0.5.4" }, "devDependencies": { - "@babel/cli": "7.17.6", - "@babel/core": "7.17.8", + "@babel/cli": "7.23.0", + "@babel/core": "7.23.2", + "@babel/plugin-transform-modules-commonjs": "7.23.0", "@babel/preset-env": "7.16.11", - "@babel/register": "7.17.7", - "chai": "4.3.6", + "@babel/preset-typescript": "7.23.2", + "@babel/register": "7.22.15", + "@types/chai": "4.3.9", + "@types/dirty-chai": "2.0.3", + "@types/mocha": "10.0.3", + "@types/node": "20.3.2", + "@types/ramda": "0.29.2", + "@types/sinon-chai": "3.2.11", + "@types/web-push": "3.6.2", + "chai": "4.3.10", "coveralls": "3.1.1", + "cross-env": "7.0.3", "dirty-chai": "2.0.1", "eslint": "8.12.0", "eslint-config-airbnb-base": "15.0.0", @@ -30,45 +40,46 @@ "eslint-plugin-import": "2.25.4", "eslint-plugin-prettier": "4.0.0", "husky": "7.0.4", - "mocha": "9.2.2", + "mocha": "10.2.0", "nyc": "15.1.0", "open-cli": "7.2.0", "prettier": "2.6.1", "pretty-quick": "3.1.3", "release-it": "15.11.0", - "sinon": "1.17.7", - "sinon-chai": "3.5.0" + "sinon": "17.0.0", + "sinon-chai": "3.7.0", + "ts-node": "10.9.1" }, "engines": { "node": ">=12.x.x" } }, "node_modules/@ampproject/remapping": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", - "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.0" + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/cli": { - "version": "7.17.6", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.17.6.tgz", - "integrity": "sha512-l4w608nsDNlxZhiJ5tE3DbNmr61fIKMZ6fTBo171VEFuFMIYuJ3mHRhTLEkKKyvx2Mizkkv/0a8OJOnZqkKYNA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.23.0.tgz", + "integrity": "sha512-17E1oSkGk2IwNILM4jtfAvgjt+ohmpfBky8aLerUfYZhiPNg7ca+CRCxZn8QDxwNhV/upsc2VHBCqGFIR+iBfA==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.4", + "@jridgewell/trace-mapping": "^0.3.17", "commander": "^4.0.1", - "convert-source-map": "^1.1.0", + "convert-source-map": "^2.0.0", "fs-readdir-recursive": "^1.1.0", - "glob": "^7.0.0", + "glob": "^7.2.0", "make-dir": "^2.1.0", - "slash": "^2.0.0", - "source-map": "^0.5.0" + "slash": "^2.0.0" }, "bin": { "babel": "bin/babel.js", @@ -85,48 +96,55 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/cli/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "node_modules/@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "dependencies": { - "@babel/highlight": "^7.16.7" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.7.tgz", - "integrity": "sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.2.tgz", + "integrity": "sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.8.tgz", - "integrity": "sha512-OdQDV/7cRBtJHLSOBqqbYNkOcydOgnX59TZx4puf41fzcVtN3e/4yqY8lMQsK+5X2lJtAdmA+6OHqsj1hBJ4IQ==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.7", - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-module-transforms": "^7.17.7", - "@babel/helpers": "^7.17.8", - "@babel/parser": "^7.17.8", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0", - "convert-source-map": "^1.7.0", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.2.tgz", + "integrity": "sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helpers": "^7.23.2", + "@babel/parser": "^7.23.0", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.2", + "@babel/types": "^7.23.0", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -136,36 +154,43 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz", - "integrity": "sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "dependencies": { - "@babel/types": "^7.17.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", - "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -185,45 +210,60 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz", - "integrity": "sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.17.5", - "semver": "^6.3.0" + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" } }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.17.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.6.tgz", - "integrity": "sha512-SogLLSxXm2OkBbSsHZMM4tUi8fUzjs63AT/d0YQIzr6GSd8Hxsbk2KYDX0k0DweAzGMj/YWeiCsorIdtdcW8Eg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", + "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-member-expression-to-functions": "^7.16.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -232,6 +272,15 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-create-regexp-features-plugin": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz", @@ -277,13 +326,10 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, - "dependencies": { - "@babel/types": "^7.16.7" - }, "engines": { "node": ">=6.9.0" } @@ -301,102 +347,89 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.16.7" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz", - "integrity": "sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", - "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", + "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz", - "integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "dev": true, "engines": { "node": ">=6.9.0" @@ -417,70 +450,80 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz", - "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-member-expression-to-functions": "^7.16.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", - "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, "dependencies": { - "@babel/types": "^7.17.0" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", - "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", "dev": true, "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", "dev": true, "engines": { "node": ">=6.9.0" @@ -502,27 +545,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.8.tgz", - "integrity": "sha512-QcL86FGxpfSJwGtAvv4iG93UL6bmqBdmoVY0CMCU2g+oD2ezQse3PT5Pa+jiD6LJndBQi0EDlpzOWNlLuhz5gw==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", + "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", "dev": true, "dependencies": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.2", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz", - "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -530,9 +573,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz", - "integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -896,6 +939,21 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@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", @@ -998,6 +1056,21 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", + "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-arrow-functions": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz", @@ -1239,15 +1312,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.17.7.tgz", - "integrity": "sha512-ITPmR2V7MqioMJyrxUo2onHNC3e+MvfFiFIR0RP21d3PtlVb6sfzoxNKiphSZUOM9hEIdzCcZe83ieX3yoqjUA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz", + "integrity": "sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -1473,6 +1545,24 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.15.tgz", + "integrity": "sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-unicode-escapes": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz", @@ -1617,10 +1707,29 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-typescript": { + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.2.tgz", + "integrity": "sha512-u4UJc1XsS1GhIGteM8rnGiIvf9rJpiVgMEeCnwlLA7WJPC+jcXWJAGxYmeqs5hOZD8BbAfnV5ezBOxQbb4OUxA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.23.0", + "@babel/plugin-transform-typescript": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/register": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.17.7.tgz", - "integrity": "sha512-fg56SwvXRifootQEDQAu1mKdjh5uthPzdO0N6t358FktfL4XjAVXuH58ULoiW8mesxiOgNIrxiImqEwv0+hRRA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.22.15.tgz", + "integrity": "sha512-V3Q3EqoQdn65RCgTLwauZaTfd1ShhwPmbBv+1dkZV/HpCGMKVyn6oFcRlI7RaKqiDQjX2Qd3AuoEguBgdjIKlg==", "dev": true, "dependencies": { "clone-deep": "^4.0.1", @@ -1649,33 +1758,33 @@ } }, "node_modules/@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", - "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.3", - "@babel/types": "^7.17.0", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1684,18 +1793,41 @@ } }, "node_modules/@babel/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", - "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@eslint/eslintrc": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", @@ -1867,29 +1999,52 @@ "node": ">=8" } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", - "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.11", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", - "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@nicolo-ribaudo/chokidar-2": { @@ -2205,6 +2360,50 @@ "url": "https://github.com/sindresorhus/is?sponsor=1" } }, + "node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", + "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "dev": true + }, "node_modules/@szmarczak/http-timer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", @@ -2223,12 +2422,61 @@ "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", "dev": true }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "node_modules/@types/chai": { + "version": "4.3.9", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.9.tgz", + "integrity": "sha512-69TtiDzu0bcmKQv3yg1Zx409/Kd7r0b5F1PfpYJfSHzLGtB53547V4u+9iqKYsTu/O2ai6KTb0TInNpvuQ3qmg==", + "dev": true + }, + "node_modules/@types/chai-as-promised": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.7.tgz", + "integrity": "sha512-APucaP5rlmTRYKtRA6FE5QPP87x76ejw5t5guRJ4y5OgMnwtsvigw7HHhKZlx2MGXLeZd6R/GNZR/IqDHcbtQw==", + "dev": true, + "dependencies": { + "@types/chai": "*" + } + }, "node_modules/@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "node_modules/@types/dirty-chai": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/dirty-chai/-/dirty-chai-2.0.3.tgz", + "integrity": "sha512-B5yxhUQG4HACWwsgqhKlw1yJb/KmvwGdMbCy7PvN/9EthCPT4AyGac7Mds8aYV2fNNkBcMv/K0kgwb5NBrvWoQ==", + "dev": true, + "dependencies": { + "@types/chai": "*", + "@types/chai-as-promised": "*" + } + }, "node_modules/@types/http-cache-semantics": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", @@ -2253,18 +2501,67 @@ "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", "dev": true }, + "node_modules/@types/mocha": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.3.tgz", + "integrity": "sha512-RsOPImTriV/OE4A9qKjMtk2MnXiuLLbcO3nCXK+kvq4nr0iMfFgpjaX3MPLb6f7+EL1FGSelYvuJMV6REH+ZPQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.3.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.2.tgz", + "integrity": "sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw==", + "dev": true + }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, - "node_modules/@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==", + "node_modules/@types/ramda": { + "version": "0.29.2", + "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.29.2.tgz", + "integrity": "sha512-JxvBGR3G4gV3RTOBugVHAAOD6iiv2WjlJ8BHr0s7KALdPpx2l+didoTuoJMmrA0eqpUaCm/slKP4TmxMRihd8g==", + "dev": true, + "dependencies": { + "types-ramda": "^0.29.3" + } + }, + "node_modules/@types/sinon": { + "version": "10.0.20", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.20.tgz", + "integrity": "sha512-2APKKruFNCAZgx3daAyACGzWuJ028VVCUDk6o2rw/Z4PXT0ogwdV4KUegW0MwVs0Zu59auPXbbuBJHF12Sx1Eg==", + "dev": true, + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "node_modules/@types/sinon-chai": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.11.tgz", + "integrity": "sha512-1C5SBFzwn9hjiMr1xfqbULcSI9qXVpkGZT/LYbbd3jWiTo2MSvA+iFfwODlSoAXGeCgBw6S509dxy8zSIacr3Q==", + "dev": true, + "dependencies": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.4.tgz", + "integrity": "sha512-GDV68H0mBSN449sa5HEj51E0wfpVQb8xNSMzxf/PrypMFcLTMwJMOM/cgXiv71Mq5drkOQmUGvL1okOZcu6RrQ==", "dev": true }, + "node_modules/@types/web-push": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@types/web-push/-/web-push-3.6.2.tgz", + "integrity": "sha512-v6Wdk1eIVbAJQjEAa1ZxuG3cfOYTd6nSv55BVJMtLQUvQ07v80MPt2Voq/z71WKhy4CORu4L3aH+8SXKX4BD5g==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/acorn": { "version": "8.7.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", @@ -2464,6 +2761,12 @@ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "node_modules/argparse": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", @@ -2962,9 +3265,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.20.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", - "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", "dev": true, "funding": [ { @@ -2974,14 +3277,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001317", - "electron-to-chromium": "^1.4.84", - "escalade": "^3.1.1", - "node-releases": "^2.0.2", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -3147,9 +3453,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001320", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001320.tgz", - "integrity": "sha512-MWPzG54AGdo3nWx7zHZTefseM5Y1ccM7hlQKHRqJkPozUaw3hNbBTMmLn16GG2FUzjR13Cr3NPfhIieX5PzXDA==", + "version": "1.0.30001557", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001557.tgz", + "integrity": "sha512-91oR7hLNUP3gG6MLU+n96em322a8Xzes8wWdBKhLgUoiJsAF5irZnxSUCbc+qUZXNnPCfUwLOi9ZCZpkvjQajw==", "dev": true, "funding": [ { @@ -3159,6 +3465,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ] }, @@ -3168,18 +3478,18 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "node_modules/chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", + "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "type-detect": "^4.0.8" }, "engines": { "node": ">=4" @@ -3230,10 +3540,13 @@ "dev": true }, "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, "engines": { "node": "*" } @@ -3398,7 +3711,7 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "node_modules/combined-stream": { @@ -3575,6 +3888,30 @@ "lcov-parse": "bin/cli.js" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3711,15 +4048,15 @@ } }, "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, "dependencies": { "type-detect": "^4.0.0" }, "engines": { - "node": ">=0.12" + "node": ">=6" } }, "node_modules/deep-extend": { @@ -4017,7 +4354,10 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/dirty-chai/-/dirty-chai-2.0.1.tgz", "integrity": "sha512-ys79pWKvDMowIDEPC6Fig8d5THiC0DJ2gmTeGzVAoEH18J8OzLud0Jh7I9IWg3NSk8x2UocznUuFmfHCXYZx9w==", - "dev": true + "dev": true, + "peerDependencies": { + "chai": ">=2.2.1 <5" + } }, "node_modules/doctrine": { "version": "3.0.0", @@ -4070,9 +4410,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.94", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.94.tgz", - "integrity": "sha512-CoOKsuACoa0PAG3hQXxbh/XDiFcjGuSyGKUi09cjMHOt6RCi7/EXgXhaFF3I+aC89Omudqmkzd0YOQKxwtf/Bg==", + "version": "1.4.569", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.569.tgz", + "integrity": "sha512-LsrJjZ0IbVy12ApW3gpYpcmHS3iRxH4bkKOW98y1/D+3cvDUWGcbzbsFinfUS8knpcZk/PG/2p/RnkMCYN7PVg==", "dev": true }, "node_modules/emoji-regex": { @@ -4234,7 +4574,7 @@ "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "engines": { "node": ">=0.8.0" @@ -5073,15 +5413,6 @@ "node": ">= 14.17" } }, - "node_modules/formatio": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.1.1.tgz", - "integrity": "sha1-XtPM1jZVEJc4NGXZlhmRAOhhYek=", - "dev": true, - "dependencies": { - "samsam": "~1.1" - } - }, "node_modules/formdata-polyfill": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", @@ -5198,9 +5529,9 @@ } }, "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "engines": { "node": "*" @@ -5492,17 +5823,8 @@ "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "engines": { - "node": ">=4.x" - } + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true }, "node_modules/har-schema": { "version": "2.0.0", @@ -5557,7 +5879,7 @@ "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { "node": ">=4" @@ -6876,6 +7198,12 @@ "node >=0.6.0" ] }, + "node_modules/just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, "node_modules/jwa": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", @@ -6989,6 +7317,12 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -7077,19 +7411,13 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/lolex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.3.2.tgz", - "integrity": "sha1-fD2mL/yzDw9agKJWbKJORdigHzE=", - "dev": true - }, "node_modules/loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, "dependencies": { - "get-func-name": "^2.0.0" + "get-func-name": "^2.0.1" } }, "node_modules/lowercase-keys": { @@ -7141,6 +7469,12 @@ "node": ">=6" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -7241,42 +7575,39 @@ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "node_modules/mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dev": true, "dependencies": { - "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", "chokidar": "3.5.3", - "debug": "4.3.3", + "debug": "4.3.4", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", "glob": "7.2.0", - "growl": "1.10.5", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", - "minimatch": "4.2.1", + "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.3.1", + "nanoid": "3.3.3", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", + "workerpool": "6.2.1", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, "bin": { "_mocha": "bin/_mocha", - "mocha": "bin/mocha" + "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 12.0.0" + "node": ">= 14.0.0" }, "funding": { "type": "opencollective", @@ -7289,6 +7620,38 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "node_modules/mocha/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -7345,12 +7708,12 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { "node": ">=10" @@ -7450,9 +7813,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", "dev": true, "bin": { "nanoid": "bin/nanoid.cjs" @@ -7503,6 +7866,46 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/nise": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.5.tgz", + "integrity": "sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "^10.0.2", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "node_modules/nise/node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/nise/node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/nise/node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, "node_modules/node-adm": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/node-adm/-/node-adm-0.9.1.tgz", @@ -7590,9 +7993,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", "dev": true }, "node_modules/normalize-path": { @@ -8814,6 +9217,21 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-to-regexp/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -9932,12 +10350,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "node_modules/samsam": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.1.2.tgz", - "integrity": "sha1-vsEf3IOp/aBjQBIQ5AF2wwJNFWc=", - "dev": true - }, "node_modules/semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -10062,25 +10474,41 @@ "dev": true }, "node_modules/sinon": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-1.17.7.tgz", - "integrity": "sha1-RUKk9JugxFwF6y6d2dID4rjv4L8=", + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.0.tgz", + "integrity": "sha512-p4lJiYKBoOEVUxxVIC9H1MM2znG1/c8gud++I2BauJA5hsz7hHsst35eurNWXTusBsIq66FzOQbZ/uMdpvbPIQ==", "dev": true, "dependencies": { - "formatio": "1.1.1", - "lolex": "1.3.2", - "samsam": "1.1.2", - "util": ">=0.10.3 <1" + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.5", + "supports-color": "^7.2.0" }, - "engines": { - "node": ">=0.1.103" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" } }, "node_modules/sinon-chai": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.5.0.tgz", - "integrity": "sha512-IifbusYiQBpUxxFJkR3wTU68xzBN0+bxCScEaKMjBvAQERg6FnTTc1F17rseLb1tjmkJ23730AXpFI0c47FgAg==", - "dev": true + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", + "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", + "dev": true, + "peerDependencies": { + "chai": "^4.0.0", + "sinon": ">=4.0.0" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } }, "node_modules/slash": { "version": "2.0.0", @@ -10164,15 +10592,6 @@ "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", "dev": true }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-support": { "version": "0.5.19", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", @@ -10466,9 +10885,9 @@ } }, "node_modules/supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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, "dependencies": { "has-flag": "^4.0.0" @@ -10643,6 +11062,64 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/ts-toolbelt": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", + "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==", + "dev": true + }, "node_modules/tsconfig-paths": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", @@ -10743,6 +11220,29 @@ "is-typedarray": "^1.0.0" } }, + "node_modules/types-ramda": { + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/types-ramda/-/types-ramda-0.29.3.tgz", + "integrity": "sha512-6z8/UCI5/kRorQ91Mo+TUXImHpGAhmhg8ZIdT/tNrG+xSQvDwJXYyT5Nlw2U5VpoKetUZVqQXYYLQyq5Bzccsg==", + "dev": true, + "dependencies": { + "ts-toolbelt": "^9.6.0" + } + }, + "node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -10837,6 +11337,36 @@ "node": ">=8" } }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/update-notifier": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", @@ -10914,27 +11444,12 @@ "resolved": "https://registry.npmjs.org/urlsafe-base64/-/urlsafe-base64-1.0.0.tgz", "integrity": "sha1-I/iQaabGL0bPOh07ABac77kL4MY=" }, - "node_modules/util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "dependencies": { - "inherits": "2.0.1" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, - "node_modules/util/node_modules/inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, "node_modules/uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", @@ -10949,6 +11464,12 @@ "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", "dev": true }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -11265,9 +11786,9 @@ } }, "node_modules/workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, "node_modules/wrap-ansi": { @@ -11407,6 +11928,15 @@ "node": ">=10" } }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/yocto-queue": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", @@ -11422,96 +11952,112 @@ }, "dependencies": { "@ampproject/remapping": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", - "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.0" + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" } }, "@babel/cli": { - "version": "7.17.6", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.17.6.tgz", - "integrity": "sha512-l4w608nsDNlxZhiJ5tE3DbNmr61fIKMZ6fTBo171VEFuFMIYuJ3mHRhTLEkKKyvx2Mizkkv/0a8OJOnZqkKYNA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.23.0.tgz", + "integrity": "sha512-17E1oSkGk2IwNILM4jtfAvgjt+ohmpfBky8aLerUfYZhiPNg7ca+CRCxZn8QDxwNhV/upsc2VHBCqGFIR+iBfA==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.4", + "@jridgewell/trace-mapping": "^0.3.17", "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", "chokidar": "^3.4.0", "commander": "^4.0.1", - "convert-source-map": "^1.1.0", + "convert-source-map": "^2.0.0", "fs-readdir-recursive": "^1.1.0", - "glob": "^7.0.0", + "glob": "^7.2.0", "make-dir": "^2.1.0", - "slash": "^2.0.0", - "source-map": "^0.5.0" + "slash": "^2.0.0" + }, + "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + } } }, "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "requires": { - "@babel/highlight": "^7.16.7" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" } }, "@babel/compat-data": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.7.tgz", - "integrity": "sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.2.tgz", + "integrity": "sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==", "dev": true }, "@babel/core": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.8.tgz", - "integrity": "sha512-OdQDV/7cRBtJHLSOBqqbYNkOcydOgnX59TZx4puf41fzcVtN3e/4yqY8lMQsK+5X2lJtAdmA+6OHqsj1hBJ4IQ==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.7", - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-module-transforms": "^7.17.7", - "@babel/helpers": "^7.17.8", - "@babel/parser": "^7.17.8", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0", - "convert-source-map": "^1.7.0", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.2.tgz", + "integrity": "sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helpers": "^7.23.2", + "@babel/parser": "^7.23.0", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.2", + "@babel/types": "^7.23.0", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } }, "@babel/generator": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz", - "integrity": "sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "requires": { - "@babel/types": "^7.17.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" } }, "@babel/helper-annotate-as-pure": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", - "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { @@ -11525,38 +12071,64 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz", - "integrity": "sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", "dev": true, "requires": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.17.5", - "semver": "^6.3.0" + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } }, "@babel/helper-create-class-features-plugin": { - "version": "7.17.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.6.tgz", - "integrity": "sha512-SogLLSxXm2OkBbSsHZMM4tUi8fUzjs63AT/d0YQIzr6GSd8Hxsbk2KYDX0k0DweAzGMj/YWeiCsorIdtdcW8Eg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", + "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-member-expression-to-functions": "^7.16.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7" + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + } } }, "@babel/helper-create-regexp-features-plugin": { @@ -11594,13 +12166,10 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true }, "@babel/helper-explode-assignable-expression": { "version": "7.16.7", @@ -11612,81 +12181,68 @@ } }, "@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" } }, "@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz", - "integrity": "sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.23.0" } }, "@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.15" } }, "@babel/helper-module-transforms": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", - "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", + "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" } }, "@babel/helper-optimise-call-expression": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz", - "integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" } }, "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "dev": true }, "@babel/helper-remap-async-to-generator": { @@ -11701,55 +12257,59 @@ } }, "@babel/helper-replace-supers": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz", - "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", "dev": true, "requires": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-member-expression-to-functions": "^7.16.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" } }, "@babel/helper-simple-access": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", - "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, "requires": { - "@babel/types": "^7.17.0" + "@babel/types": "^7.22.5" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", - "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", "dev": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.22.5" } }, "@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" } }, + "@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true + }, "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", "dev": true }, "@babel/helper-wrap-function": { @@ -11765,31 +12325,31 @@ } }, "@babel/helpers": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.8.tgz", - "integrity": "sha512-QcL86FGxpfSJwGtAvv4iG93UL6bmqBdmoVY0CMCU2g+oD2ezQse3PT5Pa+jiD6LJndBQi0EDlpzOWNlLuhz5gw==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", + "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", "dev": true, "requires": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0" + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.2", + "@babel/types": "^7.23.0" } }, "@babel/highlight": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.7.tgz", - "integrity": "sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.17.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz", - "integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { @@ -12024,6 +12584,15 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-jsx": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", + "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, "@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", @@ -12093,7 +12662,16 @@ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", + "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" } }, "@babel/plugin-transform-arrow-functions": { @@ -12247,15 +12825,14 @@ } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.17.7.tgz", - "integrity": "sha512-ITPmR2V7MqioMJyrxUo2onHNC3e+MvfFiFIR0RP21d3PtlVb6sfzoxNKiphSZUOM9hEIdzCcZe83ieX3yoqjUA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz", + "integrity": "sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" } }, "@babel/plugin-transform-modules-systemjs": { @@ -12391,6 +12968,18 @@ "@babel/helper-plugin-utils": "^7.16.7" } }, + "@babel/plugin-transform-typescript": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.15.tgz", + "integrity": "sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.22.5" + } + }, "@babel/plugin-transform-unicode-escapes": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz", @@ -12513,10 +13102,23 @@ "esutils": "^2.0.2" } }, + "@babel/preset-typescript": { + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.2.tgz", + "integrity": "sha512-u4UJc1XsS1GhIGteM8rnGiIvf9rJpiVgMEeCnwlLA7WJPC+jcXWJAGxYmeqs5hOZD8BbAfnV5ezBOxQbb4OUxA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.23.0", + "@babel/plugin-transform-typescript": "^7.22.15" + } + }, "@babel/register": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.17.7.tgz", - "integrity": "sha512-fg56SwvXRifootQEDQAu1mKdjh5uthPzdO0N6t358FktfL4XjAVXuH58ULoiW8mesxiOgNIrxiImqEwv0+hRRA==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.22.15.tgz", + "integrity": "sha512-V3Q3EqoQdn65RCgTLwauZaTfd1ShhwPmbBv+1dkZV/HpCGMKVyn6oFcRlI7RaKqiDQjX2Qd3AuoEguBgdjIKlg==", "dev": true, "requires": { "clone-deep": "^4.0.1", @@ -12536,44 +13138,66 @@ } }, "@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" } }, "@babel/traverse": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", - "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.3", - "@babel/types": "^7.17.0", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", - "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } + } + }, "@eslint/eslintrc": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", @@ -12707,26 +13331,43 @@ "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", "dev": true }, + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "@jridgewell/resolve-uri": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", - "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true }, "@jridgewell/sourcemap-codec": { - "version": "1.4.11", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", - "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "@nicolo-ribaudo/chokidar-2": { @@ -12974,6 +13615,52 @@ "integrity": "sha512-axlrvsHlHlFmKKMEg4VyvMzFr93JWJj4eIfXY1STVuO2fsImCa7ncaiG5gC8HKOX590AW5RtRsC41/B+OfrSqw==", "dev": true }, + "@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.0" + } + }, + "@sinonjs/samsam": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", + "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + } + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "dev": true + }, "@szmarczak/http-timer": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", @@ -12989,12 +13676,61 @@ "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", "dev": true }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, + "@types/chai": { + "version": "4.3.9", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.9.tgz", + "integrity": "sha512-69TtiDzu0bcmKQv3yg1Zx409/Kd7r0b5F1PfpYJfSHzLGtB53547V4u+9iqKYsTu/O2ai6KTb0TInNpvuQ3qmg==", + "dev": true + }, + "@types/chai-as-promised": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.7.tgz", + "integrity": "sha512-APucaP5rlmTRYKtRA6FE5QPP87x76ejw5t5guRJ4y5OgMnwtsvigw7HHhKZlx2MGXLeZd6R/GNZR/IqDHcbtQw==", + "dev": true, + "requires": { + "@types/chai": "*" + } + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/dirty-chai": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/dirty-chai/-/dirty-chai-2.0.3.tgz", + "integrity": "sha512-B5yxhUQG4HACWwsgqhKlw1yJb/KmvwGdMbCy7PvN/9EthCPT4AyGac7Mds8aYV2fNNkBcMv/K0kgwb5NBrvWoQ==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/chai-as-promised": "*" + } + }, "@types/http-cache-semantics": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", @@ -13019,18 +13755,67 @@ "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", "dev": true }, + "@types/mocha": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.3.tgz", + "integrity": "sha512-RsOPImTriV/OE4A9qKjMtk2MnXiuLLbcO3nCXK+kvq4nr0iMfFgpjaX3MPLb6f7+EL1FGSelYvuJMV6REH+ZPQ==", + "dev": true + }, + "@types/node": { + "version": "20.3.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.2.tgz", + "integrity": "sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw==", + "dev": true + }, "@types/normalize-package-data": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, - "@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==", + "@types/ramda": { + "version": "0.29.2", + "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.29.2.tgz", + "integrity": "sha512-JxvBGR3G4gV3RTOBugVHAAOD6iiv2WjlJ8BHr0s7KALdPpx2l+didoTuoJMmrA0eqpUaCm/slKP4TmxMRihd8g==", + "dev": true, + "requires": { + "types-ramda": "^0.29.3" + } + }, + "@types/sinon": { + "version": "10.0.20", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.20.tgz", + "integrity": "sha512-2APKKruFNCAZgx3daAyACGzWuJ028VVCUDk6o2rw/Z4PXT0ogwdV4KUegW0MwVs0Zu59auPXbbuBJHF12Sx1Eg==", + "dev": true, + "requires": { + "@types/sinonjs__fake-timers": "*" + } + }, + "@types/sinon-chai": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.11.tgz", + "integrity": "sha512-1C5SBFzwn9hjiMr1xfqbULcSI9qXVpkGZT/LYbbd3jWiTo2MSvA+iFfwODlSoAXGeCgBw6S509dxy8zSIacr3Q==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "@types/sinonjs__fake-timers": { + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.4.tgz", + "integrity": "sha512-GDV68H0mBSN449sa5HEj51E0wfpVQb8xNSMzxf/PrypMFcLTMwJMOM/cgXiv71Mq5drkOQmUGvL1okOZcu6RrQ==", "dev": true }, + "@types/web-push": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@types/web-push/-/web-push-3.6.2.tgz", + "integrity": "sha512-v6Wdk1eIVbAJQjEAa1ZxuG3cfOYTd6nSv55BVJMtLQUvQ07v80MPt2Voq/z71WKhy4CORu4L3aH+8SXKX4BD5g==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "acorn": { "version": "8.7.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", @@ -13184,6 +13969,12 @@ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "argparse": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", @@ -13546,16 +14337,15 @@ "dev": true }, "browserslist": { - "version": "4.20.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", - "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001317", - "electron-to-chromium": "^1.4.84", - "escalade": "^3.1.1", - "node-releases": "^2.0.2", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" } }, "buffer": { @@ -13669,9 +14459,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001320", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001320.tgz", - "integrity": "sha512-MWPzG54AGdo3nWx7zHZTefseM5Y1ccM7hlQKHRqJkPozUaw3hNbBTMmLn16GG2FUzjR13Cr3NPfhIieX5PzXDA==", + "version": "1.0.30001557", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001557.tgz", + "integrity": "sha512-91oR7hLNUP3gG6MLU+n96em322a8Xzes8wWdBKhLgUoiJsAF5irZnxSUCbc+qUZXNnPCfUwLOi9ZCZpkvjQajw==", "dev": true }, "caseless": { @@ -13680,18 +14470,18 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", + "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", "dev": true, "requires": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "type-detect": "^4.0.8" } }, "chalk": { @@ -13732,10 +14522,13 @@ "dev": true }, "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "requires": { + "get-func-name": "^2.0.2" + } }, "chokidar": { "version": "3.5.3", @@ -13854,7 +14647,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "combined-stream": { @@ -14002,6 +14795,21 @@ } } }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -14094,9 +14902,9 @@ } }, "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==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, "requires": { "type-detect": "^4.0.0" @@ -14299,7 +15107,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/dirty-chai/-/dirty-chai-2.0.1.tgz", "integrity": "sha512-ys79pWKvDMowIDEPC6Fig8d5THiC0DJ2gmTeGzVAoEH18J8OzLud0Jh7I9IWg3NSk8x2UocznUuFmfHCXYZx9w==", - "dev": true + "dev": true, + "requires": {} }, "doctrine": { "version": "3.0.0", @@ -14343,9 +15152,9 @@ } }, "electron-to-chromium": { - "version": "1.4.94", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.94.tgz", - "integrity": "sha512-CoOKsuACoa0PAG3hQXxbh/XDiFcjGuSyGKUi09cjMHOt6RCi7/EXgXhaFF3I+aC89Omudqmkzd0YOQKxwtf/Bg==", + "version": "1.4.569", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.569.tgz", + "integrity": "sha512-LsrJjZ0IbVy12ApW3gpYpcmHS3iRxH4bkKOW98y1/D+3cvDUWGcbzbsFinfUS8knpcZk/PG/2p/RnkMCYN7PVg==", "dev": true }, "emoji-regex": { @@ -14480,7 +15289,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, "escodegen": { @@ -15107,15 +15916,6 @@ "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", "dev": true }, - "formatio": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.1.1.tgz", - "integrity": "sha1-XtPM1jZVEJc4NGXZlhmRAOhhYek=", - "dev": true, - "requires": { - "samsam": "~1.1" - } - }, "formdata-polyfill": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", @@ -15204,9 +16004,9 @@ "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=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true }, "get-intrinsic": { @@ -15418,12 +16218,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "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", @@ -15462,7 +16256,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "has-property-descriptors": { @@ -16397,6 +17191,12 @@ } } }, + "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 + }, "jwa": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", @@ -16495,6 +17295,12 @@ "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": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, "lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -16570,19 +17376,13 @@ } } }, - "lolex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.3.2.tgz", - "integrity": "sha1-fD2mL/yzDw9agKJWbKJORdigHzE=", - "dev": true - }, "loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", "dev": true, "requires": { - "get-func-name": "^2.0.0" + "get-func-name": "^2.0.1" } }, "lowercase-keys": { @@ -16616,6 +17416,12 @@ "semver": "^5.6.0" } }, + "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 + }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -16689,32 +17495,29 @@ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", + "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", "dev": true, "requires": { - "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", "chokidar": "3.5.3", - "debug": "4.3.3", + "debug": "4.3.4", "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", "glob": "7.2.0", - "growl": "1.10.5", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", - "minimatch": "4.2.1", + "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.3.1", + "nanoid": "3.3.3", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", + "workerpool": "6.2.1", "yargs": "16.2.0", "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" @@ -16726,6 +17529,32 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "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", @@ -16767,12 +17596,12 @@ } }, "minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" } }, "ms": { @@ -16847,9 +17676,9 @@ "dev": true }, "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", "dev": true }, "natural-compare": { @@ -16881,6 +17710,50 @@ } } }, + "nise": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.5.tgz", + "integrity": "sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "^10.0.2", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.0" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + } + } + } + } + }, "node-adm": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/node-adm/-/node-adm-0.9.1.tgz", @@ -16938,9 +17811,9 @@ } }, "node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", "dev": true }, "normalize-path": { @@ -17797,6 +18670,23 @@ "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" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + } + } + }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -18588,12 +19478,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "samsam": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.1.2.tgz", - "integrity": "sha1-vsEf3IOp/aBjQBIQ5AF2wwJNFWc=", - "dev": true - }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -18687,22 +19571,33 @@ "dev": true }, "sinon": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-1.17.7.tgz", - "integrity": "sha1-RUKk9JugxFwF6y6d2dID4rjv4L8=", + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.0.tgz", + "integrity": "sha512-p4lJiYKBoOEVUxxVIC9H1MM2znG1/c8gud++I2BauJA5hsz7hHsst35eurNWXTusBsIq66FzOQbZ/uMdpvbPIQ==", "dev": true, "requires": { - "formatio": "1.1.1", - "lolex": "1.3.2", - "samsam": "1.1.2", - "util": ">=0.10.3 <1" + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.5", + "supports-color": "^7.2.0" + }, + "dependencies": { + "diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "dev": true + } } }, "sinon-chai": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.5.0.tgz", - "integrity": "sha512-IifbusYiQBpUxxFJkR3wTU68xzBN0+bxCScEaKMjBvAQERg6FnTTc1F17rseLb1tjmkJ23730AXpFI0c47FgAg==", - "dev": true + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", + "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", + "dev": true, + "requires": {} }, "slash": { "version": "2.0.0", @@ -18765,12 +19660,6 @@ } } }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, "source-map-support": { "version": "0.5.19", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", @@ -18991,9 +19880,9 @@ } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "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" @@ -19117,6 +20006,41 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + }, + "ts-toolbelt": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", + "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==", + "dev": true + }, "tsconfig-paths": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", @@ -19201,6 +20125,22 @@ "is-typedarray": "^1.0.0" } }, + "types-ramda": { + "version": "0.29.3", + "resolved": "https://registry.npmjs.org/types-ramda/-/types-ramda-0.29.3.tgz", + "integrity": "sha512-6z8/UCI5/kRorQ91Mo+TUXImHpGAhmhg8ZIdT/tNrG+xSQvDwJXYyT5Nlw2U5VpoKetUZVqQXYYLQyq5Bzccsg==", + "dev": true, + "requires": { + "ts-toolbelt": "^9.6.0" + } + }, + "typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "peer": true + }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -19268,6 +20208,16 @@ "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", "dev": true }, + "update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, "update-notifier": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", @@ -19326,23 +20276,6 @@ "resolved": "https://registry.npmjs.org/urlsafe-base64/-/urlsafe-base64-1.0.0.tgz", "integrity": "sha1-I/iQaabGL0bPOh07ABac77kL4MY=" }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -19360,6 +20293,12 @@ "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", "dev": true }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -19598,9 +20537,9 @@ "dev": true }, "workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", + "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", "dev": true }, "wrap-ansi": { @@ -19711,6 +20650,12 @@ } } }, + "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": "1.0.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", diff --git a/package.json b/package.json index c09cc24..55b5352 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,16 @@ { "name": "node-pushnotifications", "description": "A cross-platform push service for node.js", - "version": "2.1.0", + "version": "3.0.0", "author": { "name": "AppFeel", "email": "info@appfeel.com" }, "scripts": { "coveralls": "cat ./coverage/lcov.info | coveralls", - "test-cover": "nyc --reporter=lcov mocha test/ -- --require @babel/register --recursive; open-cli ./coverage/lcov-report/index.html", - "test": "mocha test/ --require @babel/register --recursive", - "build": "./node_modules/.bin/babel src -d lib", + "test-cover": "cross-env TS_NODE_PROJECT='./tsconfig.test.json' nyc --reporter=lcov mocha; open-cli ./coverage/lcov-report/index.html", + "test": "cross-env TS_NODE_PROJECT='./tsconfig.test.json' mocha", + "build": "babel src -d lib --extensions '.js,.jsx,.es,.es6,.mjs,.ts,.tsx'", "lint": "eslint {src,test}/**/*.js", "format": "prettier --write \"**/*.{js,json,md,yml}\"", "ci": "npm run build && npm run test-cover && npm run lint", @@ -60,12 +60,22 @@ "wns": "0.5.4" }, "devDependencies": { - "@babel/cli": "7.17.6", - "@babel/core": "7.17.8", + "@babel/cli": "7.23.0", + "@babel/core": "7.23.2", + "@babel/plugin-transform-modules-commonjs": "7.23.0", "@babel/preset-env": "7.16.11", - "@babel/register": "7.17.7", - "chai": "4.3.6", + "@babel/preset-typescript": "7.23.2", + "@babel/register": "7.22.15", + "@types/chai": "4.3.9", + "@types/dirty-chai": "2.0.3", + "@types/mocha": "10.0.3", + "@types/node": "20.3.2", + "@types/ramda": "0.29.2", + "@types/sinon-chai": "3.2.11", + "@types/web-push": "3.6.2", + "chai": "4.3.10", "coveralls": "3.1.1", + "cross-env": "7.0.3", "dirty-chai": "2.0.1", "eslint": "8.12.0", "eslint-config-airbnb-base": "15.0.0", @@ -73,14 +83,15 @@ "eslint-plugin-import": "2.25.4", "eslint-plugin-prettier": "4.0.0", "husky": "7.0.4", - "mocha": "9.2.2", + "mocha": "10.2.0", "nyc": "15.1.0", "open-cli": "7.2.0", "prettier": "2.6.1", "pretty-quick": "3.1.3", "release-it": "15.11.0", - "sinon": "1.17.7", - "sinon-chai": "3.5.0" + "sinon": "17.0.0", + "sinon-chai": "3.7.0", + "ts-node": "10.9.1" }, "engines": { "node": ">=12.x.x" diff --git a/src/constants.js b/src/constants.js deleted file mode 100644 index a5998b1..0000000 --- a/src/constants.js +++ /dev/null @@ -1,69 +0,0 @@ -module.exports = { - DEFAULT_TTL: 28 * 86400, - GCM_MAX_TTL: 2419200, // 4 weeks in seconds (https://firebase.google.com/docs/cloud-messaging/http-server-ref#downstream-http-messages-json) - APN_METHOD: 'apn', - GCM_METHOD: 'gcm', - ADM_METHOD: 'adm', - WNS_METHOD: 'wns', - WEB_METHOD: 'webPush', - UNKNOWN_METHOD: 'unknown', - DEFAULT_SETTINGS: { - gcm: { - id: null, // PUT YOUR GCM SERVER API KEY, - }, - apn: { - // See options at https://github.com/node-apn/node-apn/blob/master/doc/provider.markdown - token: null, - // { - // key: '', - // keyId: '', - // teamId: '', - // }, - cert: 'cert.pem', - key: 'key.pem', - ca: null, - pfx: null, - passphrase: null, - production: process.env.NODE_ENV === 'production', - voip: false, - address: null, - port: 443, - rejectUnauthorized: true, - connectionRetryLimit: 10, - - cacheLength: 1000, - connectionTimeout: 3600000, - autoAdjustCache: true, - maxConnections: 1, - minConnections: 1, - connectTimeout: 10000, - buffersNotifications: true, - fastMode: false, - disableNagle: false, - disableEPIPEFix: false, - }, - adm: { - client_id: null, // PUT YOUR ADM CLIENT ID, - client_secret: null, // PUT YOUR ADM CLIENT SECRET, - }, - wns: { - client_id: null, // PUT YOUR WNS CLIENT ID, - client_secret: null, // PUT YOUR WNS CLIENT SECRET, - accessToken: null, - headers: null, - notificationMethod: 'sendTileSquareBlock', - }, - web: { - vapidDetails: { - subject: "< 'mailto' Address or URL >", - publicKey: '< URL Safe Base64 Encoded Public Key >', - privateKey: '< URL Safe Base64 Encoded Private Key >', - }, - // gcmAPIKey: '< GCM API Key >', - // TTL: 2419200 - // headers: { } - // contentEncoding: '< Encoding type, e.g.: aesgcm or aes128gcm >' - }, - isAlwaysUseFCM: false, - }, -}; diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..23bf186 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,64 @@ +import { ADM, APN, DefaultSettings, GCM, UNKNOWN, WEB, WNS } from './types'; + +export const DEFAULT_TTL = 28 * 86400; +export const GCM_MAX_TTL = 2419200; // 4 weeks in seconds (https://firebase.google.com/docs/cloud-messaging/http-server-ref#downstream-http-messages-json) + +export const DEFAULT_SETTINGS: DefaultSettings = { + gcm: { + id: undefined, // PUT YOUR GCM SERVER API KEY, + }, + apn: { + // See options at https://github.com/node-apn/node-apn/blob/master/doc/provider.markdown + token: undefined, + // { + // key: '', + // keyId: '', + // teamId: '', + // }, + cert: 'cert.pem', + key: 'key.pem', + ca: undefined, + pfx: undefined, + passphrase: undefined, + production: process.env.NODE_ENV === 'production', + // voip: false, // VOIP is in Notification type, not in settings + address: undefined, + port: 443, + rejectUnauthorized: true, + connectionRetryLimit: 10, + + cacheLength: 1000, + connectionTimeout: 3600000, + autoAdjustCache: true, + maxConnections: 1, + minConnections: 1, + connectTimeout: 10000, + buffersNotifications: true, + fastMode: false, + disableNagle: false, + disableEPIPEFix: false, + }, + adm: { + client_id: undefined, // PUT YOUR ADM CLIENT ID, + client_secret: undefined, // PUT YOUR ADM CLIENT SECRET, + }, + wns: { + client_id: undefined, // PUT YOUR WNS CLIENT ID, + client_secret: undefined, // PUT YOUR WNS CLIENT SECRET, + accessToken: undefined, + headers: undefined, + notificationMethod: 'sendTileSquareBlock', + }, + web: { + vapidDetails: { + subject: "< 'mailto' Address or URL >", + publicKey: '< URL Safe Base64 Encoded Public Key >', + privateKey: '< URL Safe Base64 Encoded Private Key >', + }, + // gcmAPIKey: '< GCM API Key >', + // TTL: 2419200 + // headers: { } + // contentEncoding: '< Encoding type, e.g.: aesgcm or aes128gcm >' + }, + isAlwaysUseFCM: false, +}; diff --git a/src/index.js b/src/index.js deleted file mode 100644 index 3864c70..0000000 --- a/src/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./push-notifications'); diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..9cd1131 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,5 @@ +import PN from './push-notifications'; + +export default PN; +export { PN }; +export * from './types'; diff --git a/src/push-notifications.js b/src/push-notifications.js deleted file mode 100644 index cb6c8fb..0000000 --- a/src/push-notifications.js +++ /dev/null @@ -1,191 +0,0 @@ -/* eslint-disable import/no-import-module-exports */ - -import sendGCM from './sendGCM'; -import APN from './sendAPN'; -import sendADM from './sendADM'; -import sendWNS from './sendWNS'; -import sendWebPush from './sendWeb'; -import { - DEFAULT_SETTINGS, - UNKNOWN_METHOD, - WEB_METHOD, - WNS_METHOD, - ADM_METHOD, - GCM_METHOD, - APN_METHOD, -} from './constants'; - -class PN { - constructor(options) { - this.setOptions(options); - } - - setOptions(opts) { - this.settings = { ...DEFAULT_SETTINGS, ...opts }; - if (this.apn) { - this.apn.shutdown(); - } - this.apn = new APN(this.settings.apn); - } - - sendWith(method, regIds, data, cb) { - return method(regIds, data, this.settings) - .then((results) => { - (cb || ((noop) => noop))(null, results); - return results; - }) - .catch((error) => { - (cb || ((noop) => noop))(error); - return Promise.reject(error); - }); - } - - getPushMethodByRegId(regId) { - if (typeof regId === 'object' && (!regId.type || !regId.id)) { - return { regId, pushMethod: WEB_METHOD }; - } - - if (typeof regId === 'object' && regId.id && regId.type) { - return { - regId: regId.id, - pushMethod: this.settings.isAlwaysUseFCM ? GCM_METHOD : regId.type, - }; - } - - // TODO: deprecated, remove of all cases below in v3.0 - // and review test cases - if (this.settings.isAlwaysUseFCM) { - return { regId, pushMethod: GCM_METHOD }; - } - - if (regId.substring(0, 4) === 'http') { - return { regId, pushMethod: WNS_METHOD }; - } - - if (/^(amzn[0-9]*.adm)/i.test(regId)) { - return { regId, pushMethod: ADM_METHOD }; - } - - if ( - (regId.length === 64 || regId.length === 160) && - /^[a-fA-F0-9]+$/.test(regId) - ) { - return { regId, pushMethod: APN_METHOD }; - } - - if (regId.length > 64) { - return { regId, pushMethod: GCM_METHOD }; - } - - return { regId, pushMethod: UNKNOWN_METHOD }; - } - - send(_regIds, data, callback) { - const promises = []; - const regIdsGCM = []; - const regIdsAPN = []; - const regIdsWNS = []; - const regIdsADM = []; - const regIdsWebPush = []; - const regIdsUnk = []; - const regIds = Array.isArray(_regIds || []) ? _regIds || [] : [_regIds]; - - // Classify each pushId for corresponding device - regIds.forEach((regIdOriginal) => { - const { regId, pushMethod } = this.getPushMethodByRegId(regIdOriginal); - - if (pushMethod === WEB_METHOD) { - regIdsWebPush.push(regId); - } else if (pushMethod === GCM_METHOD) { - regIdsGCM.push(regId); - } else if (pushMethod === WNS_METHOD) { - regIdsWNS.push(regId); - } else if (pushMethod === ADM_METHOD) { - regIdsADM.push(regId); - } else if (pushMethod === APN_METHOD) { - regIdsAPN.push(regId); - } else { - regIdsUnk.push(regId); - } - }); - - try { - // Android GCM - if (regIdsGCM.length > 0) { - promises.push(this.sendWith(sendGCM, regIdsGCM, data)); - } - - // iOS APN - if (regIdsAPN.length > 0) { - promises.push( - this.sendWith(this.apn.sendAPN.bind(this.apn), regIdsAPN, data) - ); - } - - // Microsoft WNS - if (regIdsWNS.length > 0) { - promises.push(this.sendWith(sendWNS, regIdsWNS, data)); - } - - // Amazon ADM - if (regIdsADM.length > 0) { - promises.push(this.sendWith(sendADM, regIdsADM, data)); - } - - // Web Push - if (regIdsWebPush.length > 0) { - promises.push(this.sendWith(sendWebPush, regIdsWebPush, data)); - } - } catch (err) { - promises.push(Promise.reject(err)); - } - - // Unknown - if (regIdsUnk.length > 0) { - const results = { - method: 'unknown', - success: 0, - failure: regIdsUnk.length, - message: [], - }; - regIdsUnk.forEach((regId) => { - results.message.push({ - regId, - error: new Error('Unknown registration id'), - }); - }); - promises.push(Promise.resolve(results)); - } - - // No regIds detected - if (promises.length === 0) { - promises.push( - Promise.resolve({ - method: 'none', - success: 0, - failure: 0, - message: [], - }) - ); - } - - return Promise.all(promises) - .then((results) => { - const cb = callback || ((noop) => noop); - cb(null, results); - return results; - }) - .catch((err) => { - const cb = callback || ((noop) => noop); - cb(err); - return Promise.reject(err); - }); - } -} - -module.exports = PN; -module.exports.WEB = WEB_METHOD; -module.exports.WNS = WNS_METHOD; -module.exports.ADM = ADM_METHOD; -module.exports.GCM = GCM_METHOD; -module.exports.APN = APN_METHOD; diff --git a/src/push-notifications.ts b/src/push-notifications.ts new file mode 100644 index 0000000..af9edb2 --- /dev/null +++ b/src/push-notifications.ts @@ -0,0 +1,217 @@ +import * as webPush from 'web-push'; + +import sendGCM from './sendGCM'; +import APNSender from './sendAPN'; +import sendADM from './sendADM'; +import sendWNS from './sendWNS'; +import sendWebPush from './sendWeb'; +import { DEFAULT_SETTINGS } from './constants'; +import { DefaultSettings, RegId, RegIdType } from './types'; +import { PushMethod } from './typesInternal'; + +export default class PN { + private settings: DefaultSettings; + private apn: APNSender; + + constructor(options: DefaultSettings) { + this.setOptions(options); + } + + setOptions(opts: DefaultSettings): void { + this.settings = { ...DEFAULT_SETTINGS, ...opts }; + if (this.settings.apn) { + if (this.apn) { + this.apn.shutdown(); + } + this.apn = new APNSender(this.settings.apn); + } + } + + getOptions() { + return this.settings; + } + + async sendWith( + method: any, + regIds: any[], + data: any, + cb?: Function + ): Promise { + try { + const results = await method(regIds, data, this.settings); + (cb || ((noop: any) => noop))(null, results); + return results; + } catch (error) { + (cb || ((noop: any) => noop))(error); + return Promise.reject(error); + } + } + + getPushMethodByRegId(regId: RegId): PushMethod { + let regIdStr = ''; + + if (typeof regId === 'object') { + // regId is an object with id and type => FCM if always FCM or given type + // This is the new definition for android and ios regIds for node-pushnotifications + // This has been implemented like this because Apple does not ensure the length of its regId + if (regId.id && regId.type) { + return { + regId: regId.id, + type: this.settings.isAlwaysUseFCM ? RegIdType.gcm : regId.type, + }; + } + + // regId should be a PushSubscription object => web notifications + // PushSubscription: { endpoint, expirationTime, options, subscriptionId } + if (!regId.id) { + return { regId, type: RegIdType.web }; + } + + regIdStr = regId.id; + } else { + regIdStr = regId; + } + + // TODO: deprecated, remove all cases below in v3.0 ?? + // and review test cases + if (this.settings.isAlwaysUseFCM) { + return { regId: regIdStr, type: RegIdType.gcm }; + } + + if (regIdStr.substring(0, 4) === 'http') { + return { regId: regIdStr, type: RegIdType.wns }; + } + + if (/^(amzn[0-9]*.adm)/i.test(regIdStr)) { + return { regId: regIdStr, type: RegIdType.adm }; + } + + if ( + (regIdStr.length === 64 || regIdStr.length === 160) && + /^[a-fA-F0-9]+$/.test(regIdStr) + ) { + return { regId: regIdStr, type: RegIdType.apn }; + } + + if (regIdStr.length > 64) { + return { regId: regIdStr, type: RegIdType.gcm }; + } + + return { regId: regIdStr, type: RegIdType.unknown }; + } + + async send( + _regIds: RegId | RegId[], + data: any, + callback?: Function + ): Promise { + const promises: Promise[] = []; + const regIdsGCM: string[] = []; + const regIdsAPN: string[] = []; + const regIdsWNS: string[] = []; + const regIdsADM: string[] = []; + const regIdsWebPush: (string | webPush.PushSubscription)[] = []; + const regIdsUnk: string[] = []; + const regIds: RegId[] = Array.isArray(_regIds || []) + ? (_regIds as RegId[]) || [] + : [_regIds as RegId]; + + // Classify each pushId for corresponding device + regIds.forEach((regIdOriginal: any) => { + const { regId, type } = this.getPushMethodByRegId(regIdOriginal); + + switch (type) { + case RegIdType.adm: + regIdsADM.push(regId as string); + break; + case RegIdType.apn: + regIdsAPN.push(regId as string); + break; + case RegIdType.gcm: + regIdsGCM.push(regId as string); + break; + case RegIdType.web: + regIdsWebPush.push(regId as string); + break; + case RegIdType.wns: + regIdsWNS.push(regId as string); + break; + case RegIdType.unknown: + default: + regIdsUnk.push(regId as string); + break; + } + }); + + try { + // Android GCM + if (regIdsGCM.length > 0) { + promises.push(this.sendWith(sendGCM, regIdsGCM, data)); + } + + // iOS APN + if (regIdsAPN.length > 0) { + promises.push( + this.sendWith(this.apn.sendAPN.bind(this.apn), regIdsAPN, data) + ); + } + + // Microsoft WNS + if (regIdsWNS.length > 0) { + promises.push(this.sendWith(sendWNS, regIdsWNS, data)); + } + + // Amazon ADM + if (regIdsADM.length > 0) { + promises.push(this.sendWith(sendADM, regIdsADM, data)); + } + + // Web Push + if (regIdsWebPush.length > 0) { + promises.push(this.sendWith(sendWebPush, regIdsWebPush, data)); + } + } catch (err) { + promises.push(Promise.reject(err)); + } + + // Unknown + if (regIdsUnk.length > 0) { + const results: any = { + method: 'unknown', + success: 0, + failure: regIdsUnk.length, + message: [], + }; + regIdsUnk.forEach((regId) => { + results.message.push({ + regId, + error: new Error('Unknown registration id'), + }); + }); + promises.push(Promise.resolve(results)); + } + + // No regIds detected + if (promises.length === 0) { + promises.push( + Promise.resolve({ + method: 'none', + success: 0, + failure: 0, + message: [], + }) + ); + } + + try { + const results = await Promise.all(promises); + const cb = callback || ((noop: any) => noop); + cb(null, results); + return results; + } catch (err) { + const cb = callback || ((noop: any) => noop); + cb(err); + return Promise.reject(err); + } + } +} diff --git a/src/sendADM.js b/src/sendADM.ts similarity index 57% rename from src/sendADM.js rename to src/sendADM.ts index 08a0f78..d04c68b 100644 --- a/src/sendADM.js +++ b/src/sendADM.ts @@ -1,17 +1,21 @@ -const adm = require('node-adm'); -const { ADM_METHOD } = require('./constants'); +import adm from 'node-adm'; +import { Data, DefaultSettings, RegIdType } from './types'; -const sendADM = (regIds, _data, settings) => { - const resumed = { - method: ADM_METHOD, +const sendADM = async ( + regIds: string[], + _data: Data, + settings: DefaultSettings +) => { + const resumed: any = { + method: RegIdType.adm, success: 0, failure: 0, message: [], }; - const promises = []; + const promises: any[] = []; const admSender = new adm.Sender(settings.adm); const data = { ..._data }; - const { consolidationKey, expiry, timeToLive, custom } = data; + const { consolidationKey, expiry, timeToLive, custom = {} } = data; delete data.consolidationKey; delete data.expiry; @@ -19,10 +23,11 @@ const sendADM = (regIds, _data, settings) => { delete data.custom; const message = { - expiresAfter: - expiry - Math.floor(Date.now() / 1000) || timeToLive || 28 * 86400, + expiresAfter: expiry + ? expiry - Math.floor(Date.now() / 1000) || timeToLive || 28 * 86400 + : undefined, consolidationKey, - data: { ...data, ...custom }, + data: { ...data, ...(typeof custom === 'object' ? custom : {}) }, }; regIds.forEach((regId) => { @@ -39,13 +44,14 @@ const sendADM = (regIds, _data, settings) => { error, errorMsg, }); - resolve(); + resolve(true); }); }) ); }); - return Promise.all(promises).then(() => resumed); + await Promise.all(promises); + return resumed; }; -module.exports = sendADM; +export default sendADM; diff --git a/src/sendAPN.js b/src/sendAPN.ts similarity index 50% rename from src/sendAPN.js rename to src/sendAPN.ts index 55b5cc6..fd49548 100644 --- a/src/sendAPN.js +++ b/src/sendAPN.ts @@ -1,24 +1,25 @@ -const apn = require('@parse/node-apn'); -const R = require('ramda'); -const { DEFAULT_TTL, APN_METHOD } = require('./constants'); +import apn from '@parse/node-apn'; +import * as R from 'ramda'; +import { DEFAULT_TTL } from './constants'; +import { Data, RegIdType } from './types'; -const expiryFromTtl = (ttl) => ttl + Math.floor(Date.now() / 1000); +const expiryFromTtl = (ttl: number) => ttl + Math.floor(Date.now() / 1000); -const extractExpiry = R.cond([ - [R.propIs(Number, 'expiry'), R.prop('expiry')], +const extractExpiry = R.cond([ + [R.propIs(Number, 'expiry'), R.prop('expiry')], [ R.propIs(Number, 'timeToLive'), - ({ timeToLive }) => expiryFromTtl(timeToLive), + ({ timeToLive = 0 }) => expiryFromTtl(timeToLive), ], [R.T, () => expiryFromTtl(DEFAULT_TTL)], ]); -const getPropValueOrUndefinedIfIsSilent = (propName, data) => - R.ifElse( - R.propEq('silent', true), - R.always(undefined), - R.prop(propName) - )(data); +const getPropValueOrUndefinedIfIsSilent = (propName: string, data: any) => { + if (data.silent === true) { + return undefined; + } + return data[propName]; +}; const toJSONorUndefined = R.tryCatch(JSON.parse, R.always(undefined)); @@ -29,7 +30,7 @@ const alertLocArgsToJSON = R.evolve({ }, }); -const getDefaultAlert = (data) => ({ +const getDefaultAlert = (data: any) => ({ title: data.title, body: data.body, 'title-loc-key': data.titleLocKey, @@ -41,13 +42,13 @@ const getDefaultAlert = (data) => ({ action: data.action, }); -const alertOrDefault = (data) => +const alertOrDefault = (data: any) => R.when( R.propSatisfies(R.isNil, 'alert'), R.assoc('alert', getDefaultAlert(data)) ); -const getParsedAlertOrDefault = (data) => +const getParsedAlertOrDefault = (data: any) => R.pipe(alertOrDefault(data), alertLocArgsToJSON)(data); const getDeviceTokenOrSelf = R.ifElse( @@ -56,13 +57,16 @@ const getDeviceTokenOrSelf = R.ifElse( R.identity ); -class APN { - constructor(settings) { +export default class APNSender { + private connection?: apn.Provider; + private connectionError: any; + + constructor(settings: apn.ProviderOptions) { try { this.connection = new apn.Provider(settings); } catch (e) { this.connectionError = e; - this.connection = null; + this.connection = undefined; } } @@ -72,7 +76,7 @@ class APN { } } - sendAPN(regIds, data) { + async sendAPN(regIds: string[], data: Data): Promise { const message = new apn.Notification({ retryLimit: data.retries || -1, expiry: extractExpiry(data), @@ -98,53 +102,50 @@ class APN { }); if (!this.connection) { - return Promise.reject( + throw new Error( this.connectionError || new Error('Unknown error: APN connection not configured properly') ); } - return this.connection.send(message, regIds).then((response) => { - const resumed = { - method: APN_METHOD, - success: 0, - failure: 0, - message: [], - }; - (response.sent || []).forEach((token) => { - resumed.success += 1; + const response = await this.connection.send(message, regIds); + const resumed: any = { + method: RegIdType.apn, + success: 0, + failure: 0, + message: [], + }; + (response.sent || []).forEach((token: any) => { + resumed.success += 1; + resumed.message.push({ + regId: getDeviceTokenOrSelf(token), + error: null, + }); + }); + (response.failed || []).forEach((failure: any) => { + // See https://github.com/node-apn/node-apn/blob/master/doc/provider.markdown#failed + resumed.failure += 1; + if (failure.error) { + // A transport-level error occurred (e.g. network problem) resumed.message.push({ - regId: getDeviceTokenOrSelf(token), - error: null, + regId: failure.device, + error: failure.error, + errorMsg: failure.error.message || failure.error, }); - }); - (response.failed || []).forEach((failure) => { - // See https://github.com/node-apn/node-apn/blob/master/doc/provider.markdown#failed - resumed.failure += 1; - if (failure.error) { - // A transport-level error occurred (e.g. network problem) - resumed.message.push({ - regId: failure.device, - error: failure.error, - errorMsg: failure.error.message || failure.error, - }); - } else { - // `failure.status` is the HTTP status code - // `failure.response` is the JSON payload - resumed.message.push({ - regId: failure.device, - error: - failure.response.reason || failure.status - ? new Error(failure.response.reason || failure.status) - : failure.response, - errorMsg: failure.response.reason || failure.status, - }); - } - }); - - return resumed; + } else { + // `failure.status` is the HTTP status code + // `failure.response` is the JSON payload + resumed.message.push({ + regId: failure.device, + error: + failure.response?.reason || failure.status + ? new Error(failure.response?.reason || failure.status) + : failure.response, + errorMsg: failure.response?.reason || failure.status, + }); + } }); + + return resumed; } } - -module.exports = APN; diff --git a/src/sendGCM.js b/src/sendGCM.js deleted file mode 100644 index aa28a0d..0000000 --- a/src/sendGCM.js +++ /dev/null @@ -1,188 +0,0 @@ -const gcm = require('node-gcm'); -const R = require('ramda'); -const { DEFAULT_TTL, GCM_METHOD, GCM_MAX_TTL } = require('./constants'); - -const ttlFromExpiry = R.compose( - R.min(GCM_MAX_TTL), - (expiry) => expiry - Math.floor(Date.now() / 1000) -); - -const extractTimeToLive = R.cond([ - [R.propIs(Number, 'expiry'), ({ expiry }) => ttlFromExpiry(expiry)], - [R.propIs(Number, 'timeToLive'), R.prop('timeToLive')], - [R.T, R.always(DEFAULT_TTL)], -]); - -const pathIsString = R.pathSatisfies(R.is(String)); - -const containsValidRecipients = R.either( - pathIsString(['recipients', 'to']), - pathIsString(['recipients', 'condition']) -); - -const propValueToSingletonArray = (propName) => - R.compose(R.of, R.prop(propName)); - -const getRecipientList = R.cond([ - [R.has('registrationTokens'), R.prop('registrationTokens')], - [R.has('to'), propValueToSingletonArray('to')], - [R.has('condition'), propValueToSingletonArray('condition')], -]); - -const sendChunk = (GCMSender, recipients, message, retries) => - new Promise((resolve) => { - const recipientList = getRecipientList(recipients); - - GCMSender.send(message, recipients, retries, (err, response) => { - // Response: see https://developers.google.com/cloud-messaging/http-server-ref#table5 - if (err) { - resolve({ - method: GCM_METHOD, - success: 0, - failure: recipientList.length, - message: recipientList.map((value) => ({ - originalRegId: value, - regId: value, - error: err, - errorMsg: err instanceof Error ? err.message : err, - })), - }); - } else if (response && response.results !== undefined) { - let regIndex = 0; - resolve({ - method: GCM_METHOD, - multicastId: response.multicast_id, - success: response.success, - failure: response.failure, - message: response.results.map((value) => { - const regToken = recipientList[regIndex]; - regIndex += 1; - return { - messageId: value.message_id, - originalRegId: regToken, - regId: value.registration_id || regToken, - error: value.error ? new Error(value.error) : null, - errorMsg: value.error ? value.error.message || value.error : null, - }; - }), - }); - } else { - resolve({ - method: GCM_METHOD, - multicastId: response.multicast_id, - success: response.success, - failure: response.failure, - message: recipientList.map((value) => ({ - originalRegId: value, - regId: value, - error: new Error('unknown'), - errorMsg: 'unknown', - })), - }); - } - }); - }); - -const sendGCM = (regIds, data, settings) => { - const opts = { ...settings.gcm }; - const { id } = opts; - delete opts.id; - const GCMSender = new gcm.Sender(id, opts); - const promises = []; - const notification = { - title: data.title, // Android, iOS (Watch) - body: data.body, // Android, iOS - icon: data.icon, // Android - image: data.image, // Android - picture: data.picture, // Android - style: data.style, // Android - sound: data.sound, // Android, iOS - badge: data.badge, // iOS - tag: data.tag, // Android - color: data.color, // Android - click_action: data.clickAction || data.category, // Android, iOS - body_loc_key: data.locKey, // Android, iOS - body_loc_args: data.locArgs, // Android, iOS - title_loc_key: data.titleLocKey, // Android, iOS - title_loc_args: data.titleLocArgs, // Android, iOS - android_channel_id: data.android_channel_id, // Android - notification_count: data.notificationCount || data.badge, // Android - }; - - let custom; - if (typeof data.custom === 'string') { - custom = { - message: data.custom, - }; - } else if (typeof data.custom === 'object') { - custom = { ...data.custom }; - } else { - custom = { - data: data.custom, - }; - } - - custom.title = custom.title || data.title; - custom.message = custom.message || data.body; - custom.sound = custom.sound || data.sound; - custom.icon = custom.icon || data.icon; - custom.msgcnt = custom.msgcnt || data.badge; - if (opts.phonegap === true && data.contentAvailable) { - custom['content-available'] = 1; - } - - const message = new gcm.Message({ - // See https://developers.google.com/cloud-messaging/http-server-ref#table5 - collapseKey: data.collapseKey, - priority: data.priority === 'normal' ? 'normal' : 'high', - contentAvailable: data.silent ? true : data.contentAvailable || false, - delayWhileIdle: data.delayWhileIdle || false, - timeToLive: extractTimeToLive(data), - restrictedPackageName: data.restrictedPackageName, - dryRun: data.dryRun || false, - data: opts.phonegap === true ? Object.assign(custom, notification) : custom, // See https://github.com/phonegap/phonegap-plugin-push/blob/master/docs/PAYLOAD.md#android-behaviour - notification: - opts.phonegap === true || data.silent === true ? undefined : notification, - }); - let chunk = 0; - - /* allow to override device tokens with custom `to` or `condition` field: - * https://github.com/ToothlessGear/node-gcm#recipients */ - if (containsValidRecipients(data)) { - promises.push( - sendChunk(GCMSender, data.recipients, message, data.retries || 0) - ); - } else { - // Split tokens in 1.000 chunks, see https://developers.google.com/cloud-messaging/http-server-ref#table1 - do { - const registrationTokens = regIds.slice(chunk * 1000, (chunk + 1) * 1000); - promises.push( - sendChunk(GCMSender, { registrationTokens }, message, data.retries || 0) - ); - chunk += 1; - } while (1000 * chunk < regIds.length); - } - - return Promise.all(promises).then((results) => { - const resumed = { - method: GCM_METHOD, - multicastId: [], - success: 0, - failure: 0, - message: [], - }; - - results.forEach((result) => { - if (result.multicastId) { - resumed.multicastId.push(result.multicastId); - } - resumed.success += result.success; - resumed.failure += result.failure; - resumed.message.push(...result.message); - }); - - return resumed; - }); -}; - -module.exports = sendGCM; diff --git a/src/sendGCM.ts b/src/sendGCM.ts new file mode 100644 index 0000000..cf0870a --- /dev/null +++ b/src/sendGCM.ts @@ -0,0 +1,204 @@ +import gcm from 'node-gcm'; +import * as R from 'ramda'; +import { DEFAULT_TTL, GCM_MAX_TTL } from './constants'; +import { DefaultSettings, Data, RegIdType } from './types'; + +const ttlFromExpiry = (expiry: number) => { + const subtracted = expiry - Math.floor(Date.now() / 1000); + return Math.min(GCM_MAX_TTL, subtracted); +}; + +const extractTimeToLive = R.cond([ + [R.propIs(Number, 'expiry'), ({ expiry = 0 }) => ttlFromExpiry(expiry)], + [ + R.propIs(Number, 'timeToLive'), + R.pipe(R.prop('timeToLive'), R.defaultTo(DEFAULT_TTL)), + ], + [R.T, R.always(DEFAULT_TTL)], +]); + +// const pathIsString = R.pathSatisfies(R.is(String)); +const pathIsString = (path: (string | number)[]): ((obj: any) => boolean) => { + return (obj: any) => R.pathSatisfies(R.is(String), path, obj); +}; + +const containsValidRecipients = R.either( + pathIsString(['recipients', 'to']), + pathIsString(['recipients', 'condition']) +); + +const propValueToSingletonArray = (propName: string) => + R.compose(R.of, R.prop(propName)); + +const getRecipientList = R.cond([ + [R.has('registrationTokens'), R.prop('registrationTokens')], + [R.has('to'), propValueToSingletonArray('to')], + [R.has('condition'), propValueToSingletonArray('condition')], + [R.T, R.always([])], +]); + +const sendChunk = ( + GCMSender: any, + recipients: any, + message: any, + retries: number +) => + new Promise((resolve) => { + const recipientList = getRecipientList(recipients); + + GCMSender.send( + message, + recipients, + retries, + (err: Error | null, response: any) => { + if (err) { + resolve({ + method: RegIdType.gcm, + success: 0, + failure: recipientList.length, + message: recipientList.map((value: any) => ({ + originalRegId: value, + regId: value, + error: err, + errorMsg: err instanceof Error ? err.message : err, + })), + }); + } else if (response && response.results !== undefined) { + let regIndex = 0; + resolve({ + method: RegIdType.gcm, + multicastId: response.multicast_id, + success: response.success, + failure: response.failure, + message: response.results.map((value: any) => { + const regToken = recipientList[regIndex]; + regIndex += 1; + return { + messageId: value.message_id, + originalRegId: regToken, + regId: value.registration_id || regToken, + error: value.error ? new Error(value.error) : null, + errorMsg: value.error + ? value.error.message || value.error + : null, + }; + }), + }); + } else { + resolve({ + method: RegIdType.gcm, + multicastId: response.multicast_id, + success: response.success, + failure: response.failure, + message: recipientList.map((value: any) => ({ + originalRegId: value, + regId: value, + error: new Error('unknown'), + errorMsg: 'unknown', + })), + }); + } + } + ); + }); + +const sendGCM = async ( + regIds: string[], + data: Data, + settings: DefaultSettings +) => { + const opts = { ...settings.gcm }; + const { id } = opts; + delete opts.id; + const GCMSender = new gcm.Sender(id, opts); + const promises: Promise[] = []; + const notification = { + title: data.title, // Android, iOS (Watch) + body: data.body, // Android, iOS + icon: data.icon, // Android + image: data.image, // Android + picture: data.picture, // Android + style: data.style, // Android + sound: data.sound, // Android, iOS + badge: data.badge, // iOS + tag: data.tag, // Android + color: data.color, // Android + click_action: data.clickAction || data.category, // Android, iOS + body_loc_key: data.locKey, // Android, iOS + body_loc_args: data.locArgs, // Android, iOS + title_loc_key: data.titleLocKey, // Android, iOS + title_loc_args: data.titleLocArgs, // Android, iOS + android_channel_id: data.android_channel_id, // Android + notification_count: data.notificationCount || data.badge, // Android + }; + + let custom: any; + if (typeof data.custom === 'string') { + custom = { + message: data.custom, + }; + } else if (typeof data.custom === 'object') { + custom = { ...data.custom }; + } else { + custom = { + data: data.custom, + }; + } + + custom.title = custom.title || data.title; + custom.message = custom.message || data.body; + custom.sound = custom.sound || data.sound; + custom.icon = custom.icon || data.icon; + custom.msgcnt = custom.msgcnt || data.badge; + if (opts.phonegap === true && data.contentAvailable) { + custom['content-available'] = 1; + } + + const message = new gcm.Message({ + collapseKey: data.collapseKey, + priority: data.priority === 'normal' ? 'normal' : 'high', + contentAvailable: data.silent ? true : data.contentAvailable || false, + delayWhileIdle: data.delayWhileIdle || false, + timeToLive: extractTimeToLive(data), + restrictedPackageName: data.restrictedPackageName, + dryRun: data.dryRun || false, + data: opts.phonegap === true ? Object.assign(custom, notification) : custom, + notification: + opts.phonegap === true || data.silent === true ? undefined : notification, + }); + let chunk = 0; + + if (containsValidRecipients(data)) { + promises.push( + sendChunk(GCMSender, data.recipients, message, data.retries || 0) + ); + } else { + do { + const registrationTokens = regIds.slice(chunk * 1000, (chunk + 1) * 1000); + promises.push( + sendChunk(GCMSender, { registrationTokens }, message, data.retries || 0) + ); + chunk += 1; + } while (1000 * chunk < regIds.length); + } + + const results = await Promise.all(promises); + const resumed: any = { + method: RegIdType.gcm, + multicastId: [], + success: 0, + failure: 0, + message: [], + }; + results.forEach((result) => { + if (result.multicastId) { + resumed.multicastId.push(result.multicastId); + } + resumed.success += result.success; + resumed.failure += result.failure; + resumed.message.push(...result.message); + }); + return resumed; +}; + +export default sendGCM; diff --git a/src/sendWNS.js b/src/sendWNS.ts similarity index 68% rename from src/sendWNS.js rename to src/sendWNS.ts index afcc8f3..1af6cf1 100644 --- a/src/sendWNS.js +++ b/src/sendWNS.ts @@ -1,5 +1,5 @@ -const wns = require('wns'); -const { WNS_METHOD } = require('./constants'); +import wns from 'wns'; +import { Data, DefaultSettings, RegIdType } from './types'; const parseErrorMessage = (err) => (err instanceof Error ? err.message : err); const parseError = (err) => { @@ -27,15 +27,20 @@ function processResponse(err, response, regId) { }); } -const sendWNS = (_regIds, _data, settings) => { - // sendNotifications and sendPromises are inside exports as in this way, - // successive calls to this module doesn't override previous ones +const sendWNS = (_regIds: string[], _data: Data, settings: DefaultSettings) => { let sendPromises; - function sendNotifications(regIds, notificationMethod, data, opts, onFinish) { + function sendNotifications( + regIds: string[], + notificationMethod: string, + data: string | Data, + opts, + onFinish + ) { const regId = regIds.shift(); if (regId) { try { + delete opts.notificationMethod; wns[notificationMethod](regId, data, opts, (err, response) => { sendPromises.push(Promise.resolve()); processResponse(err, response, regId); @@ -56,46 +61,48 @@ const sendWNS = (_regIds, _data, settings) => { } } - const promises = []; + const promises: any[] = []; const opts = { ...settings.wns }; - const { notificationMethod } = opts; + const { notificationMethod = 'send' } = opts; const data = notificationMethod === 'sendRaw' ? JSON.stringify(_data) : { ..._data }; resumed = { - method: WNS_METHOD, + method: RegIdType.wns, success: 0, failure: 0, message: [], }; - opts.headers = data.headers || opts.headers; - opts.launch = data.launch || opts.launch; - opts.duration = data.duration || opts.duration; + opts.headers = + typeof data === 'object' && data.headers ? data.headers : opts.headers; + opts.launch = + typeof data === 'object' && data.launch ? data.launch : opts.launch; + opts.duration = + typeof data === 'object' && data.duration ? data.duration : opts.duration; - delete opts.notificationMethod; - delete data.headers; - delete data.launch; - delete data.duration; + if (typeof data === 'object') { + delete data.headers; + delete data.launch; + delete data.duration; + } if (opts.accessToken) { sendPromises = []; const regIds = [..._regIds]; - // eslint-disable-next-line max-len promises.push( new Promise((resolve, reject) => { sendNotifications(regIds, notificationMethod, data, opts, (err) => - err ? reject(err) : resolve() + err ? reject(err) : resolve(true) ); }) ); } else { - // eslint-disable-next-line max-len _regIds.forEach((regId) => promises.push( new Promise((resolve) => { wns[notificationMethod](regId, data, opts, (err, response) => { processResponse(err, response, regId); - resolve(); + resolve(true); }); }) ) @@ -105,4 +112,4 @@ const sendWNS = (_regIds, _data, settings) => { return Promise.all(promises).then(() => resumed); }; -module.exports = sendWNS; +export default sendWNS; diff --git a/src/sendWeb.js b/src/sendWeb.ts similarity index 60% rename from src/sendWeb.js rename to src/sendWeb.ts index c4220c6..46a634b 100644 --- a/src/sendWeb.js +++ b/src/sendWeb.ts @@ -1,14 +1,23 @@ -const webPush = require('web-push'); -const { is, unless, assoc } = require('ramda'); -const { WEB_METHOD } = require('./constants'); +import webPush from 'web-push'; +import { is, unless, assoc } from 'ramda'; +import { Data, DefaultSettings, RegIdType } from './types'; const stringify = unless(is(String), JSON.stringify); -const sendWebPush = async (regIds, data, settings) => { +const sendWebPush = async ( + regIds: (string | webPush.PushSubscription)[], + data: Data, + settings: DefaultSettings +) => { const payload = stringify(data); const promises = regIds.map((regId) => webPush - .sendNotification(regId, payload, settings.web) + // regId might be a JSON string + .sendNotification( + typeof regId === 'string' ? JSON.parse(regId) : regId, + payload, + settings.web + ) .then(() => ({ success: 1, failure: 0, @@ -39,7 +48,7 @@ const sendWebPush = async (regIds, data, settings) => { failure: acc.failure + current.failure, message: [...acc.message, ...current.message], })); - return assoc('method', WEB_METHOD, reduced); + return assoc('method', RegIdType.web, reduced); }; -module.exports = sendWebPush; +export default sendWebPush; diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..e40a376 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,205 @@ +import apn from '@parse/node-apn'; +import * as webPush from 'web-push'; + +export interface GcmSettings { + id?: string; + phonegap?: boolean; +} + +export interface ApnSettings extends apn.ProviderOptions { + // voip: boolean; // VOIP is in Notification type, not in settings + address?: string; + port?: number; + rejectUnauthorized?: boolean; + connectionRetryLimit?: number; + cacheLength?: number; + connectionTimeout?: number; + autoAdjustCache?: boolean; + maxConnections?: number; + minConnections?: number; + connectTimeout?: number; + buffersNotifications?: boolean; + fastMode?: boolean; + disableNagle?: boolean; + disableEPIPEFix?: boolean; +} + +export interface AdmSettings { + client_id?: string; + client_secret?: string; +} + +export interface WnsSettings { + client_id?: string; + client_secret?: string; + accessToken?: string; + headers?: any; + notificationMethod: string; + launch?: any; + duration?: any; +} + +export interface WebSettings { + vapidDetails: { + subject: string; + publicKey: string; + privateKey: string; + }; + gcmAPIKey?: string; +} + +export interface DefaultSettings { + /** Google Cloud Messaging settings */ + gcm?: GcmSettings; + /** Apple Push Notifications settings */ + apn?: ApnSettings; + /** Amazon Device Messaging settings */ + adm?: AdmSettings; + /** Web Push notifications settings */ + wns?: WnsSettings; + /** Microsoft Push Notification Service settings */ + web?: webPush.RequestOptions; + /** When true FCM will be used in any case except if regId is an object without type or id, in wich case WEB will be used */ + isAlwaysUseFCM?: boolean; +} + +export const APN = 'apn'; +export const GCM = 'gcm'; +export const ADM = 'adm'; +export const WNS = 'wns'; +export const WEB = 'webPush'; +export const UNKNOWN = 'unknown'; + +export enum RegIdType { + apn = APN, + gcm = GCM, + adm = ADM, + wns = WNS, + web = WEB, + unknown = UNKNOWN, +} + +/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription) */ +export interface IPushSubscription { + id?: never; + type?: never; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription/endpoint) */ + endpoint: string; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription/expirationTime) */ + expirationTime?: EpochTimeStamp | null; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription/options) */ + options?: PushSubscriptionOptions | null; + /** @deprecated [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription/options) */ + subscriptionId?: string; +} + +export interface RegIdNodePushNotifications { + id: string; + type: RegIdType; + endpoint?: never; + expirationTime?: never; + options?: never; + subscriptionId?: never; +} + +export type RegId = string | RegIdNodePushNotifications | IPushSubscription; + +export interface Data { + /** REQUIRED */ + title: string; + /** REQUIRED */ + body: string; + custom?: { [key: string]: string | number } | string; + /** + * gcm, apn. Supported values are 'high' or 'normal' (gcm). Will be translated to 10 and 5 for apn. Defaults + * to 'high' + */ + priority?: string; + /** gcm for android, used as collapseId in apn */ + collapseKey?: string; + /** gcm for android */ + contentAvailable?: boolean | string; + /** gcm for android */ + delayWhileIdle?: boolean; + /** gcm for android */ + restrictedPackageName?: string; + /** gcm for android */ + dryRun?: boolean; + /** gcm for android */ + icon?: string; + /** gcm for android */ + tag?: string; + /** gcm for android */ + color?: string; + /** gcm for android. In ios, category will be used if not supplied */ + clickAction?: string; + /** gcm, apn */ + locKey?: string; + /** gcm, apn */ + bodyLocArgs?: string; + /** gcm, apn */ + titleLocKey?: string; + /** gcm, apn */ + titleLocArgs?: string; + /** gcm, apn */ + retries?: number; + // TODO: review + /** gcm recipients */ + recipients?: any[]; + /** gcm silent notification */ + silent?: boolean; + /** gcm Android: image */ + image?: any; + /** gcm Android: picture */ + picture?: any; + /** gcm Android: style */ + style?: any; + /** gcm Android, iOS: locArgs */ + locArgs?: any; + /** gcm Android: android_channel_id */ + android_channel_id?: any; + /** gcm Android: notificationCount if not present will be taken from badge */ + notificationCount?: any; + + /** apn threadId */ + threadId?: any; + /** apn pushType */ + pushType?: any; + + /** apn */ + encoding?: string; + /** gcm for ios, apn */ + badge?: number; + /** gcm, apn */ + sound?: string; + /** apn, will take precedence over title and body. It is also accepted a text message in alert */ + alert?: {} | string; + /** apn and gcm for ios */ + launchImage?: string; + /** apn and gcm for ios */ + action?: string; + /** apn and gcm for ios */ + topic?: string; + /** apn and gcm for ios */ + category?: string; + /** apn and gcm for ios */ + mdm?: string; + /** apn and gcm for ios */ + urlArgs?: string; + /** apn and gcm for ios */ + truncateAtWordEnd?: boolean; + /** apn */ + mutableContent?: number; + /** seconds */ + expiry?: number; + /** if both expiry and timeToLive are given, expiry will take precedency */ + timeToLive?: number; + /** wns */ + headers?: string[]; + /** wns */ + launch?: string; + /** wns */ + duration?: string; + /** ADM */ + consolidationKey?: string; +} diff --git a/src/typesInternal.ts b/src/typesInternal.ts new file mode 100644 index 0000000..0027718 --- /dev/null +++ b/src/typesInternal.ts @@ -0,0 +1,6 @@ +import { RegId, RegIdType } from './types'; + +export interface PushMethod { + regId: RegId; + type: RegIdType; +} diff --git a/test/push-notifications/basic.js b/test/push-notifications/basic.ts similarity index 72% rename from test/push-notifications/basic.js rename to test/push-notifications/basic.ts index 2a6c382..be4fcf1 100644 --- a/test/push-notifications/basic.js +++ b/test/push-notifications/basic.ts @@ -4,36 +4,36 @@ import chai from 'chai'; import dirtyChai from 'dirty-chai'; import sinonChai from 'sinon-chai'; import { spy } from 'sinon'; +import { DEFAULT_SETTINGS } from '../../src/constants'; import PN from '../../src'; import { - UNKNOWN_METHOD, - WEB_METHOD, - WNS_METHOD, - ADM_METHOD, - GCM_METHOD, - APN_METHOD, -} from '../../src/constants'; + DefaultSettings, + RegId, + RegIdNodePushNotifications, + RegIdType, +} from '../../src/types'; -const { expect } = chai; chai.use(dirtyChai); chai.use(sinonChai); +const { expect } = chai; describe('push-notifications: instantiation and class properties', () => { describe('empty options', () => { it('should have send methods and settings options', () => { - const pn = new PN(); + const pn = new PN(DEFAULT_SETTINGS); expect(pn).to.have.property('send'); - expect(pn.settings).to.have.property('gcm'); - expect(pn.settings).to.have.property('apn'); - expect(pn.settings).to.have.property('adm'); - expect(pn.settings).to.have.property('wns'); - expect(pn.settings).to.have.property('web'); + const settings = pn.getOptions(); + expect(settings).to.have.property('gcm'); + expect(settings).to.have.property('apn'); + expect(settings).to.have.property('adm'); + expect(settings).to.have.property('wns'); + expect(settings).to.have.property('web'); }); }); describe('override options with constructor', () => { let pn; - const settings = { + const settings: DefaultSettings = { gcm: { id: 'gcm id', }, @@ -97,7 +97,7 @@ describe('push-notifications: instantiation and class properties', () => { const apnShutdownSpy = spy(); before(() => { - pn = new PN(); + pn = new PN(DEFAULT_SETTINGS); pn.apn.shutdown = apnShutdownSpy; pn.setOptions(settings); }); @@ -110,7 +110,7 @@ describe('push-notifications: instantiation and class properties', () => { }); it('should shutdown any previous APN providers', () => { - expect(apnShutdownSpy).to.have.been.calledOnce(); + expect(apnShutdownSpy).to.have.been.calledOnce(''); }); }); @@ -130,22 +130,20 @@ describe('push-notifications: instantiation and class properties', () => { } }; it('should resolve the promise with an empty result', (done) => { - const pn = new PN(); - pn.send() + const pn = new PN(DEFAULT_SETTINGS); + pn.send([], {}) .then((results) => test(null, results, done)) .catch(done); }); it('should fire callback with an empty result', (done) => { - const pn = new PN(); - pn.send(undefined, undefined, (err, results) => - test(null, results, done) - ); + const pn = new PN(DEFAULT_SETTINGS); + pn.send([], undefined, (err, results) => test(null, results, done)); }); }); describe('check getPushMethodByRegId returns expected push method types', () => { - const regIds = { + const regIds: { [key: string]: RegId } = { androidRegId: 'APA91bFQCD9Ndd8uVggMhj1usfeWsKIfGyBUWMprpZLGciWrMjS-77bIY24IMQNeEHzjidCcddnDxqYo-UEV03xw6ySmtIgQyzTqhSxhPGAi1maf6KDMAQGuUWc6L5Khze8YK9YrL9I_WD1gl49P3f_9hr08ZAS5Tw', androidWithAdmSubstringRegId: @@ -162,52 +160,52 @@ describe('push-notifications: instantiation and class properties', () => { 'amzn1.adm-registration.v2.Y29tLmFtYXpvbi5EZXZpY2VNZXNzYWdpbmcuUmVnaXN0cmF0aW9uSWRFbmNyeXB0aW9uS2V5ITEhOE9rZ2h5TXlhVEFFczg2ejNWL3JMcmhTa255Uk5BclhBbE1XMFZzcnU1aFF6cTlvdU5FbVEwclZmdk5oTFBVRXVDN1luQlRSNnRVRUViREdQSlBvSzRNaXVRRUlyUy9NYWZCYS9VWTJUaGZwb3ZVTHhlRTM0MGhvampBK01hVktsMEhxakdmQStOSXRjUXBTQUhNU1NlVVVUVkFreVRhRTBCYktaQ2ZkUFdqSmIwcHgzRDhMQnllVXdxQ2EwdHNXRmFVNklYL0U4UXovcHg0K3Jjb25VbVFLRUVVOFVabnh4RDhjYmtIcHd1ZThiekorbGtzR2taMG95cC92Y3NtZytrcTRPNjhXUUpiZEk3QzFvQThBRTFWWXM2NHkyMjdYVGV5RlhhMWNHS0k9IW5GNEJMSXNleC9xbWpHSU52NnczY0E9PQ', webRegId: { endpoint: 'https://push.subscription.url', - keys: { - p256dh: 'userPublicEncryptionKey', - auth: 'userAuthSecret', - }, + // keys: { + // p256dh: 'userPublicEncryptionKey', + // auth: 'userAuthSecret', + // }, }, androidObject: { id: 'APA91bFQCD9Ndd8uVggMhj1usfeWsKIfGyBUWMprpZLGciWrMjS-77bIY24IMQNeEHzjidCcddnDxqYo-UEV03xw6ySmtIgQyzTqhSxhPGAi1maf6KDMAQGuUWc6L5Khze8YK9YrL9I_WD1gl49P3f_9hr08ZAS5Tw', - type: 'gcm', + type: RegIdType.gcm, }, androidObjectWhatever: { id: 'whatever', - type: 'gcm', + type: RegIdType.gcm, }, iosObject: { id: '43e798c31a282d129a34d84472bbdd7632562ff0732b58a85a27c5d9fdf59b69', - type: 'apn', + type: RegIdType.apn, }, iosObjectWhatever: { id: 'whatever', - type: 'apn', + type: RegIdType.apn, }, unknownRegId: 'abcdef', }; it('Android / GCM', () => { - let pn = new PN(); + let pn = new PN(DEFAULT_SETTINGS); expect(pn.getPushMethodByRegId(regIds.androidRegId).regId).to.equal( regIds.androidRegId ); - expect(pn.getPushMethodByRegId(regIds.androidRegId).pushMethod).to.equal( - GCM_METHOD + expect(pn.getPushMethodByRegId(regIds.androidRegId).type).to.equal( + RegIdType.gcm ); expect( pn.getPushMethodByRegId(regIds.androidWithAdmSubstringRegId).regId ).to.equal(regIds.androidWithAdmSubstringRegId); expect( - pn.getPushMethodByRegId(regIds.androidWithAdmSubstringRegId).pushMethod - ).to.equal(GCM_METHOD); + pn.getPushMethodByRegId(regIds.androidWithAdmSubstringRegId).type + ).to.equal(RegIdType.gcm); expect( pn.getPushMethodByRegId(regIds.androidWithAmznSubscringRegId).regId ).to.equal(regIds.androidWithAmznSubscringRegId); expect( - pn.getPushMethodByRegId(regIds.androidWithAmznSubscringRegId).pushMethod - ).to.equal(GCM_METHOD); + pn.getPushMethodByRegId(regIds.androidWithAmznSubscringRegId).type + ).to.equal(RegIdType.gcm); const settings = { isAlwaysUseFCM: true, @@ -216,96 +214,98 @@ describe('push-notifications: instantiation and class properties', () => { expect(pn.getPushMethodByRegId(regIds.unknownRegId).regId).to.equal( regIds.unknownRegId ); - expect(pn.getPushMethodByRegId(regIds.unknownRegId).pushMethod).to.equal( - GCM_METHOD + expect(pn.getPushMethodByRegId(regIds.unknownRegId).type).to.equal( + RegIdType.gcm ); expect(pn.getPushMethodByRegId(regIds.androidObject).regId).to.equal( - regIds.androidObject.id + (regIds.androidObject as RegIdNodePushNotifications).id ); - expect(pn.getPushMethodByRegId(regIds.androidObject).pushMethod).to.equal( - GCM_METHOD + expect(pn.getPushMethodByRegId(regIds.androidObject).type).to.equal( + RegIdType.gcm ); expect( pn.getPushMethodByRegId(regIds.androidObjectWhatever).regId - ).to.equal(regIds.androidObjectWhatever.id); + ).to.equal( + (regIds.androidObjectWhatever as RegIdNodePushNotifications).id + ); expect( - pn.getPushMethodByRegId(regIds.androidObjectWhatever).pushMethod - ).to.equal(GCM_METHOD); + pn.getPushMethodByRegId(regIds.androidObjectWhatever).type + ).to.equal(RegIdType.gcm); }); it('iOS / APN', () => { - const pn = new PN(); + const pn = new PN(DEFAULT_SETTINGS); expect(pn.getPushMethodByRegId(regIds.iOSRegId).regId).to.equal( regIds.iOSRegId ); - expect(pn.getPushMethodByRegId(regIds.iOSRegId).pushMethod).to.equal( - APN_METHOD + expect(pn.getPushMethodByRegId(regIds.iOSRegId).type).to.equal( + RegIdType.apn ); expect(pn.getPushMethodByRegId(regIds.iosObject).regId).to.equal( - regIds.iosObject.id + (regIds.iosObject as RegIdNodePushNotifications).id ); - expect(pn.getPushMethodByRegId(regIds.iosObject).pushMethod).to.equal( - APN_METHOD + expect(pn.getPushMethodByRegId(regIds.iosObject).type).to.equal( + RegIdType.apn ); expect(pn.getPushMethodByRegId(regIds.iosObjectWhatever).regId).to.equal( - regIds.iosObjectWhatever.id + (regIds.iosObjectWhatever as RegIdNodePushNotifications).id + ); + expect(pn.getPushMethodByRegId(regIds.iosObjectWhatever).type).to.equal( + RegIdType.apn ); - expect( - pn.getPushMethodByRegId(regIds.iosObjectWhatever).pushMethod - ).to.equal(APN_METHOD); }); it('iOS / APN long', () => { - const pn = new PN(); + const pn = new PN(DEFAULT_SETTINGS); expect(pn.getPushMethodByRegId(regIds.iOSRegIdLong).regId).to.equal( regIds.iOSRegIdLong ); - expect(pn.getPushMethodByRegId(regIds.iOSRegIdLong).pushMethod).to.equal( - APN_METHOD + expect(pn.getPushMethodByRegId(regIds.iOSRegIdLong).type).to.equal( + RegIdType.apn ); }); it('Windows Phone / WNS', () => { - const pn = new PN(); + const pn = new PN(DEFAULT_SETTINGS); expect(pn.getPushMethodByRegId(regIds.windowsPhoneRegId).regId).to.equal( regIds.windowsPhoneRegId ); - expect( - pn.getPushMethodByRegId(regIds.windowsPhoneRegId).pushMethod - ).to.equal(WNS_METHOD); + expect(pn.getPushMethodByRegId(regIds.windowsPhoneRegId).type).to.equal( + RegIdType.wns + ); }); it('Amazon / ADM', () => { - const pn = new PN(); + const pn = new PN(DEFAULT_SETTINGS); expect(pn.getPushMethodByRegId(regIds.amazonRegId).regId).to.equal( regIds.amazonRegId ); - expect(pn.getPushMethodByRegId(regIds.amazonRegId).pushMethod).to.equal( - ADM_METHOD + expect(pn.getPushMethodByRegId(regIds.amazonRegId).type).to.equal( + RegIdType.adm ); }); it('Web / WEB', () => { - const pn = new PN(); + const pn = new PN(DEFAULT_SETTINGS); expect(pn.getPushMethodByRegId(regIds.webRegId).regId).to.equal( regIds.webRegId ); - expect(pn.getPushMethodByRegId(regIds.webRegId).pushMethod).to.equal( - WEB_METHOD + expect(pn.getPushMethodByRegId(regIds.webRegId).type).to.equal( + RegIdType.web ); }); it('Unknown / UNKNOWN', () => { - const pn = new PN(); + const pn = new PN(DEFAULT_SETTINGS); expect(pn.getPushMethodByRegId(regIds.unknownRegId).regId).to.equal( regIds.unknownRegId ); - expect(pn.getPushMethodByRegId(regIds.unknownRegId).pushMethod).to.equal( - UNKNOWN_METHOD + expect(pn.getPushMethodByRegId(regIds.unknownRegId).type).to.equal( + RegIdType.unknown ); }); }); diff --git a/test/push-notifications/regIds.js b/test/push-notifications/regIds.ts similarity index 67% rename from test/push-notifications/regIds.js rename to test/push-notifications/regIds.ts index 589cb08..09f8e2d 100644 --- a/test/push-notifications/regIds.js +++ b/test/push-notifications/regIds.ts @@ -2,7 +2,7 @@ import { expect } from 'chai'; // eslint-disable-line import/no-extraneous-dependencies import sinon from 'sinon'; // eslint-disable-line import/no-extraneous-dependencies -import PN from '../../src'; +import PN, { RegIdType } from '../../src'; import sendGCM from '../../src/sendGCM'; import sendADM from '../../src/sendADM'; import sendWNS from '../../src/sendWNS'; @@ -10,10 +10,43 @@ import sendWeb from '../../src/sendWeb'; const regIds = [ 'APA91bFQCD9Ndd8uVggMhj1usfeWsKIfGyBUWMprpZLGciWrMjS-77bIY24IMQNeEHzjidCcddnDxqYo-UEV03xw6ySmtIgQyzTqhSxhPGAi1maf6KDMAQGuUWc6L5Khze8YK9YrL9I_WD1gl49P3f_9hr08ZAS5Tw', // android + { + id: 'APA91bFQCD9Ndd8uVggMhj1usfeWsKIfGyBUWMprpZLGciWrMjS-77bIY24IMQNeEHzjidCcddnDxqYo-UEV03xw6ySmtIgQyzTqhSxhPGAi1maf6KDMAQGuUWc6L5Khze8YK9YrL9I_WD1gl49P3f_9hr08ZAS5Tw', + }, // android + { + id: 'APA91bFQCD9Ndd8uVggMhj1usfeWsKIfGyBUWMprpZLGciWrMjS-77bIY24IMQNeEHzjidCcddnDxqYo-UEV03xw6ySmtIgQyzTqhSxhPGAi1maf6KDMAQGuUWc6L5Khze8YK9YrL9I_WD1gl49P3f_9hr08ZAS5Tw', + type: RegIdType.gcm, + }, // android 'APA9admQCD9Ndd8uVggMhj1usfeWsKIfGyBUWMprpZLGciWrMjS-77bIY24IMQNeEHzjidCcddnDxqYo-UEV03xw6ySmtIgQyzTqhSxhPGAi1maf6KDMAQGuUWc6L5Khze8YK9YrL9I_WD1gl49P3f_9hr08ZAS5Tw', // android with adm substring + { + id: 'APA9admQCD9Ndd8uVggMhj1usfeWsKIfGyBUWMprpZLGciWrMjS-77bIY24IMQNeEHzjidCcddnDxqYo-UEV03xw6ySmtIgQyzTqhSxhPGAi1maf6KDMAQGuUWc6L5Khze8YK9YrL9I_WD1gl49P3f_9hr08ZAS5Tw', + }, // android with adm substring + { + id: 'APA9admQCD9Ndd8uVggMhj1usfeWsKIfGyBUWMprpZLGciWrMjS-77bIY24IMQNeEHzjidCcddnDxqYo-UEV03xw6ySmtIgQyzTqhSxhPGAi1maf6KDMAQGuUWc6L5Khze8YK9YrL9I_WD1gl49P3f_9hr08ZAS5Tw', + type: RegIdType.gcm, + }, // android with adm substring 'amzn1mQCD9Ndd8uVggMhj1usfeWsKIfGyBUWMprpZLGciWrMjS-77bIY24IMQNeEHzjidCcddnDxqYo-UEV03xw6ySmtIgQyzTqhSxhPGAi1maf6KDMAQGuUWc6L5Khze8YK9YrL9I_WD1gl49P3f_9hr08ZAS5Tw', // android with anzm start + { + id: 'amzn1mQCD9Ndd8uVggMhj1usfeWsKIfGyBUWMprpZLGciWrMjS-77bIY24IMQNeEHzjidCcddnDxqYo-UEV03xw6ySmtIgQyzTqhSxhPGAi1maf6KDMAQGuUWc6L5Khze8YK9YrL9I_WD1gl49P3f_9hr08ZAS5Tw', + }, // android with anzm start + { + id: 'amzn1mQCD9Ndd8uVggMhj1usfeWsKIfGyBUWMprpZLGciWrMjS-77bIY24IMQNeEHzjidCcddnDxqYo-UEV03xw6ySmtIgQyzTqhSxhPGAi1maf6KDMAQGuUWc6L5Khze8YK9YrL9I_WD1gl49P3f_9hr08ZAS5Tw', + type: RegIdType.gcm, + }, // android with anzm start '43e798c31a282d129a34d84472bbdd7632562ff0732b58a85a27c5d9fdf59b69', // ios + { id: '43e798c31a282d129a34d84472bbdd7632562ff0732b58a85a27c5d9fdf59b69' }, // ios + { + id: '43e798c31a282d129a34d84472bbdd7632562ff0732b58a85a27c5d9fdf59b69', + type: RegIdType.apn, + }, // ios '80C2D3913EE662DD25C5A3B7FCC8CBBADCA9DA429D13F106F37BF8EA268AFC610824D1B378D6E5FAFA86C63A63FDADA7A9067E1B0BC461E4020346199000D26418F38E73E32174D69F69DC35BEA27CE5', // ios + { + id: '80C2D3913EE662DD25C5A3B7FCC8CBBADCA9DA429D13F106F37BF8EA268AFC610824D1B378D6E5FAFA86C63A63FDADA7A9067E1B0BC461E4020346199000D26418F38E73E32174D69F69DC35BEA27CE5', + }, // ios + { + id: '80C2D3913EE662DD25C5A3B7FCC8CBBADCA9DA429D13F106F37BF8EA268AFC610824D1B378D6E5FAFA86C63A63FDADA7A9067E1B0BC461E4020346199000D26418F38E73E32174D69F69DC35BEA27CE5', + type: RegIdType.apn, + }, // ios 'https://db5.notify.windows.com/?token=AwYAAAD8sfbDrL9h7mN%2bmwlkSkQZCIfv4QKeu1hYRipj2zNvXaMi9ZAax%2f6CDfysyHp61STCO1pCFPt%2b9L4Jod72JhIcjDr8b2GxuUOBMTP%2b6%2bqxEfSB9iZfSATdZbdF7cJHSRA%3d', // windows phone 'amzn1.adm-registration.v2.Y29tLmFtYXpvbi5EZXZpY2VNZXNzYWdpbmcuUmVnaXN0cmF0aW9uSWRFbmNyeXB0aW9uS2V5ITEhOE9rZ2h5TXlhVEFFczg2ejNWL3JMcmhTa255Uk5BclhBbE1XMFZzcnU1aFF6cTlvdU5FbVEwclZmdk5oTFBVRXVDN1luQlRSNnRVRUViREdQSlBvSzRNaXVRRUlyUy9NYWZCYS9VWTJUaGZwb3ZVTHhlRTM0MGhvampBK01hVktsMEhxakdmQStOSXRjUXBTQUhNU1NlVVVUVkFreVRhRTBCYktaQ2ZkUFdqSmIwcHgzRDhMQnllVXdxQ2EwdHNXRmFVNklYL0U4UXovcHg0K3Jjb25VbVFLRUVVOFVabnh4RDhjYmtIcHd1ZThiekorbGtzR2taMG95cC92Y3NtZytrcTRPNjhXUUpiZEk3QzFvQThBRTFWWXM2NHkyMjdYVGV5RlhhMWNHS0k9IW5GNEJMSXNleC9xbWpHSU52NnczY0E9PQ', // amazon { @@ -24,6 +57,7 @@ const regIds = [ }, }, // web 'abcdef', // unknown + { id: 'abcdef' }, // unknown ]; const data = { title: 'title', @@ -31,17 +65,16 @@ const data = { }; describe('push-notifications: call with registration ids for android, ios, windows phone and amazon', () => { - let pn; + let pn: any; let sendWith; before(() => { - pn = new PN(); + pn = new PN({}); const sendApnFunctionName = pn.apn.sendAPN.bind(pn.apn).name; - sendWith = sinon.stub( - PN.prototype, - 'sendWith', - (method, _regIds, _data, cb) => { + sendWith = sinon + .stub(PN.prototype, 'sendWith') + .callsFake((method, _regIds, _data, cb) => { const result = { method: method.name, success: 1, @@ -52,23 +85,33 @@ describe('push-notifications: call with registration ids for android, ios, windo case 0: case 1: case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: expect(method).to.equal(sendGCM); break; - case 3: - case 4: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: expect(method.name).to.equal(sendApnFunctionName); break; - case 5: + case 15: expect(method).to.equal(sendWNS); break; - case 6: + case 16: expect(method).to.equal(sendADM); break; - case 7: + case 17: expect(method).to.equal(sendWeb); break; @@ -80,12 +123,11 @@ describe('push-notifications: call with registration ids for android, ios, windo ); break; } - expect(data).to.equal(data); + expect(data).to.equal(_data); _regIds.forEach((regId) => expect(regIds).to.include(regId)); expect(cb).to.equal(undefined); return Promise.resolve(result); - } - ); + }); }); after(() => { @@ -93,14 +135,14 @@ describe('push-notifications: call with registration ids for android, ios, windo }); const assertPushResults = (result, expectedNumRegIds) => { - if (result.method !== 'unknown') { + if (result.method !== RegIdType.unknown) { expect(result.success).to.equal(1); expect(result.failure).to.equal(0); } else { - expect(result.method).to.equal('unknown'); + expect(result.method).to.equal(RegIdType.unknown); expect(result.success).to.equal(0); - expect(result.failure).to.equal(1); - expect(result.message.length).to.equal(1); + expect(result.failure).to.equal(expectedNumRegIds); + expect(result.message.length).to.equal(expectedNumRegIds); expect(result.message[0]).to.have.property('error'); expect(result.message[0].error).to.be.instanceOf(Error); expect(result.message[0].error.message).to.equal( @@ -116,8 +158,17 @@ describe('push-notifications: call with registration ids for android, ios, windo const assertPushResultsForArrayInput = (result) => { let expectedNumRegIds = 1; if (result.method === 'sendGCM') { - expectedNumRegIds = 3; + expectedNumRegIds = 9; } else if (result.method === 'bound sendAPN') { + expectedNumRegIds = 6; + } else if (result.method === 'sendWebPush') { + // TODO: test case where { id: { endpoint: '...', ...}, type: RegIdType.web } + // TODO: test case where { id: JSON.stringify({ endpoint: '...', ...}), type: RegIdType.web } + expectedNumRegIds = 1; + } else if (result.method === 'unknown') { + // unknown + // TODO: test case where { id: 'abc' } + // TODO: test case where { id: 'abc', type: RegIdType.gcm } expectedNumRegIds = 2; } assertPushResults(result, expectedNumRegIds); @@ -131,6 +182,7 @@ describe('push-notifications: call with registration ids for android, ios, windo pn.send(regIds, data, (err, results) => { try { expect(err).to.equal(null); + // results.forEach(r => console.log(r)); results.forEach(assertPushResultsForArrayInput); done(err); } catch (e) { @@ -149,20 +201,20 @@ describe('push-notifications: call with registration ids for android, ios, windo }); it('should call the correct method for each registration id (string) and should resolve with results (callback)', (done) => { - const promises = []; - regIds.forEach((regId) => { + const promises: any[] = []; + regIds.forEach((regId) => promises.push( pn.send(regId, data, (err, results) => { expect(err).to.equal(null); results.forEach(assertPushResultsForStringInput); }) - ); - }); + ) + ); Promise.all(promises).then(() => done(), done); }); it('should call the correct method for each registration id (string) and should resolve with results (promise)', (done) => { - const promises = []; + const promises: any[] = []; regIds.forEach((regId) => { promises.push( pn.send(regId, data).then((results) => { @@ -179,8 +231,8 @@ describe('push-notifications: error while sending push notifications', () => { let pn; let sendWith; beforeEach(() => { - pn = new PN(); - sendWith = sinon.stub(PN.prototype, 'sendWith', () => { + pn = new PN({}); + sendWith = sinon.stub(PN.prototype, 'sendWith').callsFake(() => { throw fErr; }); }); diff --git a/test/send/sendADM.js b/test/send/sendADM.ts similarity index 93% rename from test/send/sendADM.js rename to test/send/sendADM.ts index c39939b..7019715 100644 --- a/test/send/sendADM.js +++ b/test/send/sendADM.ts @@ -42,10 +42,9 @@ let sendMethod; function sendOkMethod() { // Don't use arrow function because we use this!! - return sinon.stub( - adm.Sender.prototype, - 'send', - function sedADM(message, regId, cb) { + return sinon + .stub(adm.Sender.prototype, 'send') + .callsFake(function sedADM(message, regId, cb) { expect(this.options) .to.be.an('object') .includes.keys(['client_id', 'client_secret']); @@ -58,26 +57,29 @@ function sendOkMethod() { expect(message.data.body).to.eql(data.body); expect(message.data.sender).to.eql(data.custom.sender); cb(null, {}); - } - ); + }); } function sendFailureMethod() { - return sinon.stub(adm.Sender.prototype, 'send', (message, regId, cb) => { - cb(null, { - error: fErr.message, + return sinon + .stub(adm.Sender.prototype, 'send') + .callsFake((message, regId, cb) => { + cb(null, { + error: fErr.message, + }); }); - }); } function sendErrorMethod() { - return sinon.stub(adm.Sender.prototype, 'send', (message, regId, cb) => { - cb(fErr); - }); + return sinon + .stub(adm.Sender.prototype, 'send') + .callsFake((message, regId, cb) => { + cb(fErr); + }); } function sendThrowExceptionMethod() { - return sinon.stub(adm.Sender.prototype, 'send', () => { + return sinon.stub(adm.Sender.prototype, 'send').callsFake(() => { throw fErr; }); } diff --git a/test/send/sendAPN.js b/test/send/sendAPN.ts similarity index 70% rename from test/send/sendAPN.js rename to test/send/sendAPN.ts index c152f94..d4b74e3 100644 --- a/test/send/sendAPN.js +++ b/test/send/sendAPN.ts @@ -7,7 +7,7 @@ import dirtyChai from 'dirty-chai'; import { readFileSync } from 'fs'; import apn from '@parse/node-apn'; -import PN from '../../src'; +import PN, { Data } from '../../src'; import APN from '../../src/sendAPN'; import { sendOkMethodGCM, @@ -26,7 +26,7 @@ const regIds = [ '43e798c31a282d129a34d84472bbdd7632562ff0732b58a85a27c5d9fdf59b69', '43e798c31a282d129a34d84472bbdd7632562ff0732b58a85a27c5d9fdf59b69', ]; -const data = { +const data: Data = { title: 'title', body: 'body', sound: 'mySound.aiff', @@ -54,10 +54,9 @@ let sendMethod; function sendOkMethod() { // Don't use arrow function because we use this!! - return sinon.stub( - apn.Provider.prototype, - 'send', - function sendAPN(message, _regIds) { + return sinon + .stub(apn.Provider.prototype, 'send') + .callsFake(function sendAPN(message, _regIds) { // TODO: validate other props? What about token? expect(this.client.config) .to.be.an('object') @@ -66,11 +65,13 @@ function sendOkMethod() { expect(this.client.config.key).to.eql(readFileSync(apnOptions.key)); expect(_regIds).to.be.instanceOf(Array); - _regIds.forEach((regId) => expect(regIds).to.include(regId)); + (_regIds as string[]).forEach((regId) => + expect(regIds).to.include(regId) + ); expect(message).to.be.instanceOf(apn.Notification); expect(message.aps.sound).to.eql(data.sound); - expect(message.aps.alert.title).to.eql(data.title); - expect(message.aps.alert.body).to.equal(data.body); + expect((message.aps.alert as apn.ApsAlert).title).to.eql(data.title); + expect((message.aps.alert as apn.ApsAlert).body).to.equal(data.body); expect(message.aps.alert).to.eql({ body: data.body, title: data.title, @@ -84,49 +85,59 @@ function sendOkMethod() { expect(message.priority).to.equal(10); expect(message.payload).to.eql(data.custom); return Promise.resolve({ - sent: _regIds.map((device) => ({ device })), + sent: (_regIds as string[]).map((device) => ({ device })), + failed: [], }); - } - ); + }); } function sendFailureMethod1() { - return sinon.stub(apn.Provider.prototype, 'send', (message, _regIds) => - Promise.resolve({ - failed: _regIds.map((regId) => ({ - device: regId, - response: {}, - status: errStatusCode, - })), - }) - ); + return sinon + .stub(apn.Provider.prototype, 'send') + .callsFake((_message, _regIds) => + Promise.resolve({ + sent: [], + failed: (_regIds as string[]).map((regId) => ({ + device: regId, + error: new Error(`${errStatusCode}`), + })), + }) + ); } function sendFailureMethod2() { - return sinon.stub(apn.Provider.prototype, 'send', (message, _regIds) => - Promise.resolve({ - failed: _regIds.map((regId) => ({ - device: regId, - response: { - reason: fErr.message, - }, - })), - }) - ); + return sinon + .stub(apn.Provider.prototype, 'send') + .callsFake((_message, _regIds) => + Promise.resolve({ + sent: [], + failed: (_regIds as string[]).map((regId) => ({ + device: regId, + response: { + reason: fErr.message, + }, + })), + }) + ); } function sendErrorMethod() { - return sinon.stub(apn.Provider.prototype, 'send', (message, _regIds) => - Promise.resolve({ - failed: _regIds.map((regId) => ({ - device: regId, - error: fErr, - })), - }) - ); + return sinon + .stub(apn.Provider.prototype, 'send') + .callsFake((message, _regIds) => + Promise.resolve({ + sent: [], + failed: (_regIds as string[]).map((regId) => ({ + device: regId, + error: fErr, + })), + }) + ); } function sendThrowExceptionMethod() { - return sinon.stub(apn.Provider.prototype, 'send', () => Promise.reject(fErr)); + return sinon + .stub(apn.Provider.prototype, 'send') + .callsFake(() => Promise.reject(fErr)); } describe('push-notifications-apn', () => { @@ -152,21 +163,22 @@ describe('push-notifications-apn', () => { describe('send push notifications successfully (no payload)', () => { before(() => { - sendMethod = sinon.stub( - apn.Provider.prototype, - 'send', - (message, _regIds) => { + sendMethod = sinon + .stub(apn.Provider.prototype, 'send') + .callsFake((message, _regIds) => { expect(_regIds).to.be.instanceOf(Array); - _regIds.forEach((regId) => expect(regIds).to.include(regId)); + (_regIds as string[]).forEach((regId) => + expect(regIds).to.include(regId) + ); expect(message).to.be.instanceOf(apn.Notification); - expect(message.aps.alert.title).to.eql(data.title); - expect(message.aps.alert.body).to.eql(data.body); + expect((message.aps.alert as apn.ApsAlert).title).to.eql(data.title); + expect((message.aps.alert as apn.ApsAlert).body).to.eql(data.body); expect(message.payload).to.eql({}); return Promise.resolve({ - sent: _regIds, + sent: (_regIds as string[]).map((device) => ({ device })), + failed: [], }); - } - ); + }); }); after(() => { @@ -185,12 +197,13 @@ describe('push-notifications-apn', () => { describe('send silent push notifications', () => { before(() => { - sendMethod = sinon.stub( - apn.Provider.prototype, - 'send', - (message, _regIds) => { + sendMethod = sinon + .stub(apn.Provider.prototype, 'send') + .callsFake((message, _regIds) => { expect(_regIds).to.be.instanceOf(Array); - _regIds.forEach((regId) => expect(regIds).to.include(regId)); + (_regIds as string[]).forEach((regId) => + expect(regIds).to.include(regId) + ); expect(message).to.be.instanceOf(apn.Notification); expect(message.aps.sound).to.be.undefined(); expect(message.aps.alert).to.be.undefined(); @@ -200,10 +213,10 @@ describe('push-notifications-apn', () => { expect(message.aps['content-available']).to.equal(1); expect(message.payload).to.eql({ testKey: 'testValue' }); return Promise.resolve({ - sent: _regIds, + sent: (_regIds as string[]).map((device) => ({ device })), + failed: [], }); - } - ); + }); }); after(() => { @@ -231,19 +244,20 @@ describe('push-notifications-apn', () => { describe('send notifications with mutableContent=1', () => { before(() => { - sendMethod = sinon.stub( - apn.Provider.prototype, - 'send', - (message, _regIds) => { + sendMethod = sinon + .stub(apn.Provider.prototype, 'send') + .callsFake((message, _regIds) => { expect(_regIds).to.be.instanceOf(Array); - _regIds.forEach((regId) => expect(regIds).to.include(regId)); + (_regIds as string[]).forEach((regId) => + expect(regIds).to.include(regId) + ); expect(message).to.be.instanceOf(apn.Notification); expect(message.aps['mutable-content']).to.equal(1); return Promise.resolve({ - sent: _regIds, + sent: (_regIds as string[]).map((device) => ({ device })), + failed: [], }); - } - ); + }); }); after(() => { @@ -263,19 +277,20 @@ describe('push-notifications-apn', () => { describe('send notifications with pushType property', () => { before(() => { - sendMethod = sinon.stub( - apn.Provider.prototype, - 'send', - (message, _regIds) => { + sendMethod = sinon + .stub(apn.Provider.prototype, 'send') + .callsFake((message, _regIds) => { expect(_regIds).to.be.instanceOf(Array); - _regIds.forEach((regId) => expect(regIds).to.include(regId)); + (_regIds as string[]).forEach((regId) => + expect(regIds).to.include(regId) + ); expect(message).to.be.instanceOf(apn.Notification); expect(message.pushType).to.equal('alert'); return Promise.resolve({ - sent: _regIds, + sent: (_regIds as string[]).map((device) => ({ device })), + failed: [], }); - } - ); + }); }); after(() => { @@ -295,19 +310,20 @@ describe('push-notifications-apn', () => { describe('send push notifications with normal priority', () => { before(() => { - sendMethod = sinon.stub( - apn.Provider.prototype, - 'send', - (message, _regIds) => { + sendMethod = sinon + .stub(apn.Provider.prototype, 'send') + .callsFake((message, _regIds) => { expect(_regIds).to.be.instanceOf(Array); - _regIds.forEach((regId) => expect(regIds).to.include(regId)); + (_regIds as string[]).forEach((regId) => + expect(regIds).to.include(regId) + ); expect(message).to.be.instanceOf(apn.Notification); expect(message).to.have.deep.property('priority', 5); return Promise.resolve({ - sent: _regIds, + sent: (_regIds as string[]).map((device) => ({ device })), + failed: [], }); - } - ); + }); }); after(() => { @@ -327,19 +343,20 @@ describe('push-notifications-apn', () => { const expiry = 104; before(() => { - sendMethod = sinon.stub( - apn.Provider.prototype, - 'send', - (message, _regIds) => { + sendMethod = sinon + .stub(apn.Provider.prototype, 'send') + .callsFake((message, _regIds) => { expect(_regIds).to.be.instanceOf(Array); - _regIds.forEach((regId) => expect(regIds).to.include(regId)); + (_regIds as string[]).forEach((regId) => + expect(regIds).to.include(regId) + ); expect(message).to.be.instanceOf(apn.Notification); expect(message).to.have.deep.property('expiry', expiry); return Promise.resolve({ - sent: _regIds, + sent: (_regIds as string[]).map((device) => ({ device })), + failed: [], }); - } - ); + }); }); after(() => { @@ -358,19 +375,20 @@ describe('push-notifications-apn', () => { const expiry = 0; before(() => { - sendMethod = sinon.stub( - apn.Provider.prototype, - 'send', - (message, _regIds) => { + sendMethod = sinon + .stub(apn.Provider.prototype, 'send') + .callsFake((message, _regIds) => { expect(_regIds).to.be.instanceOf(Array); - _regIds.forEach((regId) => expect(regIds).to.include(regId)); + (_regIds as string[]).forEach((regId) => + expect(regIds).to.include(regId) + ); expect(message).to.be.instanceOf(apn.Notification); expect(message).to.have.deep.property('expiry', expiry); return Promise.resolve({ - sent: _regIds, + sent: (_regIds as string[]).map((device) => ({ device })), + failed: [], }); - } - ); + }); }); after(() => { @@ -395,19 +413,20 @@ describe('push-notifications-apn', () => { clock = sinon.useFakeTimers(now); - sendMethod = sinon.stub( - apn.Provider.prototype, - 'send', - (message, _regIds) => { + sendMethod = sinon + .stub(apn.Provider.prototype, 'send') + .callsFake((message, _regIds) => { expect(_regIds).to.be.instanceOf(Array); - _regIds.forEach((regId) => expect(regIds).to.include(regId)); + (_regIds as string[]).forEach((regId) => + expect(regIds).to.include(regId) + ); expect(message).to.be.instanceOf(apn.Notification); expect(message).to.have.deep.property('expiry', expectedExpiry); return Promise.resolve({ - sent: _regIds, + sent: (_regIds as string[]).map((device) => ({ device })), + failed: [], }); - } - ); + }); }); after(() => { @@ -432,22 +451,23 @@ describe('push-notifications-apn', () => { clock = sinon.useFakeTimers(now); - sendMethod = sinon.stub( - apn.Provider.prototype, - 'send', - (message, _regIds) => { + sendMethod = sinon + .stub(apn.Provider.prototype, 'send') + .callsFake((message, _regIds) => { expect(_regIds).to.be.instanceOf(Array); - _regIds.forEach((regId) => expect(regIds).to.include(regId)); + (_regIds as string[]).forEach((regId) => + expect(regIds).to.include(regId) + ); expect(message).to.be.instanceOf(apn.Notification); expect(message).to.have.deep.property( 'expiry', expiryFromDefaultTtl ); return Promise.resolve({ - sent: _regIds, + sent: (_regIds as string[]).map((device) => ({ device })), + failed: [], }); - } - ); + }); }); after(() => { @@ -466,22 +486,25 @@ describe('push-notifications-apn', () => { describe('parse title-loc-args and loc-args', () => { describe('when valid string args are passed in alert object', () => { before(() => { - sendMethod = sinon.stub( - apn.Provider.prototype, - 'send', - (message, _regIds) => { + sendMethod = sinon + .stub(apn.Provider.prototype, 'send') + .callsFake((message, _regIds) => { expect(_regIds).to.be.instanceOf(Array); - _regIds.forEach((regId) => expect(regIds).to.include(regId)); + (_regIds as string[]).forEach((regId) => + expect(regIds).to.include(regId) + ); expect(message).to.be.instanceOf(apn.Notification); - expect(message.aps.alert['title-loc-args']).to.deep.equal([ - { a: 1 }, - ]); - expect(message.aps.alert['loc-args']).to.deep.equal([{ b: 2 }]); + expect( + (message.aps.alert as apn.ApsAlert)['title-loc-args'] + ).to.deep.equal([{ a: 1 }]); + expect( + (message.aps.alert as apn.ApsAlert)['loc-args'] + ).to.deep.equal([{ b: 2 }]); return Promise.resolve({ - sent: _regIds, + sent: (_regIds as string[]).map((device) => ({ device })), + failed: [], }); - } - ); + }); }); after(() => { @@ -504,22 +527,25 @@ describe('push-notifications-apn', () => { describe('when valid string args are passed in top-level data', () => { before(() => { - sendMethod = sinon.stub( - apn.Provider.prototype, - 'send', - (message, _regIds) => { + sendMethod = sinon + .stub(apn.Provider.prototype, 'send') + .callsFake((message, _regIds) => { expect(_regIds).to.be.instanceOf(Array); - _regIds.forEach((regId) => expect(regIds).to.include(regId)); + (_regIds as string[]).forEach((regId) => + expect(regIds).to.include(regId) + ); expect(message).to.be.instanceOf(apn.Notification); - expect(message.aps.alert['title-loc-args']).to.deep.equal([ - { a: 1 }, - ]); - expect(message.aps.alert['loc-args']).to.deep.equal([{ b: 2 }]); + expect( + (message.aps.alert as apn.ApsAlert)['title-loc-args'] + ).to.deep.equal([{ a: 1 }]); + expect( + (message.aps.alert as apn.ApsAlert)['loc-args'] + ).to.deep.equal([{ b: 2 }]); return Promise.resolve({ - sent: _regIds, + sent: (_regIds as string[]).map((device) => ({ device })), + failed: [], }); - } - ); + }); }); after(() => { @@ -540,20 +566,25 @@ describe('push-notifications-apn', () => { describe("when args can't be parsed to JSON", () => { before(() => { - sendMethod = sinon.stub( - apn.Provider.prototype, - 'send', - (message, _regIds) => { + sendMethod = sinon + .stub(apn.Provider.prototype, 'send') + .callsFake((message, _regIds) => { expect(_regIds).to.be.instanceOf(Array); - _regIds.forEach((regId) => expect(regIds).to.include(regId)); + (_regIds as string[]).forEach((regId) => + expect(regIds).to.include(regId) + ); expect(message).to.be.instanceOf(apn.Notification); - expect(message.aps.alert['title-loc-args']).to.be.undefined(); - expect(message.aps.alert['loc-args']).to.be.undefined(); + expect( + (message.aps.alert as apn.ApsAlert)['title-loc-args'] + ).to.be.undefined(); + expect( + (message.aps.alert as apn.ApsAlert)['loc-args'] + ).to.be.undefined(); return Promise.resolve({ - sent: _regIds, + sent: (_regIds as string[]).map((device) => ({ device })), + failed: [], }); - } - ); + }); }); after(() => { @@ -677,10 +708,10 @@ describe('push-notifications-apn', () => { }); describe('invalid provider settings', () => { - const apnInstance = new APN(); + const apnInstance = new APN({}); it('should not instantiate an APN provider instance', () => { - expect(apnInstance.connection).to.be.null(); + expect((apnInstance).connectionn).to.be.undefined(); }); describe('send called if no provider instantiated', () => { @@ -691,7 +722,7 @@ describe('push-notifications-apn', () => { } catch (e) { expect(e).to.be.an.instanceof(Error); expect(e.message).to.equal( - "ENOENT: no such file or directory, open 'cert.pem'" + "Error: ENOENT: no such file or directory, open 'cert.pem'" ); } }); diff --git a/test/send/sendGCM.js b/test/send/sendGCM.ts similarity index 91% rename from test/send/sendGCM.js rename to test/send/sendGCM.ts index 1c6e3aa..72f4a0d 100644 --- a/test/send/sendGCM.js +++ b/test/send/sendGCM.ts @@ -49,10 +49,9 @@ let sendMethod; function sendFailureMethod1() { // Don't use arrow function because we use this!! - return sinon.stub( - gcm.Sender.prototype, - 'send', - function SenderSend(message, recipients, retries, cb) { + return sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake(function SenderSend(message, recipients, retries, cb) { const { registrationTokens } = recipients; expect(this.key).equal(gcmOpts.gcm.id); cb(null, { @@ -65,36 +64,31 @@ function sendFailureMethod1() { error: fErr.message, })), }); - } - ); + }); } function sendFailureMethod2() { - return sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + return sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { cb(null, { multicast_id: 'abc', success: 0, failure: regIds.length, }); - } - ); + }); } function sendErrorMethod() { - return sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + return sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { cb(fErr); - } - ); + }); } function sendThrowExceptionMethod() { - return sinon.stub(gcm.Sender.prototype, 'send', () => { + return sinon.stub(gcm.Sender.prototype, 'send').callsFake(() => { throw fErr; }); } @@ -122,10 +116,9 @@ describe('push-notifications-gcm', () => { describe('send push notifications successfully, data no title', () => { before(() => { - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('registrationTokens'); const { registrationTokens } = recipients; @@ -154,8 +147,7 @@ describe('push-notifications-gcm', () => { error: null, })), }); - } - ); + }); }); after(() => { @@ -163,7 +155,7 @@ describe('push-notifications-gcm', () => { }); it('all responses should be successful (callback, no title)', (done) => { - const newData = { ...data }; + const newData: any = { ...data }; delete newData.title; const callback = (err, results) => testSuccess(err, results, done); pn.send(regIds, newData, callback).catch(() => {}); @@ -172,10 +164,9 @@ describe('push-notifications-gcm', () => { describe('send push notifications successfully, (callback, no sound, icon, msgcnt, badge)', () => { before(() => { - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('registrationTokens'); const { registrationTokens } = recipients; @@ -208,8 +199,7 @@ describe('push-notifications-gcm', () => { error: null, })), }); - } - ); + }); }); after(() => { @@ -217,7 +207,7 @@ describe('push-notifications-gcm', () => { }); it('all responses should be successful (callback, no sound, icon, msgcnt)', (done) => { - const newData = { ...data }; + const newData: any = { ...data }; delete newData.sound; newData.icon = 'myicon.png'; newData.custom.msgcnt = 2; @@ -228,10 +218,9 @@ describe('push-notifications-gcm', () => { describe('send push notifications successfully, (callback, no contentAvailable, notificationCount)', () => { before(() => { - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('registrationTokens'); const { registrationTokens } = recipients; @@ -261,8 +250,7 @@ describe('push-notifications-gcm', () => { error: null, })), }); - } - ); + }); }); after(() => { @@ -270,7 +258,7 @@ describe('push-notifications-gcm', () => { }); it('all responses should be successful (callback, no contentAvailable)', (done) => { - const newData = { ...data }; + const newData: any = { ...data }; delete newData.contentAvailable; delete newData.badge; newData.notificationCount = 42; @@ -281,10 +269,9 @@ describe('push-notifications-gcm', () => { describe('send push notifications successfully, data no body', () => { before(() => { - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('registrationTokens'); const { registrationTokens } = recipients; @@ -313,8 +300,7 @@ describe('push-notifications-gcm', () => { error: null, })), }); - } - ); + }); }); after(() => { @@ -322,7 +308,7 @@ describe('push-notifications-gcm', () => { }); it('all responses should be successful (callback, no body)', (done) => { - const newData = { ...data }; + const newData: any = { ...data }; delete newData.body; const callback = (err, results) => testSuccess(err, results, done); pn.send(regIds, newData, callback).catch(() => {}); @@ -331,10 +317,9 @@ describe('push-notifications-gcm', () => { describe('send push notifications successfully, custom data string', () => { before(() => { - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('registrationTokens'); const { registrationTokens } = recipients; @@ -363,8 +348,7 @@ describe('push-notifications-gcm', () => { error: null, })), }); - } - ); + }); }); after(() => { @@ -381,10 +365,9 @@ describe('push-notifications-gcm', () => { describe('send push notifications successfully, custom data undefined', () => { before(() => { - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('registrationTokens'); const { registrationTokens } = recipients; @@ -413,8 +396,7 @@ describe('push-notifications-gcm', () => { error: null, })), }); - } - ); + }); }); after(() => { @@ -422,7 +404,7 @@ describe('push-notifications-gcm', () => { }); it('all responses should be successful (callback, custom data undefined)', (done) => { - const newData = { ...data }; + const newData: any = { ...data }; delete newData.custom; pn.send(regIds, newData, (err, results) => testSuccess(err, results, done) @@ -432,10 +414,9 @@ describe('push-notifications-gcm', () => { describe('send push notifications successfully, normal priority', () => { before(() => { - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('registrationTokens'); const { registrationTokens } = recipients; @@ -456,8 +437,7 @@ describe('push-notifications-gcm', () => { error: null, })), }); - } - ); + }); }); after(() => { @@ -465,7 +445,7 @@ describe('push-notifications-gcm', () => { }); it('all responses should be successful (callback, custom data undefined)', (done) => { - const normalPrioData = { ...data }; + const normalPrioData: any = { ...data }; normalPrioData.priority = 'normal'; pn.send(regIds, normalPrioData, (err, results) => testSuccess(err, results, done) @@ -478,10 +458,9 @@ describe('push-notifications-gcm', () => { const timeToLive = 4004; before(() => { - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('registrationTokens'); const { registrationTokens } = recipients; @@ -500,8 +479,7 @@ describe('push-notifications-gcm', () => { error: null, })), }); - } - ); + }); }); after(() => { @@ -520,10 +498,9 @@ describe('push-notifications-gcm', () => { const ttl = 0; before(() => { - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('registrationTokens'); const { registrationTokens } = recipients; @@ -542,8 +519,7 @@ describe('push-notifications-gcm', () => { error: null, })), }); - } - ); + }); }); after(() => { @@ -567,10 +543,9 @@ describe('push-notifications-gcm', () => { clock = sinon.useFakeTimers(now); - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('registrationTokens'); const { registrationTokens } = recipients; @@ -589,8 +564,7 @@ describe('push-notifications-gcm', () => { error: null, })), }); - } - ); + }); }); after(() => { @@ -613,10 +587,9 @@ describe('push-notifications-gcm', () => { before(() => { clock = sinon.useFakeTimers(now); - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('registrationTokens'); const { registrationTokens } = recipients; @@ -635,8 +608,7 @@ describe('push-notifications-gcm', () => { error: null, })), }); - } - ); + }); }); after(() => { @@ -654,10 +626,9 @@ describe('push-notifications-gcm', () => { describe('send push notifications with neither expiry nor timeToLive given', () => { before(() => { - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('registrationTokens'); const { registrationTokens } = recipients; @@ -676,8 +647,7 @@ describe('push-notifications-gcm', () => { error: null, })), }); - } - ); + }); }); after(() => { @@ -694,10 +664,9 @@ describe('push-notifications-gcm', () => { describe('send silent push notifications', () => { before(() => { - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('registrationTokens'); const { registrationTokens } = recipients; @@ -725,8 +694,7 @@ describe('push-notifications-gcm', () => { error: null, })), }); - } - ); + }); }); after(() => { @@ -749,10 +717,9 @@ describe('push-notifications-gcm', () => { describe('include Android-specific fields, such as channel id, image, style etc.', () => { before(() => { - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('registrationTokens'); const { registrationTokens } = recipients; @@ -780,8 +747,7 @@ describe('push-notifications-gcm', () => { error: null, })), }); - } - ); + }); }); after(() => { @@ -809,10 +775,9 @@ describe('push-notifications-gcm', () => { }); before(() => { - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('registrationTokens'); const { registrationTokens } = recipients; @@ -838,8 +803,7 @@ describe('push-notifications-gcm', () => { error: null, })), }); - } - ); + }); }); after(() => { @@ -866,10 +830,9 @@ describe('push-notifications-gcm', () => { const testSuccessRecipientTo = testPushSuccess(method, [recipient]); before(() => { - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('to'); expect(recipients).to.not.have.property('registrationTokens'); @@ -898,8 +861,7 @@ describe('push-notifications-gcm', () => { }, ], }); - } - ); + }); }); after(() => { @@ -928,10 +890,9 @@ describe('push-notifications-gcm', () => { const testSuccessRecipientCondition = testPushSuccess(method, [recipient]); before(() => { - sendMethod = sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sendMethod = sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('condition'); expect(recipients).to.not.have.property('registrationTokens'); @@ -960,8 +921,7 @@ describe('push-notifications-gcm', () => { }, ], }); - } - ); + }); }); after(() => { diff --git a/test/send/sendWEB.js b/test/send/sendWEB.ts similarity index 79% rename from test/send/sendWEB.js rename to test/send/sendWEB.ts index 58830d5..66f8b2d 100644 --- a/test/send/sendWEB.js +++ b/test/send/sendWEB.ts @@ -49,7 +49,7 @@ const pushError = new webpush.WebPushError( 400, {}, 'errorBody', - {} + '{}' ); const testSuccess = testPushSuccess(method, regIds); @@ -59,43 +59,49 @@ const testException = testPushException(pushError.message); let sendMethod; function sendOkMethodAsString() { - return sinon.stub(webpush, 'sendNotification', (regId, message, settings) => { - expect(regId).to.be.a('object'); - expect(regIds).to.include(regId); - expect(message).to.be.a('string'); - expect(message).to.equal(data); - expect(settings).to.eql(webOptions.web); - return Promise.resolve({ - statusCode: 200, - header: {}, - body: 'Success', + return sinon + .stub(webpush, 'sendNotification') + .callsFake((regId, message, settings) => { + expect(regId).to.be.a('object'); + expect(regIds).to.include(regId); + expect(message).to.be.a('string'); + expect(message).to.equal(data); + expect(settings).to.eql(webOptions.web); + return Promise.resolve({ + statusCode: 200, + header: {}, + body: 'Success', + headers: {}, + }); }); - }); } function sendOkMethodAsObject() { - return sinon.stub(webpush, 'sendNotification', (regId, message, settings) => { - expect(regId).to.be.a('object'); - expect(regIds).to.include(regId); - expect(message).to.be.a('string'); - expect(message).to.equal(JSON.stringify(dataObject)); - expect(settings).to.eql(webOptions.web); - return Promise.resolve({ - statusCode: 200, - header: {}, - body: 'Success', + return sinon + .stub(webpush, 'sendNotification') + .callsFake((regId, message, settings) => { + expect(regId).to.be.a('object'); + expect(regIds).to.include(regId); + expect(message).to.be.a('string'); + expect(message).to.equal(JSON.stringify(dataObject)); + expect(settings).to.eql(webOptions.web); + return Promise.resolve({ + statusCode: 200, + header: {}, + body: 'Success', + headers: {}, + }); }); - }); } function sendFailureMethod() { - return sinon.stub(webpush, 'sendNotification', () => - Promise.reject(pushError) - ); + return sinon + .stub(webpush, 'sendNotification') + .callsFake(() => Promise.reject(pushError)); } function sendThrowExceptionMethod() { - return sinon.stub(webpush, 'sendNotification', () => { + return sinon.stub(webpush, 'sendNotification').callsFake(() => { throw pushError; }); } diff --git a/test/send/sendWNS-accessToken.js b/test/send/sendWNS-accessToken.ts similarity index 95% rename from test/send/sendWNS-accessToken.js rename to test/send/sendWNS-accessToken.ts index a9c0d44..a31ac0c 100644 --- a/test/send/sendWNS-accessToken.js +++ b/test/send/sendWNS-accessToken.ts @@ -101,10 +101,9 @@ let i = 0; function sendOkMethod() { wnsMethods.forEach((wnsMethod) => { - sendWNS[wnsMethod] = sinon.stub( - wns, - wnsMethod, - (channel, message, options, cb) => { + sendWNS[wnsMethod] = sinon + .stub(wns, wnsMethod) + .callsFake((channel, message, options, cb) => { expect(options) .to.be.an('object') .includes.keys(['client_id', 'client_secret', 'accessToken']); @@ -122,33 +121,30 @@ function sendOkMethod() { cb(null, { newAccessToken: `${i}`, }); - } - ); + }); }); return sendWNS; } function sendFailureMethod() { wnsMethods.forEach((wnsMethod) => { - sendWNS[wnsMethod] = sinon.stub( - wns, - wnsMethod, - (channel, message, options, cb) => { + sendWNS[wnsMethod] = sinon + .stub(wns, wnsMethod) + .callsFake((channel, message, options, cb) => { expect(options.accessToken).to.equal(`${i}`); i += 1; cb(null, { innerError: fErr.message, newAccessToken: `${i}`, }); - } - ); + }); }); return sendWNS; } function sendThrowExceptionMethod() { wnsMethods.forEach((wnsMethod) => { - sendWNS[wnsMethod] = sinon.stub(wns, wnsMethod, () => { + sendWNS[wnsMethod] = sinon.stub(wns, wnsMethod).callsFake(() => { throw fErr; }); }); diff --git a/test/send/sendWNS.js b/test/send/sendWNS.ts similarity index 87% rename from test/send/sendWNS.js rename to test/send/sendWNS.ts index 6dfe5b2..5dbbe8d 100644 --- a/test/send/sendWNS.js +++ b/test/send/sendWNS.ts @@ -72,11 +72,12 @@ const wnsSendTileMethods = [ 'sendTileWidePeekImage05', 'sendTileWidePeekImage06', ]; -const pn = new PN({ +const options = { wns: { notificationMethod: 'sendTileSquareBlock', }, -}); +}; +const pn = new PN(options); const fErr = new Error('Forced error'); const sendWNS = { restore: () => { @@ -84,6 +85,7 @@ const sendWNS = { sendWNS[wnsMethod].restore(); }); }, + sendRaw: () => {}, }; const testSuccess = testPushSuccess(method, regIds); @@ -95,10 +97,9 @@ let sendMethod; function sendOkMethod() { wnsSendTileMethods.forEach((wnsMethod) => { - sendWNS[wnsMethod] = sinon.stub( - wns, - wnsMethod, - (channel, message, options, cb) => { + sendWNS[wnsMethod] = sinon + .stub(wns, wnsMethod) + .callsFake((channel, message, options, cb) => { expect(channel).to.be.a('string'); expect(regIds).to.include(channel); expect(message).to.be.an('object'); @@ -106,43 +107,38 @@ function sendOkMethod() { expect(message).to.have.deep.property('body', data.body); expect(message).to.have.deep.property('custom', data.custom); cb(null, {}); - } - ); + }); }); return sendWNS; } function sendFailureMethod() { wnsSendTileMethods.forEach((wnsMethod) => { - sendWNS[wnsMethod] = sinon.stub( - wns, - wnsMethod, - (channel, message, options, cb) => { + sendWNS[wnsMethod] = sinon + .stub(wns, wnsMethod) + .callsFake((channel, message, options, cb) => { cb(null, { innerError: fErr.message, }); - } - ); + }); }); return sendWNS; } function sendErrorMethod() { wnsSendTileMethods.forEach((wnsMethod) => { - sendWNS[wnsMethod] = sinon.stub( - wns, - wnsMethod, - (channel, message, options, cb) => { + sendWNS[wnsMethod] = sinon + .stub(wns, wnsMethod) + .callsFake((channel, message, options, cb) => { cb(fErr); - } - ); + }); }); return sendWNS; } function sendThrowExceptionMethod() { wnsSendTileMethods.forEach((wnsMethod) => { - sendWNS[wnsMethod] = sinon.stub(wns, wnsMethod, () => { + sendWNS[wnsMethod] = sinon.stub(wns, wnsMethod).callsFake(() => { throw fErr; }); }); @@ -171,24 +167,38 @@ describe('push-notifications-wns', () => { describe('sendRaw', () => { before(() => { - sendWNS.sendRaw = sinon.stub( - wns, - 'sendRaw', - (channel, message, options, cb) => { + sendWNS.sendRaw = sinon + .stub(wns, 'sendRaw') + .callsFake((channel, message, options, cb) => { expect(channel).to.be.a('string'); expect(regIds).to.include(channel); expect(message).to.be.a('string'); expect(message).to.equal(JSON.stringify(data)); cb(null, {}); - } - ); + }); sendMethod = sendWNS; - pn.settings.wns.notificationMethod = 'sendRaw'; + pn.setOptions({ + ...options, + ...{ + wns: { + ...options.wns, + notificationMethod: 'sendRaw', + }, + }, + }); }); after(() => { sendMethod.restore(); - pn.settings.wns.notificationMethod = 'sendTileSquareBlock'; + pn.setOptions({ + ...options, + ...{ + wns: { + ...options.wns, + notificationMethod: 'sendTileSquareBlock', + }, + }, + }); }); it('should send the correct payload as a raw string', (done) => { diff --git a/test/util.js b/test/util.ts similarity index 96% rename from test/util.js rename to test/util.ts index a3c60e6..02a89f9 100644 --- a/test/util.js +++ b/test/util.ts @@ -62,10 +62,9 @@ export const testPushException = (errMessage) => (err, results, done) => { }; export const sendOkMethodGCM = (regIds, data) => - sinon.stub( - gcm.Sender.prototype, - 'send', - (message, recipients, retries, cb) => { + sinon + .stub(gcm.Sender.prototype, 'send') + .callsFake((message, recipients, retries, cb) => { expect(recipients).to.be.instanceOf(Object); expect(recipients).to.have.property('registrationTokens'); const { registrationTokens } = recipients; @@ -93,5 +92,4 @@ export const sendOkMethodGCM = (regIds, data) => error: null, })), }); - } - ); + }); diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 0000000..1b9dcc9 --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,16 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "declaration": false, + "module": "commonjs", + "moduleResolution": "node", + "resolveJsonModule": true, + "esModuleInterop": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "target": "es6", + "typeRoots": ["node_modules/@types"], + "lib": ["es2018", "dom"] + } +}