diff --git a/.eslintrc.json b/.eslintrc.json index 3d61b294..378eefdf 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -19,7 +19,7 @@ }, "parser": "@typescript-eslint/parser", "parserOptions": { - "ecmaVersion": 2017, + "ecmaVersion": 2020, "project": [ "./tsconfig.json" ] diff --git a/.evergreen/config.yml b/.evergreen/config.yml index 9e0233af..002b2715 100644 --- a/.evergreen/config.yml +++ b/.evergreen/config.yml @@ -122,17 +122,16 @@ tasks: - func: run tests vars: TEST_TARGET: node - # TODO(NODE-3555): Karma tests pass locally still after these changes, rhel80 is just missing chrome - # - name: browser-tests - # tags: ["browser"] - # commands: - # - func: fetch source - # vars: - # NODE_MAJOR_VERSION: 16 - # - func: install dependencies - # - func: run tests - # vars: - # TEST_TARGET: browser + - name: web-tests + tags: ["web"] + commands: + - func: fetch source + vars: + NODE_MAJOR_VERSION: 18 + - func: install dependencies + - func: run tests + vars: + TEST_TARGET: web - name: run-checks tags: - run-checks @@ -177,7 +176,7 @@ buildvariants: - name: linux display_name: RHEL 8.0 run_on: rhel80-small - tasks: [".node"] + tasks: [".node", ".web"] - name: lint display_name: lint run_on: rhel80-small diff --git a/.evergreen/run-tests.sh b/.evergreen/run-tests.sh index da420fd1..5434280e 100755 --- a/.evergreen/run-tests.sh +++ b/.evergreen/run-tests.sh @@ -15,9 +15,9 @@ case $1 in "node") npm run check:coverage ;; - "browser") - # TODO(NODE-3555): remove explicit browser tests - npm run test-browser + "web") + export WEB="true" + npm run check:web ;; *) npm test diff --git a/.mocharc.json b/.mocharc.json index 9898bb9b..8aaf4437 100644 --- a/.mocharc.json +++ b/.mocharc.json @@ -2,8 +2,7 @@ "$schema": "https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/mocharc.json", "require": [ "source-map-support/register", - "ts-node/register", - "./node_modules/chai/register-expect" + "ts-node/register" ], "extension": [ "js", diff --git a/.nycrc.json b/.nycrc.json index e6c7eaad..3d7f20bc 100644 --- a/.nycrc.json +++ b/.nycrc.json @@ -1,12 +1,15 @@ { "extends": "@istanbuljs/nyc-config-typescript", + "include": [ + "src/**/*" + ], "reporter": [ "lcovonly", "text-summary", "html" ], - "statements": 53, - "branches": 38, - "functions": 52, - "lines": 54 + "statements": 81, + "branches": 73, + "functions": 74, + "lines": 83 } diff --git a/docs/upgrade-to-v5.md b/docs/upgrade-to-v5.md new file mode 100644 index 00000000..02e90efe --- /dev/null +++ b/docs/upgrade-to-v5.md @@ -0,0 +1,46 @@ +# Changes in v5 + +## About + +The following is a detailed collection of the changes in the major v5 release of the bson package +for nodejs and web platforms. + + + +### Remove reliance on Node.js Buffer + +> **TL;DR**: Web environments return Uint8Array; Node.js environments return Buffer + +For those that use the BSON library on Node.js, there is no change - the BSON APIs will still return and accept instances of Node.js Buffer. Since we no longer depend on the Buffer web shim for compatibility with browsers, in non-Node.js environments a Uint8Array will be returned instead. + +This allows the BSON library to be better at platform independence while keeping its behavior consistent cross platform. The Buffer shim served the library well but brought in more than was necessary for the concerns of the code here. + +### `ObjectId.toString` / `UUID.toString` / `Binary.toString` + +> **TL;DR**: These `toString` methods only support the following encodings: 'hex', 'base64', 'utf8' + +The methods: `ObjectId.toString`, `UUID.toString`, and `Binary.toString` took encodings that were passed through to the Node.js Buffer API. As a result of no longer relying on the presence of `Buffer` we can no longer support [every encoding that Node.js does](https://nodejs.org/dist/latest-v16.x/docs/api/buffer.html#buffers-and-character-encodings). We continue to support `'hex'` and `'base64'` on all three methods and additionally `'utf-8' | 'utf8'` on `Binary.toString`. If any of the other encodings are desired the underlying buffer for all these classes are publicly accessible and while in Node.js will be stored as a Node.js buffer: + +##### Migration Example: + +```typescript +// Given Binary constructed from one of the encodings (using 'utf16le' as an example here) +// no longer supported directly by the Binary.toString method +const bin = new Binary(Buffer.from('abc', 'utf16le'), 0); +// To obtain the original translation of bytes to string +// We can access the underlying buffer and on Node.js it will be an instanceof Buffer +// so it will support the translation to the specified encoding. +bin.value(true).toString('utf16le'); +// In web environments (and Node.js) the same can be accomplished with TextDecoder +new TextDecoder('utf-16le').decode(bin.value(true)); +``` + +### `serializeFunctions` bug fix + +> **TL;DR**: TODO + +TODO(NODE-4771): serializeFunctions bug fix makes function names outside the ascii range get serialized correctly diff --git a/karma.conf.js b/karma.conf.js deleted file mode 100644 index 2962f947..00000000 --- a/karma.conf.js +++ /dev/null @@ -1,91 +0,0 @@ -const { scenariosPlugin } = require('./tools/scenarios-plugin'); -const commonjs = require('@rollup/plugin-commonjs'); -const { nodeResolve } = require('@rollup/plugin-node-resolve'); -const nodeGlobals = require('rollup-plugin-node-globals'); -const nodePolyfills = require('rollup-plugin-node-polyfills'); -const jsonPlugin = require('@rollup/plugin-json'); - -module.exports = function (config) { - config.set({ - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: '', - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['mocha', 'chai'], - - // list of files / patterns to load in the browser - files: [{ pattern: 'test/node/!(bson_node_only_tests).js', watched: false }], - - // list of files / patterns to exclude - exclude: ['src/**/*.ts'], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - 'test/node/!(bson_node_only_tests).js': ['rollup'] - }, - - rollupPreprocessor: { - plugins: [ - scenariosPlugin(), - nodeResolve({ - preferBuiltins: false - }), - commonjs(), - nodePolyfills(), - nodeGlobals(), - jsonPlugin() - ], - output: { - format: 'iife', - name: 'BSONtest', - sourcemap: 'inline', - exports: 'named' - }, - onwarn(warning) { - if (warning.code === 'CIRCULAR_DEPENDENCY') return; - console.warn(warning.toString()); - } - }, - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ['mocha'], - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: false, - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - browsers: ['ChromeHeadlessNoSandbox'], - customLaunchers: { - ChromeHeadlessNoSandbox: { - base: 'ChromeHeadless', - flags: ['--no-sandbox'] - } - }, - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: true, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: 1, - - // Console log print outs will be prefaced with `LOG:` for grep - client: { captureConsole: true } - }); -}; diff --git a/package-lock.json b/package-lock.json index 2c1c927e..075d3b2c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,46 +8,35 @@ "name": "bson", "version": "4.7.0", "license": "Apache-2.0", - "dependencies": { - "buffer": "^5.6.0" - }, "devDependencies": { "@babel/plugin-external-helpers": "^7.18.6", "@babel/preset-env": "^7.19.4", "@istanbuljs/nyc-config-typescript": "^1.0.2", - "@microsoft/api-extractor": "^7.33.4", - "@rollup/plugin-babel": "^6.0.0", - "@rollup/plugin-commonjs": "^23.0.0", - "@rollup/plugin-json": "^5.0.0", - "@rollup/plugin-node-resolve": "^15.0.0", - "@rollup/plugin-replace": "^5.0.0", - "@rollup/plugin-typescript": "^9.0.1", - "@types/node": "^18.11.2", - "@typescript-eslint/eslint-plugin": "^5.40.1", - "@typescript-eslint/parser": "^5.40.1", + "@microsoft/api-extractor": "^7.33.5", + "@rollup/plugin-babel": "^6.0.2", + "@rollup/plugin-commonjs": "^23.0.2", + "@rollup/plugin-json": "^5.0.1", + "@rollup/plugin-node-resolve": "^15.0.1", + "@rollup/plugin-replace": "^5.0.1", + "@rollup/plugin-typescript": "^9.0.2", + "@types/chai": "^4.3.3", + "@types/mocha": "^10.0.0", + "@types/node": "^18.11.6", + "@typescript-eslint/eslint-plugin": "^5.41.0", + "@typescript-eslint/parser": "^5.41.0", "benchmark": "^2.1.4", "chai": "^4.3.6", "chalk": "^5.1.2", - "eslint": "^8.25.0", + "eslint": "^8.26.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-tsdoc": "^0.2.17", - "karma": "^6.4.1", - "karma-chai": "^0.1.0", - "karma-chrome-launcher": "^3.1.1", - "karma-mocha": "^2.0.1", - "karma-mocha-reporter": "^2.2.5", - "karma-rollup-preprocessor": "^7.0.8", "mocha": "10.1.0", "node-fetch": "^3.2.10", "nyc": "^15.1.0", "prettier": "^2.7.1", "rimraf": "^3.0.2", "rollup": "^3.2.3", - "rollup-plugin-commonjs": "^10.1.0", - "rollup-plugin-node-globals": "^1.4.0", - "rollup-plugin-node-polyfills": "^0.2.1", - "rollup-plugin-polyfill-node": "^0.10.2", "source-map-support": "^0.5.21", "standard-version": "^9.5.0", "ts-node": "^10.9.1", @@ -1743,15 +1732,6 @@ "node": ">=6.9.0" } }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, "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", @@ -2034,13 +2014,13 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.33.4", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.33.4.tgz", - "integrity": "sha512-uZG4CHxVcQNpXBC77GwHaKFwGI9vAnzORY4fFN5JuTnQQDKS0vi4BazP4pmYYwbb8IdH4ocQSwOA3j9Ul/sWmg==", + "version": "7.33.5", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.33.5.tgz", + "integrity": "sha512-ENoWpTWarKNuodpRFDQr3jyBigHuv98KuJ8H5qXc1LZ1aP5Mk77lCo88HbPisTmSnGevJJHTScfd/DPznOb4CQ==", "dev": true, "dependencies": { - "@microsoft/api-extractor-model": "7.25.1", - "@microsoft/tsdoc": "0.14.1", + "@microsoft/api-extractor-model": "7.25.2", + "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", "@rushstack/node-core-library": "3.53.2", "@rushstack/rig-package": "0.3.17", @@ -2057,12 +2037,12 @@ } }, "node_modules/@microsoft/api-extractor-model": { - "version": "7.25.1", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.25.1.tgz", - "integrity": "sha512-AaZ0ohCGLRjWiZviM+0p/DaxgMhbawS183LW2+CSqyEBh6wZks7NjoyhzhibAYapS4omnrmv96+0V/2wBvnIZQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.25.2.tgz", + "integrity": "sha512-+h1uCrLQXFAKMUdghhdDcnniDB+6UA/lS9ArlB4QZQ34UbLuXNy2oQ6fafFK8cKXU4mUPTF/yGRjv7JKD5L7eg==", "dev": true, "dependencies": { - "@microsoft/tsdoc": "0.14.1", + "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", "@rushstack/node-core-library": "3.53.2" } @@ -2083,9 +2063,9 @@ } }, "node_modules/@microsoft/tsdoc": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.1.tgz", - "integrity": "sha512-6Wci+Tp3CgPt/B9B0a3J4s3yMgLNSku6w5TV6mN+61C71UqsRBv2FUibBf3tPGlNxebgPHMEUzKpb1ggE8KCKw==", + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", + "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", "dev": true }, "node_modules/@microsoft/tsdoc-config": { @@ -2100,12 +2080,6 @@ "resolve": "~1.19.0" } }, - "node_modules/@microsoft/tsdoc-config/node_modules/@microsoft/tsdoc": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", - "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", - "dev": true - }, "node_modules/@microsoft/tsdoc-config/node_modules/resolve": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", @@ -2192,18 +2166,6 @@ "node": ">=10" } }, - "node_modules/@npmcli/move-file/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@rollup/plugin-babel": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.2.tgz", @@ -2462,12 +2424,6 @@ "string-argv": "~0.3.1" } }, - "node_modules/@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", - "dev": true - }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -2513,16 +2469,10 @@ "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", "dev": true }, - "node_modules/@types/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", - "dev": true - }, - "node_modules/@types/cors": { - "version": "2.8.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", + "node_modules/@types/chai": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", "dev": true }, "node_modules/@types/eslint": { @@ -2553,10 +2503,16 @@ "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", "dev": true }, + "node_modules/@types/mocha": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.0.tgz", + "integrity": "sha512-rADY+HtTOA52l9VZWtgQfn4p+UDVM2eDVkMZT1I6syp0YKxW2F9v+0pbRZLsvskhQv/vMb6ZfCay81GHbz5SHg==", + "dev": true + }, "node_modules/@types/node": { - "version": "18.11.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.5.tgz", - "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==", + "version": "18.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.6.tgz", + "integrity": "sha512-j3CEDa2vd96K0AXF8Wur7UucACvnjkk8hYyQAHhUNciabZLDl9nfAEVUSwmh245OOZV15bRA3Y590Gi5jUcDJg==", "dev": true }, "node_modules/@types/normalize-package-data": { @@ -2870,19 +2826,6 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/acorn": { "version": "8.8.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", @@ -2945,15 +2888,6 @@ "node": ">= 8.0.0" } }, - "node_modules/agentkeepalive/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -3186,34 +3120,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "dev": true, - "engines": { - "node": "^4.5.0 || >= 5.9" - } - }, "node_modules/benchmark": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", @@ -3233,45 +3139,6 @@ "node": ">=8" } }, - "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3328,35 +3195,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-es6": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/buffer-es6/-/buffer-es6-4.9.3.tgz", - "integrity": "sha512-Ibt+oXxhmeYJSsCkODPqNpPmyegefiD8rfutH1NYGhMZQhSp95Rz7haemgnJ6dxa6LT+JLLbtgOMORRluwKktw==", - "dev": true - }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -3375,15 +3213,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/cacache": { "version": "15.3.0", "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", @@ -3433,18 +3262,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/cacache/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/cacache/node_modules/p-map": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", @@ -3475,19 +3292,6 @@ "node": ">=8" } }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -3726,51 +3530,12 @@ "typedarray": "^0.0.6" } }, - "node_modules/connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/connect/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/connect/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "dev": true }, - "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/conventional-changelog": { "version": "3.1.25", "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz", @@ -4029,15 +3794,6 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true }, - "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/core-js-compat": { "version": "3.26.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.0.tgz", @@ -4057,19 +3813,6 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -4090,12 +3833,6 @@ "node": ">= 8" } }, - "node_modules/custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", - "dev": true - }, "node_modules/dargs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", @@ -4114,15 +3851,6 @@ "node": ">= 12" } }, - "node_modules/date-format": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", - "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -4132,12 +3860,6 @@ "node": "*" } }, - "node_modules/debounce": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", - "dev": true - }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -4235,22 +3957,12 @@ "dev": true }, "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">= 0.6" } }, "node_modules/detect-indent": { @@ -4283,12 +3995,6 @@ "node": ">=8" } }, - "node_modules/di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", - "dev": true - }, "node_modules/diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -4322,18 +4028,6 @@ "node": ">=6.0.0" } }, - "node_modules/dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", - "dev": true, - "dependencies": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -4420,12 +4114,6 @@ "node": ">=4" } }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true - }, "node_modules/electron-to-chromium": { "version": "1.4.284", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", @@ -4438,15 +4126,6 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/encoding": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", @@ -4457,55 +4136,6 @@ "iconv-lite": "^0.6.2" } }, - "node_modules/encoding/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/engine.io": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.0.tgz", - "integrity": "sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg==", - "dev": true, - "dependencies": { - "@types/cookie": "^0.4.1", - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.4.1", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.0.3", - "ws": "~8.2.3" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/engine.io-parser": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", - "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", - "dev": true - }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -4545,12 +4175,6 @@ "node": ">=6" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true - }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -4669,22 +4293,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/eslint-formatter-pretty/node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/eslint-formatter-pretty/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4728,12 +4336,6 @@ "@microsoft/tsdoc-config": "0.16.2" } }, - "node_modules/eslint-plugin-tsdoc/node_modules/@microsoft/tsdoc": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", - "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", - "dev": true - }, "node_modules/eslint-rule-docs": { "version": "1.1.235", "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.235.tgz", @@ -4962,18 +4564,6 @@ "node": ">=0.10.0" } }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5106,51 +4696,6 @@ "node": ">=8" } }, - "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/finalhandler/node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", @@ -5212,26 +4757,6 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "node_modules/foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -5376,20 +4901,6 @@ "node": "*" } }, - "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -5658,18 +5169,6 @@ "node": ">=8" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -5725,45 +5224,6 @@ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", "dev": true }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-errors/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/http-proxy-agent": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", @@ -5801,36 +5261,18 @@ } }, "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "optional": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", @@ -6115,18 +5557,6 @@ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true }, - "node_modules/isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true, - "engines": { - "node": ">= 8.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -6372,226 +5802,6 @@ "node": "*" } }, - "node_modules/karma": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz", - "integrity": "sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA==", - "dev": true, - "dependencies": { - "@colors/colors": "1.5.0", - "body-parser": "^1.19.0", - "braces": "^3.0.2", - "chokidar": "^3.5.1", - "connect": "^3.7.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.1", - "glob": "^7.1.7", - "graceful-fs": "^4.2.6", - "http-proxy": "^1.18.1", - "isbinaryfile": "^4.0.8", - "lodash": "^4.17.21", - "log4js": "^6.4.1", - "mime": "^2.5.2", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.5", - "qjobs": "^1.2.0", - "range-parser": "^1.2.1", - "rimraf": "^3.0.2", - "socket.io": "^4.4.1", - "source-map": "^0.6.1", - "tmp": "^0.2.1", - "ua-parser-js": "^0.7.30", - "yargs": "^16.1.1" - }, - "bin": { - "karma": "bin/karma" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/karma-chai": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/karma-chai/-/karma-chai-0.1.0.tgz", - "integrity": "sha512-mqKCkHwzPMhgTYca10S90aCEX9+HjVjjrBFAsw36Zj7BlQNbokXXCAe6Ji04VUMsxcY5RLP7YphpfO06XOubdg==", - "dev": true, - "peerDependencies": { - "chai": "*", - "karma": ">=0.10.9" - } - }, - "node_modules/karma-chrome-launcher": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz", - "integrity": "sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ==", - "dev": true, - "dependencies": { - "which": "^1.2.1" - } - }, - "node_modules/karma-chrome-launcher/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/karma-mocha": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-2.0.1.tgz", - "integrity": "sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.3" - } - }, - "node_modules/karma-mocha-reporter": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz", - "integrity": "sha512-Hr6nhkIp0GIJJrvzY8JFeHpQZNseuIakGac4bpw8K1+5F0tLb6l7uvXRa8mt2Z+NVwYgCct4QAfp2R2QP6o00w==", - "dev": true, - "dependencies": { - "chalk": "^2.1.0", - "log-symbols": "^2.1.0", - "strip-ansi": "^4.0.0" - }, - "peerDependencies": { - "karma": ">=0.13" - } - }, - "node_modules/karma-mocha-reporter/node_modules/ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/karma-mocha-reporter/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/karma-mocha-reporter/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/karma-mocha-reporter/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/karma-mocha-reporter/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/karma-mocha-reporter/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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/karma-mocha-reporter/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/karma-mocha-reporter/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/karma-mocha-reporter/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/karma-rollup-preprocessor": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/karma-rollup-preprocessor/-/karma-rollup-preprocessor-7.0.8.tgz", - "integrity": "sha512-WiuBCS9qsatJuR17dghiTARBZ7LF+ml+eb7qJXhw7IbsdY0lTWELDRQC/93J9i6636CsAXVBL3VJF4WtaFLZzA==", - "dev": true, - "dependencies": { - "chokidar": "^3.3.1", - "debounce": "^1.2.0" - }, - "engines": { - "node": ">= 8.0.0" - }, - "peerDependencies": { - "rollup": ">= 1.0.0" - } - }, - "node_modules/karma/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -6711,102 +5921,47 @@ "dev": true }, "node_modules/log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "dependencies": { - "chalk": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "engines": { - "node": ">=4" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "node": ">=10" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/log-symbols/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/log-symbols/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/log-symbols/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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/log4js": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.7.0.tgz", - "integrity": "sha512-KA0W9ffgNBLDj6fZCq/lRbgR6ABAodRIDHrZnS48vOtfKa4PzWImb0Md1lmGCdO3n3sbCm/n1/WmrNlZ8kCI3Q==", + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "flatted": "^3.2.7", - "rfdc": "^1.3.0", - "streamroller": "^3.1.3" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=8.0" + "node": ">=8" } }, "node_modules/loupe": { @@ -6902,15 +6057,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/meow": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", @@ -7117,39 +6263,6 @@ "node": ">=8.6" } }, - "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -7285,15 +6398,15 @@ } }, "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, "bin": { "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/mocha": { @@ -7336,34 +6449,6 @@ "url": "https://opencollective.com/mochajs" } }, - "node_modules/mocha/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/mocha/node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/mocha/node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -7396,22 +6481,6 @@ "node": "*" } }, - "node_modules/mocha/node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/mocha/node_modules/minimatch": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", @@ -7917,27 +6986,6 @@ "node": ">=0.10.0" } }, - "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -8055,15 +7103,6 @@ "node": ">=4" } }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -8263,12 +7302,6 @@ "node": ">=6.0.0" } }, - "node_modules/process-es6": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/process-es6/-/process-es6-0.11.6.tgz", - "integrity": "sha512-GYBRQtL4v3wgigq10Pv58jmTbFXlIiTbSfgnNqZLY0ldUPqy1rRxDI5fCjoCpnM6TqmHQI8ydzTBXW86OYc0gA==", - "dev": true - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -8325,30 +7358,6 @@ "teleport": ">=0.2.0" } }, - "node_modules/qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", - "dev": true, - "engines": { - "node": ">=0.9" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -8387,30 +7396,6 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -8708,12 +7693,6 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, "node_modules/resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -8754,12 +7733,6 @@ "node": ">=0.10.0" } }, - "node_modules/rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true - }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -8811,194 +7784,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/rollup-plugin-commonjs": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", - "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==", - "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-commonjs.", - "dev": true, - "dependencies": { - "estree-walker": "^0.6.1", - "is-reference": "^1.1.2", - "magic-string": "^0.25.2", - "resolve": "^1.11.0", - "rollup-pluginutils": "^2.8.1" - }, - "peerDependencies": { - "rollup": ">=1.12.0" - } - }, - "node_modules/rollup-plugin-commonjs/node_modules/estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - }, - "node_modules/rollup-plugin-commonjs/node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dev": true, - "dependencies": { - "sourcemap-codec": "^1.4.8" - } - }, - "node_modules/rollup-plugin-inject": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz", - "integrity": "sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==", - "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject.", - "dev": true, - "dependencies": { - "estree-walker": "^0.6.1", - "magic-string": "^0.25.3", - "rollup-pluginutils": "^2.8.1" - } - }, - "node_modules/rollup-plugin-inject/node_modules/estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - }, - "node_modules/rollup-plugin-inject/node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dev": true, - "dependencies": { - "sourcemap-codec": "^1.4.8" - } - }, - "node_modules/rollup-plugin-node-globals": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-globals/-/rollup-plugin-node-globals-1.4.0.tgz", - "integrity": "sha512-xRkB+W/m1KLIzPUmG0ofvR+CPNcvuCuNdjVBVS7ALKSxr3EDhnzNceGkGi1m8MToSli13AzKFYH4ie9w3I5L3g==", - "dev": true, - "dependencies": { - "acorn": "^5.7.3", - "buffer-es6": "^4.9.3", - "estree-walker": "^0.5.2", - "magic-string": "^0.22.5", - "process-es6": "^0.11.6", - "rollup-pluginutils": "^2.3.1" - } - }, - "node_modules/rollup-plugin-node-globals/node_modules/acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/rollup-plugin-node-globals/node_modules/estree-walker": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.5.2.tgz", - "integrity": "sha512-XpCnW/AE10ws/kDAs37cngSkvgIR8aN3G0MS85m7dUpuK2EREo9VJ00uvw6Dg/hXEpfsE1I1TvJOJr+Z+TL+ig==", - "dev": true - }, - "node_modules/rollup-plugin-node-globals/node_modules/magic-string": { - "version": "0.22.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", - "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", - "dev": true, - "dependencies": { - "vlq": "^0.2.2" - } - }, - "node_modules/rollup-plugin-node-polyfills": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-polyfills/-/rollup-plugin-node-polyfills-0.2.1.tgz", - "integrity": "sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==", - "dev": true, - "dependencies": { - "rollup-plugin-inject": "^3.0.0" - } - }, - "node_modules/rollup-plugin-polyfill-node": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-polyfill-node/-/rollup-plugin-polyfill-node-0.10.2.tgz", - "integrity": "sha512-5GMywXiLiuQP6ZzED/LO/Q0HyDi2W6b8VN+Zd3oB0opIjyRs494Me2ZMaqKWDNbGiW4jvvzl6L2n4zRgxS9cSQ==", - "dev": true, - "dependencies": { - "@rollup/plugin-inject": "^4.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" - } - }, - "node_modules/rollup-plugin-polyfill-node/node_modules/@rollup/plugin-inject": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-4.0.4.tgz", - "integrity": "sha512-4pbcU4J/nS+zuHk+c+OL3WtmEQhqxlZ9uqfjQMQDOHOPld7PsCd8k5LWs8h5wjwJN7MgnAn768F2sDxEP4eNFQ==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "estree-walker": "^2.0.1", - "magic-string": "^0.25.7" - }, - "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" - } - }, - "node_modules/rollup-plugin-polyfill-node/node_modules/@rollup/plugin-inject/node_modules/@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "dev": true, - "dependencies": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" - } - }, - "node_modules/rollup-plugin-polyfill-node/node_modules/@rollup/plugin-inject/node_modules/@rollup/pluginutils/node_modules/estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", - "dev": true - }, - "node_modules/rollup-plugin-polyfill-node/node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "dev": true - }, - "node_modules/rollup-plugin-polyfill-node/node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dev": true, - "dependencies": { - "sourcemap-codec": "^1.4.8" - } - }, - "node_modules/rollup-pluginutils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", - "dev": true, - "dependencies": { - "estree-walker": "^0.6.1" - } - }, - "node_modules/rollup-pluginutils/node_modules/estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -9046,7 +7831,8 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "dev": true, + "optional": true }, "node_modules/semver": { "version": "6.3.0", @@ -9072,12 +7858,6 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -9096,21 +7876,7 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, "node_modules/signal-exit": { @@ -9138,42 +7904,6 @@ "npm": ">= 3.0.0" } }, - "node_modules/socket.io": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.3.tgz", - "integrity": "sha512-zdpnnKU+H6mOp7nYRXH4GNv1ux6HL6+lHL8g7Ds7Lj8CkdK1jJK/dlwsKDculbyOHifcJ0Pr/yeXnZQ5GeFrcg==", - "dev": true, - "dependencies": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "debug": "~4.3.2", - "engine.io": "~6.2.0", - "socket.io-adapter": "~2.4.0", - "socket.io-parser": "~4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/socket.io-adapter": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", - "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==", - "dev": true - }, - "node_modules/socket.io-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", - "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", - "dev": true, - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/socks": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", @@ -9429,43 +8159,6 @@ "node": ">=4" } }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/streamroller": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.3.tgz", - "integrity": "sha512-CphIJyFx2SALGHeINanjFRKQ4l7x2c+rXYJ4BMq0gd+ZK0gi4VT8b+eHe2wi58x4UayBAKx4xtHpXT/ea1cz8w==", - "dev": true, - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/streamroller/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -9618,18 +8311,6 @@ "node": ">= 10" } }, - "node_modules/tar/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -9694,18 +8375,6 @@ "readable-stream": "3" } }, - "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -9727,15 +8396,6 @@ "node": ">=8.0" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -10050,19 +8710,6 @@ "node": ">=8" } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -10125,25 +8772,6 @@ "node": ">=6 <7 || >=8" } }, - "node_modules/ua-parser-js": { - "version": "0.7.32", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.32.tgz", - "integrity": "sha512-f9BESNVhzlhEFf2CHMSj40NWOjYPl1YKYbrvIr/hFTDEmLq7SRbWvm7FcdcpCYT95zrOhC7gZSxjdnnTpBcwVw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/ua-parser-js" - }, - { - "type": "paypal", - "url": "https://paypal.me/faisalman" - } - ], - "engines": { - "node": "*" - } - }, "node_modules/uglify-js": { "version": "3.17.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", @@ -10224,15 +8852,6 @@ "node": ">= 4.0.0" } }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/update-browserslist-db": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", @@ -10274,15 +8893,6 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/uuid": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", @@ -10328,30 +8938,6 @@ "node": ">= 0.10" } }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/vlq": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", - "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", - "dev": true - }, - "node_modules/void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/web-streams-polyfill": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", @@ -10463,27 +9049,6 @@ "typedarray-to-buffer": "^3.1.5" } }, - "node_modules/ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -11801,12 +10366,6 @@ "to-fast-properties": "^2.0.0" } }, - "@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true - }, "@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -12019,13 +10578,13 @@ } }, "@microsoft/api-extractor": { - "version": "7.33.4", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.33.4.tgz", - "integrity": "sha512-uZG4CHxVcQNpXBC77GwHaKFwGI9vAnzORY4fFN5JuTnQQDKS0vi4BazP4pmYYwbb8IdH4ocQSwOA3j9Ul/sWmg==", + "version": "7.33.5", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.33.5.tgz", + "integrity": "sha512-ENoWpTWarKNuodpRFDQr3jyBigHuv98KuJ8H5qXc1LZ1aP5Mk77lCo88HbPisTmSnGevJJHTScfd/DPznOb4CQ==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.25.1", - "@microsoft/tsdoc": "0.14.1", + "@microsoft/api-extractor-model": "7.25.2", + "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", "@rushstack/node-core-library": "3.53.2", "@rushstack/rig-package": "0.3.17", @@ -12050,20 +10609,20 @@ } }, "@microsoft/api-extractor-model": { - "version": "7.25.1", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.25.1.tgz", - "integrity": "sha512-AaZ0ohCGLRjWiZviM+0p/DaxgMhbawS183LW2+CSqyEBh6wZks7NjoyhzhibAYapS4omnrmv96+0V/2wBvnIZQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.25.2.tgz", + "integrity": "sha512-+h1uCrLQXFAKMUdghhdDcnniDB+6UA/lS9ArlB4QZQ34UbLuXNy2oQ6fafFK8cKXU4mUPTF/yGRjv7JKD5L7eg==", "dev": true, "requires": { - "@microsoft/tsdoc": "0.14.1", + "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", "@rushstack/node-core-library": "3.53.2" } }, "@microsoft/tsdoc": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.1.tgz", - "integrity": "sha512-6Wci+Tp3CgPt/B9B0a3J4s3yMgLNSku6w5TV6mN+61C71UqsRBv2FUibBf3tPGlNxebgPHMEUzKpb1ggE8KCKw==", + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", + "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", "dev": true }, "@microsoft/tsdoc-config": { @@ -12078,12 +10637,6 @@ "resolve": "~1.19.0" }, "dependencies": { - "@microsoft/tsdoc": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", - "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", - "dev": true - }, "resolve": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", @@ -12151,14 +10704,6 @@ "requires": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } } }, "@rollup/plugin-babel": { @@ -12320,12 +10865,6 @@ "string-argv": "~0.3.1" } }, - "@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", - "dev": true - }, "@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -12368,16 +10907,10 @@ "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", "dev": true }, - "@types/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", - "dev": true - }, - "@types/cors": { - "version": "2.8.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", + "@types/chai": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", "dev": true }, "@types/eslint": { @@ -12408,10 +10941,16 @@ "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", "dev": true }, + "@types/mocha": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.0.tgz", + "integrity": "sha512-rADY+HtTOA52l9VZWtgQfn4p+UDVM2eDVkMZT1I6syp0YKxW2F9v+0pbRZLsvskhQv/vMb6ZfCay81GHbz5SHg==", + "dev": true + }, "@types/node": { - "version": "18.11.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.5.tgz", - "integrity": "sha512-3JRwhbjI+cHLAkUorhf8RnqUbFXajvzX4q6fMn5JwkgtuwfYtRQYI3u4V92vI6NJuTsbBQWWh3RZjFsuevyMGQ==", + "version": "18.11.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.6.tgz", + "integrity": "sha512-j3CEDa2vd96K0AXF8Wur7UucACvnjkk8hYyQAHhUNciabZLDl9nfAEVUSwmh245OOZV15bRA3Y590Gi5jUcDJg==", "dev": true }, "@types/normalize-package-data": { @@ -12606,16 +11145,6 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, "acorn": { "version": "8.8.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", @@ -12659,14 +11188,6 @@ "debug": "^4.1.0", "depd": "^1.1.2", "humanize-ms": "^1.2.1" - }, - "dependencies": { - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "dev": true - } } }, "aggregate-error": { @@ -12845,17 +11366,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "dev": true - }, "benchmark": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", @@ -12872,43 +11382,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, - "body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "dev": true, - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -12946,21 +11419,6 @@ "update-browserslist-db": "^1.0.9" } }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-es6": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/buffer-es6/-/buffer-es6-4.9.3.tgz", - "integrity": "sha512-Ibt+oXxhmeYJSsCkODPqNpPmyegefiD8rfutH1NYGhMZQhSp95Rz7haemgnJ6dxa6LT+JLLbtgOMORRluwKktw==", - "dev": true - }, "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -12973,12 +11431,6 @@ "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true - }, "cacache": { "version": "15.3.0", "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", @@ -13019,12 +11471,6 @@ "path-is-absolute": "^1.0.0" } }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, "p-map": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", @@ -13048,16 +11494,6 @@ "write-file-atomic": "^3.0.0" } }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -13232,47 +11668,12 @@ "typedarray": "^0.0.6" } }, - "connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "dev": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", "dev": true }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, "conventional-changelog": { "version": "3.1.25", "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz", @@ -13474,12 +11875,6 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true }, - "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true - }, "core-js-compat": { "version": "3.26.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.0.tgz", @@ -13495,16 +11890,6 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -13522,12 +11907,6 @@ "which": "^2.0.1" } }, - "custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", - "dev": true - }, "dargs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", @@ -13540,24 +11919,12 @@ "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", "dev": true }, - "date-format": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", - "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", - "dev": true - }, "dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true }, - "debounce": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", - "dev": true - }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -13628,15 +11995,9 @@ "dev": true }, "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true }, "detect-indent": { @@ -13657,12 +12018,6 @@ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true }, - "di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", - "dev": true - }, "diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -13687,18 +12042,6 @@ "esutils": "^2.0.2" } }, - "dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", - "dev": true, - "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", @@ -13763,12 +12106,6 @@ } } }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true - }, "electron-to-chromium": { "version": "1.4.284", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", @@ -13779,66 +12116,18 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true - }, - "encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "dev": true, - "optional": true, - "requires": { - "iconv-lite": "^0.6.2" - }, - "dependencies": { - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - } - } + "dev": true }, - "engine.io": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.0.tgz", - "integrity": "sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg==", + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "dev": true, + "optional": true, "requires": { - "@types/cookie": "^0.4.1", - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.4.1", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.0.3", - "ws": "~8.2.3" + "iconv-lite": "^0.6.2" } }, - "engine.io-parser": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", - "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==", - "dev": true - }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", - "dev": true - }, "env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -13872,12 +12161,6 @@ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -14016,16 +12299,6 @@ "supports-color": "^7.1.0" } }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -14054,14 +12327,6 @@ "requires": { "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "0.16.2" - }, - "dependencies": { - "@microsoft/tsdoc": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", - "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", - "dev": true - } } }, "eslint-rule-docs": { @@ -14172,18 +12437,6 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -14286,47 +12539,6 @@ "to-regex-range": "^5.0.1" } }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - } - } - }, "find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", @@ -14370,12 +12582,6 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, - "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "dev": true - }, "foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -14475,17 +12681,6 @@ "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true }, - "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, "get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -14696,12 +12891,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -14745,38 +12934,6 @@ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", "dev": true }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "dependencies": { - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - } - } - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, "http-proxy-agent": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", @@ -14808,19 +12965,15 @@ } }, "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, + "optional": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": ">= 2.1.2 < 3.0.0" } }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, "ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", @@ -15033,12 +13186,6 @@ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true }, - "isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -15239,184 +13386,6 @@ "through": ">=2.2.7 <3" } }, - "karma": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz", - "integrity": "sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA==", - "dev": true, - "requires": { - "@colors/colors": "1.5.0", - "body-parser": "^1.19.0", - "braces": "^3.0.2", - "chokidar": "^3.5.1", - "connect": "^3.7.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.1", - "glob": "^7.1.7", - "graceful-fs": "^4.2.6", - "http-proxy": "^1.18.1", - "isbinaryfile": "^4.0.8", - "lodash": "^4.17.21", - "log4js": "^6.4.1", - "mime": "^2.5.2", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.5", - "qjobs": "^1.2.0", - "range-parser": "^1.2.1", - "rimraf": "^3.0.2", - "socket.io": "^4.4.1", - "source-map": "^0.6.1", - "tmp": "^0.2.1", - "ua-parser-js": "^0.7.30", - "yargs": "^16.1.1" - }, - "dependencies": { - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "karma-chai": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/karma-chai/-/karma-chai-0.1.0.tgz", - "integrity": "sha512-mqKCkHwzPMhgTYca10S90aCEX9+HjVjjrBFAsw36Zj7BlQNbokXXCAe6Ji04VUMsxcY5RLP7YphpfO06XOubdg==", - "dev": true, - "requires": {} - }, - "karma-chrome-launcher": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz", - "integrity": "sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ==", - "dev": true, - "requires": { - "which": "^1.2.1" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "karma-mocha": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-2.0.1.tgz", - "integrity": "sha512-Tzd5HBjm8his2OA4bouAsATYEpZrp9vC7z5E5j4C5Of5Rrs1jY67RAwXNcVmd/Bnk1wgvQRou0zGVLey44G4tQ==", - "dev": true, - "requires": { - "minimist": "^1.2.3" - } - }, - "karma-mocha-reporter": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz", - "integrity": "sha512-Hr6nhkIp0GIJJrvzY8JFeHpQZNseuIakGac4bpw8K1+5F0tLb6l7uvXRa8mt2Z+NVwYgCct4QAfp2R2QP6o00w==", - "dev": true, - "requires": { - "chalk": "^2.1.0", - "log-symbols": "^2.1.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "karma-rollup-preprocessor": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/karma-rollup-preprocessor/-/karma-rollup-preprocessor-7.0.8.tgz", - "integrity": "sha512-WiuBCS9qsatJuR17dghiTARBZ7LF+ml+eb7qJXhw7IbsdY0lTWELDRQC/93J9i6636CsAXVBL3VJF4WtaFLZzA==", - "dev": true, - "requires": { - "chokidar": "^3.3.1", - "debounce": "^1.2.0" - } - }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -15517,85 +13486,36 @@ "dev": true }, "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "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": "^3.0.0" + "has-flag": "^4.0.0" } } } }, - "log4js": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.7.0.tgz", - "integrity": "sha512-KA0W9ffgNBLDj6fZCq/lRbgR6ABAodRIDHrZnS48vOtfKa4PzWImb0Md1lmGCdO3n3sbCm/n1/WmrNlZ8kCI3Q==", - "dev": true, - "requires": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "flatted": "^3.2.7", - "rfdc": "^1.3.0", - "streamroller": "^3.1.3" - } - }, "loupe": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", @@ -15668,12 +13588,6 @@ "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true - }, "meow": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", @@ -15829,27 +13743,6 @@ "picomatch": "^2.3.1" } }, - "mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "requires": { - "mime-db": "1.52.0" - } - }, "min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -15950,13 +13843,10 @@ } }, "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true }, "mocha": { "version": "10.1.0", @@ -15987,27 +13877,6 @@ "yargs-unparser": "2.0.0" }, "dependencies": { - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -16033,16 +13902,6 @@ } } }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, "minimatch": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", @@ -16433,21 +14292,6 @@ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true }, - "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", - "dev": true - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -16535,12 +14379,6 @@ "json-parse-better-errors": "^1.0.1" } }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -16679,12 +14517,6 @@ "fast-diff": "^1.1.2" } }, - "process-es6": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/process-es6/-/process-es6-0.11.6.tgz", - "integrity": "sha512-GYBRQtL4v3wgigq10Pv58jmTbFXlIiTbSfgnNqZLY0ldUPqy1rRxDI5fCjoCpnM6TqmHQI8ydzTBXW86OYc0gA==", - "dev": true - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -16728,21 +14560,6 @@ "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", "dev": true }, - "qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", - "dev": true - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -16764,24 +14581,6 @@ "safe-buffer": "^5.1.0" } }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dev": true, - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", @@ -17019,12 +14818,6 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -17052,12 +14845,6 @@ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true }, - "rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true - }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -17092,185 +14879,6 @@ "fsevents": "~2.3.2" } }, - "rollup-plugin-commonjs": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", - "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==", - "dev": true, - "requires": { - "estree-walker": "^0.6.1", - "is-reference": "^1.1.2", - "magic-string": "^0.25.2", - "resolve": "^1.11.0", - "rollup-pluginutils": "^2.8.1" - }, - "dependencies": { - "estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - }, - "magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dev": true, - "requires": { - "sourcemap-codec": "^1.4.8" - } - } - } - }, - "rollup-plugin-inject": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz", - "integrity": "sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==", - "dev": true, - "requires": { - "estree-walker": "^0.6.1", - "magic-string": "^0.25.3", - "rollup-pluginutils": "^2.8.1" - }, - "dependencies": { - "estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - }, - "magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dev": true, - "requires": { - "sourcemap-codec": "^1.4.8" - } - } - } - }, - "rollup-plugin-node-globals": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-globals/-/rollup-plugin-node-globals-1.4.0.tgz", - "integrity": "sha512-xRkB+W/m1KLIzPUmG0ofvR+CPNcvuCuNdjVBVS7ALKSxr3EDhnzNceGkGi1m8MToSli13AzKFYH4ie9w3I5L3g==", - "dev": true, - "requires": { - "acorn": "^5.7.3", - "buffer-es6": "^4.9.3", - "estree-walker": "^0.5.2", - "magic-string": "^0.22.5", - "process-es6": "^0.11.6", - "rollup-pluginutils": "^2.3.1" - }, - "dependencies": { - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "estree-walker": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.5.2.tgz", - "integrity": "sha512-XpCnW/AE10ws/kDAs37cngSkvgIR8aN3G0MS85m7dUpuK2EREo9VJ00uvw6Dg/hXEpfsE1I1TvJOJr+Z+TL+ig==", - "dev": true - }, - "magic-string": { - "version": "0.22.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", - "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", - "dev": true, - "requires": { - "vlq": "^0.2.2" - } - } - } - }, - "rollup-plugin-node-polyfills": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-polyfills/-/rollup-plugin-node-polyfills-0.2.1.tgz", - "integrity": "sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==", - "dev": true, - "requires": { - "rollup-plugin-inject": "^3.0.0" - } - }, - "rollup-plugin-polyfill-node": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-polyfill-node/-/rollup-plugin-polyfill-node-0.10.2.tgz", - "integrity": "sha512-5GMywXiLiuQP6ZzED/LO/Q0HyDi2W6b8VN+Zd3oB0opIjyRs494Me2ZMaqKWDNbGiW4jvvzl6L2n4zRgxS9cSQ==", - "dev": true, - "requires": { - "@rollup/plugin-inject": "^4.0.0" - }, - "dependencies": { - "@rollup/plugin-inject": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-4.0.4.tgz", - "integrity": "sha512-4pbcU4J/nS+zuHk+c+OL3WtmEQhqxlZ9uqfjQMQDOHOPld7PsCd8k5LWs8h5wjwJN7MgnAn768F2sDxEP4eNFQ==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^3.1.0", - "estree-walker": "^2.0.1", - "magic-string": "^0.25.7" - }, - "dependencies": { - "@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "dev": true, - "requires": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "dependencies": { - "estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", - "dev": true - } - } - } - } - }, - "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "dev": true - }, - "magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dev": true, - "requires": { - "sourcemap-codec": "^1.4.8" - } - } - } - }, - "rollup-pluginutils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", - "dev": true, - "requires": { - "estree-walker": "^0.6.1" - }, - "dependencies": { - "estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - } - } - }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -17290,7 +14898,8 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "dev": true, + "optional": true }, "semver": { "version": "6.3.0", @@ -17313,12 +14922,6 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -17334,17 +14937,6 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -17363,36 +14955,6 @@ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true }, - "socket.io": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.3.tgz", - "integrity": "sha512-zdpnnKU+H6mOp7nYRXH4GNv1ux6HL6+lHL8g7Ds7Lj8CkdK1jJK/dlwsKDculbyOHifcJ0Pr/yeXnZQ5GeFrcg==", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "debug": "~4.3.2", - "engine.io": "~6.2.0", - "socket.io-adapter": "~2.4.0", - "socket.io-parser": "~4.2.0" - } - }, - "socket.io-adapter": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", - "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==", - "dev": true - }, - "socket.io-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", - "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", - "dev": true, - "requires": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - } - }, "socks": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", @@ -17604,36 +15166,6 @@ } } }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true - }, - "streamroller": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.3.tgz", - "integrity": "sha512-CphIJyFx2SALGHeINanjFRKQ4l7x2c+rXYJ4BMq0gd+ZK0gi4VT8b+eHe2wi58x4UayBAKx4xtHpXT/ea1cz8w==", - "dev": true, - "requires": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - }, - "dependencies": { - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -17744,14 +15276,6 @@ "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } } }, "test-exclude": { @@ -17808,15 +15332,6 @@ "readable-stream": "3" } }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } - }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -17832,12 +15347,6 @@ "is-number": "^7.0.0" } }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true - }, "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -18063,16 +15572,6 @@ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -18124,12 +15623,6 @@ } } }, - "ua-parser-js": { - "version": "0.7.32", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.32.tgz", - "integrity": "sha512-f9BESNVhzlhEFf2CHMSj40NWOjYPl1YKYbrvIr/hFTDEmLq7SRbWvm7FcdcpCYT95zrOhC7gZSxjdnnTpBcwVw==", - "dev": true - }, "uglify-js": { "version": "3.17.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", @@ -18189,12 +15682,6 @@ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true - }, "update-browserslist-db": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", @@ -18220,12 +15707,6 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true - }, "uuid": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", @@ -18264,24 +15745,6 @@ "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", "dev": true }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true - }, - "vlq": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", - "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", - "dev": true - }, - "void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", - "dev": true - }, "web-streams-polyfill": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", @@ -18375,13 +15838,6 @@ "typedarray-to-buffer": "^3.1.5" } }, - "ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", - "dev": true, - "requires": {} - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index f19d1a62..64d844b3 100644 --- a/package.json +++ b/package.json @@ -30,39 +30,31 @@ "@babel/plugin-external-helpers": "^7.18.6", "@babel/preset-env": "^7.19.4", "@istanbuljs/nyc-config-typescript": "^1.0.2", - "@microsoft/api-extractor": "^7.33.4", - "@rollup/plugin-babel": "^6.0.0", - "@rollup/plugin-commonjs": "^23.0.0", - "@rollup/plugin-json": "^5.0.0", - "@rollup/plugin-node-resolve": "^15.0.0", - "@rollup/plugin-replace": "^5.0.0", - "@rollup/plugin-typescript": "^9.0.1", - "@types/node": "^18.11.2", - "@typescript-eslint/eslint-plugin": "^5.40.1", - "@typescript-eslint/parser": "^5.40.1", + "@microsoft/api-extractor": "^7.33.5", + "@rollup/plugin-babel": "^6.0.2", + "@rollup/plugin-commonjs": "^23.0.2", + "@rollup/plugin-json": "^5.0.1", + "@rollup/plugin-node-resolve": "^15.0.1", + "@rollup/plugin-replace": "^5.0.1", + "@rollup/plugin-typescript": "^9.0.2", + "@types/chai": "^4.3.3", + "@types/mocha": "^10.0.0", + "@types/node": "^18.11.6", + "@typescript-eslint/eslint-plugin": "^5.41.0", + "@typescript-eslint/parser": "^5.41.0", "benchmark": "^2.1.4", "chai": "^4.3.6", - "eslint": "^8.25.0", "chalk": "^5.1.2", + "eslint": "^8.26.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-tsdoc": "^0.2.17", - "karma": "^6.4.1", - "karma-chai": "^0.1.0", - "karma-chrome-launcher": "^3.1.1", - "karma-mocha": "^2.0.1", - "karma-mocha-reporter": "^2.2.5", - "karma-rollup-preprocessor": "^7.0.8", "mocha": "10.1.0", "node-fetch": "^3.2.10", "nyc": "^15.1.0", "prettier": "^2.7.1", "rimraf": "^3.0.2", "rollup": "^3.2.3", - "rollup-plugin-commonjs": "^10.1.0", - "rollup-plugin-node-globals": "^1.4.0", - "rollup-plugin-node-polyfills": "^0.2.1", - "rollup-plugin-polyfill-node": "^0.10.2", "source-map-support": "^0.5.21", "standard-version": "^9.5.0", "ts-node": "^10.9.1", @@ -94,21 +86,19 @@ "node": ">=14.20.1" }, "scripts": { - "test": "npm run build && npm run check:test && npm run test-browser", - "check:test": "mocha test/node test/*_tests.js", + "pretest": "npm run build", + "test": "npm run check:node && npm run check:web", + "check:node": "WEB=false mocha test/node", "check:tsd": "npm run build:dts && tsd", - "test-browser": "node --max-old-space-size=4096 ./node_modules/.bin/karma start karma.conf.js", - "build:ts": "tsc", + "check:web": "WEB=true mocha test/node", + "build:ts": "node ./node_modules/typescript/bin/tsc", "build:dts": "npm run build:ts && api-extractor run --typescript-compiler-folder node_modules/typescript --local && rimraf 'lib/**/*.d.ts*'", "build:bundle": "rollup -c rollup.config.mjs", "build": "npm run build:dts && npm run build:bundle", - "check:lint": "eslint -v && eslint --ext '.js,.ts' --max-warnings=0 src test && tsc -v && tsc --noEmit && npm run check:tsd", + "check:lint": "eslint -v && eslint --ext '.js,.ts' --max-warnings=0 src test && node ./node_modules/typescript/bin/tsc -v && node ./node_modules/typescript/bin/tsc --noEmit && npm run check:tsd", "format": "eslint --ext '.js,.ts' src test --fix", - "check:coverage": "nyc --check-coverage npm run check:test", + "check:coverage": "nyc --check-coverage npm run check:node", "prepare": "node etc/prepare.js", "release": "standard-version -i HISTORY.md" - }, - "dependencies": { - "buffer": "^5.6.0" } } diff --git a/rollup.config.mjs b/rollup.config.mjs index 6d3abe70..54913780 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -1,11 +1,11 @@ -import pkg from './package.json' assert { type: 'json' }; -import commonjs from 'rollup-plugin-commonjs'; -import nodeBuiltins from 'rollup-plugin-polyfill-node'; +import commonjs from '@rollup/plugin-commonjs'; import { nodeResolve } from '@rollup/plugin-node-resolve'; import { babel } from '@rollup/plugin-babel'; import typescript from '@rollup/plugin-typescript'; -import nodeGlobals from 'rollup-plugin-node-globals'; import replace from '@rollup/plugin-replace'; +import { readFile } from 'fs/promises'; + +const pkg = JSON.parse(await readFile('./package.json', { encoding: 'utf8' })); const tsConfig = { allowJs: false, @@ -38,8 +38,6 @@ const plugins = (options = { browser: false }) => { return [ typescript(tsConfig), nodeResolve({ preferBuiltins: false }), - nodeBuiltins(), - nodeGlobals(), replace({ preventAssignment: true, values: { diff --git a/src/binary.ts b/src/binary.ts index d86275c9..eef19230 100644 --- a/src/binary.ts +++ b/src/binary.ts @@ -1,13 +1,12 @@ -import { Buffer } from 'buffer'; -import { ensureBuffer } from './ensure_buffer'; import { bufferToUuidHexString, uuidHexStringToBuffer, uuidValidateString } from './uuid_utils'; import { isUint8Array, randomBytes } from './parser/utils'; import type { EJSONOptions } from './extended_json'; import { BSONError, BSONTypeError } from './error'; import { BSON_BINARY_SUBTYPE_UUID_NEW } from './constants'; +import { ByteUtils } from './utils/byte_utils'; /** @public */ -export type BinarySequence = Uint8Array | Buffer | number[]; +export type BinarySequence = Uint8Array | number[]; /** @public */ export interface BinaryExtendedLegacy { @@ -58,7 +57,7 @@ export class Binary { /** User BSON type */ static readonly SUBTYPE_USER_DEFINED = 128; - buffer!: Buffer; + buffer!: Uint8Array; sub_type!: number; position!: number; @@ -92,18 +91,18 @@ export class Binary { if (buffer == null) { // create an empty binary buffer - this.buffer = Buffer.alloc(Binary.BUFFER_SIZE); + this.buffer = ByteUtils.allocate(Binary.BUFFER_SIZE); this.position = 0; } else { if (typeof buffer === 'string') { // string - this.buffer = Buffer.from(buffer, 'binary'); + this.buffer = ByteUtils.fromISO88591(buffer); } else if (Array.isArray(buffer)) { // number[] - this.buffer = Buffer.from(buffer); + this.buffer = ByteUtils.fromNumberArray(buffer); } else { // Buffer | TypedArray | ArrayBuffer - this.buffer = ensureBuffer(buffer); + this.buffer = ByteUtils.toLocalBufferType(buffer); } this.position = this.buffer.byteLength; @@ -115,7 +114,7 @@ export class Binary { * * @param byteValue - a single byte we wish to write. */ - put(byteValue: string | number | Uint8Array | Buffer | number[]): void { + put(byteValue: string | number | Uint8Array | number[]): void { // If it's a string and a has more than one character throw an error if (typeof byteValue === 'string' && byteValue.length !== 1) { throw new BSONTypeError('only accepts single character String'); @@ -136,13 +135,12 @@ export class Binary { throw new BSONTypeError('only accepts number in a valid unsigned byte range 0-255'); } - if (this.buffer.length > this.position) { + if (this.buffer.byteLength > this.position) { this.buffer[this.position++] = decodedByte; } else { - const buffer = Buffer.alloc(Binary.BUFFER_SIZE + this.buffer.length); - // Combine the two buffers together - this.buffer.copy(buffer, 0, 0, this.buffer.length); - this.buffer = buffer; + const newSpace = ByteUtils.allocate(Binary.BUFFER_SIZE + this.buffer.length); + newSpace.set(this.buffer, 0); + this.buffer = newSpace; this.buffer[this.position++] = decodedByte; } } @@ -157,20 +155,21 @@ export class Binary { offset = typeof offset === 'number' ? offset : this.position; // If the buffer is to small let's extend the buffer - if (this.buffer.length < offset + sequence.length) { - const buffer = Buffer.alloc(this.buffer.length + sequence.length); - this.buffer.copy(buffer, 0, 0, this.buffer.length); + if (this.buffer.byteLength < offset + sequence.length) { + const newSpace = ByteUtils.allocate(this.buffer.byteLength + sequence.length); + newSpace.set(this.buffer, 0); // Assign the new buffer - this.buffer = buffer; + this.buffer = newSpace; } if (ArrayBuffer.isView(sequence)) { - this.buffer.set(ensureBuffer(sequence), offset); + this.buffer.set(ByteUtils.toLocalBufferType(sequence), offset); this.position = offset + sequence.byteLength > this.position ? offset + sequence.length : this.position; } else if (typeof sequence === 'string') { - this.buffer.write(sequence, offset, sequence.length, 'binary'); + const bytes = ByteUtils.fromISO88591(sequence); + this.buffer.set(bytes, offset); this.position = offset + sequence.length > this.position ? offset + sequence.length : this.position; } @@ -207,7 +206,8 @@ export class Binary { if (asRaw) { return this.buffer.slice(0, this.position); } - return this.buffer.toString('binary', 0, this.position); + // TODO(NODE-4361): remove binary string support, value(true) should be the default / only option here. + return ByteUtils.toISO88591(this.buffer.subarray(0, this.position)); } /** the length of the binary sequence */ @@ -216,17 +216,20 @@ export class Binary { } toJSON(): string { - return this.buffer.toString('base64'); + return ByteUtils.toBase64(this.buffer); } - toString(format?: string): string { - return this.buffer.toString(format); + toString(encoding?: 'hex' | 'base64' | 'utf8' | 'utf-8'): string { + if (encoding === 'hex') return ByteUtils.toHex(this.buffer); + if (encoding === 'base64') return ByteUtils.toBase64(this.buffer); + if (encoding === 'utf8' || encoding === 'utf-8') return ByteUtils.toUTF8(this.buffer); + return ByteUtils.toUTF8(this.buffer); } /** @internal */ toExtendedJSON(options?: EJSONOptions): BinaryExtendedLegacy | BinaryExtended { options = options || {}; - const base64String = this.buffer.toString('base64'); + const base64String = ByteUtils.toBase64(this.buffer); const subType = Number(this.sub_type).toString(16); if (options.legacy) { @@ -259,16 +262,16 @@ export class Binary { options?: EJSONOptions ): Binary { options = options || {}; - let data: Buffer | undefined; + let data: Uint8Array | undefined; let type; if ('$binary' in doc) { if (options.legacy && typeof doc.$binary === 'string' && '$type' in doc) { type = doc.$type ? parseInt(doc.$type, 16) : 0; - data = Buffer.from(doc.$binary, 'base64'); + data = ByteUtils.fromBase64(doc.$binary); } else { if (typeof doc.$binary !== 'string') { type = doc.$binary.subType ? parseInt(doc.$binary.subType, 16) : 0; - data = Buffer.from(doc.$binary.base64, 'base64'); + data = ByteUtils.fromBase64(doc.$binary.base64); } } } else if ('$uuid' in doc) { @@ -287,8 +290,7 @@ export class Binary { } inspect(): string { - const asBuffer = this.value(true); - return `new Binary(Buffer.from("${asBuffer.toString('hex')}", "hex"), ${this.sub_type})`; + return `new Binary(Buffer.from("${ByteUtils.toHex(this.buffer)}", "hex"), ${this.sub_type})`; } } @@ -315,16 +317,16 @@ export class UUID extends Binary { * * @param input - Can be a 32 or 36 character hex string (dashes excluded/included) or a 16 byte binary Buffer. */ - constructor(input?: string | Buffer | UUID) { - let bytes; + constructor(input?: string | Uint8Array | UUID) { + let bytes: Uint8Array; let hexStr; if (input == null) { bytes = UUID.generate(); } else if (input instanceof UUID) { - bytes = Buffer.from(input.buffer); + bytes = ByteUtils.toLocalBufferType(new Uint8Array(input.buffer)); hexStr = input.__id; } else if (ArrayBuffer.isView(input) && input.byteLength === UUID_BYTE_LENGTH) { - bytes = ensureBuffer(input); + bytes = ByteUtils.toLocalBufferType(input); } else if (typeof input === 'string') { bytes = uuidHexStringToBuffer(input); } else { @@ -340,11 +342,11 @@ export class UUID extends Binary { * The UUID bytes * @readonly */ - get id(): Buffer { + get id(): Uint8Array { return this.buffer; } - set id(value: Buffer) { + set id(value: Uint8Array) { this.buffer = value; if (UUID.cacheHexString) { @@ -373,8 +375,10 @@ export class UUID extends Binary { /** * Converts the id into a 36 character (dashes included) hex string, unless a encoding is specified. */ - toString(encoding?: string): string { - return encoding ? this.id.toString(encoding) : this.toHexString(); + toString(encoding?: 'hex' | 'base64'): string { + if (encoding === 'hex') return ByteUtils.toHex(this.id); + if (encoding === 'base64') return ByteUtils.toBase64(this.id); + return this.toHexString(); } /** @@ -390,17 +394,17 @@ export class UUID extends Binary { * * @param otherId - UUID instance to compare against. */ - equals(otherId: string | Buffer | UUID): boolean { + equals(otherId: string | Uint8Array | UUID): boolean { if (!otherId) { return false; } if (otherId instanceof UUID) { - return otherId.id.equals(this.id); + return ByteUtils.equals(otherId.id, this.id); } try { - return new UUID(otherId).id.equals(this.id); + return ByteUtils.equals(new UUID(otherId).id, this.id); } catch { return false; } @@ -416,7 +420,7 @@ export class UUID extends Binary { /** * Generates a populated buffer containing a v4 uuid */ - static generate(): Buffer { + static generate(): Uint8Array { const bytes = randomBytes(UUID_BYTE_LENGTH); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` @@ -424,14 +428,14 @@ export class UUID extends Binary { bytes[6] = (bytes[6] & 0x0f) | 0x40; bytes[8] = (bytes[8] & 0x3f) | 0x80; - return Buffer.from(bytes); + return bytes; } /** * Checks if a value is a valid bson UUID * @param input - UUID, string or Buffer to validate. */ - static isValid(input: string | Buffer | UUID): boolean { + static isValid(input: string | Uint8Array | UUID): boolean { if (!input) { return false; } @@ -446,7 +450,7 @@ export class UUID extends Binary { if (isUint8Array(input)) { // check for length & uuid version (https://tools.ietf.org/html/rfc4122#section-4.1.3) - if (input.length !== UUID_BYTE_LENGTH) { + if (input.byteLength !== UUID_BYTE_LENGTH) { return false; } diff --git a/src/bson.ts b/src/bson.ts index d32cfe83..1000f137 100644 --- a/src/bson.ts +++ b/src/bson.ts @@ -1,10 +1,8 @@ -import { Buffer } from 'buffer'; import { Binary, UUID } from './binary'; import { Code } from './code'; import { DBRef } from './db_ref'; import { Decimal128 } from './decimal128'; import { Double } from './double'; -import { ensureBuffer } from './ensure_buffer'; import { EJSON } from './extended_json'; import { Int32 } from './int_32'; import { Long } from './long'; @@ -20,6 +18,7 @@ import { serializeInto as internalSerialize, SerializeOptions } from './parser/s import { BSONRegExp } from './regexp'; import { BSONSymbol } from './symbol'; import { Timestamp } from './timestamp'; +import { ByteUtils } from './utils/byte_utils'; export type { UUIDExtended, BinaryExtended, BinaryExtendedLegacy, BinarySequence } from './binary'; export type { CodeExtended } from './code'; export { @@ -107,7 +106,7 @@ export interface Document { const MAXSIZE = 1024 * 1024 * 17; // Current Internal Temporary Serialization Buffer -let buffer = Buffer.alloc(MAXSIZE); +let buffer = ByteUtils.allocate(MAXSIZE); /** * Sets the size of the internal serialization buffer. @@ -118,7 +117,7 @@ let buffer = Buffer.alloc(MAXSIZE); export function setInternalBufferSize(size: number): void { // Resize the internal serialization buffer if needed if (buffer.length < size) { - buffer = Buffer.alloc(size); + buffer = ByteUtils.allocate(size); } } @@ -129,7 +128,7 @@ export function setInternalBufferSize(size: number): void { * @returns Buffer object containing the serialized object. * @public */ -export function serialize(object: Document, options: SerializeOptions = {}): Buffer { +export function serialize(object: Document, options: SerializeOptions = {}): Uint8Array { // Unpack the options const checkKeys = typeof options.checkKeys === 'boolean' ? options.checkKeys : false; const serializeFunctions = @@ -141,7 +140,7 @@ export function serialize(object: Document, options: SerializeOptions = {}): Buf // Resize the internal serialization buffer if needed if (buffer.length < minInternalBufferSize) { - buffer = Buffer.alloc(minInternalBufferSize); + buffer = ByteUtils.allocate(minInternalBufferSize); } // Attempt to serialize @@ -157,10 +156,10 @@ export function serialize(object: Document, options: SerializeOptions = {}): Buf ); // Create the final buffer - const finishedBuffer = Buffer.alloc(serializationIndex); + const finishedBuffer = ByteUtils.allocate(serializationIndex); // Copy into the finished buffer - buffer.copy(finishedBuffer, 0, 0, finishedBuffer.length); + finishedBuffer.set(buffer.subarray(0, serializationIndex), 0); // Return the buffer return finishedBuffer; @@ -177,7 +176,7 @@ export function serialize(object: Document, options: SerializeOptions = {}): Buf */ export function serializeWithBufferAndIndex( object: Document, - finalBuffer: Buffer, + finalBuffer: Uint8Array, options: SerializeOptions = {} ): number { // Unpack the options @@ -198,7 +197,8 @@ export function serializeWithBufferAndIndex( serializeFunctions, ignoreUndefined ); - buffer.copy(finalBuffer, startIndex, 0, serializationIndex); + + finalBuffer.set(buffer.subarray(0, serializationIndex), startIndex); // Return the index return startIndex + serializationIndex - 1; @@ -211,11 +211,8 @@ export function serializeWithBufferAndIndex( * @returns returns the deserialized Javascript Object. * @public */ -export function deserialize( - buffer: Buffer | ArrayBufferView | ArrayBuffer, - options: DeserializeOptions = {} -): Document { - return internalDeserialize(buffer instanceof Buffer ? buffer : ensureBuffer(buffer), options); +export function deserialize(buffer: Uint8Array, options: DeserializeOptions = {}): Document { + return internalDeserialize(ByteUtils.toLocalBufferType(buffer), options); } /** @public */ @@ -258,7 +255,7 @@ export function calculateObjectSize( * @public */ export function deserializeStream( - data: Buffer | ArrayBufferView | ArrayBuffer, + data: Uint8Array | ArrayBuffer, startIndex: number, numberOfDocuments: number, documents: Document[], @@ -269,7 +266,7 @@ export function deserializeStream( { allowObjectSmallerThanBufferSize: true, index: 0 }, options ); - const bufferData = ensureBuffer(data); + const bufferData = ByteUtils.toLocalBufferType(data); let index = startIndex; // Loop over all documents diff --git a/src/decimal128.ts b/src/decimal128.ts index 87599864..86b664ef 100644 --- a/src/decimal128.ts +++ b/src/decimal128.ts @@ -1,7 +1,7 @@ -import { Buffer } from 'buffer'; import { BSONTypeError } from './error'; import { Long } from './long'; import { isUint8Array } from './parser/utils'; +import { ByteUtils } from './utils/byte_utils'; const PARSE_STRING_REGEXP = /^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/; const PARSE_INF_REGEXP = /^(\+|-)?(Infinity|inf)$/i; @@ -13,16 +13,22 @@ const EXPONENT_BIAS = 6176; const MAX_DIGITS = 34; // Nan value bits as 32 bit values (due to lack of longs) -const NAN_BUFFER = [ - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -].reverse(); +const NAN_BUFFER = ByteUtils.fromNumberArray( + [ + 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + ].reverse() +); // Infinity value bits 32 bit values (due to lack of longs) -const INF_NEGATIVE_BUFFER = [ - 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -].reverse(); -const INF_POSITIVE_BUFFER = [ - 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -].reverse(); +const INF_NEGATIVE_BUFFER = ByteUtils.fromNumberArray( + [ + 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + ].reverse() +); +const INF_POSITIVE_BUFFER = ByteUtils.fromNumberArray( + [ + 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + ].reverse() +); const EXPONENT_REGEX = /^([-+])?(\d+)?$/; @@ -123,13 +129,13 @@ export interface Decimal128Extended { export class Decimal128 { _bsontype!: 'Decimal128'; - readonly bytes!: Buffer; + readonly bytes!: Uint8Array; /** * @param bytes - a buffer containing the raw Decimal128 bytes in little endian order, * or a string representation as returned by .toString() */ - constructor(bytes: Buffer | string) { + constructor(bytes: Uint8Array | string) { if (!(this instanceof Decimal128)) return new Decimal128(bytes); if (typeof bytes === 'string') { @@ -239,9 +245,9 @@ export class Decimal128 { // Check if user passed Infinity or NaN if (!isDigit(representation[index]) && representation[index] !== '.') { if (representation[index] === 'i' || representation[index] === 'I') { - return new Decimal128(Buffer.from(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER)); + return new Decimal128(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER); } else if (representation[index] === 'N') { - return new Decimal128(Buffer.from(NAN_BUFFER)); + return new Decimal128(NAN_BUFFER); } } @@ -285,7 +291,7 @@ export class Decimal128 { const match = representation.substr(++index).match(EXPONENT_REGEX); // No digits read - if (!match || !match[2]) return new Decimal128(Buffer.from(NAN_BUFFER)); + if (!match || !match[2]) return new Decimal128(NAN_BUFFER); // Get exponent exponent = parseInt(match[0], 10); @@ -295,7 +301,7 @@ export class Decimal128 { } // Return not a number - if (representation[index]) return new Decimal128(Buffer.from(NAN_BUFFER)); + if (representation[index]) return new Decimal128(NAN_BUFFER); // Done reading input // Find first non-zero digit in digits @@ -423,9 +429,7 @@ export class Decimal128 { exponent = exponent + 1; digits[dIdx] = 1; } else { - return new Decimal128( - Buffer.from(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER) - ); + return new Decimal128(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER); } } } @@ -503,7 +507,7 @@ export class Decimal128 { } // Encode into a buffer - const buffer = Buffer.alloc(16); + const buffer = ByteUtils.allocate(16); index = 0; // Encode the low 64 bits of the decimal diff --git a/src/ensure_buffer.ts b/src/ensure_buffer.ts deleted file mode 100644 index 8b82a085..00000000 --- a/src/ensure_buffer.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Buffer } from 'buffer'; -import { BSONTypeError } from './error'; -import { isAnyArrayBuffer } from './parser/utils'; - -/** - * Makes sure that, if a Uint8Array is passed in, it is wrapped in a Buffer. - * - * @param potentialBuffer - The potential buffer - * @returns Buffer the input if potentialBuffer is a buffer, or a buffer that - * wraps a passed in Uint8Array - * @throws BSONTypeError If anything other than a Buffer or Uint8Array is passed in - */ -export function ensureBuffer(potentialBuffer: Buffer | ArrayBufferView | ArrayBuffer): Buffer { - if (ArrayBuffer.isView(potentialBuffer)) { - return Buffer.from( - potentialBuffer.buffer, - potentialBuffer.byteOffset, - potentialBuffer.byteLength - ); - } - - if (isAnyArrayBuffer(potentialBuffer)) { - return Buffer.from(potentialBuffer); - } - - throw new BSONTypeError('Must use either Buffer or TypedArray'); -} diff --git a/src/objectid.ts b/src/objectid.ts index 7bf012d7..d0010d27 100644 --- a/src/objectid.ts +++ b/src/objectid.ts @@ -1,7 +1,6 @@ -import { Buffer } from 'buffer'; -import { ensureBuffer } from './ensure_buffer'; import { BSONTypeError } from './error'; import { deprecate, isUint8Array, randomBytes } from './parser/utils'; +import { BSONDataView, ByteUtils } from './utils/byte_utils'; // Regular expression that checks for hex value const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$'); @@ -11,7 +10,7 @@ let PROCESS_UNIQUE: Uint8Array | null = null; /** @public */ export interface ObjectIdLike { - id: string | Buffer; + id: string | Uint8Array; __id?: string; toHexString(): string; } @@ -37,7 +36,7 @@ export class ObjectId { static cacheHexString: boolean; /** ObjectId Bytes @internal */ - private [kId]!: Buffer; + private [kId]!: Uint8Array; /** ObjectId hexString cache @internal */ private __id?: string; @@ -46,7 +45,7 @@ export class ObjectId { * * @param inputId - Can be a 24 character hex string, 12 byte binary Buffer, or a number. */ - constructor(inputId?: string | number | ObjectId | ObjectIdLike | Buffer | Uint8Array) { + constructor(inputId?: string | number | ObjectId | ObjectIdLike | Uint8Array) { if (!(this instanceof ObjectId)) return new ObjectId(inputId); // workingId is set based on type of input and whether valid id exists for the input @@ -58,7 +57,7 @@ export class ObjectId { ); } if ('toHexString' in inputId && typeof inputId.toHexString === 'function') { - workingId = Buffer.from(inputId.toHexString(), 'hex'); + workingId = ByteUtils.fromHex(inputId.toHexString()); } else { workingId = inputId.id; } @@ -73,17 +72,18 @@ export class ObjectId { this[kId] = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined); } else if (ArrayBuffer.isView(workingId) && workingId.byteLength === 12) { // If intstanceof matches we can escape calling ensure buffer in Node.js environments - this[kId] = workingId instanceof Buffer ? workingId : ensureBuffer(workingId); + this[kId] = ByteUtils.toLocalBufferType(workingId); } else if (typeof workingId === 'string') { if (workingId.length === 12) { - const bytes = Buffer.from(workingId); + // TODO(NODE-4361): Remove string of length 12 support + const bytes = ByteUtils.fromUTF8(workingId); if (bytes.byteLength === 12) { this[kId] = bytes; } else { throw new BSONTypeError('Argument passed in must be a string of 12 bytes'); } } else if (workingId.length === 24 && checkForHexRegExp.test(workingId)) { - this[kId] = Buffer.from(workingId, 'hex'); + this[kId] = ByteUtils.fromHex(workingId); } else { throw new BSONTypeError( 'Argument passed in must be a string of 12 bytes or a string of 24 hex characters or an integer' @@ -94,7 +94,7 @@ export class ObjectId { } // If we are caching the hex string if (ObjectId.cacheHexString) { - this.__id = this.id.toString('hex'); + this.__id = ByteUtils.toHex(this.id); } } @@ -102,14 +102,14 @@ export class ObjectId { * The ObjectId bytes * @readonly */ - get id(): Buffer { + get id(): Uint8Array { return this[kId]; } - set id(value: Buffer) { + set id(value: Uint8Array) { this[kId] = value; if (ObjectId.cacheHexString) { - this.__id = value.toString('hex'); + this.__id = ByteUtils.toHex(value); } } @@ -118,12 +118,12 @@ export class ObjectId { * @deprecated Please use getTimestamp / createFromTime which returns an int32 epoch */ get generationTime(): number { - return this.id.readInt32BE(0); + return BSONDataView.fromUint8Array(this.id).getUint32(0, false); } set generationTime(value: number) { // Encode time into first 4 bytes - this.id.writeUInt32BE(value, 0); + BSONDataView.fromUint8Array(this.id).setUint32(0, value, false); } /** Returns the ObjectId id as a 24 character hex string representation */ @@ -132,7 +132,7 @@ export class ObjectId { return this.__id; } - const hexString = this.id.toString('hex'); + const hexString = ByteUtils.toHex(this.id); if (ObjectId.cacheHexString && !this.__id) { this.__id = hexString; @@ -156,16 +156,16 @@ export class ObjectId { * * @param time - pass in a second based timestamp. */ - static generate(time?: number): Buffer { + static generate(time?: number): Uint8Array { if ('number' !== typeof time) { time = Math.floor(Date.now() / 1000); } const inc = ObjectId.getInc(); - const buffer = Buffer.alloc(12); + const buffer = ByteUtils.allocate(12); // 4-byte timestamp - buffer.writeUInt32BE(time, 0); + BSONDataView.fromUint8Array(buffer).setUint32(0, time, false); // set PROCESS_UNIQUE if yet not initialized if (PROCESS_UNIQUE === null) { @@ -188,13 +188,13 @@ export class ObjectId { } /** - * Converts the id into a 24 character hex string for printing - * - * @param format - The Buffer toString format parameter. + * Converts the id into a 24 character hex string for printing, unless encoding is provided. + * @param encoding - hex or base64 */ - toString(format?: string): string { + toString(encoding?: 'hex' | 'base64'): string { // Is the id a buffer then use the buffer toString method to return the format - if (format) return this.id.toString(format); + if (encoding === 'base64') return ByteUtils.toBase64(this.id); + if (encoding === 'hex') return this.toHexString(); return this.toHexString(); } @@ -214,7 +214,7 @@ export class ObjectId { } if (otherId instanceof ObjectId) { - return this[kId][11] === otherId[kId][11] && this[kId].equals(otherId[kId]); + return this[kId][11] === otherId[kId][11] && ByteUtils.equals(this[kId], otherId[kId]); } if ( @@ -223,7 +223,7 @@ export class ObjectId { otherId.length === 12 && isUint8Array(this.id) ) { - return otherId === Buffer.prototype.toString.call(this.id, 'latin1'); + return ByteUtils.equals(this.id, ByteUtils.fromISO88591(otherId)); } if (typeof otherId === 'string' && ObjectId.isValid(otherId) && otherId.length === 24) { @@ -231,7 +231,7 @@ export class ObjectId { } if (typeof otherId === 'string' && ObjectId.isValid(otherId) && otherId.length === 12) { - return Buffer.from(otherId).equals(this.id); + return ByteUtils.equals(ByteUtils.fromUTF8(otherId), this.id); } if ( @@ -250,7 +250,7 @@ export class ObjectId { /** Returns the generation date (accurate up to the second) that this ID was generated. */ getTimestamp(): Date { const timestamp = new Date(); - const time = this.id.readUInt32BE(0); + const time = BSONDataView.fromUint8Array(this.id).getUint32(0, false); timestamp.setTime(Math.floor(time) * 1000); return timestamp; } @@ -266,9 +266,9 @@ export class ObjectId { * @param time - an integer number representing a number of seconds. */ static createFromTime(time: number): ObjectId { - const buffer = Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + const buffer = ByteUtils.fromNumberArray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); // Encode time into first 4 bytes - buffer.writeUInt32BE(time, 0); + BSONDataView.fromUint8Array(buffer).setUint32(0, time, false); // Return the new objectId return new ObjectId(buffer); } @@ -286,7 +286,7 @@ export class ObjectId { ); } - return new ObjectId(Buffer.from(hexString, 'hex')); + return new ObjectId(ByteUtils.fromHex(hexString)); } /** @@ -294,7 +294,7 @@ export class ObjectId { * * @param id - ObjectId instance to validate. */ - static isValid(id: string | number | ObjectId | ObjectIdLike | Buffer | Uint8Array): boolean { + static isValid(id: string | number | ObjectId | ObjectIdLike | Uint8Array): boolean { if (id == null) return false; try { diff --git a/src/parser/calculate_size.ts b/src/parser/calculate_size.ts index cc7f431e..b4a20861 100644 --- a/src/parser/calculate_size.ts +++ b/src/parser/calculate_size.ts @@ -1,7 +1,7 @@ -import { Buffer } from 'buffer'; import { Binary } from '../binary'; import type { Document } from '../bson'; import * as constants from '../constants'; +import { ByteUtils } from '../utils/byte_utils'; import { isAnyArrayBuffer, isDate, isRegExp, normalizedFunctionString } from './utils'; export function calculateObjectSize( @@ -53,7 +53,7 @@ function calculateElement( switch (typeof value) { case 'string': - return 1 + Buffer.byteLength(name, 'utf8') + 1 + 4 + Buffer.byteLength(value, 'utf8') + 1; + return 1 + ByteUtils.utf8ByteLength(name) + 1 + 4 + ByteUtils.utf8ByteLength(value) + 1; case 'number': if ( Math.floor(value) === value && @@ -62,61 +62,61 @@ function calculateElement( ) { if (value >= constants.BSON_INT32_MIN && value <= constants.BSON_INT32_MAX) { // 32 bit - return (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + (4 + 1); + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (4 + 1); } else { - return (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + (8 + 1); + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1); } } else { // 64 bit - return (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + (8 + 1); + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1); } case 'undefined': if (isArray || !ignoreUndefined) - return (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + 1; + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1; return 0; case 'boolean': - return (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + (1 + 1); + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (1 + 1); case 'object': if (value == null || value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') { - return (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + 1; + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1; } else if (value['_bsontype'] === 'ObjectId' || value['_bsontype'] === 'ObjectID') { - return (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + (12 + 1); + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (12 + 1); } else if (value instanceof Date || isDate(value)) { - return (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + (8 + 1); + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1); } else if ( ArrayBuffer.isView(value) || value instanceof ArrayBuffer || isAnyArrayBuffer(value) ) { return ( - (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + (1 + 4 + 1) + value.byteLength + (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (1 + 4 + 1) + value.byteLength ); } else if ( value['_bsontype'] === 'Long' || value['_bsontype'] === 'Double' || value['_bsontype'] === 'Timestamp' ) { - return (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + (8 + 1); + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (8 + 1); } else if (value['_bsontype'] === 'Decimal128') { - return (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + (16 + 1); + return (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (16 + 1); } else if (value['_bsontype'] === 'Code') { // Calculate size depending on the availability of a scope if (value.scope != null && Object.keys(value.scope).length > 0) { return ( - (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + + (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + 4 + 4 + - Buffer.byteLength(value.code.toString(), 'utf8') + + ByteUtils.utf8ByteLength(value.code.toString()) + 1 + calculateObjectSize(value.scope, serializeFunctions, ignoreUndefined) ); } else { return ( - (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + + (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + 4 + - Buffer.byteLength(value.code.toString(), 'utf8') + + ByteUtils.utf8ByteLength(value.code.toString()) + 1 ); } @@ -125,18 +125,18 @@ function calculateElement( // Check what kind of subtype we have if (binary.sub_type === Binary.SUBTYPE_BYTE_ARRAY) { return ( - (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + + (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (binary.position + 1 + 4 + 1 + 4) ); } else { return ( - (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + (binary.position + 1 + 4 + 1) + (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + (binary.position + 1 + 4 + 1) ); } } else if (value['_bsontype'] === 'Symbol') { return ( - (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + - Buffer.byteLength(value.value, 'utf8') + + (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + + ByteUtils.utf8ByteLength(value.value) + 4 + 1 + 1 @@ -157,15 +157,15 @@ function calculateElement( } return ( - (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + + (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + calculateObjectSize(ordered_values, serializeFunctions, ignoreUndefined) ); } else if (value instanceof RegExp || isRegExp(value)) { return ( - (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + + (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + - Buffer.byteLength(value.source, 'utf8') + + ByteUtils.utf8ByteLength(value.source) + 1 + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + @@ -174,16 +174,16 @@ function calculateElement( ); } else if (value['_bsontype'] === 'BSONRegExp') { return ( - (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + + (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + - Buffer.byteLength(value.pattern, 'utf8') + + ByteUtils.utf8ByteLength(value.pattern) + 1 + - Buffer.byteLength(value.options, 'utf8') + + ByteUtils.utf8ByteLength(value.options) + 1 ); } else { return ( - (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + + (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + calculateObjectSize(value, serializeFunctions, ignoreUndefined) + 1 ); @@ -192,9 +192,9 @@ function calculateElement( // WTF for 0.4.X where typeof /someregexp/ === 'function' if (value instanceof RegExp || isRegExp(value) || String.call(value) === '[object RegExp]') { return ( - (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + + (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + - Buffer.byteLength(value.source, 'utf8') + + ByteUtils.utf8ByteLength(value.source) + 1 + (value.global ? 1 : 0) + (value.ignoreCase ? 1 : 0) + @@ -204,20 +204,20 @@ function calculateElement( } else { if (serializeFunctions && value.scope != null && Object.keys(value.scope).length > 0) { return ( - (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + + (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + 4 + 4 + - Buffer.byteLength(normalizedFunctionString(value), 'utf8') + + ByteUtils.utf8ByteLength(normalizedFunctionString(value)) + 1 + calculateObjectSize(value.scope, serializeFunctions, ignoreUndefined) ); } else if (serializeFunctions) { return ( - (name != null ? Buffer.byteLength(name, 'utf8') + 1 : 0) + + (name != null ? ByteUtils.utf8ByteLength(name) + 1 : 0) + 1 + 4 + - Buffer.byteLength(normalizedFunctionString(value), 'utf8') + + ByteUtils.utf8ByteLength(normalizedFunctionString(value)) + 1 ); } diff --git a/src/parser/deserializer.ts b/src/parser/deserializer.ts index faef442f..cd6d3c00 100644 --- a/src/parser/deserializer.ts +++ b/src/parser/deserializer.ts @@ -1,4 +1,3 @@ -import { Buffer } from 'buffer'; import { Binary } from '../binary'; import type { Document } from '../bson'; import { Code } from '../code'; @@ -15,6 +14,7 @@ import { ObjectId } from '../objectid'; import { BSONRegExp } from '../regexp'; import { BSONSymbol } from '../symbol'; import { Timestamp } from '../timestamp'; +import { ByteUtils } from '../utils/byte_utils'; import { validateUtf8 } from '../validate_utf8'; /** @public */ @@ -70,7 +70,7 @@ const JS_INT_MIN_LONG = Long.fromNumber(constants.JS_INT_MIN); const functionCache: { [hash: string]: Function } = {}; export function deserialize( - buffer: Buffer, + buffer: Uint8Array, options: DeserializeOptions, isArray?: boolean ): Document { @@ -115,7 +115,7 @@ export function deserialize( const allowedDBRefKeys = /^\$ref$|^\$id$|^\$db$/; function deserializeObject( - buffer: Buffer, + buffer: Uint8Array, index: number, options: DeserializeOptions, isArray = false @@ -216,7 +216,7 @@ function deserializeObject( if (i >= buffer.byteLength) throw new BSONError('Bad BSON Document: illegal CString'); // Represents the key - const name = isArray ? arrayIndex++ : buffer.toString('utf8', index, i); + const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer.subarray(index, i)); // shouldValidateKey is true if the key should be validated, false otherwise let shouldValidateKey = true; @@ -249,8 +249,8 @@ function deserializeObject( value = getValidatedString(buffer, index, index + stringSize - 1, shouldValidateKey); index = index + stringSize; } else if (elementType === constants.BSON_DATA_OID) { - const oid = Buffer.alloc(12); - buffer.copy(oid, 0, index, index + 12); + const oid = ByteUtils.allocate(12); + oid.set(buffer.subarray(index, index + 12)); value = new ObjectId(oid); index = index + 12; } else if (elementType === constants.BSON_DATA_INT && promoteValues === false) { @@ -367,9 +367,9 @@ function deserializeObject( } } else if (elementType === constants.BSON_DATA_DECIMAL128) { // Buffer to contain the decimal bytes - const bytes = Buffer.alloc(16); + const bytes = ByteUtils.allocate(16); // Copy the next 16 bytes into the bytes buffer - buffer.copy(bytes, 0, index, index + 16); + bytes.set(buffer.subarray(index, index + 16), 0); // Update index index = index + 16; // Assign the new Decimal128 value @@ -414,7 +414,7 @@ function deserializeObject( } if (promoteBuffers && promoteValues) { - value = buffer.slice(index, index + binarySize); + value = ByteUtils.toLocalBufferType(buffer.slice(index, index + binarySize)); } else { value = new Binary(buffer.slice(index, index + binarySize), subType); if (subType === constants.BSON_BINARY_SUBTYPE_UUID_NEW) { @@ -422,7 +422,7 @@ function deserializeObject( } } } else { - const _buffer = Buffer.alloc(binarySize); + const _buffer = ByteUtils.allocate(binarySize); // If we have subtype 2 skip the 4 bytes for the size if (subType === Binary.SUBTYPE_BYTE_ARRAY) { binarySize = @@ -464,7 +464,7 @@ function deserializeObject( // If are at the end of the buffer there is a problem with the document if (i >= buffer.length) throw new BSONError('Bad BSON Document: illegal CString'); // Return the C string - const source = buffer.toString('utf8', index, i); + const source = ByteUtils.toUTF8(buffer.subarray(index, i)); // Create the regexp index = i + 1; @@ -477,7 +477,7 @@ function deserializeObject( // If are at the end of the buffer there is a problem with the document if (i >= buffer.length) throw new BSONError('Bad BSON Document: illegal CString'); // Return the C string - const regExpOptions = buffer.toString('utf8', index, i); + const regExpOptions = ByteUtils.toUTF8(buffer.subarray(index, i)); index = i + 1; // For each option add the corresponding one for javascript @@ -509,7 +509,7 @@ function deserializeObject( // If are at the end of the buffer there is a problem with the document if (i >= buffer.length) throw new BSONError('Bad BSON Document: illegal CString'); // Return the C string - const source = buffer.toString('utf8', index, i); + const source = ByteUtils.toUTF8(buffer.subarray(index, i)); index = i + 1; // Get the start search index @@ -521,7 +521,7 @@ function deserializeObject( // If are at the end of the buffer there is a problem with the document if (i >= buffer.length) throw new BSONError('Bad BSON Document: illegal CString'); // Return the C string - const regExpOptions = buffer.toString('utf8', index, i); + const regExpOptions = ByteUtils.toUTF8(buffer.subarray(index, i)); index = i + 1; // Set the object @@ -687,13 +687,13 @@ function deserializeObject( throw new BSONError('Invalid UTF-8 string in BSON document'); } } - const namespace = buffer.toString('utf8', index, index + stringSize - 1); + const namespace = ByteUtils.toUTF8(buffer.subarray(index, index + stringSize - 1)); // Update parse index position index = index + stringSize; // Read the oid - const oidBuffer = Buffer.alloc(12); - buffer.copy(oidBuffer, 0, index, index + 12); + const oidBuffer = ByteUtils.allocate(12); + oidBuffer.set(buffer.subarray(index, index + 12), 0); const oid = new ObjectId(oidBuffer); // Update the index @@ -761,12 +761,12 @@ function isolateEval( } function getValidatedString( - buffer: Buffer, + buffer: Uint8Array, start: number, end: number, shouldValidateUtf8: boolean ) { - const value = buffer.toString('utf8', start, end); + const value = ByteUtils.toUTF8(buffer.subarray(start, end)); // if utf8 validation is on, do the check if (shouldValidateUtf8) { for (let i = 0; i < value.length; i++) { diff --git a/src/parser/serializer.ts b/src/parser/serializer.ts index e76402aa..dadbf7b5 100644 --- a/src/parser/serializer.ts +++ b/src/parser/serializer.ts @@ -1,4 +1,3 @@ -import type { Buffer } from 'buffer'; import { Binary } from '../binary'; import type { BSONSymbol, DBRef, Document, MaxKey } from '../bson'; import type { Code } from '../code'; @@ -6,7 +5,6 @@ import * as constants from '../constants'; import type { DBRefLike } from '../db_ref'; import type { Decimal128 } from '../decimal128'; import type { Double } from '../double'; -import { ensureBuffer } from '../ensure_buffer'; import { BSONError, BSONTypeError } from '../error'; import { isBSONType } from '../extended_json'; import type { Int32 } from '../int_32'; @@ -15,6 +13,7 @@ import { Map } from '../map'; import type { MinKey } from '../min_key'; import type { ObjectId } from '../objectid'; import type { BSONRegExp } from '../regexp'; +import { ByteUtils } from '../utils/byte_utils'; import { isBigInt64Array, isBigUInt64Array, @@ -48,24 +47,16 @@ const ignoreKeys = new Set(['$db', '$ref', '$id', '$clusterTime']); * This will catch any errors in index as a string generation */ -function serializeString( - buffer: Buffer, - key: string, - value: string, - index: number, - isArray?: boolean -) { +function serializeString(buffer: Uint8Array, key: string, value: string, index: number) { // Encode String type buffer[index++] = constants.BSON_DATA_STRING; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes + 1; buffer[index - 1] = 0; // Write the string - const size = buffer.write(value, index + 4, undefined, 'utf8'); + const size = ByteUtils.encodeUTF8Into(buffer, value, index + 4); // Write the size of the string to buffer buffer[index + 3] = ((size + 1) >> 24) & 0xff; buffer[index + 2] = ((size + 1) >> 16) & 0xff; @@ -84,13 +75,7 @@ const DV_FOR_FLOAT64 = new DataView( SPACE_FOR_FLOAT64.byteOffset, SPACE_FOR_FLOAT64.byteLength ); -function serializeNumber( - buffer: Buffer, - key: string, - value: number, - index: number, - isArray?: boolean -) { +function serializeNumber(buffer: Uint8Array, key: string, value: number, index: number) { // We have an integer value // TODO(NODE-2529): Add support for big int if ( @@ -102,9 +87,7 @@ function serializeNumber( // Set int type 32 bits or less buffer[index++] = constants.BSON_DATA_INT; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; @@ -117,9 +100,7 @@ function serializeNumber( // Encode as double buffer[index++] = constants.BSON_DATA_NUMBER; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; @@ -133,14 +114,12 @@ function serializeNumber( return index; } -function serializeNull(buffer: Buffer, key: string, _: unknown, index: number, isArray?: boolean) { +function serializeNull(buffer: Uint8Array, key: string, _: unknown, index: number) { // Set long type buffer[index++] = constants.BSON_DATA_NULL; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; @@ -148,19 +127,11 @@ function serializeNull(buffer: Buffer, key: string, _: unknown, index: number, i return index; } -function serializeBoolean( - buffer: Buffer, - key: string, - value: boolean, - index: number, - isArray?: boolean -) { +function serializeBoolean(buffer: Uint8Array, key: string, value: boolean, index: number) { // Write the type buffer[index++] = constants.BSON_DATA_BOOLEAN; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; @@ -169,13 +140,11 @@ function serializeBoolean( return index; } -function serializeDate(buffer: Buffer, key: string, value: Date, index: number, isArray?: boolean) { +function serializeDate(buffer: Uint8Array, key: string, value: Date, index: number) { // Write the type buffer[index++] = constants.BSON_DATA_DATE; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; @@ -197,19 +166,11 @@ function serializeDate(buffer: Buffer, key: string, value: Date, index: number, return index; } -function serializeRegExp( - buffer: Buffer, - key: string, - value: RegExp, - index: number, - isArray?: boolean -) { +function serializeRegExp(buffer: Uint8Array, key: string, value: RegExp, index: number) { // Write the type buffer[index++] = constants.BSON_DATA_REGEXP; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; @@ -218,7 +179,7 @@ function serializeRegExp( throw Error('value ' + value.source + ' must not contain null bytes'); } // Adjust the index - index = index + buffer.write(value.source, index, undefined, 'utf8'); + index = index + ByteUtils.encodeUTF8Into(buffer, value.source, index); // Write zero buffer[index++] = 0x00; // Write the parameters @@ -231,19 +192,11 @@ function serializeRegExp( return index; } -function serializeBSONRegExp( - buffer: Buffer, - key: string, - value: BSONRegExp, - index: number, - isArray?: boolean -) { +function serializeBSONRegExp(buffer: Uint8Array, key: string, value: BSONRegExp, index: number) { // Write the type buffer[index++] = constants.BSON_DATA_REGEXP; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; @@ -256,23 +209,18 @@ function serializeBSONRegExp( } // Adjust the index - index = index + buffer.write(value.pattern, index, undefined, 'utf8'); + index = index + ByteUtils.encodeUTF8Into(buffer, value.pattern, index); // Write zero buffer[index++] = 0x00; // Write the options - index = index + buffer.write(value.options.split('').sort().join(''), index, undefined, 'utf8'); + const sortedOptions = value.options.split('').sort().join(''); + index = index + ByteUtils.encodeUTF8Into(buffer, sortedOptions, index); // Add ending zero buffer[index++] = 0x00; return index; } -function serializeMinMax( - buffer: Buffer, - key: string, - value: MinKey | MaxKey, - index: number, - isArray?: boolean -) { +function serializeMinMax(buffer: Uint8Array, key: string, value: MinKey | MaxKey, index: number) { // Write the type of either min or max key if (value === null) { buffer[index++] = constants.BSON_DATA_NULL; @@ -283,39 +231,25 @@ function serializeMinMax( } // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; return index; } -function serializeObjectId( - buffer: Buffer, - key: string, - value: ObjectId, - index: number, - isArray?: boolean -) { +function serializeObjectId(buffer: Uint8Array, key: string, value: ObjectId, index: number) { // Write the type buffer[index++] = constants.BSON_DATA_OID; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; // Write the objectId into the shared buffer - if (typeof value.id === 'string') { - buffer.write(value.id, index, undefined, 'binary'); - } else if (isUint8Array(value.id)) { - // Use the standard JS methods here because buffer.copy() is buggy with the - // browser polyfill + if (isUint8Array(value.id)) { buffer.set(value.id.subarray(0, 12), index); } else { throw new BSONTypeError('object [' + JSON.stringify(value) + '] is not a valid ObjectId'); @@ -325,19 +259,11 @@ function serializeObjectId( return index + 12; } -function serializeBuffer( - buffer: Buffer, - key: string, - value: Buffer | Uint8Array, - index: number, - isArray?: boolean -) { +function serializeBuffer(buffer: Uint8Array, key: string, value: Uint8Array, index: number) { // Write the type buffer[index++] = constants.BSON_DATA_BINARY; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; @@ -351,14 +277,14 @@ function serializeBuffer( // Write the default subtype buffer[index++] = constants.BSON_BINARY_SUBTYPE_DEFAULT; // Copy the content form the binary field to the buffer - buffer.set(ensureBuffer(value), index); + buffer.set(value, index); // Adjust the index index = index + size; return index; } function serializeObject( - buffer: Buffer, + buffer: Uint8Array, key: string, value: Document, index: number, @@ -366,7 +292,6 @@ function serializeObject( depth = 0, serializeFunctions = false, ignoreUndefined = true, - isArray = false, path: Document[] = [] ) { for (let i = 0; i < path.length; i++) { @@ -378,9 +303,7 @@ function serializeObject( // Write the type buffer[index++] = Array.isArray(value) ? constants.BSON_DATA_ARRAY : constants.BSON_DATA_OBJECT; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; @@ -399,36 +322,24 @@ function serializeObject( return endIndex; } -function serializeDecimal128( - buffer: Buffer, - key: string, - value: Decimal128, - index: number, - isArray?: boolean -) { +function serializeDecimal128(buffer: Uint8Array, key: string, value: Decimal128, index: number) { buffer[index++] = constants.BSON_DATA_DECIMAL128; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; // Write the data from the value - // Prefer the standard JS methods because their typechecking is not buggy, - // unlike the `buffer` polyfill's. buffer.set(value.bytes.subarray(0, 16), index); return index + 16; } -function serializeLong(buffer: Buffer, key: string, value: Long, index: number, isArray?: boolean) { +function serializeLong(buffer: Uint8Array, key: string, value: Long, index: number) { // Write the type buffer[index++] = value._bsontype === 'Long' ? constants.BSON_DATA_LONG : constants.BSON_DATA_TIMESTAMP; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; @@ -448,20 +359,12 @@ function serializeLong(buffer: Buffer, key: string, value: Long, index: number, return index; } -function serializeInt32( - buffer: Buffer, - key: string, - value: Int32 | number, - index: number, - isArray?: boolean -) { +function serializeInt32(buffer: Uint8Array, key: string, value: Int32 | number, index: number) { value = value.valueOf(); // Set int type 32 bits or less buffer[index++] = constants.BSON_DATA_INT; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; @@ -473,20 +376,12 @@ function serializeInt32( return index; } -function serializeDouble( - buffer: Buffer, - key: string, - value: Double, - index: number, - isArray?: boolean -) { +function serializeDouble(buffer: Uint8Array, key: string, value: Double, index: number) { // Encode as double buffer[index++] = constants.BSON_DATA_NUMBER; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; @@ -502,19 +397,16 @@ function serializeDouble( } function serializeFunction( - buffer: Buffer, + buffer: Uint8Array, key: string, value: Function, index: number, _checkKeys = false, - _depth = 0, - isArray?: boolean + _depth = 0 ) { buffer[index++] = constants.BSON_DATA_CODE; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; @@ -522,7 +414,7 @@ function serializeFunction( const functionString = normalizedFunctionString(value); // Write the string - const size = buffer.write(functionString, index + 4, undefined, 'utf8') + 1; + const size = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1; // Write the size of the string to buffer buffer[index] = size & 0xff; buffer[index + 1] = (size >> 8) & 0xff; @@ -536,23 +428,20 @@ function serializeFunction( } function serializeCode( - buffer: Buffer, + buffer: Uint8Array, key: string, value: Code, index: number, checkKeys = false, depth = 0, serializeFunctions = false, - ignoreUndefined = true, - isArray = false + ignoreUndefined = true ) { if (value.scope && typeof value.scope === 'object') { // Write the type buffer[index++] = constants.BSON_DATA_CODE_W_SCOPE; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; @@ -566,7 +455,7 @@ function serializeCode( // Index adjustment index = index + 4; // Write string into buffer - const codeSize = buffer.write(functionString, index + 4, undefined, 'utf8') + 1; + const codeSize = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1; // Write the size of the string to buffer buffer[index] = codeSize & 0xff; buffer[index + 1] = (codeSize >> 8) & 0xff; @@ -603,16 +492,14 @@ function serializeCode( } else { buffer[index++] = constants.BSON_DATA_CODE; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; // Function string const functionString = value.code.toString(); // Write the string - const size = buffer.write(functionString, index + 4, undefined, 'utf8') + 1; + const size = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1; // Write the size of the string to buffer buffer[index] = size & 0xff; buffer[index + 1] = (size >> 8) & 0xff; @@ -627,24 +514,16 @@ function serializeCode( return index; } -function serializeBinary( - buffer: Buffer, - key: string, - value: Binary, - index: number, - isArray?: boolean -) { +function serializeBinary(buffer: Uint8Array, key: string, value: Binary, index: number) { // Write the type buffer[index++] = constants.BSON_DATA_BINARY; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; // Extract the buffer - const data = value.value(true) as Buffer | Uint8Array; + const data = value.buffer; // Calculate size let size = value.position; // Add the deprecated 02 type 4 bytes of size to total @@ -673,24 +552,16 @@ function serializeBinary( return index; } -function serializeSymbol( - buffer: Buffer, - key: string, - value: BSONSymbol, - index: number, - isArray?: boolean -) { +function serializeSymbol(buffer: Uint8Array, key: string, value: BSONSymbol, index: number) { // Write the type buffer[index++] = constants.BSON_DATA_SYMBOL; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; buffer[index++] = 0; // Write the string - const size = buffer.write(value.value, index + 4, undefined, 'utf8') + 1; + const size = ByteUtils.encodeUTF8Into(buffer, value.value, index + 4) + 1; // Write the size of the string to buffer buffer[index] = size & 0xff; buffer[index + 1] = (size >> 8) & 0xff; @@ -704,20 +575,17 @@ function serializeSymbol( } function serializeDBRef( - buffer: Buffer, + buffer: Uint8Array, key: string, value: DBRef, index: number, depth: number, - serializeFunctions: boolean, - isArray?: boolean + serializeFunctions: boolean ) { // Write the type buffer[index++] = constants.BSON_DATA_OBJECT; // Number of written bytes - const numberOfWrittenBytes = !isArray - ? buffer.write(key, index, undefined, 'utf8') - : buffer.write(key, index, undefined, 'ascii'); + const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index); // Encode the name index = index + numberOfWrittenBytes; @@ -748,7 +616,7 @@ function serializeDBRef( } export function serializeInto( - buffer: Buffer, + buffer: Uint8Array, object: Document, checkKeys = false, startingIndex = 0, @@ -779,25 +647,25 @@ export function serializeInto( } if (typeof value === 'string') { - index = serializeString(buffer, key, value, index, true); + index = serializeString(buffer, key, value, index); } else if (typeof value === 'number') { - index = serializeNumber(buffer, key, value, index, true); + index = serializeNumber(buffer, key, value, index); } else if (typeof value === 'bigint') { throw new BSONTypeError('Unsupported type BigInt, please use Decimal128'); } else if (typeof value === 'boolean') { - index = serializeBoolean(buffer, key, value, index, true); + index = serializeBoolean(buffer, key, value, index); } else if (value instanceof Date || isDate(value)) { - index = serializeDate(buffer, key, value, index, true); + index = serializeDate(buffer, key, value, index); } else if (value === undefined) { - index = serializeNull(buffer, key, value, index, true); + index = serializeNull(buffer, key, value, index); } else if (value === null) { - index = serializeNull(buffer, key, value, index, true); + index = serializeNull(buffer, key, value, index); } else if (value['_bsontype'] === 'ObjectId' || value['_bsontype'] === 'ObjectID') { - index = serializeObjectId(buffer, key, value, index, true); + index = serializeObjectId(buffer, key, value, index); } else if (isUint8Array(value)) { - index = serializeBuffer(buffer, key, value, index, true); + index = serializeBuffer(buffer, key, value, index); } else if (value instanceof RegExp || isRegExp(value)) { - index = serializeRegExp(buffer, key, value, index, true); + index = serializeRegExp(buffer, key, value, index); } else if (typeof value === 'object' && value['_bsontype'] == null) { index = serializeObject( buffer, @@ -808,7 +676,6 @@ export function serializeInto( depth, serializeFunctions, ignoreUndefined, - true, path ); } else if ( @@ -816,13 +683,13 @@ export function serializeInto( isBSONType(value) && value._bsontype === 'Decimal128' ) { - index = serializeDecimal128(buffer, key, value, index, true); + index = serializeDecimal128(buffer, key, value, index); } else if (value['_bsontype'] === 'Long' || value['_bsontype'] === 'Timestamp') { - index = serializeLong(buffer, key, value, index, true); + index = serializeLong(buffer, key, value, index); } else if (value['_bsontype'] === 'Double') { - index = serializeDouble(buffer, key, value, index, true); + index = serializeDouble(buffer, key, value, index); } else if (typeof value === 'function' && serializeFunctions) { - index = serializeFunction(buffer, key, value, index, checkKeys, depth, true); + index = serializeFunction(buffer, key, value, index, checkKeys, depth); } else if (value['_bsontype'] === 'Code') { index = serializeCode( buffer, @@ -832,21 +699,20 @@ export function serializeInto( checkKeys, depth, serializeFunctions, - ignoreUndefined, - true + ignoreUndefined ); } else if (value['_bsontype'] === 'Binary') { - index = serializeBinary(buffer, key, value, index, true); + index = serializeBinary(buffer, key, value, index); } else if (value['_bsontype'] === 'Symbol') { - index = serializeSymbol(buffer, key, value, index, true); + index = serializeSymbol(buffer, key, value, index); } else if (value['_bsontype'] === 'DBRef') { - index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions, true); + index = serializeDBRef(buffer, key, value, index, depth, serializeFunctions); } else if (value['_bsontype'] === 'BSONRegExp') { - index = serializeBSONRegExp(buffer, key, value, index, true); + index = serializeBSONRegExp(buffer, key, value, index); } else if (value['_bsontype'] === 'Int32') { - index = serializeInt32(buffer, key, value, index, true); + index = serializeInt32(buffer, key, value, index); } else if (value['_bsontype'] === 'MinKey' || value['_bsontype'] === 'MaxKey') { - index = serializeMinMax(buffer, key, value, index, true); + index = serializeMinMax(buffer, key, value, index); } else if (typeof value['_bsontype'] !== 'undefined') { throw new BSONTypeError(`Unrecognized or invalid _bsontype: ${String(value['_bsontype'])}`); } @@ -914,7 +780,6 @@ export function serializeInto( depth, serializeFunctions, ignoreUndefined, - false, path ); } else if (type === 'object' && value['_bsontype'] === 'Decimal128') { @@ -935,7 +800,7 @@ export function serializeInto( ignoreUndefined ); } else if (typeof value === 'function' && serializeFunctions) { - index = serializeFunction(buffer, key, value, index, checkKeys, depth, serializeFunctions); + index = serializeFunction(buffer, key, value, index, checkKeys, depth); } else if (value['_bsontype'] === 'Binary') { index = serializeBinary(buffer, key, value, index); } else if (value['_bsontype'] === 'Symbol') { @@ -1019,7 +884,6 @@ export function serializeInto( depth, serializeFunctions, ignoreUndefined, - false, path ); } else if (type === 'object' && value['_bsontype'] === 'Decimal128') { @@ -1040,7 +904,7 @@ export function serializeInto( ignoreUndefined ); } else if (typeof value === 'function' && serializeFunctions) { - index = serializeFunction(buffer, key, value, index, checkKeys, depth, serializeFunctions); + index = serializeFunction(buffer, key, value, index, checkKeys, depth); } else if (value['_bsontype'] === 'Binary') { index = serializeBinary(buffer, key, value, index); } else if (value['_bsontype'] === 'Symbol') { diff --git a/src/parser/utils.ts b/src/parser/utils.ts index abf935df..54695f22 100644 --- a/src/parser/utils.ts +++ b/src/parser/utils.ts @@ -1,4 +1,4 @@ -import { Buffer } from 'buffer'; +import { ByteUtils } from '../utils/byte_utils'; import { getGlobal } from '../utils/global'; type RandomBytesFunction = (size: number) => Uint8Array; @@ -22,7 +22,7 @@ const insecureRandomBytes: RandomBytesFunction = function insecureRandomBytes(si : 'BSON: No cryptographic implementation for random bytes present, falling back to a less secure implementation.'; console.warn(insecureWarning); - const result = Buffer.alloc(size); + const result = ByteUtils.allocate(size); for (let i = 0; i < size; ++i) result[i] = Math.floor(Math.random() * 256); return result; }; @@ -42,13 +42,13 @@ const detectRandomBytes = (): RandomBytesFunction => { // browser crypto implementation(s) const target = window.crypto || window.msCrypto; // allow for IE11 if (target && target.getRandomValues) { - return size => target.getRandomValues(Buffer.alloc(size)); + return size => target.getRandomValues(ByteUtils.allocate(size)); } } if (typeof global !== 'undefined' && global.crypto && global.crypto.getRandomValues) { // allow for RN packages such as https://www.npmjs.com/package/react-native-get-random-values to populate global - return size => global.crypto.getRandomValues(Buffer.alloc(size)); + return size => global.crypto.getRandomValues(ByteUtils.allocate(size)); } return insecureRandomBytes; @@ -94,11 +94,6 @@ export function isMap(d: unknown): d is Map { return Object.prototype.toString.call(d) === '[object Map]'; } -/** Call to check if your environment has `Buffer` */ -export function haveBuffer(): boolean { - return typeof global !== 'undefined' && typeof global.Buffer !== 'undefined'; -} - // To ensure that 0.4 of node works correctly export function isDate(d: unknown): d is Date { return isObjectLike(d) && Object.prototype.toString.call(d) === '[object Date]'; diff --git a/src/utils/byte_utils.ts b/src/utils/byte_utils.ts new file mode 100644 index 00000000..7847e5fd --- /dev/null +++ b/src/utils/byte_utils.ts @@ -0,0 +1,59 @@ +import { nodeJsByteUtils } from './node_byte_utils'; +import { webByteUtils } from './web_byte_utils'; + +/** @internal */ +export type ByteUtils = { + /** Transforms the input to an instance of Buffer if running on node, otherwise Uint8Array */ + toLocalBufferType(buffer: Uint8Array | ArrayBufferView | ArrayBuffer): Uint8Array; + /** Create empty space of size */ + allocate: (size: number) => Uint8Array; + /** Check if two Uint8Arrays are deep equal */ + equals: (a: Uint8Array, b: Uint8Array) => boolean; + /** Check if two Uint8Arrays are deep equal */ + fromNumberArray: (array: number[]) => Uint8Array; + /** Create a Uint8Array from a base64 string */ + fromBase64: (base64: string) => Uint8Array; + /** Create a base64 string from bytes */ + toBase64: (buffer: Uint8Array) => string; + /** **Legacy** binary strings are an outdated method of data transfer. Do not add public API support for interpreting this format */ + fromISO88591: (codePoints: string) => Uint8Array; + /** **Legacy** binary strings are an outdated method of data transfer. Do not add public API support for interpreting this format */ + toISO88591: (buffer: Uint8Array) => string; + /** Create a Uint8Array from a hex string */ + fromHex: (hex: string) => Uint8Array; + /** Create a hex string from bytes */ + toHex: (buffer: Uint8Array) => string; + /** Create a Uint8Array containing utf8 code units from a string */ + fromUTF8: (text: string) => Uint8Array; + /** Create a string from utf8 code units */ + toUTF8: (buffer: Uint8Array) => string; + /** Get the utf8 code unit count from a string if it were to be transformed to utf8 */ + utf8ByteLength: (input: string) => number; + /** encode UTF8 bytes generated from `source` string into `destination` at byteOffset. Returns the number of bytes encoded. */ + encodeUTF8Into(destination: Uint8Array, source: string, byteOffset: number): number; +}; + +declare const Buffer: { new (): unknown; prototype?: { _isBuffer?: boolean } } | undefined; + +/** + * Check that a global Buffer exists that is a function and + * does not have a '_isBuffer' property defined on the prototype + * (this is to prevent using the npm buffer) + */ +const hasGlobalBuffer = typeof Buffer === 'function' && Buffer.prototype?._isBuffer !== true; + +/** + * This is the only ByteUtils that should be used across the rest of the BSON library. + * + * The type annotation is important here, it asserts that each of the platform specific + * utils implementations are compatible with the common one. + * + * @internal + */ +export const ByteUtils: ByteUtils = hasGlobalBuffer ? nodeJsByteUtils : webByteUtils; + +export class BSONDataView extends DataView { + static fromUint8Array(input: Uint8Array) { + return new DataView(input.buffer, input.byteOffset, input.byteLength); + } +} diff --git a/src/utils/node_byte_utils.ts b/src/utils/node_byte_utils.ts new file mode 100644 index 00000000..d347088e --- /dev/null +++ b/src/utils/node_byte_utils.ts @@ -0,0 +1,108 @@ +import { BSONError } from '../error'; + +type NodeJsEncoding = 'base64' | 'hex' | 'utf8' | 'binary'; +type NodeJsBuffer = ArrayBufferView & + Uint8Array & { + write(string: string, offset: number, length: undefined, encoding: 'utf8'): number; + copy(target: Uint8Array, targetStart: number, sourceStart: number, sourceEnd: number): number; + toString: (this: Uint8Array, encoding: NodeJsEncoding) => string; + equals: (this: Uint8Array, other: Uint8Array) => boolean; + }; +type NodeJsBufferConstructor = Omit & { + alloc: (size: number) => NodeJsBuffer; + from(array: number[]): NodeJsBuffer; + from(array: Uint8Array): NodeJsBuffer; + from(array: ArrayBuffer): NodeJsBuffer; + from(array: ArrayBuffer, byteOffset: number, byteLength: number): NodeJsBuffer; + from(base64: string, encoding: NodeJsEncoding): NodeJsBuffer; + byteLength(input: string, encoding: 'utf8'): number; + isBuffer(value: unknown): value is NodeJsBuffer; +}; + +// This can be nullish, but we gate the nodejs functions on being exported whether or not this exists +// Node.js global +declare const Buffer: NodeJsBufferConstructor; + +/** @internal */ +export const nodeJsByteUtils = { + toLocalBufferType(potentialBuffer: Uint8Array | NodeJsBuffer | ArrayBuffer): NodeJsBuffer { + if (Buffer.isBuffer(potentialBuffer)) { + return potentialBuffer; + } + + if (ArrayBuffer.isView(potentialBuffer)) { + return Buffer.from( + potentialBuffer.buffer, + potentialBuffer.byteOffset, + potentialBuffer.byteLength + ); + } + + const stringTag = + potentialBuffer?.[Symbol.toStringTag] ?? Object.prototype.toString.call(potentialBuffer); + if ( + stringTag === 'ArrayBuffer' || + stringTag === 'SharedArrayBuffer' || + stringTag === '[object ArrayBuffer]' || + stringTag === '[object SharedArrayBuffer]' + ) { + return Buffer.from(potentialBuffer); + } + + throw new BSONError(`Cannot create Buffer from ${String(potentialBuffer)}`); + }, + + allocate(size: number): NodeJsBuffer { + return Buffer.alloc(size); + }, + + equals(a: Uint8Array, b: Uint8Array): boolean { + return nodeJsByteUtils.toLocalBufferType(a).equals(b); + }, + + fromNumberArray(array: number[]): NodeJsBuffer { + return Buffer.from(array); + }, + + fromBase64(base64: string): NodeJsBuffer { + return Buffer.from(base64, 'base64'); + }, + + toBase64(buffer: Uint8Array): string { + return nodeJsByteUtils.toLocalBufferType(buffer).toString('base64'); + }, + + /** **Legacy** binary strings are an outdated method of data transfer. Do not add public API support for interpreting this format */ + fromISO88591(codePoints: string): NodeJsBuffer { + return Buffer.from(codePoints, 'binary'); + }, + + /** **Legacy** binary strings are an outdated method of data transfer. Do not add public API support for interpreting this format */ + toISO88591(buffer: Uint8Array): string { + return nodeJsByteUtils.toLocalBufferType(buffer).toString('binary'); + }, + + fromHex(hex: string): NodeJsBuffer { + return Buffer.from(hex, 'hex'); + }, + + toHex(buffer: Uint8Array): string { + return nodeJsByteUtils.toLocalBufferType(buffer).toString('hex'); + }, + + fromUTF8(text: string): NodeJsBuffer { + return Buffer.from(text, 'utf8'); + }, + + toUTF8(buffer: Uint8Array): string { + return nodeJsByteUtils.toLocalBufferType(buffer).toString('utf8'); + }, + + utf8ByteLength(input: string): number { + return Buffer.byteLength(input, 'utf8'); + }, + + encodeUTF8Into(buffer: Uint8Array, source: string, byteOffset: number): number { + return nodeJsByteUtils.toLocalBufferType(buffer).write(source, byteOffset, undefined, 'utf8'); + } +}; diff --git a/src/utils/web_byte_utils.ts b/src/utils/web_byte_utils.ts new file mode 100644 index 00000000..d4ff2df9 --- /dev/null +++ b/src/utils/web_byte_utils.ts @@ -0,0 +1,151 @@ +import { BSONError } from '../error'; + +type TextDecoder = { + readonly encoding: string; + readonly fatal: boolean; + readonly ignoreBOM: boolean; + decode(input?: Uint8Array): string; +}; +type TextDecoderConstructor = { + new (label: 'utf8', options: { fatal: boolean; ignoreBOM?: boolean }): TextDecoder; +}; + +type TextEncoder = { + readonly encoding: string; + encode(input?: string): Uint8Array; +}; +type TextEncoderConstructor = { + new (): TextEncoder; +}; + +// Web global +declare const TextDecoder: TextDecoderConstructor; +declare const TextEncoder: TextEncoderConstructor; +declare const atob: (base64: string) => string; +declare const btoa: (binary: string) => string; + +type ArrayBufferViewWithTag = ArrayBufferView & { + [Symbol.toStringTag]?: string; +}; + +const HEX_DIGIT = /(\d|[a-f])/i; + +/** @internal */ +export const webByteUtils = { + toLocalBufferType( + potentialUint8array: Uint8Array | ArrayBufferViewWithTag | ArrayBuffer + ): Uint8Array { + const stringTag = + potentialUint8array?.[Symbol.toStringTag] ?? + Object.prototype.toString.call(potentialUint8array); + + if (stringTag === 'Uint8Array') { + return potentialUint8array as Uint8Array; + } + + if (ArrayBuffer.isView(potentialUint8array)) { + return new Uint8Array( + potentialUint8array.buffer.slice( + potentialUint8array.byteOffset, + potentialUint8array.byteOffset + potentialUint8array.byteLength + ) + ); + } + + if ( + stringTag === 'ArrayBuffer' || + stringTag === 'SharedArrayBuffer' || + stringTag === '[object ArrayBuffer]' || + stringTag === '[object SharedArrayBuffer]' + ) { + return new Uint8Array(potentialUint8array); + } + + throw new BSONError(`Cannot make a Uint8Array from ${String(potentialUint8array)}`); + }, + + allocate(size: number): Uint8Array { + if (typeof size !== 'number') { + throw new TypeError(`The "size" argument must be of type number. Received ${String(size)}`); + } + return new Uint8Array(size); + }, + + equals(a: Uint8Array, b: Uint8Array): boolean { + if (a.byteLength !== b.byteLength) { + return false; + } + for (let i = 0; i < a.byteLength; i++) { + if (a[i] !== b[i]) { + return false; + } + } + return true; + }, + + fromNumberArray(array: number[]): Uint8Array { + return Uint8Array.from(array); + }, + + fromBase64(base64: string): Uint8Array { + return Uint8Array.from(atob(base64), c => c.charCodeAt(0)); + }, + + toBase64(uint8array: Uint8Array): string { + return btoa(webByteUtils.toISO88591(uint8array)); + }, + + /** **Legacy** binary strings are an outdated method of data transfer. Do not add public API support for interpreting this format */ + fromISO88591(codePoints: string): Uint8Array { + return Uint8Array.from(codePoints, c => c.charCodeAt(0) & 0xff); + }, + + /** **Legacy** binary strings are an outdated method of data transfer. Do not add public API support for interpreting this format */ + toISO88591(uint8array: Uint8Array): string { + return Array.from(Uint16Array.from(uint8array), b => String.fromCharCode(b)).join(''); + }, + + fromHex(hex: string): Uint8Array { + const evenLengthHex = hex.length % 2 === 0 ? hex : hex.slice(0, hex.length - 1); + const buffer = []; + + for (let i = 0; i < evenLengthHex.length; i += 2) { + const firstDigit = evenLengthHex[i]; + const secondDigit = evenLengthHex[i + 1]; + + if (!HEX_DIGIT.test(firstDigit)) { + break; + } + if (!HEX_DIGIT.test(secondDigit)) { + break; + } + + const hexDigit = Number.parseInt(`${firstDigit}${secondDigit}`, 16); + buffer.push(hexDigit); + } + + return Uint8Array.from(buffer); + }, + + toHex(uint8array: Uint8Array): string { + return Array.from(uint8array, byte => byte.toString(16).padStart(2, '0')).join(''); + }, + + fromUTF8(text: string): Uint8Array { + return new TextEncoder().encode(text); + }, + + toUTF8(uint8array: Uint8Array): string { + return new TextDecoder('utf8', { fatal: false }).decode(uint8array); + }, + + utf8ByteLength(input: string): number { + return webByteUtils.fromUTF8(input).byteLength; + }, + + encodeUTF8Into(buffer: Uint8Array, source: string, byteOffset: number): number { + const bytes = webByteUtils.fromUTF8(source); + buffer.set(bytes, byteOffset); + return bytes.byteLength; + } +}; diff --git a/src/uuid_utils.ts b/src/uuid_utils.ts index f37b0659..859d5cfd 100644 --- a/src/uuid_utils.ts +++ b/src/uuid_utils.ts @@ -1,5 +1,5 @@ -import { Buffer } from 'buffer'; import { BSONTypeError } from './error'; +import { ByteUtils } from './utils/byte_utils'; // Validation regex for v4 uuid (validates with or without dashes) const VALIDATION_REGEX = @@ -8,7 +8,7 @@ const VALIDATION_REGEX = export const uuidValidateString = (str: string): boolean => typeof str === 'string' && VALIDATION_REGEX.test(str); -export const uuidHexStringToBuffer = (hexString: string): Buffer => { +export const uuidHexStringToBuffer = (hexString: string): Uint8Array => { if (!uuidValidateString(hexString)) { throw new BSONTypeError( 'UUID string representations must be a 32 or 36 character hex string (dashes excluded/included). Format: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" or "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".' @@ -16,18 +16,18 @@ export const uuidHexStringToBuffer = (hexString: string): Buffer => { } const sanitizedHexString = hexString.replace(/-/g, ''); - return Buffer.from(sanitizedHexString, 'hex'); + return ByteUtils.fromHex(sanitizedHexString); }; -export const bufferToUuidHexString = (buffer: Buffer, includeDashes = true): string => - includeDashes - ? buffer.toString('hex', 0, 4) + - '-' + - buffer.toString('hex', 4, 6) + - '-' + - buffer.toString('hex', 6, 8) + - '-' + - buffer.toString('hex', 8, 10) + - '-' + - buffer.toString('hex', 10, 16) - : buffer.toString('hex'); +export function bufferToUuidHexString(buffer: Uint8Array, includeDashes = true): string { + if (includeDashes) { + return [ + ByteUtils.toHex(buffer.subarray(0, 4)), + ByteUtils.toHex(buffer.subarray(4, 6)), + ByteUtils.toHex(buffer.subarray(6, 8)), + ByteUtils.toHex(buffer.subarray(8, 10)), + ByteUtils.toHex(buffer.subarray(10, 16)) + ].join('-'); + } + return ByteUtils.toHex(buffer); +} diff --git a/test/.eslintrc.json b/test/.eslintrc.json index 051f3f2b..f7998fcf 100644 --- a/test/.eslintrc.json +++ b/test/.eslintrc.json @@ -1,5 +1,6 @@ { "root": true, + "parser": "@typescript-eslint/parser", "env": { "node": true, "mocha": true, @@ -8,7 +9,9 @@ "globals": { "expect": true, "BSON": false, - "Buffer": false + "Buffer": false, + "BigInt": true, + "globalThis": true }, "parserOptions": { "ecmaVersion": 2020 @@ -47,5 +50,17 @@ "property": "only" } ] - } + }, + "overrides": [ + { + "files": "./**/*.ts", + "extends": [ + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@typescript-eslint/no-non-null-assertion": "off" + } + } + ] } diff --git a/test/node/bigint_tests.js b/test/node/bigint_tests.js index efdb82ac..d20f8def 100644 --- a/test/node/bigint_tests.js +++ b/test/node/bigint_tests.js @@ -1,4 +1,3 @@ -/* globals BigInt */ 'use strict'; const BSON = require('../register-bson'); diff --git a/test/bson_node_only_tests.js b/test/node/bson_node_only_tests.js similarity index 77% rename from test/bson_node_only_tests.js rename to test/node/bson_node_only_tests.js index 773c49a7..01a2500c 100644 --- a/test/bson_node_only_tests.js +++ b/test/node/bson_node_only_tests.js @@ -1,14 +1,15 @@ 'use strict'; const fs = require('fs'); -const BSON = require('./register-bson'); +const path = require('path'); +const BSON = require('../register-bson'); const Binary = BSON.Binary; -const { assertBuffersEqual } = require('./node/tools/utils'); +const { assertBuffersEqual } = require('./tools/utils'); const Buffer = require('buffer').Buffer; describe('BSON - Node only', function () { it('Should Correctly Serialize and Deserialize a big Binary object', function (done) { - var data = fs.readFileSync('test/node/data/test_gs_weird_bug.png', 'binary'); + var data = fs.readFileSync(path.resolve(__dirname, './data/test_gs_weird_bug.png'), 'binary'); var bin = new Binary(); bin.write(data); var doc = { doc: bin }; @@ -26,7 +27,7 @@ describe('BSON - Node only', function () { describe('Full BSON - Node only', function () { it('Should Correctly Serialize and Deserialize a big Binary object', function (done) { - var data = fs.readFileSync('test/node/data/test_gs_weird_bug.png', 'binary'); + var data = fs.readFileSync(path.resolve(__dirname, './data/test_gs_weird_bug.png'), 'binary'); var bin = new Binary(); bin.write(data); var doc = { doc: bin }; @@ -37,7 +38,7 @@ describe('Full BSON - Node only', function () { }); it('Should Correctly Deserialize bson file from mongodump', function (done) { - var data = fs.readFileSync('test/node/data/test.bson', { encoding: null }); + var data = fs.readFileSync(path.resolve(__dirname, './data/test.bson'), { encoding: null }); data = Buffer.from(data); var docs = []; var bsonIndex = 0; diff --git a/test/bson_older_versions_tests.js b/test/node/bson_older_versions_tests.js similarity index 91% rename from test/bson_older_versions_tests.js rename to test/node/bson_older_versions_tests.js index c4f4aa79..a651f495 100644 --- a/test/bson_older_versions_tests.js +++ b/test/node/bson_older_versions_tests.js @@ -1,10 +1,11 @@ 'use strict'; -const currentNodeBSON = require('./register-bson'); +const currentNodeBSON = require('../register-bson'); const vm = require('vm'); const fs = require('fs'); const rimraf = require('rimraf'); const cp = require('child_process'); +const { __isWeb__ } = require('../register-bson'); // node-fetch is an es-module let fetch; @@ -23,7 +24,7 @@ let fetch; */ const OLD_VERSIONS = ['v1.1.5', 'v1.1.4']; const getZipUrl = ver => `https://github.com/mongodb/js-bson/archive/${ver}.zip`; -const getImportPath = ver => `../bson-${ver}/js-bson-${ver.substring(1)}`; +const getImportPath = ver => `../../bson-${ver}/js-bson-${ver.substring(1)}`; function downloadZip(version, done) { // downloads a zip of previous BSON version @@ -44,6 +45,10 @@ function downloadZip(version, done) { } describe('Mutual version and distribution compatibility', function () { + before(function () { + if (__isWeb__) this.skip(); + }); + before(async () => { fetch = await import('node-fetch').then(mod => mod.default); }); @@ -88,9 +93,9 @@ describe('Mutual version and distribution compatibility', function () { try { fs.writeFileSync( './bson.browser.esm.mjs', - fs.readFileSync(__dirname + '/../dist/bson.browser.esm.js') + fs.readFileSync(__dirname + '/../../dist/bson.browser.esm.js') ); - fs.writeFileSync('./bson.esm.mjs', fs.readFileSync(__dirname + '/../dist/bson.esm.js')); + fs.writeFileSync('./bson.esm.mjs', fs.readFileSync(__dirname + '/../../dist/bson.esm.js')); } catch (e) { // bundling fails in CI on Windows, no idea why, hence also the // process.platform !== 'win32' check below @@ -124,25 +129,25 @@ describe('Mutual version and distribution compatibility', function () { name: 'Browser ESM', // eval because import is a syntax error in earlier Node.js versions // that are still supported in CI - load: () => eval(`import("${__dirname}/../bson.browser.esm.mjs")`), + load: () => eval(`import("${__dirname}/../../bson.browser.esm.mjs")`), usesBufferPolyfill: true }, { name: 'Browser UMD', - load: () => Promise.resolve(require('../dist/bson.browser.umd.js')), + load: () => Promise.resolve(require('../../dist/bson.browser.umd.js')), usesBufferPolyfill: true }, { name: 'Generic bundle', load: () => { - const source = fs.readFileSync(__dirname + '/../dist/bson.bundle.js', 'utf8'); + const source = fs.readFileSync(__dirname + '/../../dist/bson.bundle.js', 'utf8'); return Promise.resolve(vm.runInNewContext(`${source}; BSON`, { global, process })); }, usesBufferPolyfill: true }, { name: 'Node.js ESM', - load: () => eval(`import("${__dirname}/../bson.esm.mjs")`) + load: () => eval(`import("${__dirname}/../../bson.esm.mjs")`) } ]); @@ -223,9 +228,7 @@ describe('Mutual version and distribution compatibility', function () { try { // Check that both BSON versions serialize to equal Buffers - expect(toBSON.serialize({ object }).toString('hex')).to.equal( - fromBSON.serialize({ object }).toString('hex') - ); + expect(toBSON.serialize({ object })).to.deep.equal(fromBSON.serialize({ object })); if (!from.legacy) { // Check that serializing using one version and deserializing using // the other gives back the original object. diff --git a/test/node/bson_test.js b/test/node/bson_test.js index ac178000..c0c314cb 100644 --- a/test/node/bson_test.js +++ b/test/node/bson_test.js @@ -17,9 +17,9 @@ const Double = BSON.Double; const MinKey = BSON.MinKey; const MaxKey = BSON.MaxKey; const BSONError = BSON.BSONError; -const { BinaryParser } = require('../binary_parser'); +const { BinaryParser } = require('./tools/binary_parser'); const vm = require('vm'); -const { assertBuffersEqual } = require('./tools/utils'); +const { assertBuffersEqual, isBufferOrUint8Array } = require('./tools/utils'); const { inspect } = require('util'); /** @@ -403,7 +403,7 @@ describe('BSON', function () { var deserialized = BSON.deserialize(serialized_data); expect(deserialized.doc instanceof Binary).to.be.ok; - expect('hello world').to.equal(deserialized.doc.toString()); + expect(deserialized.doc.toString()).to.equal('hello world'); done(); }); @@ -421,8 +421,12 @@ describe('BSON', function () { var deserialized = BSON.deserialize(serialized_data, { promoteBuffers: true }); - expect(Buffer.isBuffer(deserialized.doc)).to.be.ok; - expect('hello world').to.equal(deserialized.doc.toString()); + expect( + isBufferOrUint8Array(deserialized.doc), + `expected deserialized.doc to be instanceof buffer or uint8Array` + ).to.be.true; + expect(deserialized.doc).to.not.be.instanceOf(Binary); + expect(doc.doc).to.deep.equal(deserialized.doc); done(); }); diff --git a/test/node/byte_utils.test.ts b/test/node/byte_utils.test.ts new file mode 100644 index 00000000..7e1d19f4 --- /dev/null +++ b/test/node/byte_utils.test.ts @@ -0,0 +1,515 @@ +import { expect } from 'chai'; +import { types, inspect } from 'node:util'; +import { isBufferOrUint8Array } from './tools/utils'; +import { ByteUtils } from '../../src/utils/byte_utils'; +import { nodeJsByteUtils } from '../../src/utils/node_byte_utils'; +import { webByteUtils } from '../../src/utils/web_byte_utils'; + +type ByteUtilTest = { + name: string; + inputs: Parameters; + expectation: (result: { + web: boolean; + output: ReturnType | null; + error: Error | null; + }) => void; +}; + +const isNode14OrLower = (() => { + let [majorVersion] = process.version.split('.'); + majorVersion = majorVersion.slice(1); // drop 'v' + return Number.parseInt(majorVersion, 10) <= 14; +})(); + +const testArrayBuffer = new ArrayBuffer(8); + +const toLocalBufferTypeTests: ByteUtilTest<'toLocalBufferType'>[] = [ + { + name: 'should transform to local type', + inputs: [new Uint8Array()], + expectation({ web, output }) { + if (web) { + expect(types.isUint8Array(output), 'expected output to be a Uint8Array').to.be.true; + } else { + expect(Buffer.isBuffer(output), 'expected output to be a Buffer').to.be.true; + } + } + }, + { + name: 'should account for the input view byteLength and byteOffset', + inputs: [new Uint8Array(testArrayBuffer, 1, 3)], + expectation({ web, output, error }) { + expect(error).to.be.null; + if (web) { + expect(types.isUint8Array(output), 'expected output to be a Uint8Array').to.be.true; + } else { + expect(Buffer.isBuffer(output), 'expected output to be a Buffer').to.be.true; + } + expect(output).to.have.property('byteLength', 3); + expect(output).to.have.property('byteOffset', 1); + } + }, + ...[ + Uint8Array, + Int8Array, + Uint8ClampedArray, + Int16Array, + Uint16Array, + Int32Array, + Uint32Array, + Float32Array, + Float64Array + ].map(TypedArray => { + return { + name: `should create view if input is typed array ${TypedArray.name}`, + inputs: [new TypedArray(testArrayBuffer)], + expectation({ output, error }) { + expect(error).to.be.null; + expect( + isBufferOrUint8Array(output), + `expected output to be instanceof buffer or uint8Array` + ).to.be.true; + expect(output).to.have.property('byteLength', testArrayBuffer.byteLength); + } + } as ByteUtilTest<'toLocalBufferType'>; + }), + ...[0, 12, -1, '', 'foo', null, undefined, ['list'], {}, /x/].map(item => { + return { + name: `should throw if input is ${typeof item}: ${inspect(item)}`, + inputs: [item], + expectation({ output, error }) { + expect(output).to.be.null; + expect(error).to.have.property('name', 'BSONError'); + } + } as ByteUtilTest<'toLocalBufferType'>; + }) +]; +const allocateTests: ByteUtilTest<'allocate'>[] = [ + { + name: 'should return a byteArray with byteLength equal to size', + inputs: [3], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.have.property('byteLength', 3); + output?.set([1, 2, 3], 0); + expect([...(output ?? [])]).to.deep.equal([1, 2, 3]); + } + }, + { + name: 'should throw if argument is invalid size', + inputs: [-1], + expectation({ error }) { + expect(error).to.have.property('name', 'RangeError'); + } + }, + { + name: 'should throw if no argument is supplied', + // @ts-expect-error: testing bad input + inputs: [], + expectation({ error }) { + expect(error).to.have.property('name', 'TypeError'); + } + }, + { + name: 'should throw if invalid typed argument is supplied', + // @ts-expect-error: testing bad input + inputs: ['abc'], + expectation({ error }) { + expect(error).to.have.property('name', 'TypeError'); + } + }, + { + name: 'should handle zero sized allocation', + inputs: [0], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.have.property('byteLength', 0); + } + } +]; +const equalsTests: ByteUtilTest<'equals'>[] = [ + { + name: 'should return true for zero sized buffers', + inputs: [new Uint8Array(), new Uint8Array()], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.be.true; + } + }, + { + name: 'should return true for equal buffers', + inputs: [Uint8Array.from([1, 2, 3]), Uint8Array.from([1, 2, 3])], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.be.true; + } + }, + { + name: 'should return true for different Buffer instances whose contents are equal', + inputs: [Uint8Array.from([1, 2, 3]), Buffer.from([1, 2, 3])], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.be.true; + } + }, + { + name: 'should return false for buffers with a different length', + inputs: [Uint8Array.from([1, 2]), Uint8Array.from([1, 2, 3])], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.be.false; + } + }, + { + name: 'should return false for buffers with different content', + inputs: [Uint8Array.from([1, 2, 3]), Uint8Array.from([1, 2, 4])], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.be.false; + } + } +]; +const fromNumberArrayTests: ByteUtilTest<'fromNumberArray'>[] = [ + { + name: 'should construct a buffer from an array with numbers', + inputs: [[1, 2, 3]], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.deep.equal(Buffer.from([1, 2, 3])); + } + }, + { + name: 'should construct an empty buffer from an empty array', + inputs: [[]], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.have.property('byteLength', 0); + } + } +]; +const fromBase64Tests: ByteUtilTest<'fromBase64'>[] = [ + { + name: 'should create buffer from base64 input', + inputs: [Buffer.from('abc\u{1f913}', 'utf8').toString('base64')], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.deep.equal(Buffer.from('abc\u{1f913}', 'utf8')); + } + }, + { + name: 'should return empty buffer for empty string input', + inputs: [''], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.have.property('byteLength', 0); + } + } +]; +const toBase64Tests: ByteUtilTest<'toBase64'>[] = [ + { + name: 'should create base64 string from buffer input', + inputs: [Buffer.from('abc\u{1f913}', 'utf8')], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.deep.equal(Buffer.from('abc\u{1f913}', 'utf8').toString('base64')); + } + }, + { + name: 'should return empty string for empty buffer input', + inputs: [Buffer.alloc(0)], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.be.a('string').with.lengthOf(0); + } + } +]; +const fromHexTests: ByteUtilTest<'fromHex'>[] = [ + { + name: 'should create buffer from hex input', + inputs: [Buffer.from('abc\u{1f913}', 'utf8').toString('hex')], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.deep.equal(Buffer.from('abc\u{1f913}', 'utf8')); + } + }, + { + name: 'should return empty buffer for empty string input', + inputs: [''], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.have.property('byteLength', 0); + } + }, + { + name: 'should use leading valid hex characters', + inputs: ['abxxcd'], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.deep.equal(Buffer.from('abxxcd', 'hex')); + expect(output).to.deep.equal(Buffer.from('ab', 'hex')); + } + }, + { + name: 'should slice input strings down to nearest even length (len: 1)', + inputs: ['a'], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.deep.equal(Buffer.from('a', 'hex')); + expect(output).to.deep.equal(Buffer.alloc(0)); + expect(output).to.have.property('byteLength', 0); + } + }, + { + name: 'should slice input strings down to nearest even length (len: 5)', + inputs: ['abcde'], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.deep.equal(Buffer.from('abcde', 'hex')); + expect(output).to.have.property('byteLength', 2); + expect(output).to.have.property('0', 0xab); + expect(output).to.have.property('1', 0xcd); + expect(output).to.not.have.property('2'); + } + }, + { + name: 'should return empty buffer when no characters are valid hex', + inputs: ['xxxx'], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.deep.equal(Buffer.from('xxxx', 'hex')); + expect(output).to.have.property('byteLength', 0); + } + }, + { + name: 'should ignore double digit hex subsequence that ends with invalid character', + inputs: ['abcx'], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.deep.equal(Buffer.from('abcx', 'hex')); + expect(output).to.have.property('byteLength', 1); + expect(output).to.have.property('0', 0xab); + } + }, + { + name: 'should ignore double digit hex subsequence that starts with invalid character', + inputs: ['abxc'], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.deep.equal(Buffer.from('abxc', 'hex')); + expect(output).to.have.property('byteLength', 1); + expect(output).to.have.property('0', 0xab); + } + } +]; +const toHexTests: ByteUtilTest<'toHex'>[] = [ + { + name: 'should create hex string from buffer input', + inputs: [Buffer.from('abc\u{1f913}', 'utf8')], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.deep.equal(Buffer.from('abc\u{1f913}', 'utf8').toString('hex')); + } + }, + { + name: 'should return empty string for empty buffer input', + inputs: [Buffer.alloc(0)], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.be.a('string').with.lengthOf(0); + } + } +]; +const fromISO88591Tests: ByteUtilTest<'fromISO88591'>[] = [ + { + name: 'should create buffer from ISO-8859-1 input', + inputs: [Buffer.from('abc\u{1f913}', 'utf8').toString('latin1')], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.deep.equal(Buffer.from('abc\u{1f913}', 'utf8')); + } + }, + { + name: 'should return empty buffer for empty string input', + inputs: [''], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.have.property('byteLength', 0); + } + } +]; +const toISO88591Tests: ByteUtilTest<'toISO88591'>[] = [ + { + name: 'should create latin1 string from buffer input', + inputs: [Buffer.from('abc\u{1f913}', 'utf8')], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.deep.equal(Buffer.from('abc\u{1f913}', 'utf8').toString('latin1')); + } + }, + { + name: 'should return empty string for empty buffer input', + inputs: [Buffer.alloc(0)], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.be.a('string').with.lengthOf(0); + } + } +]; +const fromUTF8Tests: ByteUtilTest<'fromUTF8'>[] = [ + { + name: 'should create buffer from utf8 input', + inputs: [Buffer.from('abc\u{1f913}', 'utf8').toString('utf8')], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.deep.equal(Buffer.from('abc\u{1f913}', 'utf8')); + } + }, + { + name: 'should return empty buffer for empty string input', + inputs: [''], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.have.property('byteLength', 0); + } + }, + { + name: 'should return bytes with replacement character if string is not encodable', + inputs: ['\u{1f913}'.slice(0, 1)], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.have.property('byteLength', 3); + expect(output).to.have.property('0', 0xef); + expect(output).to.have.property('1', 0xbf); + expect(output).to.have.property('2', 0xbd); + const backToString = Buffer.from(output!).toString('utf8'); + const replacementCharacter = '\u{fffd}'; + expect(backToString).to.equal(replacementCharacter); + } + } +]; +const toUTF8Tests: ByteUtilTest<'toUTF8'>[] = [ + { + name: 'should create utf8 string from buffer input', + inputs: [Buffer.from('abc\u{1f913}', 'utf8')], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.deep.equal(Buffer.from('abc\u{1f913}', 'utf8').toString('utf8')); + } + }, + { + name: 'should return empty string for empty buffer input', + inputs: [Buffer.alloc(0)], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.be.a('string').with.lengthOf(0); + } + } +]; +const utf8ByteLengthTests: ByteUtilTest<'utf8ByteLength'>[] = [ + { + name: 'should return zero for empty string', + inputs: [''], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.equal(0); + } + }, + { + name: 'should return zero for empty string', + inputs: ['abc\u{1f913}'], + expectation({ output, error }) { + expect(error).to.be.null; + expect(output).to.equal(7); + } + } +]; + +const utils = new Map([ + ['nodeJsByteUtils', nodeJsByteUtils], + ['webByteUtils', webByteUtils] +]); + +const table = new Map[]>([ + ['toLocalBufferType', toLocalBufferTypeTests], + ['allocate', allocateTests], + ['equals', equalsTests], + ['fromNumberArray', fromNumberArrayTests], + ['fromBase64', fromBase64Tests], + ['toBase64', toBase64Tests], + ['fromHex', fromHexTests], + ['toHex', toHexTests], + ['fromISO88591', fromISO88591Tests], + ['toISO88591', toISO88591Tests], + ['fromUTF8', fromUTF8Tests], + ['toUTF8', toUTF8Tests], + ['utf8ByteLength', utf8ByteLengthTests] +]); + +describe('ByteUtils', () => { + it('should be set to the nodeJsByteUtils when run on Node.js', () => { + // The import at the top of our Mocha tests will always be the nodejs version + // since the import will happen in an environment the defines a global Buffer + expect(ByteUtils).to.equal(nodeJsByteUtils); + }); + + describe('toLocalBufferType special cases', () => { + describe('nodejs', () => { + it('should return input instance if it is already the correct type', () => { + const nodejsBuffer = Buffer.from('abc', 'utf8'); + expect(nodeJsByteUtils.toLocalBufferType(nodejsBuffer)).to.equal(nodejsBuffer); + }); + + it('should create a view on a SharedArrayBuffer', function () { + const arrayBufferIn = new SharedArrayBuffer(3); + const bufferOut = nodeJsByteUtils.toLocalBufferType(arrayBufferIn); + expect(bufferOut).to.be.an.instanceOf(Buffer); + expect(bufferOut.buffer).to.equal(arrayBufferIn); + }); + }); + + describe('web', () => { + it('should return input instance if it is already the correct type', () => { + const uint8array = new Uint8Array(8); + expect(webByteUtils.toLocalBufferType(uint8array)).to.equal(uint8array); + }); + + it('should create a view on a SharedArrayBuffer', function () { + const arrayBufferIn = new SharedArrayBuffer(3); + const bufferOut = nodeJsByteUtils.toLocalBufferType(arrayBufferIn); + expect(bufferOut).to.be.an.instanceOf(Buffer); + expect(bufferOut.buffer).to.equal(arrayBufferIn); + }); + }); + }); + + for (const [byteUtilsName, byteUtils] of utils) { + for (const [utility, tests] of table) { + const maybeDescribe = isNode14OrLower && /base64/i.test(utility) ? describe.skip : describe; + maybeDescribe(`${byteUtilsName}.${utility}()`, () => { + for (const test of tests) { + it(test.name, function () { + expect(byteUtils).to.have.property(utility).that.is.a('function'); + let output = null; + let error = null; + + try { + output = byteUtils[utility].call(null, ...test.inputs); + } catch (thrownError) { + error = thrownError; + } + + if (error != null) { + expect(output).to.be.null; + } + + if (output != null) { + expect(error).to.be.null; + } + + test.expectation({ web: byteUtilsName === 'webByteUtils', output, error }); + }); + } + }); + } + } +}); diff --git a/test/node/ensure_buffer_test.js b/test/node/ensure_buffer_test.js deleted file mode 100644 index a4648128..00000000 --- a/test/node/ensure_buffer_test.js +++ /dev/null @@ -1,104 +0,0 @@ -/* global SharedArrayBuffer */ -'use strict'; - -const { Buffer } = require('buffer'); -const { ensureBuffer } = require('../register-bson'); -const BSON = require('../register-bson'); -const BSONTypeError = BSON.BSONTypeError; - -describe('ensureBuffer tests', function () { - it('should be a function', function () { - expect(ensureBuffer).to.be.a('function'); - }); - - it('should return a view over the exact same memory when a Buffer is passed in', function () { - const bufferIn = Buffer.alloc(10); - let bufferOut; - - expect(function () { - bufferOut = ensureBuffer(bufferIn); - }).to.not.throw(BSONTypeError); - - expect(bufferOut).to.be.an.instanceOf(Buffer); - expect(bufferOut.buffer).to.equal(bufferIn.buffer); - expect(bufferOut.byteLength).to.equal(bufferIn.byteLength); - expect(bufferOut.byteOffset).to.equal(bufferIn.byteOffset); - }); - - it('should wrap a Uint8Array with a buffer', function () { - const arrayIn = Uint8Array.from([1, 2, 3]); - let bufferOut; - - expect(function () { - bufferOut = ensureBuffer(arrayIn); - }).to.not.throw(BSONTypeError); - - expect(bufferOut).to.be.an.instanceOf(Buffer); - expect(bufferOut.buffer).to.equal(arrayIn.buffer); - }); - - it('should wrap a ArrayBuffer with a buffer', function () { - const arrayBufferIn = Uint8Array.from([1, 2, 3]).buffer; - let bufferOut; - - expect(function () { - bufferOut = ensureBuffer(arrayBufferIn); - }).to.not.throw(BSONTypeError); - - expect(bufferOut).to.be.an.instanceOf(Buffer); - expect(bufferOut.buffer).to.equal(arrayBufferIn); - }); - - it('should wrap a SharedArrayBuffer with a buffer', function () { - if (typeof SharedArrayBuffer === 'undefined') { - this.skip(); - return; - } - const arrayBufferIn = new SharedArrayBuffer(3); - let bufferOut; - - expect(function () { - bufferOut = ensureBuffer(arrayBufferIn); - }).to.not.throw(BSONTypeError); - - expect(bufferOut).to.be.an.instanceOf(Buffer); - expect(bufferOut.buffer).to.equal(arrayBufferIn); - }); - - it('should account for the input view byteLength and byteOffset', function () { - const input = new Uint8Array(new Uint8Array([1, 2, 3, 4, 5]).buffer, 1, 3); - let bufferOut; - - expect(function () { - bufferOut = ensureBuffer(input); - }).to.not.throw(BSONTypeError); - - expect(bufferOut).to.be.an.instanceOf(Buffer); - expect(bufferOut.byteLength).to.equal(3); - expect(bufferOut.byteOffset).to.equal(1); - }); - - [0, 12, -1, '', 'foo', null, undefined, ['list'], {}, /x/].forEach(function (item) { - it(`should throw if input is ${typeof item}: ${item}`, function () { - expect(function () { - ensureBuffer(item); - }).to.throw(BSONTypeError); - }); - }); - - [ - Int8Array, - Uint8ClampedArray, - Int16Array, - Uint16Array, - Int32Array, - Uint32Array, - Float32Array, - Float64Array - ].forEach(function (TypedArray) { - it(`should throw if input is typed array ${TypedArray.name}`, function () { - const typedArray = new TypedArray(); - expect(ensureBuffer(typedArray)).to.be.instanceOf(Buffer); - }); - }); -}); diff --git a/test/node/error_test.js b/test/node/error_test.js index 60f09397..2ba82add 100644 --- a/test/node/error_test.js +++ b/test/node/error_test.js @@ -1,5 +1,6 @@ 'use strict'; +const { __isWeb__ } = require('../register-bson'); const BSON = require('../register-bson'); const BSONTypeError = BSON.BSONTypeError; const BSONError = BSON.BSONError; @@ -7,10 +8,15 @@ const BSONError = BSON.BSONError; describe('BSONTypeError', function () { it('should evaluate true on instanceof BSONTypeError and TypeError', function () { const bsonTypeErr = new BSONTypeError(); - expect(bsonTypeErr instanceof BSONTypeError).to.be.true; - expect(bsonTypeErr instanceof TypeError).to.be.true; - expect(bsonTypeErr).to.be.instanceOf(BSONTypeError); - expect(bsonTypeErr).to.be.instanceOf(TypeError); + if (__isWeb__) { + expect(bsonTypeErr).to.have.property('name', 'BSONTypeError'); + expect(Object.getPrototypeOf(BSONTypeError.prototype)).to.have.property('name', 'TypeError'); + } else { + expect(bsonTypeErr instanceof BSONTypeError).to.be.true; + expect(bsonTypeErr).to.be.instanceOf(BSONTypeError); + expect(bsonTypeErr instanceof TypeError).to.be.true; + expect(bsonTypeErr).to.be.instanceOf(TypeError); + } }); it('should correctly set BSONTypeError name and message properties', function () { @@ -23,10 +29,15 @@ describe('BSONTypeError', function () { describe('BSONError', function () { it('should evaluate true on instanceof BSONError and Error', function () { const bsonErr = new BSONError(); - expect(bsonErr instanceof BSONError).to.be.true; - expect(bsonErr instanceof Error).to.be.true; - expect(bsonErr).to.be.instanceOf(BSONError); - expect(bsonErr).to.be.instanceOf(Error); + if (__isWeb__) { + expect(bsonErr).to.have.property('name', 'BSONError'); + expect(Object.getPrototypeOf(BSONError.prototype)).to.have.property('name', 'Error'); + } else { + expect(bsonErr instanceof BSONError).to.be.true; + expect(bsonErr instanceof Error).to.be.true; + expect(bsonErr).to.be.instanceOf(BSONError); + expect(bsonErr).to.be.instanceOf(Error); + } }); it('should correctly set BSONError name and message properties', function () { diff --git a/test/node/object_id_tests.js b/test/node/object_id_tests.js index e34a1fbd..7d72ea94 100644 --- a/test/node/object_id_tests.js +++ b/test/node/object_id_tests.js @@ -6,6 +6,7 @@ const BSONTypeError = BSON.BSONTypeError; const ObjectId = BSON.ObjectId; const util = require('util'); const getSymbolFrom = require('./tools/utils').getSymbolFrom; +const isBufferOrUint8Array = require('./tools/utils').isBufferOrUint8Array; describe('ObjectId', function () { it('should correctly handle objectId timestamps', function (done) { @@ -171,8 +172,15 @@ describe('ObjectId', function () { it(`should correctly create ObjectId from ${input} and result in ${output}`, function () { const objId = new ObjectId(input); expect(objId).to.have.property('id'); - expect(objId.id).to.be.instanceOf(Buffer); - expect(objId.id.readUInt32BE(0)).to.equal(output); + expect( + isBufferOrUint8Array(objId.id), + `expected objId.id to be instanceof buffer or uint8Array` + ).to.be.true; + const num = new DataView(objId.id.buffer, objId.id.byteOffset, objId.id.byteLength).getInt32( + 0, + false + ); + expect(num).to.equal(output); }); } @@ -180,9 +188,18 @@ describe('ObjectId', function () { const objNull = new ObjectId(null); const objNoArg = new ObjectId(); const objUndef = new ObjectId(undefined); - expect(objNull.id).to.be.instanceOf(Buffer); - expect(objNoArg.id).to.be.instanceOf(Buffer); - expect(objUndef.id).to.be.instanceOf(Buffer); + expect( + isBufferOrUint8Array(objNull.id), + `expected objNull.id to be instanceof buffer or uint8Array` + ).to.be.true; + expect( + isBufferOrUint8Array(objNoArg.id), + `expected objNoArg.id to be instanceof buffer or uint8Array` + ).to.be.true; + expect( + isBufferOrUint8Array(objUndef.id), + `expected objUndef.id to be instanceof buffer or uint8Array` + ).to.be.true; }); it('should throw error if non-12 byte non-24 hex string passed in', function () { diff --git a/test/node/promote_values_test.js b/test/node/promote_values_test.js index e2df7bec..1934f0cd 100644 --- a/test/node/promote_values_test.js +++ b/test/node/promote_values_test.js @@ -4,7 +4,7 @@ const Buffer = require('buffer').Buffer; const BSON = require('../register-bson'); const Int32 = BSON.Int32; const Double = BSON.Double; -const BinaryParser = require('../binary_parser').BinaryParser; +const { BinaryParser } = require('./tools/binary_parser'); describe('promote values', function () { /** diff --git a/test/node/test_full_bson.js b/test/node/test_full_bson.js index 2e1e46b5..0c9f66e0 100644 --- a/test/node/test_full_bson.js +++ b/test/node/test_full_bson.js @@ -2,7 +2,7 @@ const BSON = require('../register-bson'); const Buffer = require('buffer').Buffer; -const BinaryParser = require('../binary_parser').BinaryParser; +const { BinaryParser } = require('./tools/binary_parser'); const ObjectId = BSON.ObjectId; const Binary = BSON.Binary; const BSONRegExp = BSON.BSONRegExp; @@ -205,30 +205,22 @@ describe('Full BSON', function () { /** * @ignore */ - it('Should Correctly Serialize and Deserialize Buffer', function (done) { + it('Should Correctly Serialize and Deserialize Buffer', function () { var doc = { doc: Buffer.from('123451234512345') }; var serialized_data = BSON.serialize(doc); - expect('123451234512345').to.equal( - BSON.deserialize(serialized_data).doc.buffer.toString('ascii') - ); - - done(); + expect(doc.doc).to.deep.equal(BSON.deserialize(serialized_data).doc.buffer); }); /** * @ignore */ - it('Should Correctly Serialize and Deserialize Buffer with promoteBuffers option', function (done) { + it('Should Correctly Serialize and Deserialize Buffer with promoteBuffers option', function () { var doc = { doc: Buffer.from('123451234512345') }; var serialized_data = BSON.serialize(doc); var options = { promoteBuffers: true }; - expect('123451234512345').to.equal( - BSON.deserialize(serialized_data, options).doc.toString('ascii') - ); - - done(); + expect(doc.doc).to.deep.equal(BSON.deserialize(serialized_data, options).doc); }); /** diff --git a/test/node/to_bson_test.js b/test/node/to_bson_test.js index 2c5142a1..1178cda3 100644 --- a/test/node/to_bson_test.js +++ b/test/node/to_bson_test.js @@ -1,9 +1,7 @@ 'use strict'; const BSON = require('../register-bson'); -const ObjectId = BSON.ObjectId; - -const BigInt = global.BigInt; +const { ObjectId, __isWeb__ } = BSON; describe('toBSON', function () { /** @@ -133,11 +131,16 @@ describe('toBSON', function () { }); describe('when used on global existing types', () => { - beforeEach(() => { - Number.prototype.toBSON = () => 'hello'; - String.prototype.toBSON = () => 'hello'; - Boolean.prototype.toBSON = () => 'hello'; - if (BigInt) BigInt.prototype.toBSON = () => 'hello'; + beforeEach(function () { + if (__isWeb__) { + // These prototype modification do not make it + // to the BSON lib that was run in a separate context + return this.skip(); + } + Number.prototype.toBSON = () => `hello ${typeof 0}`; + String.prototype.toBSON = () => `hello ${typeof ''}`; + Boolean.prototype.toBSON = () => `hello ${typeof false}`; + BigInt.prototype.toBSON = () => `hello ${typeof 0n}`; }); afterEach(() => { @@ -145,16 +148,19 @@ describe('toBSON', function () { delete Number.prototype.toBSON; delete String.prototype.toBSON; delete Boolean.prototype.toBSON; - if (BigInt) delete BigInt.prototype.toBSON; + delete BigInt.prototype.toBSON; }); const testToBSONFor = value => { it(`should use toBSON on false-y ${typeof value} ${value === '' ? "''" : value}`, () => { + const expectedString = `hello ${typeof value}`; const serialized_data = BSON.serialize({ a: value }); - expect(serialized_data.indexOf(Buffer.from('hello\0', 'utf8'))).to.be.greaterThan(0); + expect( + serialized_data.indexOf(Buffer.from(expectedString + '\0', 'utf8')) + ).to.be.greaterThan(0); const deserialized_doc = BSON.deserialize(serialized_data); - expect(deserialized_doc).to.have.property('a', 'hello'); + expect(deserialized_doc).to.have.property('a', expectedString); }); }; @@ -162,9 +168,7 @@ describe('toBSON', function () { testToBSONFor(NaN); testToBSONFor(''); testToBSONFor(false); - if (BigInt) { - testToBSONFor(BigInt(0)); - } + testToBSONFor(0n); it('should use toBSON on false-y number in calculateObjectSize', () => { // Normally is 20 bytes @@ -172,12 +176,12 @@ describe('toBSON', function () { // int32 0x10 '0\x00' int32 \0 // \0 // --------- - // with toBSON is 26 bytes (hello + null) + // with toBSON is 33 bytes (hello number + null) // int32 0x04 'a\x00' - // int32 0x02 '0\x00' int32 'hello\0' \0 + // int32 0x02 '0\x00' int32 'hello number\0' \0 // \0 const sizeNestedToBSON = BSON.calculateObjectSize({ a: [0] }); - expect(sizeNestedToBSON).to.equal(26); + expect(sizeNestedToBSON).to.equal(33); }); }); @@ -197,7 +201,10 @@ describe('toBSON', function () { expect(size).to.equal(17); const bytes = BSON.serialize({ toBSON: 1 }); - expect(bytes.indexOf(Buffer.from('toBSON\0', 'utf8'))).to.be.greaterThan(0); + const keyStart = 5; + const keyEnd = 12; + const serializedKey = bytes.subarray(keyStart, keyEnd); + expect(serializedKey).to.deep.equal(Buffer.from('toBSON\0', 'utf8')); }); it('should still be omitted if serializeFunctions is true', () => { @@ -205,7 +212,7 @@ describe('toBSON', function () { { toBSON: () => ({ a: 1, fn: () => ({ a: 1 }) }) }, { serializeFunctions: true } ); - expect(bytes.indexOf(Buffer.from('a\0', 'utf8'))).to.be.greaterThan(0); + expect(bytes.indexOf(97)).to.be.greaterThan(0); const doc = BSON.deserialize(bytes); expect(doc).to.have.property('a', 1); expect(doc).to.have.property('fn').that.is.instanceOf(BSON.Code); diff --git a/test/binary_parser.js b/test/node/tools/binary_parser.js similarity index 99% rename from test/binary_parser.js rename to test/node/tools/binary_parser.js index c2d1a461..3d669fc3 100644 --- a/test/binary_parser.js +++ b/test/node/tools/binary_parser.js @@ -1,6 +1,6 @@ 'use strict'; -const BSON = require('./register-bson'); +const BSON = require('../../register-bson'); const BSONError = BSON.BSONError; /** diff --git a/test/node/tools/utils.js b/test/node/tools/utils.js index 788c04ea..f96c36a2 100644 --- a/test/node/tools/utils.js +++ b/test/node/tools/utils.js @@ -1,5 +1,6 @@ /* globals window */ 'use strict'; +const { types } = require('node:util'); exports.assertArrayEqual = function (array1, array2) { if (array1.length !== array2.length) return false; @@ -158,6 +159,8 @@ exports.isNode6 = function () { return process.version.split('.')[0] === 'v6'; }; +exports.isBufferOrUint8Array = b => Buffer.isBuffer(b) || types.isUint8Array(b); + const getSymbolFrom = function (target, symbolName, assertExists) { if (assertExists == null) assertExists = true; diff --git a/test/node/uuid_tests.js b/test/node/uuid_tests.js index 37dd9ec2..97601d53 100644 --- a/test/node/uuid_tests.js +++ b/test/node/uuid_tests.js @@ -72,7 +72,7 @@ describe('UUID', () => { const org = new UUID(); const copy = new UUID(org); expect(org.id).to.not.equal(copy.id); - expect(org.id.equals(copy.id)).to.be.true; + expect(org.id).to.deep.equal(copy.id); }); /** diff --git a/test/register-bson.js b/test/register-bson.js index e4e57f1d..73166402 100644 --- a/test/register-bson.js +++ b/test/register-bson.js @@ -1,7 +1,66 @@ 'use strict'; -// TODO(NODE-3555): When we remove karma in favor of vm we can use ts-node to test src instead of lib here. -const BSON = require('../lib/bson'); -const { ensureBuffer } = require('../lib/ensure_buffer'); -BSON.ensureBuffer = ensureBuffer; +require('source-map-support').install({ + hookRequire: true +}); + +const { inspect } = require('node:util'); +const vm = require('node:vm'); +const fs = require('node:fs'); +const path = require('node:path'); +const chai = require('chai'); + +/** + * In the runInContext "web" testing instanceof checks fail + * since the error classes are declared in a different realm (?) + * So here we augment the chai assertion to fallback on checking the name property of the error instance + */ +chai.use(function (chai) { + const throwsAssertion = chai.Assertion.prototype.throw; + chai.Assertion.addMethod('throw', function (...args) { + try { + throwsAssertion.call(this, ...args); + } catch (assertionError) { + if (assertionError.actual?.name === assertionError.expected) { + return; + } + throw assertionError; + } + }); +}); + +// TODO(NODE-4786) +// Register expect globally, this is no longer necessary since we do not use karma / bundle everything together +globalThis.expect = chai.expect; + +// Controls whether to run BSON library declaration in an node or "web" environment +const web = process.env.WEB === 'true'; +console.error(inspect({ web }, { colors: true })); + +// TODO(NODE-4787): Node.js 16 was when the atob and btoa globals were introduced, so we need replacements for testing on 14 +const shim_btoa = input => Buffer.prototype.toString.call(Buffer.from(input), 'base64'); +const shim_atob = input => Buffer.from(input, 'base64').toString('binary'); + +let BSON; +if (web) { + // TODO(NODE-4713): Using the umd for now since it works well as a Node.js import + // Switch to the .cjs rollup planned for NODE-4713 + const filename = path.resolve(__dirname, '../dist/bson.browser.umd.js'); + const code = fs.readFileSync(filename, { encoding: 'utf8' }); + // These are the only globals BSON strictly depends on + // an optional global is crypto + const context = vm.createContext({ + TextEncoder, + TextDecoder, + btoa: typeof btoa !== 'undefined' ? btoa : shim_btoa, + atob: typeof atob !== 'undefined' ? atob : shim_atob + }); + vm.runInContext(code, context, { filename }); + BSON = context.BSON; +} else { + BSON = require('../src/bson'); +} + +// Some mocha tests need to know the environment for instanceof assertions or be skipped +BSON.__isWeb__ = web; module.exports = BSON; diff --git a/test/types/bson.test-d.ts b/test/types/bson.test-d.ts index 0a04870a..7c25258a 100644 --- a/test/types/bson.test-d.ts +++ b/test/types/bson.test-d.ts @@ -22,7 +22,7 @@ import { expectType<() => UUID>(Binary.prototype.toUUID); expectType<() => Binary>(UUID.prototype.toBinary); -expectType<(format?: string) => string>(Binary.prototype.toString); +expectType<(encoding?: 'hex' | 'base64' | 'utf8' | 'utf-8') => string>(Binary.prototype.toString); expectType<(radix?: number) => string>(Double.prototype.toString); expectType<(radix?: number) => string>(Long.prototype.toString); expectType<(radix?: number) => string>(Int32.prototype.toString); diff --git a/tools/.eslintrc.json b/tools/.eslintrc.json deleted file mode 100644 index f7e0f546..00000000 --- a/tools/.eslintrc.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "root": true, - "env": { - "node": true, - "es6": true - }, - "globals": { - "expect": true, - "BSON": false, - "Buffer": false - }, - "parserOptions": { - "ecmaVersion": 2018 - }, - "extends": [ - "eslint:recommended", - "plugin:prettier/recommended" - ], - "rules": { - "prettier/prettier": "error", - "no-console": "off", - "eqeqeq": [ - "error", - "always", - { - "null": "ignore" - } - ], - "strict": [ - "error", - "global" - ], - "promise/no-native": "off" - } -} diff --git a/tools/README.hbs b/tools/README.hbs deleted file mode 100644 index d64e3394..00000000 --- a/tools/README.hbs +++ /dev/null @@ -1,103 +0,0 @@ -# BSON parser - -BSON is short for "Binary JSON," and is the binary-encoded serialization of JSON-like documents. You can learn more about it in [the specification](http://bsonspec.org). - -This browser version of the BSON parser is compiled using [rollup](https://rollupjs.org/) and the current version is pre-compiled in the `dist` directory. - -This is the default BSON parser, however, there is a C++ Node.js addon version as well that does not support the browser. It can be found at [mongod-js/bson-ext](https://github.com/mongodb-js/bson-ext). - -### Table of Contents -- [Usage](#usage) -- [Bugs/Feature Requests](#bugs--feature-requests) -- [Installation](#installation) -- [Documentation](#documentation) -- [FAQ](#faq) - -## Bugs / Feature Requests - -Think you've found a bug? Want to see a new feature in `bson`? Please open a case in our issue management tool, JIRA: - -1. Create an account and login: [jira.mongodb.org](https://jira.mongodb.org) -2. Navigate to the NODE project: [jira.mongodb.org/browse/NODE](https://jira.mongodb.org/browse/NODE) -3. Click **Create Issue** - Please provide as much information as possible about the issue and how to reproduce it. - -Bug reports in JIRA for all driver projects (i.e. NODE, PYTHON, CSHARP, JAVA) and the Core Server (i.e. SERVER) project are **public**. - -## Usage - -To build a new version perform the following operations: - -``` -npm install -npm run build -``` - -A simple example of how to use BSON in the browser: - -```html - - - -``` - -A simple example of how to use BSON in `Node.js`: - -```js -const BSON = require('bson'); -const Long = BSON.Long; - -const doc = { long: Long.fromNumber(100) }; - -// Serialize a document -const data = BSON.serialize(doc); -console.log('data:', data); - -// Deserialize the resulting Buffer -const doc_2 = BSON.deserialize(data); -console.log('doc_2:', doc_2); -``` - -## Installation - -`npm install bson` - -## Documentation - -{{>main}} - -## FAQ - -#### Why does `undefined` get converted to `null`? - -The `undefined` BSON type has been [deprecated for many years](http://bsonspec.org/spec.html), so this library has dropped support for it. Use the `ignoreUndefined` option (for example, from the [driver](http://mongodb.github.io/node-mongodb-native/2.2/api/MongoClient.html#connect) ) to instead remove `undefined` keys. - -#### How do I add custom serialization logic? - -This library looks for `toBSON()` functions on every path, and calls the `toBSON()` function to get the value to serialize. - -```javascript -const BSON = require('bson'); - -class CustomSerialize { - toBSON() { - return 42; - } -} - -const obj = { answer: new CustomSerialize() }; -// "{ answer: 42 }" -console.log(BSON.deserialize(BSON.serialize(obj))); -``` diff --git a/tools/gleak.js b/tools/gleak.js deleted file mode 100644 index 226484c9..00000000 --- a/tools/gleak.js +++ /dev/null @@ -1,20 +0,0 @@ -var gleak = require('gleak')(); -gleak.ignore('AssertionError'); -gleak.ignore('testFullSpec_param_found'); -gleak.ignore('events'); -gleak.ignore('Uint8Array'); -gleak.ignore('Uint8ClampedArray'); -gleak.ignore('TAP_Global_Harness'); -gleak.ignore('setImmediate'); -gleak.ignore('clearImmediate'); - -gleak.ignore('DTRACE_NET_SERVER_CONNECTION'); -gleak.ignore('DTRACE_NET_STREAM_END'); -gleak.ignore('DTRACE_NET_SOCKET_READ'); -gleak.ignore('DTRACE_NET_SOCKET_WRITE'); -gleak.ignore('DTRACE_HTTP_SERVER_REQUEST'); -gleak.ignore('DTRACE_HTTP_SERVER_RESPONSE'); -gleak.ignore('DTRACE_HTTP_CLIENT_REQUEST'); -gleak.ignore('DTRACE_HTTP_CLIENT_RESPONSE'); - -module.exports = gleak; diff --git a/tools/scenarios-plugin.js b/tools/scenarios-plugin.js deleted file mode 100644 index 2ae3ef27..00000000 --- a/tools/scenarios-plugin.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - -const scenariosPlugin = () => { - return { - name: 'scenarios', - load(id) { - if (id.includes('bson_corpus_test_loader.js')) { - const corpus = require('../test/node/tools/bson_corpus_test_loader'); - return { - code: `export default ${JSON.stringify(corpus)};\n`, - map: { mappings: '' } - }; - } - } - }; -}; - -module.exports = { scenariosPlugin }; diff --git a/tsconfig.json b/tsconfig.json index 8ed4b682..5dda2773 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -31,7 +31,10 @@ }, "ts-node": { "transpileOnly": true, - "compiler": "typescript-cached-transpile" + "compiler": "typescript-cached-transpile", + "compilerOptions": { + "downlevelIteration": true + } }, "include": [ "src/**/*"