diff --git a/.github/workflows/install-test-react-native.yml b/.github/workflows/install-test-react-native.yml new file mode 100644 index 00000000000..e3267a9d5f8 --- /dev/null +++ b/.github/workflows/install-test-react-native.yml @@ -0,0 +1,69 @@ +name: Install test (React Native) + +on: + # Any change to these files + push: + paths: + - install-tests/react-native/** + - .github/workflows/install-test-react-native.yml + # Every day at 9:00 CET + schedule: + - cron: "0 8 * * *" + # You can also activate this workflow manually from the Actions tab + workflow_dispatch: + inputs: + react-native-version: + description: The version of React Native to install + required: true + default: next + realm-version: + description: The version of Realm to install + required: true + default: latest + +defaults: + run: + working-directory: install-tests/react-native + +jobs: + install: + name: Installing Realm → React Native (using Xcode v${{matrix.xcode}}, node v${{ matrix.node }}, npm v${{ matrix.npm }}) + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + # See https://github.com/actions/virtual-environments/blob/main/images/macos/macos-11-Readme.md#xcode + xcode: + # - 12.5 + - 13.1 + npm: + - 7 + node: + - 14 + env: + DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node }} + - name: Install npm v7 + run: npm install -g npm@7 + - name: ccache + uses: hendrikmuhs/ccache-action@v1 + with: + key: install-test + - name: Prepend ccache executables to the PATH + run: echo PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" >> $GITHUB_ENV + - name: Install React Native & Realm + run: ./install.sh ${{ github.event.inputs.react-native-version }} ${{ github.event.inputs.realm-version }} + - name: Invoke the simulator (making subsequent "open -a Simulator" calls work) + run: open -a ${{ env.DEVELOPER_DIR }}/Contents/Developer/Applications/Simulator.app/Contents/MacOS/Simulator + - name: Run test (iOS) + run: ./run-ios.sh + # - name: Run test (Android) + # uses: reactivecircus/android-emulator-runner@v2 + # with: + # api-level: 29 + # target: google_apis + # script: ./run-android.sh diff --git a/.gitignore b/.gitignore index 37ff1b8ec4a..7b8c69d10d7 100644 --- a/.gitignore +++ b/.gitignore @@ -70,6 +70,7 @@ crash.log examples/ReactExample/ios/Pods/ examples/ReactExample/ios/ReactExample.xcworkspace/ tests/mongodb-realm +install-tests/react-native/app/ # Integration tests integration-tests/environments/electron/dist/ diff --git a/.vscode/launch.json b/.vscode/launch.json index 2c4175b577c..7a46305c90e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -89,6 +89,24 @@ ], "cwd": "${workspaceFolder}/tests" }, + { + "type": "lldb", + "request": "launch", + "name": "LLDB Debug Integration Tests", + "program": "node", + "args": [ + "--expose_gc", + "node_modules/mocha/bin/mocha", + "--require", + "ts-node/register/transpile-only", + "--require", + "src/utils/inject-node-globals.ts", + "src/index.ts", + "--grep", + "${input:integrationTestFilter}" + ], + "cwd": "${workspaceFolder}/integration-tests/tests" + } ], "compounds": [ { @@ -112,6 +130,12 @@ "type": "promptString", "default": ".", "description": "Filtering used to limit what tests are run" + }, + { + "id": "integrationTestFilter", + "type": "promptString", + "default": "", + "description": "Filtering used to limit what tests are run" } ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 972248cbd00..c0a1b41c118 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,26 @@ NOTE: This is an early (alpha) release with Hermes/JSI support. Only iOS is supp * * +10.10.1 Release notes (2021-11-18) +============================================================= +### Enhancements +* None. + +### Fixed +* A sync user's Realm was not deleted when the user was removed if the Realm path was too long such that it triggered the fallback hashed name (this is OS dependant but is 300 characters on linux). ([realm/realm-core#4187](https://github.com/realm/realm-core/issues/4187), since v10.0.0-beta.10) +* Fixed a bug where opening a synced Realm would hang if the device's clock is more than 30 minutes fast. ([realm/realm-core#4941](https://github.com/realm/realm-core/issues/4941), since v10.0.0) +* Fixed a bug where an app hangs if it tries to connect after being offline for more than 30 minutes. ([#3882](https://github.com/realm/realm-js/issues/3882), since v10.0.0) + + +### Compatibility +* MongoDB Realm Cloud. +* Realm Studio v11.0.0. +* APIs are backwards compatible with all previous releases of Realm JavaScript in the 10.5.x series. +* File format: generates Realms with format v22 (reads and upgrades file format v5 or later for non-synced Realm, upgrades file format v10 or later for synced Realms). + +### Internal +* Upgraded Realm Core from v11.6.0 to v11.6.1. + 10.10.0 Release notes (2021-11-11) ============================================================= diff --git a/dependencies.list b/dependencies.list index 610b6ef5f94..8cb08a0cbdd 100644 --- a/dependencies.list +++ b/dependencies.list @@ -1,6 +1,6 @@ PACKAGE_NAME=realm-js VERSION=10.20.0-alpha.1 -REALM_CORE_VERSION=11.6.0 +REALM_CORE_VERSION=11.6.1 NAPI_VERSION=4 OPENSSL_VERSION=1.1.1g MDBREALM_TEST_SERVER_TAG=2021-06-01 diff --git a/install-tests/react-native/.eslintrc.json b/install-tests/react-native/.eslintrc.json new file mode 100644 index 00000000000..99e40cf38ed --- /dev/null +++ b/install-tests/react-native/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "extends": [ + "@react-native-community", + "../../.eslintrc" + ] +} \ No newline at end of file diff --git a/install-tests/react-native/App.js b/install-tests/react-native/App.js new file mode 100644 index 00000000000..1962f307ca2 --- /dev/null +++ b/install-tests/react-native/App.js @@ -0,0 +1,57 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2021 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +import { useEffect } from "react"; +import Realm from "realm"; + +const CALLBACK_HOST = "http://localhost:3000"; +const DELAY = 5000; +const schema = [{ name: "Person", properties: { name: "string" } }]; +const App = () => { + useEffect(() => { + const realm = new Realm({ schema }); + // Write persons into the database + if (realm.empty) { + realm.write(() => { + realm.create("Person", { name: "Alice" }); + realm.create("Person", { name: "Bob" }); + realm.create("Person", { name: "Charlie" }); + }); + } + // Read the persons out of the database again + const message = + "Persons are " + + realm + .objects("Person") + .map((p) => p.name) + .join(", "); + console.log(`Sending '${message}'`); + // Perform a request to signal a successful write & read + setTimeout(() => { + fetch(CALLBACK_HOST, { + method: "POST", + body: message, + }).catch(console.error); + }, DELAY); + // Close the Realm when component unmounts + return () => realm.close(); + }, []); + return null; +}; + +export default App; diff --git a/install-tests/react-native/install.sh b/install-tests/react-native/install.sh new file mode 100755 index 00000000000..2cad05116d6 --- /dev/null +++ b/install-tests/react-native/install.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +set -e + +react_native_version="${1:-next}" +realm_version="${2:-latest}" + +echo "Using React Native version = $react_native_version" +echo "Using Realm version = $realm_version" + +APP_DIR="$PWD/`dirname $0`/app" + +# Manually delete any previously created app +if [ -d "$APP_DIR" ]; then + echo "Found an existing app directory: Skipping React Native init" +else + # Create a new React Native app using the desired version + npx --yes react-native@$react_native_version init ReactNativeTestApp --version $react_native_version --directory $APP_DIR --npm +fi + +cd $APP_DIR +# Install CLI tools and Realm (using --force to ignore potential peerDependencies failures) +npm install ios-simulator concurrently retry-cli pod-install realm@$realm_version --force +# Run pod-install again +npx pod-install +# Overwrite the App.js +cp ../App.js . diff --git a/install-tests/react-native/listen.js b/install-tests/react-native/listen.js new file mode 100644 index 00000000000..0bda23d780c --- /dev/null +++ b/install-tests/react-native/listen.js @@ -0,0 +1,45 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2021 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +const { createServer } = require("http"); + +const TIMEOUT = 5 * 60 * 1000; // 5 minutes (although it shouldn't really take more than a minute) +const PORT = 3000; +const EXPECTED_MESSAGE = "Persons are Alice, Bob, Charlie"; + +createServer((req, res) => { + console.log("Client connected"); + req.on("data", (data) => { + const message = data.toString("utf-8"); + res.statusCode = 200; + res.end(); + console.log(`App sent "${message}"!`); + if (message === EXPECTED_MESSAGE) { + console.log("This was expected!"); + process.exit(0); + } else { + console.log(`This was unexpected! (expected ${EXPECTED_MESSAGE})`); + process.exit(1); + } + }); +}).listen(PORT); + +setTimeout(() => { + console.log("It took too long for the app to send the message"); + process.exit(1); +}, TIMEOUT); diff --git a/install-tests/react-native/package.json b/install-tests/react-native/package.json new file mode 100644 index 00000000000..84d59fd1de2 --- /dev/null +++ b/install-tests/react-native/package.json @@ -0,0 +1,4 @@ +{ + "name": "empty-package-to-avoid-react-native-cli-confusions", + "see": "https://github.com/react-native-community/cli/issues/1493" +} \ No newline at end of file diff --git a/install-tests/react-native/run-ios.sh b/install-tests/react-native/run-ios.sh new file mode 100755 index 00000000000..cb9738575b5 --- /dev/null +++ b/install-tests/react-native/run-ios.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +set -e + +APP_DIR="$PWD/`dirname $0`/app" +PROJECT_ROOT=$APP_DIR/../../.. + +# Manually delete any app previously created +if [ ! -d "$APP_DIR" ]; then + echo "Couldn't locate an app directory, did you run install.sh?" + exit 1 +fi + +# Determine the simulator's UDID +DEVICE_UDID=`npx ios-simulator -n 'iPhone 13'` +# Open the simulator +open -a Simulator --args -CurrentDeviceUDID $DEVICE_UDID +# Await the boot of the device +xcrun simctl bootstatus $DEVICE_UDID + +cd $APP_DIR + +# Build the app (ccache enabled) +RCT_NO_LAUNCH_PACKAGER=1 xcodebuild \ + -workspace ios/ReactNativeTestApp.xcworkspace \ + -configuration Debug \ + -scheme ReactNativeTestApp \ + -derivedDataPath ./build \ + -destination id=$DEVICE_UDID \ + CC="$PROJECT_ROOT/scripts/ccache-clang.sh" \ + CXX="$PROJECT_ROOT/scripts/ccache-clang++.sh" + +# Install the app onto the device +APP_BUNDLE_ID=org.reactjs.native.example.ReactNativeTestApp +APP_BUILD_PATH=./build/Build/Products/Debug-iphonesimulator/ReactNativeTestApp.app +xcrun simctl install $DEVICE_UDID $APP_BUILD_PATH + +# Run the app: Starting the listening server, Metro bundler and delayed launch of the app. +npx concurrently --kill-others --success "first" --names "listen,metro,app" \ + "node ../listen.js" \ + "react-native start" \ + "sleep 5; xcrun simctl launch --console-pty $DEVICE_UDID $APP_BUNDLE_ID" diff --git a/integration-tests/README.md b/integration-tests/README.md index 7edc66c526d..4c630890b04 100644 --- a/integration-tests/README.md +++ b/integration-tests/README.md @@ -71,6 +71,12 @@ When running the environments individually the test suite's TypeScript is not au npm run build:watch --prefix tests ``` +## Running tests with a C++ debugger attached + +In order to debug the tests with `lldb` attached to debug C++, you can use the VS Code launch configuration `LLDB Debug Integration Tests`. + +This bypasses the usual startup script (as this spawns a child process for the tests, which stops `lldb` working), so you need to have the app importer running separately when doing this: `npm run app-importer` from the `integration-tests/tests` directory. + ### Environment variables // TODO: Provide an explanation of the environment variables. diff --git a/integration-tests/tests/.mocharc.json b/integration-tests/tests/.mocharc.json new file mode 100644 index 00000000000..99f3ad09577 --- /dev/null +++ b/integration-tests/tests/.mocharc.json @@ -0,0 +1,4 @@ +{ + "extension": ["ts"], + "require": ["ts-node/register/transpile-only", "src/utils/inject-node-globals.ts"] +} diff --git a/integration-tests/tests/package-lock.json b/integration-tests/tests/package-lock.json index e64f441d069..493e7df3377 100644 --- a/integration-tests/tests/package-lock.json +++ b/integration-tests/tests/package-lock.json @@ -16,9 +16,9 @@ "@types/mocha": "^5.2.6", "concurrently": "^6.0.2", "fs-extra": "^7.0.1", - "mocha": "^5.2.0", + "mocha": "^9.1.3", "node-fetch": "^2.6.1", - "ts-mocha": "^6.0.0", + "ts-node": "^10.4.0", "typescript": "^4.2.4" }, "peerDependencies": { @@ -2056,6 +2056,27 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "peer": true }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@hapi/hoek": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", @@ -2245,26 +2266,6 @@ "node": ">=6 <7 || >=8" } }, - "node_modules/@react-native-community/cli-platform-android/node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@react-native-community/cli-platform-android/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -2305,26 +2306,6 @@ "node": ">=8" } }, - "node_modules/@react-native-community/cli-platform-ios/node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@react-native-community/cli-platform-ios/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -2463,26 +2444,6 @@ "node": ">=6 <7 || >=8" } }, - "node_modules/@react-native-community/cli/node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@react-native-community/cli/node_modules/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", @@ -2561,6 +2522,30 @@ "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", "peer": true }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, "node_modules/@types/chai": { "version": "4.2.16", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.16.tgz", @@ -2609,13 +2594,6 @@ "@types/istanbul-lib-report": "*" } }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true, - "optional": true - }, "node_modules/@types/mocha": { "version": "5.2.7", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", @@ -2648,6 +2626,12 @@ "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "peer": true }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -2679,6 +2663,27 @@ "node": ">= 0.6" } }, + "node_modules/acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/agent-base": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", @@ -2713,6 +2718,15 @@ "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==", "peer": true }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-fragments": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/ansi-fragments/-/ansi-fragments-0.2.1.tgz", @@ -2830,7 +2844,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "peer": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -2861,6 +2874,12 @@ "readable-stream": "^2.0.6" } }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -2933,15 +2952,6 @@ "node": ">=0.10.0" } }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -3232,6 +3242,15 @@ "node": ">=0.6" } }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -3300,7 +3319,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "peer": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -3385,7 +3403,8 @@ "node_modules/buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "peer": true }, "node_modules/bytes": { "version": "3.0.0", @@ -3466,7 +3485,6 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "peer": true, "engines": { "node": ">=10" }, @@ -3552,6 +3570,27 @@ "node": "*" } }, + "node_modules/chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -3809,12 +3848,6 @@ "node": ">=4.0.0" } }, - "node_modules/commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -4046,6 +4079,12 @@ "object-assign": "^4.1.1" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "node_modules/cross-fetch": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", @@ -4090,6 +4129,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "peer": true, "dependencies": { "ms": "2.0.0" } @@ -4252,9 +4292,9 @@ } }, "node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true, "engines": { "node": ">=0.3.1" @@ -4778,7 +4818,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "peer": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -4852,6 +4891,15 @@ "node": ">=8" } }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, "node_modules/flow-parser": { "version": "0.121.0", "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.121.0.tgz", @@ -4960,7 +5008,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -5109,9 +5156,9 @@ "peer": true }, "node_modules/glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5122,6 +5169,21 @@ }, "engines": { "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, "node_modules/graceful-fs": { @@ -5262,9 +5324,9 @@ } }, "node_modules/he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, "bin": { "he": "bin/he" @@ -5472,6 +5534,18 @@ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -5548,6 +5622,15 @@ "node": ">=0.10.0" } }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -5556,15 +5639,35 @@ "node": ">=8" } }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "peer": true, "engines": { "node": ">=0.12.0" } }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -5592,6 +5695,18 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "peer": true }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -5619,8 +5734,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "peer": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "node_modules/isobject": { "version": "3.0.1", @@ -6014,26 +6128,6 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "peer": true }, - "node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "optional": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/json5/node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true, - "optional": true - }, "node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -6479,26 +6573,6 @@ "integrity": "sha512-O9B65G8L/fopck45ZhdRosyVZdMtUQuX5mBWEC1NRj02iWBIUPLmYMjrunqIe8vHipCMp3DtTCm/65IlBmO8jg==", "peer": true }, - "node_modules/metro-cache/node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/metro-cache/node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -6870,26 +6944,6 @@ "klaw": "^1.0.0" } }, - "node_modules/metro/node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "peer": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/metro/node_modules/jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", @@ -7066,7 +7120,8 @@ "node_modules/minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "peer": true }, "node_modules/minipass": { "version": "3.1.3", @@ -7074,107 +7129,262 @@ "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", "peer": true, "dependencies": { - "yallist": "^4.0.0" + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "peer": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "peer": true, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "peer": true, + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "peer": true + }, + "node_modules/mocha": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", + "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.2", + "debug": "4.3.2", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.7", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.25", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.1.5", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "peer": true, + "node_modules/mocha/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" + "argparse": "^2.0.1" }, - "engines": { - "node": ">= 8" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "peer": true, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "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": { - "minimist": "0.0.8" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, - "bin": { - "mkdirp": "bin/cmd.js" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "peer": true + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, - "node_modules/mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "node_modules/mocha/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "dependencies": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">= 4.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha/node_modules/supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "node_modules/mocha/node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, "engines": { - "node": ">=4" + "node": ">=10" } }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "peer": true + }, + "node_modules/nanoid": { + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", + "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } }, "node_modules/nanomatch": { "version": "1.2.13", @@ -7325,7 +7535,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -7794,7 +8003,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "peer": true, "engines": { "node": ">=8" } @@ -7830,7 +8038,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "peer": true, "engines": { "node": ">=8.6" }, @@ -8082,6 +8289,15 @@ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", "peer": true }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -8285,6 +8501,18 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/realm": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/realm/-/realm-10.6.0.tgz", @@ -8610,8 +8838,7 @@ "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "peer": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/safe-regex": { "version": "1.1.0", @@ -8900,6 +9127,15 @@ "node": ">=0.10.0" } }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/serve-static": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", @@ -9268,6 +9504,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -9289,6 +9526,7 @@ "version": "0.5.19", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "peer": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -9564,16 +9802,6 @@ "node": ">=8" } }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, - "optional": true, - "engines": { - "node": ">=4" - } - }, "node_modules/strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", @@ -9583,6 +9811,18 @@ "node": ">=0.10.0" } }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/sudo-prompt": { "version": "9.2.1", "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz", @@ -9808,7 +10048,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "peer": true, "dependencies": { "is-number": "^7.0.0" }, @@ -9847,75 +10086,56 @@ "tree-kill": "cli.js" } }, - "node_modules/ts-mocha": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-6.0.0.tgz", - "integrity": "sha512-ZCtJK8WXxHNbFNjvUKQIXZby/+ybQQkaBcM/3QhBQUfwjpdGFE9F6iWsHhF5ifQNFV/lWiOODi2VMD5AyPcQyg==", - "dev": true, - "dependencies": { - "ts-node": "7.0.1" - }, - "bin": { - "ts-mocha": "bin/ts-mocha" - }, - "engines": { - "node": ">= 6.X.X" - }, - "optionalDependencies": { - "tsconfig-paths": "^3.5.0" - }, - "peerDependencies": { - "mocha": "^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X" - } - }, "node_modules/ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", "dev": true, "dependencies": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" + "yn": "3.1.1" }, "bin": { - "ts-node": "dist/bin.js" + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" }, - "engines": { - "node": ">=4.2.0" + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } } }, - "node_modules/ts-node/node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "node_modules/tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "optional": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" + "engines": { + "node": ">=0.3.1" } }, - "node_modules/tsconfig-paths/node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true, - "optional": true - }, "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -10297,6 +10517,21 @@ "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==", "peer": true }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -10355,6 +10590,12 @@ "node": ">=4" } }, + "node_modules/workerpool": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", + "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", + "dev": true + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -10488,13 +10729,52 @@ "node": ">=10" } }, - "node_modules/yn": { + "node_modules/yargs-unparser": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, "engines": { - "node": ">=4" + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } } }, @@ -11912,6 +12192,21 @@ } } }, + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, "@hapi/hoek": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", @@ -12033,20 +12328,6 @@ "universalify": "^0.1.0" } }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "peer": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", @@ -12161,20 +12442,6 @@ "universalify": "^0.1.0" } }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "peer": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -12211,20 +12478,6 @@ "supports-color": "^7.1.0" } }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "peer": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -12342,11 +12595,35 @@ "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==", "peer": true }, - "@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", - "peer": true + "@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "peer": true + }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true }, "@types/chai": { "version": "4.2.16", @@ -12396,13 +12673,6 @@ "@types/istanbul-lib-report": "*" } }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true, - "optional": true - }, "@types/mocha": { "version": "5.2.7", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", @@ -12435,6 +12705,12 @@ "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "peer": true }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -12460,6 +12736,18 @@ "negotiator": "0.6.2" } }, + "acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, "agent-base": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", @@ -12487,6 +12775,12 @@ "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==", "peer": true }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, "ansi-fragments": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/ansi-fragments/-/ansi-fragments-0.2.1.tgz", @@ -12579,7 +12873,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "peer": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -12607,6 +12900,12 @@ "readable-stream": "^2.0.6" } }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -12664,12 +12963,6 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "peer": true }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -12905,6 +13198,12 @@ "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==", "peer": true }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, "bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -12969,7 +13268,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "peer": true, "requires": { "fill-range": "^7.0.1" } @@ -13024,7 +13322,8 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "peer": true }, "bytes": { "version": "3.0.0", @@ -13088,8 +13387,7 @@ "camelcase": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "peer": true + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" }, "caniuse-lite": { "version": "1.0.30001245", @@ -13149,6 +13447,22 @@ "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" }, + "chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, "chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -13352,12 +13666,6 @@ "typical": "^4.0.0" } }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -13557,6 +13865,12 @@ "object-assign": "^4.1.1" } }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "cross-fetch": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", @@ -13591,6 +13905,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "peer": true, "requires": { "ms": "2.0.0" } @@ -13713,9 +14028,9 @@ "peer": true }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, "ecc-jsbn": { @@ -14143,7 +14458,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "peer": true, "requires": { "to-regex-range": "^5.0.1" } @@ -14204,6 +14518,12 @@ "path-exists": "^4.0.0" } }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, "flow-parser": { "version": "0.121.0", "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.121.0.tgz", @@ -14283,8 +14603,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true, - "peer": true + "optional": true }, "function-bind": { "version": "1.1.1", @@ -14402,9 +14721,9 @@ "peer": true }, "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -14414,6 +14733,15 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", @@ -14519,9 +14847,9 @@ } }, "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, "hermes-engine": { @@ -14685,6 +15013,15 @@ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -14743,16 +15080,36 @@ "is-plain-object": "^2.0.4" } }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "peer": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true }, "is-plain-object": { "version": "2.0.4", @@ -14775,6 +15132,12 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "peer": true }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -14796,8 +15159,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "peer": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isobject": { "version": "3.0.1", @@ -15125,25 +15487,6 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "peer": true }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "optional": true, - "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true, - "optional": true - } - } - }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -15523,20 +15866,6 @@ "klaw": "^1.0.0" } }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "peer": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", @@ -15657,20 +15986,6 @@ "rimraf": "^2.5.4" }, "dependencies": { - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "peer": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -16034,7 +16349,8 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "peer": true }, "minipass": { "version": "3.1.3", @@ -16069,6 +16385,7 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "peer": true, "requires": { "minimist": "0.0.8" } @@ -16080,45 +16397,147 @@ "peer": true }, "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", + "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", "dev": true, "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", + "chokidar": "3.5.2", + "debug": "4.3.2", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.7", "growl": "1.10.5", - "he": "1.1.1", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - }, - "dependencies": { - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "ms": "2.1.3", + "nanoid": "3.1.25", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.1.5", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "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" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true } } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "peer": true + }, + "nanoid": { + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", + "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", + "dev": true }, "nanomatch": { "version": "1.2.13", @@ -16243,8 +16662,7 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "peer": true + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "npm-run-path": { "version": "2.0.2", @@ -16600,8 +17018,7 @@ "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "peer": true + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "path-is-absolute": { "version": "1.0.1", @@ -16627,8 +17044,7 @@ "picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "peer": true + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" }, "pify": { "version": "4.0.1", @@ -16832,6 +17248,15 @@ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", "peer": true }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -17000,6 +17425,15 @@ "util-deprecate": "~1.0.1" } }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "realm": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/realm/-/realm-10.6.0.tgz", @@ -17269,8 +17703,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "peer": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-regex": { "version": "1.1.0", @@ -17519,6 +17952,15 @@ "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=", "peer": true }, + "serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, "serve-static": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", @@ -17815,7 +18257,8 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "peer": true }, "source-map-resolve": { "version": "0.5.3", @@ -17834,6 +18277,7 @@ "version": "0.5.19", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "peer": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -18061,19 +18505,18 @@ "ansi-regex": "^5.0.0" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, - "optional": true - }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "peer": true }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, "sudo-prompt": { "version": "9.2.1", "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.2.1.tgz", @@ -18272,7 +18715,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "peer": true, "requires": { "is-number": "^7.0.0" } @@ -18299,62 +18741,34 @@ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", "dev": true }, - "ts-mocha": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-6.0.0.tgz", - "integrity": "sha512-ZCtJK8WXxHNbFNjvUKQIXZby/+ybQQkaBcM/3QhBQUfwjpdGFE9F6iWsHhF5ifQNFV/lWiOODi2VMD5AyPcQyg==", - "dev": true, - "requires": { - "ts-node": "7.0.1", - "tsconfig-paths": "^3.5.0" - } - }, "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", "dev": true, "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" + "yn": "3.1.1" }, "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true } } }, - "tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", - "dev": true, - "optional": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true, - "optional": true - } - } - }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -18649,6 +19063,15 @@ "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==", "peer": true }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -18697,6 +19120,12 @@ } } }, + "workerpool": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", + "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", + "dev": true + }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -18803,10 +19232,36 @@ "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", "dev": true }, - "yn": { + "yargs-unparser": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + } + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true } } diff --git a/integration-tests/tests/package.json b/integration-tests/tests/package.json index 93af3c9dbaa..1a8d81600d6 100644 --- a/integration-tests/tests/package.json +++ b/integration-tests/tests/package.json @@ -10,7 +10,7 @@ "build": "tsc", "build:watch": "tsc --watch", "app-importer": "realm-app-importer serve ../realm-apps", - "mocha": "ts-mocha --project ./tsconfig.json --require src/utils/inject-node-globals.ts --watch-extensions ts,js src/index.ts", + "mocha": "mocha --watch-extensions ts,js src/index.ts", "lint": "eslint --ext .js,.ts .", "prepare": "npm run build" }, @@ -24,11 +24,11 @@ "@types/mocha": "^5.2.6", "concurrently": "^6.0.2", "fs-extra": "^7.0.1", - "mocha": "^5.2.0", + "mocha": "^9.1.3", "node-fetch": "^2.6.1", "realm": "*", "realm-app-importer": "*", - "ts-mocha": "^6.0.0", + "ts-node": "^10.4.0", "typescript": "^4.2.4" }, "dependencies": { @@ -38,4 +38,4 @@ "files": [ "/dist" ] -} \ No newline at end of file +} diff --git a/integration-tests/tests/start.js b/integration-tests/tests/start.js index ee67217cd97..773f484b73b 100644 --- a/integration-tests/tests/start.js +++ b/integration-tests/tests/start.js @@ -25,9 +25,12 @@ const concurrently = require("concurrently"); const extraArgs = process.argv.slice(2); -concurrently([{ command: `npm:mocha -- ${extraArgs.join(" ")}` }, { command: "npm:app-importer" }], { - killOthers: ["failure", "success"], -}).catch((tasks) => { +concurrently( + [{ command: `npm:mocha -- ${extraArgs.map((arg) => `"${arg}"`).join(" ")}` }, { command: "npm:app-importer" }], + { + killOthers: ["failure", "success"], + }, +).catch((tasks) => { const mocha = tasks.find((t) => t.index === 0); process.exit(mocha.exitCode); }); diff --git a/packages/realm-network-transport/src/dom/index.ts b/packages/realm-network-transport/src/dom/index.ts index 211860fcd74..5b371baa459 100644 --- a/packages/realm-network-transport/src/dom/index.ts +++ b/packages/realm-network-transport/src/dom/index.ts @@ -21,5 +21,5 @@ export * from "../index"; import { DefaultNetworkTransport } from "../DefaultNetworkTransport"; import { AbortController, Fetch } from "../types"; -DefaultNetworkTransport.fetch = window.fetch.bind(window) as Fetch; -DefaultNetworkTransport.AbortController = window.AbortController as AbortController; +DefaultNetworkTransport.fetch = globalThis.fetch.bind(globalThis) as Fetch; +DefaultNetworkTransport.AbortController = globalThis.AbortController as AbortController; diff --git a/packages/realm-web/.eslintrc.json b/packages/realm-web/.eslintrc.json index 7b1e580b2b6..7d84ce945bc 100644 --- a/packages/realm-web/.eslintrc.json +++ b/packages/realm-web/.eslintrc.json @@ -5,6 +5,7 @@ "plugin:jsdoc/recommended" ], "rules": { + "no-restricted-globals": ["error", "window", "global"], "@typescript-eslint/explicit-function-return-type": "off", "jsdoc/require-param-type": "off", "jsdoc/require-returns-type": "off", diff --git a/packages/realm-web/CHANGELOG.md b/packages/realm-web/CHANGELOG.md index cf25a748a1c..6e027f81000 100644 --- a/packages/realm-web/CHANGELOG.md +++ b/packages/realm-web/CHANGELOG.md @@ -1,3 +1,33 @@ +?.?.? Release notes (2020-??-??) +============================================================= + +### Breaking Changes +* None + +### Enhancements +* None + +### Fixed +* None + +### Internal +* None + +1.5.1 Release notes (2021-11-17) +============================================================= + +### Breaking Changes +* None + +### Enhancements +* None + +### Fixed +* Using `globalThis` instead of `window` global. This fix runtime issues when the package is bundled and loaded into a Cloudflare Worker. ([#4084](https://github.com/realm/realm-js/pull/4084), since 0.5.0) + +### Internal +* None + 1.5.0 Release notes (2021-11-11) ============================================================= diff --git a/packages/realm-web/README.md b/packages/realm-web/README.md index 5b888b876f1..dccdc85d587 100644 --- a/packages/realm-web/README.md +++ b/packages/realm-web/README.md @@ -19,7 +19,7 @@ npm install realm-web As a script-tag in the head of a browser: ```html - + ``` ## Caveats / limitations diff --git a/packages/realm-web/package-lock.json b/packages/realm-web/package-lock.json index 754ab726992..b12ce28fef2 100644 --- a/packages/realm-web/package-lock.json +++ b/packages/realm-web/package-lock.json @@ -1,17 +1,16 @@ { "name": "realm-web", - "version": "1.5.0", + "version": "1.5.1", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "realm-web", - "version": "1.5.0", + "version": "1.5.1", "license": "SEE LICENSE IN LICENSE", "dependencies": { - "bson": "^4.2.0", - "detect-browser": "^5.1.1", - "js-base64": "^2.6.3" + "bson": "^4.5.4", + "detect-browser": "^5.2.1", + "js-base64": "^3.7.2" }, "devDependencies": { "@rollup/plugin-commonjs": "^13.0.1", @@ -20,7 +19,7 @@ "@rollup/plugin-typescript": "^4.1.1", "@types/chai": "^4.2.9", "@types/fs-extra": "^8.1.0", - "@types/js-base64": "^2.3.2", + "@types/js-base64": "^3.3.1", "@types/mocha": "^7.0.1", "@types/node": "^13.7.6", "abort-controller": "^3.0.0", @@ -174,10 +173,14 @@ } }, "node_modules/@types/js-base64": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@types/js-base64/-/js-base64-2.3.2.tgz", - "integrity": "sha512-iGjZEnheu9n53fhlU+QLovdKHsdwPJ79iammNM0opTEp18zcJ/nNAIthuMilJoDPNUQHoqRAJdDNI5rxHY4nkA==", - "dev": true + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/js-base64/-/js-base64-3.3.1.tgz", + "integrity": "sha512-Zw33oQNAvDdAN9b0IE5stH0y2MylYvtU7VVTKEJPxhyM2q57CVaNJhtJW258ah24NRtaiA23tptUmVn3dmTKpw==", + "deprecated": "This is a stub types definition. js-base64 provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "js-base64": "*" + } }, "node_modules/@types/mocha": { "version": "7.0.2", @@ -464,9 +467,9 @@ ] }, "node_modules/bson": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-4.2.0.tgz", - "integrity": "sha512-c3MlJqdROnCRvDr/+MLfaDvQ7CvGI4p1hKX45/fvgzSwKRdOjsfRug1NJJ8ty5mXCNtUdjJEWzoZWcBQxV4TyA==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/bson/-/bson-4.5.4.tgz", + "integrity": "sha512-wIt0bPACnx8Ju9r6IsS2wVtGDHBr9Dxb+U29A1YED2pu8XOhS8aKjOnLZ8sxyXkPwanoK7iWWVhS1+coxde6xA==", "dependencies": { "buffer": "^5.6.0" }, @@ -737,9 +740,9 @@ } }, "node_modules/detect-browser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.1.1.tgz", - "integrity": "sha512-5n2aWI57qC3kZaK4j2zYsG6L1LrxgLptGCNhMQgdKhVn6cSdcq43pp6xHPfTHG3TYM6myF4tIPWiZtfdVDgb9w==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.2.1.tgz", + "integrity": "sha512-eAcRiEPTs7utXWPaAgu/OX1HRJpxW7xSHpw4LTDrGFaeWnJ37HRlqpUkKsDm0AoTbtrvHQhH+5U2Cd87EGhJTg==" }, "node_modules/diff": { "version": "3.5.0", @@ -1129,9 +1132,9 @@ "dev": true }, "node_modules/js-base64": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", - "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz", + "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==" }, "node_modules/js-tokens": { "version": "4.0.0", @@ -2056,10 +2059,13 @@ } }, "@types/js-base64": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@types/js-base64/-/js-base64-2.3.2.tgz", - "integrity": "sha512-iGjZEnheu9n53fhlU+QLovdKHsdwPJ79iammNM0opTEp18zcJ/nNAIthuMilJoDPNUQHoqRAJdDNI5rxHY4nkA==", - "dev": true + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/js-base64/-/js-base64-3.3.1.tgz", + "integrity": "sha512-Zw33oQNAvDdAN9b0IE5stH0y2MylYvtU7VVTKEJPxhyM2q57CVaNJhtJW258ah24NRtaiA23tptUmVn3dmTKpw==", + "dev": true, + "requires": { + "js-base64": "*" + } }, "@types/mocha": { "version": "7.0.2", @@ -2327,9 +2333,9 @@ } }, "bson": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-4.2.0.tgz", - "integrity": "sha512-c3MlJqdROnCRvDr/+MLfaDvQ7CvGI4p1hKX45/fvgzSwKRdOjsfRug1NJJ8ty5mXCNtUdjJEWzoZWcBQxV4TyA==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/bson/-/bson-4.5.4.tgz", + "integrity": "sha512-wIt0bPACnx8Ju9r6IsS2wVtGDHBr9Dxb+U29A1YED2pu8XOhS8aKjOnLZ8sxyXkPwanoK7iWWVhS1+coxde6xA==", "requires": { "buffer": "^5.6.0" } @@ -2561,9 +2567,9 @@ } }, "detect-browser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.1.1.tgz", - "integrity": "sha512-5n2aWI57qC3kZaK4j2zYsG6L1LrxgLptGCNhMQgdKhVn6cSdcq43pp6xHPfTHG3TYM6myF4tIPWiZtfdVDgb9w==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.2.1.tgz", + "integrity": "sha512-eAcRiEPTs7utXWPaAgu/OX1HRJpxW7xSHpw4LTDrGFaeWnJ37HRlqpUkKsDm0AoTbtrvHQhH+5U2Cd87EGhJTg==" }, "diff": { "version": "3.5.0", @@ -2883,9 +2889,9 @@ "dev": true }, "js-base64": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", - "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==" + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz", + "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==" }, "js-tokens": { "version": "4.0.0", diff --git a/packages/realm-web/package.json b/packages/realm-web/package.json index 9841fe5e7b9..70f06ea3803 100644 --- a/packages/realm-web/package.json +++ b/packages/realm-web/package.json @@ -1,6 +1,6 @@ { "name": "realm-web", - "version": "1.5.0", + "version": "1.5.1", "description": "Authenticate and communicate with the MongoDB Realm platform, from your web-browser", "main": "./dist/bundle.cjs.js", "module": "./dist/bundle.es.js", @@ -46,9 +46,9 @@ "license": "SEE LICENSE IN LICENSE", "dependencies": { "@realm.io/common": "^0.1.1", - "bson": "^4.2.0", - "detect-browser": "^5.1.1", - "js-base64": "^2.6.3" + "bson": "^4.5.4", + "detect-browser": "^5.2.1", + "js-base64": "^3.7.2" }, "optionalDependencies": { "abort-controller": "^3.0.0", @@ -61,7 +61,7 @@ "@rollup/plugin-typescript": "^4.1.1", "@types/chai": "^4.2.9", "@types/fs-extra": "^8.1.0", - "@types/js-base64": "^2.3.2", + "@types/js-base64": "^3.3.1", "@types/mocha": "^7.0.1", "@types/node": "^13.7.6", "abort-controller": "^3.0.0", diff --git a/packages/realm-web/src/FunctionsFactory.ts b/packages/realm-web/src/FunctionsFactory.ts index 28bd5e33cb6..9d5e6f6ecf7 100644 --- a/packages/realm-web/src/FunctionsFactory.ts +++ b/packages/realm-web/src/FunctionsFactory.ts @@ -16,6 +16,8 @@ // //////////////////////////////////////////////////////////////////////////// +import { Base64 } from "js-base64"; + import { Fetcher } from "./Fetcher"; import { serialize } from "./utils/ejson"; import { encodeQueryString } from "./utils/string"; diff --git a/packages/realm-web/src/dom/LocalStorage.ts b/packages/realm-web/src/dom/LocalStorage.ts index 419af3429e5..b84c92c540f 100644 --- a/packages/realm-web/src/dom/LocalStorage.ts +++ b/packages/realm-web/src/dom/LocalStorage.ts @@ -26,32 +26,32 @@ export class LocalStorage implements Storage { /** * Internal state of the storage. */ - private readonly window: Window; + private readonly global: typeof globalThis; /** * Constructs a LocalStorage using the global window. */ constructor() { - if (typeof window === "object") { - this.window = window; + if (typeof globalThis.localStorage === "object") { + this.global = globalThis; } else { - throw new Error("Cannot use LocalStorage without a global window object"); + throw new Error("Cannot use LocalStorage without a global localStorage object"); } } /** @inheritdoc */ public get(key: string): string | null { - return this.window.localStorage.getItem(key); + return this.global.localStorage.getItem(key); } /** @inheritdoc */ public set(key: string, value: string): void { - return this.window.localStorage.setItem(key, value); + return this.global.localStorage.setItem(key, value); } /** @inheritdoc */ public remove(key: string): void { - return this.window.localStorage.removeItem(key); + return this.global.localStorage.removeItem(key); } /** @inheritdoc */ @@ -63,25 +63,25 @@ export class LocalStorage implements Storage { public clear(prefix?: string): void { const keys = []; // Iterate all keys to find the once have a matching prefix. - for (let i = 0; i < this.window.localStorage.length; i++) { - const key = this.window.localStorage.key(i); + for (let i = 0; i < this.global.localStorage.length; i++) { + const key = this.global.localStorage.key(i); if (key && (!prefix || key.startsWith(prefix))) { keys.push(key); } } // Remove the items in a seperate loop to avoid updating while iterating. for (const key of keys) { - this.window.localStorage.removeItem(key); + this.global.localStorage.removeItem(key); } } /** @inheritdoc */ public addListener(listener: StorageChangeListener): void { - return this.window.addEventListener("storage", listener); + return this.global.addEventListener("storage", listener); } /** @inheritdoc */ public removeListener(listener: StorageChangeListener): void { - return this.window.removeEventListener("storage", listener); + return this.global.removeEventListener("storage", listener); } } diff --git a/packages/realm-web/src/dom/index.ts b/packages/realm-web/src/dom/index.ts index ee0f305a782..a5e9d189f57 100644 --- a/packages/realm-web/src/dom/index.ts +++ b/packages/realm-web/src/dom/index.ts @@ -25,20 +25,36 @@ declare global { export * from "../index"; import { setEnvironment, Environment } from "../environment"; - +import { MemoryStorage } from "../storage/MemoryStorage"; import { OAuth2Helper } from "../OAuth2Helper"; + import { LocalStorage } from "./LocalStorage"; export { LocalStorage }; const browser = detect(); -const environment: Environment = { - defaultStorage: new LocalStorage().prefix("realm-web"), - openWindow: (url) => window.open(url), +const DefaultStorage = "localStorage" in globalThis ? LocalStorage : MemoryStorage; +/** + * Attempt to use the browser to open a window + * + * @param url The url to open a window to. + * @returns Then newly create window. + */ +function openWindow(url: string) { + if (typeof globalThis.open === "function") { + return globalThis.open(url); + } else { + console.log(`Please open ${url}`); + return null; + } +} + +const environment: Environment = { + defaultStorage: new DefaultStorage().prefix("realm-web"), + openWindow, platform: browser?.name || "web", platformVersion: browser?.version || "0.0.0", - TextDecoder, }; @@ -50,7 +66,7 @@ setEnvironment(environment); * @param location An optional location to use (defaults to the windows current location). * @param storage Optional storage used to save any results from the location. */ -export function handleAuthRedirect(location = window.location, storage = environment.defaultStorage): void { +export function handleAuthRedirect(location = globalThis.location, storage = environment.defaultStorage): void { try { const queryString = location.hash.substr(1); // Strip the initial # from the hash OAuth2Helper.handleRedirect(queryString, storage); diff --git a/packages/realm-web/test/env.js b/packages/realm-web/test/env.js index a37ba0b1548..03188bcd71b 100644 --- a/packages/realm-web/test/env.js +++ b/packages/realm-web/test/env.js @@ -25,4 +25,6 @@ const tsConfigPath = path.resolve(__dirname, "../src/tests/tsconfig.json"); process.env.TS_NODE_PROJECT = tsConfigPath; console.log(`Loading TypeScript configuration from ${tsConfigPath}`); +// We can disable no-restricted-globals, since we know this will run on node.js +// eslint-disable-next-line no-restricted-globals global.__SDK_VERSION__ = "0.0.0-test"; diff --git a/src/android/io_realm_react_RealmReactModule.cpp b/src/android/io_realm_react_RealmReactModule.cpp index dfb78d18dfe..5dfb69fe414 100644 --- a/src/android/io_realm_react_RealmReactModule.cpp +++ b/src/android/io_realm_react_RealmReactModule.cpp @@ -100,7 +100,7 @@ JNIEXPORT void JNICALL Java_io_realm_react_RealmReactModule_install __android_log_print(ANDROID_LOG_VERBOSE, "JSRealm", "Building an exports object"); auto exports = jsi::Object(*runtime); __android_log_print(ANDROID_LOG_VERBOSE, "JSRealm", "Initializing ..."); - realm_jsi_init(*runtime, exports); + realm_hermes_init(*runtime, exports); } } @@ -108,5 +108,5 @@ JNIEXPORT void JNICALL Java_io_realm_react_RealmReactModule_invalidateCaches (JNIEnv *, jclass) { __android_log_print(ANDROID_LOG_VERBOSE, "JSRealm", "invalidateCaches"); - realm_jsi_invalidate_caches(); + realm_hermes_invalidate_caches(); } diff --git a/src/hermes/CMakeLists.txt b/src/hermes/CMakeLists.txt new file mode 100644 index 00000000000..35df2f21596 --- /dev/null +++ b/src/hermes/CMakeLists.txt @@ -0,0 +1,10 @@ +set(REACT_NATIVE_ROOT_DIR "${PACKAGE_ROOT_DIR}/node_modules/react-native") +set(JSI_HEADER_DIR "${REACT_NATIVE_ROOT_DIR}/ReactCommon/jsi") + +add_library(realm-js-hermes OBJECT + hermes_init.cpp +) + +target_include_directories(realm-js-hermes PRIVATE ${JSI_HEADER_DIR}) + +target_link_libraries(realm-js-hermes PUBLIC realm-js-shared) diff --git a/src/hermes/hermes_class.hpp b/src/hermes/hermes_class.hpp new file mode 100644 index 00000000000..bdf59deb5fa --- /dev/null +++ b/src/hermes/hermes_class.hpp @@ -0,0 +1,647 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2021 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "hermes_types.hpp" +#include "hermes_return_value.hpp" +#include "hermes_string.hpp" +#include "hermes_object.hpp" + +#include "js_class.hpp" +#include "js_util.hpp" + +#include +#include +#include +#include +#include +#include +#include + +namespace realm::js { + +template +struct RealmObjectClass; +template +class RealmClass; + +template<> +struct Arguments { + const std::vector valStorage; + const JsiEnv ctx; + const size_t count; + const JsiVal* const value; + Arguments(JsiEnv env, size_t argc, const jsi::Value* argv) + : valStorage([&] { + std::vector out; + out.reserve(argc); + for (size_t i = 0; i < argc; i++) { + out.emplace_back(env, argv[i]); + } + return out; + }()), + ctx(env), + count(argc), + value(valStorage.data()) {} + + // If moving or copying were allowed, we would need to update value's pointer + Arguments(Arguments&&) = delete; + + JsiVal operator[](size_t index) const noexcept { + if (index >= count) { + return ctx.undefined(); + } + return ctx(value[index]); + } + + void validate_maximum(size_t max) const { + if (max < count) { + throw std::invalid_argument(util::format("Invalid arguments: at most %1 expected, but %2 supplied.", max, count)); + } + } + + void validate_count(size_t expected) const { + if (count != expected) { + throw std::invalid_argument(util::format("Invalid arguments: %1 expected, but %2 supplied.", expected, count)); + } + } + + void validate_between(size_t min, size_t max) const { + if (count < min || count > max) { + throw std::invalid_argument(util::format("Invalid arguments: expected between %1 and %2, but %3 supplied.", min, max, count)); + } + } +}; + +namespace hermes { + +inline std::optional ObjectGetOwnPropertyDescriptor(JsiEnv env, const jsi::Object& target, const std::string& name) { + auto obj = js::globalType(env, "Object"); + auto res = obj.getPropertyAsFunction(env, "getOwnPropertyDescriptor").callWithThis(env, obj, target, name); + if (!res.isObject()) + return {}; + return std::move(res).getObject(env); +} + +inline void ObjectSetPrototypeOf(JsiEnv env, const jsi::Value& target, const jsi::Value& proto) { + auto obj = js::globalType(env, "Object"); + obj.getPropertyAsFunction(env, "setPrototypeOf").callWithThis(env, obj, target, proto); +} + +inline void defineProperty(JsiEnv env, const jsi::Object& target, StringData name, const jsi::Object& descriptor) { + auto objClass = js::globalType(env, "Object"); + objClass.getPropertyAsFunction(env, "defineProperty") + .callWithThis(env, objClass, target, str(env, name), descriptor); +}; + +inline void copyProperty(JsiEnv env, const jsi::Object& from, const jsi::Object& to, const std::string& name) { + auto prop = ObjectGetOwnPropertyDescriptor(env, from, name); + REALM_ASSERT_RELEASE(prop); + defineProperty(env, to, "name", *prop); +} + +inline constexpr const char g_internal_field[] = "__Realm_internal"; + +template +using ClassDefinition = js::ClassDefinition; + +using ConstructorType = js::ConstructorType; +using ArgumentsMethodType = js::ArgumentsMethodType; +using ReturnValue = js::ReturnValue; +using Arguments = js::Arguments; +using PropertyType = js::PropertyType; +using IndexPropertyType = js::IndexPropertyType; +using StringPropertyType = js::StringPropertyType; + +template +class Wrapper : public jsi::HostObject { +public: + template >> + Wrapper(Args&&... args) : obj(std::forward(args)...) {} + + T obj; +}; + +template +inline T& unwrap(Wrapper& wrapper) { + return wrapper.obj; +} + +template +inline T& unwrap(const std::shared_ptr>& wrapper) { + return unwrap(*wrapper); +} + +template +inline T& unwrap(JsiEnv env, const jsi::Object& wrapper) { + return unwrap(wrapper.getHostObject>(env)); +} + +template +inline T& unwrap(JsiEnv env, const jsi::Value& wrapper) { + return unwrap(env, wrapper.asObject(env)); +} + +template +inline T& unwrap(const JsiObj& wrapper) { + return unwrap(wrapper.env(), wrapper.get()); +} + +template +inline T& unwrap(const JsiVal& wrapper) { + return unwrap(wrapper.env(), wrapper.get()); +} + +template +inline T* unwrapUnique(JsiEnv env, const U& arg) { + return unwrap>(env, arg).get(); +} + +template +JsiObj wrap(JsiEnv env, T arg) { + return env(jsi::Object::createFromHostObject(env, std::make_shared>(std::move(arg)))); +} + +template >> +JsiObj wrap(JsiEnv env, Args&&... args) { + return env(jsi::Object::createFromHostObject(env, std::make_shared>(std::forward(args)...))); +} + +template +JsiObj wrapUnique(JsiEnv env, T* arg) { + return wrap(env, std::unique_ptr(arg)); +} + +template +class ObjectWrap { +public: + using Internal = typename T::Internal; + using ParentClassType = typename T::Parent; + + // XXX if this is static, it won't support multiple runtimes. + // Also, may need to suppress destruction. + inline static std::optional s_ctor; + + static JsiFunc create_constructor(JsiEnv env) { + auto& s_type = get_class(); + + auto nativeFunc = + !bool(s_type.constructor) + ? jsi::Value() + : jsi::Function::createFromHostFunction( + env, propName(env, s_type.name), /* XXX paramCount */0, + [](jsi::Runtime& rt, const jsi::Value&, const jsi::Value* args, size_t count) -> jsi::Value { + REALM_ASSERT_RELEASE(count >= 1); + auto env = JsiEnv(rt); + auto& s_type = get_class(); + auto arguments = Arguments{env, count - 1, args + 1}; + s_type.constructor(env, env(args[0]).asObject(), arguments); + return jsi::Value(); + }); + + s_ctor = env(globalType(env, "Function") + .call(env, + "nativeFunc", + util::format(R"( + return function %1(...args) { + // "use strict"; + if (!nativeFunc && false) // XXX only disable check for Realm.Object + throw TypeError("%1() cannot be constructed directly from javascript"); + if (!new.target && false) { // XXX find another way to detect this correctly + throw TypeError("%1() must be called as a constructor"); + } + if (nativeFunc) + nativeFunc(this, ...args); + + if ('_proxyWrapper' in %1) + return %1._proxyWrapper(this); + })", s_type.name)) + .asObject(env).asFunction(env) + .call(env, std::move(nativeFunc)) + .asObject(env).asFunction(env) + ); + + js::Context::register_invalidator([] { + // Ensure the static constructor is destructed when the runtime goes away. + // This is to avoid the reassignment of s_ctor throwing because the runtime has disappeared. + s_ctor.reset(); + }); + + for (auto&& [name, prop] : s_type.static_properties) { + auto desc = jsi::Object(env); + if (prop.getter) { + desc.setProperty(env, "get", funcVal(env, "get_" + name, 0, prop.getter)); + } + if (prop.setter) { + desc.setProperty(env, "set", funcVal(env, "set_" + name, 1, prop.setter)); + } + defineProperty(env, *s_ctor, name, desc); + } + + for (auto&& [name, method] : s_type.static_methods) { + auto desc = jsi::Object(env); + desc.setProperty(env, "value", funcVal(env, name, /* XXX paramCount */ 0, method)); + defineProperty(env, *s_ctor, name, desc); + } + + auto proto = (*s_ctor)->getPropertyAsObject(env, "prototype"); + + for (auto&& [name, prop] : s_type.properties) { + auto desc = jsi::Object(env); + if (prop.getter) { + desc.setProperty(env, "get", funcVal(env, "get_" + name, 0, prop.getter)); + } + if (prop.setter) { + desc.setProperty(env, "set", funcVal(env, "set_" + name, 1, prop.setter)); + } + defineProperty(env, proto, name, desc); + } + + for (auto&& [name, method] : s_type.methods) { + auto desc = jsi::Object(env); + desc.setProperty(env, "value", funcVal(env, name, /* XXX paramCount */ 0, method)); + defineProperty(env, proto, name, desc); + } + + if constexpr (!std::is_void_v) { + REALM_ASSERT_RELEASE(ObjectWrap::s_ctor); + JsiFunc parentCtor = *ObjectWrap::s_ctor; + + auto parentProto = parentCtor->getProperty(env, "prototype"); + if (parentProto.isUndefined()) { + throw std::runtime_error("undefined 'prototype' on parent constructor"); + } + + ObjectSetPrototypeOf(env, jsi::Value(env, proto), jsi::Value(std::move(parentProto))); + ObjectSetPrototypeOf(env, jsi::Value(env, s_ctor->get()), jsi::Value(std::move(parentCtor.get()))); + } + + if (s_type.index_accessor) { + // Code below assumes getter is present, and it doesn't make sense to have setter without one. + REALM_ASSERT_RELEASE(s_type.index_accessor.getter); + + // XXX Do we want to trap things like ownKeys() and getOwnPropertyDescriptors() to support for...in? + auto [getter, setter] = s_type.index_accessor; + auto desc = jsi::Object(env); + desc.setProperty( + env, + "value", + globalType(env, "Function").call(env, "getter", "setter", R"( + const integerPattern = /^\d+$/; + function getIndex(prop) { + if (typeof prop === "string" && integerPattern.test(prop)) { + return parseInt(prop, 10); + } else { + return Number.NaN; + } + } + const handler = { + ownKeys(target) { + const out = Reflect.ownKeys(target) + const end = target.length + for (let i = 0; i < end; i++) { + out.push(String(i)); + } + return out; + }, + getOwnPropertyDescriptor(target, prop) { + const index = getIndex(prop); + if (Number.isNaN(index)) { + return Reflect.getOwnPropertyDescriptor(...arguments); + } else if (index >= 0 && index < target.length) { + return { + configurable: true, + enumerable: true, + }; + } + }, + get(target, prop, receiver) { + const index = getIndex(prop); + if (Number.isNaN(index)) { + return Reflect.get(...arguments); + } else if (index >= 0 && index < target.length) { + return getter(target, index); + } + }, + set(target, prop, value, receiver) { + const index = getIndex(prop); + if (Number.isNaN(index)) { + return Reflect.set(...arguments); + } else if (setter) { + return setter(target, index, value); + } else { + return false; + } + } + } + return (obj) => new Proxy(obj, handler); + )") + .asObject(env).asFunction(env) + .call(env, funcVal(env, "getter", 0, getter), funcVal(env, "setter", 1, setter)) + .asObject(env).asFunction(env) + ); + defineProperty(env, *s_ctor, "_proxyWrapper", desc); + } + + return env((*s_ctor)->getFunction(env)); + } + + static JsiObj create_instance(JsiEnv env, Internal* ptr = nullptr) { + auto proto = (*s_ctor)->getPropertyAsObject(env, "prototype"); + auto objClass = js::globalType(env, "Object"); + auto obj = env(objClass.getPropertyAsFunction(env, "create").callWithThis(env, objClass, proto)).asObject(); + set_internal(env, obj, ptr); + + auto wrapper = (*s_ctor)->getProperty(env, "_proxyWrapper"); + if (!wrapper.isUndefined()) { + obj = env(wrapper.asObject(env).asFunction(env).call(env, std::move(obj.get()))).asObject(); + } + + return obj; + } + + static JsiObj create_instance_by_schema(JsiEnv env, JsiFunc& constructor, const realm::ObjectSchema& schema, Internal* internal = nullptr) { + return create_instance_by_schema(env, &constructor, schema, internal); + } + static JsiObj create_instance_by_schema(JsiEnv env, const realm::ObjectSchema& schema, Internal* internal = nullptr) { + return create_instance_by_schema(env, nullptr, schema, internal); + } + + static void on_context_destroy(JsiEnv, std::string realmPath) { + get_schemaObjectTypes().erase(realmPath); + } + + static bool is_instance(JsiEnv env, JsiObj object) { + return object->instanceOf(env, *s_ctor); + } + + static Internal* get_internal(JsiEnv env, const JsiObj& object) { + auto internal = object->getProperty(env, g_internal_field); + if (internal.isUndefined()) { + if constexpr (std::is_same_v>) // XXX comment why + return nullptr; + throw jsi::JSError(env, "no internal field"); + } + if (!JsiObj(object)->instanceOf(env, *s_ctor)) { + throw jsi::JSError(env, "calling method on wrong type of object"); + } + return unwrapUnique(env, std::move(internal)); + } + static void set_internal(JsiEnv env, const JsiObj& object, Internal* data) { + auto desc = jsi::Object(env); + desc.setProperty(env, "value", wrapUnique(env, data)); + desc.setProperty(env, "configurable", true); + defineProperty(env, object, g_internal_field, desc); + } + +private: + static jsi::Value funcVal(JsiEnv env, const std::string& name, size_t args, jsi::HostFunctionType&& func) { + if (!func) + return jsi::Value(); + return jsi::Value(jsi::Function::createFromHostFunction(env, propName(env, name), uint32_t(args), std::move(func))); + }; + + static void defineSchemaProperties(JsiEnv env, const jsi::Object& constructorPrototype, const realm::ObjectSchema& schema, bool redefine) { + // Do the same thing for all computed and persisted properties + auto loopBody = [&] (const Property& property) { + const auto& name = property.public_name.empty() ? property.name : property.public_name; + // TODO should this use hasOwnProperty? + if (!redefine && constructorPrototype.hasProperty(env, str(env, name))) { + return; + } + + auto desc = jsi::Object(env); + desc.setProperty(env, "enumerable", true); + + desc.setProperty(env, "get", funcVal(env, "get_" + name, 0, [name = String(name)] (jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) { + if (count != 0) + throw jsi::JSError(rt, "getters take no arguments"); + return get_class().string_accessor.getter(rt, thisVal, name); + })); + desc.setProperty(env, "set", funcVal(env, "set_" + name, 1, [name = String(name)] (jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) { + if (count != 1) + throw jsi::JSError(rt, "setters take exactly 1 argument"); + return get_class().string_accessor.setter(rt, thisVal, name, args[0]); + })); + + defineProperty(env, constructorPrototype, name, desc); + }; + + for (auto&& property : schema.persisted_properties) { loopBody(property); } + for (auto&& property : schema.computed_properties) { loopBody(property); } + } + + static JsiObj create_instance_by_schema(JsiEnv env, JsiFunc* maybeConstructor, const realm::ObjectSchema& schema, Internal* internal = nullptr) { + auto& s_schemaObjectTypes = get_schemaObjectTypes(); + auto& s_class = get_class(); + + bool isRealmObjectClass = std::is_same_v>; + if (!isRealmObjectClass) { + throw jsi::JSError(env, "Creating instances by schema is supported for RealmObjectClass only"); + } + + if (!internal) { + throw jsi::JSError(env, "RealmObjectClass requires an internal realm object when creating instances by schema"); + } + + REALM_ASSERT_RELEASE(!s_class.index_accessor); // assume we don't need a ProxyWrapper + + auto config = internal->realm()->config(); + std::string path = config.path; + auto version = internal->realm()->schema_version(); + std::string schemaName = schema.name + ":" + std::to_string(version); + + const JsiFunc& realmObjectClassConstructor = *ObjectWrap::s_ctor; + + auto& schemaObjects = s_schemaObjectTypes[path]; + + //jsi::Symbol externalSymbol = ExternalSymbol; + + //if we are creating a RealmObject from schema with no user defined constructor + if (!maybeConstructor) { + //1.Check by name if the constructor is already created for this RealmObject + if (!schemaObjects.count(schemaName)) { + + //2.Create the constructor + + //create the RealmObject function by name + // XXX May need to escape/sanitize schema.name to avoid code injection + auto schemaObjectConstructor = + globalType(env, "Function") + .callAsConstructor(env, "return function " + schema.name + "() {}") + .asObject(env).asFunction(env).call(env) + .asObject(env).asFunction(env); + + + auto schemaProto = schemaObjectConstructor.getProperty(env, "prototype"); + ObjectSetPrototypeOf(env, + schemaProto, + realmObjectClassConstructor->getProperty(env, "prototype")); + ObjectSetPrototypeOf(env, + JsiVal(env(schemaObjectConstructor)), + JsiVal(realmObjectClassConstructor)); + + defineSchemaProperties(env, std::move(schemaProto).asObject(env), schema, true); + + schemaObjects.emplace(schemaName, std::move(schemaObjectConstructor)); + } + } else { + //creating a RealmObject with user defined constructor + auto& constructor = *maybeConstructor; + + bool schemaExists = schemaObjects.count(schemaName); + if (schemaExists) { + //check if constructors have changed for the same schema object and name + if (!jsi::Function::strictEquals(env, schemaObjects.at(schemaName), constructor)) { + schemaExists = false; + schemaObjects.erase(schemaName); + } + } + + if (!schemaExists) { + schemaObjects.emplace(schemaName, JsiFunc(constructor).get()); + auto constructorPrototype = constructor->getPropertyAsObject(env, "prototype"); + + //get all properties from the schema + defineSchemaProperties(env, env(constructorPrototype), schema, false); + + //Skip if the user defined constructor inherited the RealmObjectClass. All RealmObjectClass members are available already. + if (!constructorPrototype.instanceOf(env, realmObjectClassConstructor)) { + //setup all RealmObjectClass methods to the prototype of the object + auto realmObjectClassProto = realmObjectClassConstructor->getPropertyAsObject(env, "prototype"); + for (auto& [name, method] : s_class.methods) { + //don't redefine if exists + // TODO should this use hasOwnProperty? + if (!constructorPrototype.hasProperty(env, propName(env, name))) { + copyProperty(env, realmObjectClassProto, constructorPrototype, name); + } + } + + for (auto& [name, property] : s_class.properties) { + // TODO should this use hasOwnProperty? + if (!constructorPrototype.hasProperty(env, propName(env, name))) { + copyProperty(env, realmObjectClassProto, constructorPrototype, name); + } + } + } + } + } + + const auto& schemaObjectCtor = schemaObjects.at(schemaName); + auto instanceVal = schemaObjectCtor.callAsConstructor(env); + if (!instanceVal.isObject()) { + throw jsi::JSError(env, "Realm object constructor must not return another value"); + } + auto instance = env(std::move(instanceVal).getObject(env)); + if (!instance->instanceOf(env, schemaObjectCtor)) { + throw jsi::JSError(env, "Realm object constructor must not return another value"); + } + + set_internal(env, instance, internal); + return instance; + } + + static auto& get_class() { + // TODO this is silly. These should be static properties. + static T s_class; + return s_class; + } + + inline static auto& get_schemaObjectTypes() { + // XXX this being static prevents using multiple runtimes. + static std::unordered_map> s_schemaObjectTypes; + return s_schemaObjectTypes; + } +}; + +} // hermes + +template + class ObjectWrap : public hermes::ObjectWrap {}; + +template +jsi::Value wrap(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) { + auto env = JsiEnv(rt); + auto result = hermes::ReturnValue(env); + auto arguments = hermes::Arguments{env, count, args}; + + F(env, env(thisVal).asObject(), arguments, result); + return std::move(result).ToValue(); +} + +template +jsi::Value wrap(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) { + auto env = JsiEnv(rt); + auto result = hermes::ReturnValue(env); + auto arguments = hermes::Arguments{env, count, args}; + arguments.validate_count(0); + + F(env, env(thisVal).asObject(), result); + return std::move(result).ToValue(); +} + +template +jsi::Value wrap(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) { + auto env = JsiEnv(rt); + auto arguments = hermes::Arguments{env, count, args}; + arguments.validate_count(1); + + F(env, env(thisVal).asObject(), JsiVal(env, args[0])); + + return jsi::Value(); +} + +template +jsi::Value wrap(jsi::Runtime& rt, const jsi::Value&, const jsi::Value* args, size_t count) { + REALM_ASSERT_RELEASE(count == 2); + auto env = JsiEnv(rt); + auto out = hermes::ReturnValue(env); + F(env, env(args[0]).asObject(), uint32_t(args[1].asNumber()), out); + return std::move(out).ToValue(); +} + +template +jsi::Value wrap(jsi::Runtime& rt, const jsi::Value&, const jsi::Value* args, size_t count) { + REALM_ASSERT_RELEASE(count == 3); + auto env = JsiEnv(rt); + return jsi::Value(F(env, env(args[0]).asObject(), uint32_t(args[1].asNumber()), env(args[2]))); +} + +template +jsi::Value wrap(jsi::Runtime& rt, const jsi::Value& thisVal, const hermes::String& str) { + auto env = JsiEnv(rt); + auto result = hermes::ReturnValue(env); + F(env, env(thisVal).asObject(), str, result); + return std::move(result).ToValue(); +} + +template +jsi::Value wrap(jsi::Runtime& rt, const jsi::Value& thisVal, const hermes::String& str, const jsi::Value& value) { + auto env = JsiEnv(rt); + F(env, env(thisVal).asObject(), str, env(value)); + return jsi::Value(); +} + +template +jsi::Value wrap(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count) { + // This is only used in the JSC impl. + REALM_UNREACHABLE(); +} + +} // realm::js diff --git a/src/hermes/hermes_function.hpp b/src/hermes/hermes_function.hpp new file mode 100644 index 00000000000..ce187dff5e6 --- /dev/null +++ b/src/hermes/hermes_function.hpp @@ -0,0 +1,51 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2021 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "hermes_types.hpp" + +namespace realm { +namespace js { + +template <> +inline JsiVal hermes::Function::call(JsiEnv env, const JsiFunc& function, size_t argc, const JsiVal arguments[]) { + return env(function->call(env, env.args(arguments, argc), argc)); +} + +template <> +inline JsiVal hermes::Function::call(JsiEnv env, const JsiFunc& function, const JsiObj& this_object, size_t argc, const JsiVal arguments[]) { + return env(function->callWithThis(env, this_object, env.args(arguments, argc), argc)); +} + +template <> +inline JsiVal hermes::Function::callback(JsiEnv env, const JsiFunc& function, size_t argc, const JsiVal arguments[]) { + return env(function->call(env, env.args(arguments, argc), argc)); +} +template <> +inline JsiVal hermes::Function::callback(JsiEnv env, const JsiFunc& function, const JsiObj& this_object, size_t argc, const JsiVal arguments[]) { + return env(function->callWithThis(env, this_object, env.args(arguments, argc), argc)); +} + +template <> +inline JsiObj hermes::Function::construct(JsiEnv env, const JsiFunc& function, size_t argc, const JsiVal arguments[]) { + return env(function->callAsConstructor(env, env.args(arguments, argc), argc).asObject(env)); +} + +} // namespace js +} // namespace realm diff --git a/src/hermes/hermes_init.cpp b/src/hermes/hermes_init.cpp new file mode 100644 index 00000000000..523b8839809 --- /dev/null +++ b/src/hermes/hermes_init.cpp @@ -0,0 +1,49 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2021 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + + +#include "hermes_init.hpp" + +#if !REALM_ENABLE_SYNC +#pragma comment( lib, "ws2_32.lib") +#pragma comment (lib, "crypt32") +#endif + +#include "js_realm.hpp" + +#include +#include + +namespace realm::js::hermes { + extern "C" void realm_hermes_init(jsi::Runtime& rt, jsi::Object& exports) { + auto env = JsiEnv(rt); + jsi::Function realm_constructor = js::RealmClass::create_constructor(env); + auto name = realm_constructor.getProperty(env, "name").asString(env); + exports.setProperty(env, std::move(name), std::move(realm_constructor)); + } + extern "C" void realm_hermes_invalidate_caches() { + // Close all cached Realms + realm::_impl::RealmCoordinator::clear_all_caches(); + // Clear the Object Store App cache, to prevent instances from using a context that was released + realm::app::App::clear_cached_apps(); + // Ensure all registered invalidators get notified that the runtime is going away. + realm::js::Context::invalidate(); + } +} + +// TODO hook up as TurboModule diff --git a/src/hermes/hermes_init.h b/src/hermes/hermes_init.h new file mode 100644 index 00000000000..759e56b4d73 --- /dev/null +++ b/src/hermes/hermes_init.h @@ -0,0 +1,33 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2021 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#pragma once + +#import + +#ifdef __cplusplus +extern "C" { +#endif + +namespace jsi = facebook::jsi; +void realm_hermes_init(jsi::Runtime& rt, jsi::Object& exports); +void realm_hermes_invalidate_caches(); + +#ifdef __cplusplus +} +#endif diff --git a/src/hermes/hermes_init.hpp b/src/hermes/hermes_init.hpp new file mode 100644 index 00000000000..79df738d4f4 --- /dev/null +++ b/src/hermes/hermes_init.hpp @@ -0,0 +1,30 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2021 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "hermes_string.hpp" +#include "hermes_protected.hpp" +#include "hermes_function.hpp" +#include "hermes_value.hpp" +#include "hermes_object.hpp" +#include "hermes_return_value.hpp" +#include "hermes_class.hpp" + +// FIXME: js_object_accessor.hpp includes js_list.hpp which includes js_object_accessor.hpp. +#include "js_object_accessor.hpp" diff --git a/src/hermes/hermes_object.hpp b/src/hermes/hermes_object.hpp new file mode 100644 index 00000000000..5429299833c --- /dev/null +++ b/src/hermes/hermes_object.hpp @@ -0,0 +1,197 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2021 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "hermes_types.hpp" +#include "hermes_string.hpp" + +namespace realm { +namespace js { + +#if 0 +inline napi_property_attributes operator|(napi_property_attributes a, PropertyAttributes b) { + int flag = napi_default; + + if ((b & DontEnum) != DontEnum) { + flag |= napi_enumerable; + } + + if ((b & DontDelete) != DontDelete) { + flag |= napi_configurable; + } + + if ((b & ReadOnly) != ReadOnly) { + flag |= napi_writable; + } + + napi_property_attributes napi_flag = static_cast(a | flag); + return napi_flag; +} +#endif + +template<> +inline JsiVal hermes::Object::get_property(JsiEnv env, const JsiObj& object, StringData key) { + return env(object->getProperty(env, propName(env, key))); +} + +template<> +inline JsiVal hermes::Object::get_property(JsiEnv env, const JsiObj& object, const hermes::String &key) { + return env(object->getProperty(env, propName(env, key))); +} + +template<> +inline JsiVal hermes::Object::get_property(JsiEnv env, const JsiObj& object, uint32_t index) { + if (object->isArray(env)) + return env(object->asArray(env).getValueAtIndex(env, index)); + return hermes::Object::get_property(env, object, std::to_string(index)); +} + +template<> +inline void hermes::Object::set_property(JsiEnv env, JsiObj& object, const hermes::String& key, const JsiVal& value, PropertyAttributes attributes) { + if (attributes) { + auto desc = jsi::Object(env); + desc.setProperty(env, "configurable", !(attributes & DontDelete)); + desc.setProperty(env, "enumerable", !(attributes & DontEnum)); + desc.setProperty(env, "writable", !(attributes & ReadOnly)); + desc.setProperty(env, "value", value); + + auto objClass = env->global().getPropertyAsObject(env, "Object"); + objClass.getPropertyAsFunction(env, "defineProperty").callWithThis( + env, + objClass, + object, + str(env, key), + std::move(desc)); + } else { + object->setProperty(env, propName(env, key), value); + } +} + +template<> +inline void hermes::Object::set_property(JsiEnv env, JsiObj& object, uint32_t index, const JsiVal& value) { + if (object->isArray(env)) + return object->asArray(env).setValueAtIndex(env, index, value); + return hermes::Object::set_property(env, object, std::to_string(index), value); +} + +template<> +inline std::vector hermes::Object::get_property_names(JsiEnv env, const JsiObj& object) { + auto namesArray = object->getPropertyNames(env); + + size_t count = namesArray.length(env); + std::vector names; + names.reserve(count); + + for (size_t i = 0; i < count; i++) { + names.push_back(namesArray.getValueAtIndex(env, i).asString(env).utf8(env)); + } + + return names; +} + +template<> +inline JsiVal hermes::Object::get_prototype(JsiEnv env, const JsiObj& object) { + auto objClass = env->global().getPropertyAsObject(env, "Object"); + return env(objClass.getPropertyAsFunction(env, "getPrototypeOf").callWithThis(env, objClass, object)); +} + +template<> +inline void hermes::Object::set_prototype(JsiEnv env, const JsiObj& object, const JsiVal& prototype) { + auto objClass = env->global().getPropertyAsObject(env, "Object"); + objClass.getPropertyAsFunction(env, "setPrototypeOf").callWithThis(env, objClass, object, prototype); +} + +template<> +inline JsiObj hermes::Object::create_empty(JsiEnv env) { + return JsiObj(env); +} + +template<> +inline JsiObj hermes::Object::create_array(JsiEnv env, uint32_t length, const JsiVal values[]) { + jsi::Array array = jsi::Array(env, length); + for (uint32_t i = 0; i < length; i++) { + array.setValueAtIndex(env, i, values[i]); + } + return env(std::move(array)); +} + +template<> +inline JsiObj hermes::Object::create_date(JsiEnv env, double time) { + return env(env->global().getPropertyAsFunction(env, "Date").callAsConstructor(env, time).asObject(env)); +} + +template<> +template +inline JsiObj hermes::Object::create_instance(JsiEnv env, typename ClassType::Internal* internal) { + return hermes::ObjectWrap::create_instance(env, internal); +} + +template<> +template +inline JsiObj hermes::Object::create_instance_by_schema(JsiEnv env, JsiFunc& constructor, const realm::ObjectSchema& schema, typename ClassType::Internal* internal) { + return hermes::ObjectWrap::create_instance_by_schema(env, constructor, schema, internal); +} + +template<> +template +inline JsiObj hermes::Object::create_instance_by_schema(JsiEnv env, const realm::ObjectSchema& schema, typename ClassType::Internal* internal) { + return hermes::ObjectWrap::create_instance_by_schema(env, schema, internal); +} + +template +inline void on_context_destroy(JsiEnv env, std::string realmPath) { + hermes::ObjectWrap::on_context_destroy(env, realmPath); +} + +template<> +template +inline bool hermes::Object::is_instance(JsiEnv env, const JsiObj& object) { + return hermes::ObjectWrap::is_instance(env, object); +} + +template<> +template +inline typename ClassType::Internal* hermes::Object::get_internal(JsiEnv env, const JsiObj& object) { + return hermes::ObjectWrap::get_internal(env, object); +} + +template<> +template +inline void hermes::Object::set_internal(JsiEnv env, const JsiObj& object, typename ClassType::Internal* internal) { + return hermes::ObjectWrap::set_internal(env, object, internal); +} + +template<> +inline void hermes::Object::set_global(JsiEnv env, const hermes::String &key, const JsiVal &value) { + auto global = env.global(); + Object::set_property(env, global, key, value); +} + +template<> +inline JsiVal hermes::Object::get_global(JsiEnv env, const hermes::String &key) { + return Object::get_property(env, env.global(), key); +} + +template<> +inline JsiVal hermes::Exception::value(JsiEnv env, const std::string &message) { + return str(env, message); +} + +} // js +} // realm diff --git a/src/hermes/hermes_protected.hpp b/src/hermes/hermes_protected.hpp new file mode 100644 index 00000000000..fa4503f24d5 --- /dev/null +++ b/src/hermes/hermes_protected.hpp @@ -0,0 +1,63 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2016 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "hermes_types.hpp" + +namespace realm { +namespace js { + +template<> +class Protected : public JsiVal { + public: + Protected(JsiEnv, JsiVal value) : JsiVal(std::move(value)) {} + struct Comparator { + bool operator()(const Protected& a, const Protected& b) const { return a == b; } + }; +}; + +template<> +class Protected : public JsiObj { + public: + Protected(JsiEnv, JsiObj value) : JsiObj(std::move(value)) {} + struct Comparator { + bool operator()(const Protected& a, const Protected& b) const { return a == b; } + }; +}; + +template<> +class Protected : public JsiFunc { + public: + Protected(JsiEnv, JsiFunc value) : JsiFunc(std::move(value)) {} + struct Comparator { + bool operator()(const Protected& a, const Protected& b) const { return a == b; } + }; +}; + +template<> +class Protected : public JsiEnv { + public: + Protected(JsiEnv env) : JsiEnv(env) {} + struct Comparator { + bool operator()(const Protected& a, const Protected& b) const { return a == b; } + }; +}; + +} // js +} // realm diff --git a/src/hermes/hermes_return_value.hpp b/src/hermes/hermes_return_value.hpp new file mode 100644 index 00000000000..324229bb143 --- /dev/null +++ b/src/hermes/hermes_return_value.hpp @@ -0,0 +1,99 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2021 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "hermes_types.hpp" +#include "hermes_string.hpp" + +namespace realm { +namespace js { + +template<> + class ReturnValue { + JsiEnv m_env; + jsi::Value m_value; // defaults to undefined + + public: + ReturnValue(JsiEnv env) : m_env(env) {} + ReturnValue(JsiEnv env, jsi::Value&& value) : m_env(env), m_value(std::move(value)) {} + ReturnValue(JsiEnv env, const jsi::Value& value) : m_env(env), m_value(env, value) {} + + jsi::Value ToValue() && { + return std::move(m_value); + } + + void set(JsiVal value) { + m_value = std::move(value.get()); + } + + void set(const std::string &string) { + m_value = str(m_env, string).get(); + } + + void set(const char* c_str) { + if (!c_str) { + set_null(); + } + else { + m_value = str(m_env, c_str).get(); + } + } + + void set(bool boolean) { + m_value = jsi::Value(boolean); + } + + void set(double number) { + m_value = jsi::Value(number); + } + + void set(int32_t number) { + set(double(number)); + } + + void set(uint32_t number) { + set(double(number)); + } + + void set(realm::Mixed mixed) { + m_value = Value::from_mixed(m_env, nullptr, mixed).get(); + } + + void set_null() { + m_value = jsi::Value::null(); + } + + + void set_undefined() { + m_value = jsi::Value::undefined(); + } + + template + void set(util::Optional value) { + if (value) { + set(std::move(*value)); + } + else { + set_undefined(); + } + } + }; + +} // js +} // realm diff --git a/src/hermes/hermes_string.hpp b/src/hermes/hermes_string.hpp new file mode 100644 index 00000000000..30eb9be2135 --- /dev/null +++ b/src/hermes/hermes_string.hpp @@ -0,0 +1,71 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2021 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "hermes_types.hpp" + +namespace realm { +namespace js { + +template<> +class String { + using StringType = String; + + std::string m_str; + + public: + static bson::Bson to_bson(StringType stringified_ejson) { + return bson::parse(std::string(std::move(stringified_ejson))); + } + + static std::string from_bson(const bson::Bson& bson) { + return bson.to_string(); + } + + String(StringData s) : m_str(s) {} + String(std::string&& s) : m_str(std::move(s)) {} + String(const std::string& s) : m_str(s) {} + String(const char* s) : m_str(s) {} + + operator StringData() const { + return m_str; + } + + operator std::string() && { + return std::move(m_str); + } + operator std::string() const& { + return m_str; + } + + jsi::String ToString(jsi::Runtime* env) { + return jsi::String::createFromUtf8(*env, m_str); + } +}; + +inline jsi::PropNameID propName(JsiEnv env, StringData name) { + return jsi::PropNameID::forUtf8(env, reinterpret_cast(name.data()), name.size()); +} + +inline JsiString str(JsiEnv env, StringData name) { + return env(jsi::String::createFromUtf8(env, reinterpret_cast(name.data()), name.size())); +} + +} // js +} // realm diff --git a/src/hermes/hermes_types.hpp b/src/hermes/hermes_types.hpp new file mode 100644 index 00000000000..647eb31466c --- /dev/null +++ b/src/hermes/hermes_types.hpp @@ -0,0 +1,267 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2021 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include +#include + +#include + +#define HANDLESCOPE(env) ::facebook::jsi::Scope handle_scope(env); + +#include "js_types.hpp" + + +namespace realm { + +namespace jsi = facebook::jsi; + +namespace js { +class JsiVal; +class JsiObj; +class JsiString; +class JsiFunc; + +class JsiEnv { +public: + /*implicit*/JsiEnv(jsi::Runtime& rt) : m_rt(&rt) {} + /*implicit*/ operator jsi::Runtime&() const { + return *m_rt; + } + + jsi::Runtime* operator->() const { + return m_rt; + } + jsi::Runtime& get() const { + return *m_rt; + } + + JsiVal operator()(const jsi::Value&) const; + JsiVal operator()(jsi::Value&&) const; + JsiObj operator()(const jsi::Object&) const; + JsiObj operator()(jsi::Object&&) const; + JsiString operator()(const jsi::String&) const; + JsiString operator()(jsi::String&&) const; + JsiFunc operator()(const jsi::Function&) const; + JsiFunc operator()(jsi::Function&&) const; + + JsiVal null() const; + JsiVal undefined() const; + + JsiObj global() const; + + /** Warning, this can only appear directly as an argument to callFoo(), not assigned to a variable! */ + const jsi::Value* args(const JsiVal* argv, size_t argc, std::vector&& buf = {}) const; + + friend bool operator==(const JsiEnv& a, const JsiEnv& b) { + return a.m_rt == b.m_rt; + } + + template + JsiObj obj(std::pair... pairs); + +private: + jsi::Runtime* m_rt; +}; + +template +class JsiWrap { +public: + JsiWrap(JsiEnv env, T&& val) : m_env(env), m_val(std::move(val)) {} + + JsiWrap(JsiWrap&& other) = default; + JsiWrap& operator=(JsiWrap&& other) = default; + + JsiWrap(const JsiWrap& other) : JsiWrap(CRTP(other.env(), other.get())) {} + JsiWrap& operator=(const JsiWrap& other) { + *this = JsiWrap(other); + } + + T* operator->() { return &m_val; } + const T* operator->() const { return &m_val; } + + /*implicit*/ operator const T&() const& { return m_val; } + /*implicit*/ operator T&() & { return m_val; } + /*implicit*/ operator T&&() && { return std::move(m_val); } + + const T& get() const& { return m_val; } + T& get() & { return m_val; } + T&& get() && { return std::move(m_val); } + + const JsiEnv& env() const { + return m_env; + } + + friend bool operator==(const JsiWrap& a, const JsiWrap& b) { + REALM_ASSERT_RELEASE(&a.env().get() == &b.env().get()); + return T::strictEquals(a.env(), a.get(), b.get()); + } + +protected: + JsiEnv m_env; + T m_val; +}; + +class JsiString : public JsiWrap { +public: + using JsiWrap::JsiWrap; + JsiString(JsiEnv env, const jsi::String& val) : JsiWrap(env, jsi::Value(env, val).getString(env)) {} +}; + +class JsiFunc : public JsiWrap { +public: + using JsiWrap::JsiWrap; + JsiFunc(JsiEnv env, const jsi::Function& val) : JsiWrap(env, jsi::Value(env, val).getObject(env).getFunction(env)) {} +}; + +class JsiObj : public JsiWrap { +public: + using JsiWrap::JsiWrap; + JsiObj(JsiEnv env, const jsi::Object& val) : JsiWrap(env, jsi::Value(env, val).getObject(env)) {} + /*implicit*/ JsiObj(JsiFunc f) : JsiWrap(f.env(), std::move(f).get()) {} + explicit JsiObj(JsiEnv env) : JsiWrap(env, jsi::Object(env)) {} +}; + +class JsiVal : public JsiWrap { +public: + using JsiWrap::JsiWrap; + JsiVal(JsiEnv env, const jsi::Value& val) : JsiWrap(env, jsi::Value(env, val)) {} + /*implicit*/ JsiVal(JsiString val) : JsiWrap(val.env(), std::move(val).get()) {} + /*implicit*/ JsiVal(JsiFunc val) : JsiWrap(val.env(), std::move(val).get()) {} + /*implicit*/ JsiVal(JsiObj val) : JsiWrap(val.env(), std::move(val).get()) {} + + JsiObj asObject() const & { return {env(), get().asObject(env())} ;} + JsiObj asObject() && { return {env(), std::move(get()).asObject(env())} ;} +}; + +inline JsiVal JsiEnv::operator()(const jsi::Value& val) const { return {*this, val}; } +inline JsiVal JsiEnv::operator()(jsi::Value&& val) const { return {*this, std::move(val)}; } +inline JsiObj JsiEnv::operator()(const jsi::Object& val) const { return {*this, val}; } +inline JsiObj JsiEnv::operator()(jsi::Object&& val) const { return {*this, std::move(val)}; } +inline JsiString JsiEnv::operator()(const jsi::String& val) const { return {*this, val}; } +inline JsiString JsiEnv::operator()(jsi::String&& val) const { return {*this, std::move(val)}; } +inline JsiFunc JsiEnv::operator()(const jsi::Function& val) const { return {*this, val}; } +inline JsiFunc JsiEnv::operator()(jsi::Function&& val) const { return {*this, std::move(val)}; } + +inline JsiVal JsiEnv::null() const { + return {*this, jsi::Value::null()}; +} +inline JsiVal JsiEnv::undefined() const { + return {*this, jsi::Value::undefined()}; +} +inline JsiObj JsiEnv::global() const { + return {*this, m_rt->global()}; +} +inline const jsi::Value* JsiEnv::args(const JsiVal* argv, size_t argc, std::vector&& buf) const { + // Special case for 0 or 1 arguments to avoid any copies and allocations. + if (argc == 0) + return nullptr; + if (argc == 1) + return &argv[0].get(); + + buf.reserve(argc); + for (size_t i = 0; i < argc; i++) { + buf.emplace_back(*this, argv[i]); + } + + return buf.data(); +} + +template +JsiObj JsiEnv::obj(std::pair... pairs) { + auto obj = jsi::Object(*this); + (..., obj.setProperty(*this, pairs.first, std::move(pairs.second))); + return (*this)(std::move(obj)); +} + +namespace hermes { +struct Types { + using Context = JsiEnv; + using GlobalContext = JsiEnv; + using Value = JsiVal; + using Object = JsiObj; + using String = JsiString; + using Function = JsiFunc; + + using JsiFunctionCallback = jsi::Value(*)(jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count); + + using JsiIndexGetterCallback = JsiFunctionCallback; + using JsiIndexSetterCallback = JsiFunctionCallback; + using JsiPropertyGetterCallback = JsiFunctionCallback; + using JsiPropertySetterCallback = JsiFunctionCallback; + + using JsiStringPropertyGetterCallback = JsiFunctionCallback; + using JsiStringPropertySetterCallback = JsiFunctionCallback; + using JsiStringPropertyEnumeratorCallback = JsiFunctionCallback; + + using ConstructorCallback = JsiFunctionCallback; + using FunctionCallback = JsiFunctionCallback; + using PropertyGetterCallback = JsiPropertyGetterCallback; + using PropertySetterCallback = JsiPropertySetterCallback; + using IndexPropertyGetterCallback = JsiIndexGetterCallback; + using IndexPropertySetterCallback = JsiIndexSetterCallback; + + using StringPropertyGetterCallback = jsi::Value(*)(jsi::Runtime&, const jsi::Value&, const js::String&); + using StringPropertySetterCallback = jsi::Value(*)(jsi::Runtime&, const jsi::Value&, const js::String&, const jsi::Value&); + using StringPropertyEnumeratorCallback = JsiStringPropertyEnumeratorCallback; +}; + +template +class ObjectWrap; + +using String = js::String; +using Context = js::Context; +using Value = js::Value; +using Function = js::Function; +using Object = js::Object; +using Exception = js::Exception; +using ReturnValue = js::ReturnValue; + +} // hermes + + +template<> +inline hermes::Types::Context hermes::Context::get_global_context(hermes::Types::Context env) { + return env; +} + +inline jsi::Function globalType(jsi::Runtime& env, const char* name) { + return env.global().getPropertyAsFunction(env, name); +} + +} // js +} // realm + +// A bit of a hack, but important for usability. +namespace facebook { +namespace jsi { +namespace detail { +template <> +inline Value toValue(Runtime&, const realm::js::JsiVal& val) { return realm::js::JsiVal(val).get(); } +template <> +inline Value toValue(Runtime&, const realm::js::JsiObj& val) { return realm::js::JsiVal(val).get(); } +template <> +inline Value toValue(Runtime&, const realm::js::JsiFunc& val) { return realm::js::JsiVal(val).get(); } +template <> +inline Value toValue(Runtime&, const realm::js::JsiString& val) { return realm::js::JsiVal(val).get(); } +} +} +} diff --git a/src/hermes/hermes_value.hpp b/src/hermes/hermes_value.hpp new file mode 100644 index 00000000000..33399a70894 --- /dev/null +++ b/src/hermes/hermes_value.hpp @@ -0,0 +1,344 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2021 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "hermes_string.hpp" +#include "hermes_types.hpp" +//#include "node_buffer.hpp" + +namespace realm { +namespace js { + +template <> +inline const char *hermes::Value::typeof(JsiEnv env, const JsiVal &value) { + if (value->isNull()) { + return "null"; + } + if (value->isNumber()) { + return "number"; + } + if (value->isString()) { + return "string"; + } + if (value->isBool()) { + return "boolean"; + } + if (value->isUndefined()) { + return "undefined"; + } + if (value->isObject()) { + return "object"; + } + return "unknown"; +} + +template <> +inline bool hermes::Value::is_array(JsiEnv env, const JsiVal &value) { + return value->isObject() && value->getObject(env).isArray(env); +} + +template <> +inline bool hermes::Value::is_array_buffer(JsiEnv env, const JsiVal &value) { + return value->isObject() && value->getObject(env).isArrayBuffer(env); +} + +template <> +inline bool hermes::Value::is_array_buffer_view(JsiEnv env, + const JsiVal &value) { + return globalType(env, "ArrayBuffer") + .getPropertyAsFunction(env, "isView") + .call(env, value) + .getBool(); +} + +template <> +inline bool hermes::Value::is_date(JsiEnv env, const JsiVal &value) { + return value->isObject() && + value->getObject(env).instanceOf( + env, env->global().getPropertyAsFunction(env, "Date")); +} + +template <> +inline bool hermes::Value::is_boolean(JsiEnv env, const JsiVal &value) { + return value->isBool(); +} + +template <> +inline bool hermes::Value::is_constructor(JsiEnv env, const JsiVal &value) { + return value->isObject() && value->getObject(env).isFunction(env); +} + +template <> +inline bool hermes::Value::is_error(JsiEnv env, const JsiVal &value) { + return value->isObject() && + value->getObject(env).instanceOf( + env, env->global().getPropertyAsFunction(env, "Error")); +} + +template <> +inline bool hermes::Value::is_function(JsiEnv env, const JsiVal &value) { + return value->isObject() && value->getObject(env).isFunction(env); +} + +template <> +inline bool hermes::Value::is_null(JsiEnv env, const JsiVal &value) { + return value->isNull(); +} + +template <> +inline bool hermes::Value::is_number(JsiEnv env, const JsiVal &value) { + return value->isNumber(); +} + +inline bool is_bson_type(JsiEnv env, const JsiVal &value, std::string type) { + if (value->isNull() || value->isUndefined() || !value->isObject()) { + return false; + } + + auto bsonType = value->getObject(env).getProperty(env, "_bsontype"); + if (bsonType.isUndefined()) { + return false; + } + + return jsi::Value::strictEquals(env, bsonType, JsiVal(str(env, type))); +} + +template <> +inline bool hermes::Value::is_decimal128(JsiEnv env, const JsiVal &value) { + return is_bson_type(env, value, "Decimal128"); +} + +template <> +inline bool hermes::Value::is_object_id(JsiEnv env, const JsiVal &value) { + return is_bson_type(env, value, "ObjectID"); +} + +template <> +inline bool hermes::Value::is_object(JsiEnv env, const JsiVal &value) { + return value->isObject(); +} + +template <> +inline bool hermes::Value::is_string(JsiEnv env, const JsiVal &value) { + return value->isString(); +} + +template <> +inline bool hermes::Value::is_undefined(JsiEnv env, const JsiVal &value) { + return value->isUndefined(); +} + +template <> +inline bool hermes::Value::is_binary(JsiEnv env, const JsiVal &value) { + return Value::is_array_buffer(env, value) || + Value::is_array_buffer_view(env, value); +} + +template <> +inline bool hermes::Value::is_valid(const JsiVal &value) { + return true; // XXX +} + +template<> +inline bool hermes::Value::is_uuid(JsiEnv env, const JsiVal &value) { + return is_bson_type(env, value, "UUID"); +} + +template <> +inline JsiVal hermes::Value::from_boolean(JsiEnv env, bool boolean) { + return JsiVal(env, boolean); +} + +template <> inline JsiVal hermes::Value::from_null(JsiEnv env) { + return env.null(); +} + +template <> +inline JsiVal hermes::Value::from_number(JsiEnv env, double number) { + return JsiVal(env, number); +} + +template <> +inline JsiVal hermes::Value::from_nonnull_string(JsiEnv env, + const hermes::String &string) { + return str(env, StringData(string)); +} + +template <> +inline JsiVal hermes::Value::from_nonnull_binary(JsiEnv env, BinaryData data) { + jsi::ArrayBuffer buffer = globalType(env, "ArrayBuffer") + .callAsConstructor(env, double(data.size())) + .getObject(env) + .getArrayBuffer(env); + + if (data.size()) { + memcpy(buffer.data(env), data.data(), data.size()); + } + + return env(std::move(buffer)); +} + +template <> inline JsiVal hermes::Value::from_undefined(JsiEnv env) { + return env.undefined(); +} + +template <> +inline JsiVal hermes::Value::from_uuid(JsiEnv env, const UUID& uuid) { + return env(globalType(env, "Realm") + .getPropertyAsFunction(env, "_UUID") + .callAsConstructor(env, str(env, uuid.to_string()))); +} + +template <> +inline bool hermes::Value::to_boolean(JsiEnv env, const JsiVal &value) { + return value->getBool(); // XXX should do conversion. +} + +template <> +inline hermes::String hermes::Value::to_string(JsiEnv env, + const JsiVal &value) { + return value->toString(env).utf8(env); +} + +template <> +inline double hermes::Value::to_number(JsiEnv env, const JsiVal &value) { + double number = std::nan(""); + if (value->isNumber()) { + number = value->asNumber(); + } else if (value->isString()) { + std::string string = value->toString(env).utf8(env); + try { + number = std::stod(string); + } catch (std::invalid_argument) { + // The number will remain nan and we defer to the check below to throw an exception. + } + } else if (is_date(env, value)) { + jsi::Object date = value->getObject(env); + number = date.getPropertyAsFunction(env, "getTime") + .callWithThis(env, date) + .getNumber(); + } + if (std::isnan(number)) { + throw std::invalid_argument( + util::format("Value '%1' not convertible to a number.", + (std::string)to_string(env, value))); + } + + return number; +} + +template <> +inline OwnedBinaryData hermes::Value::to_binary(JsiEnv env, + const JsiVal &value) { + auto obj = value->asObject(env); + if (obj.isArrayBuffer(env)) { + auto buf = std::move(obj).getArrayBuffer(env); + return OwnedBinaryData(reinterpret_cast(buf.data(env)), + buf.length(env)); + } + + if (is_array_buffer_view(env, value)) { + auto buffer = obj.getPropertyAsObject(env, "buffer").getArrayBuffer(env); + size_t byteOffset = static_cast(obj.getProperty(env, "byteOffset").asNumber()); + size_t byteLength = static_cast(obj.getProperty(env, "byteLength").asNumber()); + return OwnedBinaryData(reinterpret_cast(buffer.data(env) + byteOffset), byteLength); + } + + throw std::runtime_error("Can only convert ArrayBuffer and ArrayBufferView objects to binary"); +} + +template <> +inline JsiObj hermes::Value::to_object(JsiEnv env, const JsiVal &value) { + return env(value->asObject(env)); // XXX convert? +} + +template <> +inline JsiObj hermes::Value::to_array(JsiEnv env, const JsiVal &value) { + return to_object(env, value); +} + +template <> +inline JsiFunc hermes::Value::to_function(JsiEnv env, const JsiVal &value) { + return env(value->asObject(env).asFunction(env)); +} + +template <> +inline JsiFunc hermes::Value::to_constructor(JsiEnv env, const JsiVal &value) { + return to_function(env, value); +} + +template <> +inline JsiObj hermes::Value::to_date(JsiEnv env, const JsiVal &value) { + if (value->isString()) { + return env( + globalType(env, "Date").callAsConstructor(env, value).asObject(env)); + } + + return to_object(env, value); +} + +template <> +inline JsiVal hermes::Value::from_decimal128(JsiEnv env, + const Decimal128 &number) { + if (number.is_null()) { + return env(jsi::Value::null()); + } + + return env(globalType(env, "Realm") + .getPropertyAsObject(env, "_Decimal128") + .getPropertyAsFunction(env, "fromString") + .call(env, str(env, number.to_string()))); +} + +template <> +inline Decimal128 hermes::Value::to_decimal128(JsiEnv env, + const JsiVal &value) { + return Decimal128(value->toString(env).utf8(env)); +} + +template <> +inline JsiVal hermes::Value::from_object_id(JsiEnv env, + const ObjectId &objectId) { + return env(globalType(env, "Realm") + .getPropertyAsFunction(env, "_ObjectId") + .callAsConstructor(env, str(env, objectId.to_string()))); +} + +template <> +inline ObjectId hermes::Value::to_object_id(JsiEnv env, const JsiVal &value) { + auto objectId = value->asObject(env); + return ObjectId(objectId.getPropertyAsFunction(env, "toHexString") + .callWithThis(env, objectId) + .getString(env) + .utf8(env) + .c_str()); +} + +template <> +inline UUID hermes::Value::to_uuid(JsiEnv env, const JsiVal &value) { + auto uuid = value->asObject(env); + return UUID(uuid.getPropertyAsFunction(env, "toHexString") + .callWithThis(env, uuid) + .getString(env) + .utf8(env) + .c_str()); +} + +} // namespace js +} // namespace realm diff --git a/vendor/realm-core b/vendor/realm-core index b170db6a477..c3c11a84164 160000 --- a/vendor/realm-core +++ b/vendor/realm-core @@ -1 +1 @@ -Subproject commit b170db6a47789ff5f2fbc3eeed0220b4b0a3f6b7 +Subproject commit c3c11a841642ac93c27bd1edd61f989fc0bfb809