diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..311827173 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,14 @@ +{ + "name": "TypeScriptToLua", + "image": "mcr.microsoft.com/vscode/devcontainers/javascript-node:14", + "settings": { + "terminal.integrated.shell.linux": "/bin/bash" + }, + "extensions": [ + "ark120202.vscode-typescript-to-lua", + "dbaeumer.vscode-eslint", + "editorconfig.editorconfig", + "esbenp.prettier-vscode" + ], + "postCreateCommand": "npm ci" +} diff --git a/.eslintignore b/.eslintignore index 707cb8140..492195f96 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,4 +3,5 @@ /test/cli/errors /test/cli/watch /test/transpile/directories +/test/transpile/module-resolution/*/node_modules /test/transpile/outFile diff --git a/.eslintrc.js b/.eslintrc.js index fb8ec7488..52df969ff 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,70 +1,3 @@ -// https://github.com/ark120202/eslint-config/blob/2c24f13fd99af7ccf29e56d5d936b3ab0f237db6/bases/typescript.js -const typescriptBase = { - "@typescript-eslint/adjacent-overload-signatures": "error", - "@typescript-eslint/array-type": "error", - "@typescript-eslint/await-thenable": "error", - "@typescript-eslint/ban-types": [ - "error", - { - types: { - Function: null, - CallableFunction: { fixWith: "(...args: any[]) => any" }, - NewableFunction: { fixWith: "new (...args: any[]) => any" }, - }, - }, - ], - camelcase: "off", - "@typescript-eslint/camelcase": ["error", { properties: "never", ignoreDestructuring: true }], - "@typescript-eslint/class-name-casing": "error", - "@typescript-eslint/consistent-type-assertions": [ - "error", - { assertionStyle: "as", objectLiteralTypeAssertions: "never" }, - ], - "@typescript-eslint/consistent-type-definitions": "error", - "@typescript-eslint/explicit-member-accessibility": ["error", { overrides: { constructors: "no-public" } }], - "@typescript-eslint/generic-type-naming": ["error", "^(T([A-Z][A-Za-z]*)?|U|P|K|V)$"], - "@typescript-eslint/interface-name-prefix": "error", - "no-array-constructor": "off", - "@typescript-eslint/no-array-constructor": "error", - "@typescript-eslint/no-empty-interface": "error", - "@typescript-eslint/no-extra-non-null-assertion": "error", - "@typescript-eslint/no-extraneous-class": "error", - "@typescript-eslint/no-floating-promises": "error", - "@typescript-eslint/no-for-in-array": "error", - "@typescript-eslint/no-inferrable-types": "error", - "@typescript-eslint/no-misused-new": "error", - "@typescript-eslint/no-misused-promises": "error", - "@typescript-eslint/no-namespace": "error", - "@typescript-eslint/no-require-imports": "error", - "@typescript-eslint/no-this-alias": "error", - "no-throw-literal": "off", - "@typescript-eslint/no-throw-literal": "error", - "no-constant-condition": "off", - "@typescript-eslint/no-unnecessary-condition": ["error", { ignoreRhs: true, allowConstantLoopConditions: true }], - "@typescript-eslint/no-unnecessary-qualifier": "error", - "@typescript-eslint/no-unnecessary-type-arguments": "error", - "@typescript-eslint/no-unnecessary-type-assertion": "error", - "no-unused-expressions": "off", - "@typescript-eslint/no-unused-expressions": "error", - "no-useless-constructor": "off", - "@typescript-eslint/no-useless-constructor": "error", - "@typescript-eslint/prefer-function-type": "error", - "@typescript-eslint/prefer-includes": "error", - "@typescript-eslint/prefer-optional-chain": "error", - "@typescript-eslint/prefer-namespace-keyword": "error", - "@typescript-eslint/prefer-readonly": "error", - "@typescript-eslint/prefer-string-starts-ends-with": "error", - "@typescript-eslint/promise-function-async": ["error", { checkArrowFunctions: false }], - quotes: "off", - "@typescript-eslint/quotes": ["error", "single", { avoidEscape: true, allowTemplateLiterals: false }], - "@typescript-eslint/require-array-sort-compare": "error", - "@typescript-eslint/require-await": "error", - "@typescript-eslint/restrict-plus-operands": ["error", { checkCompoundAssignments: true }], - "@typescript-eslint/return-await": "error", - "@typescript-eslint/triple-slash-reference": "error", - "@typescript-eslint/unified-signatures": "error", -}; - module.exports = { extends: ["plugin:jest/recommended", "plugin:jest/style"], parserOptions: { @@ -130,6 +63,8 @@ module.exports = { "no-useless-return": ["error"], "import/no-default-export": "error", + // TODO currently only works for direct imports (useless for now) https://github.com/benmosher/eslint-plugin-import/issues/1729 + // "import/no-deprecated": "error", "jest/expect-expect": "off", "jest/consistent-test-it": ["error", { fn: "test", withinDescribe: "test" }], @@ -147,38 +82,124 @@ module.exports = { files: "**/*.ts", extends: ["plugin:@typescript-eslint/base"], rules: { - ...typescriptBase, + // https://github.com/ark120202/eslint-config/blob/2c24f13fd99af7ccf29e56d5d936b3ab0f237db6/bases/typescript.js + "@typescript-eslint/adjacent-overload-signatures": "error", + "@typescript-eslint/array-type": "error", + "@typescript-eslint/await-thenable": "error", + "@typescript-eslint/ban-types": [ + "error", + { + types: { + Function: null, + CallableFunction: { fixWith: "(...args: any[]) => any" }, + NewableFunction: { fixWith: "new (...args: any[]) => any" }, + }, + }, + ], + camelcase: "off", + "@typescript-eslint/camelcase": ["error", { properties: "never", ignoreDestructuring: true }], + "@typescript-eslint/consistent-type-assertions": [ + "error", + { assertionStyle: "as", objectLiteralTypeAssertions: "never" }, + ], + "@typescript-eslint/consistent-type-definitions": "error", + "@typescript-eslint/explicit-member-accessibility": [ + "error", + { overrides: { constructors: "no-public" } }, + ], + "no-array-constructor": "off", + "@typescript-eslint/no-array-constructor": "error", + "@typescript-eslint/no-empty-interface": "error", + "@typescript-eslint/no-extra-non-null-assertion": "error", + "@typescript-eslint/no-extraneous-class": "error", + "@typescript-eslint/no-floating-promises": "error", + "@typescript-eslint/no-for-in-array": "error", + "@typescript-eslint/no-inferrable-types": "error", + "@typescript-eslint/no-misused-new": "error", + "@typescript-eslint/no-misused-promises": "error", + "@typescript-eslint/no-namespace": "error", + "@typescript-eslint/no-require-imports": "error", + "@typescript-eslint/no-this-alias": "error", + "no-throw-literal": "off", + "@typescript-eslint/no-throw-literal": "error", + "no-constant-condition": "off", + "@typescript-eslint/no-unnecessary-condition": [ + "error", + { ignoreRhs: true, allowConstantLoopConditions: true }, + ], + "@typescript-eslint/no-unnecessary-qualifier": "error", + "@typescript-eslint/no-unnecessary-type-arguments": "error", + "@typescript-eslint/no-unnecessary-type-assertion": "error", + "no-unused-expressions": "off", + "@typescript-eslint/no-unused-expressions": "error", + "no-useless-constructor": "off", + "@typescript-eslint/no-useless-constructor": "error", + "@typescript-eslint/prefer-function-type": "error", + "@typescript-eslint/prefer-includes": "error", + "@typescript-eslint/prefer-optional-chain": "error", + "@typescript-eslint/prefer-namespace-keyword": "error", + "@typescript-eslint/prefer-readonly": "error", + "@typescript-eslint/prefer-string-starts-ends-with": "error", + "@typescript-eslint/promise-function-async": ["error", { checkArrowFunctions: false }], + quotes: "off", + "@typescript-eslint/quotes": ["error", "single", { avoidEscape: true, allowTemplateLiterals: false }], + "@typescript-eslint/require-array-sort-compare": "error", + "@typescript-eslint/require-await": "error", + "@typescript-eslint/restrict-plus-operands": ["error", { checkCompoundAssignments: true }], + "@typescript-eslint/return-await": "error", + "@typescript-eslint/triple-slash-reference": "error", + "@typescript-eslint/unified-signatures": "error", + // end of https://github.com/ark120202/eslint-config/blob/2c24f13fd99af7ccf29e56d5d936b3ab0f237db6/bases/typescript.js "@typescript-eslint/array-type": ["error", { default: "array-simple" }], "@typescript-eslint/ban-types": ["error", { types: { null: null } }], "@typescript-eslint/no-namespace": ["error", { allowDeclarations: true }], "@typescript-eslint/no-require-imports": "off", "@typescript-eslint/no-unnecessary-condition": "off", "@typescript-eslint/prefer-for-of": "error", - // TODO: https://github.com/typescript-eslint/typescript-eslint/issues/1265 - // "@typescript-eslint/prefer-nullish-coalescing": "error", + "@typescript-eslint/prefer-nullish-coalescing": "error", "@typescript-eslint/prefer-readonly": "off", "@typescript-eslint/quotes": ["error", "double", { avoidEscape: true, allowTemplateLiterals: false }], "@typescript-eslint/require-array-sort-compare": "off", "@typescript-eslint/camelcase": "off", - // TODO: https://github.com/typescript-eslint/typescript-eslint/issues/1712 - // "@typescript-eslint/naming-convention": [ - // "error", - // { - // selector: "default", - // format: ["camelCase"], - // leadingUnderscore: "allow", - // }, - // { - // selector: "variable", - // format: ["camelCase", "UPPER_CASE"], - // leadingUnderscore: "allow", - // }, - // { - // selector: "typeLike", - // format: ["PascalCase"], - // }, - // ], + "@typescript-eslint/naming-convention": [ + "error", + { + selector: "default", + format: ["camelCase"], + leadingUnderscore: "allow", + }, + { + selector: "variable", + format: ["camelCase", "UPPER_CASE"], + leadingUnderscore: "allow", + }, + { + selector: "typeLike", + format: ["PascalCase"], + }, + { + selector: "enumMember", + format: ["PascalCase"], + }, + { + selector: "typeParameter", + format: ["PascalCase"], + prefix: ["T"], + filter: { + regex: "K|V", + match: false, + }, + }, + { + selector: "interface", + format: ["PascalCase"], + custom: { + regex: "^I[A-Z]", + match: false, + }, + }, + ], }, }, { @@ -187,6 +208,13 @@ module.exports = { "no-restricted-syntax": ["error", "LabeledStatement", "SequenceExpression"], "@typescript-eslint/no-throw-literal": "off", "@typescript-eslint/prefer-optional-chain": "off", + "@typescript-eslint/naming-convention": "off", + }, + }, + { + files: "language-extensions/index.d.ts", + rules: { + "@typescript-eslint/naming-convention": "off", }, }, { diff --git a/.gitattributes b/.gitattributes index fcadb2cf9..6313b56c5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -* text eol=lf +* text=auto eol=lf diff --git a/.github/scripts/create_benchmark_check.js b/.github/scripts/create_benchmark_check.js new file mode 100644 index 000000000..e1d303e06 --- /dev/null +++ b/.github/scripts/create_benchmark_check.js @@ -0,0 +1,22 @@ +module.exports = ({ github, context, core }) => { + const fs = require("fs"); + + const benchmarkResultPathLua = core.getInput("benchmark-result-path-lua", { required: true }); + const benchmarkInfoLua = JSON.parse(fs.readFileSync(benchmarkResultPathLua)); + + const benchmarkResultPathJIT = core.getInput("benchmark-result-path-jit", { required: true }); + const benchmarkInfoJIT = JSON.parse(fs.readFileSync(benchmarkResultPathJIT)); + + // Remove Comparison info to save some bytes + const benchmarkInfoForVizLua = { old: benchmarkInfoLua.old, new: benchmarkInfoLua.new }; + const buffer = Buffer.from(JSON.stringify(benchmarkInfoForVizLua)); + + const zlib = require("zlib"); + const compressed = zlib.deflateSync(buffer); + + const summary = + `[Open visualizer](https://typescripttolua.github.io/benchviz?d=${compressed.toString("base64")})\n` + + `### Lua5.3\n${benchmarkInfoLua.comparison.summary}\n### LuaJIT\n${benchmarkInfoJIT.comparison.summary}`; + + return summary; +}; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3cff50e60..b0e0bf6cd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,100 +39,80 @@ jobs: - if: matrix.os == 'ubuntu-latest' uses: codecov/codecov-action@v1 - benchmark: - name: Benchmark - runs-on: ubuntu-latest - steps: - - name: Lua Install - run: sudo apt-get install lua5.3 luajit - # Checkout master & commit - - name: Checkout master - uses: actions/checkout@v2 - with: - ref: master - path: master - - name: Checkout commit - uses: actions/checkout@v2 - with: - path: commit - - name: Use Node.js 12.13.1 - uses: actions/setup-node@v1 - with: - node-version: 12.13.1 - # NPM - - name: NPM master - # TODO Lua types is only added manually to test the benchmark PR this can be removed again once the PR is merged - run: npm ci && npm run build && npm install -D lua-types - working-directory: master - - name: NPM commit - run: npm ci && npm run build - working-directory: commit - # Benchmark directory setup - - name: Ensure benchmark data dir exists - run: mkdir -p ./benchmark/data - working-directory: commit - - name: Copy commit benchmark to master - run: rm -rf ./master/benchmark && cp -rf ./commit/benchmark ./master/benchmark - # Run master benchmark first and output to commit benchmark data - - name: Build benchmark Lua 5.3 master - run: node ../dist/tstl.js -p tsconfig.53.json - working-directory: master/benchmark - - name: Run benchmark Lua 5.3 master - id: benchmark-lua-master - run: lua5.3 -- run.lua ../../../commit/benchmark/data/benchmark_master_53.json - working-directory: master/benchmark/dist - - name: Build benchmark LuaJIT master - run: node ../dist/tstl.js -p tsconfig.jit.json - working-directory: master/benchmark - - name: Run benchmark LuaJIT master - id: benchmark-jit-master - run: luajit -- run.lua ../../../commit/benchmark/data/benchmark_master_jit.json - working-directory: master/benchmark/dist - # Run commit benchmark and compare with master - - name: Build benchmark Lua 5.3 commit - run: node ../dist/tstl.js -p tsconfig.53.json - working-directory: commit/benchmark - - name: Run benchmark Lua 5.3 commit - id: benchmark-lua-commit - run: echo ::set-output name=info::`lua5.3 -- run.lua ../data/benchmark_commit_53.json ../data/benchmark_master_53.json` - working-directory: commit/benchmark/dist - - name: Build benchmark LuaJIT commit - run: node ../dist/tstl.js -p tsconfig.jit.json - working-directory: commit/benchmark - - name: Run benchmark LuaJIT commit - id: benchmark-jit-commit - run: echo ::set-output name=info::`luajit -- run.lua ../data/benchmark_commit_jit.json ../data/benchmark_master_jit.json` - working-directory: commit/benchmark/dist - - name: Create benchmark check - uses: actions/github-script@0.9.0 - with: - benchmark-info-lua: ${{steps.benchmark-lua-commit.outputs.info}} - benchmark-info-jit: ${{steps.benchmark-jit-commit.outputs.info}} - script: | - const benchmarkInfoLua = JSON.parse(core.getInput('benchmark-info-lua', { required: true })); - const benchmarkInfoJIT = JSON.parse(core.getInput('benchmark-info-jit', { required: true })); - - const summary = `### Lua5.3\n${benchmarkInfoLua.summary}\n### LuaJIT\n${benchmarkInfoJIT.summary}`; - - const text = `### Lua5.3\n${benchmarkInfoLua.text}\n### LuaJIT\n${benchmarkInfoJIT.text}`; - - const pull_request = context.payload.pull_request; - if (!pull_request || pull_request.head.repo.url === pull_request.base.repo.url) { - // This only works if not in a fork. - github.checks.create({ - owner: context.repo.owner, - repo: context.repo.repo, - name: "Benchmark results", - head_sha: context.sha, - status: "completed", - conclusion: "neutral", - output: { - title: "Benchmark results", - summary: summary, - text: text - } - }); - } else { - console.log(summary); - console.log(text); - } + # benchmark: + # name: Benchmark + # runs-on: ubuntu-latest + # steps: + # - name: Lua Install + # run: sudo apt-get install lua5.3 luajit + # - name: Glow Install + # run: brew install glow + # # Checkout master & commit + # - name: Checkout master + # uses: actions/checkout@v2 + # with: + # ref: master + # path: master + # - name: Checkout commit + # uses: actions/checkout@v2 + # with: + # path: commit + # - name: Use Node.js 12.13.1 + # uses: actions/setup-node@v1 + # with: + # node-version: 12.13.1 + # # NPM + # - name: NPM master + # run: npm ci && npm run build + # working-directory: master + # - name: NPM commit + # run: npm ci && npm run build + # working-directory: commit + # # Benchmark directory setup + # - name: Ensure benchmark data dir exists + # run: mkdir -p ./benchmark/data + # working-directory: commit + # - name: Copy commit benchmark to master + # run: rm -rf ./master/benchmark && cp -rf ./commit/benchmark ./master/benchmark + # # Run master benchmark first and output to commit benchmark data + # - name: Build benchmark Lua 5.3 master + # run: node ../../commit/dist/tstl.js -p tsconfig.53.json + # working-directory: master/benchmark + # - name: Run benchmark Lua 5.3 master + # id: benchmark-lua-master + # run: lua5.3 -- run.lua ../../../commit/benchmark/data/benchmark_master_53.json + # working-directory: master/benchmark/dist + # - name: Build benchmark LuaJIT master + # run: node ../../commit/dist/tstl.js -p tsconfig.jit.json + # working-directory: master/benchmark + # - name: Run benchmark LuaJIT master + # id: benchmark-jit-master + # run: luajit -- run.lua ../../../commit/benchmark/data/benchmark_master_jit.json + # working-directory: master/benchmark/dist + # # Run commit benchmark and compare with master + # - name: Build benchmark Lua 5.3 commit + # run: node ../../commit/dist/tstl.js -p tsconfig.53.json + # working-directory: commit/benchmark + # - name: Run benchmark Lua 5.3 commit + # id: benchmark-lua-commit + # run: lua5.3 -- run.lua ../data/benchmark_master_vs_commit_53.json ../data/benchmark_master_53.json + # working-directory: commit/benchmark/dist + # - name: Build benchmark LuaJIT commit + # run: node ../../commit/dist/tstl.js -p tsconfig.jit.json + # working-directory: commit/benchmark + # - name: Run benchmark LuaJIT commit + # id: benchmark-jit-commit + # run: luajit -- run.lua ../data/benchmark_master_vs_commit_jit.json ../data/benchmark_master_jit.json + # working-directory: commit/benchmark/dist + # - name: Combine benchmark results + # id: script-combine-results + # uses: actions/github-script@v3 + # with: + # benchmark-result-path-lua: commit/benchmark/data/benchmark_master_vs_commit_53.json + # benchmark-result-path-jit: commit/benchmark/data/benchmark_master_vs_commit_jit.json + # result-encoding: string + # script: | + # const createBenchmarkCheck = require(`${process.env.GITHUB_WORKSPACE}/commit/.github/scripts/create_benchmark_check.js`); + # return createBenchmarkCheck({ github, context, core }); + # - name: Benchmark results + # run: echo "${{steps.script-combine-results.outputs.result}}" | glow -s dark -w 120 - diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..a50a68074 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug current jest test", + "type": "node", + "request": "launch", + "env": { "CI": "true" }, + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/jest", + "args": ["--runInBand", "--no-cache", "--runTestsByPath", "${relativeFile}"], + "cwd": "${workspaceRoot}", + "protocol": "inspector", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" + } + ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 044cba2e3..4ec913ca1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,116 @@ # Changelog -## Unreleased +## 1.0.0 + +- **[Breaking]** `/* @tupleReturn */` has been removed and will no longer have any effect. You will get an error if you try ot use it or if you use declarations that use it. +- Added support for the `Promise` class. +- Added support for `async` and `await` using coroutines. +- Module resolution now also correctly resolves `/init.lua` files for `require("")`. +- Fixed an error not being thrown when trying to call a method in an optional chain that does not exist. (If the method itself is not optional) +- Fixed a bug where parentheses could break the context parameter being resolved for a method. +- Fixed a bug where context parameters in object literal methods were not inferred correctly. +- Fixed a bug with sourceMapTraceback. +- Fixed TS emitting empty JSON files if you use JSON source files. + +## 0.42.0 + +- **[Breaking]** The `/** @tupleReturn */` is now deprecated, and will be removed next release. If you are still using it, please upgrade to the [LuaMultiReturn language extension](https://typescripttolua.github.io/docs/advanced/language-extensions#luamultireturn-type). +- Added support for JSX, see [documentation](https://typescripttolua.github.io/docs/jsx) for more information. +- Added support for the `baseUrl` configuration key for module resolution. + +A large list of bugfixes: + +- Fixed an exception causing tstl to exit when trying to assign to an optional chain. +- Fixed resolved files appearing duplicated in lua bundles. +- Fixed a problem resolving external Lua files in nested directories. +- Fixed `@noResolution` in library packages losing their NoResolution tag, causing attempts to resolve them for package users. +- Fixed a bug in the bundling code causing modules not to be cached if they return nil (which happens if they are not a module) +- Fixed module resolution trying to incorrectly resolve and rewrite things like `myObject.require()` or `my_custom_require()`. +- Fixed lualib bundle not being included in the output if external packages use it, but the client code does not. + +## 0.41.0 + +- Added support for [optional chaining](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html) `a?.b`, `a?.[b]` and `a?.()`. +- Added an error when trying to bundle a library (`"buildmode": "library"`) project. +- Added `--tstlVerbose` CLI flag to help with diagnosing problems. +- Fixed a bug where vararg (`...`) was not correctly optimized. +- Fixed .tsx files not correctly being resolved. +- Fixed a bug where files were emitted to the wrong location if no `outDir` was specified. + +## 0.40.0 + +- Added support for using external Lua code in your project. This means you can create and install node_modules packages containing Lua code. It also lets you include Lua source files as part of your source files. Used Lua will automatically be added to your output. For more information, see the [External Lua Code](https://typescripttolua.github.io/docs/external-lua-code) page in the docs. +- **[Breaking]** Removed support for deprecated annotations that have been replaced with language extensions: `/** @luaIterator */`, `/** @vararg */`, `/** @luatable */` and `/** forRange */`. If you were still using these, see [the docs](https://typescripttolua.github.io/docs/advanced/compiler-annotations) for instructions how to upgrade. +- Added support for `array.entries()`. +- Added support for `LuaTable.has(key)` and `LuaTable.delete(key)` to the language extensions. See [docs](https://typescripttolua.github.io/docs/advanced/language-extensions#lua-table-types) for more info. +- Made language extension types more strict, disallowing `null` and `undefined` in some places where they would cause problems in Lua. + +- Fixed an issue where using TypeScript transformer plugins would cause invalid namespace and module code, as well as breaking hoisting. +- Fixed invalid switch statement output when the `default` clause was not the last clause in the switch. +- Fixed missing LuaLib dependency when using `string.split`. +- Fixed **lots** of bundling bugs and issues, also added the TypeScriptToLua header to the top of the bundle unless _noHeader_ is specified. -- `Function.length` is supported now +Under the hood: + +- Various improvements to testing infrastructure for testing (virtual) projects with multiple files. + +## 0.39.0 + +- **[Breaking]** Removed support for `@phantom`, `@metaExtension`, `@extension`, `@pureAbstract` compiler annotations. As of this version **these will no longer function!** For help upgrading your code see [the deprecated annotation docs](https://typescripttolua.github.io/docs/advanced/compiler-annotations#deprecated). +- Added official support for **Lua 5.4**. +- Added the `LuaTable` language extension. This allows the use of barebones Lua tables for key-value storage, without suffering from JS's forced string indexes. For more information see [the LuaTable docs](https://typescripttolua.github.io/docs/advanced/language-extensions#lua-table-types). +- Deprecated `@vararg`. Instead, tstl will figure out itself when use of the Lua ellipsis token (`...`) is appropriate. Also language extension `$vararg` was added to force use of the ellipsis token. See [the docs](https://typescripttolua.github.io/docs/advanced/language-extensions#vararg-constant) for more information. +- Added `trailingComments` and `leadingComments` fields to statements in the Lua AST. These can be modified by plugins to emit comments in the output lua. For an example see [the add-comments test plugin](https://github.com/TypeScriptToLua/TypeScriptToLua/blob/master/test/transpile/plugins/add-comments.ts). + +Under the hood: +- Tests are now run on a WebAssembly-compiled version of official Lua releases. This means we can now execute test Lua on all Lua versions (except LuaJIT). Shoutout to [Fengari](https://github.com/fengari-lua/fengari) for serving us well for a long time. + +## 0.38.0 + +- **[Breaking]** Renamed `MultiReturn` to `LuaMultiReturn` to be consistent with other language extensions all starting with Lua-. +- Fixed various bugs and issues related to `LuaMultiReturn`, including its value not correctly being wrapped in some cases. +- Added support for indexing `LuaMultiReturn` values without destructing. +- Added language extensions to allow translation directly to (overwritten) Lua operators like `+`,`-`,`..`. For more information see [Operator Map Types](https://typescripttolua.github.io/docs/advanced/language-extensions#operator-map-types). +- Added language extension `$range()`. This function can be used to create numeric lua loops, for example `for (const i of $range(1, 10)) {` translates to `for i=1,10 do`. For more information see [\$range Iterator Function](https://typescripttolua.github.io/docs/advanced/language-extensions#range-iterator-function). +- Added support for `Array.isArray`, formalizing tstl's isArray convention (**note:** Due to `[]` and `{}` being the same in Lua, `{}` - without any keys - is considered an array too.) +- Added support for `string.prototype.includes`. +- Added support for enum merging. +- Fixed missing lualib dependency in `string.prototype.split`. +- Added a not-supported diagnostic for not-yet-implemented optional chaining (`a?.b`). +- Moved remaining legacy tests to modern testing utils, removing the legacy testing code. + +## 0.37.0 + +- **[Important]** Deprecated the @phantom, @extension, @metaExtension and @pureAbstract annotations. This is done because there are good alternatives in regular TypeScript, and this helps us simplify the transpiler. For now, using these annotations will result in a warning but they will still continue to function. A few months from now these annotations will no longer be supported, so upgrade if possible. See [Compiler Annotations](https://typescripttolua.github.io/docs/advanced/compiler-annotations) for more info. +- Added the `MultiReturn<>` type and `$multi()` helper function as the first language extensions. This is to provide a type-safe alternative to the `@tupleReturn` annotation. For more information see [the new Language Extensions page](https://typescripttolua.github.io/docs/advanced/language-extensions) on the docs website. +- Removed some class transformation code from the transpiler that was no longer used. +- Fixed a bug causing object spread to malfunction in some cases ([#898](https://github.com/TypeScriptToLua/TypeScriptToLua/issues/898)). +- Omitted `tostring` for parameters of template literals (`` `${}` ``) that are already known strings. +- Fixed a bug causing incorrect Lua syntax to be generated in some cases ([#944](https://github.com/TypeScriptToLua/TypeScriptToLua/issues/944)). + +## 0.36.0 + +- Upgraded to TypeScript 4.0. +- Added support for `parseInt` and `parseFloat`. +- Added support for `yield*` [for generator functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield*). +- Added support for [method, property and accessor decorators](https://www.typescriptlang.org/docs/handbook/decorators.html). +- Shebangs at the top of a .ts file will now be preserved. +- Fixed an issue causing declarations referencing their own identifier to cause a nil reference error. + +## 0.35.0 + +- In preparation for some new features, some public APIs have been changed: + - High-level APIs that read input files from the file system (`transpileFiles` and `transpileProject`) now write transpiled files by default. This behavior can be changed by providing a `writeFile` callback, similarly to TypeScript's `program.emit`. + - `transpile` and `emitTranspiledFiles` functions have been replaced with the `Transpiler` class. See [documentation](https://typescripttolua.github.io/docs/api/overview#low-level-api) for usage examples. +- Fixed `declarationDir` option not being respected. +- `Function.length` is supported now. +- String iteration is now supported. +- Exposed `parseConfigFileWithSystem` to parse _tsconfig.json_ files as part of the tstl API. - Fixed `string.replace` incorrectly escaping some `replaceValue` characters (`().+-*?[^$`) +- Fixed several other string operations behaving differently from JS (mostly regarding indices out of bounds and NaN arguments). +- Fixed a bug where the length argument of `String.prototype.substr` was evaluated twice. +- Fixed some missing dependencies in LuaLib classes (Map, Set, WeakMap, WeakSet) ## 0.34.0 diff --git a/benchmark/dist/json.lua b/benchmark/src/json.lua similarity index 100% rename from benchmark/dist/json.lua rename to benchmark/src/json.lua diff --git a/benchmark/src/memory_benchmark.ts b/benchmark/src/memory_benchmark.ts index 10934757a..51f8031be 100644 --- a/benchmark/src/memory_benchmark.ts +++ b/benchmark/src/memory_benchmark.ts @@ -1,7 +1,7 @@ import { BenchmarkKind, MemoryBenchmarkResult, ComparisonInfo, MemoryBenchmarkCategory } from "./benchmark_types"; import { toFixed, json, calculatePercentageChange } from "./util"; -export function runMemoryBenchmark(benchmarkFunction: Function): MemoryBenchmarkResult { +export function runMemoryBenchmark(benchmarkFunction: () => void): MemoryBenchmarkResult { const result: MemoryBenchmarkResult = { kind: BenchmarkKind.Memory, benchmarkName: "NO_NAME", diff --git a/benchmark/src/memory_benchmarks/graph_cylce.ts b/benchmark/src/memory_benchmarks/graph_cylce.ts index c78812dc5..c75372d07 100644 --- a/benchmark/src/memory_benchmarks/graph_cylce.ts +++ b/benchmark/src/memory_benchmarks/graph_cylce.ts @@ -1,4 +1,4 @@ -type Graph = Map; +type Graph = Map; function range(start: number, end: number): number[] { if (start > end) return []; diff --git a/benchmark/src/run.ts b/benchmark/src/run.ts index c632efe39..b880537e5 100644 --- a/benchmark/src/run.ts +++ b/benchmark/src/run.ts @@ -27,11 +27,8 @@ function benchmark(): void { oldBenchmarkResults = json.decode(oldBenchmarkData) as BenchmarkResult[]; } - // Compare results - const comparisonInfo = compareBenchmarks(oldBenchmarkResults, newBenchmarkResults); - // Output comparison info - outputBenchmarkData(comparisonInfo, newBenchmarkResults); + outputBenchmarkData(oldBenchmarkResults, newBenchmarkResults); } benchmark(); @@ -44,18 +41,24 @@ function compareBenchmarks(oldResults: BenchmarkResult[], newResults: BenchmarkR return { summary: memoryComparisonInfo.summary, text: memoryComparisonInfo.text }; } -function outputBenchmarkData(comparisonInfo: { summary: string; text: string }, newResults: BenchmarkResult[]): void { - if (!arg[2]) { - // Output to stdout as json by default, this is used by the CI to retrieve the info - print(json.encode(comparisonInfo)); - } else { +function outputBenchmarkData(oldResults: BenchmarkResult[], newResults: BenchmarkResult[]): void { + // Output benchmark results to json + if (arg[0]) { + if (arg[1]) { + // if baseline is provide output full comparison info + const comparisonInfo = compareBenchmarks(oldResults, newResults); + const jsonDataFile = io.open(arg[0], "w+")[0]!; + jsonDataFile.write(json.encode({ old: oldResults, new: newResults, comparison: comparisonInfo })); + } else { + const jsonDataFile = io.open(arg[0], "w+")[0]!; + jsonDataFile.write(json.encode(newResults)); + } + } + if (arg[2]) { // Output to file as markdown if arg[2] is set, this is useful for local development + // Compare results + const comparisonInfo = compareBenchmarks(oldResults, newResults); const markdownDataFile = io.open(arg[2], "w+")[0]!; markdownDataFile.write(comparisonInfo.summary + comparisonInfo.text); } - // Output benchmark results to json - if (arg[0]) { - const jsonDataFile = io.open(arg[0], "w+")[0]!; - jsonDataFile.write(json.encode(newResults)); - } } diff --git a/benchmark/src/util.ts b/benchmark/src/util.ts index d1c9fcc1d..41f2159f5 100644 --- a/benchmark/src/util.ts +++ b/benchmark/src/util.ts @@ -12,7 +12,7 @@ export function calculatePercentageChange(oldValue: number, newValue: number): n export const isWindows = package.config.startsWith("\\"); export const json: { - decode: (this: void, str: string) => {}; + decode: (this: void, str: string) => Record | unknown[]; encode: (this: void, val: any) => string; } = require("json"); @@ -30,16 +30,21 @@ export function readFile(path: string): string { } export function readAll(file: LuaFile): string { - const content = file.read(_VERSION === "Lua 5.3" ? "a" : ("*a" as any)) as [string | undefined]; + const content = file.read(_VERSION === "Lua 5.3" ? "a" : ("*a" as any)); - if (content[0]) { - return content[0]; + if (content) { + return content as string; } throw Error(`Can't readAll for file ${file}`); } export function readDir(dir: string): string[] { - const findHandle = io.popen(isWindows ? `dir /A-D /B ${dir}` : `find '${dir}' -maxdepth 1 -type f`); + const [findHandle] = io.popen(isWindows ? `dir /A-D /B ${dir}` : `find '${dir}' -maxdepth 1 -type f`); + + if (!findHandle) { + throw new Error(`Failed to read dir ${dir}`); + } + const findResult = readAll(findHandle); if (!findHandle.close()) { diff --git a/jest.config.js b/jest.config.js index 09d82545f..2d390c93d 100644 --- a/jest.config.js +++ b/jest.config.js @@ -17,7 +17,7 @@ module.exports = { preset: "ts-jest", globals: { "ts-jest": { - tsConfig: "/test/tsconfig.json", + tsconfig: "/test/tsconfig.json", diagnostics: { warnOnly: !isCI }, }, }, diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts new file mode 100644 index 000000000..30eb70009 --- /dev/null +++ b/language-extensions/index.d.ts @@ -0,0 +1,566 @@ +type AnyTable = Record; +// eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/consistent-type-definitions +type AnyNotNil = {}; + +/** + * Indicates a type is a language extension provided by TypescriptToLua. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TBrand A string used to uniquely identify the language extension type + */ +declare type LuaExtension = { [T in TBrand]: { readonly __luaExtensionSymbol: unique symbol } }; + +/** + * Returns multiple values from a function, by wrapping them in a LuaMultiReturn tuple. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param T A tuple type with each element type representing a return value's type. + * @param values Return values. + */ +declare const $multi: ((...values: T) => LuaMultiReturn) & LuaExtension<"__luaMultiFunctionBrand">; + +/** + * Represents multiple return values as a tuple. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param T A tuple type with each element type representing a return value's type. + */ +declare type LuaMultiReturn = T & LuaExtension<"__luaMultiReturnBrand">; + +/** + * Creates a Lua-style numeric for loop (for i=start,limit,step) when used in for...of. Not valid in any other context. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param start The first number in the sequence to iterate over. + * @param limit The last number in the sequence to iterate over. + * @param step The amount to increment each iteration. + */ +declare const $range: ((start: number, limit: number, step?: number) => Iterable) & + LuaExtension<"__luaRangeFunctionBrand">; + +/** + * Transpiles to the global vararg (`...`) + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + */ +declare const $vararg: string[] & LuaExtension<"__luaVarargConstantBrand">; + +/** + * Represents a Lua-style iterator which is returned from a LuaIterable. + * For simple iterators (with no state), this is just a function. + * For complex iterators that use a state, this is a LuaMultiReturn tuple containing a function, the state, and the initial value to pass to the function. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param state The state object returned from the LuaIterable. + * @param lastValue The last value returned from this function. If iterating LuaMultiReturn values, this is the first value of the tuple. + */ +declare type LuaIterator = TState extends undefined + ? (this: void) => TValue + : LuaMultiReturn< + [ + ( + this: void, + state: TState, + lastValue: TValue extends LuaMultiReturn ? TTuple[0] : TValue + ) => TValue, + TState, + TValue extends LuaMultiReturn ? TTuple[0] : TValue + ] + >; + +/** + * Represents a Lua-style iteratable which iterates single values in a `for...in` loop (ex. `for x in iter() do`). + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TValue The type of value returned each iteration. If this is LuaMultiReturn, multiple values will be returned each iteration. + * @param TState The type of the state value passed back to the iterator function each iteration. + */ +declare type LuaIterable = Iterable & + LuaIterator & + LuaExtension<"__luaIterableBrand">; + +/** + * Calls to functions with this type are translated to `left + right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaAddition = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaAdditionBrand">; + +/** + * Calls to methods with this type are translated to `left + right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaAdditionMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaAdditionMethodBrand">; + +/** + * Calls to functions with this type are translated to `left - right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaSubtraction = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaSubtractionBrand">; + +/** + * Calls to methods with this type are translated to `left - right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaSubtractionMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaSubtractionMethodBrand">; + +/** + * Calls to functions with this type are translated to `left * right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaMultiplication = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaMultiplicationBrand">; + +/** + * Calls to methods with this type are translated to `left * right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaMultiplicationMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaMultiplicationMethodBrand">; + +/** + * Calls to functions with this type are translated to `left / right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaDivision = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaDivisionBrand">; + +/** + * Calls to methods with this type are translated to `left / right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaDivisionMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaDivisionMethodBrand">; + +/** + * Calls to functions with this type are translated to `left % right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaModulo = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaModuloBrand">; + +/** + * Calls to methods with this type are translated to `left % right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaModuloMethod = ((right: TRight) => TReturn) & LuaExtension<"__luaModuloMethodBrand">; + +/** + * Calls to functions with this type are translated to `left ^ right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaPower = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaPowerBrand">; + +/** + * Calls to methods with this type are translated to `left ^ right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaPowerMethod = ((right: TRight) => TReturn) & LuaExtension<"__luaPowerMethodBrand">; + +/** + * Calls to functions with this type are translated to `left // right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaFloorDivision = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaFloorDivisionBrand">; + +/** + * Calls to methods with this type are translated to `left // right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaFloorDivisionMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaFloorDivisionMethodBrand">; + +/** + * Calls to functions with this type are translated to `left & right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseAnd = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseAndBrand">; + +/** + * Calls to methods with this type are translated to `left & right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseAndMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseAndMethodBrand">; + +/** + * Calls to functions with this type are translated to `left | right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseOr = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseOrBrand">; + +/** + * Calls to methods with this type are translated to `left | right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseOrMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseOrMethodBrand">; + +/** + * Calls to functions with this type are translated to `left ~ right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseExclusiveOr = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseExclusiveOrBrand">; + +/** + * Calls to methods with this type are translated to `left ~ right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseExclusiveOrMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseExclusiveOrMethodBrand">; + +/** + * Calls to functions with this type are translated to `left << right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseLeftShift = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseLeftShiftBrand">; + +/** + * Calls to methods with this type are translated to `left << right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseLeftShiftMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseLeftShiftMethodBrand">; + +/** + * Calls to functions with this type are translated to `left >> right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseRightShift = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseRightShiftBrand">; + +/** + * Calls to methods with this type are translated to `left >> right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseRightShiftMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseRightShiftMethodBrand">; + +/** + * Calls to functions with this type are translated to `left .. right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaConcat = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaConcatBrand">; + +/** + * Calls to methods with this type are translated to `left .. right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaConcatMethod = ((right: TRight) => TReturn) & LuaExtension<"__luaConcatMethodBrand">; + +/** + * Calls to functions with this type are translated to `left < right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaLessThan = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaLessThanBrand">; + +/** + * Calls to methods with this type are translated to `left < right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaLessThanMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaLessThanMethodBrand">; + +/** + * Calls to functions with this type are translated to `left > right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaGreaterThan = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaGreaterThanBrand">; + +/** + * Calls to methods with this type are translated to `left > right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaGreaterThanMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaGreaterThanMethodBrand">; + +/** + * Calls to functions with this type are translated to `-operand`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TOperand The type of the value in the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaNegation = ((operand: TOperand) => TReturn) & LuaExtension<"__luaNegationBrand">; + +/** + * Calls to method with this type are translated to `-operand`, where `operand` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaNegationMethod = (() => TReturn) & LuaExtension<"__luaNegationMethodBrand">; + +/** + * Calls to functions with this type are translated to `~operand`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TOperand The type of the value in the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseNot = ((operand: TOperand) => TReturn) & LuaExtension<"__luaBitwiseNotBrand">; + +/** + * Calls to method with this type are translated to `~operand`, where `operand` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseNotMethod = (() => TReturn) & LuaExtension<"__luaBitwiseNotMethodBrand">; + +/** + * Calls to functions with this type are translated to `#operand`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TOperand The type of the value in the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaLength = ((operand: TOperand) => TReturn) & LuaExtension<"__luaLengthBrand">; + +/** + * Calls to method with this type are translated to `#operand`, where `operand` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaLengthMethod = (() => TReturn) & LuaExtension<"__luaLengthMethodBrand">; + +/** + * Calls to functions with this type are translated to `table[key]`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TTable The type to access as a Lua table. + * @param TKey The type of the key to use to access the table. + * @param TValue The type of the value stored in the table. + */ +declare type LuaTableGet = (( + table: TTable, + key: TKey +) => TValue) & + LuaExtension<"__luaTableGetBrand">; + +/** + * Calls to methods with this type are translated to `table[key]`, where `table` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the key to use to access the table. + * @param TValue The type of the value stored in the table. + */ +declare type LuaTableGetMethod = ((key: TKey) => TValue) & + LuaExtension<"__luaTableGetMethodBrand">; + +/** + * Calls to functions with this type are translated to `table[key] = value`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TTable The type to access as a Lua table. + * @param TKey The type of the key to use to access the table. + * @param TValue The type of the value to assign to the table. + */ +declare type LuaTableSet = (( + table: TTable, + key: TKey, + value: TValue +) => void) & + LuaExtension<"__luaTableSetBrand">; + +/** + * Calls to methods with this type are translated to `table[key] = value`, where `table` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the key to use to access the table. + * @param TValue The type of the value to assign to the table. + */ +declare type LuaTableSetMethod = ((key: TKey, value: TValue) => void) & + LuaExtension<"__luaTableSetMethodBrand">; + +/** + * Calls to functions with this type are translated to `table[key] ~= nil`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TTable The type to access as a Lua table. + * @param TKey The type of the key to use to access the table. + */ +declare type LuaTableHas = ((table: TTable, key: TKey) => boolean) & + LuaExtension<"__luaTableHasBrand">; + +/** + * Calls to methods with this type are translated to `table[key] ~= nil`, where `table` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the key to use to access the table. + */ +declare type LuaTableHasMethod = ((key: TKey) => boolean) & + LuaExtension<"__luaTableHasMethodBrand">; + +/** + * Calls to functions with this type are translated to `table[key] = nil`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TTable The type to access as a Lua table. + * @param TKey The type of the key to use to access the table. + */ +declare type LuaTableDelete = ((table: TTable, key: TKey) => boolean) & + LuaExtension<"__luaTableDeleteBrand">; + +/** + * Calls to methods with this type are translated to `table[key] = nil`, where `table` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the key to use to access the table. + */ +declare type LuaTableDeleteMethod = ((key: TKey) => boolean) & + LuaExtension<"__luaTableDeleteMethodBrand">; + +/** + * A convenience type for working directly with a Lua table. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the keys used to access the table. + * @param TValue The type of the values stored in the table. + */ +declare interface LuaTable { + length: LuaLengthMethod; + get: LuaTableGetMethod; + set: LuaTableSetMethod; + has: LuaTableHasMethod; + delete: LuaTableDeleteMethod; +} + +/** + * A convenience type for working directly with a Lua table. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the keys used to access the table. + * @param TValue The type of the values stored in the table. + */ +declare type LuaTableConstructor = (new () => LuaTable< + TKey, + TValue +>) & + LuaExtension<"__luaTableNewBrand">; + +/** + * A convenience type for working directly with a Lua table. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the keys used to access the table. + * @param TValue The type of the values stored in the table. + */ +declare const LuaTable: LuaTableConstructor; diff --git a/package-lock.json b/package-lock.json index 2a7114663..816c311bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,1458 +1,12604 @@ { "name": "typescript-to-lua", - "version": "0.35.0", - "lockfileVersion": 1, + "version": "1.0.0", + "lockfileVersion": 2, "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "packages": { + "": { + "name": "typescript-to-lua", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "enhanced-resolve": "^5.8.2", + "resolve": "^1.15.1", + "source-map": "^0.7.3", + "typescript": "^4.3.5" + }, + "bin": { + "tstl": "dist/tstl.js" + }, + "devDependencies": { + "@types/fs-extra": "^8.1.0", + "@types/glob": "^7.1.1", + "@types/jest": "^25.1.3", + "@types/node": "^13.7.7", + "@types/resolve": "1.14.0", + "@typescript-eslint/eslint-plugin": "^4.26.1", + "@typescript-eslint/parser": "^4.26.1", + "eslint": "^7.28.0", + "eslint-plugin-import": "^2.20.1", + "eslint-plugin-jest": "^23.8.2", + "fs-extra": "^8.1.0", + "javascript-stringify": "^2.0.1", + "jest": "^26.0.1", + "jest-circus": "^25.1.0", + "lua-types": "2.10.1", + "lua-wasm-bindings": "^0.2.2", + "prettier": "^2.3.2", + "ts-jest": "^26.3.0", + "ts-node": "^8.6.2" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, - "requires": { - "@babel/highlight": "^7.8.3" + "dependencies": { + "@babel/highlight": "^7.10.4" } }, - "@babel/core": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz", - "integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helpers": "^7.9.6", - "@babel/parser": "^7.9.6", - "@babel/template": "^7.8.6", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6", + "node_modules/@babel/compat-data": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.0.tgz", + "integrity": "sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.0", + "@babel/helper-compilation-targets": "^7.15.0", + "@babel/helper-module-transforms": "^7.15.0", + "@babel/helpers": "^7.14.8", + "@babel/parser": "^7.15.0", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", + "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", + "semver": "^6.3.0", "source-map": "^0.5.0" }, - "dependencies": { - "@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", - "dev": true, - "requires": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - } - }, - "@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true - }, - "@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" - } - }, - "@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "@babel/generator": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", - "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "node_modules/@babel/core/node_modules/@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, - "requires": { - "@babel/types": "^7.8.3", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - }, "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "bin": { + "semver": "bin/semver.js" } }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "node_modules/@babel/core/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true, - "requires": { - "@babel/types": "^7.8.3" + "engines": { + "node": ">=0.10.0" } }, - "@babel/helper-member-expression-to-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", - "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "node_modules/@babel/generator": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.0.tgz", + "integrity": "sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==", "dev": true, - "requires": { - "@babel/types": "^7.8.3" + "dependencies": { + "@babel/types": "^7.15.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-module-imports": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", - "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "node_modules/@babel/generator/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true, - "requires": { - "@babel/types": "^7.8.3" + "engines": { + "node": ">=0.10.0" } }, - "@babel/helper-module-transforms": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", - "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz", + "integrity": "sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A==", "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.6", - "@babel/helper-simple-access": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/template": "^7.8.6", - "@babel/types": "^7.9.0", - "lodash": "^4.17.13" - }, "dependencies": { - "@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true - }, - "@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" - } - }, - "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "@babel/helper-optimise-call-expression": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", - "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "requires": { - "@babel/types": "^7.8.3" + "bin": { + "semver": "bin/semver.js" } }, - "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", - "dev": true - }, - "@babel/helper-replace-supers": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz", - "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==", + "node_modules/@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.8.3", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6" - }, "dependencies": { - "@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", - "dev": true, - "requires": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - } - }, - "@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true - }, - "@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-simple-access": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", - "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "node_modules/@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", "dev": true, - "requires": { - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "node_modules/@babel/helper-hoist-variables": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", + "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", "dev": true, - "requires": { - "@babel/types": "^7.8.3" + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", - "dev": true - }, - "@babel/helpers": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz", - "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==", + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz", + "integrity": "sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg==", "dev": true, - "requires": { - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6" - }, "dependencies": { - "@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", - "dev": true, - "requires": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - } - }, - "@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true - }, - "@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "@babel/types": "^7.15.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "node_modules/@babel/helper-module-imports": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", + "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/parser": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", - "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", - "dev": true - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "node_modules/@babel/helper-module-transforms": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz", + "integrity": "sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "dependencies": { + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-replace-supers": "^7.15.0", + "@babel/helper-simple-access": "^7.14.8", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.9", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", + "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/plugin-syntax-class-properties": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.8.3.tgz", - "integrity": "sha512-UcAyQWg2bAN647Q+O811tG9MrJ38Z10jjhQdKNAL8fsyPzE3cCN/uT+f55cFVY4aGO4jqJAvmqsuY3GQDwAoXg==", + "node_modules/@babel/helper-plugin-utils": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "engines": { + "node": ">=6.9.0" } }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "node_modules/@babel/helper-replace-supers": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz", + "integrity": "sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==", "dev": true, - "requires": { + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.15.0", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz", + "integrity": "sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.14.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.14.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", + "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.15.3", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.3.tgz", + "integrity": "sha512-HwJiz52XaS96lX+28Tnbu31VeFSQJGOeKHJeaEPQlTl7PnlhFElWPj8tUXtqFIzeN86XxXoBr+WFAyK2PPVz6g==", + "dev": true, + "dependencies": { + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.15.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.3.tgz", + "integrity": "sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-logical-assignment-operators": { + "node_modules/@babel/plugin-syntax-bigint": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.8.3.tgz", - "integrity": "sha512-Zpg2Sgc++37kuFl6ppq2Q7Awc6E6AIW671x5PY8E/f7MCIyPPGK/EoeZXvvY3P42exZ3Q4/t3YOzP/HiN79jDg==", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-nullish-coalescing-operator": { + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz", - "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==", + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-object-rest-spread": { + "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-optional-catch-binding": { + "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/plugin-syntax-optional-chaining": { + "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "@babel/traverse": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", - "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "node_modules/@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.4", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.4", - "@babel/types": "^7.8.3", + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template/node_modules/@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.0.tgz", + "integrity": "sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.0", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.15.0", + "@babel/types": "^7.15.0", "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/types": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", - "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "node_modules/@babel/traverse/node_modules/@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", + "dependencies": { + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.0.tgz", + "integrity": "sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.9", "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@bcoe/v8-coverage": { + "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "@cnakazawa/watch": { + "node_modules/@cnakazawa/watch": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", "dev": true, - "requires": { + "dependencies": { "exec-sh": "^0.3.2", "minimist": "^1.2.0" + }, + "bin": { + "watch": "cli.js" + }, + "engines": { + "node": ">=0.1.95" } }, - "@istanbuljs/load-nyc-config": { + "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, + "optional": true, + "peer": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz", + "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, - "requires": { + "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", - "dev": true + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } }, - "@jest/console": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", - "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "jest-message-util": "^25.5.0", - "jest-util": "^25.5.0", - "slash": "^3.0.0" + "dependencies": { + "p-locate": "^4.1.0" }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "@jest/core": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.0.1.tgz", - "integrity": "sha512-Xq3eqYnxsG9SjDC+WLeIgf7/8KU6rddBxH+SCt18gEpOhAGYC/Mq+YbtlNcIdwjnnT+wDseXSbU0e5X84Y4jTQ==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, - "requires": { - "@jest/console": "^26.0.1", - "@jest/reporters": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", + "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "dev": true, + "dependencies": { + "@jest/console": "^26.6.2", + "@jest/reporters": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.0.1", - "jest-config": "^26.0.1", - "jest-haste-map": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-changed-files": "^26.6.2", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.0.1", - "jest-resolve-dependencies": "^26.0.1", - "jest-runner": "^26.0.1", - "jest-runtime": "^26.0.1", - "jest-snapshot": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", - "jest-watcher": "^26.0.1", + "jest-resolve": "^26.6.2", + "jest-resolve-dependencies": "^26.6.3", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "jest-watcher": "^26.6.2", "micromatch": "^4.0.2", "p-each-series": "^2.1.0", "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/@jest/core/node_modules/acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/@jest/core/node_modules/jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@jest/core/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/@jest/core/node_modules/ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@cspotcode/source-map-support": "0.6.1", + "@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", + "yn": "3.1.1" + }, + "bin": { + "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": ">=12.0.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/@jest/environment": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", + "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/environment/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/environment/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@jest/environment/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/fake-timers": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "lolex": "^5.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/fake-timers/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/fake-timers/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@jest/fake-timers/node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "node_modules/@jest/fake-timers/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/fake-timers/node_modules/jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/fake-timers/node_modules/jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/globals": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", + "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "dev": true, + "dependencies": { + "@jest/environment": "^26.6.2", + "@jest/types": "^26.6.2", + "expect": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/expect": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/jest-matcher-utils": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/node": "*" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@jest/globals/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/@jest/reporters": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", + "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^7.0.0" + }, + "engines": { + "node": ">= 10.14.2" + }, + "optionalDependencies": { + "node-notifier": "^8.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/source-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", + "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/test-result": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "dev": true, + "dependencies": { + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", + "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/transform": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.6.2", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.6.2", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "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, + "optional": true, + "peer": 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, + "optional": true, + "peer": 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, + "optional": true, + "peer": 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, + "optional": true, + "peer": true + }, + "node_modules/@types/babel__core": { + "version": "7.1.15", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz", + "integrity": "sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", + "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/fs-extra": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", + "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "25.2.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz", + "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==", + "dev": true, + "dependencies": { + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "13.13.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", + "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.14.0.tgz", + "integrity": "sha512-bmjNBW6tok+67iOsASeYSJxSgY++BIR35nGyGLORTDirhra9reJ0shgGL3U7KPDUbOBCx8JrlCjd4d/y5uiMRQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "15.0.14", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", + "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.2.tgz", + "integrity": "sha512-x4EMgn4BTfVd9+Z+r+6rmWxoAzBaapt4QFqE+d8L8sUtYZYLDTK6VG/y/SMMWA5t1/BVU5Kf+20rX4PtWzUYZg==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "4.29.2", + "@typescript-eslint/scope-manager": "4.29.2", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.2.tgz", + "integrity": "sha512-P6mn4pqObhftBBPAv4GQtEK7Yos1fz/MlpT7+YjH9fTxZcALbiiPKuSIfYP/j13CeOjfq8/fr9Thr2glM9ub7A==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.29.2", + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/typescript-estree": "4.29.2", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.29.2.tgz", + "integrity": "sha512-WQ6BPf+lNuwteUuyk1jD/aHKqMQ9jrdCn7Gxt9vvBnzbpj7aWEf+aZsJ1zvTjx5zFxGCt000lsbD9tQPEL8u6g==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "4.29.2", + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/typescript-estree": "4.29.2", + "debug": "^4.3.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.29.2.tgz", + "integrity": "sha512-mfHmvlQxmfkU8D55CkZO2sQOueTxLqGvzV+mG6S/6fIunDiD2ouwsAoiYCZYDDK73QCibYjIZmGhpvKwAB5BOA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/visitor-keys": "4.29.2" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.29.2.tgz", + "integrity": "sha512-K6ApnEXId+WTGxqnda8z4LhNMa/pZmbTFkDxEBLQAbhLZL50DjeY0VIDCml/0Y3FlcbqXZrABqrcKxq+n0LwzQ==", + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.2.tgz", + "integrity": "sha512-TJ0/hEnYxapYn9SGn3dCnETO0r+MjaxtlWZ2xU+EvytF0g4CqTpZL48SqSNn2hXsPolnewF30pdzR9a5Lj3DNg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/visitor-keys": "4.29.2", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.2.tgz", + "integrity": "sha512-bDgJLQ86oWHJoZ1ai4TZdgXzJxsea3Ee9u9wsTAvjChdj2WLcVsgWYAPeY7RQMn16tKrlQaBnpKv7KBfs4EQag==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.29.2", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "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-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "node_modules/babel-jest": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", + "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", + "dev": true, + "dependencies": { + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", + "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", + "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^26.6.2", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "node_modules/browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "dependencies": { + "resolve": "1.1.7" + } + }, + "node_modules/browser-resolve/node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.16.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.8.tgz", + "integrity": "sha512-sc2m9ohR/49sWEbPj14ZSSZqp+kbi16aLao42Hmn3Z8FpjuMaq2xCA2l4zl9ITfyzvnvyE0hcg62YkIGKxgaNQ==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001251", + "colorette": "^1.3.0", + "electron-to-chromium": "^1.3.811", + "escalade": "^3.1.1", + "node-releases": "^1.1.75" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001251", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz", + "integrity": "sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "dependencies": { + "rsvp": "^4.8.4" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/cjs-module-lexer": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", + "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "dev": true + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colorette": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz", + "integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "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, + "optional": true, + "peer": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "dev": true + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.3.813", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.813.tgz", + "integrity": "sha512-YcSRImHt6JZZ2sSuQ4Bzajtk98igQ0iKkksqlzZLzbh4p0OIyJRSvUbsgqfcR8txdfsoYCc4ym306t4p2kP/aw==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", + "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.18.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz", + "integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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/escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz", + "integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "pkg-dir": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.24.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.1.tgz", + "integrity": "sha512-KSFWhNxPH8OGJwpRJJs+Z7I0a13E2iFQZJIvSnCu6KUs4qmgAm3xN9GYBCSoiGWmwA7gERZPXqYQjcoCROnYhQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.3", + "array.prototype.flat": "^1.2.4", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.6.2", + "find-up": "^2.0.0", + "has": "^1.0.3", + "is-core-module": "^2.6.0", + "minimatch": "^3.0.4", + "object.values": "^1.1.4", + "pkg-up": "^2.0.0", + "read-pkg-up": "^3.0.0", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.10.1" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-plugin-jest": { + "version": "23.20.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.20.0.tgz", + "integrity": "sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "^2.5.0" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/experimental-utils": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", + "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/typescript-estree": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jest/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-plugin-jest/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/exec-sh": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", + "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==", + "dev": true + }, + "node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/expect": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", + "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/expect/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/expect/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/expect/node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "node_modules/expect/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/expect/node_modules/jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/expect/node_modules/jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastq": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.12.0.tgz", + "integrity": "sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", + "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", + "dev": true + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": 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/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/globals": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", + "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + }, + "node_modules/growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true, + "optional": true + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", + "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "optional": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "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", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/javascript-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", + "dev": true + }, + "node_modules/jest": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", + "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", + "dev": true, + "dependencies": { + "@jest/core": "^26.6.3", + "import-local": "^3.0.2", + "jest-cli": "^26.6.3" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-changed-files": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", + "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "execa": "^4.0.0", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-circus": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-25.5.4.tgz", + "integrity": "sha512-nOLJXZjWuV2i8yQ2w+MZ8NhFuqrbgpPAa4mh+DWPYmNI377YYpDKvDUrLMW8U1sa2iGt5mjKQbmJz2SK9AYjWg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "co": "^4.6.0", + "expect": "^25.5.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^25.5.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0", + "stack-utils": "^1.0.1", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-circus/node_modules/@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-circus/node_modules/@jest/globals": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", + "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", + "dev": true, + "dependencies": { + "@jest/environment": "^25.5.0", + "@jest/types": "^25.5.0", + "expect": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-circus/node_modules/@jest/source-map": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-circus/node_modules/@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "dev": true, + "dependencies": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-circus/node_modules/@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-circus/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-circus/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-circus/node_modules/@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", + "dev": true + }, + "node_modules/jest-circus/node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + }, + "engines": { + "node": ">= 8.3" + }, + "optionalDependencies": { + "fsevents": "^2.1.2" + } + }, + "node_modules/jest-circus/node_modules/jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-circus/node_modules/jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-circus/node_modules/jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-circus/node_modules/jest-runtime": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", + "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", + "dev": true, + "dependencies": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/globals": "^25.5.2", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "jest-runtime": "bin/jest-runtime.js" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-circus/node_modules/jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-circus/node_modules/jest-snapshot": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", + "chalk": "^3.0.0", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^25.5.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-circus/node_modules/jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-circus/node_modules/jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-circus/node_modules/jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "dev": true, + "dependencies": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-circus/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-circus/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-circus/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-circus/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-circus/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/jest-circus/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-circus/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", + "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", + "dev": true, + "dependencies": { + "@jest/core": "^26.6.3", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.6.3", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "prompts": "^2.0.1", + "yargs": "^15.4.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-cli/node_modules/acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-cli/node_modules/acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-cli/node_modules/jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-cli/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jest-cli/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/jest-cli/node_modules/ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@cspotcode/source-map-support": "0.6.1", + "@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", + "yn": "3.1.1" + }, + "bin": { + "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": ">=12.0.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/jest-config": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.5.4.tgz", + "integrity": "sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^25.5.4", + "@jest/types": "^25.5.0", + "babel-jest": "^25.5.1", + "chalk": "^3.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^25.5.0", + "jest-environment-node": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-jasmine2": "^25.5.4", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "micromatch": "^4.0.2", + "pretty-format": "^25.5.0", + "realpath-native": "^2.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/@jest/globals": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", + "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", + "dev": true, + "dependencies": { + "@jest/environment": "^25.5.0", + "@jest/types": "^25.5.0", + "expect": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/@jest/source-map": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "dev": true, + "dependencies": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/@jest/test-sequencer": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz", + "integrity": "sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==", + "dev": true, + "dependencies": { + "@jest/test-result": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-config/node_modules/@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", + "dev": true + }, + "node_modules/jest-config/node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "node_modules/jest-config/node_modules/acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dev": true, + "dependencies": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + } + }, + "node_modules/jest-config/node_modules/acorn-globals/node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-config/node_modules/acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-config/node_modules/babel-jest": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", + "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", + "dev": true, + "dependencies": { + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/jest-config/node_modules/babel-plugin-jest-hoist": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", + "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/babel-preset-current-node-syntax": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.4.tgz", + "integrity": "sha512-5/INNCYhUGqw7VbVjT/hb3ucjgkVHKXY7lX3ZjlN4gm565VyFmJUrJ/h+h16ECVB38R/9SF6aACydpKMLZ/c9w==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/jest-config/node_modules/babel-preset-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", + "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^25.5.0", + "babel-preset-current-node-syntax": "^0.1.2" + }, + "engines": { + "node": ">= 8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, + "node_modules/jest-config/node_modules/domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "dependencies": { + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/jest-config/node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/jest-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^1.0.1" + } + }, + "node_modules/jest-config/node_modules/jest-docblock": { + "version": "25.3.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.3.0.tgz", + "integrity": "sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/jest-environment-jsdom": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz", + "integrity": "sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A==", + "dev": true, + "dependencies": { + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "jsdom": "^15.2.1" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/jest-environment-node": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.5.0.tgz", + "integrity": "sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA==", + "dev": true, + "dependencies": { + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + }, + "engines": { + "node": ">= 8.3" + }, + "optionalDependencies": { + "fsevents": "^2.1.2" + } + }, + "node_modules/jest-config/node_modules/jest-jasmine2": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.5.4.tgz", + "integrity": "sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^25.5.0", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "co": "^4.6.0", + "expect": "^25.5.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^25.5.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/jest-leak-detector": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz", + "integrity": "sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA==", + "dev": true, + "dependencies": { + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/jest-runner": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.5.4.tgz", + "integrity": "sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg==", + "dev": true, + "dependencies": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-docblock": "^25.3.0", + "jest-haste-map": "^25.5.1", + "jest-jasmine2": "^25.5.4", + "jest-leak-detector": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "jest-runtime": "^25.5.4", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/jest-runtime": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", + "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", + "dev": true, + "dependencies": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/globals": "^25.5.2", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "jest-runtime": "bin/jest-runtime.js" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/jest-snapshot": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", + "chalk": "^3.0.0", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^25.5.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "dev": true, + "dependencies": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config/node_modules/jsdom": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", + "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", + "dev": true, + "dependencies": { + "abab": "^2.0.0", + "acorn": "^7.1.0", + "acorn-globals": "^4.3.2", + "array-equal": "^1.0.0", + "cssom": "^0.4.1", + "cssstyle": "^2.0.0", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.1", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.2.0", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", + "saxes": "^3.1.9", + "symbol-tree": "^3.2.2", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^7.0.0", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/jest-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/jest-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-config/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-config/node_modules/parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "dev": true + }, + "node_modules/jest-config/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/jest-config/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-config/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "dev": true, + "dependencies": { + "xmlchars": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/jest-config/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-config/node_modules/tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dev": true, + "dependencies": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-config/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/jest-config/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/jest-config/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "dev": true, + "dependencies": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, + "node_modules/jest-config/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "node_modules/jest-config/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-each": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", + "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-each/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-each/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/node_modules/jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", + "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "dev": true, + "dependencies": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2", + "jsdom": "^16.4.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/node": "*" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", + "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", + "dev": true, + "dependencies": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/node": "*" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + }, + "engines": { + "node": ">= 10.14.2" + }, + "optionalDependencies": { + "fsevents": "^2.1.2" + } + }, + "node_modules/jest-jasmine2": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", + "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.6.2", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/expect": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-each": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-matcher-utils": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/node": "*" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jest-jasmine2/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/jest-leak-detector": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", + "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "dev": true, + "dependencies": { + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-leak-detector/node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-message-util/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jest-message-util/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/jest-message-util/node_modules/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-mock": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-mock/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-mock/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-mock/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", + "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-resolve/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-resolve/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-resolve/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-resolve/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", + "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "dev": true, + "dependencies": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.7.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.6.2", + "jest-leak-detector": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-runner/node_modules/acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-runner/node_modules/jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-runner/node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/node": "*" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jest-runner/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/jest-runner/node_modules/ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@cspotcode/source-map-support": "0.6.1", + "@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", + "yn": "3.1.1" + }, + "bin": { + "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": ">=12.0.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/jest-runtime": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", + "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", + "dev": true, + "dependencies": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/globals": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^0.6.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.4.1" + }, + "bin": { + "jest-runtime": "bin/jest-runtime.js" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-runtime/node_modules/acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-runtime/node_modules/jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-runtime/node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/node": "*" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jest-runtime/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@cspotcode/source-map-support": "0.6.1", + "@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", + "yn": "3.1.1" + }, + "bin": { + "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": ">=12.0.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/jest-serializer": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "dev": true, + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-snapshot": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "natural-compare": "^1.4.0", + "pretty-format": "^26.6.2", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-snapshot/node_modules/diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-snapshot/node_modules/expect": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-snapshot/node_modules/jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-snapshot/node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-validate": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "leven": "^3.1.0", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-validate/node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jest-validate/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/jest-watcher": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", + "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "dev": true, + "dependencies": { + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.6.2", + "string-length": "^4.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "dev": true, + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "node_modules/lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lua-types": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.10.1.tgz", + "integrity": "sha512-Ai7L25I5kHZYGN5C3LALUse7Eus0k/kM9tEO2zwReG2Xuker0c+0e2M4iyfiEvlGOmBc7cDouqJ5lFwyg8JqiQ==", + "dev": true, + "dependencies": { + "typescript-to-lua": "^0.39.0" + } + }, + "node_modules/lua-wasm-bindings": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.2.tgz", + "integrity": "sha512-Z2v3An8jEvYbhUJ/gYxNd65ZBbaRyPMmUaleDoOhzJSIGrMgjURvy1EtHtgRGTzdtpmKtHA+YYKDrSZBE9g/ig==", + "dev": true + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "dependencies": { + "tmpl": "1.0.x" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "dev": true, + "dependencies": { + "mime-db": "1.49.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "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/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/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/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node_modules/node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-notifier": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", + "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", + "dev": true, + "optional": true, + "dependencies": { + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", + "shellwords": "^0.1.1", + "uuid": "^8.3.0", + "which": "^2.0.2" + } + }, + "node_modules/node-releases": { + "version": "1.1.75", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", + "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.values": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-each-series": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", + "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "dependencies": { + "node-modules-regexp": "^1.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "dev": true, + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/pretty-format/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/pretty-format/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/pretty-format/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/prompts": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", + "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/realpath-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.19" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.12.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "node_modules/request-promise-native/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true, + "engines": { + "node": "6.* || >= 7.*" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "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==", + "dev": true + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "deprecated": "some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added", + "dev": true, + "dependencies": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "bin": { + "sane": "src/cli.js" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/sane/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/sane/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/sane/node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sane/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sane/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sane/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/sane/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/sane/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true, + "optional": true + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/snapdragon/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "dev": true + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", + "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", + "dev": true + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stack-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "node_modules/table": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", + "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true + }, + "node_modules/tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "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==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-jest": { + "version": "26.5.6", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.6.tgz", + "integrity": "sha512-rua+rCP8DxpA8b4DQD/6X2HQS8Zy/xzViVYfEs2OQu68tkCuKLV0Md8pmX55+W24uRIyAsf/BajRfxOs+R2MKA==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^26.1.0", + "json5": "2.x", + "lodash": "4.x", + "make-error": "1.x", + "mkdirp": "1.x", + "semver": "7.x", + "yargs-parser": "20.x" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": ">= 10" + }, + "peerDependencies": { + "jest": ">=26 <27", + "typescript": ">=3.8 <5.0" + } + }, + "node_modules/ts-node": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "dev": true, + "dependencies": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.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": ">=6.0.0" + }, + "peerDependencies": { + "typescript": ">=2.7" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", + "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", + "dev": true, + "dependencies": { + "json5": "^2.2.0", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/typescript-to-lua": { + "version": "0.39.6", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-0.39.6.tgz", + "integrity": "sha512-Yq+XsmFKknMlz9jm1FvTw5B7R4H8lYUly4uwxlR44aT4OFyG9S7mOImrTIF07j414PdrJSQ5dAAhQOBVRqHbMw==", + "dev": true, + "dependencies": { + "resolve": "^1.15.1", + "source-map": "^0.7.3", + "typescript": "~4.3.2" + }, + "bin": { + "tstl": "dist/tstl.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/union-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", + "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "dependencies": { + "makeerror": "1.0.x" + } + }, + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true, + "engines": { + "node": ">=10.4" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dev": true, + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "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-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", + "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/compat-data": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "dev": true + }, + "@babel/core": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.0.tgz", + "integrity": "sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.0", + "@babel/helper-compilation-targets": "^7.15.0", + "@babel/helper-module-transforms": "^7.15.0", + "@babel/helpers": "^7.14.8", + "@babel/parser": "^7.15.0", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, "dependencies": { - "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", - "slash": "^3.0.0" - } - }, - "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", - "dev": true, - "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", - "dev": true - }, - "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", - "dev": true - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-regex-util": "^26.0.0" + "@babel/highlight": "^7.14.5" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, - "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" - } - }, - "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true - }, - "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" - } - }, - "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - } - }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + } + } + }, + "@babel/generator": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.0.tgz", + "integrity": "sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==", + "dev": true, + "requires": { + "@babel/types": "^7.15.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true - }, - "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", - "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", - "slash": "^3.0.0" - } - }, - "jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.0.1", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", - "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", - "semver": "^7.3.2" - } - }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } - }, - "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" - } - }, - "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - } - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz", + "integrity": "sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "dependencies": { "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true - }, - "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - } } } }, - "@jest/environment": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", - "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", + "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz", + "integrity": "sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg==", + "dev": true, + "requires": { + "@babel/types": "^7.15.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", + "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-module-transforms": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz", + "integrity": "sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-replace-supers": "^7.15.0", + "@babel/helper-simple-access": "^7.14.8", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.9", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", + "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz", + "integrity": "sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.15.0", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz", + "integrity": "sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg==", "dev": true, "requires": { - "@jest/fake-timers": "^25.5.0", - "@jest/types": "^25.5.0", - "jest-mock": "^25.5.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } + "@babel/types": "^7.14.8" } }, - "@jest/fake-timers": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", - "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", "dev": true, "requires": { - "@jest/types": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-mock": "^25.5.0", - "jest-util": "^25.5.0", - "lolex": "^5.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } + "@babel/types": "^7.14.5" } }, - "@jest/globals": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.0.1.tgz", - "integrity": "sha512-iuucxOYB7BRCvT+TYBzUqUNuxFX1hqaR6G6IcGgEqkJ5x4htNKo1r7jk1ji9Zj8ZMiMw0oB5NaA7k5Tx6MVssA==", + "@babel/helper-validator-identifier": { + "version": "7.14.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", + "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true + }, + "@babel/helpers": { + "version": "7.15.3", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.3.tgz", + "integrity": "sha512-HwJiz52XaS96lX+28Tnbu31VeFSQJGOeKHJeaEPQlTl7PnlhFElWPj8tUXtqFIzeN86XxXoBr+WFAyK2PPVz6g==", + "dev": true, + "requires": { + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0" + } + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, "requires": { - "@jest/environment": "^26.0.1", - "@jest/types": "^26.0.1", - "expect": "^26.0.1" + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" }, "dependencies": { - "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", - "dev": true, - "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" - } - }, - "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" - } - }, - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "color-convert": "^1.9.0" } }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", - "dev": true - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-regex-util": "^26.0.0" + "color-name": "1.1.3" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" - } - }, - "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, - "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" - } - }, - "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - } - }, - "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1" - } - }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "has-flag": "^3.0.0" } - }, - "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + } + } + }, + "@babel/parser": { + "version": "7.15.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.3.tgz", + "integrity": "sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==", + "dev": true + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "@babel/highlight": "^7.14.5" } - }, - "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + } + } + }, + "@babel/traverse": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.0.tgz", + "integrity": "sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.0", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.15.0", + "@babel/types": "^7.15.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "requires": { - "escape-string-regexp": "^2.0.0" + "@babel/highlight": "^7.14.5" } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true } } }, - "@jest/reporters": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.0.1.tgz", - "integrity": "sha512-NWWy9KwRtE1iyG/m7huiFVF9YsYv/e+mbflKRV84WDoJfBqUrNRyDbL/vFxQcYLl8IRqI4P3MgPn386x76Gf2g==", + "@babel/types": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.0.tgz", + "integrity": "sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==", "dev": true, "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.0.1", - "jest-resolve": "^26.0.1", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", - "node-notifier": "^7.0.0", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^4.1.3" + "@babel/helper-validator-identifier": "^7.14.9", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@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, + "optional": true, + "peer": true + }, + "@cspotcode/source-map-support": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz", + "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + } + }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" }, "dependencies": { - "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", - "slash": "^3.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, - "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "p-locate": "^4.1.0" } }, - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "p-try": "^2.0.0" } }, - "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "p-limit": "^2.2.0" } }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jest/console": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", + "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/reporters": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.6.2", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-resolve-dependencies": "^26.6.3", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "jest-watcher": "^26.6.2", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - } + "optional": true, + "peer": true }, - "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", - "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", - "slash": "^3.0.0" - } + "optional": true, + "peer": true }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } - }, - "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" - } - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" } }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - } + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" + "optional": true, + "peer": true, + "requires": { + "@cspotcode/source-map-support": "0.6.1", + "@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", + "yn": "3.1.1" } } } }, - "@jest/source-map": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.0.0.tgz", - "integrity": "sha512-S2Z+Aj/7KOSU2TfW0dyzBze7xr95bkm5YXNUqqCek+HE0VbNNSNzrRwfIi5lf7wvzDTSS0/ib8XQ1krFNyYgbQ==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "@jest/test-result": { + "@jest/environment": { "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", - "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", + "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", "dev": true, "requires": { - "@jest/console": "^25.5.0", + "@jest/fake-timers": "^25.5.0", "@jest/types": "^25.5.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "jest-mock": "^25.5.0" }, "dependencies": { "@jest/types": { @@ -1466,191 +12612,336 @@ "@types/yargs": "^15.0.0", "chalk": "^3.0.0" } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } } } }, - "@jest/test-sequencer": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.0.1.tgz", - "integrity": "sha512-ssga8XlwfP8YjbDcmVhwNlrmblddMfgUeAkWIXts1V22equp2GMIHxm7cyeD5Q/B0ZgKPK/tngt45sH99yLLGg==", + "@jest/fake-timers": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", "dev": true, "requires": { - "@jest/test-result": "^26.0.1", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.0.1", - "jest-runner": "^26.0.1", - "jest-runtime": "^26.0.1" + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "lolex": "^5.0.0" }, "dependencies": { - "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", - "slash": "^3.0.0" - } - }, - "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" } }, - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" } }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^25.5.0", "@types/stack-utils": "^1.0.1", - "chalk": "^4.0.0", + "chalk": "^3.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "stack-utils": "^1.0.1" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" } - }, - "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - } } } }, - "@jest/transform": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.0.1.tgz", - "integrity": "sha512-pPRkVkAQ91drKGbzCfDOoHN838+FSbYaEAvBXvKuWeeRRUD8FjwXkqfUNUZL6Ke48aA/1cqq/Ni7kVMCoqagWA==", + "@jest/globals": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", + "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.0.1", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.0.1", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.0.1", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" + "@jest/environment": "^26.6.2", + "@jest/types": "^26.6.2", + "expect": "^26.6.2" }, "dependencies": { - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, - "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "expect": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" + } + }, + "jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "jest-matcher-utils": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { - "@jest/types": "^26.0.1", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + } + } + }, + "@jest/reporters": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", + "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "node-notifier": "^8.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^7.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@jest/source-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", + "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@jest/test-result": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", + "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "dev": true, + "requires": { + "@jest/test-result": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3" + } + }, + "@jest/transform": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.6.2", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.6.2", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1660,21 +12951,48 @@ } }, "@jest/types": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.1.0.tgz", - "integrity": "sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "chalk": "^4.0.0" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" } }, "@sinonjs/commons": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", - "integrity": "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==", + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -1689,10 +13007,48 @@ "@sinonjs/commons": "^1.7.0" } }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true, + "optional": true, + "peer": 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, + "optional": true, + "peer": 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, + "optional": true, + "peer": 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, + "optional": true, + "peer": true + }, "@types/babel__core": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.7.tgz", - "integrity": "sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw==", + "version": "7.1.15", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz", + "integrity": "sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -1703,18 +13059,18 @@ } }, "@types/babel__generator": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", - "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", + "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", "dev": true, "requires": { "@babel/types": "^7.0.0" } }, "@types/babel__template": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", - "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -1722,65 +13078,46 @@ } }, "@types/babel__traverse": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.11.tgz", - "integrity": "sha512-ddHK5icION5U6q11+tV2f9Mo6CZVuT8GJKld2q9LqHSZbvLbH34Kcu2yFGckZut453+eQU6btIA3RihmnRgI+Q==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", "dev": true, "requires": { "@babel/types": "^7.3.0" } }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true - }, - "@types/eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, "@types/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg==", + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", + "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", "dev": true, "requires": { "@types/node": "*" } }, "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", "dev": true, "requires": { - "@types/events": "*", "@types/minimatch": "*", "@types/node": "*" } }, "@types/graceful-fs": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", - "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", "dev": true, "requires": { "@types/node": "*" } }, "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", "dev": true }, "@types/istanbul-lib-report": { @@ -1793,53 +13130,52 @@ } }, "@types/istanbul-reports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", - "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "*", "@types/istanbul-lib-report": "*" } }, "@types/jest": { - "version": "25.1.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.1.3.tgz", - "integrity": "sha512-jqargqzyJWgWAJCXX96LBGR/Ei7wQcZBvRv0PLEu9ZByMfcs23keUJrKv9FMR6YZf9YCbfqDqgmY+JUBsnqhrg==", + "version": "25.2.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz", + "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==", "dev": true, "requires": { - "jest-diff": "^25.1.0", - "pretty-format": "^25.1.0" + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" } }, "@types/json-schema": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", - "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", "dev": true }, "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", "dev": true }, "@types/node": { - "version": "13.7.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.7.tgz", - "integrity": "sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg==", + "version": "13.13.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", + "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", "dev": true }, "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, "@types/prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog==", "dev": true }, "@types/resolve": { @@ -1852,191 +13188,118 @@ } }, "@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, "@types/yargs": { - "version": "15.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.4.tgz", - "integrity": "sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg==", + "version": "15.0.14", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", + "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, "requires": { "@types/yargs-parser": "*" } }, "@types/yargs-parser": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", - "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.31.0.tgz", - "integrity": "sha512-iIC0Pb8qDaoit+m80Ln/aaeu9zKQdOLF4SHcGLarSeY1gurW6aU4JsOPMjKQwXlw70MvWKZQc6S2NamA8SJ/gg==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.2.tgz", + "integrity": "sha512-x4EMgn4BTfVd9+Z+r+6rmWxoAzBaapt4QFqE+d8L8sUtYZYLDTK6VG/y/SMMWA5t1/BVU5Kf+20rX4PtWzUYZg==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "2.31.0", + "@typescript-eslint/experimental-utils": "4.29.2", + "@typescript-eslint/scope-manager": "4.29.2", + "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", - "regexpp": "^3.0.0", - "tsutils": "^3.17.1" - }, - "dependencies": { - "@typescript-eslint/experimental-utils": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.31.0.tgz", - "integrity": "sha512-MI6IWkutLYQYTQgZ48IVnRXmLR/0Q6oAyJgiOror74arUMh7EWjJkADfirZhRsUMHeLJ85U2iySDwHTSnNi9vA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.31.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, - "@typescript-eslint/typescript-estree": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", - "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^6.3.0", - "tsutils": "^3.17.1" - } - }, - "eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" } }, "@typescript-eslint/experimental-utils": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.23.0.tgz", - "integrity": "sha512-OswxY59RcXH3NNPmq+4Kis2CYZPurRU6mG5xPcn24CjFyfdVli5mySwZz/g/xDbJXgDsYqNGq7enV0IziWGXVQ==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.2.tgz", + "integrity": "sha512-P6mn4pqObhftBBPAv4GQtEK7Yos1fz/MlpT7+YjH9fTxZcALbiiPKuSIfYP/j13CeOjfq8/fr9Thr2glM9ub7A==", "dev": true, "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.23.0", - "eslint-scope": "^5.0.0" + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.29.2", + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/typescript-estree": "4.29.2", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" } }, "@typescript-eslint/parser": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.31.0.tgz", - "integrity": "sha512-uph+w6xUOlyV2DLSC6o+fBDzZ5i7+3/TxAsH4h3eC64tlga57oMb96vVlXoMwjR/nN+xyWlsnxtbDkB46M2EPQ==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.29.2.tgz", + "integrity": "sha512-WQ6BPf+lNuwteUuyk1jD/aHKqMQ9jrdCn7Gxt9vvBnzbpj7aWEf+aZsJ1zvTjx5zFxGCt000lsbD9tQPEL8u6g==", "dev": true, "requires": { - "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "2.31.0", - "@typescript-eslint/typescript-estree": "2.31.0", - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "@typescript-eslint/experimental-utils": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.31.0.tgz", - "integrity": "sha512-MI6IWkutLYQYTQgZ48IVnRXmLR/0Q6oAyJgiOror74arUMh7EWjJkADfirZhRsUMHeLJ85U2iySDwHTSnNi9vA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.31.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, - "@typescript-eslint/typescript-estree": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", - "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^6.3.0", - "tsutils": "^3.17.1" - } - }, - "eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "@typescript-eslint/scope-manager": "4.29.2", + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/typescript-estree": "4.29.2", + "debug": "^4.3.1" + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.29.2.tgz", + "integrity": "sha512-mfHmvlQxmfkU8D55CkZO2sQOueTxLqGvzV+mG6S/6fIunDiD2ouwsAoiYCZYDDK73QCibYjIZmGhpvKwAB5BOA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/visitor-keys": "4.29.2" } }, + "@typescript-eslint/types": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.29.2.tgz", + "integrity": "sha512-K6ApnEXId+WTGxqnda8z4LhNMa/pZmbTFkDxEBLQAbhLZL50DjeY0VIDCml/0Y3FlcbqXZrABqrcKxq+n0LwzQ==", + "dev": true + }, "@typescript-eslint/typescript-estree": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.23.0.tgz", - "integrity": "sha512-pmf7IlmvXdlEXvE/JWNNJpEvwBV59wtJqA8MLAxMKLXNKVRC3HZBXR/SlZLPWTCcwOSg9IM7GeRSV3SIerGVqw==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.2.tgz", + "integrity": "sha512-TJ0/hEnYxapYn9SGn3dCnETO0r+MjaxtlWZ2xU+EvytF0g4CqTpZL48SqSNn2hXsPolnewF30pdzR9a5Lj3DNg==", "dev": true, "requires": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/visitor-keys": "4.29.2", + "debug": "^4.3.1", + "globby": "^11.0.3", "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^6.3.0", - "tsutils": "^3.17.1" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.2.tgz", + "integrity": "sha512-bDgJLQ86oWHJoZ1ai4TZdgXzJxsea3Ee9u9wsTAvjChdj2WLcVsgWYAPeY7RQMn16tKrlQaBnpKv7KBfs4EQag==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.29.2", + "eslint-visitor-keys": "^2.0.0" } }, "abab": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", - "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", "dev": true }, "acorn": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", - "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, "acorn-globals": { @@ -2050,21 +13313,31 @@ } }, "acorn-jsx": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", - "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", - "dev": true + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} }, "acorn-walk": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", - "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, "ajv": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", - "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -2073,13 +13346,27 @@ "uri-js": "^4.2.2" } }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, "ansi-escapes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", - "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } } }, "ansi-regex": { @@ -2089,19 +13376,18 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -2121,14 +13407,6 @@ "dev": true, "requires": { "sprintf-js": "~1.0.2" - }, - "dependencies": { - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - } } }, "arr-diff": { @@ -2149,17 +13427,31 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, "array-includes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", - "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", "dev": true, "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", "is-string": "^1.0.5" } }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", @@ -2167,13 +13459,14 @@ "dev": true }, "array.prototype.flat": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", - "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" + "es-abstract": "^1.18.0-next.1" } }, "asn1": { @@ -2198,9 +13491,9 @@ "dev": true }, "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "asynckit": { @@ -2222,55 +13515,25 @@ "dev": true }, "aws4": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", - "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, "babel-jest": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.0.1.tgz", - "integrity": "sha512-Z4GGmSNQ8pX3WS1O+6v3fo41YItJJZsVxG5gIQ+HuB/iuAQBJxMTHTwz292vuYws1LnHfwSRgoqI+nxdy/pcvw==", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", + "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", "dev": true, "requires": { - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", "@types/babel__core": "^7.1.7", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.0.0", + "babel-preset-jest": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } } }, "babel-plugin-istanbul": { @@ -2287,48 +13550,51 @@ } }, "babel-plugin-jest-hoist": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.0.0.tgz", - "integrity": "sha512-+AuoehOrjt9irZL7DOt2+4ZaTM6dlu1s5TTS46JBa0/qem4dy7VNW3tMb96qeEqcIh20LD73TVNtmVEeymTG7w==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", + "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", "dev": true, "requires": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", "@types/babel__traverse": "^7.0.6" } }, "babel-preset-current-node-syntax": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz", - "integrity": "sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, "requires": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-numeric-separator": "^7.8.3", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" } }, "babel-preset-jest": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.0.0.tgz", - "integrity": "sha512-9ce+DatAa31DpR4Uir8g4Ahxs5K4W4L8refzt+qHWQANb6LhGcAEfIFgLUwk67oya2cCUd6t4eUMtO/z64ocNw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", + "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^26.0.0", - "babel-preset-current-node-syntax": "^0.1.2" + "babel-plugin-jest-hoist": "^26.6.2", + "babel-preset-current-node-syntax": "^1.0.0" } }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "base": { @@ -2354,35 +13620,6 @@ "requires": { "is-descriptor": "^1.0.0" } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } } } }, @@ -2437,6 +13674,19 @@ } } }, + "browserslist": { + "version": "4.16.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.8.tgz", + "integrity": "sha512-sc2m9ohR/49sWEbPj14ZSSZqp+kbi16aLao42Hmn3Z8FpjuMaq2xCA2l4zl9ITfyzvnvyE0hcg62YkIGKxgaNQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001251", + "colorette": "^1.3.0", + "electron-to-chromium": "^1.3.811", + "escalade": "^3.1.1", + "node-releases": "^1.1.75" + } + }, "bs-logger": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", @@ -2456,9 +13706,9 @@ } }, "buffer-from": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", - "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, "cache-base": { @@ -2478,6 +13728,16 @@ "unset-value": "^1.0.0" } }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2490,6 +13750,12 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, + "caniuse-lite": { + "version": "1.0.30001251", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz", + "integrity": "sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A==", + "dev": true + }, "capture-exit": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", @@ -2506,9 +13772,9 @@ "dev": true }, "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -2521,18 +13787,18 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, + "cjs-module-lexer": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", + "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "dev": true + }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -2551,26 +13817,68 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -2619,6 +13927,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "colorette": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz", + "integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2640,16 +13954,10 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", "dev": true, "requires": { "safe-buffer": "~5.1.1" @@ -2667,17 +13975,23 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "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, + "optional": true, + "peer": true + }, "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, "cssom": { @@ -2724,12 +14038,12 @@ } }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "decamelize": { @@ -2739,9 +14053,9 @@ "dev": true }, "decimal.js": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", - "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", "dev": true }, "decode-uri-component": { @@ -2779,37 +14093,6 @@ "requires": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } } }, "delayed-stream": { @@ -2831,11 +14114,20 @@ "dev": true }, "diff-sequences": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.1.0.tgz", - "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==", + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", "dev": true }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -2872,6 +14164,18 @@ "safer-buffer": "^2.1.0" } }, + "electron-to-chromium": { + "version": "1.3.813", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.813.tgz", + "integrity": "sha512-YcSRImHt6JZZ2sSuQ4Bzajtk98igQ0iKkksqlzZLzbh4p0OIyJRSvUbsgqfcR8txdfsoYCc4ym306t4p2kP/aw==", + "dev": true + }, + "emittery": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", + "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "dev": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -2887,6 +14191,24 @@ "once": "^1.4.0" } }, + "enhanced-resolve": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -2897,22 +14219,28 @@ } }, "es-abstract": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", - "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "version": "1.18.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz", + "integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==", "dev": true, "requires": { + "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.11.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" } }, "es-to-primitive": { @@ -2926,297 +14254,215 @@ "is-symbol": "^1.0.2" } }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, "escodegen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz", - "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", "dev": true, "requires": { "esprima": "^4.0.1", - "estraverse": "^4.2.0", + "estraverse": "^5.2.0", "esutils": "^2.0.2", "optionator": "^0.8.1", "source-map": "~0.6.1" }, "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } } } }, "eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.3", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "requires": { - "type-fest": "^0.8.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "eslint-import-resolver-node": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", - "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "resolve": "^1.13.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-module-utils": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz", - "integrity": "sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { - "p-try": "^1.0.0" + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + } + } + }, + "eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "p-limit": "^1.1.0" + "ms": "^2.1.1" } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + } + } + }, + "eslint-module-utils": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz", + "integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "find-up": "^2.1.0" + "ms": "^2.1.1" } } } }, "eslint-plugin-import": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz", - "integrity": "sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw==", + "version": "2.24.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.1.tgz", + "integrity": "sha512-KSFWhNxPH8OGJwpRJJs+Z7I0a13E2iFQZJIvSnCu6KUs4qmgAm3xN9GYBCSoiGWmwA7gERZPXqYQjcoCROnYhQ==", "dev": true, "requires": { - "array-includes": "^3.0.3", - "array.prototype.flat": "^1.2.1", - "contains-path": "^0.1.0", + "array-includes": "^3.1.3", + "array.prototype.flat": "^1.2.4", "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.2", - "eslint-module-utils": "^2.4.1", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.6.2", + "find-up": "^2.0.0", "has": "^1.0.3", + "is-core-module": "^2.6.0", "minimatch": "^3.0.4", - "object.values": "^1.1.0", - "read-pkg-up": "^2.0.0", - "resolve": "^1.12.0" + "object.values": "^1.1.4", + "pkg-up": "^2.0.0", + "read-pkg-up": "^3.0.0", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.10.1" }, "dependencies": { "debug": { @@ -3229,13 +14475,12 @@ } }, "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" + "esutils": "^2.0.2" } }, "ms": { @@ -3247,54 +14492,98 @@ } }, "eslint-plugin-jest": { - "version": "23.8.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.8.2.tgz", - "integrity": "sha512-xwbnvOsotSV27MtAe7s8uGWOori0nUsrXh2f1EnpmXua8sDfY6VZhHAhHg2sqK7HBNycRQExF074XSZ7DvfoFg==", + "version": "23.20.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.20.0.tgz", + "integrity": "sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw==", "dev": true, "requires": { "@typescript-eslint/experimental-utils": "^2.5.0" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", + "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { - "esrecurse": "^4.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0" + "eslint-visitor-keys": "^2.0.0" } }, "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true }, "espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" }, "dependencies": { - "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true } } @@ -3306,21 +14595,37 @@ "dev": true }, "esquery": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", - "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { - "estraverse": "^4.0.0" + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { - "estraverse": "^4.1.0" + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, "estraverse": { @@ -3336,24 +14641,26 @@ "dev": true }, "exec-sh": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", - "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", + "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==", "dev": true }, "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" } }, "exit": { @@ -3404,6 +14711,69 @@ "is-extendable": "^0.1.0" } }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -3438,53 +14808,53 @@ "chalk": "^3.0.0" } }, - "diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true - }, - "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" } }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", "dev": true }, - "jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "pretty-format": { + "jest-message-util": { "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "dev": true, "requires": { + "@babel/code-frame": "^7.0.0", "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" } + }, + "jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "dev": true } } }, @@ -3502,28 +14872,6 @@ "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" } }, "extglob": { @@ -3560,34 +14908,11 @@ "is-extendable": "^0.1.0" } }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true } } }, @@ -3598,11 +14923,24 @@ "dev": true }, "fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -3615,42 +14953,31 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, - "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "fengari": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/fengari/-/fengari-0.1.4.tgz", - "integrity": "sha512-6ujqUuiIYmcgkGz8MGAdERU57EIluGGPSUgGPTsco657EHa+srq0S3/YUl/r9kx1+D+d4rGfYObd+m8K22gB1g==", + "fastq": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.12.0.tgz", + "integrity": "sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg==", "dev": true, "requires": { - "readline-sync": "^1.4.9", - "sprintf-js": "^1.1.1", - "tmp": "^0.0.33" + "reusify": "^1.0.4" } }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5" + "bser": "2.1.1" } }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "fill-range": { @@ -3663,41 +14990,28 @@ } }, "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "locate-path": "^2.0.0" } }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } + "flatted": "^3.1.0", + "rimraf": "^3.0.2" } }, "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", + "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", "dev": true }, "for-in": { @@ -3713,13 +15027,13 @@ "dev": true }, "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "dev": true, "requires": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, @@ -3741,14 +15055,6 @@ "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "dev": true - } } }, "fs.realpath": { @@ -3758,17 +15064,16 @@ "dev": true }, "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -3777,9 +15082,9 @@ "dev": true }, "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true }, "get-caller-file": { @@ -3788,6 +15093,17 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -3795,9 +15111,9 @@ "dev": true }, "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -3819,9 +15135,9 @@ } }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -3833,25 +15149,49 @@ } }, "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "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" } }, "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", + "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + } + } }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, "growly": { "version": "1.3.0", @@ -3867,12 +15207,12 @@ "dev": true }, "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "dev": true, "requires": { - "ajv": "^6.5.5", + "ajv": "^6.12.3", "har-schema": "^2.0.0" } }, @@ -3880,11 +15220,16 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3892,11 +15237,20 @@ "dev": true }, "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -3950,9 +15304,9 @@ } }, "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "html-encoding-sniffer": { @@ -3970,6 +15324,17 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -3981,6 +15346,16 @@ "sshpk": "^1.7.0" } }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, "human-signals": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", @@ -4003,21 +15378,13 @@ "dev": true }, "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - } } }, "import-local": { @@ -4028,6 +15395,66 @@ "requires": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + } } }, "imurmurhash": { @@ -4052,25 +15479,15 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "inquirer": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", - "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", "dev": true, "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.5.3", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" } }, "ip-regex": { @@ -4080,23 +15497,12 @@ "dev": true }, "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "kind-of": "^6.0.0" } }, "is-arrayish": { @@ -4105,6 +15511,25 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -4112,9 +15537,9 @@ "dev": true }, "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", "dev": true }, "is-ci": { @@ -4126,63 +15551,58 @@ "ci-info": "^2.0.0" } }, + "is-core-module": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", + "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", + "requires": { + "has": "^1.0.3" + } + }, "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "kind-of": "^6.0.0" } }, "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "is-docker": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", - "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, "optional": true }, "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } }, "is-extglob": { "version": "2.1.1", @@ -4211,12 +15631,27 @@ "is-extglob": "^2.1.1" } }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -4227,45 +15662,43 @@ } }, "is-potential-custom-element-name": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", - "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", - "dev": true - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "requires": { - "has": "^1.0.3" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" } }, "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, "requires": { - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.2" } }, "is-typedarray": { @@ -4381,401 +15814,396 @@ } }, "javascript-stringify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.1.tgz", - "integrity": "sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", "dev": true }, "jest": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.0.1.tgz", - "integrity": "sha512-29Q54kn5Bm7ZGKIuH2JRmnKl85YRigp0o0asTc6Sb6l2ch1DCXIeZTLLFy9ultJvhkTqbswF5DEx4+RlkmCxWg==", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", + "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", + "dev": true, + "requires": { + "@jest/core": "^26.6.3", + "import-local": "^3.0.2", + "jest-cli": "^26.6.3" + } + }, + "jest-changed-files": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", + "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "execa": "^4.0.0", + "throat": "^5.0.0" + } + }, + "jest-circus": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-25.5.4.tgz", + "integrity": "sha512-nOLJXZjWuV2i8yQ2w+MZ8NhFuqrbgpPAa4mh+DWPYmNI377YYpDKvDUrLMW8U1sa2iGt5mjKQbmJz2SK9AYjWg==", "dev": true, "requires": { - "@jest/core": "^26.0.1", - "import-local": "^3.0.2", - "jest-cli": "^26.0.1" + "@babel/traverse": "^7.1.0", + "@jest/environment": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "co": "^4.6.0", + "expect": "^25.5.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^25.5.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0", + "stack-utils": "^1.0.1", + "throat": "^5.0.0" }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", "slash": "^3.0.0" } }, + "@jest/globals": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", + "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", + "dev": true, + "requires": { + "@jest/environment": "^25.5.0", + "@jest/types": "^25.5.0", + "expect": "^25.5.0" + } + }, + "@jest/source-map": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, + "@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^1.1.1", "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "chalk": "^3.0.0" } }, - "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" } }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", "dev": true }, - "jest-cli": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.0.1.tgz", - "integrity": "sha512-pFLfSOBcbG9iOZWaMK4Een+tTxi/Wcm34geqZEqrst9cZDkTQ1LZ2CnBrTlHWuYAiTMFr0EQeK52ScyFU8wK+w==", + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "@jest/core": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", - "prompts": "^2.0.1", - "yargs": "^15.3.1" + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" } }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^25.5.0", "@types/stack-utils": "^1.0.1", - "chalk": "^4.0.0", + "chalk": "^3.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "stack-utils": "^1.0.1" } }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "dev": true + }, + "jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" } }, - "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - } - } - } - }, - "jest-changed-files": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.0.1.tgz", - "integrity": "sha512-q8LP9Sint17HaE2LjxQXL+oYWW/WeeXMPE2+Op9X3mY8IEGFVc14xRxFjUuXUbcPAlDLhtWdIEt59GdQbn76Hw==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "execa": "^4.0.0", - "throat": "^5.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "jest-runtime": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", + "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/globals": "^25.5.2", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" } }, - "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "graceful-fs": "^4.2.4" } }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "jest-snapshot": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", "dev": true, "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "@babel/types": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", + "chalk": "^3.0.0", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^25.5.0", + "semver": "^6.3.0" } }, - "execa": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz", - "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==", + "jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "dev": true, "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" } }, - "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", "dev": true, "requires": { - "pump": "^3.0.0" + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" } }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", "dev": true, "requires": { - "path-key": "^3.0.0" + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" } }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "shebang-regex": "^3.0.0" + "p-locate": "^4.1.0" } }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": 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" - } - } - } - }, - "jest-circus": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-25.1.0.tgz", - "integrity": "sha512-Axlcr2YMxVarMW4SiZhCFCjNKhdF4xF9AIdltyutQOKyyDT795Kl/fzI95O0l8idE51Npj2wDj5GhrV7uEoEJA==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", - "co": "^4.6.0", - "expect": "^25.1.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^25.1.0", - "jest-matcher-utils": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-snapshot": "^25.1.0", - "jest-util": "^25.1.0", - "pretty-format": "^25.1.0", - "stack-utils": "^1.0.1", - "throat": "^5.0.0" - } - }, - "jest-config": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.0.1.tgz", - "integrity": "sha512-9mWKx2L1LFgOXlDsC4YSeavnblN6A4CPfXFiobq+YYLaBMymA/SczN7xYTSmLaEYHZOcB98UdoN4m5uNt6tztg==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.0.1", - "@jest/types": "^26.0.1", - "babel-jest": "^26.0.1", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.0.1", - "jest-environment-node": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-jasmine2": "^26.0.1", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", - "micromatch": "^4.0.2", - "pretty-format": "^26.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "p-try": "^2.0.0" } }, - "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "p-limit": "^2.2.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", - "dev": true - }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", - "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", - "slash": "^3.0.0" - } - }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } - }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, - "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - } + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true }, "read-pkg": { "version": "5.2.0", @@ -4808,687 +16236,807 @@ "type-fest": "^0.8.1" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true } } }, - "jest-diff": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.1.0.tgz", - "integrity": "sha512-nepXgajT+h017APJTreSieh4zCqnSHEJ1iT8HDlewu630lSJ4Kjjr9KNzm+kzGwwcpsDE6Snx1GJGzzsefaEHw==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.1.0", - "jest-get-type": "^25.1.0", - "pretty-format": "^25.1.0" - } - }, - "jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", - "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", + "jest-cli": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", + "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", "dev": true, "requires": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "jest-get-type": "^25.2.6", - "jest-util": "^25.5.0", - "pretty-format": "^25.5.0" + "@jest/core": "^26.6.3", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.6.3", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "prompts": "^2.0.1", + "yargs": "^15.4.1" }, "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "dev": true, + "optional": true, + "peer": true + }, + "acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", + "dev": true, + "optional": true, + "peer": true + }, + "jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" } }, "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^25.5.0", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "@cspotcode/source-map-support": "0.6.1", + "@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", + "yn": "3.1.1" } } } }, - "jest-environment-jsdom": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.0.1.tgz", - "integrity": "sha512-u88NJa3aptz2Xix2pFhihRBAatwZHWwSiRLBDBQE1cdJvDjPvv7ZGA0NQBxWwDDn7D0g1uHqxM8aGgfA9Bx49g==", + "jest-config": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.5.4.tgz", + "integrity": "sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==", "dev": true, "requires": { - "@jest/environment": "^26.0.1", - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1", - "jsdom": "^16.2.2" + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^25.5.4", + "@jest/types": "^25.5.0", + "babel-jest": "^25.5.1", + "chalk": "^3.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^25.5.0", + "jest-environment-node": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-jasmine2": "^25.5.4", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "micromatch": "^4.0.2", + "pretty-format": "^25.5.0", + "realpath-native": "^2.0.0" }, "dependencies": { - "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", - "dev": true, - "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" - } - }, - "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" - } - }, - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" } }, - "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "@jest/globals": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", + "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/environment": "^25.5.0", + "@jest/types": "^25.5.0", + "expect": "^25.5.0" } }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "@jest/source-map": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", - "chalk": "^4.0.0", + "callsites": "^3.0.0", "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "source-map": "^0.6.0" } }, - "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" } }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "@jest/test-sequencer": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz", + "integrity": "sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", + "@jest/test-result": "^25.5.0", "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } - }, - "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - } - } - } - }, - "jest-environment-node": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.0.1.tgz", - "integrity": "sha512-4FRBWcSn5yVo0KtNav7+5NH5Z/tEgDLp7VRQVS5tCouWORxj+nI+1tOLutM07Zb2Qi7ja+HEDoOUkjBSWZg/IQ==", - "dev": true, - "requires": { - "@jest/environment": "^26.0.1", - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" - }, - "dependencies": { - "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", - "dev": true, - "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "jest-haste-map": "^25.5.1", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4" } }, - "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^1.1.1", "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "chalk": "^3.0.0" } }, - "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" } }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", "dev": true }, - "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + } } }, - "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "dev": true + }, + "babel-jest": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", + "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" } }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "babel-plugin-jest-hoist": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", + "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" } }, - "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "babel-preset-current-node-syntax": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.4.tgz", + "integrity": "sha512-5/INNCYhUGqw7VbVjT/hb3ucjgkVHKXY7lX3ZjlN4gm565VyFmJUrJ/h+h16ECVB38R/9SF6aACydpKMLZ/c9w==", "dev": true, "requires": { - "escape-string-regexp": "^2.0.0" + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" } - } - } - }, - "jest-get-type": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", - "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==", - "dev": true - }, - "jest-haste-map": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.0.1.tgz", - "integrity": "sha512-J9kBl/EdjmDsvyv7CiyKY5+DsTvVOScenprz/fGqfLg/pm1gdjbwwQ98nW0t+OIt+f+5nAVaElvn/6wP5KO7KA==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "@types/graceful-fs": "^4.1.2", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", - "graceful-fs": "^4.2.4", - "jest-serializer": "^26.0.0", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7", - "which": "^2.0.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + }, + "babel-preset-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", + "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "babel-plugin-jest-hoist": "^25.5.0", + "babel-preset-current-node-syntax": "^0.1.2" } }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } - }, - "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" - } - } - } - }, - "jest-jasmine2": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.0.1.tgz", - "integrity": "sha512-ILaRyiWxiXOJ+RWTKupzQWwnPaeXPIoLS5uW41h18varJzd9/7I0QJGqg69fhTT1ev9JpSSo9QtalriUN0oqOg==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.0.1", - "@jest/source-map": "^26.0.0", - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^26.0.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^26.0.1", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-runtime": "^26.0.1", - "jest-snapshot": "^26.0.1", - "jest-util": "^26.0.1", - "pretty-format": "^26.0.1", - "throat": "^5.0.0" - }, - "dependencies": { - "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", - "slash": "^3.0.0" + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" } }, - "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", "dev": true, "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "webidl-conversions": "^4.0.2" } }, - "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" } }, - "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "whatwg-encoding": "^1.0.1" } }, - "@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", - "dev": true - }, - "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "jest-docblock": { + "version": "25.3.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.3.0.tgz", + "integrity": "sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "detect-newline": "^3.0.0" } }, - "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", - "dev": true - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "jest-environment-jsdom": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz", + "integrity": "sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-regex-util": "^26.0.0" + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "jsdom": "^15.2.1" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "jest-environment-node": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.5.0.tgz", + "integrity": "sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA==", "dev": true, "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "semver": "^6.3.0" } }, - "jest-each": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.0.1.tgz", - "integrity": "sha512-OTgJlwXCAR8NIWaXFL5DBbeS4QIYPuNASkzSwMCJO+ywo9BEa6TqkaSWsfR7VdbMLdgYJqSfQcIyjJCNwl5n4Q==", + "jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-util": "^26.0.1", - "pretty-format": "^26.0.1" + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" } }, - "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", - "dev": true - }, - "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "jest-jasmine2": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.5.4.tgz", + "integrity": "sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==", "dev": true, "requires": { - "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "@babel/traverse": "^7.1.0", + "@jest/environment": "^25.5.0", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "co": "^4.6.0", + "expect": "^25.5.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^25.5.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0", + "throat": "^5.0.0" + } + }, + "jest-leak-detector": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz", + "integrity": "sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA==", + "dev": true, + "requires": { + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" } }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^25.5.0", "@types/stack-utils": "^1.0.1", - "chalk": "^4.0.0", + "chalk": "^3.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", "slash": "^3.0.0", - "stack-utils": "^2.0.2" - } - }, - "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1" + "stack-utils": "^1.0.1" } }, "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", "dev": true }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", "graceful-fs": "^4.2.4", "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", "resolve": "^1.17.0", "slash": "^3.0.0" } }, + "jest-runner": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.5.4.tgz", + "integrity": "sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-docblock": "^25.3.0", + "jest-haste-map": "^25.5.1", + "jest-jasmine2": "^25.5.4", + "jest-leak-detector": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "jest-runtime": "^25.5.4", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + } + }, + "jest-runtime": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", + "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/globals": "^25.5.2", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + } + }, + "jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4" + } + }, "jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.0.1", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", + "chalk": "^3.0.0", + "expect": "^25.5.0", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", "make-dir": "^3.0.0", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", - "semver": "^7.3.2" + "pretty-format": "^25.5.0", + "semver": "^6.3.0" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" } }, - "parse-json": { + "jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" + } + }, + "jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "jsdom": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", + "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^7.1.0", + "acorn-globals": "^4.3.2", + "array-equal": "^1.0.0", + "cssom": "^0.4.1", + "cssstyle": "^2.0.0", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.1", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.2.0", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", + "saxes": "^3.1.9", + "symbol-tree": "^3.2.2", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^7.0.0", + "xml-name-validator": "^3.0.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" + "p-locate": "^4.1.0" } }, - "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" } }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -5520,182 +17068,136 @@ "type-fest": "^0.8.1" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "xmlchars": "^2.1.1" } }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, - "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", "dev": true, "requires": { - "escape-string-regexp": "^2.0.0" + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" } - } - } - }, - "jest-leak-detector": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.0.1.tgz", - "integrity": "sha512-93FR8tJhaYIWrWsbmVN1pQ9ZNlbgRpfvrnw5LmgLRX0ckOJ8ut/I35CL7awi2ecq6Ca4lL59bEK9hr7nqoHWPA==", - "dev": true, - "requires": { - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "punycode": "^2.1.0" } }, - "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "prelude-ls": "~1.1.2" } }, - "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true }, - "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" } - } - } - }, - "jest-matcher-utils": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.1.0.tgz", - "integrity": "sha512-KGOAFcSFbclXIFE7bS4C53iYobKI20ZWleAdAFun4W1Wz1Kkej8Ng6RRbhL8leaEvIOjGXhGf/a1JjO8bkxIWQ==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "jest-diff": "^25.1.0", - "jest-get-type": "^25.1.0", - "pretty-format": "^25.1.0" - } - }, - "jest-message-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", - "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true } } }, - "jest-mock": { + "jest-diff": { "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", - "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", "dev": true, "requires": { - "@jest/types": "^25.5.0" + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" }, "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } } } }, - "jest-pnp-resolver": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", - "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", - "dev": true - }, - "jest-regex-util": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", - "dev": true + "jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } }, - "jest-resolve": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", - "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "jest-each": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", + "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", "dev": true, "requires": { "@jest/types": "^25.5.0", - "browser-resolve": "^1.11.3", "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "read-pkg-up": "^7.0.1", - "realpath-native": "^2.0.0", - "resolve": "^1.17.0", - "slash": "^3.0.0" + "jest-get-type": "^25.2.6", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0" }, "dependencies": { "@jest/types": { @@ -5710,315 +17212,424 @@ "chalk": "^3.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } }, - "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "dev": true, "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + } + } + }, + "jest-environment-jsdom": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", + "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "dev": true, + "requires": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2", + "jsdom": "^16.4.0" + }, + "dependencies": { + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "@jest/types": "^26.6.2", + "@types/node": "*" } } } }, - "jest-resolve-dependencies": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.0.1.tgz", - "integrity": "sha512-9d5/RS/ft0vB/qy7jct/qAhzJsr6fRQJyGAFigK3XD4hf9kIbEH5gks4t4Z7kyMRhowU6HWm/o8ILqhaHdSqLw==", + "jest-environment-node": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", + "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.0.1" + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "dependencies": { - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, - "@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", - "dev": true - }, - "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, - "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", - "dev": true - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-regex-util": "^26.0.0" + "@jest/types": "^26.6.2", + "@types/node": "*" } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + } + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true + }, + "jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-jasmine2": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", + "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.6.2", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2", + "throat": "^5.0.0" + }, + "dependencies": { + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, - "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", - "dev": true - }, - "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, - "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "dev": true + }, + "expect": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" } }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true - }, - "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", - "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", - "slash": "^3.0.0" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, - "jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "jest-each": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", "dev": true, "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/prettier": "^2.0.0", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", - "expect": "^26.0.1", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", - "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", - "semver": "^7.3.2" + "jest-get-type": "^26.3.0", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" } }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true + }, + "jest-matcher-utils": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { - "@jest/types": "^26.0.1", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, - "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" + "@jest/types": "^26.6.2", + "@types/node": "*" } }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + } + } + }, + "jest-leak-detector": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", + "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "dev": true, + "requires": { + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" } }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + } + } + }, + "jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } + } + } + }, + "jest-message-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" } }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -6026,182 +17637,139 @@ } } }, - "jest-runner": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.0.1.tgz", - "integrity": "sha512-CApm0g81b49Znm4cZekYQK67zY7kkB4umOlI2Dx5CwKAzdgw75EN+ozBHRvxBzwo1ZLYZ07TFxkaPm+1t4d8jA==", + "jest-mock": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/environment": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.0.1", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.0.1", - "jest-jasmine2": "^26.0.1", - "jest-leak-detector": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "jest-runtime": "^26.0.1", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" + "@jest/types": "^25.5.0" }, "dependencies": { - "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", - "slash": "^3.0.0" - } - }, - "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", - "dev": true, - "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" - } - }, - "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" - } - }, - "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" } }, - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" } }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + } + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "requires": {} + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-resolve": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, - "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "p-locate": "^4.1.0" } }, - "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", - "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", - "slash": "^3.0.0" + "p-try": "^2.0.0" } }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "p-limit": "^2.2.0" } }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -6233,691 +17801,526 @@ "type-fest": "^0.8.1" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - } + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true } } }, - "jest-runtime": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.0.1.tgz", - "integrity": "sha512-Ci2QhYFmANg5qaXWf78T2Pfo6GtmIBn2rRaLnklRyEucmPccmCKvS9JPljcmtVamsdMmkyNkVFb9pBTD6si9Lw==", - "dev": true, - "requires": { - "@jest/console": "^26.0.1", - "@jest/environment": "^26.0.1", - "@jest/fake-timers": "^26.0.1", - "@jest/globals": "^26.0.1", - "@jest/source-map": "^26.0.0", - "@jest/test-result": "^26.0.1", - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", - "@types/yargs": "^15.0.0", + "jest-resolve-dependencies": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", + "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.6.2" + } + }, + "jest-runner": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", + "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", + "emittery": "^0.7.1", "exit": "^0.1.2", - "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-config": "^26.0.1", - "jest-haste-map": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.0.1", - "jest-snapshot": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.3.1" + "jest-config": "^26.6.3", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.6.2", + "jest-leak-detector": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" }, "dependencies": { - "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", - "slash": "^3.0.0" - } - }, "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, - "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", "dev": true, - "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } + "optional": true, + "peer": true }, - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", - "dev": true + "optional": true, + "peer": true }, - "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" } }, - "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", - "dev": true - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, - "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-regex-util": "^26.0.0" + "@jest/types": "^26.6.2", + "@types/node": "*" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" } }, - "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" - } - }, - "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "optional": true, + "peer": true, + "requires": { + "@cspotcode/source-map-support": "0.6.1", + "@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", + "yn": "3.1.1" } - }, - "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + } + } + }, + "jest-runtime": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", + "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/globals": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^0.6.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.4.1" + }, + "dependencies": { + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true - }, - "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", - "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", - "slash": "^3.0.0" + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, - "jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", "dev": true, - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.0.1", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", - "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", - "semver": "^7.3.2" - } + "optional": true, + "peer": true }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", + "dev": true, + "optional": true, + "peer": true + }, + "jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" } }, - "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true + }, + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" + "@jest/types": "^26.6.2", + "@types/node": "*" } }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - } - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" + "react-is": "^17.0.1" } }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" + "optional": true, + "peer": true, + "requires": { + "@cspotcode/source-map-support": "0.6.1", + "@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", + "yn": "3.1.1" } } } }, "jest-serializer": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.0.0.tgz", - "integrity": "sha512-sQGXLdEGWFAE4wIJ2ZaIDb+ikETlUirEOBsLXdoBbeLhTHkZUJwgk3+M8eyFizhM6le43PDCCKPA1hzkSDo4cQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", "dev": true, "requires": { + "@types/node": "*", "graceful-fs": "^4.2.4" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } } }, "jest-snapshot": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", - "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/prettier": "^1.19.0", - "chalk": "^3.0.0", - "expect": "^25.5.0", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "jest-matcher-utils": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-resolve": "^25.5.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^25.5.0", - "semver": "^6.3.0" + "pretty-format": "^26.6.2", + "semver": "^7.3.2" }, "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, "diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true + "expect": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" + } }, "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^25.5.0", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true } } }, "jest-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", - "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } + "micromatch": "^4.0.2" } }, "jest-validate": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.0.1.tgz", - "integrity": "sha512-u0xRc+rbmov/VqXnX3DlkxD74rHI/CfS5xaV2VpeaVySjbb1JioNVOyly5b56q2l9ZKe7bVG5qWmjfctkQb0bA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "camelcase": "^6.0.0", "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", + "jest-get-type": "^26.3.0", "leven": "^3.1.0", - "pretty-format": "^26.0.1" + "pretty-format": "^26.6.2" }, "dependencies": { - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, "camelcase": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", - "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true }, - "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true } } }, "jest-watcher": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.0.1.tgz", - "integrity": "sha512-pdZPydsS8475f89kGswaNsN3rhP6lnC3/QDCppP7bg1L9JQz7oU9Mb/5xPETk1RHDCWeqmVC47M4K5RR7ejxFw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", + "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", "dev": true, "requires": { - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^26.0.1", + "jest-util": "^26.6.2", "string-length": "^4.0.1" - }, - "dependencies": { - "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", - "slash": "^3.0.0" - } - }, - "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", - "dev": true, - "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - } - }, - "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } - }, - "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - } - } } }, "jest-worker": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz", - "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, "requires": { + "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^7.0.0" } @@ -6929,9 +18332,9 @@ "dev": true }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -6945,37 +18348,46 @@ "dev": true }, "jsdom": { - "version": "16.2.2", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.2.2.tgz", - "integrity": "sha512-pDFQbcYtKBHxRaP55zGXCJWgFHkDAYbKcsXEK/3Icu9nKYZkutUXfLBwbD+09XDutkYSHcgfQLZ0qvpAAm9mvg==", + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "dev": true, "requires": { - "abab": "^2.0.3", - "acorn": "^7.1.1", + "abab": "^2.0.5", + "acorn": "^8.2.4", "acorn-globals": "^6.0.0", "cssom": "^0.4.4", - "cssstyle": "^2.2.0", + "cssstyle": "^2.3.0", "data-urls": "^2.0.0", - "decimal.js": "^10.2.0", + "decimal.js": "^10.2.1", "domexception": "^2.0.1", - "escodegen": "^1.14.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", "html-encoding-sniffer": "^2.0.1", - "is-potential-custom-element-name": "^1.0.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", "nwsapi": "^2.2.0", - "parse5": "5.1.1", - "request": "^2.88.2", - "request-promise-native": "^1.0.8", - "saxes": "^5.0.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", "symbol-tree": "^3.2.4", - "tough-cookie": "^3.0.1", + "tough-cookie": "^4.0.0", "w3c-hr-time": "^1.0.2", "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.0.0", + "webidl-conversions": "^6.1.0", "whatwg-encoding": "^1.0.5", "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0", - "ws": "^7.2.3", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "dev": true + } } }, "jsesc": { @@ -6990,6 +18402,12 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -7015,9 +18433,9 @@ "dev": true }, "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -7063,13 +18481,13 @@ "dev": true }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "lines-and-columns": { @@ -7079,14 +18497,14 @@ "dev": true }, "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", + "parse-json": "^4.0.0", + "pify": "^3.0.0", "strip-bom": "^3.0.0" }, "dependencies": { @@ -7099,24 +18517,31 @@ } }, "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { - "p-locate": "^4.1.0" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, "lodash.sortby": { @@ -7125,6 +18550,12 @@ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, "lolex": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", @@ -7134,10 +18565,28 @@ "@sinonjs/commons": "^1.7.0" } }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "lua-types": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.8.0.tgz", - "integrity": "sha512-FJY32giHIqD/XW1XGkJnl8XotXIJsJ2M42fj9A2UudttWA6orJioToW1OpgPdayTr+S1/oTO7i+hfBY3UVG8Fg==", + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.10.1.tgz", + "integrity": "sha512-Ai7L25I5kHZYGN5C3LALUse7Eus0k/kM9tEO2zwReG2Xuker0c+0e2M4iyfiEvlGOmBc7cDouqJ5lFwyg8JqiQ==", + "dev": true, + "requires": { + "typescript-to-lua": "^0.39.0" + } + }, + "lua-wasm-bindings": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.2.tgz", + "integrity": "sha512-Z2v3An8jEvYbhUJ/gYxNd65ZBbaRyPMmUaleDoOhzJSIGrMgjURvy1EtHtgRGTzdtpmKtHA+YYKDrSZBE9g/ig==", "dev": true }, "make-dir": { @@ -7193,29 +18642,35 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "requires": { "braces": "^3.0.1", - "picomatch": "^2.0.5" + "picomatch": "^2.2.3" } }, "mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", "dev": true }, "mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", "dev": true, "requires": { - "mime-db": "1.44.0" + "mime-db": "1.49.0" } }, "mimic-fn": { @@ -7247,27 +18702,13 @@ "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } } }, "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true }, "ms": { "version": "2.1.2", @@ -7275,12 +18716,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -7325,39 +18760,26 @@ "dev": true }, "node-notifier": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.1.tgz", - "integrity": "sha512-VkzhierE7DBmQEElhTGJIoiZa1oqRijOtgOlsXg32KrJRXsPy0NXFBqWGW/wTswnJlDCs5viRYaqWguqzsKcmg==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", + "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", "dev": true, "optional": true, "requires": { "growly": "^1.3.0", - "is-wsl": "^2.1.1", - "semver": "^7.2.1", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", "shellwords": "^0.1.1", - "uuid": "^7.0.3", + "uuid": "^8.3.0", "which": "^2.0.2" - }, - "dependencies": { - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true, - "optional": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "optional": true, - "requires": { - "isexe": "^2.0.0" - } - } } }, + "node-releases": { + "version": "1.1.75", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", + "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==", + "dev": true + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -7368,6 +18790,14 @@ "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } } }, "normalize-path": { @@ -7377,12 +18807,12 @@ "dev": true }, "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "requires": { - "path-key": "^2.0.0" + "path-key": "^3.0.0" } }, "nwsapi": { @@ -7417,6 +18847,43 @@ "is-descriptor": "^0.1.0" } }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -7429,9 +18896,9 @@ } }, "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", "dev": true }, "object-keys": { @@ -7450,15 +18917,15 @@ } }, "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" } }, "object.pick": { @@ -7471,15 +18938,14 @@ } }, "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", "dev": true, "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" + "es-abstract": "^1.18.2" } }, "once": { @@ -7492,38 +18958,32 @@ } }, "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { "mimic-fn": "^2.1.0" } }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, "p-each-series": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", - "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", + "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", "dev": true }, "p-finally": { @@ -7533,27 +18993,27 @@ "dev": true }, "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, "requires": { - "p-try": "^2.0.0" + "p-try": "^1.0.0" } }, "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { - "p-limit": "^2.2.0" + "p-limit": "^1.1.0" } }, "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, "parent-module": { @@ -7566,18 +19026,19 @@ } }, "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { - "error-ex": "^1.2.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" } }, "parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, "pascalcase": { @@ -7587,9 +19048,9 @@ "dev": true }, "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "path-is-absolute": { @@ -7599,24 +19060,21 @@ "dev": true }, "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true }, "performance-now": { "version": "2.1.0", @@ -7625,15 +19083,15 @@ "dev": true }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, "pirates": { @@ -7646,14 +19104,29 @@ } }, "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", "dev": true, "requires": { - "find-up": "^4.0.0" + "find-up": "^2.1.0" + } + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "dev": true, + "requires": { + "find-up": "^2.1.0" } }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -7661,27 +19134,61 @@ "dev": true }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prettier": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", - "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", "dev": true }, "pretty-format": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", - "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", "dev": true, "requires": { - "@jest/types": "^25.1.0", + "@jest/types": "^25.5.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } } }, "progress": { @@ -7691,13 +19198,13 @@ "dev": true }, "prompts": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", - "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", + "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", "dev": true, "requires": { "kleur": "^3.0.3", - "sisteransi": "^1.0.4" + "sisteransi": "^1.0.5" } }, "psl": { @@ -7723,94 +19230,54 @@ "dev": true }, "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "dependencies": { + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { - "p-limit": "^1.1.0" + "pify": "^3.0.0" } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true } } }, - "readline-sync": { - "version": "1.4.9", - "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz", - "integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No=", - "dev": true + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } }, "realpath-native": { "version": "2.0.0", @@ -7829,9 +19296,9 @@ } }, "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "remove-trailing-separator": { @@ -7841,9 +19308,9 @@ "dev": true }, "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", "dev": true }, "repeat-string": { @@ -7880,6 +19347,17 @@ "uuid": "^3.3.2" }, "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -7899,21 +19377,21 @@ } }, "request-promise-core": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", - "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", "dev": true, "requires": { - "lodash": "^4.17.15" + "lodash": "^4.17.19" } }, "request-promise-native": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", - "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", "dev": true, "requires": { - "request-promise-core": "1.1.3", + "request-promise-core": "1.1.4", "stealthy-require": "^1.1.1", "tough-cookie": "^2.3.3" }, @@ -7936,6 +19414,12 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -7943,10 +19427,11 @@ "dev": true }, "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "requires": { + "is-core-module": "^2.2.0", "path-parse": "^1.0.6" } }, @@ -7957,12 +19442,20 @@ "dev": true, "requires": { "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } } }, "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "resolve-url": { @@ -7971,22 +19464,18 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -8002,22 +19491,13 @@ "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", "dev": true }, - "run-async": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", - "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, - "rxjs": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", - "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "requires": { - "tslib": "^1.9.0" + "queue-microtask": "^1.2.2" } }, "safe-buffer": { @@ -8097,6 +19577,34 @@ } } }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -8120,6 +19628,21 @@ } } }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -8140,6 +19663,12 @@ } } }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -8170,6 +19699,42 @@ "remove-trailing-separator": "^1.0.1" } }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, "to-regex-range": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", @@ -8179,6 +19744,15 @@ "is-number": "^3.0.0", "repeat-string": "^1.6.1" } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -8192,10 +19766,13 @@ } }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "set-blocking": { "version": "2.0.0", @@ -8223,22 +19800,28 @@ "requires": { "is-extendable": "^0.1.0" } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true } } }, "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" } }, "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "shellwords": { @@ -8248,10 +19831,21 @@ "dev": true, "optional": true }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, "sisteransi": { @@ -8267,46 +19861,14 @@ "dev": true }, "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - } + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" } }, "snapdragon": { @@ -8352,6 +19914,69 @@ "is-extendable": "^0.1.0" } }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -8375,44 +20000,15 @@ "define-property": "^1.0.0", "isobject": "^3.0.0", "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-descriptor": "^1.0.0" } } } @@ -8456,9 +20052,9 @@ } }, "source-map-support": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", - "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -8474,15 +20070,15 @@ } }, "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", "dev": true }, "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -8490,15 +20086,15 @@ } }, "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", @@ -8506,9 +20102,9 @@ } }, "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", + "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", "dev": true }, "split-string": { @@ -8521,9 +20117,9 @@ } }, "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, "sshpk": { @@ -8544,10 +20140,21 @@ } }, "stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", - "dev": true + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } }, "static-extend": { "version": "0.1.2", @@ -8567,6 +20174,63 @@ "requires": { "is-descriptor": "^0.1.0" } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, @@ -8577,9 +20241,9 @@ "dev": true }, "string-length": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", - "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "requires": { "char-regex": "^1.0.2", @@ -8587,9 +20251,9 @@ } }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -8597,24 +20261,24 @@ "strip-ansi": "^6.0.0" } }, - "string.prototype.trimleft": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", - "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, - "string.prototype.trimright": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", - "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, "strip-ansi": { @@ -8645,24 +20309,24 @@ "dev": true }, "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "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 }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } }, "supports-hyperlinks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", - "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", "dev": true, "requires": { "has-flag": "^4.0.0", @@ -8676,57 +20340,44 @@ "dev": true }, "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "ajv": { + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", + "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true } } }, + "tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" + }, "terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -8760,21 +20411,6 @@ "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", "dev": true }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -8829,80 +20465,85 @@ } }, "tough-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", - "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", "dev": true, "requires": { - "ip-regex": "^2.1.0", - "psl": "^1.1.28", - "punycode": "^2.1.1" + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" } }, "tr46": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", - "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", "dev": true, "requires": { "punycode": "^2.1.1" } }, "ts-jest": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.0.0.tgz", - "integrity": "sha512-eBpWH65mGgzobuw7UZy+uPP9lwu+tPp60o324ASRX4Ijg8UC5dl2zcge4kkmqr2Zeuk9FwIjvCTOPuNMEyGWWw==", + "version": "26.5.6", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.6.tgz", + "integrity": "sha512-rua+rCP8DxpA8b4DQD/6X2HQS8Zy/xzViVYfEs2OQu68tkCuKLV0Md8pmX55+W24uRIyAsf/BajRfxOs+R2MKA==", "dev": true, "requires": { "bs-logger": "0.x", "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", + "jest-util": "^26.1.0", "json5": "2.x", - "lodash.memoize": "4.x", + "lodash": "4.x", "make-error": "1.x", - "micromatch": "4.x", "mkdirp": "1.x", "semver": "7.x", - "yargs-parser": "18.x" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - } + "yargs-parser": "20.x" } }, "ts-node": { - "version": "8.6.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.6.2.tgz", - "integrity": "sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg==", + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", "dev": true, "requires": { "arg": "^4.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "source-map-support": "^0.5.6", + "source-map-support": "^0.5.17", "yn": "3.1.1" } }, + "tsconfig-paths": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", + "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", + "dev": true, + "requires": { + "json5": "^2.2.0", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, "tslib": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.0.tgz", - "integrity": "sha512-BmndXUtiTn/VDDrJzQE7Mm22Ix3PxgLltW9bSNLoeCY31gnG2OPx0QqJnuc9oMIKioYrz487i6K9o4Pdn0j+Kg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, "tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -8924,12 +20565,12 @@ "dev": true }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" } }, "type-detect": { @@ -8939,9 +20580,9 @@ "dev": true }, "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, "typedarray-to-buffer": { @@ -8954,9 +20595,32 @@ } }, "typescript": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.2.tgz", - "integrity": "sha512-q2ktq4n/uLuNNShyayit+DTobV2ApPEo/6so68JaD5ojvc/6GClBipedB9zNWYxRSAlZXAe405Rlijzl6qDiSw==" + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==" + }, + "typescript-to-lua": { + "version": "0.39.6", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-0.39.6.tgz", + "integrity": "sha512-Yq+XsmFKknMlz9jm1FvTw5B7R4H8lYUly4uwxlR44aT4OFyG9S7mOImrTIF07j414PdrJSQ5dAAhQOBVRqHbMw==", + "dev": true, + "requires": { + "resolve": "^1.15.1", + "source-map": "^0.7.3", + "typescript": "~4.3.2" + } + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } }, "union-value": { "version": "1.0.1", @@ -8968,6 +20632,14 @@ "get-value": "^2.0.6", "is-extendable": "^0.1.1", "set-value": "^2.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + } } }, "universalify": { @@ -9017,9 +20689,9 @@ } }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "requires": { "punycode": "^2.1.0" @@ -9038,22 +20710,22 @@ "dev": true }, "uuid": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", - "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, "optional": true }, "v8-compile-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", - "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, "v8-to-istanbul": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", - "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", + "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -9131,33 +20803,38 @@ "dev": true }, "whatwg-url": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", - "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", "dev": true, "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^2.0.2", - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" } }, "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "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-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -9187,15 +20864,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", @@ -9209,10 +20877,11 @@ } }, "ws": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", - "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", - "dev": true + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", + "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", + "dev": true, + "requires": {} }, "xml-name-validator": { "version": "3.0.0", @@ -9227,15 +20896,21 @@ "dev": true }, "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "yargs": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", - "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, "requires": { "cliui": "^6.0.0", @@ -9248,18 +20923,75 @@ "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^18.1.1" + "yargs-parser": "^18.1.2" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } } }, "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true }, "yn": { "version": "3.1.1", diff --git a/package.json b/package.json index 744d4571b..d80bb1a36 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.35.0", + "version": "1.0.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", + "homepage": "https://typescripttolua.github.io/", + "bugs": { + "url": "https://github.com/TypeScriptToLua/TypeScriptToLua/issues" + }, "license": "MIT", "keywords": [ "typescript", @@ -13,32 +17,35 @@ "files": [ "dist/**/*.js", "dist/**/*.lua", - "dist/**/*.ts" + "dist/**/*.ts", + "language-extensions/**/*.ts" ], "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { "build": "tsc && npm run build-lualib", "build-lualib": "node build-lualib.js", - "pretest": "npm run lint && npm run build-lualib", + "pretest": "npm run lint && npm run check:language-extensions && npm run build-lualib", "test": "jest", "lint": "npm run lint:eslint && npm run lint:prettier", "lint:prettier": "prettier --check . || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", "lint:eslint": "eslint . --ext .js,.ts", "fix:prettier": "prettier --write .", + "check:language-extensions": "tsc language-extensions/index.d.ts", "preversion": "npm run build && npm test", "postversion": "git push && git push --tags" }, "bin": { - "tstl": "./dist/tstl.js" + "tstl": "dist/tstl.js" }, "engines": { "node": ">=12.13.0" }, "dependencies": { + "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", "source-map": "^0.7.3", - "typescript": "^3.9.2" + "typescript": "~4.3.5" }, "devDependencies": { "@types/fs-extra": "^8.1.0", @@ -46,19 +53,19 @@ "@types/jest": "^25.1.3", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^2.31.0", - "@typescript-eslint/parser": "^2.31.0", - "eslint": "^6.8.0", + "@typescript-eslint/eslint-plugin": "^4.26.1", + "@typescript-eslint/parser": "^4.26.1", + "eslint": "^7.28.0", "eslint-plugin-import": "^2.20.1", "eslint-plugin-jest": "^23.8.2", - "fengari": "^0.1.4", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^26.0.1", "jest-circus": "^25.1.0", - "lua-types": "^2.8.0", - "prettier": "^2.0.5", - "ts-jest": "^26.0.0", + "lua-types": "2.10.1", + "lua-wasm-bindings": "^0.2.2", + "prettier": "^2.3.2", + "ts-jest": "^26.3.0", "ts-node": "^8.6.2" } } diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 2e78b2b87..9fc232f68 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -1,13 +1,10 @@ import * as ts from "typescript"; +import { JsxEmit } from "typescript"; import * as diagnosticFactories from "./transpilation/diagnostics"; -type KnownKeys = { [K in keyof T]: string extends K ? never : number extends K ? never : K } extends { - [K in keyof T]: infer U; -} - ? U - : never; - -type OmitIndexSignature> = Pick>; +type OmitIndexSignature = { + [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K]; +}; export interface TransformerImport { transform: string; @@ -21,9 +18,11 @@ export interface TransformerImport { export interface LuaPluginImport { name: string; import?: string; + [option: string]: any; } export type CompilerOptions = OmitIndexSignature & { + buildMode?: BuildMode; noImplicitSelf?: boolean; noHeader?: boolean; luaBundle?: string; @@ -33,6 +32,7 @@ export type CompilerOptions = OmitIndexSignature & { sourceMapTraceback?: boolean; luaPlugins?: LuaPluginImport[]; plugins?: Array; + tstlVerbose?: boolean; [option: string]: any; }; @@ -48,9 +48,15 @@ export enum LuaTarget { Lua51 = "5.1", Lua52 = "5.2", Lua53 = "5.3", + Lua54 = "5.4", LuaJIT = "JIT", } +export enum BuildMode { + Default = "default", + Library = "library", +} + export const isBundleEnabled = (options: CompilerOptions) => options.luaBundle !== undefined && options.luaBundleEntry !== undefined; @@ -65,5 +71,13 @@ export function validateOptions(options: CompilerOptions): ts.Diagnostic[] { diagnostics.push(diagnosticFactories.usingLuaBundleWithInlineMightGenerateDuplicateCode()); } + if (options.luaBundle && options.buildMode === BuildMode.Library) { + diagnostics.push(diagnosticFactories.cannotBundleLibrary()); + } + + if (options.jsx && options.jsx !== JsxEmit.React) { + diagnostics.push(diagnosticFactories.unsupportedJsxEmit()); + } + return diagnostics; } diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 99af02718..1ac86d3f5 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -5,9 +5,11 @@ // because we don't create the AST from text import * as ts from "typescript"; +import { LuaLibFeature } from "./transformation/utils/lualib"; import { castArray } from "./utils"; export enum SyntaxKind { + File, Block, // Statements @@ -172,10 +174,12 @@ export function setNodeOriginal(node: T | undefined, tsOriginal: } function getSourcePosition(sourceNode: ts.Node): TextRange | undefined { - if (sourceNode.getSourceFile() !== undefined && sourceNode.pos >= 0) { + const parseTreeNode = ts.getParseTreeNode(sourceNode) ?? sourceNode; + const sourceFile = parseTreeNode.getSourceFile(); + if (sourceFile !== undefined && parseTreeNode.pos >= 0) { const { line, character } = ts.getLineAndCharacterOfPosition( - sourceNode.getSourceFile(), - sourceNode.pos + sourceNode.getLeadingTriviaWidth() + sourceFile, + parseTreeNode.pos + parseTreeNode.getLeadingTriviaWidth() ); return { line, column: character }; @@ -186,6 +190,30 @@ export function getOriginalPos(node: Node): TextRange { return { line: node.line, column: node.column }; } +export interface File extends Node { + kind: SyntaxKind.File; + statements: Statement[]; + luaLibFeatures: Set; + trivia: string; +} + +export function isFile(node: Node): node is File { + return node.kind === SyntaxKind.File; +} + +export function createFile( + statements: Statement[], + luaLibFeatures: Set, + trivia: string, + tsOriginal?: ts.Node +): File { + const file = createNode(SyntaxKind.File, tsOriginal) as File; + file.statements = statements; + file.luaLibFeatures = luaLibFeatures; + file.trivia = trivia; + return file; +} + export interface Block extends Node { kind: SyntaxKind.Block; statements: Statement[]; @@ -203,6 +231,8 @@ export function createBlock(statements: Statement[], tsOriginal?: ts.Node): Bloc export interface Statement extends Node { _statementBrand: any; + leadingComments?: Array; + trailingComments?: Array; } export interface DoStatement extends Statement { @@ -776,7 +806,7 @@ export function isInlineFunctionExpression(expression: FunctionExpression): expr return ( expression.body.statements?.length === 1 && isReturnStatement(expression.body.statements[0]) && - (expression.body.statements[0] as ReturnStatement).expressions !== undefined && + expression.body.statements[0].expressions !== undefined && (expression.flags & FunctionExpressionFlags.Inline) !== 0 ); } diff --git a/src/LuaLib.ts b/src/LuaLib.ts index c476882c7..9c50019f5 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -3,6 +3,7 @@ import { EmitHost } from "./transpilation"; export enum LuaLibFeature { ArrayConcat = "ArrayConcat", + ArrayEntries = "ArrayEntries", ArrayEvery = "ArrayEvery", ArrayFilter = "ArrayFilter", ArrayForEach = "ArrayForEach", @@ -10,6 +11,7 @@ export enum LuaLibFeature { ArrayFindIndex = "ArrayFindIndex", ArrayIncludes = "ArrayIncludes", ArrayIndexOf = "ArrayIndexOf", + ArrayIsArray = "ArrayIsArray", ArrayJoin = "ArrayJoin", ArrayMap = "ArrayMap", ArrayPush = "ArrayPush", @@ -26,10 +28,14 @@ export enum LuaLibFeature { ArrayFlat = "ArrayFlat", ArrayFlatMap = "ArrayFlatMap", ArraySetLength = "ArraySetLength", + Await = "Await", Class = "Class", ClassExtends = "ClassExtends", + CloneDescriptor = "CloneDescriptor", Decorate = "Decorate", - Descriptors = "Descriptors", + DecorateParam = "DecorateParam", + Delete = "Delete", + DelegatedYield = "DelegatedYield", Error = "Error", FunctionBind = "FunctionBind", Generator = "Generator", @@ -44,12 +50,26 @@ export enum LuaLibFeature { NumberIsNaN = "NumberIsNaN", NumberToString = "NumberToString", ObjectAssign = "ObjectAssign", + ObjectDefineProperty = "ObjectDefineProperty", ObjectEntries = "ObjectEntries", ObjectFromEntries = "ObjectFromEntries", + ObjectGetOwnPropertyDescriptor = "ObjectGetOwnPropertyDescriptor", + ObjectGetOwnPropertyDescriptors = "ObjectGetOwnPropertyDescriptors", ObjectKeys = "ObjectKeys", ObjectRest = "ObjectRest", ObjectValues = "ObjectValues", + OptionalChainAccess = "OptionalChainAccess", + OptionalFunctionCall = "OptionalFunctionCall", + OptionalMethodCall = "OptionalMethodCall", + ParseFloat = "ParseFloat", + ParseInt = "ParseInt", + Promise = "Promise", + PromiseAll = "PromiseAll", + PromiseAllSettled = "PromiseAllSettled", + PromiseAny = "PromiseAny", + PromiseRace = "PromiseRace", Set = "Set", + SetDescriptor = "SetDescriptor", WeakMap = "WeakMap", WeakSet = "WeakSet", SourceMapTraceBack = "SourceMapTraceBack", @@ -59,6 +79,7 @@ export enum LuaLibFeature { StringCharCodeAt = "StringCharCodeAt", StringConcat = "StringConcat", StringEndsWith = "StringEndsWith", + StringIncludes = "StringIncludes", StringPadEnd = "StringPadEnd", StringPadStart = "StringPadStart", StringReplace = "StringReplace", @@ -76,22 +97,59 @@ export enum LuaLibFeature { Unpack = "Unpack", } +/* eslint-disable @typescript-eslint/naming-convention */ const luaLibDependencies: Partial> = { - ArrayFlat: [LuaLibFeature.ArrayConcat], - ArrayFlatMap: [LuaLibFeature.ArrayConcat], - Error: [LuaLibFeature.New, LuaLibFeature.Class], + ArrayConcat: [LuaLibFeature.ArrayIsArray], + ArrayFlat: [LuaLibFeature.ArrayConcat, LuaLibFeature.ArrayIsArray], + ArrayFlatMap: [LuaLibFeature.ArrayConcat, LuaLibFeature.ArrayIsArray], + Await: [LuaLibFeature.InstanceOf, LuaLibFeature.New], + Decorate: [LuaLibFeature.ObjectGetOwnPropertyDescriptor, LuaLibFeature.SetDescriptor, LuaLibFeature.ObjectAssign], + DelegatedYield: [LuaLibFeature.StringAccess], + Delete: [LuaLibFeature.ObjectGetOwnPropertyDescriptors], + Error: [LuaLibFeature.Class, LuaLibFeature.ClassExtends, LuaLibFeature.New], FunctionBind: [LuaLibFeature.Unpack], Generator: [LuaLibFeature.Symbol], InstanceOf: [LuaLibFeature.Symbol], Iterator: [LuaLibFeature.Symbol], + NumberToString: [LuaLibFeature.StringAccess], + ObjectDefineProperty: [LuaLibFeature.CloneDescriptor, LuaLibFeature.SetDescriptor], ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol], + Promise: [ + LuaLibFeature.ArrayPush, + LuaLibFeature.Class, + LuaLibFeature.FunctionBind, + LuaLibFeature.InstanceOf, + LuaLibFeature.New, + ], + PromiseAll: [LuaLibFeature.InstanceOf, LuaLibFeature.New, LuaLibFeature.Promise, LuaLibFeature.Iterator], + PromiseAllSettled: [LuaLibFeature.InstanceOf, LuaLibFeature.New, LuaLibFeature.Promise, LuaLibFeature.Iterator], + PromiseAny: [ + LuaLibFeature.ArrayPush, + LuaLibFeature.InstanceOf, + LuaLibFeature.New, + LuaLibFeature.Promise, + LuaLibFeature.Iterator, + ], + PromiseRace: [ + LuaLibFeature.ArrayPush, + LuaLibFeature.InstanceOf, + LuaLibFeature.New, + LuaLibFeature.Promise, + LuaLibFeature.Iterator, + ], + ParseFloat: [LuaLibFeature.StringAccess], + ParseInt: [LuaLibFeature.StringSubstr, LuaLibFeature.StringSubstring], + SetDescriptor: [LuaLibFeature.CloneDescriptor], + Spread: [LuaLibFeature.Iterator, LuaLibFeature.StringAccess, LuaLibFeature.Unpack], + StringSplit: [LuaLibFeature.StringSubstring, LuaLibFeature.StringAccess], + SymbolRegistry: [LuaLibFeature.Symbol], + Map: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], Set: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], WeakMap: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], WeakSet: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], - Spread: [LuaLibFeature.Iterator, LuaLibFeature.Unpack], - SymbolRegistry: [LuaLibFeature.Symbol], }; +/* eslint-enable @typescript-eslint/naming-convention */ export function loadLuaLibFeatures(features: Iterable, emitHost: EmitHost): string { let result = ""; diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 63654c595..390b62977 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,4 +1,3 @@ -import * as path from "path"; import { Mapping, SourceMapGenerator, SourceNode } from "source-map"; import * as ts from "typescript"; import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; @@ -6,7 +5,7 @@ import * as lua from "./LuaAST"; import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; import { isValidLuaIdentifier } from "./transformation/utils/safe-names"; import { EmitHost } from "./transpilation"; -import { intersperse, trimExtension, normalizeSlashes } from "./utils"; +import { intersperse, trimExtension } from "./utils"; // https://www.lua.org/pil/2.4.html // https://www.ecma-international.org/ecma-262/10.0/index.html#table-34 @@ -25,6 +24,8 @@ const escapeStringMap: Record = { export const escapeString = (value: string) => `"${value.replace(escapeStringRegExp, char => escapeStringMap[char])}"`; +export const tstlHeader = "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n"; + /** * Checks that a name is valid for use in lua function declaration syntax: * @@ -71,13 +72,7 @@ function isSimpleExpression(expression: lua.Expression): boolean { type SourceChunk = string | SourceNode; -export type Printer = ( - program: ts.Program, - emitHost: EmitHost, - fileName: string, - block: lua.Block, - luaLibFeatures: Set -) => PrintResult; +export type Printer = (program: ts.Program, emitHost: EmitHost, fileName: string, file: lua.File) => PrintResult; export interface PrintResult { code: string; @@ -87,7 +82,7 @@ export interface PrintResult { export function createPrinter(printers: Printer[]): Printer { if (printers.length === 0) { - return (program, emitHost, fileName, ...args) => new LuaPrinter(emitHost, program, fileName).print(...args); + return (program, emitHost, fileName, file) => new LuaPrinter(emitHost, program, fileName).print(file); } else if (printers.length === 1) { return printers[0]; } else { @@ -130,35 +125,20 @@ export class LuaPrinter { constructor(private emitHost: EmitHost, program: ts.Program, fileName: string) { this.options = program.getCompilerOptions(); - - if (this.options.outDir) { - const relativeFileName = path.relative(program.getCommonSourceDirectory(), fileName); - if (this.options.sourceRoot) { - // When sourceRoot is specified, just use relative path inside rootDir - this.sourceFile = relativeFileName; - } else { - // Calculate relative path from rootDir to outDir - const outputPath = path.resolve(this.options.outDir, relativeFileName); - this.sourceFile = path.relative(path.dirname(outputPath), fileName); - } - // We want forward slashes, even in windows - this.sourceFile = normalizeSlashes(this.sourceFile); - } else { - this.sourceFile = path.basename(fileName); // File will be in same dir as source - } + this.sourceFile = fileName; } - public print(block: lua.Block, luaLibFeatures: Set): PrintResult { + public print(file: lua.File): PrintResult { // Add traceback lualib if sourcemap traceback option is enabled if (this.options.sourceMapTraceback) { - luaLibFeatures.add(LuaLibFeature.SourceMapTraceBack); + file.luaLibFeatures.add(LuaLibFeature.SourceMapTraceBack); } const sourceRoot = this.options.sourceRoot ? // According to spec, sourceRoot is simply prepended to the source name, so the slash should be included - this.options.sourceRoot.replace(/[\\/]+$/, "") + "/" + `${this.options.sourceRoot.replace(/[\\/]+$/, "")}/` : ""; - const rootSourceNode = this.printImplementation(block, luaLibFeatures); + const rootSourceNode = this.printFile(file); const sourceMap = this.buildSourceMap(sourceRoot, rootSourceNode); let code = rootSourceNode.toString(); @@ -203,33 +183,31 @@ export class LuaPrinter { return `__TS__SourceMapTraceBack(debug.getinfo(1).short_src, ${mapString});`; } - private printImplementation(block: lua.Block, luaLibFeatures: Set): SourceNode { - let header = ""; + private printFile(file: lua.File): SourceNode { + let header = file.trivia; if (!this.options.noHeader) { - header += "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n"; + header += tstlHeader; } const luaLibImport = this.options.luaLibImport ?? LuaLibImportKind.Require; if ( luaLibImport === LuaLibImportKind.Always || - (luaLibImport === LuaLibImportKind.Require && luaLibFeatures.size > 0) + (luaLibImport === LuaLibImportKind.Require && file.luaLibFeatures.size > 0) ) { // Require lualib bundle header += 'require("lualib_bundle");\n'; - } else if (luaLibImport === LuaLibImportKind.Inline && luaLibFeatures.size > 0) { + } else if (luaLibImport === LuaLibImportKind.Inline && file.luaLibFeatures.size > 0) { // Inline lualib features header += "-- Lua Library inline imports\n"; - header += loadLuaLibFeatures(luaLibFeatures, this.emitHost); + header += loadLuaLibFeatures(file.luaLibFeatures, this.emitHost); } if (this.options.sourceMapTraceback) { header += "{#SourceMapTraceback}\n"; } - const fileBlockNode = this.printBlock(block); - - return this.concatNodes(header, fileBlockNode); + return this.concatNodes(header, ...this.printStatementArray(file.statements)); } protected pushIndent(): void { @@ -280,7 +258,7 @@ export class LuaPrinter { } } }); - return result || false; + return result ?? false; } protected printStatementArray(statements: lua.Statement[]): SourceChunk[] { @@ -305,6 +283,42 @@ export class LuaPrinter { } public printStatement(statement: lua.Statement): SourceNode { + let resultNode = this.printStatementExcludingComments(statement); + + if (statement.leadingComments) { + resultNode = this.concatNodes( + statement.leadingComments.map(c => this.printComment(c)).join("\n"), + "\n", + resultNode + ); + } + + if (statement.trailingComments) { + resultNode = this.concatNodes( + resultNode, + "\n", + statement.trailingComments.map(c => this.printComment(c)).join("\n") + ); + } + + return resultNode; + } + + public printComment(comment: string | string[]): SourceChunk { + if (Array.isArray(comment)) { + if (comment.length === 0) { + return this.indent("--[[]]"); + } else { + const [firstLine, ...restLines] = comment; + const commentLines = this.concatNodes(...restLines.map(c => this.concatNodes("\n", this.indent(c)))); + return this.concatNodes(this.indent("--[["), firstLine, commentLines, "]]"); + } + } else { + return this.indent(`--${comment}`); + } + } + + protected printStatementExcludingComments(statement: lua.Statement): SourceNode { switch (statement.kind) { case lua.SyntaxKind.DoStatement: return this.printDoStatement(statement as lua.DoStatement); diff --git a/src/cli/parse.ts b/src/cli/parse.ts index fff0ef0d0..b7ed906e3 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -1,5 +1,5 @@ import * as ts from "typescript"; -import { CompilerOptions, LuaLibImportKind, LuaTarget } from "../CompilerOptions"; +import { BuildMode, CompilerOptions, LuaLibImportKind, LuaTarget } from "../CompilerOptions"; import * as cliDiagnostics from "./diagnostics"; export interface ParsedCommandLine extends ts.ParsedCommandLine { @@ -24,6 +24,12 @@ interface CommandLineOptionOfPrimitive extends CommandLineOptionBase { type CommandLineOption = CommandLineOptionOfEnum | CommandLineOptionOfPrimitive; export const optionDeclarations: CommandLineOption[] = [ + { + name: "buildMode", + description: "'default' or 'library'. Compiling as library will not resolve external dependencies.", + type: "enum", + choices: Object.values(BuildMode), + }, { name: "luaBundle", description: "The name of the lua file to bundle output lua to. Requires luaBundleEntry.", @@ -67,6 +73,11 @@ export const optionDeclarations: CommandLineOption[] = [ description: "List of TypeScriptToLua plugins.", type: "object", }, + { + name: "tstlVerbose", + description: "Provide verbose output useful for diagnosing problems.", + type: "boolean", + }, ]; export function updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine { diff --git a/src/cli/tsconfig.ts b/src/cli/tsconfig.ts index bec7c2d31..bc6fb5ae9 100644 --- a/src/cli/tsconfig.ts +++ b/src/cli/tsconfig.ts @@ -12,7 +12,7 @@ export function locateConfigFile(commandLine: ParsedCommandLine): ts.Diagnostic return undefined; } - const searchPath = normalizeSlashes(ts.sys.getCurrentDirectory()); + const searchPath = normalizeSlashes(process.cwd()); return ts.findConfigFile(searchPath, ts.sys.fileExists); } @@ -21,7 +21,7 @@ export function locateConfigFile(commandLine: ParsedCommandLine): ts.Diagnostic } // TODO: Unlike tsc, this resolves `.` to absolute path - const fileOrDirectory = normalizeSlashes(path.resolve(ts.sys.getCurrentDirectory(), project)); + const fileOrDirectory = normalizeSlashes(path.resolve(process.cwd(), project)); if (ts.sys.directoryExists(fileOrDirectory)) { const configFileName = path.posix.join(fileOrDirectory, "tsconfig.json"); if (ts.sys.fileExists(configFileName)) { diff --git a/src/lualib/ArrayConcat.ts b/src/lualib/ArrayConcat.ts index a133bb97a..30da83514 100644 --- a/src/lualib/ArrayConcat.ts +++ b/src/lualib/ArrayConcat.ts @@ -4,9 +4,8 @@ function __TS__ArrayConcat(this: void, arr1: any[], ...args: any[]): any[] { out[out.length] = val; } for (const arg of args) { - // Hack because we don't have an isArray function - if (pcall(() => (arg as any[]).length) && type(arg) !== "string") { - const argAsArray = arg as any[]; + if (Array.isArray(arg)) { + const argAsArray = arg; for (const val of argAsArray) { out[out.length] = val; } diff --git a/src/lualib/ArrayEntries.ts b/src/lualib/ArrayEntries.ts new file mode 100644 index 000000000..7d12f1347 --- /dev/null +++ b/src/lualib/ArrayEntries.ts @@ -0,0 +1,14 @@ +// https://262.ecma-international.org/10.0/#sec-array.prototype.entries +function __TS__ArrayEntries(this: void, array: T[]): IterableIterator<[number, T]> { + let key = 0; + return { + [Symbol.iterator](): IterableIterator<[number, T]> { + return this; + }, + next(): IteratorResult<[number, T]> { + const result = { done: array[key] === undefined, value: [key, array[key]] as [number, T] }; + key++; + return result; + }, + }; +} diff --git a/src/lualib/ArrayFlat.ts b/src/lualib/ArrayFlat.ts index 54120e69a..2bed314cb 100644 --- a/src/lualib/ArrayFlat.ts +++ b/src/lualib/ArrayFlat.ts @@ -1,13 +1,7 @@ function __TS__ArrayFlat(this: void, array: any[], depth = 1): any[] { let result: any[] = []; for (const value of array) { - if ( - depth > 0 && - type(value) === "table" && - // Workaround to determine if value is an array or not (fails in case of objects without keys) - // See discussion in: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/737 - (1 in value || (next as NextEmptyCheck)(value, undefined) === undefined) - ) { + if (depth > 0 && Array.isArray(value)) { result = result.concat(__TS__ArrayFlat(value, depth - 1)); } else { result[result.length] = value; diff --git a/src/lualib/ArrayFlatMap.ts b/src/lualib/ArrayFlatMap.ts index 02d58329b..c31af9046 100644 --- a/src/lualib/ArrayFlatMap.ts +++ b/src/lualib/ArrayFlatMap.ts @@ -6,12 +6,7 @@ function __TS__ArrayFlatMap( let result: U[] = []; for (let i = 0; i < array.length; i++) { const value = callback(array[i], i, array); - if ( - type(value) === "table" && - // Workaround to determine if value is an array or not (fails in case of objects without keys) - // See discussion in: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/737 - (1 in value || (next as NextEmptyCheck)(value as any, undefined) === undefined) - ) { + if (type(value) === "table" && Array.isArray(value)) { result = result.concat(value); } else { result[result.length] = value as U; diff --git a/src/lualib/ArrayIncludes.ts b/src/lualib/ArrayIncludes.ts index a9ff19ba4..b012f87bf 100644 --- a/src/lualib/ArrayIncludes.ts +++ b/src/lualib/ArrayIncludes.ts @@ -11,7 +11,7 @@ function __TS__ArrayIncludes(this: T[], searchElement: T, fromIndex = 0): boo k = 0; } - for (const i of forRange(k, len)) { + for (const i of $range(k, len)) { if (this[i] === searchElement) { return true; } diff --git a/src/lualib/ArrayIsArray.ts b/src/lualib/ArrayIsArray.ts new file mode 100644 index 000000000..417ae6e6e --- /dev/null +++ b/src/lualib/ArrayIsArray.ts @@ -0,0 +1,7 @@ +declare type NextEmptyCheck = (this: void, table: any, index: undefined) => unknown | undefined; + +function __TS__ArrayIsArray(this: void, value: any): value is any[] { + // Workaround to determine if value is an array or not (fails in case of objects without keys) + // See discussion in: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/737 + return type(value) === "table" && (1 in value || (next as NextEmptyCheck)(value, undefined) === undefined); +} diff --git a/src/lualib/ArrayReduce.ts b/src/lualib/ArrayReduce.ts index 8dda6ebd5..5ac7bd856 100644 --- a/src/lualib/ArrayReduce.ts +++ b/src/lualib/ArrayReduce.ts @@ -1,26 +1,26 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.reduce -function __TS__ArrayReduce( +function __TS__ArrayReduce( this: void, - arr: T[], - callbackFn: (accumulator: T, currentValue: T, index: number, array: T[]) => T, - ...initial: Vararg -): T { + arr: TElement[], + callbackFn: (accumulator: TAccumulator, currentValue: TElement, index: number, array: TElement[]) => TAccumulator, + ...initial: TAccumulator[] +): TAccumulator { const len = arr.length; let k = 0; - let accumulator = undefined; + let accumulator: TAccumulator = undefined; // Check if initial value is present in function call if (select("#", ...initial) !== 0) { - accumulator = select(1, ...initial); + [accumulator] = select(1, ...initial); } else if (len > 0) { - accumulator = arr[0]; + accumulator = arr[0] as unknown as TAccumulator; k = 1; } else { throw "Reduce of empty array with no initial value"; } - for (const i of forRange(k, len - 1)) { + for (const i of $range(k, len - 1)) { accumulator = callbackFn(accumulator, arr[i], i, arr); } diff --git a/src/lualib/ArrayReduceRight.ts b/src/lualib/ArrayReduceRight.ts index a57f78697..26258b862 100644 --- a/src/lualib/ArrayReduceRight.ts +++ b/src/lualib/ArrayReduceRight.ts @@ -1,26 +1,26 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.reduce -function __TS__ArrayReduceRight( +function __TS__ArrayReduceRight( this: void, - arr: T[], - callbackFn: (accumulator: T, currentValue: T, index: number, array: T[]) => T, - ...initial: Vararg -): T { + arr: TElement[], + callbackFn: (accumulator: TAccumulator, currentValue: TElement, index: number, array: TElement[]) => TAccumulator, + ...initial: TAccumulator[] +): TAccumulator { const len = arr.length; let k = len - 1; - let accumulator = undefined; + let accumulator: TAccumulator = undefined; // Check if initial value is present in function call if (select("#", ...initial) !== 0) { - accumulator = select(1, ...initial); + [accumulator] = select(1, ...initial); } else if (len > 0) { - accumulator = arr[k]; + accumulator = arr[k] as unknown as TAccumulator; k -= 1; } else { throw "Reduce of empty array with no initial value"; } - for (const i of forRange(k, 0, -1)) { + for (const i of $range(k, 0, -1)) { accumulator = callbackFn(accumulator, arr[i], i, arr); } diff --git a/src/lualib/ArraySplice.ts b/src/lualib/ArraySplice.ts index 5df67938f..d4a122181 100644 --- a/src/lualib/ArraySplice.ts +++ b/src/lualib/ArraySplice.ts @@ -1,10 +1,10 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.splice -function __TS__ArraySplice(this: void, list: T[], ...args: Vararg): T[] { +function __TS__ArraySplice(this: void, list: T[], ...args: T[]): T[] { const len = list.length; const actualArgumentCount = select("#", ...args); - const start = select(1, ...args) as number; - const deleteCount = select(2, ...args) as number; + const start = select(1, ...args)[0] as unknown as number; + const deleteCount = select(2, ...args)[0] as unknown as number; let actualStart: number; @@ -66,8 +66,8 @@ function __TS__ArraySplice(this: void, list: T[], ...args: Vararg) } let j = actualStart; - for (const i of forRange(3, actualArgumentCount)) { - list[j] = select(i, ...args) as T; + for (const i of $range(3, actualArgumentCount)) { + list[j] = select(i, ...args)[0]; j++; } diff --git a/src/lualib/ArrayToObject.ts b/src/lualib/ArrayToObject.ts index 385906f0a..460a77250 100644 --- a/src/lualib/ArrayToObject.ts +++ b/src/lualib/ArrayToObject.ts @@ -1,4 +1,4 @@ -function __TS__ArrayToObject(this: void, array: any[]): object { +function __TS__ArrayToObject(this: void, array: T[]): Record { const object: Record = {}; for (let i = 0; i < array.length; i += 1) { object[i] = array[i]; diff --git a/src/lualib/Await.ts b/src/lualib/Await.ts new file mode 100644 index 000000000..61f383e96 --- /dev/null +++ b/src/lualib/Await.ts @@ -0,0 +1,52 @@ +// The following is a translation of the TypeScript async awaiter which uses generators and yields. +// For Lua we use coroutines instead. +// +// Source: +// +// var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { +// function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } +// return new (P || (P = Promise))(function (resolve, reject) { +// function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } +// function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } +// function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } +// step((generator = generator.apply(thisArg, _arguments || [])).next()); +// }); +// }; +// + +// eslint-disable-next-line @typescript-eslint/promise-function-async +function __TS__AsyncAwaiter(this: void, generator: (this: void) => void) { + return new Promise((resolve, reject) => { + const asyncCoroutine = coroutine.create(generator); + + // eslint-disable-next-line @typescript-eslint/promise-function-async + function adopt(value: unknown) { + return value instanceof __TS__Promise ? value : Promise.resolve(value); + } + function fulfilled(value) { + const [success, resultOrError] = coroutine.resume(asyncCoroutine, value); + if (success) { + step(resultOrError); + } else { + reject(resultOrError); + } + } + function step(result: unknown) { + if (coroutine.status(asyncCoroutine) === "dead") { + resolve(result); + } else { + adopt(result).then(fulfilled, reason => reject(reason)); + } + } + const [success, resultOrError] = coroutine.resume(asyncCoroutine); + if (success) { + step(resultOrError); + } else { + reject(resultOrError); + } + }); +} + +function __TS__Await(this: void, thing: unknown) { + return coroutine.yield(thing); +} diff --git a/src/lualib/CloneDescriptor.ts b/src/lualib/CloneDescriptor.ts new file mode 100644 index 000000000..d74292bab --- /dev/null +++ b/src/lualib/CloneDescriptor.ts @@ -0,0 +1,26 @@ +function __TS__CloneDescriptor( + this: void, + { enumerable, configurable, get, set, writable, value }: PropertyDescriptor +): PropertyDescriptor { + const descriptor: PropertyDescriptor = { + enumerable: enumerable === true, + configurable: configurable === true, + }; + + const hasGetterOrSetter = get !== undefined || set !== undefined; + const hasValueOrWritableAttribute = writable !== undefined || value !== undefined; + + if (hasGetterOrSetter && hasValueOrWritableAttribute) { + throw "Invalid property descriptor. Cannot both specify accessors and a value or writable attribute."; + } + + if (get || set) { + descriptor.get = get; + descriptor.set = set; + } else { + descriptor.value = value; + descriptor.writable = writable === true; + } + + return descriptor; +} diff --git a/src/lualib/Decorate.ts b/src/lualib/Decorate.ts index 15dbee15d..816721da7 100644 --- a/src/lualib/Decorate.ts +++ b/src/lualib/Decorate.ts @@ -1,7 +1,18 @@ /** * SEE: https://github.com/Microsoft/TypeScript/blob/master/src/compiler/transformers/ts.ts#L3598 */ -function __TS__Decorate(this: void, decorators: Function[], target: {}, key?: string, desc?: any): {} { +type Decorator = ( + target: TTarget, + key?: TKey, + descriptor?: PropertyDescriptor +) => TTarget; +function __TS__Decorate( + this: void, + decorators: Array>, + target: TTarget, + key?: TKey, + desc?: any +): TTarget { let result = target; for (let i = decorators.length; i >= 0; i--) { @@ -11,8 +22,22 @@ function __TS__Decorate(this: void, decorators: Function[], target: {}, key?: st if (key === undefined) { result = decorator(result); - } else if (desc !== undefined) { - result = decorator(target, key, result); + } else if (desc === true) { + const value = rawget(target, key); + const descriptor = __TS__ObjectGetOwnPropertyDescriptor(target, key) || { + configurable: true, + writable: true, + value, + }; + const desc = decorator(target, key, descriptor) || descriptor; + const isSimpleValue = desc.configurable === true && desc.writable === true && !desc.get && !desc.set; + if (isSimpleValue) { + rawset(target, key, desc.value); + } else { + __TS__SetDescriptor(target, key, { ...descriptor, ...desc }); + } + } else if (desc === false) { + result = decorator(target, key, desc); } else { result = decorator(target, key); } diff --git a/src/lualib/DecorateParam.ts b/src/lualib/DecorateParam.ts new file mode 100644 index 000000000..4e11f3e54 --- /dev/null +++ b/src/lualib/DecorateParam.ts @@ -0,0 +1,12 @@ +type ParamDecorator = ( + target: TTarget, + key: TKey, + index: number +) => TTarget; +function __TS__DecorateParam( + this: void, + paramIndex: number, + decorator: ParamDecorator +): Decorator { + return (target: TTarget, key?: TKey) => decorator(target, key, paramIndex); +} diff --git a/src/lualib/DelegatedYield.ts b/src/lualib/DelegatedYield.ts new file mode 100644 index 000000000..ab47d02d8 --- /dev/null +++ b/src/lualib/DelegatedYield.ts @@ -0,0 +1,32 @@ +function __TS__DelegatedYield(this: void, iterable: string | GeneratorIterator | Iterable | readonly T[]) { + if (typeof iterable === "string") { + for (const index of $range(0, iterable.length - 1)) { + coroutine.yield(iterable[index]); + } + } else if ("____coroutine" in iterable) { + const co = iterable.____coroutine; + while (true) { + const [status, value] = coroutine.resume(co); + if (!status) throw value; + if (coroutine.status(co) === "dead") { + return value; + } else { + coroutine.yield(value); + } + } + } else if (iterable[Symbol.iterator]) { + const iterator = iterable[Symbol.iterator](); + while (true) { + const result = iterator.next(); + if (result.done) { + return result.value; + } else { + coroutine.yield(result.value); + } + } + } else { + for (const value of iterable as readonly T[]) { + coroutine.yield(value); + } + } +} diff --git a/src/lualib/Delete.ts b/src/lualib/Delete.ts new file mode 100644 index 000000000..079dcb93d --- /dev/null +++ b/src/lualib/Delete.ts @@ -0,0 +1,19 @@ +function __TS__Delete(this: void, target: any, key: any): boolean { + const descriptors = __TS__ObjectGetOwnPropertyDescriptors(target); + const descriptor = descriptors[key]; + if (descriptor) { + if (!descriptor.configurable) { + throw `Cannot delete property ${key} of ${target}.`; + } + + descriptors[key] = undefined; + return true; + } + + if (target[key] !== undefined) { + target[key] = undefined; + return true; + } + + return false; +} diff --git a/src/lualib/Error.ts b/src/lualib/Error.ts index d44a3b9eb..197ff816b 100644 --- a/src/lualib/Error.ts +++ b/src/lualib/Error.ts @@ -3,7 +3,7 @@ interface ErrorType { new (...args: any[]): Error; } -function __TS__GetErrorStack(constructor: Function): string { +function __TS__GetErrorStack(constructor: () => any): string { let level = 1; while (true) { const info = debug.getinfo(level, "f"); diff --git a/src/lualib/Generator.ts b/src/lualib/Generator.ts index a71740761..1e18f2e25 100644 --- a/src/lualib/Generator.ts +++ b/src/lualib/Generator.ts @@ -8,7 +8,7 @@ function __TS__GeneratorIterator(this: GeneratorIterator) { return this; } -function __TS__GeneratorNext(this: GeneratorIterator, ...args: Vararg) { +function __TS__GeneratorNext(this: GeneratorIterator, ...args: any[]) { const co = this.____coroutine; if (coroutine.status(co) === "dead") return { done: true }; @@ -19,11 +19,11 @@ function __TS__GeneratorNext(this: GeneratorIterator, ...args: Vararg) { } function __TS__Generator(this: void, fn: (this: void, ...args: any[]) => any) { - return function (this: void, ...args: Vararg): GeneratorIterator { + return function (this: void, ...args: any[]): GeneratorIterator { const argsLength = select("#", ...args); return { // Using explicit this there, since we don't pass arguments after the first nil and context is likely to be nil - ____coroutine: coroutine.create(() => fn((unpack || table.unpack)(args, 1, argsLength))), + ____coroutine: coroutine.create(() => fn(...(unpack ?? table.unpack)(args, 1, argsLength))), [Symbol.iterator]: __TS__GeneratorIterator, next: __TS__GeneratorNext, }; diff --git a/src/lualib/Iterator.ts b/src/lualib/Iterator.ts index e55de6404..29da08683 100644 --- a/src/lualib/Iterator.ts +++ b/src/lualib/Iterator.ts @@ -1,41 +1,37 @@ -/** @tupleReturn */ -function __TS__IteratorGeneratorStep(this: GeneratorIterator): [true, any] | [] { +function __TS__IteratorGeneratorStep(this: GeneratorIterator): LuaMultiReturn<[true, any] | []> { const co = this.____coroutine; const [status, value] = coroutine.resume(co); if (!status) throw value; - if (coroutine.status(co) === "dead") return []; - return [true, value]; + if (coroutine.status(co) === "dead") return $multi(); + return $multi(true, value); } -/** @tupleReturn */ -function __TS__IteratorIteratorStep(this: Iterator): [true, T] | [] { +function __TS__IteratorIteratorStep(this: Iterator): LuaMultiReturn<[true, T] | []> { const result = this.next(); - if (result.done) return []; - return [true, result.value]; + if (result.done) return $multi(); + return $multi(true, result.value); } -/** @tupleReturn */ -function __TS__IteratorStringStep(this: string, index: number): [number, string] | [] { +function __TS__IteratorStringStep(this: string, index: number): LuaMultiReturn<[number, string] | []> { index += 1; - if (index > this.length) return []; - return [index, string.sub(this, index, index)]; + if (index > this.length) return $multi(); + return $multi(index, string.sub(this, index, index)); } -/** @tupleReturn */ function __TS__Iterator( this: void, - iterable: Iterable | GeneratorIterator | readonly T[] -): [(...args: any[]) => [any, any] | [], ...any[]] { - if ("____coroutine" in iterable) { - return [__TS__IteratorGeneratorStep, iterable]; + iterable: string | GeneratorIterator | Iterable | readonly T[] +): LuaMultiReturn<[(...args: any[]) => [any, any] | [], ...any[]]> | LuaIterable> { + if (typeof iterable === "string") { + return $multi(__TS__IteratorStringStep, iterable, 0); + } else if ("____coroutine" in iterable) { + return $multi(__TS__IteratorGeneratorStep, iterable); } else if (iterable[Symbol.iterator]) { const iterator = iterable[Symbol.iterator](); - return [__TS__IteratorIteratorStep, iterator]; - } else if (typeof iterable === "string") { - return [__TS__IteratorStringStep, iterable, 0]; + return $multi(__TS__IteratorIteratorStep, iterator); } else { - return ipairs(iterable as readonly T[]) as any; + return ipairs(iterable as readonly T[]); } } diff --git a/src/lualib/New.ts b/src/lualib/New.ts index 507ba120c..8b33ec837 100644 --- a/src/lualib/New.ts +++ b/src/lualib/New.ts @@ -1,4 +1,4 @@ -function __TS__New(this: void, target: LuaClass, ...args: Vararg): any { +function __TS__New(this: void, target: LuaClass, ...args: any[]): any { const instance: any = setmetatable({}, target.prototype); instance.____constructor(...args); return instance; diff --git a/src/lualib/ObjectAssign.ts b/src/lualib/ObjectAssign.ts index da49d9eb0..bcf521c07 100644 --- a/src/lualib/ObjectAssign.ts +++ b/src/lualib/ObjectAssign.ts @@ -1,4 +1,5 @@ // https://tc39.github.io/ecma262/#sec-object.assign +// eslint-disable-next-line @typescript-eslint/ban-types function __TS__ObjectAssign(this: void, to: T, ...sources: object[]): T { if (to === undefined) { return to; diff --git a/src/lualib/ObjectDefineProperty.ts b/src/lualib/ObjectDefineProperty.ts new file mode 100644 index 000000000..f37b36c2a --- /dev/null +++ b/src/lualib/ObjectDefineProperty.ts @@ -0,0 +1,31 @@ +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty + +// eslint-disable-next-line @typescript-eslint/ban-types +function __TS__ObjectDefineProperty(this: void, target: T, key: any, desc: PropertyDescriptor): T { + const luaKey = typeof key === "number" ? key + 1 : key; + const value = rawget(target, luaKey); + + const hasGetterOrSetter = desc.get !== undefined || desc.set !== undefined; + + let descriptor: PropertyDescriptor; + if (hasGetterOrSetter) { + if (value !== undefined) { + throw `Cannot redefine property: ${key}`; + } + + descriptor = desc; + } else { + const valueExists = value !== undefined; + descriptor = { + set: desc.set, + get: desc.get, + configurable: desc.configurable !== undefined ? desc.configurable : valueExists, + enumerable: desc.enumerable !== undefined ? desc.enumerable : valueExists, + writable: desc.writable !== undefined ? desc.writable : valueExists, + value: desc.value !== undefined ? desc.value : value, + }; + } + + __TS__SetDescriptor(target, luaKey, descriptor); + return target; +} diff --git a/src/lualib/ObjectGetOwnPropertyDescriptor.ts b/src/lualib/ObjectGetOwnPropertyDescriptor.ts new file mode 100644 index 000000000..84dab33df --- /dev/null +++ b/src/lualib/ObjectGetOwnPropertyDescriptor.ts @@ -0,0 +1,6 @@ +function __TS__ObjectGetOwnPropertyDescriptor(this: void, object: any, key: any): PropertyDescriptor | undefined { + const metatable = getmetatable(object); + if (!metatable) return; + if (!rawget(metatable, "_descriptors")) return; + return rawget(metatable, "_descriptors")[key]; +} diff --git a/src/lualib/ObjectGetOwnPropertyDescriptors.ts b/src/lualib/ObjectGetOwnPropertyDescriptors.ts new file mode 100644 index 000000000..04aee8b51 --- /dev/null +++ b/src/lualib/ObjectGetOwnPropertyDescriptors.ts @@ -0,0 +1,5 @@ +function __TS__ObjectGetOwnPropertyDescriptors(this: void, object: any): Record { + const metatable = getmetatable(object); + if (!metatable) return {}; + return rawget(metatable, "_descriptors") || {}; +} diff --git a/src/lualib/OptionalChainAccess.ts b/src/lualib/OptionalChainAccess.ts new file mode 100644 index 000000000..7924aa282 --- /dev/null +++ b/src/lualib/OptionalChainAccess.ts @@ -0,0 +1,10 @@ +function __TS__OptionalChainAccess( + this: void, + table: Record, + key: TKey +): TReturn | undefined { + if (table) { + return table[key]; + } + return undefined; +} diff --git a/src/lualib/OptionalFunctionCall.ts b/src/lualib/OptionalFunctionCall.ts new file mode 100644 index 000000000..85b52a047 --- /dev/null +++ b/src/lualib/OptionalFunctionCall.ts @@ -0,0 +1,10 @@ +function __TS__OptionalFunctionCall( + this: void, + f: (this: void, ...args: [...TArgs]) => TReturn, + ...args: [...TArgs] +): TReturn | undefined { + if (f) { + return f(...args); + } + return undefined; +} diff --git a/src/lualib/OptionalMethodCall.ts b/src/lualib/OptionalMethodCall.ts new file mode 100644 index 000000000..5549a1c36 --- /dev/null +++ b/src/lualib/OptionalMethodCall.ts @@ -0,0 +1,17 @@ +function __TS__OptionalMethodCall( + this: void, + table: Record TReturn>, + methodName: string, + isMethodOptional: boolean, + ...args: [...TArgs] +): TReturn | undefined { + if (table) { + const method = table[methodName]; + if (method) { + return method.call(table, ...args); + } else if (!isMethodOptional) { + throw `${methodName} is not a function`; + } + } + return undefined; +} diff --git a/src/lualib/ParseFloat.ts b/src/lualib/ParseFloat.ts new file mode 100644 index 000000000..0c6d04d65 --- /dev/null +++ b/src/lualib/ParseFloat.ts @@ -0,0 +1,11 @@ +function __TS__ParseFloat(this: void, numberString: string): number { + // Check if string is infinity + const [infinityMatch] = string.match(numberString, "^%s*(-?Infinity)"); + if (infinityMatch) { + // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with + return infinityMatch[0] === "-" ? -Infinity : Infinity; + } + + const number = tonumber(string.match(numberString, "^%s*(-?%d+%.?%d*)")[0]); + return number ?? NaN; +} diff --git a/src/lualib/ParseInt.ts b/src/lualib/ParseInt.ts new file mode 100644 index 000000000..cb1d851f4 --- /dev/null +++ b/src/lualib/ParseInt.ts @@ -0,0 +1,41 @@ +const __TS__parseInt_base_pattern = "0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTvVwWxXyYzZ"; + +function __TS__ParseInt(this: void, numberString: string, base?: number): number { + // Check which base to use if none specified + if (base === undefined) { + base = 10; + const [hexMatch] = string.match(numberString, "^%s*-?0[xX]"); + if (hexMatch) { + base = 16; + numberString = string.match(hexMatch, "-")[0] + ? "-" + numberString.substr(hexMatch.length) + : numberString.substr(hexMatch.length); + } + } + + // Check if base is in bounds + if (base < 2 || base > 36) { + return NaN; + } + + // Calculate string match pattern to use + const allowedDigits = + base <= 10 + ? __TS__parseInt_base_pattern.substring(0, base) + : __TS__parseInt_base_pattern.substr(0, 10 + 2 * (base - 10)); + const pattern = `^%s*(-?[${allowedDigits}]*)`; + + // Try to parse with Lua tonumber + const number = tonumber(string.match(numberString, pattern)[0], base); + + if (number === undefined) { + return NaN; + } + + // Lua uses a different floor convention for negative numbers than JS + if (number >= 0) { + return math.floor(number); + } else { + return math.ceil(number); + } +} diff --git a/src/lualib/Promise.ts b/src/lualib/Promise.ts new file mode 100644 index 000000000..c8fdea117 --- /dev/null +++ b/src/lualib/Promise.ts @@ -0,0 +1,188 @@ +/* eslint-disable @typescript-eslint/promise-function-async */ + +// Promises implemented based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise +// and https://promisesaplus.com/ + +enum __TS__PromiseState { + Pending, + Fulfilled, + Rejected, +} + +type FulfillCallback = (value: TData) => TResult | PromiseLike; +type RejectCallback = (reason: any) => TResult | PromiseLike; + +function __TS__PromiseDeferred() { + let resolve: FulfillCallback; + let reject: RejectCallback; + const promise = new Promise((res, rej) => { + resolve = res; + reject = rej; + }); + + return { promise, resolve, reject }; +} + +function __TS__IsPromiseLike(thing: unknown): thing is PromiseLike { + return thing instanceof __TS__Promise; +} + +class __TS__Promise implements Promise { + public state = __TS__PromiseState.Pending; + public value?: T; + public rejectionReason?: any; + + private fulfilledCallbacks: Array> = []; + private rejectedCallbacks: Array> = []; + private finallyCallbacks: Array<() => void> = []; + + public [Symbol.toStringTag]: string; // Required to implement interface, no output Lua + + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve + public static resolve(this: void, data: TData): Promise { + // Create and return a promise instance that is already resolved + const promise = new __TS__Promise(() => {}); + promise.state = __TS__PromiseState.Fulfilled; + promise.value = data; + return promise; + } + + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject + public static reject(this: void, reason: any): Promise { + // Create and return a promise instance that is already rejected + const promise = new __TS__Promise(() => {}); + promise.state = __TS__PromiseState.Rejected; + promise.rejectionReason = reason; + return promise; + } + + constructor(executor: (resolve: (data: T) => void, reject: (reason: any) => void) => void) { + try { + executor(this.resolve.bind(this), this.reject.bind(this)); + } catch (e) { + // When a promise executor throws, the promise should be rejected with the thrown object as reason + this.reject(e); + } + } + + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then + public then( + onFulfilled?: FulfillCallback, + onRejected?: RejectCallback + ): Promise { + const { promise, resolve, reject } = __TS__PromiseDeferred(); + + if (onFulfilled) { + const internalCallback = this.createPromiseResolvingCallback(onFulfilled, resolve, reject); + this.fulfilledCallbacks.push(internalCallback); + + if (this.state === __TS__PromiseState.Fulfilled) { + // If promise already resolved, immediately call callback + internalCallback(this.value); + } + } else { + // We always want to resolve our child promise if this promise is resolved, even if we have no handler + this.fulfilledCallbacks.push(() => resolve(undefined)); + } + + if (onRejected) { + const internalCallback = this.createPromiseResolvingCallback(onRejected, resolve, reject); + this.rejectedCallbacks.push(internalCallback); + + if (this.state === __TS__PromiseState.Rejected) { + // If promise already rejected, immediately call callback + internalCallback(this.rejectionReason); + } + } + + return promise; + } + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch + public catch(onRejected?: (reason: any) => TResult | PromiseLike): Promise { + return this.then(undefined, onRejected); + } + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally + public finally(onFinally?: () => void): Promise { + if (onFinally) { + this.finallyCallbacks.push(onFinally); + + if (this.state !== __TS__PromiseState.Pending) { + // If promise already resolved or rejected, immediately fire finally callback + onFinally(); + } + } + return this; + } + + private resolve(data: T): void { + // Resolve this promise, if it is still pending. This function is passed to the constructor function. + if (this.state === __TS__PromiseState.Pending) { + this.state = __TS__PromiseState.Fulfilled; + this.value = data; + + for (const callback of this.fulfilledCallbacks) { + callback(data); + } + for (const callback of this.finallyCallbacks) { + callback(); + } + } + } + + private reject(reason: any): void { + // Reject this promise, if it is still pending. This function is passed to the constructor function. + if (this.state === __TS__PromiseState.Pending) { + this.state = __TS__PromiseState.Rejected; + this.rejectionReason = reason; + + for (const callback of this.rejectedCallbacks) { + callback(reason); + } + for (const callback of this.finallyCallbacks) { + callback(); + } + } + } + + private createPromiseResolvingCallback( + f: FulfillCallback | RejectCallback, + resolve: FulfillCallback, + reject: RejectCallback + ) { + return value => { + try { + this.handleCallbackData(f(value), resolve, reject); + } catch (e) { + // If a handler function throws an error, the promise returned by then gets rejected with the thrown error as its value + reject(e); + } + }; + } + private handleCallbackData( + data: TResult | PromiseLike, + resolve: FulfillCallback, + reject: RejectCallback + ) { + if (__TS__IsPromiseLike(data)) { + const nextpromise = data as __TS__Promise; + if (nextpromise.state === __TS__PromiseState.Fulfilled) { + // If a handler function returns an already fulfilled promise, + // the promise returned by then gets fulfilled with that promise's value + resolve(nextpromise.value); + } else if (nextpromise.state === __TS__PromiseState.Rejected) { + // If a handler function returns an already rejected promise, + // the promise returned by then gets fulfilled with that promise's value + reject(nextpromise.rejectionReason); + } else { + // If a handler function returns another pending promise object, the resolution/rejection + // of the promise returned by then will be subsequent to the resolution/rejection of + // the promise returned by the handler. + data.then(resolve, reject); + } + } else { + // If a handler returns a value, the promise returned by then gets resolved with the returned value as its value + // If a handler doesn't return anything, the promise returned by then gets resolved with undefined + resolve(data); + } + } +} diff --git a/src/lualib/PromiseAll.ts b/src/lualib/PromiseAll.ts new file mode 100644 index 000000000..e0d940977 --- /dev/null +++ b/src/lualib/PromiseAll.ts @@ -0,0 +1,54 @@ +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all +// eslint-disable-next-line @typescript-eslint/promise-function-async +function __TS__PromiseAll(this: void, iterable: Iterable>): Promise { + const results: T[] = []; + + const toResolve = new LuaTable>(); + let numToResolve = 0; + + let i = 0; + for (const item of iterable) { + if (item instanceof __TS__Promise) { + if (item.state === __TS__PromiseState.Fulfilled) { + // If value is a resolved promise, add its value to our results array + results[i] = item.value; + } else if (item.state === __TS__PromiseState.Rejected) { + // If value is a rejected promise, return a rejected promise with the rejection reason + return Promise.reject(item.rejectionReason); + } else { + // If value is a pending promise, add it to the list of pending promises + numToResolve++; + toResolve.set(i, item); + } + } else { + // If value is not a promise, add it to the results array + results[i] = item as T; + } + i++; + } + + // If there are no remaining pending promises, return a resolved promise with the results + if (numToResolve === 0) { + return Promise.resolve(results); + } + + return new Promise((resolve, reject) => { + for (const [index, promise] of pairs(toResolve)) { + promise.then( + data => { + // When resolved, store value in results array + results[index] = data; + numToResolve--; + if (numToResolve === 0) { + // If there are no more promises to resolve, resolve with our filled results array + resolve(results); + } + }, + reason => { + // When rejected, immediately reject the returned promise + reject(reason); + } + ); + } + }); +} diff --git a/src/lualib/PromiseAllSettled.ts b/src/lualib/PromiseAllSettled.ts new file mode 100644 index 000000000..165e226f4 --- /dev/null +++ b/src/lualib/PromiseAllSettled.ts @@ -0,0 +1,62 @@ +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled +// eslint-disable-next-line @typescript-eslint/promise-function-async +function __TS__PromiseAllSettled( + this: void, + iterable: Iterable +): Promise ? U : T>>> { + const results: Array ? U : T>> = []; + + const toResolve = new LuaTable>(); + let numToResolve = 0; + + let i = 0; + for (const item of iterable) { + if (item instanceof __TS__Promise) { + if (item.state === __TS__PromiseState.Fulfilled) { + // If value is a resolved promise, add a fulfilled PromiseSettledResult + results[i] = { status: "fulfilled", value: item.value }; + } else if (item.state === __TS__PromiseState.Rejected) { + // If value is a rejected promise, add a rejected PromiseSettledResult + results[i] = { status: "rejected", reason: item.rejectionReason }; + } else { + // If value is a pending promise, add it to the list of pending promises + numToResolve++; + toResolve.set(i, item); + } + } else { + // If value is not a promise, add it to the results as fulfilled PromiseSettledResult + results[i] = { status: "fulfilled", value: item as any }; + } + i++; + } + + // If there are no remaining pending promises, return a resolved promise with the results + if (numToResolve === 0) { + return Promise.resolve(results); + } + + return new Promise(resolve => { + for (const [index, promise] of pairs(toResolve)) { + promise.then( + data => { + // When resolved, add a fulfilled PromiseSettledResult + results[index] = { status: "fulfilled", value: data as any }; + numToResolve--; + if (numToResolve === 0) { + // If there are no more promises to resolve, resolve with our filled results array + resolve(results); + } + }, + reason => { + // When resolved, add a rejected PromiseSettledResult + results[index] = { status: "rejected", reason }; + numToResolve--; + if (numToResolve === 0) { + // If there are no more promises to resolve, resolve with our filled results array + resolve(results); + } + } + ); + } + }); +} diff --git a/src/lualib/PromiseAny.ts b/src/lualib/PromiseAny.ts new file mode 100644 index 000000000..eb70bf12f --- /dev/null +++ b/src/lualib/PromiseAny.ts @@ -0,0 +1,55 @@ +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any +// eslint-disable-next-line @typescript-eslint/promise-function-async +function __TS__PromiseAny(this: void, iterable: Iterable>): Promise { + const rejections: string[] = []; + const pending: Array> = []; + + for (const item of iterable) { + if (item instanceof __TS__Promise) { + if (item.state === __TS__PromiseState.Fulfilled) { + // If value is a resolved promise, return a new resolved promise with its value + return Promise.resolve(item.value); + } else if (item.state === __TS__PromiseState.Rejected) { + // If value is a rejected promise, add its value to our list of rejections + rejections.push(item.rejectionReason); + } else { + // If value is a pending promise, add it to the list of pending promises + pending.push(item); + } + } else { + // If value is not a promise, return a resolved promise with it as its value + return Promise.resolve(item); + } + } + + // If we have not returned yet and there are no pending promises, reject + if (pending.length === 0) { + return Promise.reject("No promises to resolve with .any()"); + } + + let numResolved = 0; + + return new Promise((resolve, reject) => { + for (const promise of pending) { + promise.then( + data => { + // If any pending promise resolves, resolve this promise with its data + resolve(data); + }, + reason => { + // If a pending promise rejects, add its rejection to our rejection list + rejections.push(reason); + numResolved++; + if (numResolved === pending.length) { + // If there are no more pending promises, reject with the list of rejections + reject({ + name: "AggregateError", + message: "All Promises rejected", + errors: rejections, + }); + } + } + ); + } + }); +} diff --git a/src/lualib/PromiseRace.ts b/src/lualib/PromiseRace.ts new file mode 100644 index 000000000..3b3a1fb7b --- /dev/null +++ b/src/lualib/PromiseRace.ts @@ -0,0 +1,34 @@ +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race +// eslint-disable-next-line @typescript-eslint/promise-function-async +function __TS__PromiseRace(this: void, iterable: Iterable>): Promise { + const pending: Array> = []; + + for (const item of iterable) { + if (item instanceof __TS__Promise) { + if (item.state === __TS__PromiseState.Fulfilled) { + // If value is a fulfilled promise, return a resolved promise with its value + return Promise.resolve(item.value); + } else if (item.state === __TS__PromiseState.Rejected) { + // If value is a rejected promise, return rejected promise with its value + return Promise.reject(item.rejectionReason); + } else { + // If value is a pending promise, add it to the list of pending promises + pending.push(item); + } + } else { + // If value is not a promise, return a promise resolved with it as its value + return Promise.resolve(item); + } + } + + // If not yet returned, wait for any pending promise to resolve or reject. + // If there are no pending promise, this promise will be pending forever as per specification. + return new Promise((resolve, reject) => { + for (const promise of pending) { + promise.then( + value => resolve(value), + reason => reject(reason) + ); + } + }); +} diff --git a/src/lualib/Descriptors.ts b/src/lualib/SetDescriptor.ts similarity index 62% rename from src/lualib/Descriptors.ts rename to src/lualib/SetDescriptor.ts index 7b6410ed6..5659848d5 100644 --- a/src/lualib/Descriptors.ts +++ b/src/lualib/SetDescriptor.ts @@ -6,7 +6,7 @@ function ____descriptorIndex(this: any, key: string): void { let metatable = getmetatable(this); while (metatable) { - const rawResult = rawget(metatable, key); + const rawResult = rawget(metatable, key as any); if (rawResult !== undefined) { return rawResult; } @@ -19,7 +19,7 @@ function ____descriptorIndex(this: any, key: string): void { return descriptor.get.call(this); } - return; + return descriptor.value; } } @@ -36,8 +36,13 @@ function ____descriptorNewindex(this: any, key: string, value: any): void { if (descriptor) { if (descriptor.set) { descriptor.set.call(this, value); - } + } else { + if (descriptor.writable === false) { + throw `Cannot assign to read only property '${key}' of object '${this}'`; + } + descriptor.value = value; + } return; } } @@ -49,27 +54,19 @@ function ____descriptorNewindex(this: any, key: string, value: any): void { } // It's also used directly in class transform to add descriptors to the prototype -function __TS__SetDescriptor(this: void, metatable: Metatable, prop: string, descriptor: PropertyDescriptor): void { - if (!rawget(metatable, "_descriptors")) metatable._descriptors = {}; - metatable._descriptors[prop] = descriptor; - - if (descriptor.get) metatable.__index = ____descriptorIndex; - if (descriptor.set) metatable.__newindex = ____descriptorNewindex; -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty -function __TS__ObjectDefineProperty( - this: void, - object: T, - prop: string, - descriptor: PropertyDescriptor -): T { - let metatable = getmetatable(object); +function __TS__SetDescriptor(this: void, target: any, key: any, desc: PropertyDescriptor, isPrototype = false): void { + let metatable = isPrototype ? target : getmetatable(target); if (!metatable) { metatable = {}; - setmetatable(object, metatable); + setmetatable(target, metatable); } - __TS__SetDescriptor(metatable, prop, descriptor); - return object; + const value = rawget(target, key); + if (value !== undefined) rawset(target, key, undefined); + + if (!rawget(metatable, "_descriptors")) metatable._descriptors = {}; + const descriptor = __TS__CloneDescriptor(desc); + metatable._descriptors[key] = descriptor; + metatable.__index = ____descriptorIndex; + metatable.__newindex = ____descriptorNewindex; } diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts index 3a264ead9..b46ba4786 100644 --- a/src/lualib/SourceMapTraceBack.ts +++ b/src/lualib/SourceMapTraceBack.ts @@ -1,12 +1,13 @@ // TODO: In the future, change this to __TS__RegisterFileInfo and provide tstl interface to // get some metadata about transpilation. +declare function __TS__originalTraceback(this: void, thread?: LuaThread, message?: string, level?: number); function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: { [line: number]: number }): void { globalThis.__TS__sourcemap = globalThis.__TS__sourcemap || {}; globalThis.__TS__sourcemap[fileName] = sourceMap; if (globalThis.__TS__originalTraceback === undefined) { globalThis.__TS__originalTraceback = debug.traceback; - debug.traceback = (thread, message, level) => { + debug.traceback = ((thread, message, level) => { let trace: string; if (thread === undefined && message === undefined && level === undefined) { trace = globalThis.__TS__originalTraceback(); @@ -27,6 +28,6 @@ function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: { [li }); return result; - }; + }) as typeof debug.traceback; } } diff --git a/src/lualib/Spread.ts b/src/lualib/Spread.ts index 2bc96395b..6bc3bf628 100644 --- a/src/lualib/Spread.ts +++ b/src/lualib/Spread.ts @@ -1,4 +1,4 @@ -function __TS__Spread(this: void, iterable: string | Iterable): T[] { +function __TS__Spread(this: void, iterable: string | Iterable): LuaMultiReturn { const arr = []; if (typeof iterable === "string") { // eslint-disable-next-line @typescript-eslint/prefer-for-of @@ -10,5 +10,5 @@ function __TS__Spread(this: void, iterable: string | Iterable): T[] { arr[arr.length] = item; } } - return __TS__Unpack(arr); + return $multi(...arr); } diff --git a/src/lualib/StringIncludes.ts b/src/lualib/StringIncludes.ts new file mode 100644 index 000000000..7508a2a42 --- /dev/null +++ b/src/lualib/StringIncludes.ts @@ -0,0 +1,10 @@ +function __TS__StringIncludes(this: string, searchString: string, position?: number): boolean { + // http://lua-users.org/wiki/StringLibraryTutorial + if (!position) { + position = 1; + } else { + position += 1; + } + const [index] = string.find(this, searchString, position, true); + return index !== undefined; +} diff --git a/src/lualib/Symbol.ts b/src/lualib/Symbol.ts index 61a5c0423..41be3fc28 100644 --- a/src/lualib/Symbol.ts +++ b/src/lualib/Symbol.ts @@ -5,7 +5,7 @@ const ____symbolMetatable = { }; function __TS__Symbol(this: void, description?: string | number): symbol { - return setmetatable({ description }, ____symbolMetatable) as any; + return setmetatable({ description }, ____symbolMetatable) as symbol; } Symbol = { diff --git a/src/lualib/WeakMap.ts b/src/lualib/WeakMap.ts index 772f7bb58..7b7df1e99 100644 --- a/src/lualib/WeakMap.ts +++ b/src/lualib/WeakMap.ts @@ -1,4 +1,4 @@ -WeakMap = class WeakMap { +WeakMap = class WeakMap { public static [Symbol.species] = WeakMap; public [Symbol.toStringTag] = "WeakMap"; diff --git a/src/lualib/WeakSet.ts b/src/lualib/WeakSet.ts index ebc950a5a..670b3c695 100644 --- a/src/lualib/WeakSet.ts +++ b/src/lualib/WeakSet.ts @@ -1,4 +1,4 @@ -WeakSet = class WeakSet { +WeakSet = class WeakSet { public static [Symbol.species] = WeakSet; public [Symbol.toStringTag] = "WeakSet"; diff --git a/src/lualib/declarations/coroutine.d.ts b/src/lualib/declarations/coroutine.d.ts deleted file mode 100644 index 1e648d6c8..000000000 --- a/src/lualib/declarations/coroutine.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** @noSelfInFile */ - -interface LuaThread { - readonly __internal__: unique symbol; -} - -declare namespace coroutine { - function create(f: (...args: any[]) => any): LuaThread; - - /** @tupleReturn */ - function resume(co: LuaThread, ...val: any[]): [true, ...any[]] | [false, string]; - - function status(co: LuaThread): "running" | "suspended" | "normal" | "dead"; - - function wrap(f: (...args: any[]) => any): /** @tupleReturn */ (...args: any[]) => any[]; - - /** @tupleReturn */ - function yield(...args: any[]): any[]; -} diff --git a/src/lualib/declarations/debug.d.ts b/src/lualib/declarations/debug.d.ts deleted file mode 100644 index a451fe07f..000000000 --- a/src/lualib/declarations/debug.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** @noSelfInFile */ - -declare const _VERSION: string; -declare function error(...args: any[]): never; - -declare namespace debug { - function traceback(...args: any[]): string; - - interface FunctionInfo { - func: T; - name?: string; - namewhat: "global" | "local" | "method" | "field" | ""; - source: string; - short_src: string; - linedefined: number; - lastlinedefined: number; - what: "Lua" | "C" | "main"; - currentline: number; - nups: number; - } - - function getinfo(i: number, what?: string): Partial; -} diff --git a/src/lualib/declarations/global.d.ts b/src/lualib/declarations/global.d.ts deleted file mode 100644 index 450fba8dc..000000000 --- a/src/lualib/declarations/global.d.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* eslint-disable no-var */ -/** @noSelfInFile */ - -declare var __TS__sourcemap: Record | undefined; -declare var __TS__originalTraceback: - | ((this: void, thread?: any, message?: string, level?: number) => string) - | undefined; - -// Override next declaration so we can omit extra return values -declare type NextEmptyCheck = (this: void, table: any, index: undefined) => unknown | undefined; - -declare function tonumber(value: any, base?: number): number | undefined; -declare function type( - value: any -): "nil" | "number" | "string" | "boolean" | "table" | "function" | "thread" | "userdata"; -declare function setmetatable(table: T, metatable: any): T; -declare function getmetatable(table: T): any; -declare function rawget(table: T, key: K): T[K]; -declare function rawset(table: T, key: K, val: T[K]): void; -/** @tupleReturn */ -declare function next(table: Record, index?: K): [K, V]; -declare function pcall(func: () => any): any; -declare function unpack(list: T[], i?: number, j?: number): T[]; - -declare function select(index: number, ...args: T[]): T; -declare function select(index: "#", ...args: T[]): number; - -/** - * @luaIterator - * @tupleReturn - */ -type LuaTupleIterator = Iterable & { " LuaTupleIterator": never }; - -declare function ipairs(t: Record): LuaTupleIterator<[number, T]>; diff --git a/src/lualib/declarations/luatable.d.ts b/src/lualib/declarations/luatable.d.ts deleted file mode 100644 index 63805d283..000000000 --- a/src/lualib/declarations/luatable.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** @LuaTable */ -declare class LuaTable { - public readonly length: number; - public set(key: K, value: V | undefined): void; - public get(key: K): V | undefined; -} diff --git a/src/lualib/declarations/math.d.ts b/src/lualib/declarations/math.d.ts deleted file mode 100644 index 837f717f9..000000000 --- a/src/lualib/declarations/math.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** @noSelf */ -declare namespace math { - /** @tupleReturn */ - function modf(x: number): [number, number]; - - function atan(x: number): number; - // eslint-disable-next-line @typescript-eslint/unified-signatures - function atan(y: number, x?: number): number; - - function atan2(y: number, x: number): number; -} diff --git a/src/lualib/declarations/string.d.ts b/src/lualib/declarations/string.d.ts deleted file mode 100644 index e8d657da6..000000000 --- a/src/lualib/declarations/string.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** @noSelf */ -declare namespace string { - function byte(s: string, i?: number): number | undefined; - /** @tupleReturn */ - function byte(s: string, i?: number, j?: number): number[]; - - /** @tupleReturn */ - function gsub( - source: string, - searchValue: string, - replaceValue: string | ((...groups: string[]) => string), - n?: number - ): [string, number]; - function sub(s: string, i: number, j?: number): string; - function format(formatstring: string, ...args: any[]): string; -} diff --git a/src/lualib/declarations/table.d.ts b/src/lualib/declarations/table.d.ts deleted file mode 100644 index 776fe72b0..000000000 --- a/src/lualib/declarations/table.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** @noSelfInFile */ - -declare namespace table { - function sort(list: T[], compareFn?: (a: T, b: T) => boolean): void; - function remove(list: T[], idx: number): T; - function insert(list: T[], idx: number, val: T): void; - function unpack(list: T[], i?: number, j?: number): T[]; -} diff --git a/src/lualib/declarations/tstl.d.ts b/src/lualib/declarations/tstl.d.ts index 57e436ae3..90a3283ef 100644 --- a/src/lualib/declarations/tstl.d.ts +++ b/src/lualib/declarations/tstl.d.ts @@ -1,24 +1,27 @@ /** @noSelfInFile */ -/** @vararg */ -type Vararg = T & { __luaVararg?: never }; - -/** @forRange */ -declare function forRange(start: number, limit: number, step?: number): number[]; - -interface Metatable { +interface LuaMetatable { _descriptors?: Record; __index?: any; __newindex?: any; __tostring?: any; + __errorToStringPatched?: boolean; } -interface LuaClass extends Metatable { +interface LuaClass extends LuaMetatable { prototype: LuaClassInstance; [Symbol.hasInstance]?(instance: LuaClassInstance): any; ____super?: LuaClass; } -interface LuaClassInstance extends Metatable { +interface LuaClassInstance extends LuaMetatable { constructor: LuaClass; } + +// Declare unpack for versions that have it instead of table.unpack +declare const unpack: typeof table.unpack | undefined; + +// Declare math atan2 for versions that have it instead of math.atan +declare namespace math { + const atan2: typeof atan; +} diff --git a/src/lualib/tsconfig.json b/src/lualib/tsconfig.json index b9d6de8ce..f9d65a555 100644 --- a/src/lualib/tsconfig.json +++ b/src/lualib/tsconfig.json @@ -3,7 +3,7 @@ "outDir": "../../dist/lualib", "target": "esnext", "lib": ["esnext"], - "types": [], + "types": ["../../language-extensions", "lua-types/5.4"], "skipLibCheck": true, "noUnusedLocals": true, diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index 35be01a00..d8bd4dd3b 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -6,6 +6,23 @@ import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; import { isStringType, isNumberType } from "../utils/typescript"; +export function transformArrayConstructorCall( + context: TransformationContext, + node: PropertyCallExpression +): lua.CallExpression | undefined { + const expression = node.expression; + const signature = context.checker.getResolvedSignature(node); + const params = transformArguments(context, node.arguments, signature); + + const expressionName = expression.name.text; + switch (expressionName) { + case "isArray": + return transformLuaLibFunction(context, LuaLibFeature.ArrayIsArray, node, ...params); + default: + context.diagnostics.push(unsupportedProperty(expression.name, "Array", expressionName)); + } +} + export function transformArrayPrototypeCall( context: TransformationContext, node: PropertyCallExpression @@ -19,6 +36,8 @@ export function transformArrayPrototypeCall( switch (expressionName) { case "concat": return transformLuaLibFunction(context, LuaLibFeature.ArrayConcat, node, caller, ...params); + case "entries": + return transformLuaLibFunction(context, LuaLibFeature.ArrayEntries, node, caller); case "push": return transformLuaLibFunction(context, LuaLibFeature.ArrayPush, node, caller, ...params); case "reverse": diff --git a/src/transformation/builtins/global.ts b/src/transformation/builtins/global.ts index 2021951a5..79f359bbd 100644 --- a/src/transformation/builtins/global.ts +++ b/src/transformation/builtins/global.ts @@ -30,5 +30,9 @@ export function transformGlobalCall( node, ...numberParameters ); + case "parseFloat": + return transformLuaLibFunction(context, LuaLibFeature.ParseFloat, node, ...parameters); + case "parseInt": + return transformLuaLibFunction(context, LuaLibFeature.ParseInt, node, ...parameters); } } diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index 1125e96b2..53473b420 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -15,13 +15,14 @@ import { } from "../utils/typescript"; import { PropertyCallExpression } from "../visitors/call"; import { checkForLuaLibType } from "../visitors/class/new"; -import { transformArrayProperty, transformArrayPrototypeCall } from "./array"; +import { transformArrayConstructorCall, transformArrayProperty, transformArrayPrototypeCall } from "./array"; import { transformConsoleCall } from "./console"; import { transformFunctionPrototypeCall, transformFunctionProperty } from "./function"; import { transformGlobalCall } from "./global"; import { transformMathCall, transformMathProperty } from "./math"; import { transformNumberConstructorCall, transformNumberPrototypeCall } from "./number"; import { transformObjectConstructorCall, transformObjectPrototypeCall } from "./object"; +import { transformPromiseConstructorCall } from "./promise"; import { transformStringConstructorCall, transformStringProperty, transformStringPrototypeCall } from "./string"; import { transformSymbolConstructorCall } from "./symbol"; @@ -79,6 +80,8 @@ export function transformBuiltinCallExpression( if (isStandardLibraryType(context, ownerType, undefined)) { const symbol = ownerType.getSymbol(); switch (symbol?.name) { + case "ArrayConstructor": + return transformArrayConstructorCall(context, node); case "Console": return transformConsoleCall(context, node); case "Math": @@ -91,6 +94,8 @@ export function transformBuiltinCallExpression( return transformSymbolConstructorCall(context, node); case "NumberConstructor": return transformNumberConstructorCall(context, node); + case "PromiseConstructor": + return transformPromiseConstructorCall(context, node); } } diff --git a/src/transformation/builtins/object.ts b/src/transformation/builtins/object.ts index 358bebbf5..2db793f91 100644 --- a/src/transformation/builtins/object.ts +++ b/src/transformation/builtins/object.ts @@ -9,20 +9,26 @@ export function transformObjectConstructorCall( expression: PropertyCallExpression ): lua.Expression | undefined { const method = expression.expression; - const parameters = transformArguments(context, expression.arguments); + const args = transformArguments(context, expression.arguments); const methodName = method.name.text; switch (methodName) { case "assign": - return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...args); + case "defineProperty": + return transformLuaLibFunction(context, LuaLibFeature.ObjectDefineProperty, expression, ...args); case "entries": - return transformLuaLibFunction(context, LuaLibFeature.ObjectEntries, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ObjectEntries, expression, ...args); case "fromEntries": - return transformLuaLibFunction(context, LuaLibFeature.ObjectFromEntries, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ObjectFromEntries, expression, ...args); + case "getOwnPropertyDescriptor": + return transformLuaLibFunction(context, LuaLibFeature.ObjectGetOwnPropertyDescriptor, expression, ...args); + case "getOwnPropertyDescriptors": + return transformLuaLibFunction(context, LuaLibFeature.ObjectGetOwnPropertyDescriptors, expression, ...args); case "keys": - return transformLuaLibFunction(context, LuaLibFeature.ObjectKeys, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ObjectKeys, expression, ...args); case "values": - return transformLuaLibFunction(context, LuaLibFeature.ObjectValues, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ObjectValues, expression, ...args); default: context.diagnostics.push(unsupportedProperty(method.name, "Object", methodName)); } diff --git a/src/transformation/builtins/promise.ts b/src/transformation/builtins/promise.ts new file mode 100644 index 000000000..cd30aa718 --- /dev/null +++ b/src/transformation/builtins/promise.ts @@ -0,0 +1,53 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; +import { unsupportedProperty } from "../utils/diagnostics"; +import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { isStandardLibraryType } from "../utils/typescript"; +import { PropertyCallExpression, transformArguments } from "../visitors/call"; + +export function isPromiseClass(context: TransformationContext, node: ts.Identifier) { + const type = context.checker.getTypeAtLocation(node); + return isStandardLibraryType(context, type, undefined) && node.text === "Promise"; +} + +export function createPromiseIdentifier(original: ts.Node) { + return lua.createIdentifier("__TS__Promise", original); +} + +export function transformPromiseConstructorCall( + context: TransformationContext, + node: PropertyCallExpression +): lua.Expression | undefined { + const expression = node.expression; + const signature = context.checker.getResolvedSignature(node); + const params = transformArguments(context, node.arguments, signature); + + const expressionName = expression.name.text; + switch (expressionName) { + case "all": + return transformLuaLibFunction(context, LuaLibFeature.PromiseAll, node, ...params); + case "allSettled": + return transformLuaLibFunction(context, LuaLibFeature.PromiseAllSettled, node, ...params); + case "any": + return transformLuaLibFunction(context, LuaLibFeature.PromiseAny, node, ...params); + case "race": + return transformLuaLibFunction(context, LuaLibFeature.PromiseRace, node, ...params); + case "resolve": + importLuaLibFeature(context, LuaLibFeature.Promise); + return lua.createCallExpression(createStaticPromiseFunctionAccessor("resolve", expression), params, node); + case "reject": + importLuaLibFeature(context, LuaLibFeature.Promise); + return lua.createCallExpression(createStaticPromiseFunctionAccessor("reject", expression), params, node); + default: + context.diagnostics.push(unsupportedProperty(expression.name, "Promise", expressionName)); + } +} + +function createStaticPromiseFunctionAccessor(functionName: string, node: ts.Node) { + return lua.createTableIndexExpression( + lua.createIdentifier("__TS__Promise"), + lua.createStringLiteral(functionName), + node + ); +} diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index 65a76d28b..4cb21ea93 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -129,6 +129,8 @@ export function transformStringPrototypeCall( return transformLuaLibFunction(context, LuaLibFeature.StringStartsWith, node, caller, ...params); case "endsWith": return transformLuaLibFunction(context, LuaLibFeature.StringEndsWith, node, caller, ...params); + case "includes": + return transformLuaLibFunction(context, LuaLibFeature.StringIncludes, node, caller, ...params); case "repeat": const math = lua.createIdentifier("math"); const floor = lua.createStringLiteral("floor"); diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index 4ee4515c4..4dbcf9e10 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -27,8 +27,7 @@ export interface DiagnosticsProducingTypeChecker extends ts.TypeChecker { export class TransformationContext { public readonly diagnostics: ts.Diagnostic[] = []; - public readonly checker: DiagnosticsProducingTypeChecker = (this - .program as any).getDiagnosticsProducingTypeChecker(); + public readonly checker: DiagnosticsProducingTypeChecker = this.program.getDiagnosticsProducingTypeChecker(); public readonly resolver: EmitResolver; public readonly options: CompilerOptions = this.program.getCompilerOptions(); diff --git a/src/transformation/context/visitors.ts b/src/transformation/context/visitors.ts index 5967c18b4..df7cd7acb 100644 --- a/src/transformation/context/visitors.ts +++ b/src/transformation/context/visitors.ts @@ -143,7 +143,7 @@ export type VisitorResult = T extends ExpressionLikeNode : T extends StatementLikeNode ? OneToManyVisitorResult : T extends ts.SourceFile - ? lua.Block + ? lua.File : OneToManyVisitorResult; export type Visitor = FunctionVisitor | ObjectVisitor; diff --git a/src/transformation/index.ts b/src/transformation/index.ts index 69b098811..5b6fca647 100644 --- a/src/transformation/index.ts +++ b/src/transformation/index.ts @@ -1,9 +1,7 @@ import * as ts from "typescript"; import * as lua from "../LuaAST"; -import { LuaLibFeature } from "../LuaLib"; import { getOrUpdate } from "../utils"; import { ObjectVisitor, TransformationContext, VisitorMap, Visitors } from "./context"; -import { getUsedLuaLibFeatures } from "./utils/lualib"; import { standardVisitors } from "./visitors"; export function createVisitorMap(customVisitors: Visitors[]): VisitorMap { @@ -29,23 +27,9 @@ export function createVisitorMap(customVisitors: Visitors[]): VisitorMap { return visitorMap; } -export interface TransformSourceFileResult { - luaAst: lua.Block; - luaLibFeatures: Set; - diagnostics: ts.Diagnostic[]; -} - -export function transformSourceFile( - program: ts.Program, - sourceFile: ts.SourceFile, - visitorMap: VisitorMap -): TransformSourceFileResult { +export function transformSourceFile(program: ts.Program, sourceFile: ts.SourceFile, visitorMap: VisitorMap) { const context = new TransformationContext(program, sourceFile, visitorMap); - const [luaAst] = context.transformNode(sourceFile) as [lua.Block]; + const [file] = context.transformNode(sourceFile) as [lua.File]; - return { - luaAst, - luaLibFeatures: getUsedLuaLibFeatures(context), - diagnostics: context.diagnostics, - }; + return { file, diagnostics: context.diagnostics }; } diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index bd9d052ab..7f7b19652 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -1,6 +1,5 @@ import * as ts from "typescript"; import { TransformationContext } from "../context"; -import { findFirstNodeAbove, inferAssignedType } from "./typescript"; export enum AnnotationKind { Extension = "extension", @@ -17,6 +16,8 @@ export enum AnnotationKind { NoSelfInFile = "noSelfInFile", Vararg = "vararg", ForRange = "forRange", + Jsx = "jsx", + JsxFrag = "jsxFrag", } export interface Annotation { @@ -35,7 +36,7 @@ export type AnnotationsMap = Map; function collectAnnotations(source: ts.Symbol | ts.Signature, annotationsMap: AnnotationsMap): void { for (const tag of source.getJsDocTags()) { - const annotation = createAnnotation(tag.name, tag.text ? tag.text.split(" ") : []); + const annotation = createAnnotation(tag.name, tag.text?.map(p => p.text) ?? []); if (annotation) { annotationsMap.set(annotation.kind, annotation); } @@ -62,7 +63,7 @@ export function getNodeAnnotations(node: ts.Node): AnnotationsMap { for (const tag of ts.getJSDocTags(node)) { const tagName = tag.tagName.text; - const annotation = createAnnotation(tagName, tag.comment ? tag.comment.split(" ") : []); + const annotation = createAnnotation(tagName, getTagArgsFromComment(tag)); if (annotation) { annotationsMap.set(annotation.kind, annotation); } @@ -80,7 +81,7 @@ export function getFileAnnotations(sourceFile: ts.SourceFile): AnnotationsMap { if (jsDoc) { for (const tag of jsDoc.flatMap(x => x.tags ?? [])) { const tagName = tag.tagName.text; - const annotation = createAnnotation(tagName, tag.comment ? tag.comment.split(" ") : []); + const annotation = createAnnotation(tagName, getTagArgsFromComment(tag)); if (annotation) { annotationsMap.set(annotation.kind, annotation); } @@ -133,37 +134,6 @@ export function isTupleReturnCall(context: TransformationContext, node: ts.Node) return getTypeAnnotations(type).has(AnnotationKind.TupleReturn); } -export function isInTupleReturnFunction(context: TransformationContext, node: ts.Node): boolean { - const declaration = findFirstNodeAbove(node, ts.isFunctionLike); - if (!declaration) { - return false; - } - - let functionType: ts.Type | undefined; - if (ts.isFunctionExpression(declaration) || ts.isArrowFunction(declaration)) { - functionType = inferAssignedType(context, declaration); - } else if (ts.isMethodDeclaration(declaration) && ts.isObjectLiteralExpression(declaration.parent)) { - // Manually lookup type for object literal properties declared with method syntax - const interfaceType = inferAssignedType(context, declaration.parent); - const propertySymbol = interfaceType.getProperty(declaration.name.getText()); - if (propertySymbol) { - functionType = context.checker.getTypeOfSymbolAtLocation(propertySymbol, declaration); - } - } - - if (functionType === undefined) { - functionType = context.checker.getTypeAtLocation(declaration); - } - - // Check all overloads for directive - const signatures = functionType.getCallSignatures(); - if (signatures?.some(s => getSignatureAnnotations(context, s).has(AnnotationKind.TupleReturn))) { - return true; - } - - return getTypeAnnotations(functionType).has(AnnotationKind.TupleReturn); -} - export function isLuaIteratorType(context: TransformationContext, node: ts.Node): boolean { const type = context.checker.getTypeAtLocation(node); return getTypeAnnotations(type).has(AnnotationKind.LuaIterator); @@ -178,3 +148,15 @@ export function isForRangeType(context: TransformationContext, node: ts.Node): b const type = context.checker.getTypeAtLocation(node); return getTypeAnnotations(type).has(AnnotationKind.ForRange); } + +export function getTagArgsFromComment(tag: ts.JSDocTag): string[] { + if (tag.comment) { + if (typeof tag.comment === "string") { + return tag.comment.split(" "); + } else { + return tag.comment.map(part => part.text); + } + } + + return []; +} diff --git a/src/transformation/utils/assignment-validation.ts b/src/transformation/utils/assignment-validation.ts index a31a24fdf..e62045248 100644 --- a/src/transformation/utils/assignment-validation.ts +++ b/src/transformation/utils/assignment-validation.ts @@ -34,8 +34,8 @@ export function validateAssignment( validateFunctionAssignment(context, node, fromType, toType, toName); - const fromTypeNode = context.checker.typeToTypeNode(fromType); - const toTypeNode = context.checker.typeToTypeNode(toType); + const fromTypeNode = context.checker.typeToTypeNode(fromType, undefined, undefined); + const toTypeNode = context.checker.typeToTypeNode(toType, undefined, undefined); if (!fromTypeNode || !toTypeNode) { return; } diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index a5bdb35db..a7a63a717 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -3,21 +3,32 @@ import { LuaTarget } from "../../CompilerOptions"; import { createSerialDiagnosticFactory } from "../../utils"; import { AnnotationKind } from "./annotations"; -const createDiagnosticFactory = (message: string | ((...args: TArgs) => string)) => +type MessageProvider = string | ((...args: TArgs) => string); + +const createDiagnosticFactory = ( + category: ts.DiagnosticCategory, + message: MessageProvider +) => createSerialDiagnosticFactory((node: ts.Node, ...args: TArgs) => ({ file: node.getSourceFile(), start: node.getStart(), length: node.getWidth(), messageText: typeof message === "string" ? message : message(...args), + category, })); -export const unsupportedNodeKind = createDiagnosticFactory( +const createErrorDiagnosticFactory = (message: MessageProvider) => + createDiagnosticFactory(ts.DiagnosticCategory.Error, message); +const createWarningDiagnosticFactory = (message: MessageProvider) => + createDiagnosticFactory(ts.DiagnosticCategory.Warning, message); + +export const unsupportedNodeKind = createErrorDiagnosticFactory( (kind: ts.SyntaxKind) => `Unsupported node kind ${ts.SyntaxKind[kind]}` ); -export const forbiddenForIn = createDiagnosticFactory("Iterating over arrays with 'for ... in' is not allowed."); +export const forbiddenForIn = createErrorDiagnosticFactory("Iterating over arrays with 'for ... in' is not allowed."); -export const unsupportedNoSelfFunctionConversion = createDiagnosticFactory((name?: string) => { +export const unsupportedNoSelfFunctionConversion = createErrorDiagnosticFactory((name?: string) => { const nameReference = name ? ` '${name}'` : ""; return ( `Unable to convert function with a 'this' parameter to function${nameReference} with no 'this'. ` + @@ -25,7 +36,7 @@ export const unsupportedNoSelfFunctionConversion = createDiagnosticFactory((name ); }); -export const unsupportedSelfFunctionConversion = createDiagnosticFactory((name?: string) => { +export const unsupportedSelfFunctionConversion = createErrorDiagnosticFactory((name?: string) => { const nameReference = name ? ` '${name}'` : ""; return ( `Unable to convert function with no 'this' parameter to function${nameReference} with 'this'. ` + @@ -33,7 +44,7 @@ export const unsupportedSelfFunctionConversion = createDiagnosticFactory((name?: ); }); -export const unsupportedOverloadAssignment = createDiagnosticFactory((name?: string) => { +export const unsupportedOverloadAssignment = createErrorDiagnosticFactory((name?: string) => { const nameReference = name ? ` to '${name}'` : ""; return ( `Unsupported assignment of function with different overloaded types for 'this'${nameReference}. ` + @@ -41,88 +52,102 @@ export const unsupportedOverloadAssignment = createDiagnosticFactory((name?: str ); }); -export const decoratorInvalidContext = createDiagnosticFactory("Decorator function cannot have 'this: void'."); +export const decoratorInvalidContext = createErrorDiagnosticFactory("Decorator function cannot have 'this: void'."); -export const annotationInvalidArgumentCount = createDiagnosticFactory( +export const annotationInvalidArgumentCount = createErrorDiagnosticFactory( (kind: AnnotationKind, got: number, expected: number) => `'@${kind}' expects ${expected} arguments, but got ${got}.` ); -export const extensionCannotConstruct = createDiagnosticFactory( - "Cannot construct classes with '@extension' or '@metaExtension' annotation." +export const invalidRangeUse = createErrorDiagnosticFactory("$range can only be used in a for...of loop."); + +export const invalidVarargUse = createErrorDiagnosticFactory( + "$vararg can only be used in a spread element ('...$vararg') in global scope." +); + +export const invalidRangeControlVariable = createErrorDiagnosticFactory( + "For loop using $range must declare a single control variable." ); -export const extensionCannotExtend = createDiagnosticFactory( - "Cannot extend classes with '@extension' or '@metaExtension' annotation." +export const invalidMultiIterableWithoutDestructuring = createErrorDiagnosticFactory( + "LuaIterable with a LuaMultiReturn return value type must be destructured." ); -export const extensionCannotExport = createDiagnosticFactory( - "Cannot export classes with '@extension' or '@metaExtension' annotation." +export const unsupportedAccessorInObjectLiteral = createErrorDiagnosticFactory( + "Accessors in object literal are not supported." ); -export const extensionInvalidInstanceOf = createDiagnosticFactory( - "Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation." +export const unsupportedRightShiftOperator = createErrorDiagnosticFactory( + "Right shift operator is not supported for target Lua 5.3. Use `>>>` instead." ); -export const extensionAndMetaExtensionConflict = createDiagnosticFactory( - "Cannot use both '@extension' and '@metaExtension' annotations on the same class." +const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`); +export const unsupportedForTarget = createErrorDiagnosticFactory( + (functionality: string, version: Exclude) => + `${functionality} is/are not supported for target ${getLuaTargetName(version)}.` ); -export const metaExtensionMissingExtends = createDiagnosticFactory( - "'@metaExtension' annotation requires the extension of the metatable class." +export const unsupportedProperty = createErrorDiagnosticFactory( + (parentName: string, property: string) => `${parentName}.${property} is unsupported.` ); -export const invalidForRangeCall = createDiagnosticFactory((message: string) => `Invalid @forRange call: ${message}.`); +export const invalidAmbientIdentifierName = createErrorDiagnosticFactory( + (text: string) => `Invalid ambient identifier name '${text}'. Ambient identifiers must be valid lua identifiers.` +); -export const luaTableMustBeAmbient = createDiagnosticFactory( - "Classes with the '@luaTable' annotation must be ambient." +export const unsupportedVarDeclaration = createErrorDiagnosticFactory( + "`var` declarations are not supported. Use `let` or `const` instead." ); -export const luaTableCannotBeExtended = createDiagnosticFactory( - "Cannot extend classes with the '@luaTable' annotation." +export const invalidMultiFunctionUse = createErrorDiagnosticFactory( + "The $multi function must be called in a return statement." ); -export const luaTableInvalidInstanceOf = createDiagnosticFactory( - "The instanceof operator cannot be used with a '@luaTable' class." +export const invalidMultiFunctionReturnType = createErrorDiagnosticFactory( + "The $multi function cannot be cast to a non-LuaMultiReturn type." ); -export const luaTableCannotBeAccessedDynamically = createDiagnosticFactory("@luaTable cannot be accessed dynamically."); +export const invalidMultiTypeToNonArrayLiteral = createErrorDiagnosticFactory("Expected an array literal."); -export const luaTableForbiddenUsage = createDiagnosticFactory( - (description: string) => `Invalid @luaTable usage: ${description}.` +export const invalidMultiTypeToEmptyPatternOrArrayLiteral = createErrorDiagnosticFactory( + "There must be one or more elements specified here." ); -export const luaIteratorForbiddenUsage = createDiagnosticFactory( - "Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. " + - "You must use a destructuring statement to catch results from a lua iterator with " + - "the '@tupleReturn' annotation." +export const invalidMultiReturnAccess = createErrorDiagnosticFactory( + "The LuaMultiReturn type can only be accessed via an element access expression of a numeric type." ); -export const unsupportedAccessorInObjectLiteral = createDiagnosticFactory( - "Accessors in object literal are not supported." +export const invalidOperatorMappingUse = createErrorDiagnosticFactory( + "This function must always be directly called and cannot be referred to." ); -export const unsupportedRightShiftOperator = createDiagnosticFactory( - "Right shift operator is not supported for target Lua 5.3. Use `>>>` instead." +export const invalidTableExtensionUse = createErrorDiagnosticFactory( + "This function must be called directly and cannot be referred to." ); -const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`); -export const unsupportedForTarget = createDiagnosticFactory( - (functionality: string, version: Exclude) => - `${functionality} is/are not supported for target ${getLuaTargetName(version)}.` +export const invalidTableDeleteExpression = createErrorDiagnosticFactory( + "Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement." ); -export const unsupportedProperty = createDiagnosticFactory( - (parentName: string, property: string) => `${parentName}.${property} is unsupported.` +export const invalidTableSetExpression = createErrorDiagnosticFactory( + "Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement." ); -export const invalidAmbientIdentifierName = createDiagnosticFactory( - (text: string) => `Invalid ambient identifier name '${text}'. Ambient identifiers must be valid lua identifiers.` +export const annotationRemoved = createErrorDiagnosticFactory( + (kind: AnnotationKind) => + `'@${kind}' has been removed and will no longer have any effect.` + + `See https://typescripttolua.github.io/docs/advanced/compiler-annotations#${kind.toLowerCase()} for more information.` ); -export const unresolvableRequirePath = createDiagnosticFactory( - (path: string) => `Cannot create require path. Module '${path}' does not exist within --rootDir.` +export const annotationDeprecated = createWarningDiagnosticFactory( + (kind: AnnotationKind) => + `'@${kind}' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. ` + + `See https://typescripttolua.github.io/docs/advanced/compiler-annotations#${kind.toLowerCase()} for more information.` ); -export const unsupportedVarDeclaration = createDiagnosticFactory( - "`var` declarations are not supported. Use `let` or `const` instead." +export const notAllowedOptionalAssignment = createErrorDiagnosticFactory( + "The left-hand side of an assignment expression may not be an optional property access." +); + +export const awaitMustBeInAsyncFunction = createErrorDiagnosticFactory( + "Await can only be used inside async functions." ); diff --git a/src/transformation/utils/export.ts b/src/transformation/utils/export.ts index d11109427..1edee936c 100644 --- a/src/transformation/utils/export.ts +++ b/src/transformation/utils/export.ts @@ -96,7 +96,7 @@ export function getExportedSymbolsFromScope( export function getDependenciesOfSymbol(context: TransformationContext, originalSymbol: ts.Symbol): ts.Symbol[] { return getExportedSymbolsFromScope(context, context.sourceFile).filter(exportSymbol => exportSymbol.declarations - .filter(ts.isExportSpecifier) + ?.filter(ts.isExportSpecifier) .map(context.checker.getExportSpecifierLocalTargetSymbol) .includes(originalSymbol) ); diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index 8bf05255c..b3e9ee2c5 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -113,17 +113,25 @@ function getSignatureDeclarations( ): ts.SignatureDeclaration[] { return signatures.flatMap(signature => { const signatureDeclaration = signature.getDeclaration(); + let inferredType: ts.Type | undefined; if ( + ts.isMethodDeclaration(signatureDeclaration) && + ts.isObjectLiteralExpression(signatureDeclaration.parent) && + !getExplicitThisParameter(signatureDeclaration) + ) { + inferredType = context.checker.getContextualTypeForObjectLiteralElement(signatureDeclaration); + } else if ( (ts.isFunctionExpression(signatureDeclaration) || ts.isArrowFunction(signatureDeclaration)) && !getExplicitThisParameter(signatureDeclaration) ) { // Infer type of function expressions/arrow functions - const inferredType = inferAssignedType(context, signatureDeclaration); - if (inferredType) { - const inferredSignatures = getAllCallSignatures(inferredType); - if (inferredSignatures.length > 0) { - return inferredSignatures.map(s => s.getDeclaration()); - } + inferredType = inferAssignedType(context, signatureDeclaration); + } + + if (inferredType) { + const inferredSignatures = getAllCallSignatures(inferredType); + if (inferredSignatures.length > 0) { + return inferredSignatures.map(s => s.getDeclaration()); } } diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts new file mode 100644 index 000000000..3861cbf57 --- /dev/null +++ b/src/transformation/utils/language-extensions.ts @@ -0,0 +1,130 @@ +import * as ts from "typescript"; +import { TransformationContext } from "../context"; + +export enum ExtensionKind { + MultiFunction = "MultiFunction", + MultiType = "MultiType", + RangeFunction = "RangeFunction", + VarargConstant = "VarargConstant", + IterableType = "IterableType", + AdditionOperatorType = "AdditionOperatorType", + AdditionOperatorMethodType = "AdditionOperatorMethodType", + SubtractionOperatorType = "SubtractionOperatorType", + SubtractionOperatorMethodType = "SubtractionOperatorMethodType", + MultiplicationOperatorType = "MultiplicationOperatorType", + MultiplicationOperatorMethodType = "MultiplicationOperatorMethodType", + DivisionOperatorType = "DivisionOperatorType", + DivisionOperatorMethodType = "DivisionOperatorMethodType", + ModuloOperatorType = "ModuloOperatorType", + ModuloOperatorMethodType = "ModuloOperatorMethodType", + PowerOperatorType = "PowerOperatorType", + PowerOperatorMethodType = "PowerOperatorMethodType", + FloorDivisionOperatorType = "FloorDivisionOperatorType", + FloorDivisionOperatorMethodType = "FloorDivisionOperatorMethodType", + BitwiseAndOperatorType = "BitwiseAndOperatorType", + BitwiseAndOperatorMethodType = "BitwiseAndOperatorMethodType", + BitwiseOrOperatorType = "BitwiseOrOperatorType", + BitwiseOrOperatorMethodType = "BitwiseOrOperatorMethodType", + BitwiseExclusiveOrOperatorType = "BitwiseExclusiveOrOperatorType", + BitwiseExclusiveOrOperatorMethodType = "BitwiseExclusiveOrOperatorMethodType", + BitwiseLeftShiftOperatorType = "BitwiseLeftShiftOperatorType", + BitwiseLeftShiftOperatorMethodType = "BitwiseLeftShiftOperatorMethodType", + BitwiseRightShiftOperatorType = "BitwiseRightShiftOperatorType", + BitwiseRightShiftOperatorMethodType = "BitwiseRightShiftOperatorMethodType", + ConcatOperatorType = "ConcatOperatorType", + ConcatOperatorMethodType = "ConcatOperatorMethodType", + LessThanOperatorType = "LessThanOperatorType", + LessThanOperatorMethodType = "LessThanOperatorMethodType", + GreaterThanOperatorType = "GreaterThanOperatorType", + GreaterThanOperatorMethodType = "GreaterThanOperatorMethodType", + NegationOperatorType = "NegationOperatorType", + NegationOperatorMethodType = "NegationOperatorMethodType", + BitwiseNotOperatorType = "BitwiseNotOperatorType", + BitwiseNotOperatorMethodType = "BitwiseNotOperatorMethodType", + LengthOperatorType = "LengthOperatorType", + LengthOperatorMethodType = "LengthOperatorMethodType", + TableNewType = "TableNewType", + TableDeleteType = "TableDeleteType", + TableDeleteMethodType = "TableDeleteMethodType", + TableGetType = "TableGetType", + TableGetMethodType = "TableGetMethodType", + TableHasType = "TableHasType", + TableHasMethodType = "TableHasMethodType", + TableSetType = "TableSetType", + TableSetMethodType = "TableSetMethodType", +} + +const extensionKindToValueName: { [T in ExtensionKind]?: string } = { + [ExtensionKind.MultiFunction]: "$multi", + [ExtensionKind.RangeFunction]: "$range", + [ExtensionKind.VarargConstant]: "$vararg", +}; + +const extensionKindToTypeBrand: { [T in ExtensionKind]: string } = { + [ExtensionKind.MultiFunction]: "__luaMultiFunctionBrand", + [ExtensionKind.MultiType]: "__luaMultiReturnBrand", + [ExtensionKind.RangeFunction]: "__luaRangeFunctionBrand", + [ExtensionKind.VarargConstant]: "__luaVarargConstantBrand", + [ExtensionKind.IterableType]: "__luaIterableBrand", + [ExtensionKind.AdditionOperatorType]: "__luaAdditionBrand", + [ExtensionKind.AdditionOperatorMethodType]: "__luaAdditionMethodBrand", + [ExtensionKind.SubtractionOperatorType]: "__luaSubtractionBrand", + [ExtensionKind.SubtractionOperatorMethodType]: "__luaSubtractionMethodBrand", + [ExtensionKind.MultiplicationOperatorType]: "__luaMultiplicationBrand", + [ExtensionKind.MultiplicationOperatorMethodType]: "__luaMultiplicationMethodBrand", + [ExtensionKind.DivisionOperatorType]: "__luaDivisionBrand", + [ExtensionKind.DivisionOperatorMethodType]: "__luaDivisionMethodBrand", + [ExtensionKind.ModuloOperatorType]: "__luaModuloBrand", + [ExtensionKind.ModuloOperatorMethodType]: "__luaModuloMethodBrand", + [ExtensionKind.PowerOperatorType]: "__luaPowerBrand", + [ExtensionKind.PowerOperatorMethodType]: "__luaPowerMethodBrand", + [ExtensionKind.FloorDivisionOperatorType]: "__luaFloorDivisionBrand", + [ExtensionKind.FloorDivisionOperatorMethodType]: "__luaFloorDivisionMethodBrand", + [ExtensionKind.BitwiseAndOperatorType]: "__luaBitwiseAndBrand", + [ExtensionKind.BitwiseAndOperatorMethodType]: "__luaBitwiseAndMethodBrand", + [ExtensionKind.BitwiseOrOperatorType]: "__luaBitwiseOrBrand", + [ExtensionKind.BitwiseOrOperatorMethodType]: "__luaBitwiseOrMethodBrand", + [ExtensionKind.BitwiseExclusiveOrOperatorType]: "__luaBitwiseExclusiveOrBrand", + [ExtensionKind.BitwiseExclusiveOrOperatorMethodType]: "__luaBitwiseExclusiveOrMethodBrand", + [ExtensionKind.BitwiseLeftShiftOperatorType]: "__luaBitwiseLeftShiftBrand", + [ExtensionKind.BitwiseLeftShiftOperatorMethodType]: "__luaBitwiseLeftShiftMethodBrand", + [ExtensionKind.BitwiseRightShiftOperatorType]: "__luaBitwiseRightShiftBrand", + [ExtensionKind.BitwiseRightShiftOperatorMethodType]: "__luaBitwiseRightShiftMethodBrand", + [ExtensionKind.ConcatOperatorType]: "__luaConcatBrand", + [ExtensionKind.ConcatOperatorMethodType]: "__luaConcatMethodBrand", + [ExtensionKind.LessThanOperatorType]: "__luaLessThanBrand", + [ExtensionKind.LessThanOperatorMethodType]: "__luaLessThanMethodBrand", + [ExtensionKind.GreaterThanOperatorType]: "__luaGreaterThanBrand", + [ExtensionKind.GreaterThanOperatorMethodType]: "__luaGreaterThanMethodBrand", + [ExtensionKind.NegationOperatorType]: "__luaNegationBrand", + [ExtensionKind.NegationOperatorMethodType]: "__luaNegationMethodBrand", + [ExtensionKind.BitwiseNotOperatorType]: "__luaBitwiseNotBrand", + [ExtensionKind.BitwiseNotOperatorMethodType]: "__luaBitwiseNotMethodBrand", + [ExtensionKind.LengthOperatorType]: "__luaLengthBrand", + [ExtensionKind.LengthOperatorMethodType]: "__luaLengthMethodBrand", + [ExtensionKind.TableNewType]: "__luaTableNewBrand", + [ExtensionKind.TableDeleteType]: "__luaTableDeleteBrand", + [ExtensionKind.TableDeleteMethodType]: "__luaTableDeleteMethodBrand", + [ExtensionKind.TableGetType]: "__luaTableGetBrand", + [ExtensionKind.TableGetMethodType]: "__luaTableGetMethodBrand", + [ExtensionKind.TableHasType]: "__luaTableHasBrand", + [ExtensionKind.TableHasMethodType]: "__luaTableHasMethodBrand", + [ExtensionKind.TableSetType]: "__luaTableSetBrand", + [ExtensionKind.TableSetMethodType]: "__luaTableSetMethodBrand", +}; + +export function isExtensionType(type: ts.Type, extensionKind: ExtensionKind): boolean { + const typeBrand = extensionKindToTypeBrand[extensionKind]; + return typeBrand !== undefined && type.getProperty(typeBrand) !== undefined; +} + +export function isExtensionValue( + context: TransformationContext, + symbol: ts.Symbol, + extensionKind: ExtensionKind +): boolean { + return ( + symbol.getName() === extensionKindToValueName[extensionKind] && + symbol.declarations?.some(d => isExtensionType(context.checker.getTypeAtLocation(d), extensionKind)) === true + ); +} diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 236e32437..5f3a21e4a 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -4,8 +4,7 @@ import * as lua from "../../LuaAST"; import { assert, castArray } from "../../utils"; import { TransformationContext } from "../context"; import { createExportedIdentifier, getIdentifierExportScope } from "./export"; -import { peekScope, ScopeType } from "./scope"; -import { isFunctionType } from "./typescript"; +import { peekScope, ScopeType, Scope } from "./scope"; import { transformLuaLibFunction } from "./lualib"; import { LuaLibFeature } from "../../LuaLib"; @@ -63,6 +62,8 @@ export function getNumberLiteralValue(expression?: lua.Expression) { return undefined; } +// Prefer use of transformToImmediatelyInvokedFunctionExpression to maintain correct scope. If you use this directly, +// ensure you push/pop a function scope appropriately to avoid incorrect vararg optimization. export function createImmediatelyInvokedFunctionExpression( statements: lua.Statement[], result: lua.Expression | lua.Expression[], @@ -129,6 +130,17 @@ export function createHoistableVariableDeclarationStatement( return declaration; } +function hasMultipleReferences(scope: Scope, identifiers: lua.Identifier | lua.Identifier[]) { + const scopeSymbols = scope.referencedSymbols; + if (!scopeSymbols) { + return false; + } + + const referenceLists = castArray(identifiers).map(i => i.symbolId && scopeSymbols.get(i.symbolId)); + + return referenceLists.some(symbolRefs => symbolRefs && symbolRefs.length > 1); +} + export function createLocalOrExportedOrGlobalDeclaration( context: TransformationContext, lhs: lua.Identifier | lua.Identifier[], @@ -163,17 +175,12 @@ export function createLocalOrExportedOrGlobalDeclaration( const isTopLevelVariable = scope.type === ScopeType.File; if (context.isModule || !isTopLevelVariable) { - const isPossibleWrappedFunction = - !isFunctionDeclaration && - tsOriginal && - ts.isVariableDeclaration(tsOriginal) && - tsOriginal.initializer && - isFunctionType(context, context.checker.getTypeAtLocation(tsOriginal.initializer)); - - if (isPossibleWrappedFunction || scope.type === ScopeType.Switch) { - // Split declaration and assignment for wrapped function types to allow recursion + if (scope.type === ScopeType.Switch || (!isFunctionDeclaration && hasMultipleReferences(scope, lhs))) { + // Split declaration and assignment of identifiers that reference themselves in their declaration declaration = lua.createVariableDeclarationStatement(lhs, undefined, tsOriginal); - assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal); + if (rhs) { + assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal); + } } else { declaration = lua.createVariableDeclarationStatement(lhs, rhs, tsOriginal); } diff --git a/src/transformation/utils/safe-names.ts b/src/transformation/utils/safe-names.ts index c072135f4..877196ba4 100644 --- a/src/transformation/utils/safe-names.ts +++ b/src/transformation/utils/safe-names.ts @@ -72,7 +72,7 @@ export function hasUnsafeSymbolName( symbol: ts.Symbol, tsOriginal: ts.Identifier ): boolean { - const isAmbient = symbol.declarations && symbol.declarations.some(d => isAmbientNode(d)); + const isAmbient = symbol.declarations?.some(d => isAmbientNode(d)) ?? false; // Catch ambient declarations of identifiers with bad names if (isAmbient && checkName(context, symbol.name, tsOriginal)) { diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 2c9f267dd..53169765a 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -3,7 +3,7 @@ import * as lua from "../../LuaAST"; import { assert, getOrUpdate, isNonNull } from "../../utils"; import { TransformationContext } from "../context"; import { getSymbolInfo } from "./symbols"; -import { getFirstDeclarationInFile } from "./typescript"; +import { findFirstNodeAbove, getFirstDeclarationInFile } from "./typescript"; export enum ScopeType { File = 1 << 0, @@ -24,6 +24,7 @@ interface FunctionDefinitionInfo { export interface Scope { type: ScopeType; id: number; + node?: ts.Node; referencedSymbols?: Map; variableDeclarations?: lua.VariableDeclarationStatement[]; functionDefinitions?: Map; @@ -91,6 +92,47 @@ export function popScope(context: TransformationContext): Scope { return scope; } +function isHoistableFunctionDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Node) { + return symbol?.declarations?.some( + d => ts.isFunctionDeclaration(d) && findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode) + ); +} + +// Checks for references to local functions which haven't been defined yet, +// and thus will be hoisted above the current position. +export function hasReferencedUndefinedLocalFunction(context: TransformationContext, scope: Scope) { + if (!scope.referencedSymbols || !scope.node) { + return false; + } + for (const [symbolId, nodes] of scope.referencedSymbols) { + const type = context.checker.getTypeAtLocation(nodes[0]); + if ( + !scope.functionDefinitions?.has(symbolId) && + type.getCallSignatures().length > 0 && + isHoistableFunctionDeclaredInScope(type.symbol, scope.node) + ) { + return true; + } + } + return false; +} + +export function hasReferencedSymbol(context: TransformationContext, scope: Scope, symbol: ts.Symbol) { + if (!scope.referencedSymbols) { + return; + } + for (const nodes of scope.referencedSymbols.values()) { + if (nodes.some(node => context.checker.getSymbolAtLocation(node) === symbol)) { + return true; + } + } + return false; +} + +export function isFunctionScopeWithDefinition(scope: Scope): scope is Scope & { node: ts.SignatureDeclaration } { + return scope.node !== undefined && ts.isFunctionLike(scope.node); +} + export function performHoisting(context: TransformationContext, statements: lua.Statement[]): lua.Statement[] { const scope = peekScope(context); let result = statements; diff --git a/src/transformation/utils/symbols.ts b/src/transformation/utils/symbols.ts index c99b41a25..f800eea86 100644 --- a/src/transformation/utils/symbols.ts +++ b/src/transformation/utils/symbols.ts @@ -2,6 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { getOrUpdate } from "../../utils"; import { TransformationContext } from "../context"; +import { isOptimizedVarArgSpread } from "../visitors/spread"; import { markSymbolAsReferencedInCurrentScopes } from "./scope"; const symbolIdCounters = new WeakMap(); @@ -44,7 +45,11 @@ export function trackSymbolReference( symbolInfo.set(symbolId, { symbol, firstSeenAtPos: identifier.pos }); } - markSymbolAsReferencedInCurrentScopes(context, symbolId, identifier); + // If isOptimizedVarArgSpread returns true, the identifier will not appear in the resulting Lua. + // Only the optimized ellipses (...) will be used. + if (!isOptimizedVarArgSpread(context, symbol, identifier)) { + markSymbolAsReferencedInCurrentScopes(context, symbolId, identifier); + } return symbolId; } diff --git a/src/transformation/utils/transform.ts b/src/transformation/utils/transform.ts new file mode 100644 index 000000000..215a018d5 --- /dev/null +++ b/src/transformation/utils/transform.ts @@ -0,0 +1,22 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { castArray } from "../../utils"; +import { TransformationContext } from "../context"; +import { createImmediatelyInvokedFunctionExpression } from "./lua-ast"; +import { ScopeType, pushScope, popScope } from "./scope"; + +export interface ImmediatelyInvokedFunctionParameters { + statements: lua.Statement | lua.Statement[]; + result: lua.Expression | lua.Expression[]; +} + +export function transformToImmediatelyInvokedFunctionExpression( + context: TransformationContext, + transformFunction: () => ImmediatelyInvokedFunctionParameters, + tsOriginal?: ts.Node +): lua.CallExpression { + pushScope(context, ScopeType.Function); + const { statements, result } = transformFunction(); + popScope(context); + return createImmediatelyInvokedFunctionExpression(castArray(statements), result, tsOriginal); +} diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index 394d67656..6d7bfa68c 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -32,7 +32,8 @@ export function getFirstDeclarationInFile(symbol: ts.Symbol, sourceFile: ts.Sour } function isStandardLibraryDeclaration(context: TransformationContext, declaration: ts.Declaration): boolean { - const sourceFile = declaration.getSourceFile(); + const parseTreeNode = ts.getParseTreeNode(declaration) ?? declaration; + const sourceFile = parseTreeNode.getSourceFile(); if (!sourceFile) { return false; } @@ -79,3 +80,15 @@ export function getAllCallSignatures(type: ts.Type): readonly ts.Signature[] { export function isExpressionWithEvaluationEffect(node: ts.Expression): boolean { return !(ts.isLiteralExpression(node) || ts.isIdentifier(node) || node.kind === ts.SyntaxKind.ThisKeyword); } + +export function getFunctionTypeForCall(context: TransformationContext, node: ts.CallExpression) { + const signature = context.checker.getResolvedSignature(node); + if (!signature || !signature.declaration) { + return; + } + const typeDeclaration = findFirstNodeAbove(signature.declaration, ts.isTypeAliasDeclaration); + if (!typeDeclaration) { + return; + } + return context.checker.getTypeFromTypeNode(typeDeclaration.type); +} diff --git a/src/transformation/utils/typescript/nodes.ts b/src/transformation/utils/typescript/nodes.ts index db0f85641..3007c4d7d 100644 --- a/src/transformation/utils/typescript/nodes.ts +++ b/src/transformation/utils/typescript/nodes.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import { TransformationContext } from "../../context"; export function isAssignmentPattern(node: ts.Node): node is ts.AssignmentPattern { return ts.isObjectLiteralExpression(node) || ts.isArrayLiteralExpression(node); @@ -23,3 +24,15 @@ export function isInDestructingAssignment(node: ts.Node): boolean { (ts.isBinaryExpression(node.parent) && ts.isArrayLiteralExpression(node.parent.left))) ); } + +/** + * Quite hacky, avoid unless absolutely necessary! + */ +export function getSymbolOfNode(context: TransformationContext, node: ts.Node): ts.Symbol | undefined { + return (node as any).symbol ?? context.checker.getSymbolAtLocation(node); +} + +export function isFirstDeclaration(context: TransformationContext, node: ts.Node) { + const symbol = getSymbolOfNode(context, node); + return symbol ? symbol.valueDeclaration === node : true; +} diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index eaa5591b7..389bbde5f 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -3,11 +3,12 @@ import * as lua from "../../LuaAST"; import { transformBuiltinPropertyAccessExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; +import { annotationRemoved, invalidMultiReturnAccess } from "../utils/diagnostics"; import { addToNumericExpression } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; import { tryGetConstEnumValue } from "./enum"; -import { transformLuaTablePropertyAccessExpression, validateLuaTableElementAccessExpression } from "./lua-table"; +import { isMultiReturnCall, returnsMultiType } from "./language-extensions/multi"; export function transformElementAccessArgument( context: TransformationContext, @@ -25,8 +26,6 @@ export function transformElementAccessArgument( } export const transformElementAccessExpression: FunctionVisitor = (node, context) => { - validateLuaTableElementAccessExpression(context, node); - const constEnumValue = tryGetConstEnumValue(context, node); if (constEnumValue) { return constEnumValue; @@ -41,50 +40,88 @@ export const transformElementAccessExpression: FunctionVisitor = ( - expression, - context -) => { - const constEnumValue = tryGetConstEnumValue(context, expression); - if (constEnumValue) { - return constEnumValue; +export const transformPropertyAccessExpression: FunctionVisitor = (node, context) => { + const property = node.name.text; + const type = context.checker.getTypeAtLocation(node.expression); + + const annotations = getTypeAnnotations(type); + + if (annotations.has(AnnotationKind.LuaTable)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.LuaTable)); } - const luaTableResult = transformLuaTablePropertyAccessExpression(context, expression); - if (luaTableResult) { - return luaTableResult; + const constEnumValue = tryGetConstEnumValue(context, node); + if (constEnumValue) { + return constEnumValue; } - const builtinResult = transformBuiltinPropertyAccessExpression(context, expression); + const builtinResult = transformBuiltinPropertyAccessExpression(context, node); if (builtinResult) { return builtinResult; } - const property = expression.name.text; - const type = context.checker.getTypeAtLocation(expression.expression); + if (ts.isCallExpression(node.expression) && returnsMultiType(context, node.expression)) { + context.diagnostics.push(invalidMultiReturnAccess(node)); + } - const annotations = getTypeAnnotations(type); // Do not output path for member only enums if (annotations.has(AnnotationKind.CompileMembersOnly)) { - if (ts.isPropertyAccessExpression(expression.expression)) { + if (ts.isPropertyAccessExpression(node.expression)) { // in case of ...x.enum.y transform to ...x.y return lua.createTableIndexExpression( - context.transformExpression(expression.expression.expression), + context.transformExpression(node.expression.expression), lua.createStringLiteral(property), - expression + node ); } else { - return lua.createIdentifier(property, expression); + return lua.createIdentifier(property, node); } } - const callPath = context.transformExpression(expression.expression); - return lua.createTableIndexExpression(callPath, lua.createStringLiteral(property), expression); + if (ts.isOptionalChain(node)) { + // Only handle full optional chains separately, not partial ones + return transformOptionalChain(context, node); + } + + const callPath = context.transformExpression(node.expression); + return lua.createTableIndexExpression(callPath, lua.createStringLiteral(property), node); }; +function transformOptionalChain( + context: TransformationContext, + node: ts.OptionalChain & ts.PropertyAccessExpression +): lua.CallExpression { + const left = context.transformExpression(node.expression); + const right = lua.createStringLiteral(node.name.text, node.name); + + return transformLuaLibFunction(context, LuaLibFeature.OptionalChainAccess, node, left, right); +} + export const transformQualifiedName: FunctionVisitor = (node, context) => { const right = lua.createStringLiteral(node.right.text, node.right); const left = context.transformExpression(node.left); diff --git a/src/transformation/visitors/async-await.ts b/src/transformation/visitors/async-await.ts new file mode 100644 index 000000000..c6dcc86dc --- /dev/null +++ b/src/transformation/visitors/async-await.ts @@ -0,0 +1,36 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { awaitMustBeInAsyncFunction } from "../utils/diagnostics"; +import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { findFirstNodeAbove } from "../utils/typescript"; + +export const transformAwaitExpression: FunctionVisitor = (node, context) => { + // Check if await is inside an async function, it is not allowed at top level or in non-async functions + const containingFunction = findFirstNodeAbove(node, ts.isFunctionLike); + if ( + containingFunction === undefined || + !containingFunction.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) + ) { + context.diagnostics.push(awaitMustBeInAsyncFunction(node)); + } + + const expression = context.transformExpression(node.expression); + return transformLuaLibFunction(context, LuaLibFeature.Await, node, expression); +}; + +export function isAsyncFunction(declaration: ts.FunctionLikeDeclaration): boolean { + return declaration.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) ?? false; +} + +export function wrapInAsyncAwaiter(context: TransformationContext, statements: lua.Statement[]): lua.Statement[] { + importLuaLibFeature(context, LuaLibFeature.Await); + + return [ + lua.createReturnStatement([ + lua.createCallExpression(lua.createIdentifier("__TS__AsyncAwaiter"), [ + lua.createFunctionExpression(lua.createBlock(statements)), + ]), + ]), + ]; +} diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index 94e17e9c7..b934ca2e0 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -2,24 +2,27 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { cast } from "../../../utils"; import { TransformationContext } from "../../context"; -import { isTupleReturnCall } from "../../utils/annotations"; import { validateAssignment } from "../../utils/assignment-validation"; import { createExportedIdentifier, getDependenciesOfSymbol, isSymbolExported } from "../../utils/export"; -import { createImmediatelyInvokedFunctionExpression, createUnpackCall, wrapInTable } from "../../utils/lua-ast"; +import { createUnpackCall, wrapInTable } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isDestructuringAssignment } from "../../utils/typescript"; import { transformElementAccessArgument } from "../access"; -import { transformLuaTablePropertyAccessInAssignment } from "../lua-table"; import { isArrayLength, transformDestructuringAssignment } from "./destructuring-assignments"; +import { isMultiReturnCall } from "../language-extensions/multi"; +import { popScope, pushScope, ScopeType } from "../../utils/scope"; +import { + ImmediatelyInvokedFunctionParameters, + transformToImmediatelyInvokedFunctionExpression, +} from "../../utils/transform"; +import { notAllowedOptionalAssignment } from "../../utils/diagnostics"; export function transformAssignmentLeftHandSideExpression( context: TransformationContext, node: ts.Expression ): lua.AssignmentLeftHandSideExpression { const symbol = context.checker.getSymbolAtLocation(node); - const left = ts.isPropertyAccessExpression(node) - ? transformLuaTablePropertyAccessInAssignment(context, node) ?? context.transformExpression(node) - : context.transformExpression(node); + const left = context.transformExpression(node); return lua.isIdentifier(left) && symbol && isSymbolExported(context, symbol) ? createExportedIdentifier(context, left) @@ -33,6 +36,11 @@ export function transformAssignment( right: lua.Expression, parent?: ts.Expression ): lua.Statement[] { + if (ts.isOptionalChain(lhs)) { + context.diagnostics.push(notAllowedOptionalAssignment(lhs)); + return []; + } + if (isArrayLength(context, lhs)) { const arrayLengthAssignment = lua.createExpressionStatement( transformLuaLibFunction( @@ -67,6 +75,25 @@ export function transformAssignment( ]; } +function transformDestructuredAssignmentExpression( + context: TransformationContext, + expression: ts.DestructuringAssignment +): ImmediatelyInvokedFunctionParameters { + const rootIdentifier = lua.createAnonymousIdentifier(expression.left); + + let right = context.transformExpression(expression.right); + if (isMultiReturnCall(context, expression.right)) { + right = wrapInTable(right); + } + + const statements = [ + lua.createVariableDeclarationStatement(rootIdentifier, right), + ...transformDestructuringAssignment(context, expression, rootIdentifier), + ]; + + return { statements, result: rootIdentifier }; +} + export function transformAssignmentExpression( context: TransformationContext, expression: ts.AssignmentExpression @@ -88,19 +115,11 @@ export function transformAssignmentExpression( } if (isDestructuringAssignment(expression)) { - const rootIdentifier = lua.createAnonymousIdentifier(expression.left); - - let right = context.transformExpression(expression.right); - if (isTupleReturnCall(context, expression.right)) { - right = wrapInTable(right); - } - - const statements = [ - lua.createVariableDeclarationStatement(rootIdentifier, right), - ...transformDestructuringAssignment(context, expression, rootIdentifier), - ]; - - return createImmediatelyInvokedFunctionExpression(statements, rootIdentifier, expression); + return transformToImmediatelyInvokedFunctionExpression( + context, + () => transformDestructuredAssignmentExpression(context, expression), + expression + ); } if (ts.isPropertyAccessExpression(expression.left) || ts.isElementAccessExpression(expression.left)) { @@ -119,12 +138,10 @@ export function transformAssignmentExpression( indexParameter, valueParameter, ]); + pushScope(context, ScopeType.Function); const objExpression = context.transformExpression(expression.left.expression); let indexExpression: lua.Expression; if (ts.isPropertyAccessExpression(expression.left)) { - // Called only for validation - transformLuaTablePropertyAccessInAssignment(context, expression.left); - // Property access indexExpression = lua.createStringLiteral(expression.left.name.text); } else { @@ -133,15 +150,19 @@ export function transformAssignmentExpression( } const args = [objExpression, indexExpression, context.transformExpression(expression.right)]; + popScope(context); return lua.createCallExpression(iife, args, expression); } else { - // Simple assignment - // (function() ${left} = ${right}; return ${left} end)() - const left = context.transformExpression(expression.left); - const right = context.transformExpression(expression.right); - return createImmediatelyInvokedFunctionExpression( - transformAssignment(context, expression.left, right), - left, + return transformToImmediatelyInvokedFunctionExpression( + context, + () => { + // Simple assignment + // (function() ${left} = ${right}; return ${left} end)() + const left = context.transformExpression(expression.left); + const right = context.transformExpression(expression.right); + const statements = transformAssignment(context, expression.left, right); + return { statements, result: left }; + }, expression ); } @@ -182,9 +203,11 @@ export function transformAssignmentStatement( if (isDestructuringAssignment(expression)) { if (canBeTransformedToLuaAssignmentStatement(context, expression)) { const rightType = context.checker.getTypeAtLocation(expression.right); - let right = context.transformExpression(expression.right); + let right: lua.Expression | lua.Expression[] = context.transformExpression(expression.right); - if (!isTupleReturnCall(context, expression.right) && isArrayType(context, rightType)) { + if (ts.isArrayLiteralExpression(expression.right)) { + right = expression.right.elements.map(e => context.transformExpression(e)); + } else if (!isMultiReturnCall(context, expression.right) && isArrayType(context, rightType)) { right = createUnpackCall(context, right, expression.right); } @@ -194,7 +217,7 @@ export function transformAssignmentStatement( } let right = context.transformExpression(expression.right); - if (isTupleReturnCall(context, expression.right)) { + if (isMultiReturnCall(context, expression.right)) { right = wrapInTable(right); } diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index 0eec44875..febd7681e 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -1,8 +1,11 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { cast } from "../../../utils"; +import { cast, assertNever } from "../../../utils"; import { TransformationContext } from "../../context"; -import { createImmediatelyInvokedFunctionExpression } from "../../utils/lua-ast"; +import { + ImmediatelyInvokedFunctionParameters, + transformToImmediatelyInvokedFunctionExpression, +} from "../../utils/transform"; import { isArrayType, isExpressionWithEvaluationEffect } from "../../utils/typescript"; import { transformBinaryOperation } from "../binary-expression"; import { transformAssignment } from "./assignments"; @@ -19,15 +22,15 @@ export function parseAccessExpressionWithEvaluationEffects( const type = context.checker.getTypeAtLocation(node.expression); if (isArrayType(context, type)) { // Offset arrays by one - const oneLit = ts.createNumericLiteral("1"); - const exp = ts.createParen(node.argumentExpression); - const addExp = ts.createBinary(exp, ts.SyntaxKind.PlusToken, oneLit); + const oneLit = ts.factory.createNumericLiteral("1"); + const exp = ts.factory.createParenthesizedExpression(node.argumentExpression); + const addExp = ts.factory.createBinaryExpression(exp, ts.SyntaxKind.PlusToken, oneLit); return [node.expression, addExp]; } else { return [node.expression, node.argumentExpression]; } } else if (ts.isPropertyAccessExpression(node) && isExpressionWithEvaluationEffect(node.expression)) { - return [node.expression, ts.createStringLiteral(node.name.text)]; + return [node.expression, ts.factory.createStringLiteral(node.name.text)]; } return []; @@ -46,7 +49,10 @@ type CompoundAssignmentToken = | ts.SyntaxKind.AsteriskAsteriskToken | ts.SyntaxKind.LessThanLessThanToken | ts.SyntaxKind.GreaterThanGreaterThanToken - | ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken; + | ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken + | ts.SyntaxKind.BarBarToken + | ts.SyntaxKind.AmpersandAmpersandToken + | ts.SyntaxKind.QuestionQuestionToken; const compoundToAssignmentTokens: Record = { [ts.SyntaxKind.BarEqualsToken]: ts.SyntaxKind.BarToken, @@ -61,6 +67,9 @@ const compoundToAssignmentTokens: Record @@ -69,15 +78,14 @@ export const isCompoundAssignmentToken = (token: ts.BinaryOperator): token is ts export const unwrapCompoundAssignmentToken = (token: ts.CompoundAssignmentOperator): CompoundAssignmentToken => compoundToAssignmentTokens[token]; -export function transformCompoundAssignmentExpression( +export function transformCompoundAssignment( context: TransformationContext, expression: ts.Expression, - // TODO: Change type to ts.LeftHandSideExpression? lhs: ts.Expression, rhs: ts.Expression, operator: CompoundAssignmentToken, isPostfix: boolean -): lua.CallExpression { +): ImmediatelyInvokedFunctionParameters { const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); const right = context.transformExpression(rhs); @@ -110,11 +118,7 @@ export function transformCompoundAssignmentExpression( assignStatement = lua.createAssignmentStatement(accessExpression, tmp); } // return ____tmp - return createImmediatelyInvokedFunctionExpression( - [objAndIndexDeclaration, tmpDeclaration, assignStatement], - tmp, - expression - ); + return { statements: [objAndIndexDeclaration, tmpDeclaration, assignStatement], result: tmp }; } else if (isPostfix) { // Postfix expressions need to cache original value in temp // local ____tmp = ${left}; @@ -124,11 +128,7 @@ export function transformCompoundAssignmentExpression( const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, left); const operatorExpression = transformBinaryOperation(context, tmpIdentifier, right, operator, expression); const assignStatements = transformAssignment(context, lhs, operatorExpression); - return createImmediatelyInvokedFunctionExpression( - [tmpDeclaration, ...assignStatements], - tmpIdentifier, - expression - ); + return { statements: [tmpDeclaration, ...assignStatements], result: tmpIdentifier }; } else if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) { // Simple property/element access expressions need to cache in temp to avoid double-evaluation // local ____tmp = ${left} ${replacementOperator} ${right}; @@ -138,20 +138,41 @@ export function transformCompoundAssignmentExpression( const operatorExpression = transformBinaryOperation(context, left, right, operator, expression); const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, operatorExpression); const assignStatements = transformAssignment(context, lhs, tmpIdentifier); - return createImmediatelyInvokedFunctionExpression( - [tmpDeclaration, ...assignStatements], - tmpIdentifier, - expression - ); + + if (isSetterSkippingCompoundAssignmentOperator(operator)) { + const statements = [ + tmpDeclaration, + ...transformSetterSkippingCompoundAssignment(context, tmpIdentifier, operator, rhs), + ]; + return { statements, result: tmpIdentifier }; + } + + return { statements: [tmpDeclaration, ...assignStatements], result: tmpIdentifier }; } else { // Simple expressions // ${left} = ${right}; return ${right} const operatorExpression = transformBinaryOperation(context, left, right, operator, expression); - const assignStatements = transformAssignment(context, lhs, operatorExpression); - return createImmediatelyInvokedFunctionExpression(assignStatements, left, expression); + const statements = transformAssignment(context, lhs, operatorExpression); + return { statements, result: left }; } } +export function transformCompoundAssignmentExpression( + context: TransformationContext, + expression: ts.Expression, + // TODO: Change type to ts.LeftHandSideExpression? + lhs: ts.Expression, + rhs: ts.Expression, + operator: CompoundAssignmentToken, + isPostfix: boolean +): lua.CallExpression { + return transformToImmediatelyInvokedFunctionExpression( + context, + () => transformCompoundAssignment(context, expression, lhs, rhs, operator, isPostfix), + expression + ); +} + export function transformCompoundAssignmentStatement( context: TransformationContext, node: ts.Node, @@ -174,13 +195,74 @@ export function transformCompoundAssignmentStatement( [context.transformExpression(objExpression), context.transformExpression(indexExpression)] ); const accessExpression = lua.createTableIndexExpression(obj, index); + + if (isSetterSkippingCompoundAssignmentOperator(operator)) { + return [ + objAndIndexDeclaration, + ...transformSetterSkippingCompoundAssignment(context, accessExpression, operator, rhs, node), + ]; + } + const operatorExpression = transformBinaryOperation(context, accessExpression, right, operator, node); const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression); return [objAndIndexDeclaration, assignStatement]; } else { + if (isSetterSkippingCompoundAssignmentOperator(operator)) { + const luaLhs = context.transformExpression(lhs) as lua.AssignmentLeftHandSideExpression; + return transformSetterSkippingCompoundAssignment(context, luaLhs, operator, rhs, node); + } + // Simple statements // ${left} = ${left} ${replacementOperator} ${right} const operatorExpression = transformBinaryOperation(context, left, right, operator, node); return transformAssignment(context, lhs, operatorExpression); } } + +/* These setter-skipping operators will not execute the setter if result does not change. + * x.y ||= z does NOT call the x.y setter if x.y is already true. + * x.y &&= z does NOT call the x.y setter if x.y is already false. + * x.y ??= z does NOT call the x.y setter if x.y is already not nullish. + */ +type SetterSkippingCompoundAssignmentOperator = ts.LogicalOperator | ts.SyntaxKind.QuestionQuestionToken; + +function isSetterSkippingCompoundAssignmentOperator( + operator: ts.BinaryOperator +): operator is SetterSkippingCompoundAssignmentOperator { + return ( + operator === ts.SyntaxKind.AmpersandAmpersandToken || + operator === ts.SyntaxKind.BarBarToken || + operator === ts.SyntaxKind.QuestionQuestionToken + ); +} + +function transformSetterSkippingCompoundAssignment( + context: TransformationContext, + lhs: lua.AssignmentLeftHandSideExpression, + operator: SetterSkippingCompoundAssignmentOperator, + rhs: ts.Expression, + node?: ts.Node +): lua.Statement[] { + // These assignments have the form 'if x then y = z', figure out what condition x is first. + let condition: lua.Expression; + + if (operator === ts.SyntaxKind.AmpersandAmpersandToken) { + condition = lhs; + } else if (operator === ts.SyntaxKind.BarBarToken) { + condition = lua.createUnaryExpression(lhs, lua.SyntaxKind.NotOperator); + } else if (operator === ts.SyntaxKind.QuestionQuestionToken) { + condition = lua.createBinaryExpression(lhs, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator); + } else { + assertNever(operator); + } + + // if condition then lhs = rhs end + return [ + lua.createIfStatement( + condition, + lua.createBlock([lua.createAssignmentStatement(lhs, context.transformExpression(rhs))]), + undefined, + node + ), + ]; +} diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index 356b2bcff..93ea66018 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -1,9 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; -import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { extensionInvalidInstanceOf, luaTableInvalidInstanceOf } from "../../utils/diagnostics"; -import { createImmediatelyInvokedFunctionExpression, wrapInToStringForConcat } from "../../utils/lua-ast"; +import { wrapInToStringForConcat } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isStandardLibraryType, isStringType, typeCanSatisfy } from "../../utils/typescript"; import { transformTypeOfBinaryExpression } from "../typeof"; @@ -15,6 +13,8 @@ import { transformCompoundAssignmentStatement, unwrapCompoundAssignmentToken, } from "./compound"; +import { assert } from "../../../utils"; +import { transformToImmediatelyInvokedFunctionExpression } from "../../utils/transform"; type SimpleOperator = | ts.AdditiveOperatorOrHigher @@ -45,22 +45,30 @@ export function transformBinaryOperation( context: TransformationContext, left: lua.Expression, right: lua.Expression, - operator: BitOperator | SimpleOperator, + operator: BitOperator | SimpleOperator | ts.SyntaxKind.QuestionQuestionToken, node: ts.Node ): lua.Expression { if (isBitOperator(operator)) { return transformBinaryBitOperation(context, node, left, right, operator); } + if (operator === ts.SyntaxKind.QuestionQuestionToken) { + assert(ts.isBinaryExpression(node)); + return transformNullishCoalescingExpression(context, node, left, right); + } + let luaOperator = simpleOperatorsToLua[operator]; // Check if we need to use string concat operator if (operator === ts.SyntaxKind.PlusToken && ts.isBinaryExpression(node)) { const typeLeft = context.checker.getTypeAtLocation(node.left); const typeRight = context.checker.getTypeAtLocation(node.right); - if (isStringType(context, typeLeft) || isStringType(context, typeRight)) { - left = wrapInToStringForConcat(left); - right = wrapInToStringForConcat(right); + + const isLeftString = isStringType(context, typeLeft); + const isRightString = isStringType(context, typeRight); + if (isLeftString || isRightString) { + left = isLeftString ? left : wrapInToStringForConcat(left); + right = isRightString ? right : wrapInToStringForConcat(right); luaOperator = lua.SyntaxKind.ConcatOperator; } } @@ -77,14 +85,8 @@ export const transformBinaryExpression: FunctionVisitor = ( } if (isCompoundAssignmentToken(operator)) { - return transformCompoundAssignmentExpression( - context, - node, - node.left, - node.right, - unwrapCompoundAssignmentToken(operator), - false - ); + const token = unwrapCompoundAssignmentToken(operator); + return transformCompoundAssignmentExpression(context, node, node.left, node.right, token, false); } switch (operator) { @@ -107,15 +109,6 @@ export const transformBinaryExpression: FunctionVisitor = ( const lhs = context.transformExpression(node.left); const rhs = context.transformExpression(node.right); const rhsType = context.checker.getTypeAtLocation(node.right); - const annotations = getTypeAnnotations(rhsType); - - if (annotations.has(AnnotationKind.Extension) || annotations.has(AnnotationKind.MetaExtension)) { - context.diagnostics.push(extensionInvalidInstanceOf(node)); - } - - if (annotations.has(AnnotationKind.LuaTable)) { - context.diagnostics.push(luaTableInvalidInstanceOf(node)); - } if (isStandardLibraryType(context, rhsType, "ObjectConstructor")) { return transformLuaLibFunction(context, LuaLibFeature.InstanceOfObject, node, lhs); @@ -125,17 +118,16 @@ export const transformBinaryExpression: FunctionVisitor = ( } case ts.SyntaxKind.CommaToken: { - return createImmediatelyInvokedFunctionExpression( - context.transformStatements(ts.createExpressionStatement(node.left)), - context.transformExpression(node.right), + return transformToImmediatelyInvokedFunctionExpression( + context, + () => ({ + statements: context.transformStatements(ts.factory.createExpressionStatement(node.left)), + result: context.transformExpression(node.right), + }), node ); } - case ts.SyntaxKind.QuestionQuestionToken: { - return transformNullishCoalescingExpression(context, node); - } - default: return transformBinaryOperation( context, @@ -157,19 +149,14 @@ export function transformBinaryExpressionStatement( if (isCompoundAssignmentToken(operator)) { // +=, -=, etc... - return transformCompoundAssignmentStatement( - context, - expression, - expression.left, - expression.right, - unwrapCompoundAssignmentToken(operator) - ); + const token = unwrapCompoundAssignmentToken(operator); + return transformCompoundAssignmentStatement(context, expression, expression.left, expression.right, token); } else if (operator === ts.SyntaxKind.EqualsToken) { return transformAssignmentStatement(context, expression as ts.AssignmentExpression); } else if (operator === ts.SyntaxKind.CommaToken) { const statements = [ - ...context.transformStatements(ts.createExpressionStatement(expression.left)), - ...context.transformStatements(ts.createExpressionStatement(expression.right)), + ...context.transformStatements(ts.factory.createExpressionStatement(expression.left)), + ...context.transformStatements(ts.factory.createExpressionStatement(expression.right)), ]; return lua.createDoStatement(statements, expression); @@ -178,7 +165,9 @@ export function transformBinaryExpressionStatement( function transformNullishCoalescingExpression( context: TransformationContext, - node: ts.BinaryExpression + node: ts.BinaryExpression, + transformedLeft: lua.Expression, + transformedRight: lua.Expression ): lua.Expression { const lhsType = context.checker.getTypeAtLocation(node.left); @@ -197,20 +186,15 @@ function transformNullishCoalescingExpression( // if ____ == nil then return rhs else return ____ end const ifStatement = lua.createIfStatement( nilComparison, - lua.createBlock([lua.createReturnStatement([context.transformExpression(node.right)])]), + lua.createBlock([lua.createReturnStatement([transformedRight])]), lua.createBlock([lua.createReturnStatement([lua.cloneIdentifier(lhsIdentifier)])]) ); // (function(lhs') if lhs' == nil then return rhs else return lhs' end)(lhs) return lua.createCallExpression(lua.createFunctionExpression(lua.createBlock([ifStatement]), [lhsIdentifier]), [ - context.transformExpression(node.left), + transformedLeft, ]); } else { // lhs or rhs - return lua.createBinaryExpression( - context.transformExpression(node.left), - context.transformExpression(node.right), - lua.SyntaxKind.OrOperator, - node - ); + return lua.createBinaryExpression(transformedLeft, transformedRight, lua.SyntaxKind.OrOperator, node); } } diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 366ff8041..22adb9a45 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -2,15 +2,31 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { transformBuiltinCallExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; -import { isInTupleReturnFunction, isTupleReturnCall, isVarargType } from "../utils/annotations"; +import { AnnotationKind, getTypeAnnotations, isTupleReturnCall } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { ContextType, getDeclarationContextType } from "../utils/function-context"; -import { createImmediatelyInvokedFunctionExpression, createUnpackCall, wrapInTable } from "../utils/lua-ast"; +import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isValidLuaIdentifier } from "../utils/safe-names"; -import { isArrayType, isExpressionWithEvaluationEffect, isInDestructingAssignment } from "../utils/typescript"; +import { isExpressionWithEvaluationEffect } from "../utils/typescript"; import { transformElementAccessArgument } from "./access"; -import { transformLuaTableCallExpression } from "./lua-table"; +import { isMultiReturnCall, shouldMultiReturnCallBeWrapped } from "./language-extensions/multi"; +import { isOperatorMapping, transformOperatorMappingExpression } from "./language-extensions/operators"; +import { + isTableDeleteCall, + isTableGetCall, + isTableHasCall, + isTableSetCall, + transformTableDeleteExpression, + transformTableGetExpression, + transformTableHasExpression, + transformTableSetExpression, +} from "./language-extensions/table"; +import { annotationRemoved, invalidTableDeleteExpression, invalidTableSetExpression } from "../utils/diagnostics"; +import { + ImmediatelyInvokedFunctionParameters, + transformToImmediatelyInvokedFunctionExpression, +} from "../utils/transform"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; @@ -96,53 +112,82 @@ export function transformArguments( for (const [index, param] of params.entries()) { const signatureParameter = signature.parameters[index]; const paramType = context.checker.getTypeAtLocation(param); - const signatureType = context.checker.getTypeAtLocation(signatureParameter.valueDeclaration); - validateAssignment(context, param, paramType, signatureType, signatureParameter.name); + if (signatureParameter.valueDeclaration !== undefined) { + const signatureType = context.checker.getTypeAtLocation(signatureParameter.valueDeclaration); + validateAssignment(context, param, paramType, signatureType, signatureParameter.name); + } } } return parameters; } +function transformElementAccessCall( + context: TransformationContext, + left: ts.PropertyAccessExpression | ts.ElementAccessExpression, + args: ts.Expression[] | ts.NodeArray, + signature?: ts.Signature +): ImmediatelyInvokedFunctionParameters { + const transformedArguments = transformArguments(context, args, signature, ts.factory.createIdentifier("____self")); + + // Cache left-side if it has effects + // (function() local ____self = context; return ____self[argument](parameters); end)() + const argument = ts.isElementAccessExpression(left) + ? transformElementAccessArgument(context, left) + : lua.createStringLiteral(left.name.text); + const selfIdentifier = lua.createIdentifier("____self"); + const callContext = context.transformExpression(left.expression); + const selfAssignment = lua.createVariableDeclarationStatement(selfIdentifier, callContext); + const index = lua.createTableIndexExpression(selfIdentifier, argument); + const callExpression = lua.createCallExpression(index, transformedArguments); + return { statements: selfAssignment, result: callExpression }; +} + export function transformContextualCallExpression( context: TransformationContext, node: ts.CallExpression | ts.TaggedTemplateExpression, - transformedArguments: lua.Expression[] -): lua.Expression { + args: ts.Expression[] | ts.NodeArray, + signature?: ts.Signature +): lua.CallExpression | lua.MethodCallExpression { const left = ts.isCallExpression(node) ? node.expression : node.tag; if (ts.isPropertyAccessExpression(left) && ts.isIdentifier(left.name) && isValidLuaIdentifier(left.name.text)) { // table:name() const table = context.transformExpression(left.expression); - return lua.createMethodCallExpression( - table, - lua.createIdentifier(left.name.text, left.name), - transformedArguments, - node - ); + if (ts.isOptionalChain(node)) { + return transformLuaLibFunction( + context, + LuaLibFeature.OptionalMethodCall, + node, + table, + lua.createStringLiteral(left.name.text, left.name), + lua.createBooleanLiteral(node.questionDotToken !== undefined), // Require method is present if no ?.() call + ...transformArguments(context, args, signature) + ); + } else { + return lua.createMethodCallExpression( + table, + lua.createIdentifier(left.name.text, left.name), + transformArguments(context, args, signature), + node + ); + } } else if (ts.isElementAccessExpression(left) || ts.isPropertyAccessExpression(left)) { - const callContext = context.transformExpression(left.expression); if (isExpressionWithEvaluationEffect(left.expression)) { - // Inject context parameter - transformedArguments.unshift(lua.createIdentifier("____self")); - - // Cache left-side if it has effects - // (function() local ____self = context; return ____self[argument](parameters); end)() - const argument = ts.isElementAccessExpression(left) - ? transformElementAccessArgument(context, left) - : lua.createStringLiteral(left.name.text); - const selfIdentifier = lua.createIdentifier("____self"); - const selfAssignment = lua.createVariableDeclarationStatement(selfIdentifier, callContext); - const index = lua.createTableIndexExpression(selfIdentifier, argument); - const callExpression = lua.createCallExpression(index, transformedArguments); - return createImmediatelyInvokedFunctionExpression([selfAssignment], callExpression, node); + return transformToImmediatelyInvokedFunctionExpression( + context, + () => transformElementAccessCall(context, left, args, signature), + node + ); } else { + const callContext = context.transformExpression(left.expression); const expression = context.transformExpression(left); + const transformedArguments = transformArguments(context, args, signature); return lua.createCallExpression(expression, [callContext, ...transformedArguments]); } } else if (ts.isIdentifier(left)) { - const callContext = context.isStrict ? lua.createNilLiteral() : lua.createIdentifier("_G"); - transformedArguments.unshift(callContext); + const callContext = context.isStrict ? ts.factory.createNull() : ts.factory.createIdentifier("_G"); + const transformedArguments = transformArguments(context, args, signature, callContext); const expression = context.transformExpression(left); return lua.createCallExpression(expression, transformedArguments, node); } else { @@ -150,82 +195,121 @@ export function transformContextualCallExpression( } } -function transformPropertyCall(context: TransformationContext, node: PropertyCallExpression): lua.Expression { +function transformPropertyCall( + context: TransformationContext, + node: PropertyCallExpression +): lua.CallExpression | lua.MethodCallExpression { const signature = context.checker.getResolvedSignature(node); if (node.expression.expression.kind === ts.SyntaxKind.SuperKeyword) { // Super calls take the format of super.call(self,...) - const parameters = transformArguments(context, node.arguments, signature, ts.createThis()); + const parameters = transformArguments(context, node.arguments, signature, ts.factory.createThis()); return lua.createCallExpression(context.transformExpression(node.expression), parameters); } - const parameters = transformArguments(context, node.arguments, signature); const signatureDeclaration = signature?.getDeclaration(); if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { // table:name() - return transformContextualCallExpression(context, node, parameters); + return transformContextualCallExpression(context, node, node.arguments, signature); } else { - const table = context.transformExpression(node.expression.expression); - // table.name() - const name = node.expression.name.text; - const callPath = lua.createTableIndexExpression(table, lua.createStringLiteral(name), node.expression); - return lua.createCallExpression(callPath, parameters, node); + const callPath = context.transformExpression(node.expression); + const parameters = transformArguments(context, node.arguments, signature); + + if (ts.isOptionalChain(node)) { + return transformLuaLibFunction(context, LuaLibFeature.OptionalFunctionCall, node, callPath, ...parameters); + } else { + return lua.createCallExpression(callPath, parameters, node); + } } } -function transformElementCall(context: TransformationContext, node: ts.CallExpression): lua.Expression { +function transformElementCall( + context: TransformationContext, + node: ts.CallExpression +): lua.CallExpression | lua.MethodCallExpression { const signature = context.checker.getResolvedSignature(node); const signatureDeclaration = signature?.getDeclaration(); - const parameters = transformArguments(context, node.arguments, signature); if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { // A contextual parameter must be given to this call expression - return transformContextualCallExpression(context, node, parameters); + return transformContextualCallExpression(context, node, node.arguments, signature); } else { // No context const expression = context.transformExpression(node.expression); + const parameters = transformArguments(context, node.arguments, signature); return lua.createCallExpression(expression, parameters); } } export const transformCallExpression: FunctionVisitor = (node, context) => { - const luaTableResult = transformLuaTableCallExpression(context, node); - if (luaTableResult) { - return luaTableResult; - } - - const isTupleReturn = isTupleReturnCall(context, node); - const isTupleReturnForward = - node.parent && ts.isReturnStatement(node.parent) && isInTupleReturnFunction(context, node); - const isInSpread = node.parent && ts.isSpreadElement(node.parent); - const returnValueIsUsed = node.parent && !ts.isExpressionStatement(node.parent); - const wrapResult = - isTupleReturn && !isTupleReturnForward && !isInDestructingAssignment(node) && !isInSpread && returnValueIsUsed; + const wrapResultInTable = isMultiReturnCall(context, node) && shouldMultiReturnCallBeWrapped(context, node); + const wrapResultInOptional = ts.isOptionalChain(node); const builtinResult = transformBuiltinCallExpression(context, node); if (builtinResult) { - return wrapResult ? wrapInTable(builtinResult) : builtinResult; + return wrapResultInTable ? wrapInTable(builtinResult) : builtinResult; + } + + if (isTupleReturnCall(context, node)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.TupleReturn)); + } + + if (isOperatorMapping(context, node)) { + return transformOperatorMappingExpression(context, node); + } + + if (isTableDeleteCall(context, node)) { + context.diagnostics.push(invalidTableDeleteExpression(node)); + return transformToImmediatelyInvokedFunctionExpression( + context, + () => ({ statements: transformTableDeleteExpression(context, node), result: lua.createNilLiteral() }), + node + ); + } + + if (isTableGetCall(context, node)) { + return transformTableGetExpression(context, node); + } + + if (isTableHasCall(context, node)) { + return transformTableHasExpression(context, node); + } + + if (isTableSetCall(context, node)) { + context.diagnostics.push(invalidTableSetExpression(node)); + return transformToImmediatelyInvokedFunctionExpression( + context, + () => ({ statements: transformTableSetExpression(context, node), result: lua.createNilLiteral() }), + node + ); } if (ts.isPropertyAccessExpression(node.expression)) { + const ownerType = context.checker.getTypeAtLocation(node.expression.expression); + const annotations = getTypeAnnotations(ownerType); + if (annotations.has(AnnotationKind.LuaTable)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.LuaTable)); + } + const result = transformPropertyCall(context, node as PropertyCallExpression); - return wrapResult ? wrapInTable(result) : result; + // transformPropertyCall already wraps optional so no need to do so here + return wrapResultInTable ? wrapInTable(result) : result; } if (ts.isElementAccessExpression(node.expression)) { const result = transformElementCall(context, node); - return wrapResult ? wrapInTable(result) : result; + return wrapIfRequired(context, wrapResultInTable, wrapResultInOptional, result, node); } const signature = context.checker.getResolvedSignature(node); // Handle super calls properly if (node.expression.kind === ts.SyntaxKind.SuperKeyword) { - const parameters = transformArguments(context, node.arguments, signature, ts.createThis()); + const parameters = transformArguments(context, node.arguments, signature, ts.factory.createThis()); return lua.createCallExpression( lua.createTableIndexExpression( - context.transformExpression(ts.createSuper()), + context.transformExpression(ts.factory.createSuper()), lua.createStringLiteral("____constructor") ), parameters @@ -239,29 +323,47 @@ export const transformCallExpression: FunctionVisitor = (node if (signatureDeclaration && getDeclarationContextType(context, signatureDeclaration) === ContextType.Void) { parameters = transformArguments(context, node.arguments, signature); } else { - const callContext = context.isStrict ? ts.createNull() : ts.createIdentifier("_G"); + const callContext = context.isStrict ? ts.factory.createNull() : ts.factory.createIdentifier("_G"); parameters = transformArguments(context, node.arguments, signature, callContext); } const callExpression = lua.createCallExpression(callPath, parameters, node); - return wrapResult ? wrapInTable(callExpression) : callExpression; + return wrapIfRequired(context, wrapResultInTable, wrapResultInOptional, callExpression, node); }; -// TODO: Currently it's also used as an array member -export const transformSpreadElement: FunctionVisitor = (node, context) => { - const innerExpression = context.transformExpression(node.expression); - if (isTupleReturnCall(context, node.expression)) { - return innerExpression; - } - - if (ts.isIdentifier(node.expression) && isVarargType(context, node.expression)) { - return lua.createDotsLiteral(node); - } +function wrapIfRequired( + context: TransformationContext, + shouldWrapInTable: boolean, + shouldWrapOptional: boolean, + call: lua.CallExpression | lua.MethodCallExpression, + node: ts.CallExpression +): lua.Expression { + const wrappedOptional = shouldWrapOptional ? wrapOptionalCall(context, call, node) : call; + return shouldWrapInTable ? wrapInTable(wrappedOptional) : wrappedOptional; +} - const type = context.checker.getTypeAtLocation(node.expression); - if (isArrayType(context, type)) { - return createUnpackCall(context, innerExpression, node); +function wrapOptionalCall( + context: TransformationContext, + call: lua.CallExpression | lua.MethodCallExpression, + node: ts.CallExpression +): lua.CallExpression { + if (lua.isMethodCallExpression(call)) { + return transformLuaLibFunction( + context, + LuaLibFeature.OptionalMethodCall, + node, + call.prefixExpression, + lua.createStringLiteral(call.name.text), + lua.createBooleanLiteral(node.questionDotToken !== undefined), // Require method is present if no ?.() call + ...call.params + ); + } else { + return transformLuaLibFunction( + context, + LuaLibFeature.OptionalFunctionCall, + node, + call.expression, + ...call.params + ); } - - return transformLuaLibFunction(context, LuaLibFeature.Spread, node, innerExpression); -}; +} diff --git a/src/transformation/visitors/class/decorators.ts b/src/transformation/visitors/class/decorators.ts index 5cae0cf17..4b913485c 100644 --- a/src/transformation/visitors/class/decorators.ts +++ b/src/transformation/visitors/class/decorators.ts @@ -2,42 +2,38 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; import { decoratorInvalidContext } from "../../utils/diagnostics"; -import { addExportToIdentifier } from "../../utils/export"; import { ContextType, getFunctionContextType } from "../../utils/function-context"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; -import { transformIdentifier } from "../identifier"; -export function createConstructorDecorationStatement( - context: TransformationContext, - declaration: ts.ClassLikeDeclaration -): lua.AssignmentStatement | undefined { - const className = - declaration.name !== undefined - ? addExportToIdentifier(context, transformIdentifier(context, declaration.name)) - : lua.createAnonymousIdentifier(); - - const decorators = declaration.decorators; - if (!decorators) { - return undefined; +export function transformDecoratorExpression(context: TransformationContext, decorator: ts.Decorator): lua.Expression { + const expression = decorator.expression; + const type = context.checker.getTypeAtLocation(expression); + const callContext = getFunctionContextType(context, type); + if (callContext === ContextType.Void) { + context.diagnostics.push(decoratorInvalidContext(decorator)); } - const decoratorExpressions = decorators.map(decorator => { - const expression = decorator.expression; - const type = context.checker.getTypeAtLocation(expression); - const callContext = getFunctionContextType(context, type); - if (callContext === ContextType.Void) { - context.diagnostics.push(decoratorInvalidContext(decorator)); - } + return context.transformExpression(expression); +} - return context.transformExpression(expression); - }); +export function createDecoratingExpression( + context: TransformationContext, + kind: ts.SyntaxKind, + decorators: lua.Expression[], + targetTableName: lua.Expression, + targetFieldExpression?: lua.Expression +): lua.Expression { + const decoratorTable = lua.createTableExpression(decorators.map(e => lua.createTableFieldExpression(e))); + const trailingExpressions = [decoratorTable, targetTableName]; - const decoratorTable = lua.createTableExpression( - decoratorExpressions.map(expression => lua.createTableFieldExpression(expression)) - ); + if (targetFieldExpression) { + trailingExpressions.push(targetFieldExpression); + const isMethodOrAccessor = + kind === ts.SyntaxKind.MethodDeclaration || + kind === ts.SyntaxKind.GetAccessor || + kind === ts.SyntaxKind.SetAccessor; + trailingExpressions.push(isMethodOrAccessor ? lua.createBooleanLiteral(true) : lua.createNilLiteral()); + } - return lua.createAssignmentStatement( - className, - transformLuaLibFunction(context, LuaLibFeature.Decorate, undefined, decoratorTable, className) - ); + return transformLuaLibFunction(context, LuaLibFeature.Decorate, undefined, ...trailingExpressions); } diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 59ecc10b7..98d74f84a 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -1,38 +1,28 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { getOrUpdate, isNonNull } from "../../../utils"; +import { getOrUpdate } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { - extensionAndMetaExtensionConflict, - extensionCannotExport, - extensionCannotExtend, - luaTableCannotBeExtended, - luaTableMustBeAmbient, - metaExtensionMissingExtends, -} from "../../utils/diagnostics"; +import { annotationRemoved } from "../../utils/diagnostics"; import { createDefaultExportIdentifier, createExportedIdentifier, - getIdentifierExportScope, hasDefaultExportModifier, isSymbolExported, } from "../../utils/export"; -import { - createImmediatelyInvokedFunctionExpression, - createSelfIdentifier, - unwrapVisitorResult, -} from "../../utils/lua-ast"; +import { createSelfIdentifier, unwrapVisitorResult } from "../../utils/lua-ast"; import { createSafeName, isUnsafeName } from "../../utils/safe-names"; -import { popScope, pushScope, ScopeType } from "../../utils/scope"; -import { isAmbientNode } from "../../utils/typescript"; +import { transformToImmediatelyInvokedFunctionExpression } from "../../utils/transform"; import { transformIdentifier } from "../identifier"; -import { transformPropertyName } from "../literal"; -import { createConstructorDecorationStatement } from "./decorators"; -import { isGetAccessorOverride, transformAccessorDeclarations } from "./members/accessors"; +import { createDecoratingExpression, transformDecoratorExpression } from "./decorators"; +import { transformAccessorDeclarations } from "./members/accessors"; import { createConstructorName, transformConstructorDeclaration } from "./members/constructor"; -import { transformClassInstanceFields } from "./members/fields"; -import { transformMethodDeclaration } from "./members/method"; +import { + createPropertyDecoratingExpression, + transformClassInstanceFields, + transformStaticPropertyDeclaration, +} from "./members/fields"; +import { createMethodDecoratingExpression, transformMethodDeclaration } from "./members/method"; import { checkForLuaLibType } from "./new"; import { createClassSetup } from "./setup"; import { getExtendedNode, getExtendedType, isStaticNode } from "./utils"; @@ -55,11 +45,14 @@ export function transformClassAsExpression( expression: ts.ClassLikeDeclaration, context: TransformationContext ): lua.Expression { - pushScope(context, ScopeType.Function); - const { statements, name } = transformClassLikeDeclaration(expression, context); - popScope(context); - - return createImmediatelyInvokedFunctionExpression(unwrapVisitorResult(statements), name, expression); + return transformToImmediatelyInvokedFunctionExpression( + context, + () => { + const { statements, name } = transformClassLikeDeclaration(expression, context); + return { statements: unwrapVisitorResult(statements), result: name }; + }, + expression + ); } const classSuperInfos = new WeakMap(); @@ -85,18 +78,11 @@ function transformClassLikeDeclaration( const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(classDeclaration)); - // Find out if this class is extension of existing class - const extensionDirective = annotations.get(AnnotationKind.Extension); - const isExtension = extensionDirective !== undefined; - const isMetaExtension = annotations.has(AnnotationKind.MetaExtension); - - if (isExtension && isMetaExtension) { - context.diagnostics.push(extensionAndMetaExtensionConflict(classDeclaration)); + if (annotations.has(AnnotationKind.Extension)) { + context.diagnostics.push(annotationRemoved(classDeclaration, AnnotationKind.Extension)); } - - if ((isExtension || isMetaExtension) && getIdentifierExportScope(context, className) !== undefined) { - // Cannot export extension classes - context.diagnostics.push(extensionCannotExport(classDeclaration)); + if (annotations.has(AnnotationKind.MetaExtension)) { + context.diagnostics.push(annotationRemoved(classDeclaration, AnnotationKind.MetaExtension)); } // Get type that is extended @@ -110,72 +96,14 @@ function transformClassLikeDeclaration( checkForLuaLibType(context, extendedType); } - if (!(isExtension || isMetaExtension) && extendedType) { - // Non-extensions cannot extend extension classes - const extendsAnnotations = getTypeAnnotations(extendedType); - if (extendsAnnotations.has(AnnotationKind.Extension) || extendsAnnotations.has(AnnotationKind.MetaExtension)) { - context.diagnostics.push(extensionCannotExtend(classDeclaration)); - } - } - - // You cannot extend LuaTable classes - if (extendedType) { - const annotations = getTypeAnnotations(extendedType); - if (annotations.has(AnnotationKind.LuaTable)) { - context.diagnostics.push(luaTableCannotBeExtended(extendedTypeNode!)); - } - } - - if (annotations.has(AnnotationKind.LuaTable) && !isAmbientNode(classDeclaration)) { - context.diagnostics.push(luaTableMustBeAmbient(classDeclaration)); - } - // Get all properties with value const properties = classDeclaration.members.filter(ts.isPropertyDeclaration).filter(member => member.initializer); // Divide properties into static and non-static - const staticFields = properties.filter(isStaticNode); const instanceFields = properties.filter(prop => !isStaticNode(prop)); const result: lua.Statement[] = []; - // Overwrite the original className with the class we are overriding for extensions - if (isMetaExtension) { - if (extendedType) { - const extendsName = lua.createStringLiteral(extendedType.symbol.name); - className = lua.createIdentifier("__meta__" + extendsName.value); - - // local className = debug.getregistry()["extendsName"] - const assignDebugCallIndex = lua.createVariableDeclarationStatement( - className, - lua.createTableIndexExpression( - lua.createCallExpression( - lua.createTableIndexExpression( - lua.createIdentifier("debug"), - lua.createStringLiteral("getregistry") - ), - [] - ), - extendsName - ), - classDeclaration - ); - - result.push(assignDebugCallIndex); - } else { - context.diagnostics.push(metaExtensionMissingExtends(classDeclaration)); - } - } - - if (extensionDirective !== undefined) { - const [extensionName] = extensionDirective.args; - if (extensionName) { - className = lua.createIdentifier(extensionName); - } else if (extendedType) { - className = lua.createIdentifier(extendedType.symbol.name); - } - } - let localClassName: lua.Identifier; if (isUnsafeName(className.text)) { localClassName = lua.createIdentifier( @@ -189,85 +117,60 @@ function transformClassLikeDeclaration( localClassName = className; } - if (!isExtension && !isMetaExtension) { - result.push(...createClassSetup(context, classDeclaration, className, localClassName, extendedType)); - } else { - for (const f of instanceFields) { - const fieldName = transformPropertyName(context, f.name); - - const value = f.initializer !== undefined ? context.transformExpression(f.initializer) : undefined; + result.push(...createClassSetup(context, classDeclaration, className, localClassName, extendedType)); - // className["fieldName"] - const classField = lua.createTableIndexExpression(lua.cloneIdentifier(className), fieldName); - - // className["fieldName"] = value; - const assignClassField = lua.createAssignmentStatement(classField, value); + // Find first constructor with body + const constructor = classDeclaration.members.find( + (n): n is ts.ConstructorDeclaration => ts.isConstructorDeclaration(n) && n.body !== undefined + ); - result.push(assignClassField); - } - } + if (constructor) { + // Add constructor plus initialization of instance fields + const constructorResult = transformConstructorDeclaration( + context, + constructor, + localClassName, + instanceFields, + classDeclaration + ); - // Find first constructor with body - if (!isExtension && !isMetaExtension) { - const constructor = classDeclaration.members.find( - (n): n is ts.ConstructorDeclaration => ts.isConstructorDeclaration(n) && n.body !== undefined + if (constructorResult) result.push(constructorResult); + } else if (!extendedType) { + // Generate a constructor if none was defined in a base class + const constructorResult = transformConstructorDeclaration( + context, + ts.factory.createConstructorDeclaration([], [], [], ts.factory.createBlock([], true)), + localClassName, + instanceFields, + classDeclaration ); - if (constructor) { - // Add constructor plus initialization of instance fields - const constructorResult = transformConstructorDeclaration( - context, - constructor, - localClassName, - instanceFields, - classDeclaration - ); - - if (constructorResult) result.push(constructorResult); - } else if (!extendedType) { - // Generate a constructor if none was defined in a base class - const constructorResult = transformConstructorDeclaration( - context, - ts.createConstructor([], [], [], ts.createBlock([], true)), - localClassName, - instanceFields, - classDeclaration - ); - - if (constructorResult) result.push(constructorResult); - } else if ( - instanceFields.length > 0 || - classDeclaration.members.some(m => isGetAccessorOverride(context, m, classDeclaration)) - ) { - // Generate a constructor if none was defined in a class with instance fields that need initialization - // localClassName.prototype.____constructor = function(self, ...) - // baseClassName.prototype.____constructor(self, ...) - // ... - const constructorBody = transformClassInstanceFields(context, classDeclaration, instanceFields); - const superCall = lua.createExpressionStatement( - lua.createCallExpression( - lua.createTableIndexExpression( - context.transformExpression(ts.createSuper()), - lua.createStringLiteral("____constructor") - ), - [createSelfIdentifier(), lua.createDotsLiteral()] - ) - ); - constructorBody.unshift(superCall); - const constructorFunction = lua.createFunctionExpression( - lua.createBlock(constructorBody), - [createSelfIdentifier()], - lua.createDotsLiteral(), - lua.FunctionExpressionFlags.Declaration - ); - result.push( - lua.createAssignmentStatement( - createConstructorName(localClassName), - constructorFunction, - classDeclaration - ) - ); - } + if (constructorResult) result.push(constructorResult); + } else if (instanceFields.length > 0) { + // Generate a constructor if none was defined in a class with instance fields that need initialization + // localClassName.prototype.____constructor = function(self, ...) + // baseClassName.prototype.____constructor(self, ...) + // ... + const constructorBody = transformClassInstanceFields(context, instanceFields); + const superCall = lua.createExpressionStatement( + lua.createCallExpression( + lua.createTableIndexExpression( + context.transformExpression(ts.factory.createSuper()), + lua.createStringLiteral("____constructor") + ), + [createSelfIdentifier(), lua.createDotsLiteral()] + ) + ); + constructorBody.unshift(superCall); + const constructorFunction = lua.createFunctionExpression( + lua.createBlock(constructorBody), + [createSelfIdentifier()], + lua.createDotsLiteral(), + lua.FunctionExpressionFlags.Declaration + ); + result.push( + lua.createAssignmentStatement(createConstructorName(localClassName), constructorFunction, classDeclaration) + ); } // Transform accessors @@ -282,29 +185,41 @@ function transformClassLikeDeclaration( } } - // Transform methods - result.push( - ...classDeclaration.members - .filter(ts.isMethodDeclaration) - .map(m => transformMethodDeclaration(context, m, localClassName, isExtension || isMetaExtension)) - .filter(isNonNull) - ); - - // Add static declarations - for (const field of staticFields) { - const fieldName = transformPropertyName(context, field.name); - const value = field.initializer ? context.transformExpression(field.initializer) : undefined; + const decorationStatements: lua.Statement[] = []; - const classField = lua.createTableIndexExpression(lua.cloneIdentifier(localClassName), fieldName); - - const fieldAssign = lua.createAssignmentStatement(classField, value); - - result.push(fieldAssign); + for (const member of classDeclaration.members) { + if (ts.isAccessor(member)) { + const expression = createPropertyDecoratingExpression(context, member, localClassName); + if (expression) decorationStatements.push(lua.createExpressionStatement(expression)); + } else if (ts.isMethodDeclaration(member)) { + const statement = transformMethodDeclaration(context, member, localClassName); + if (statement) result.push(statement); + if (member.body) { + const statement = createMethodDecoratingExpression(context, member, localClassName); + if (statement) decorationStatements.push(statement); + } + } else if (ts.isPropertyDeclaration(member)) { + if (isStaticNode(member)) { + const statement = transformStaticPropertyDeclaration(context, member, localClassName); + if (statement) decorationStatements.push(statement); + } + const expression = createPropertyDecoratingExpression(context, member, localClassName); + if (expression) decorationStatements.push(lua.createExpressionStatement(expression)); + } } - const decorationStatement = createConstructorDecorationStatement(context, classDeclaration); - if (decorationStatement) { - result.push(decorationStatement); + result.push(...decorationStatements); + + // Decorate the class + if (classDeclaration.decorators) { + const decoratingExpression = createDecoratingExpression( + context, + classDeclaration.kind, + classDeclaration.decorators.map(d => transformDecoratorExpression(context, d)), + localClassName + ); + const decoratingStatement = lua.createAssignmentStatement(localClassName, decoratingExpression); + result.push(decoratingStatement); } superInfo.pop(); diff --git a/src/transformation/visitors/class/members/accessors.ts b/src/transformation/visitors/class/members/accessors.ts index 88a7f1545..f774b9645 100644 --- a/src/transformation/visitors/class/members/accessors.ts +++ b/src/transformation/visitors/class/members/accessors.ts @@ -2,10 +2,11 @@ import * as ts from "typescript"; import * as lua from "../../../../LuaAST"; import { AllAccessorDeclarations, TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; -import { importLuaLibFeature, LuaLibFeature } from "../../../utils/lualib"; +import { LuaLibFeature, transformLuaLibFunction } from "../../../utils/lualib"; import { transformFunctionBody, transformParameters } from "../../function"; import { transformPropertyName } from "../../literal"; -import { getExtendedType, isStaticNode } from "../utils"; +import { isStaticNode } from "../utils"; +import { createPrototypeName } from "./constructor"; function transformAccessor(context: TransformationContext, node: ts.AccessorDeclaration): lua.FunctionExpression { const [params, dot, restParam] = transformParameters(context, node.parameters, createSelfIdentifier()); @@ -31,83 +32,11 @@ export function transformAccessorDeclarations( descriptor.fields.push(lua.createTableFieldExpression(setterFunction, lua.createStringLiteral("set"))); } - importLuaLibFeature(context, LuaLibFeature.Descriptors); - const call = isStaticNode(firstAccessor) - ? lua.createCallExpression(lua.createIdentifier("__TS__ObjectDefineProperty"), [ - lua.cloneIdentifier(className), - propertyName, - descriptor, - ]) - : lua.createCallExpression(lua.createIdentifier("__TS__SetDescriptor"), [ - lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")), - propertyName, - descriptor, - ]); - + const isStatic = isStaticNode(firstAccessor); + const target = isStatic ? lua.cloneIdentifier(className) : createPrototypeName(className); + const feature = isStatic ? LuaLibFeature.ObjectDefineProperty : LuaLibFeature.SetDescriptor; + const parameters: lua.Expression[] = [target, propertyName, descriptor]; + if (!isStatic) parameters.push(lua.createBooleanLiteral(true)); + const call = transformLuaLibFunction(context, feature, undefined, ...parameters); return lua.createExpressionStatement(call); } - -function* classWithAncestors( - context: TransformationContext, - classDeclaration: ts.ClassLikeDeclarationBase -): Generator { - yield classDeclaration; - - const extendsType = getExtendedType(context, classDeclaration); - if (!extendsType) { - return false; - } - - const symbol = extendsType.getSymbol(); - if (symbol === undefined) { - return false; - } - - const symbolDeclarations = symbol.getDeclarations(); - if (symbolDeclarations === undefined) { - return false; - } - - const declaration = symbolDeclarations.find(ts.isClassLike); - if (!declaration) { - return false; - } - - yield* classWithAncestors(context, declaration); -} - -export const hasMemberInClassOrAncestor = ( - context: TransformationContext, - classDeclaration: ts.ClassLikeDeclarationBase, - callback: (m: ts.ClassElement) => boolean -) => [...classWithAncestors(context, classDeclaration)].some(c => c.members.some(callback)); - -function getPropertyName(propertyName: ts.PropertyName): string | number | undefined { - if (ts.isIdentifier(propertyName) || ts.isStringLiteral(propertyName) || ts.isNumericLiteral(propertyName)) { - return propertyName.text; - } else { - return undefined; // TODO: how to handle computed property names? - } -} - -function isSamePropertyName(a: ts.PropertyName, b: ts.PropertyName): boolean { - const aName = getPropertyName(a); - const bName = getPropertyName(b); - return aName !== undefined && aName === bName; -} - -export function isGetAccessorOverride( - context: TransformationContext, - element: ts.ClassElement, - classDeclaration: ts.ClassLikeDeclarationBase -): element is ts.GetAccessorDeclaration { - if (!ts.isGetAccessor(element) || isStaticNode(element)) { - return false; - } - - return hasMemberInClassOrAncestor( - context, - classDeclaration, - m => ts.isPropertyDeclaration(m) && m.initializer !== undefined && isSamePropertyName(m.name, element.name) - ); -} diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index fe25a21b2..11766d2a8 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -3,15 +3,16 @@ import * as lua from "../../../../LuaAST"; import { TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; import { popScope, pushScope, ScopeType } from "../../../utils/scope"; -import { transformFunctionBodyHeader, transformFunctionBodyStatements, transformParameters } from "../../function"; +import { transformFunctionBodyContent, transformFunctionBodyHeader, transformParameters } from "../../function"; import { transformIdentifier } from "../../identifier"; import { transformClassInstanceFields } from "./fields"; +export function createPrototypeName(className: lua.Identifier): lua.TableIndexExpression { + return lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")); +} + export function createConstructorName(className: lua.Identifier): lua.TableIndexExpression { - return lua.createTableIndexExpression( - lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")), - lua.createStringLiteral("____constructor") - ); + return lua.createTableIndexExpression(createPrototypeName(className), lua.createStringLiteral("____constructor")); } export function transformConstructorDeclaration( @@ -28,7 +29,7 @@ export function transformConstructorDeclaration( // Transform body const scope = pushScope(context, ScopeType.Function); - const body = transformFunctionBodyStatements(context, statement.body); + const body = transformFunctionBodyContent(context, statement.body); const [params, dotsLiteral, restParamName] = transformParameters( context, @@ -42,7 +43,7 @@ export function transformConstructorDeclaration( // Check for field declarations in constructor const constructorFieldsDeclarations = statement.parameters.filter(p => p.modifiers !== undefined); - const classInstanceFields = transformClassInstanceFields(context, classDeclaration, instanceFields); + const classInstanceFields = transformClassInstanceFields(context, instanceFields); // If there are field initializers and the first statement is a super call, // move super call between default assignments and initializers diff --git a/src/transformation/visitors/class/members/fields.ts b/src/transformation/visitors/class/members/fields.ts index 9117c1519..980c6f851 100644 --- a/src/transformation/visitors/class/members/fields.ts +++ b/src/transformation/visitors/class/members/fields.ts @@ -3,11 +3,28 @@ import * as lua from "../../../../LuaAST"; import { TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; import { transformPropertyName } from "../../literal"; -import { isGetAccessorOverride } from "./accessors"; +import { createDecoratingExpression, transformDecoratorExpression } from "../decorators"; +import { transformMemberExpressionOwnerName } from "./method"; + +export function createPropertyDecoratingExpression( + context: TransformationContext, + node: ts.PropertyDeclaration | ts.AccessorDeclaration, + className: lua.Identifier +): lua.Expression | undefined { + if (!node.decorators) return; + const propertyName = transformPropertyName(context, node.name); + const propertyOwnerTable = transformMemberExpressionOwnerName(node, className); + return createDecoratingExpression( + context, + node.kind, + node.decorators.map(d => transformDecoratorExpression(context, d)), + propertyOwnerTable, + propertyName + ); +} export function transformClassInstanceFields( context: TransformationContext, - classDeclaration: ts.ClassLikeDeclaration, instanceFields: ts.PropertyDeclaration[] ): lua.Statement[] { const statements: lua.Statement[] = []; @@ -27,25 +44,17 @@ export function transformClassInstanceFields( statements.push(assignClassField); } - // TODO: Remove when `useDefineForClassFields` would be `true` by default - - const getOverrides = classDeclaration.members.filter((m): m is ts.GetAccessorDeclaration => - isGetAccessorOverride(context, m, classDeclaration) - ); - - for (const getter of getOverrides) { - const getterName = transformPropertyName(context, getter.name); - - const resetGetter = lua.createExpressionStatement( - lua.createCallExpression(lua.createIdentifier("rawset"), [ - createSelfIdentifier(), - getterName, - lua.createNilLiteral(), - ]), - classDeclaration.members.find(ts.isConstructorDeclaration) ?? classDeclaration - ); - statements.push(resetGetter); - } - return statements; } + +export function transformStaticPropertyDeclaration( + context: TransformationContext, + field: ts.PropertyDeclaration, + className: lua.Identifier +): lua.AssignmentStatement | undefined { + if (!field.initializer) return; + const fieldName = transformPropertyName(context, field.name); + const value = context.transformExpression(field.initializer); + const classField = lua.createTableIndexExpression(lua.cloneIdentifier(className), fieldName); + return lua.createAssignmentStatement(classField, value); +} diff --git a/src/transformation/visitors/class/members/method.ts b/src/transformation/visitors/class/members/method.ts index 6f6df45b0..c902ea8de 100644 --- a/src/transformation/visitors/class/members/method.ts +++ b/src/transformation/visitors/class/members/method.ts @@ -4,28 +4,36 @@ import { TransformationContext } from "../../../context"; import { transformFunctionToExpression } from "../../function"; import { transformPropertyName } from "../../literal"; import { isStaticNode } from "../utils"; +import { createDecoratingExpression, transformDecoratorExpression } from "../decorators"; +import { createPrototypeName } from "./constructor"; +import { transformLuaLibFunction, LuaLibFeature } from "../../../utils/lualib"; +import { isNonNull } from "../../../../utils"; + +export function transformMemberExpressionOwnerName( + node: ts.PropertyDeclaration | ts.MethodDeclaration | ts.AccessorDeclaration, + className: lua.Identifier +): lua.Expression { + return isStaticNode(node) ? lua.cloneIdentifier(className) : createPrototypeName(className); +} + +export function transformMethodName(context: TransformationContext, node: ts.MethodDeclaration): lua.Expression { + const methodName = transformPropertyName(context, node.name); + if (lua.isStringLiteral(methodName) && methodName.value === "toString") { + return lua.createStringLiteral("__tostring", node.name); + } + return methodName; +} export function transformMethodDeclaration( context: TransformationContext, node: ts.MethodDeclaration, - className: lua.Identifier, - noPrototype: boolean + className: lua.Identifier ): lua.Statement | undefined { // Don't transform methods without body (overload declarations) - if (!node.body) { - return undefined; - } - - const methodTable = - isStaticNode(node) || noPrototype - ? lua.cloneIdentifier(className) - : lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")); - - let methodName = transformPropertyName(context, node.name); - if (lua.isStringLiteral(methodName) && methodName.value === "toString") { - methodName = lua.createStringLiteral("__tostring", node.name); - } + if (!node.body) return; + const methodTable = transformMemberExpressionOwnerName(node, className); + const methodName = transformMethodName(context, node); const [functionExpression] = transformFunctionToExpression(context, node); return lua.createAssignmentStatement( @@ -34,3 +42,39 @@ export function transformMethodDeclaration( node ); } + +export function createMethodDecoratingExpression( + context: TransformationContext, + node: ts.MethodDeclaration, + className: lua.Identifier +): lua.Statement | undefined { + const methodTable = transformMemberExpressionOwnerName(node, className); + const methodName = transformMethodName(context, node); + + const parameterDecorators = node.parameters + .flatMap((parameter, index) => + parameter.decorators?.map(decorator => + transformLuaLibFunction( + context, + LuaLibFeature.DecorateParam, + node, + lua.createNumericLiteral(index), + transformDecoratorExpression(context, decorator) + ) + ) + ) + .filter(isNonNull); + + const methodDecorators = node.decorators?.map(d => transformDecoratorExpression(context, d)) ?? []; + + if (methodDecorators.length > 0 || parameterDecorators.length > 0) { + const decorateMethod = createDecoratingExpression( + context, + node.kind, + [...methodDecorators, ...parameterDecorators], + methodTable, + methodName + ); + return lua.createExpressionStatement(decorateMethod); + } +} diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index da1c2f124..97e1c3407 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -2,10 +2,10 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { annotationInvalidArgumentCount, extensionCannotConstruct } from "../../utils/diagnostics"; +import { annotationInvalidArgumentCount, annotationRemoved } from "../../utils/diagnostics"; import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { transformArguments } from "../call"; -import { transformLuaTableNewExpression } from "../lua-table"; +import { isTableNewCall } from "../language-extensions/table"; const builtinErrorTypeNames = new Set([ "Error", @@ -48,26 +48,26 @@ export function checkForLuaLibType(context: TransformationContext, type: ts.Type } export const transformNewExpression: FunctionVisitor = (node, context) => { - const luaTableResult = transformLuaTableNewExpression(context, node); - if (luaTableResult) { - return luaTableResult; + const type = context.checker.getTypeAtLocation(node); + + const annotations = getTypeAnnotations(type); + + if (annotations.has(AnnotationKind.LuaTable)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.LuaTable)); + } + + if (isTableNewCall(context, node)) { + return lua.createTableExpression(undefined, node); } - const name = context.transformExpression(node.expression); const signature = context.checker.getResolvedSignature(node); const params = node.arguments ? transformArguments(context, node.arguments, signature) : [lua.createBooleanLiteral(true)]; - const type = context.checker.getTypeAtLocation(node); - checkForLuaLibType(context, type); - const annotations = getTypeAnnotations(type); - - if (annotations.has(AnnotationKind.Extension) || annotations.has(AnnotationKind.MetaExtension)) { - context.diagnostics.push(extensionCannotConstruct(node)); - } + const name = context.transformExpression(node.expression); const customConstructorAnnotation = annotations.get(AnnotationKind.CustomConstructor); if (customConstructorAnnotation) { diff --git a/src/transformation/visitors/class/utils.ts b/src/transformation/visitors/class/utils.ts index 9ba263818..aea06680a 100644 --- a/src/transformation/visitors/class/utils.ts +++ b/src/transformation/visitors/class/utils.ts @@ -1,6 +1,7 @@ import * as ts from "typescript"; import { TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; +import { annotationRemoved } from "../../utils/diagnostics"; export function isStaticNode(node: ts.Node): boolean { return (node.modifiers ?? []).some(m => m.kind === ts.SyntaxKind.StaticKeyword); @@ -19,9 +20,12 @@ export function getExtendedNode( const superType = context.checker.getTypeAtLocation(extendsClause.types[0]); const annotations = getTypeAnnotations(superType); - if (!annotations.has(AnnotationKind.PureAbstract)) { - return extendsClause.types[0]; + + if (annotations.has(AnnotationKind.PureAbstract)) { + context.diagnostics.push(annotationRemoved(extendsClause, AnnotationKind.PureAbstract)); } + + return extendsClause.types[0]; } export function getExtendedType( diff --git a/src/transformation/visitors/delete.ts b/src/transformation/visitors/delete.ts index 34e378be8..39bbf1d57 100644 --- a/src/transformation/visitors/delete.ts +++ b/src/transformation/visitors/delete.ts @@ -1,25 +1,35 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; -import { cast } from "../../utils"; -import { FunctionVisitor, TransformationContext } from "../context"; -import { createImmediatelyInvokedFunctionExpression } from "../utils/lua-ast"; +import { FunctionVisitor } from "../context"; +import { transformLuaLibFunction, LuaLibFeature } from "../utils/lualib"; +import { unsupportedProperty } from "../utils/diagnostics"; +import { isArrayType, isNumberType } from "../utils/typescript"; +import { addToNumericExpression } from "../utils/lua-ast"; export const transformDeleteExpression: FunctionVisitor = (node, context) => { - const lhs = cast(context.transformExpression(node.expression), lua.isAssignmentLeftHandSideExpression); - const assignment = lua.createAssignmentStatement(lhs, lua.createNilLiteral(), node); - return createImmediatelyInvokedFunctionExpression([assignment], [lua.createBooleanLiteral(true)], node); -}; + let ownerExpression: lua.Expression | undefined; + let propertyExpression: lua.Expression | undefined; + + if (ts.isPropertyAccessExpression(node.expression)) { + if (ts.isPrivateIdentifier(node.expression.name)) throw new Error("PrivateIdentifier is not supported"); + ownerExpression = context.transformExpression(node.expression.expression); + propertyExpression = lua.createStringLiteral(node.expression.name.text); + } else if (ts.isElementAccessExpression(node.expression)) { + ownerExpression = context.transformExpression(node.expression.expression); + propertyExpression = context.transformExpression(node.expression.argumentExpression); -export function transformDeleteExpressionStatement( - context: TransformationContext, - node: ts.ExpressionStatement -): lua.Statement | undefined { - const expression = ts.isExpressionStatement(node) ? node.expression : node; - if (ts.isDeleteExpression(expression)) { - return lua.createAssignmentStatement( - cast(context.transformExpression(expression.expression), lua.isAssignmentLeftHandSideExpression), - lua.createNilLiteral(), - expression - ); + const type = context.checker.getTypeAtLocation(node.expression.expression); + const argumentType = context.checker.getTypeAtLocation(node.expression.argumentExpression); + + if (isArrayType(context, type) && isNumberType(context, argumentType)) { + propertyExpression = addToNumericExpression(propertyExpression, 1); + } } -} + + if (!ownerExpression || !propertyExpression) { + context.diagnostics.push(unsupportedProperty(node, "delete", ts.SyntaxKind[node.kind])); + return lua.createNilLiteral(); + } + + return transformLuaLibFunction(context, LuaLibFeature.Delete, node, ownerExpression, propertyExpression); +}; diff --git a/src/transformation/visitors/enum.ts b/src/transformation/visitors/enum.ts index e915440c7..918e685f6 100644 --- a/src/transformation/visitors/enum.ts +++ b/src/transformation/visitors/enum.ts @@ -4,6 +4,7 @@ import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; import { getSymbolExportScope } from "../utils/export"; import { createLocalOrExportedOrGlobalDeclaration } from "../utils/lua-ast"; +import { isFirstDeclaration } from "../utils/typescript"; import { transformIdentifier } from "./identifier"; import { transformPropertyName } from "./literal"; @@ -28,9 +29,13 @@ export const transformEnumDeclaration: FunctionVisitor = (no const membersOnly = getTypeAnnotations(type).has(AnnotationKind.CompileMembersOnly); const result: lua.Statement[] = []; - if (!membersOnly) { + if (!membersOnly && isFirstDeclaration(context, node)) { const name = transformIdentifier(context, node.name); - const table = lua.createTableExpression(); + const table = lua.createBinaryExpression( + lua.cloneIdentifier(name), + lua.createTableExpression(), + lua.SyntaxKind.OrOperator + ); result.push(...createLocalOrExportedOrGlobalDeclaration(context, name, table, node)); } diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index 6d683c475..0f067c939 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -1,11 +1,11 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; -import { isInTupleReturnFunction } from "../utils/annotations"; import { createUnpackCall } from "../utils/lua-ast"; import { findScope, ScopeType } from "../utils/scope"; import { transformScopeBlock } from "./block"; import { transformIdentifier } from "./identifier"; +import { isInMultiReturnFunction } from "./language-extensions/multi"; export const transformTryStatement: FunctionVisitor = (statement, context) => { const [tryBlock, tryScope] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try); @@ -88,7 +88,7 @@ export const transformTryStatement: FunctionVisitor = (statemen returnValues.push(lua.createBooleanLiteral(true)); } - if (isInTupleReturnFunction(context, statement)) { + if (isInMultiReturnFunction(context, statement)) { returnValues.push(createUnpackCall(context, lua.cloneIdentifier(returnValueIdentifier))); } else { returnValues.push(lua.cloneIdentifier(returnValueIdentifier)); diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index 0b338be6f..228307f25 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -2,14 +2,23 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; import { transformBinaryExpressionStatement } from "./binary-expression"; -import { transformDeleteExpressionStatement } from "./delete"; -import { transformLuaTableExpressionStatement } from "./lua-table"; +import { + isTableDeleteCall, + isTableSetCall, + transformTableDeleteExpression, + transformTableSetExpression, +} from "./language-extensions/table"; import { transformUnaryExpressionStatement } from "./unary-expression"; export const transformExpressionStatement: FunctionVisitor = (node, context) => { - const luaTableResult = transformLuaTableExpressionStatement(context, node); - if (luaTableResult) { - return luaTableResult; + const expression = node.expression; + + if (ts.isCallExpression(expression) && isTableDeleteCall(context, expression)) { + return transformTableDeleteExpression(context, expression); + } + + if (ts.isCallExpression(expression) && isTableSetCall(context, expression)) { + return transformTableSetExpression(context, expression); } const unaryExpressionResult = transformUnaryExpressionStatement(context, node); @@ -22,12 +31,6 @@ export const transformExpressionStatement: FunctionVisitor !r.parent || !ts.isSpreadElement(r.parent) || !isVarargType(context, r)); + return references !== undefined && references.length > 0; } -export function transformFunctionBodyStatements(context: TransformationContext, body: ts.Block): lua.Statement[] { +export function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[] { + if (!ts.isBlock(body)) { + const returnStatement = transformExpressionBodyToReturnStatement(context, body); + return [returnStatement]; + } + const bodyStatements = performHoisting(context, context.transformStatements(body.statements)); return bodyStatements; } @@ -93,7 +97,7 @@ export function transformFunctionBodyHeader( } // Push spread operator here - if (spreadIdentifier && isRestParameterReferenced(context, spreadIdentifier, bodyScope)) { + if (spreadIdentifier && isRestParameterReferenced(spreadIdentifier, bodyScope)) { const spreadTable = wrapInTable(lua.createDotsLiteral()); headerStatements.push(lua.createVariableDeclarationStatement(spreadIdentifier, spreadTable)); } @@ -107,11 +111,16 @@ export function transformFunctionBodyHeader( export function transformFunctionBody( context: TransformationContext, parameters: ts.NodeArray, - body: ts.Block, - spreadIdentifier?: lua.Identifier + body: ts.ConciseBody, + spreadIdentifier?: lua.Identifier, + node?: ts.FunctionLikeDeclaration ): [lua.Statement[], Scope] { const scope = pushScope(context, ScopeType.Function); - const bodyStatements = transformFunctionBodyStatements(context, body); + scope.node = node; + let bodyStatements = transformFunctionBodyContent(context, body); + if (node && isAsyncFunction(node)) { + bodyStatements = wrapInAsyncAwaiter(context, bodyStatements); + } const headerStatements = transformFunctionBodyHeader(context, scope, parameters, spreadIdentifier); popScope(context); return [[...headerStatements, ...bodyStatements], scope]; @@ -184,18 +193,15 @@ export function transformFunctionToExpression( flags |= lua.FunctionExpressionFlags.Declaration; } - let body: ts.Block; - if (ts.isBlock(node.body)) { - body = node.body; - } else { - const returnExpression = ts.createReturn(node.body); - body = ts.createBlock([returnExpression]); - returnExpression.parent = body; - if (node.body) body.parent = node.body.parent; - } - const [paramNames, dotsLiteral, spreadIdentifier] = transformParameters(context, node.parameters, functionContext); - const [transformedBody, functionScope] = transformFunctionBody(context, node.parameters, body, spreadIdentifier); + const [transformedBody, functionScope] = transformFunctionBody( + context, + node.parameters, + node.body, + spreadIdentifier, + node + ); + const functionExpression = lua.createFunctionExpression( lua.createBlock(transformedBody), paramNames, @@ -221,6 +227,10 @@ export function transformFunctionLikeDeclaration( return lua.createNilLiteral(); } + if (getNodeAnnotations(node).has(AnnotationKind.TupleReturn)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.TupleReturn)); + } + const [functionExpression, functionScope] = transformFunctionToExpression(context, node); // Handle named function expressions which reference themselves @@ -235,6 +245,10 @@ export function transformFunctionLikeDeclaration( // Only wrap if the name is actually referenced inside the function if (isReferenced) { const nameIdentifier = transformIdentifier(context, node.name); + // We cannot use transformToImmediatelyInvokedFunctionExpression() here because we need to transpile + // the function first to determine if it's self-referencing. Fortunately, this does not cause issues + // with var-arg optimization because the IIFE is just wrapping another function which will already push + // another scope. return createImmediatelyInvokedFunctionExpression( [lua.createVariableDeclarationStatement(nameIdentifier, functionExpression)], lua.cloneIdentifier(nameIdentifier) @@ -247,6 +261,10 @@ export function transformFunctionLikeDeclaration( } export const transformFunctionDeclaration: FunctionVisitor = (node, context) => { + if (getNodeAnnotations(node).has(AnnotationKind.TupleReturn)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.TupleReturn)); + } + // Don't transform functions without body (overload declarations) if (node.body === undefined) { return undefined; @@ -278,9 +296,13 @@ export const transformFunctionDeclaration: FunctionVisitor = (expression, context) => - lua.createCallExpression( - lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("yield")), - expression.expression ? [context.transformExpression(expression.expression)] : [], - expression - ); +export const transformYieldExpression: FunctionVisitor = (expression, context) => { + const parameters = expression.expression ? [context.transformExpression(expression.expression)] : []; + return expression.asteriskToken + ? transformLuaLibFunction(context, LuaLibFeature.DelegatedYield, expression, ...parameters) + : lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("yield")), + parameters, + expression + ); +}; diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index 54ed2a2f0..3d39b16a4 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -1,22 +1,58 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { transformBuiltinIdentifierExpression } from "../builtins"; +import { createPromiseIdentifier, isPromiseClass } from "../builtins/promise"; import { FunctionVisitor, TransformationContext } from "../context"; -import { isForRangeType } from "../utils/annotations"; -import { invalidForRangeCall } from "../utils/diagnostics"; +import { AnnotationKind, isForRangeType } from "../utils/annotations"; +import { + invalidMultiFunctionUse, + invalidOperatorMappingUse, + invalidRangeUse, + invalidVarargUse, + invalidTableExtensionUse, + annotationRemoved, +} from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; +import { importLuaLibFeature, LuaLibFeature } from "../utils/lualib"; import { createSafeName, hasUnsafeIdentifierName } from "../utils/safe-names"; import { getIdentifierSymbolId } from "../utils/symbols"; -import { findFirstNodeAbove } from "../utils/typescript"; +import { isMultiFunctionNode } from "./language-extensions/multi"; +import { isOperatorMapping } from "./language-extensions/operators"; +import { isRangeFunctionNode } from "./language-extensions/range"; +import { isTableExtensionIdentifier } from "./language-extensions/table"; +import { isVarargConstantNode } from "./language-extensions/vararg"; export function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier { + if (isMultiFunctionNode(context, identifier)) { + context.diagnostics.push(invalidMultiFunctionUse(identifier)); + return lua.createAnonymousIdentifier(identifier); + } + + if (isOperatorMapping(context, identifier)) { + context.diagnostics.push(invalidOperatorMappingUse(identifier)); + } + + if (isTableExtensionIdentifier(context, identifier)) { + context.diagnostics.push(invalidTableExtensionUse(identifier)); + } + + if (isRangeFunctionNode(context, identifier)) { + context.diagnostics.push(invalidRangeUse(identifier)); + return lua.createAnonymousIdentifier(identifier); + } + + if (isVarargConstantNode(context, identifier)) { + context.diagnostics.push(invalidVarargUse(identifier)); + return lua.createAnonymousIdentifier(identifier); + } + if (isForRangeType(context, identifier)) { - const callExpression = findFirstNodeAbove(identifier, ts.isCallExpression); - if (!callExpression || !callExpression.parent || !ts.isForOfStatement(callExpression.parent)) { - context.diagnostics.push( - invalidForRangeCall(identifier, "can be used only as an iterable in a for...of loop") - ); - } + context.diagnostics.push(annotationRemoved(identifier, AnnotationKind.ForRange)); + } + + if (isPromiseClass(context, identifier)) { + importLuaLibFeature(context, LuaLibFeature.Promise); + return createPromiseIdentifier(identifier); } const text = hasUnsafeIdentifierName(context, identifier) ? createSafeName(identifier.text) : identifier.text; diff --git a/src/transformation/visitors/index.ts b/src/transformation/visitors/index.ts index 48469a84b..28f965932 100644 --- a/src/transformation/visitors/index.ts +++ b/src/transformation/visitors/index.ts @@ -4,7 +4,8 @@ import { transformElementAccessExpression, transformPropertyAccessExpression, tr import { transformBinaryExpression } from "./binary-expression"; import { transformBlock } from "./block"; import { transformBreakStatement, transformContinueStatement } from "./break-continue"; -import { transformCallExpression, transformSpreadElement } from "./call"; +import { transformCallExpression } from "./call"; +import { transformSpreadElement } from "./spread"; import { transformClassAsExpression, transformClassDeclaration, @@ -39,6 +40,8 @@ import { transformTypeOfExpression } from "./typeof"; import { typescriptVisitors } from "./typescript"; import { transformPostfixUnaryExpression, transformPrefixUnaryExpression } from "./unary-expression"; import { transformVariableStatement } from "./variable-declaration"; +import { jsxVisitors } from "./jsx/jsx"; +import { transformAwaitExpression } from "./async-await"; const transformEmptyStatement: FunctionVisitor = () => undefined; const transformParenthesizedExpression: FunctionVisitor = (node, context) => @@ -47,7 +50,9 @@ const transformParenthesizedExpression: FunctionVisitor= charCodes.a && ch <= charCodes.z) || name.includes("-") || name.includes(":"); +} + +function transformTagName(name: ts.JsxTagNameExpression, context: TransformationContext): lua.Expression { + if (ts.isIdentifier(name) && isIntrinsicJsxName(name.escapedText)) { + return lua.createStringLiteral(ts.idText(name), name); + } else { + return context.transformExpression(name); + } +} + +function transformJsxChildren( + children: ts.NodeArray | undefined, + context: TransformationContext +): lua.Expression[] | undefined { + if (!children) return undefined; + + return children + .map(child => { + if (ts.isJsxText(child)) { + return processJsxText(child); + } + if (ts.isJsxExpression(child)) { + return child.expression; + } + return child; + }) + .filter(child => child !== undefined) + .map(child => context.transformExpression(child!)); +} + +function createJsxFactoryCall( + tagName: lua.Expression, + props: lua.Expression | undefined, + tsChildren: ts.NodeArray | undefined, + tsOriginal: ts.Node, + context: TransformationContext +): lua.Expression { + const transformedChildren = transformJsxChildren(tsChildren, context); + const jsxFactory = getJsxFactory(tsOriginal, context); + + const args = [tagName]; + if (props) { + args.push(props); + } + if (transformedChildren && transformedChildren.length > 0) { + if (!props) { + args.push(lua.createNilLiteral()); + } + args.push(...transformedChildren); + } + return lua.createCallExpression(jsxFactory, args, tsOriginal); +} + +function transformJsxOpeningLikeElement( + node: ts.JsxOpeningLikeElement, + children: ts.NodeArray | undefined, + context: TransformationContext +): lua.Expression { + const tagName = transformTagName(node.tagName, context); + const props = + node.attributes.properties.length !== 0 ? transformJsxAttributes(node.attributes, context) : undefined; + + return createJsxFactoryCall(tagName, props, children, node, context); +} + +const transformJsxElement: FunctionVisitor = (node, context) => + transformJsxOpeningLikeElement(node.openingElement, node.children, context); +const transformSelfClosingJsxElement: FunctionVisitor = (node, context) => + transformJsxOpeningLikeElement(node, undefined, context); +const transformJsxFragment: FunctionVisitor = (node, context) => { + const tagName = getJsxFragmentName(node, context); + return createJsxFactoryCall(tagName, undefined, node.children, node, context); +}; + +export const jsxVisitors: Visitors = { + [ts.SyntaxKind.JsxElement]: transformJsxElement, + [ts.SyntaxKind.JsxSelfClosingElement]: transformSelfClosingJsxElement, + [ts.SyntaxKind.JsxFragment]: transformJsxFragment, +}; diff --git a/src/transformation/visitors/jsx/xhtml.ts b/src/transformation/visitors/jsx/xhtml.ts new file mode 100644 index 000000000..814191df0 --- /dev/null +++ b/src/transformation/visitors/jsx/xhtml.ts @@ -0,0 +1,256 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +export const XHTMLEntities: { [name: string]: string } = { + quot: "\u0022", + amp: "&", + apos: "\u0027", + lt: "<", + gt: ">", + nbsp: "\u00A0", + iexcl: "\u00A1", + cent: "\u00A2", + pound: "\u00A3", + curren: "\u00A4", + yen: "\u00A5", + brvbar: "\u00A6", + sect: "\u00A7", + uml: "\u00A8", + copy: "\u00A9", + ordf: "\u00AA", + laquo: "\u00AB", + not: "\u00AC", + shy: "\u00AD", + reg: "\u00AE", + macr: "\u00AF", + deg: "\u00B0", + plusmn: "\u00B1", + sup2: "\u00B2", + sup3: "\u00B3", + acute: "\u00B4", + micro: "\u00B5", + para: "\u00B6", + middot: "\u00B7", + cedil: "\u00B8", + sup1: "\u00B9", + ordm: "\u00BA", + raquo: "\u00BB", + frac14: "\u00BC", + frac12: "\u00BD", + frac34: "\u00BE", + iquest: "\u00BF", + Agrave: "\u00C0", + Aacute: "\u00C1", + Acirc: "\u00C2", + Atilde: "\u00C3", + Auml: "\u00C4", + Aring: "\u00C5", + AElig: "\u00C6", + Ccedil: "\u00C7", + Egrave: "\u00C8", + Eacute: "\u00C9", + Ecirc: "\u00CA", + Euml: "\u00CB", + Igrave: "\u00CC", + Iacute: "\u00CD", + Icirc: "\u00CE", + Iuml: "\u00CF", + ETH: "\u00D0", + Ntilde: "\u00D1", + Ograve: "\u00D2", + Oacute: "\u00D3", + Ocirc: "\u00D4", + Otilde: "\u00D5", + Ouml: "\u00D6", + times: "\u00D7", + Oslash: "\u00D8", + Ugrave: "\u00D9", + Uacute: "\u00DA", + Ucirc: "\u00DB", + Uuml: "\u00DC", + Yacute: "\u00DD", + THORN: "\u00DE", + szlig: "\u00DF", + agrave: "\u00E0", + aacute: "\u00E1", + acirc: "\u00E2", + atilde: "\u00E3", + auml: "\u00E4", + aring: "\u00E5", + aelig: "\u00E6", + ccedil: "\u00E7", + egrave: "\u00E8", + eacute: "\u00E9", + ecirc: "\u00EA", + euml: "\u00EB", + igrave: "\u00EC", + iacute: "\u00ED", + icirc: "\u00EE", + iuml: "\u00EF", + eth: "\u00F0", + ntilde: "\u00F1", + ograve: "\u00F2", + oacute: "\u00F3", + ocirc: "\u00F4", + otilde: "\u00F5", + ouml: "\u00F6", + divide: "\u00F7", + oslash: "\u00F8", + ugrave: "\u00F9", + uacute: "\u00FA", + ucirc: "\u00FB", + uuml: "\u00FC", + yacute: "\u00FD", + thorn: "\u00FE", + yuml: "\u00FF", + OElig: "\u0152", + oelig: "\u0153", + Scaron: "\u0160", + scaron: "\u0161", + Yuml: "\u0178", + fnof: "\u0192", + circ: "\u02C6", + tilde: "\u02DC", + Alpha: "\u0391", + Beta: "\u0392", + Gamma: "\u0393", + Delta: "\u0394", + Epsilon: "\u0395", + Zeta: "\u0396", + Eta: "\u0397", + Theta: "\u0398", + Iota: "\u0399", + Kappa: "\u039A", + Lambda: "\u039B", + Mu: "\u039C", + Nu: "\u039D", + Xi: "\u039E", + Omicron: "\u039F", + Pi: "\u03A0", + Rho: "\u03A1", + Sigma: "\u03A3", + Tau: "\u03A4", + Upsilon: "\u03A5", + Phi: "\u03A6", + Chi: "\u03A7", + Psi: "\u03A8", + Omega: "\u03A9", + alpha: "\u03B1", + beta: "\u03B2", + gamma: "\u03B3", + delta: "\u03B4", + epsilon: "\u03B5", + zeta: "\u03B6", + eta: "\u03B7", + theta: "\u03B8", + iota: "\u03B9", + kappa: "\u03BA", + lambda: "\u03BB", + mu: "\u03BC", + nu: "\u03BD", + xi: "\u03BE", + omicron: "\u03BF", + pi: "\u03C0", + rho: "\u03C1", + sigmaf: "\u03C2", + sigma: "\u03C3", + tau: "\u03C4", + upsilon: "\u03C5", + phi: "\u03C6", + chi: "\u03C7", + psi: "\u03C8", + omega: "\u03C9", + thetasym: "\u03D1", + upsih: "\u03D2", + piv: "\u03D6", + ensp: "\u2002", + emsp: "\u2003", + thinsp: "\u2009", + zwnj: "\u200C", + zwj: "\u200D", + lrm: "\u200E", + rlm: "\u200F", + ndash: "\u2013", + mdash: "\u2014", + lsquo: "\u2018", + rsquo: "\u2019", + sbquo: "\u201A", + ldquo: "\u201C", + rdquo: "\u201D", + bdquo: "\u201E", + dagger: "\u2020", + Dagger: "\u2021", + bull: "\u2022", + hellip: "\u2026", + permil: "\u2030", + prime: "\u2032", + Prime: "\u2033", + lsaquo: "\u2039", + rsaquo: "\u203A", + oline: "\u203E", + frasl: "\u2044", + euro: "\u20AC", + image: "\u2111", + weierp: "\u2118", + real: "\u211C", + trade: "\u2122", + alefsym: "\u2135", + larr: "\u2190", + uarr: "\u2191", + rarr: "\u2192", + darr: "\u2193", + harr: "\u2194", + crarr: "\u21B5", + lArr: "\u21D0", + uArr: "\u21D1", + rArr: "\u21D2", + dArr: "\u21D3", + hArr: "\u21D4", + forall: "\u2200", + part: "\u2202", + exist: "\u2203", + empty: "\u2205", + nabla: "\u2207", + isin: "\u2208", + notin: "\u2209", + ni: "\u220B", + prod: "\u220F", + sum: "\u2211", + minus: "\u2212", + lowast: "\u2217", + radic: "\u221A", + prop: "\u221D", + infin: "\u221E", + ang: "\u2220", + and: "\u2227", + or: "\u2228", + cap: "\u2229", + cup: "\u222A", + int: "\u222B", + there4: "\u2234", + sim: "\u223C", + cong: "\u2245", + asymp: "\u2248", + ne: "\u2260", + equiv: "\u2261", + le: "\u2264", + ge: "\u2265", + sub: "\u2282", + sup: "\u2283", + nsub: "\u2284", + sube: "\u2286", + supe: "\u2287", + oplus: "\u2295", + otimes: "\u2297", + perp: "\u22A5", + sdot: "\u22C5", + lceil: "\u2308", + rceil: "\u2309", + lfloor: "\u230A", + rfloor: "\u230B", + lang: "\u2329", + rang: "\u232A", + loz: "\u25CA", + spades: "\u2660", + clubs: "\u2663", + hearts: "\u2665", + diams: "\u2666", +}; diff --git a/src/transformation/visitors/language-extensions/iterable.ts b/src/transformation/visitors/language-extensions/iterable.ts new file mode 100644 index 000000000..769e15093 --- /dev/null +++ b/src/transformation/visitors/language-extensions/iterable.ts @@ -0,0 +1,82 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import * as extensions from "../../utils/language-extensions"; +import { TransformationContext } from "../../context"; +import { getVariableDeclarationBinding, transformForInitializer } from "../loops/utils"; +import { transformArrayBindingElement } from "../variable-declaration"; +import { invalidMultiIterableWithoutDestructuring } from "../../utils/diagnostics"; +import { cast } from "../../../utils"; +import { isMultiReturnType } from "./multi"; + +export function isIterableType(type: ts.Type): boolean { + return extensions.isExtensionType(type, extensions.ExtensionKind.IterableType); +} + +export function returnsIterableType(context: TransformationContext, node: ts.CallExpression): boolean { + const signature = context.checker.getResolvedSignature(node); + const type = signature?.getReturnType(); + return type ? isIterableType(type) : false; +} + +export function isIterableExpression(context: TransformationContext, expression: ts.Expression): boolean { + const type = context.checker.getTypeAtLocation(expression); + return isIterableType(type); +} + +function transformForOfMultiIterableStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + const luaIterator = context.transformExpression(statement.expression); + let identifiers: lua.Identifier[] = []; + + if (ts.isVariableDeclarationList(statement.initializer)) { + // Variables declared in for loop + // for ${initializer} in ${iterable} do + const binding = getVariableDeclarationBinding(context, statement.initializer); + if (ts.isArrayBindingPattern(binding)) { + identifiers = binding.elements.map(e => transformArrayBindingElement(context, e)); + } else { + context.diagnostics.push(invalidMultiIterableWithoutDestructuring(binding)); + } + } else if (ts.isArrayLiteralExpression(statement.initializer)) { + // Variables NOT declared in for loop - catch iterator values in temps and assign + // for ____value0 in ${iterable} do + // ${initializer} = ____value0 + identifiers = statement.initializer.elements.map((_, i) => lua.createIdentifier(`____value${i}`)); + if (identifiers.length > 0) { + block.statements.unshift( + lua.createAssignmentStatement( + statement.initializer.elements.map(e => + cast(context.transformExpression(e), lua.isAssignmentLeftHandSideExpression) + ), + identifiers + ) + ); + } + } else { + context.diagnostics.push(invalidMultiIterableWithoutDestructuring(statement.initializer)); + } + + if (identifiers.length === 0) { + identifiers.push(lua.createAnonymousIdentifier()); + } + + return lua.createForInStatement(block, identifiers, [luaIterator], statement); +} + +export function transformForOfIterableStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + const type = context.checker.getTypeAtLocation(statement.expression); + if (type.aliasTypeArguments?.length === 2 && isMultiReturnType(type.aliasTypeArguments[0])) { + return transformForOfMultiIterableStatement(context, statement, block); + } + + const luaIterator = context.transformExpression(statement.expression); + const identifier = transformForInitializer(context, statement.initializer, block); + return lua.createForInStatement(block, [identifier], [luaIterator], statement); +} diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts new file mode 100644 index 000000000..a1c9c4030 --- /dev/null +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -0,0 +1,113 @@ +import * as ts from "typescript"; +import * as extensions from "../../utils/language-extensions"; +import { TransformationContext } from "../../context"; +import { findFirstNodeAbove } from "../../utils/typescript"; +import { isIterableExpression } from "./iterable"; +import { invalidMultiFunctionUse } from "../../utils/diagnostics"; + +export function isMultiReturnType(type: ts.Type): boolean { + return extensions.isExtensionType(type, extensions.ExtensionKind.MultiType); +} + +export function canBeMultiReturnType(type: ts.Type): boolean { + return isMultiReturnType(type) || (type.isUnion() && type.types.some(canBeMultiReturnType)); +} + +export function isMultiFunctionCall(context: TransformationContext, expression: ts.CallExpression): boolean { + return isMultiFunctionNode(context, expression.expression); +} + +export function returnsMultiType(context: TransformationContext, node: ts.CallExpression): boolean { + const signature = context.checker.getResolvedSignature(node); + const type = signature?.getReturnType(); + return type ? isMultiReturnType(type) : false; +} + +export function isMultiReturnCall(context: TransformationContext, expression: ts.Expression) { + return ts.isCallExpression(expression) && returnsMultiType(context, expression); +} + +export function isMultiFunctionNode(context: TransformationContext, node: ts.Node): boolean { + const symbol = context.checker.getSymbolAtLocation(node); + return symbol ? extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.MultiFunction) : false; +} + +export function isInMultiReturnFunction(context: TransformationContext, node: ts.Node) { + const declaration = findFirstNodeAbove(node, ts.isFunctionLike); + if (!declaration) { + return false; + } + const signature = context.checker.getSignatureFromDeclaration(declaration); + const type = signature?.getReturnType(); + return type ? isMultiReturnType(type) : false; +} + +export function shouldMultiReturnCallBeWrapped(context: TransformationContext, node: ts.CallExpression) { + if (!returnsMultiType(context, node)) { + return false; + } + + // Variable declaration with destructuring + if (ts.isVariableDeclaration(node.parent) && ts.isArrayBindingPattern(node.parent.name)) { + return false; + } + + // Variable assignment with destructuring + if ( + ts.isBinaryExpression(node.parent) && + node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && + ts.isArrayLiteralExpression(node.parent.left) + ) { + return false; + } + + // Spread operator + if (ts.isSpreadElement(node.parent)) { + return false; + } + + // Stand-alone expression + if (ts.isExpressionStatement(node.parent)) { + return false; + } + + // Forwarded multi-return call + if ( + (ts.isReturnStatement(node.parent) || ts.isArrowFunction(node.parent)) && // Body-less arrow func + isInMultiReturnFunction(context, node) + ) { + return false; + } + + // Element access expression 'foo()[0]' will be optimized using 'select' + if (ts.isElementAccessExpression(node.parent)) { + return false; + } + + // LuaIterable in for...of + if (ts.isForOfStatement(node.parent) && isIterableExpression(context, node)) { + return false; + } + + return true; +} + +export function findMultiAssignmentViolations( + context: TransformationContext, + node: ts.ObjectLiteralExpressionBase +): ts.Node[] { + const result: ts.Node[] = []; + + for (const element of node.properties) { + if (!ts.isShorthandPropertyAssignment(element)) continue; + const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); + if (valueSymbol) { + if (extensions.isExtensionValue(context, valueSymbol, extensions.ExtensionKind.MultiFunction)) { + context.diagnostics.push(invalidMultiFunctionUse(element)); + result.push(element); + } + } + } + + return result; +} diff --git a/src/transformation/visitors/language-extensions/operators.ts b/src/transformation/visitors/language-extensions/operators.ts new file mode 100644 index 000000000..5cc039d31 --- /dev/null +++ b/src/transformation/visitors/language-extensions/operators.ts @@ -0,0 +1,138 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { TransformationContext } from "../../context"; +import * as extensions from "../../utils/language-extensions"; +import { assert } from "../../../utils"; +import { getFunctionTypeForCall } from "../../utils/typescript"; +import { LuaTarget } from "../../../CompilerOptions"; +import { unsupportedForTarget } from "../../utils/diagnostics"; + +const binaryOperatorMappings = new Map([ + [extensions.ExtensionKind.AdditionOperatorType, lua.SyntaxKind.AdditionOperator], + [extensions.ExtensionKind.AdditionOperatorMethodType, lua.SyntaxKind.AdditionOperator], + [extensions.ExtensionKind.SubtractionOperatorType, lua.SyntaxKind.SubtractionOperator], + [extensions.ExtensionKind.SubtractionOperatorMethodType, lua.SyntaxKind.SubtractionOperator], + [extensions.ExtensionKind.MultiplicationOperatorType, lua.SyntaxKind.MultiplicationOperator], + [extensions.ExtensionKind.MultiplicationOperatorMethodType, lua.SyntaxKind.MultiplicationOperator], + [extensions.ExtensionKind.DivisionOperatorType, lua.SyntaxKind.DivisionOperator], + [extensions.ExtensionKind.DivisionOperatorMethodType, lua.SyntaxKind.DivisionOperator], + [extensions.ExtensionKind.ModuloOperatorType, lua.SyntaxKind.ModuloOperator], + [extensions.ExtensionKind.ModuloOperatorMethodType, lua.SyntaxKind.ModuloOperator], + [extensions.ExtensionKind.PowerOperatorType, lua.SyntaxKind.PowerOperator], + [extensions.ExtensionKind.PowerOperatorMethodType, lua.SyntaxKind.PowerOperator], + [extensions.ExtensionKind.FloorDivisionOperatorType, lua.SyntaxKind.FloorDivisionOperator], + [extensions.ExtensionKind.FloorDivisionOperatorMethodType, lua.SyntaxKind.FloorDivisionOperator], + [extensions.ExtensionKind.BitwiseAndOperatorType, lua.SyntaxKind.BitwiseAndOperator], + [extensions.ExtensionKind.BitwiseAndOperatorMethodType, lua.SyntaxKind.BitwiseAndOperator], + [extensions.ExtensionKind.BitwiseOrOperatorType, lua.SyntaxKind.BitwiseOrOperator], + [extensions.ExtensionKind.BitwiseOrOperatorMethodType, lua.SyntaxKind.BitwiseOrOperator], + [extensions.ExtensionKind.BitwiseExclusiveOrOperatorType, lua.SyntaxKind.BitwiseExclusiveOrOperator], + [extensions.ExtensionKind.BitwiseExclusiveOrOperatorMethodType, lua.SyntaxKind.BitwiseExclusiveOrOperator], + [extensions.ExtensionKind.BitwiseLeftShiftOperatorType, lua.SyntaxKind.BitwiseLeftShiftOperator], + [extensions.ExtensionKind.BitwiseLeftShiftOperatorMethodType, lua.SyntaxKind.BitwiseLeftShiftOperator], + [extensions.ExtensionKind.BitwiseRightShiftOperatorType, lua.SyntaxKind.BitwiseRightShiftOperator], + [extensions.ExtensionKind.BitwiseRightShiftOperatorMethodType, lua.SyntaxKind.BitwiseRightShiftOperator], + [extensions.ExtensionKind.ConcatOperatorType, lua.SyntaxKind.ConcatOperator], + [extensions.ExtensionKind.ConcatOperatorMethodType, lua.SyntaxKind.ConcatOperator], + [extensions.ExtensionKind.LessThanOperatorType, lua.SyntaxKind.LessThanOperator], + [extensions.ExtensionKind.LessThanOperatorMethodType, lua.SyntaxKind.LessThanOperator], + [extensions.ExtensionKind.GreaterThanOperatorType, lua.SyntaxKind.GreaterThanOperator], + [extensions.ExtensionKind.GreaterThanOperatorMethodType, lua.SyntaxKind.GreaterThanOperator], +]); + +const unaryOperatorMappings = new Map([ + [extensions.ExtensionKind.NegationOperatorType, lua.SyntaxKind.NegationOperator], + [extensions.ExtensionKind.NegationOperatorMethodType, lua.SyntaxKind.NegationOperator], + [extensions.ExtensionKind.BitwiseNotOperatorType, lua.SyntaxKind.BitwiseNotOperator], + [extensions.ExtensionKind.BitwiseNotOperatorMethodType, lua.SyntaxKind.BitwiseNotOperator], + [extensions.ExtensionKind.LengthOperatorType, lua.SyntaxKind.LengthOperator], + [extensions.ExtensionKind.LengthOperatorMethodType, lua.SyntaxKind.LengthOperator], +]); + +const operatorMapExtensions = [...binaryOperatorMappings.keys(), ...unaryOperatorMappings.keys()]; + +const bitwiseOperatorMapExtensions = new Set([ + extensions.ExtensionKind.BitwiseAndOperatorType, + extensions.ExtensionKind.BitwiseAndOperatorMethodType, + extensions.ExtensionKind.BitwiseOrOperatorType, + extensions.ExtensionKind.BitwiseOrOperatorMethodType, + extensions.ExtensionKind.BitwiseExclusiveOrOperatorType, + extensions.ExtensionKind.BitwiseExclusiveOrOperatorMethodType, + extensions.ExtensionKind.BitwiseLeftShiftOperatorType, + extensions.ExtensionKind.BitwiseLeftShiftOperatorMethodType, + extensions.ExtensionKind.BitwiseRightShiftOperatorType, + extensions.ExtensionKind.BitwiseRightShiftOperatorMethodType, + extensions.ExtensionKind.BitwiseNotOperatorType, + extensions.ExtensionKind.BitwiseNotOperatorMethodType, +]); + +function getOperatorMapExtensionKindForCall(context: TransformationContext, node: ts.CallExpression) { + const type = getFunctionTypeForCall(context, node); + return type && operatorMapExtensions.find(extensionKind => extensions.isExtensionType(type, extensionKind)); +} + +export function isOperatorMapping(context: TransformationContext, node: ts.CallExpression | ts.Identifier) { + if (ts.isCallExpression(node)) { + return getOperatorMapExtensionKindForCall(context, node) !== undefined; + } else { + const type = context.checker.getTypeAtLocation(node); + return operatorMapExtensions.some(extensionKind => extensions.isExtensionType(type, extensionKind)); + } +} + +export function transformOperatorMappingExpression( + context: TransformationContext, + node: ts.CallExpression +): lua.Expression { + const extensionKind = getOperatorMapExtensionKindForCall(context, node); + assert(extensionKind); + + const isBefore53 = + context.luaTarget === LuaTarget.Lua51 || + context.luaTarget === LuaTarget.Lua52 || + context.luaTarget === LuaTarget.LuaJIT || + context.luaTarget === LuaTarget.Universal; + if (isBefore53) { + const luaTarget = context.luaTarget === LuaTarget.Universal ? LuaTarget.Lua51 : context.luaTarget; + if (bitwiseOperatorMapExtensions.has(extensionKind)) { + context.diagnostics.push(unsupportedForTarget(node, "Native bitwise operations", luaTarget)); + } else if ( + extensionKind === extensions.ExtensionKind.FloorDivisionOperatorType || + extensionKind === extensions.ExtensionKind.FloorDivisionOperatorMethodType + ) { + context.diagnostics.push(unsupportedForTarget(node, "Floor division operator", luaTarget)); + } + } + + const args = node.arguments.slice(); + if (binaryOperatorMappings.has(extensionKind)) { + if ( + args.length === 1 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + args.unshift(node.expression.expression); + } + + const luaOperator = binaryOperatorMappings.get(extensionKind); + assert(luaOperator); + return lua.createBinaryExpression( + context.transformExpression(args[0]), + context.transformExpression(args[1]), + luaOperator + ); + } else { + let arg: ts.Expression; + if ( + args.length === 0 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + arg = node.expression.expression; + } else { + arg = args[0]; + } + + const luaOperator = unaryOperatorMappings.get(extensionKind); + assert(luaOperator); + return lua.createUnaryExpression(context.transformExpression(arg), luaOperator); + } +} diff --git a/src/transformation/visitors/language-extensions/range.ts b/src/transformation/visitors/language-extensions/range.ts new file mode 100644 index 000000000..43f297a9a --- /dev/null +++ b/src/transformation/visitors/language-extensions/range.ts @@ -0,0 +1,49 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import * as extensions from "../../utils/language-extensions"; +import { TransformationContext } from "../../context"; +import { getVariableDeclarationBinding } from "../loops/utils"; +import { transformIdentifier } from "../identifier"; +import { transformArguments } from "../call"; +import { assert } from "../../../utils"; +import { invalidRangeControlVariable } from "../../utils/diagnostics"; + +export function isRangeFunction(context: TransformationContext, expression: ts.CallExpression): boolean { + return isRangeFunctionNode(context, expression.expression); +} + +export function isRangeFunctionNode(context: TransformationContext, node: ts.Node): boolean { + const symbol = context.checker.getSymbolAtLocation(node); + return symbol ? extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.RangeFunction) : false; +} + +function getControlVariable(context: TransformationContext, statement: ts.ForOfStatement) { + if (!ts.isVariableDeclarationList(statement.initializer)) { + context.diagnostics.push(invalidRangeControlVariable(statement.initializer)); + return; + } + + const binding = getVariableDeclarationBinding(context, statement.initializer); + if (!ts.isIdentifier(binding)) { + context.diagnostics.push(invalidRangeControlVariable(statement.initializer)); + return; + } + + return transformIdentifier(context, binding); +} + +export function transformRangeStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + assert(ts.isCallExpression(statement.expression)); + const controlVariable = + getControlVariable(context, statement) ?? lua.createAnonymousIdentifier(statement.initializer); + const [start = lua.createNumericLiteral(0), limit = lua.createNumericLiteral(0), step] = transformArguments( + context, + statement.expression.arguments, + context.checker.getResolvedSignature(statement.expression) + ); + return lua.createForStatement(block, controlVariable, start, limit, step, statement); +} diff --git a/src/transformation/visitors/language-extensions/table.ts b/src/transformation/visitors/language-extensions/table.ts new file mode 100644 index 000000000..695bcd3b1 --- /dev/null +++ b/src/transformation/visitors/language-extensions/table.ts @@ -0,0 +1,151 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { TransformationContext } from "../../context"; +import * as extensions from "../../utils/language-extensions"; +import { getFunctionTypeForCall } from "../../utils/typescript"; +import { assert } from "../../../utils"; + +const tableDeleteExtensions = [ + extensions.ExtensionKind.TableDeleteType, + extensions.ExtensionKind.TableDeleteMethodType, +]; + +const tableGetExtensions = [extensions.ExtensionKind.TableGetType, extensions.ExtensionKind.TableGetMethodType]; + +const tableHasExtensions = [extensions.ExtensionKind.TableHasType, extensions.ExtensionKind.TableHasMethodType]; + +const tableSetExtensions = [extensions.ExtensionKind.TableSetType, extensions.ExtensionKind.TableSetMethodType]; + +const tableExtensions = [ + extensions.ExtensionKind.TableNewType, + ...tableDeleteExtensions, + ...tableGetExtensions, + ...tableHasExtensions, + ...tableSetExtensions, +]; + +function getTableExtensionKindForCall( + context: TransformationContext, + node: ts.CallExpression, + validExtensions: extensions.ExtensionKind[] +) { + const type = getFunctionTypeForCall(context, node); + return type && validExtensions.find(extensionKind => extensions.isExtensionType(type, extensionKind)); +} + +export function isTableExtensionIdentifier(context: TransformationContext, node: ts.Identifier) { + const type = context.checker.getTypeAtLocation(node); + return tableExtensions.some(extensionKind => extensions.isExtensionType(type, extensionKind)); +} + +export function isTableDeleteCall(context: TransformationContext, node: ts.CallExpression) { + return getTableExtensionKindForCall(context, node, tableDeleteExtensions) !== undefined; +} + +export function isTableGetCall(context: TransformationContext, node: ts.CallExpression) { + return getTableExtensionKindForCall(context, node, tableGetExtensions) !== undefined; +} + +export function isTableHasCall(context: TransformationContext, node: ts.CallExpression) { + return getTableExtensionKindForCall(context, node, tableHasExtensions) !== undefined; +} + +export function isTableSetCall(context: TransformationContext, node: ts.CallExpression) { + return getTableExtensionKindForCall(context, node, tableSetExtensions) !== undefined; +} + +export function isTableNewCall(context: TransformationContext, node: ts.NewExpression) { + const type = context.checker.getTypeAtLocation(node.expression); + return extensions.isExtensionType(type, extensions.ExtensionKind.TableNewType); +} + +export function transformTableDeleteExpression(context: TransformationContext, node: ts.CallExpression): lua.Statement { + const extensionKind = getTableExtensionKindForCall(context, node, tableDeleteExtensions); + assert(extensionKind); + + const args = node.arguments.slice(); + if ( + args.length === 1 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + // In case of method (no table argument), push method owner to front of args list + args.unshift(node.expression.expression); + } + + // arg0[arg1] = nil + return lua.createAssignmentStatement( + lua.createTableIndexExpression(context.transformExpression(args[0]), context.transformExpression(args[1])), + lua.createNilLiteral(), + node + ); +} + +export function transformTableGetExpression(context: TransformationContext, node: ts.CallExpression): lua.Expression { + const extensionKind = getTableExtensionKindForCall(context, node, tableGetExtensions); + assert(extensionKind); + + const args = node.arguments.slice(); + if ( + args.length === 1 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + // In case of method (no table argument), push method owner to front of args list + args.unshift(node.expression.expression); + } + + // arg0[arg1] + return lua.createTableIndexExpression( + context.transformExpression(args[0]), + context.transformExpression(args[1]), + node + ); +} + +export function transformTableHasExpression(context: TransformationContext, node: ts.CallExpression): lua.Expression { + const extensionKind = getTableExtensionKindForCall(context, node, tableHasExtensions); + assert(extensionKind); + + const args = node.arguments.slice(); + if ( + args.length === 1 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + // In case of method (no table argument), push method owner to front of args list + args.unshift(node.expression.expression); + } + + // arg0[arg1] + const tableIndexExpression = lua.createTableIndexExpression( + context.transformExpression(args[0]), + context.transformExpression(args[1]) + ); + + // arg0[arg1] ~= nil + return lua.createBinaryExpression( + tableIndexExpression, + lua.createNilLiteral(), + lua.SyntaxKind.InequalityOperator, + node + ); +} + +export function transformTableSetExpression(context: TransformationContext, node: ts.CallExpression): lua.Statement { + const extensionKind = getTableExtensionKindForCall(context, node, tableSetExtensions); + assert(extensionKind); + + const args = node.arguments.slice(); + if ( + args.length === 2 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + // In case of method (no table argument), push method owner to front of args list + args.unshift(node.expression.expression); + } + + // arg0[arg1] = arg2 + return lua.createAssignmentStatement( + lua.createTableIndexExpression(context.transformExpression(args[0]), context.transformExpression(args[1])), + context.transformExpression(args[2]), + node + ); +} diff --git a/src/transformation/visitors/language-extensions/vararg.ts b/src/transformation/visitors/language-extensions/vararg.ts new file mode 100644 index 000000000..99eea82a9 --- /dev/null +++ b/src/transformation/visitors/language-extensions/vararg.ts @@ -0,0 +1,16 @@ +import * as ts from "typescript"; +import { TransformationContext } from "../../context"; +import * as extensions from "../../utils/language-extensions"; +import { Scope, ScopeType } from "../../utils/scope"; + +export function isGlobalVarargConstant(context: TransformationContext, symbol: ts.Symbol, scope: Scope) { + return ( + scope.type === ScopeType.File && + extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.VarargConstant) + ); +} + +export function isVarargConstantNode(context: TransformationContext, node: ts.Node): boolean { + const symbol = context.checker.getSymbolAtLocation(node); + return symbol ? extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.VarargConstant) : false; +} diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts index 6544367a2..75b4a3224 100644 --- a/src/transformation/visitors/literal.ts +++ b/src/transformation/visitors/literal.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { assertNever } from "../../utils"; import { FunctionVisitor, TransformationContext, Visitors } from "../context"; -import { unsupportedAccessorInObjectLiteral } from "../utils/diagnostics"; +import { invalidMultiFunctionUse, unsupportedAccessorInObjectLiteral } from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { createSafeName, hasUnsafeIdentifierName, hasUnsafeSymbolName } from "../utils/safe-names"; @@ -10,6 +10,8 @@ import { getSymbolIdOfSymbol, trackSymbolReference } from "../utils/symbols"; import { isArrayType } from "../utils/typescript"; import { transformFunctionLikeDeclaration } from "./function"; import { flattenSpreadExpressions } from "./call"; +import { findMultiAssignmentViolations } from "./language-extensions/multi"; +import { formatJSXStringValueLiteral } from "./jsx/jsx"; // TODO: Move to object-literal.ts? export function transformPropertyName(context: TransformationContext, node: ts.PropertyName): lua.Expression { @@ -37,7 +39,7 @@ export function createShorthandIdentifier( const name = isUnsafeName ? createSafeName(propertyName) : propertyName; - let identifier = context.transformExpression(ts.createIdentifier(name)); + let identifier = context.transformExpression(ts.factory.createIdentifier(name)); lua.setNodeOriginal(identifier, propertyIdentifier); if (valueSymbol !== undefined && lua.isIdentifier(identifier)) { identifier.symbolId = getSymbolIdOfSymbol(context, valueSymbol); @@ -61,76 +63,103 @@ const transformNumericLiteralExpression: FunctionVisitor = ex return lua.createNumericLiteral(Number(expression.text), expression); }; -const transformObjectLiteralExpression: FunctionVisitor = (expression, context) => { - let properties: lua.TableFieldExpression[] = []; - const tableExpressions: lua.Expression[] = []; +const transformObjectLiteralExpressionOrJsxAttributes: FunctionVisitor = + (expression, context) => { + const violations = findMultiAssignmentViolations(context, expression); + if (violations.length > 0) { + context.diagnostics.push(...violations.map(e => invalidMultiFunctionUse(e))); + return lua.createNilLiteral(expression); + } - for (const element of expression.properties) { - const name = element.name ? transformPropertyName(context, element.name) : undefined; + let properties: lua.TableFieldExpression[] = []; + const tableExpressions: lua.Expression[] = []; + + for (const element of expression.properties) { + const name = element.name ? transformPropertyName(context, element.name) : undefined; + + if (ts.isPropertyAssignment(element)) { + const expression = context.transformExpression(element.initializer); + properties.push(lua.createTableFieldExpression(expression, name, element)); + } else if (ts.isJsxAttribute(element)) { + const initializer = element.initializer; + let expression: lua.Expression; + if (initializer === undefined) { + expression = lua.createBooleanLiteral(true); + } else if (ts.isStringLiteral(initializer)) { + const text = formatJSXStringValueLiteral(initializer.text); + expression = lua.createStringLiteral(text, initializer); + } else if (ts.isJsxExpression(initializer)) { + expression = initializer.expression + ? context.transformExpression(initializer.expression) + : lua.createBooleanLiteral(true); + } else { + assertNever(initializer); + } + properties.push(lua.createTableFieldExpression(expression, name, element)); + } else if (ts.isShorthandPropertyAssignment(element)) { + const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); + if (valueSymbol) { + trackSymbolReference(context, valueSymbol, element.name); + } + + const identifier = createShorthandIdentifier(context, valueSymbol, element.name); + properties.push(lua.createTableFieldExpression(identifier, name, element)); + } else if (ts.isMethodDeclaration(element)) { + const expression = transformFunctionLikeDeclaration(element, context); + properties.push(lua.createTableFieldExpression(expression, name, element)); + } else if (ts.isSpreadAssignment(element) || ts.isJsxSpreadAttribute(element)) { + // Create a table for preceding properties to preserve property order + // { x: 0, ...{ y: 2 }, y: 1, z: 2 } --> __TS__ObjectAssign({x = 0}, {y = 2}, {y = 1, z = 2}) + if (properties.length > 0) { + const tableExpression = lua.createTableExpression(properties, expression); + tableExpressions.push(tableExpression); + properties = []; + } + + const type = context.checker.getTypeAtLocation(element.expression); + let tableExpression: lua.Expression; + if (isArrayType(context, type)) { + tableExpression = transformLuaLibFunction( + context, + LuaLibFeature.ArrayToObject, + element.expression, + context.transformExpression(element.expression) + ); + } else { + tableExpression = context.transformExpression(element.expression); + } - if (ts.isPropertyAssignment(element)) { - const expression = context.transformExpression(element.initializer); - properties.push(lua.createTableFieldExpression(expression, name, element)); - } else if (ts.isShorthandPropertyAssignment(element)) { - const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); - if (valueSymbol) { - trackSymbolReference(context, valueSymbol, element.name); + tableExpressions.push(tableExpression); + } else if (ts.isAccessor(element)) { + context.diagnostics.push(unsupportedAccessorInObjectLiteral(element)); + } else { + assertNever(element); } + } - const identifier = createShorthandIdentifier(context, valueSymbol, element.name); - properties.push(lua.createTableFieldExpression(identifier, name, element)); - } else if (ts.isMethodDeclaration(element)) { - const expression = transformFunctionLikeDeclaration(element, context); - properties.push(lua.createTableFieldExpression(expression, name, element)); - } else if (ts.isSpreadAssignment(element)) { - // Create a table for preceding properties to preserve property order - // { x: 0, ...{ y: 2 }, y: 1, z: 2 } --> __TS__ObjectAssign({x = 0}, {y = 2}, {y = 1, z = 2}) + if (tableExpressions.length === 0) { + return lua.createTableExpression(properties, expression); + } else { if (properties.length > 0) { const tableExpression = lua.createTableExpression(properties, expression); tableExpressions.push(tableExpression); - properties = []; } - const type = context.checker.getTypeAtLocation(element.expression); - let tableExpression: lua.Expression; - if (isArrayType(context, type)) { - tableExpression = transformLuaLibFunction( - context, - LuaLibFeature.ArrayToObject, - element.expression, - context.transformExpression(element.expression) - ); - } else { - tableExpression = context.transformExpression(element.expression); + if (tableExpressions[0].kind !== lua.SyntaxKind.TableExpression) { + tableExpressions.unshift(lua.createTableExpression(undefined, expression)); } - tableExpressions.push(tableExpression); - } else if (ts.isAccessor(element)) { - context.diagnostics.push(unsupportedAccessorInObjectLiteral(element)); - } else { - assertNever(element); - } - } - - if (tableExpressions.length === 0) { - return lua.createTableExpression(properties, expression); - } else { - if (properties.length > 0) { - const tableExpression = lua.createTableExpression(properties, expression); - tableExpressions.push(tableExpression); - } - - if (tableExpressions[0].kind !== lua.SyntaxKind.TableExpression) { - tableExpressions.unshift(lua.createTableExpression(undefined, expression)); + return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...tableExpressions); } - - return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...tableExpressions); - } -}; + }; +const transformObjectLiteralExpression: FunctionVisitor = + transformObjectLiteralExpressionOrJsxAttributes; +export const transformJsxAttributes: FunctionVisitor = + transformObjectLiteralExpressionOrJsxAttributes; const transformArrayLiteralExpression: FunctionVisitor = (expression, context) => { const filteredElements = expression.elements.map(e => - ts.isOmittedExpression(e) ? ts.createIdentifier("undefined") : e + ts.isOmittedExpression(e) ? ts.factory.createIdentifier("undefined") : e ); const values = flattenSpreadExpressions(context, filteredElements).map(e => lua.createTableFieldExpression(e)); diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts index 67adb2ca2..64d2c211b 100644 --- a/src/transformation/visitors/loops/for-of.ts +++ b/src/transformation/visitors/loops/for-of.ts @@ -1,121 +1,13 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { assert, cast } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; -import { AnnotationKind, getTypeAnnotations, isForRangeType, isLuaIteratorType } from "../../utils/annotations"; -import { invalidForRangeCall, luaIteratorForbiddenUsage } from "../../utils/diagnostics"; +import { AnnotationKind, isForRangeType, isLuaIteratorType } from "../../utils/annotations"; +import { annotationRemoved } from "../../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; -import { isArrayType, isNumberType } from "../../utils/typescript"; -import { transformArguments } from "../call"; -import { transformIdentifier } from "../identifier"; -import { transformArrayBindingElement } from "../variable-declaration"; -import { getVariableDeclarationBinding, transformForInitializer, transformLoopBody } from "./utils"; - -function transformForRangeStatement( - context: TransformationContext, - statement: ts.ForOfStatement, - block: lua.Block -): lua.Statement { - assert(ts.isCallExpression(statement.expression)); - - const callArguments = statement.expression.arguments; - if (callArguments.length !== 2 && callArguments.length !== 3) { - context.diagnostics.push( - invalidForRangeCall(statement.expression, `Expected 2-3 arguments, but got ${callArguments.length}`) - ); - } - - if (statement.expression.arguments.some(a => !isNumberType(context, context.checker.getTypeAtLocation(a)))) { - context.diagnostics.push(invalidForRangeCall(statement.expression, "arguments must be numbers")); - } - - const controlVariable = getControlVariable() ?? lua.createAnonymousIdentifier(); - function getControlVariable(): lua.Identifier | undefined { - if (!ts.isVariableDeclarationList(statement.initializer)) { - context.diagnostics.push( - invalidForRangeCall(statement.initializer, "loop must declare it's own control variable") - ); - return; - } - - const binding = getVariableDeclarationBinding(context, statement.initializer); - if (!ts.isIdentifier(binding)) { - context.diagnostics.push(invalidForRangeCall(statement.initializer, "destructuring cannot be used")); - return; - } - - if (!isNumberType(context, context.checker.getTypeAtLocation(binding))) { - context.diagnostics.push( - invalidForRangeCall(statement.expression, "function must return Iterable") - ); - } - - return transformIdentifier(context, binding); - } - - const [start = lua.createNumericLiteral(0), limit = lua.createNumericLiteral(0), step] = transformArguments( - context, - callArguments, - context.checker.getResolvedSignature(statement.expression) - ); - - return lua.createForStatement(block, controlVariable, start, limit, step, statement); -} - -function transformForOfLuaIteratorStatement( - context: TransformationContext, - statement: ts.ForOfStatement, - block: lua.Block -): lua.Statement { - const luaIterator = context.transformExpression(statement.expression); - const type = context.checker.getTypeAtLocation(statement.expression); - const tupleReturn = getTypeAnnotations(type).has(AnnotationKind.TupleReturn); - let identifiers: lua.Identifier[] = []; - - if (tupleReturn) { - // LuaIterator + TupleReturn - - if (ts.isVariableDeclarationList(statement.initializer)) { - // Variables declared in for loop - // for ${initializer} in ${iterable} do - - const binding = getVariableDeclarationBinding(context, statement.initializer); - if (ts.isArrayBindingPattern(binding)) { - identifiers = binding.elements.map(e => transformArrayBindingElement(context, e)); - } else { - context.diagnostics.push(luaIteratorForbiddenUsage(binding)); - } - } else if (ts.isArrayLiteralExpression(statement.initializer)) { - // Variables NOT declared in for loop - catch iterator values in temps and assign - // for ____value0 in ${iterable} do - // ${initializer} = ____value0 - - identifiers = statement.initializer.elements.map((_, i) => lua.createIdentifier(`____value${i}`)); - if (identifiers.length > 0) { - block.statements.unshift( - lua.createAssignmentStatement( - statement.initializer.elements.map(e => - cast(context.transformExpression(e), lua.isAssignmentLeftHandSideExpression) - ), - identifiers - ) - ); - } - } else { - context.diagnostics.push(luaIteratorForbiddenUsage(statement.initializer)); - } - } else { - // LuaIterator (no TupleReturn) - - identifiers.push(transformForInitializer(context, statement.initializer, block)); - } - - if (identifiers.length === 0) { - identifiers.push(lua.createAnonymousIdentifier()); - } - - return lua.createForInStatement(block, identifiers, [luaIterator], statement); -} +import { isArrayType } from "../../utils/typescript"; +import { isIterableExpression, transformForOfIterableStatement } from "../language-extensions/iterable"; +import { isRangeFunction, transformRangeStatement } from "../language-extensions/range"; +import { transformForInitializer, transformLoopBody } from "./utils"; function transformForOfArrayStatement( context: TransformationContext, @@ -149,10 +41,14 @@ function transformForOfIteratorStatement( export const transformForOfStatement: FunctionVisitor = (node, context) => { const body = lua.createBlock(transformLoopBody(context, node)); - if (ts.isCallExpression(node.expression) && isForRangeType(context, node.expression.expression)) { - return transformForRangeStatement(context, node, body); + if (ts.isCallExpression(node.expression) && isRangeFunction(context, node.expression)) { + return transformRangeStatement(context, node, body); + } else if (ts.isCallExpression(node.expression) && isForRangeType(context, node.expression.expression)) { + context.diagnostics.push(annotationRemoved(node.expression, AnnotationKind.ForRange)); + } else if (isIterableExpression(context, node.expression)) { + return transformForOfIterableStatement(context, node, body); } else if (isLuaIteratorType(context, node.expression)) { - return transformForOfLuaIteratorStatement(context, node, body); + context.diagnostics.push(annotationRemoved(node.expression, AnnotationKind.LuaIterator)); } else if (isArrayType(context, context.checker.getTypeAtLocation(node.expression))) { return transformForOfArrayStatement(context, node, body); } else { diff --git a/src/transformation/visitors/loops/for.ts b/src/transformation/visitors/loops/for.ts index f81a62199..98864082e 100644 --- a/src/transformation/visitors/loops/for.ts +++ b/src/transformation/visitors/loops/for.ts @@ -13,7 +13,7 @@ export const transformForStatement: FunctionVisitor = (statemen // local initializer = value result.push(...statement.initializer.declarations.flatMap(d => transformVariableDeclaration(context, d))); } else { - result.push(...context.transformStatements(ts.createExpressionStatement(statement.initializer))); + result.push(...context.transformStatements(ts.factory.createExpressionStatement(statement.initializer))); } } @@ -25,7 +25,7 @@ export const transformForStatement: FunctionVisitor = (statemen const body: lua.Statement[] = transformLoopBody(context, statement); if (statement.incrementor) { - body.push(...context.transformStatements(ts.createExpressionStatement(statement.incrementor))); + body.push(...context.transformStatements(ts.factory.createExpressionStatement(statement.incrementor))); } // while (condition) do ... end diff --git a/src/transformation/visitors/loops/utils.ts b/src/transformation/visitors/loops/utils.ts index 8ee86f4ea..a7402b653 100644 --- a/src/transformation/visitors/loops/utils.ts +++ b/src/transformation/visitors/loops/utils.ts @@ -36,7 +36,7 @@ export function getVariableDeclarationBinding( checkVariableDeclarationList(context, node); if (node.declarations.length === 0) { - return ts.createIdentifier("____"); + return ts.factory.createIdentifier("____"); } return node.declarations[0].name; diff --git a/src/transformation/visitors/lua-table.ts b/src/transformation/visitors/lua-table.ts deleted file mode 100644 index 300837c1e..000000000 --- a/src/transformation/visitors/lua-table.ts +++ /dev/null @@ -1,158 +0,0 @@ -import * as ts from "typescript"; -import * as lua from "../../LuaAST"; -import { TransformationContext } from "../context"; -import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { luaTableCannotBeAccessedDynamically, luaTableForbiddenUsage, unsupportedProperty } from "../utils/diagnostics"; -import { transformArguments } from "./call"; - -const parseLuaTableExpression = (context: TransformationContext, node: ts.PropertyAccessExpression) => - [context.transformExpression(node.expression), node.name.text] as const; - -function validateLuaTableCall( - context: TransformationContext, - node: ts.Node, - methodName: string, - callArguments: ts.NodeArray -): void { - for (const argument of callArguments) { - if (ts.isSpreadElement(argument)) { - context.diagnostics.push(luaTableForbiddenUsage(argument, "Arguments cannot be spread")); - return; - } - } - - switch (methodName) { - case "get": - if (callArguments.length !== 1) { - context.diagnostics.push( - luaTableForbiddenUsage(node, `Expected 1 arguments, but got ${callArguments.length}`) - ); - } - break; - - case "set": - if (callArguments.length !== 2) { - context.diagnostics.push( - luaTableForbiddenUsage(node, `Expected 2 arguments, but got ${callArguments.length}`) - ); - } - break; - } -} - -export function transformLuaTableExpressionStatement( - context: TransformationContext, - node: ts.ExpressionStatement -): lua.Statement | undefined { - const expression = ts.isExpressionStatement(node) ? node.expression : node; - - if (!ts.isCallExpression(expression) || !ts.isPropertyAccessExpression(expression.expression)) return; - - const ownerType = context.checker.getTypeAtLocation(expression.expression.expression); - const annotations = getTypeAnnotations(ownerType); - if (!annotations.has(AnnotationKind.LuaTable)) return; - - const [luaTable, methodName] = parseLuaTableExpression(context, expression.expression); - validateLuaTableCall(context, expression, methodName, expression.arguments); - const signature = context.checker.getResolvedSignature(expression); - const params = transformArguments(context, expression.arguments, signature); - - switch (methodName) { - case "get": - return lua.createVariableDeclarationStatement( - lua.createAnonymousIdentifier(expression), - lua.createTableIndexExpression(luaTable, params[0] ?? lua.createNilLiteral(), expression), - expression - ); - case "set": - return lua.createAssignmentStatement( - lua.createTableIndexExpression(luaTable, params[0] ?? lua.createNilLiteral(), expression), - [params[1] ?? lua.createNilLiteral()], - expression - ); - default: - context.diagnostics.push(unsupportedProperty(expression.expression.name, "LuaTable", methodName)); - } -} - -export function transformLuaTableCallExpression( - context: TransformationContext, - node: ts.CallExpression -): lua.Expression | undefined { - if (!ts.isPropertyAccessExpression(node.expression)) return; - - const ownerType = context.checker.getTypeAtLocation(node.expression.expression); - const annotations = getTypeAnnotations(ownerType); - if (!annotations.has(AnnotationKind.LuaTable)) return; - - const [luaTable, methodName] = parseLuaTableExpression(context, node.expression); - validateLuaTableCall(context, node, methodName, node.arguments); - const signature = context.checker.getResolvedSignature(node); - const params = transformArguments(context, node.arguments, signature); - - switch (methodName) { - case "get": - return lua.createTableIndexExpression(luaTable, params[0] ?? lua.createNilLiteral(), node); - default: - context.diagnostics.push(unsupportedProperty(node.expression.name, "LuaTable", methodName)); - } -} - -export function transformLuaTablePropertyAccessExpression( - context: TransformationContext, - node: ts.PropertyAccessExpression -): lua.Expression | undefined { - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node.expression)); - if (!annotations.has(AnnotationKind.LuaTable)) return; - - const [luaTable, propertyName] = parseLuaTableExpression(context, node); - if (propertyName === "length") { - return lua.createUnaryExpression(luaTable, lua.SyntaxKind.LengthOperator, node); - } - - context.diagnostics.push(unsupportedProperty(node.name, "LuaTable", propertyName)); -} - -export function transformLuaTablePropertyAccessInAssignment( - context: TransformationContext, - node: ts.PropertyAccessExpression -): lua.AssignmentLeftHandSideExpression | undefined { - if (!ts.isPropertyAccessExpression(node)) return; - - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node.expression)); - if (!annotations.has(AnnotationKind.LuaTable)) return; - - const [luaTable, propertyName] = parseLuaTableExpression(context, node); - if (propertyName === "length") { - context.diagnostics.push(luaTableForbiddenUsage(node, "A LuaTable object's length cannot be re-assigned")); - return lua.createTableIndexExpression(luaTable, lua.createStringLiteral(propertyName), node); - } - - context.diagnostics.push(unsupportedProperty(node.name, "LuaTable", propertyName)); -} - -export function validateLuaTableElementAccessExpression( - context: TransformationContext, - node: ts.ElementAccessExpression -): void { - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node.expression)); - if (annotations.has(AnnotationKind.LuaTable)) { - context.diagnostics.push(luaTableCannotBeAccessedDynamically(node)); - } -} - -export function transformLuaTableNewExpression( - context: TransformationContext, - node: ts.NewExpression -): lua.Expression | undefined { - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node)); - if (!annotations.has(AnnotationKind.LuaTable)) return; - - if (node.arguments && node.arguments.length > 0) { - context.diagnostics.push( - luaTableForbiddenUsage(node, "No parameters are allowed when constructing a LuaTable object") - ); - } - - return lua.createTableExpression(); -} diff --git a/src/transformation/visitors/modules/export.ts b/src/transformation/visitors/modules/export.ts index 5e12c6c5e..955f56866 100644 --- a/src/transformation/visitors/modules/export.ts +++ b/src/transformation/visitors/modules/export.ts @@ -36,7 +36,7 @@ export const transformExportAssignment: FunctionVisitor = ( } }; -function transformExportAllFrom(context: TransformationContext, node: ts.ExportDeclaration): lua.Statement | undefined { +function transformExportAll(context: TransformationContext, node: ts.ExportDeclaration): lua.Statement | undefined { assert(node.moduleSpecifier); if (!context.resolver.moduleExportsSomeValue(node.moduleSpecifier)) { @@ -44,26 +44,64 @@ function transformExportAllFrom(context: TransformationContext, node: ts.ExportD } const moduleRequire = createModuleRequire(context, node.moduleSpecifier); - const tempModuleIdentifier = lua.createIdentifier("____export"); + // export * as ns from "..."; + // exports.ns = require(...) + if (node.exportClause && ts.isNamespaceExport(node.exportClause)) { + const assignToExports = lua.createAssignmentStatement( + lua.createTableIndexExpression( + createExportsIdentifier(), + lua.createStringLiteral(node.exportClause.name.text) + ), + moduleRequire + ); + return assignToExports; + } + + // export * from "..."; + // exports all values EXCEPT "default" from "..." + const result: lua.Statement[] = []; + + // local ____export = require(...) + const tempModuleIdentifier = lua.createIdentifier("____export"); const declaration = lua.createVariableDeclarationStatement(tempModuleIdentifier, moduleRequire); + result.push(declaration); + // ____exports[____exportKey] = ____exportValue const forKey = lua.createIdentifier("____exportKey"); const forValue = lua.createIdentifier("____exportValue"); + const leftAssignment = lua.createAssignmentStatement( + lua.createTableIndexExpression(createExportsIdentifier(), forKey), + forValue + ); - const body = lua.createBlock([ - lua.createAssignmentStatement(lua.createTableIndexExpression(createExportsIdentifier(), forKey), forValue), - ]); + // if key ~= "default" then + // -- export the value, do not export "default" values + // end + const ifBody = lua.createBlock([leftAssignment]); + const ifStatement = lua.createIfStatement( + lua.createBinaryExpression( + lua.cloneIdentifier(forKey), + lua.createStringLiteral("default"), + lua.SyntaxKind.InequalityOperator + ), + ifBody + ); + // for ____exportKey, ____exportValue in ____export do + // -- export ____exportValue, unless ____exportKey is "default" + // end const pairsIdentifier = lua.createIdentifier("pairs"); const forIn = lua.createForInStatement( - body, + lua.createBlock([ifStatement]), [lua.cloneIdentifier(forKey), lua.cloneIdentifier(forValue)], [lua.createCallExpression(pairsIdentifier, [lua.cloneIdentifier(tempModuleIdentifier)])] ); + result.push(forIn); + // Wrap this in a DoStatement to prevent polluting the scope. - return lua.createDoStatement([declaration, forIn], node); + return lua.createDoStatement(result, node); } const isDefaultExportSpecifier = (node: ts.ExportSpecifier) => @@ -91,12 +129,15 @@ function transformExportSpecifiersFrom( exportSpecifiers: ts.ExportSpecifier[] ): lua.Statement { // First transpile as import clause - const importClause = ts.createImportClause( + const importClause = ts.factory.createImportClause( + false, undefined, - ts.createNamedImports(exportSpecifiers.map(s => ts.createImportSpecifier(s.propertyName, s.name))) + ts.factory.createNamedImports( + exportSpecifiers.map(s => ts.factory.createImportSpecifier(s.propertyName, s.name)) + ) ); - const importDeclaration = ts.createImportDeclaration( + const importDeclaration = ts.factory.createImportDeclaration( statement.decorators, statement.modifiers, importClause, @@ -104,7 +145,7 @@ function transformExportSpecifiersFrom( ); // Wrap in block to prevent imports from hoisting out of `do` statement - const [block] = transformScopeBlock(context, ts.createBlock([importDeclaration]), ScopeType.Block); + const [block] = transformScopeBlock(context, ts.factory.createBlock([importDeclaration]), ScopeType.Block); const result = block.statements; // Now the module is imported, add the imports to the export table @@ -127,7 +168,7 @@ export const getExported = (context: TransformationContext, exportSpecifiers: ts export const transformExportDeclaration: FunctionVisitor = (node, context) => { if (!node.exportClause) { // export * from "..."; - return transformExportAllFrom(context, node); + return transformExportAll(context, node); } if (!context.resolver.isValueAliasDeclaration(node)) { @@ -136,7 +177,7 @@ export const transformExportDeclaration: FunctionVisitor = if (ts.isNamespaceExport(node.exportClause)) { // export * as ns from "..."; - throw new Error("NamespaceExport is not supported"); + return transformExportAll(context, node); } const exportSpecifiers = getExported(context, node.exportClause); diff --git a/src/transformation/visitors/modules/import.ts b/src/transformation/visitors/modules/import.ts index 34fa216d6..d8daba8c9 100644 --- a/src/transformation/visitors/modules/import.ts +++ b/src/transformation/visitors/modules/import.ts @@ -1,45 +1,21 @@ import * as path from "path"; import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { formatPathToLuaPath } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; -import { AnnotationKind, getSymbolAnnotations, getTypeAnnotations } from "../../utils/annotations"; +import { AnnotationKind, getSymbolAnnotations } from "../../utils/annotations"; import { createDefaultExportStringLiteral } from "../../utils/export"; import { createHoistableVariableDeclarationStatement } from "../../utils/lua-ast"; import { createSafeName } from "../../utils/safe-names"; import { peekScope } from "../../utils/scope"; import { transformIdentifier } from "../identifier"; import { transformPropertyName } from "../literal"; -import { unresolvableRequirePath } from "../../utils/diagnostics"; -const getAbsoluteImportPath = (relativePath: string, directoryPath: string, options: ts.CompilerOptions): string => - !relativePath.startsWith(".") && options.baseUrl - ? path.resolve(options.baseUrl, relativePath) - : path.resolve(directoryPath, relativePath); - -function getImportPath(context: TransformationContext, relativePath: string, node: ts.Node): string { - const { options, sourceFile } = context; - const { fileName } = sourceFile; - const rootDir = options.rootDir ? path.resolve(options.rootDir) : path.resolve("."); - - const absoluteImportPath = path.format( - path.parse(getAbsoluteImportPath(relativePath, path.dirname(fileName), options)) - ); - const absoluteRootDirPath = path.format(path.parse(rootDir)); - if (absoluteImportPath.includes(absoluteRootDirPath)) { - return formatPathToLuaPath(absoluteImportPath.replace(absoluteRootDirPath, "").slice(1)); - } else { - context.diagnostics.push(unresolvableRequirePath(node, relativePath)); - return relativePath; - } -} - -function shouldResolveModulePath(context: TransformationContext, moduleSpecifier: ts.Expression): boolean { +function isNoResolutionPath(context: TransformationContext, moduleSpecifier: ts.Expression): boolean { const moduleOwnerSymbol = context.checker.getSymbolAtLocation(moduleSpecifier); - if (!moduleOwnerSymbol) return true; + if (!moduleOwnerSymbol) return false; const annotations = getSymbolAnnotations(moduleOwnerSymbol); - return !annotations.has(AnnotationKind.NoResolution); + return annotations.has(AnnotationKind.NoResolution); } export function createModuleRequire( @@ -49,8 +25,8 @@ export function createModuleRequire( ): lua.CallExpression { const params: lua.Expression[] = []; if (ts.isStringLiteral(moduleSpecifier)) { - const modulePath = shouldResolveModulePath(context, moduleSpecifier) - ? getImportPath(context, moduleSpecifier.text.replace(/"/g, ""), moduleSpecifier) + const modulePath = isNoResolutionPath(context, moduleSpecifier) + ? `@NoResolution:${moduleSpecifier.text}` : moduleSpecifier.text; params.push(lua.createStringLiteral(modulePath)); @@ -60,13 +36,7 @@ export function createModuleRequire( } function shouldBeImported(context: TransformationContext, importNode: ts.ImportClause | ts.ImportSpecifier): boolean { - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(importNode)); - - return ( - context.resolver.isReferencedAliasDeclaration(importNode) && - !annotations.has(AnnotationKind.Extension) && - !annotations.has(AnnotationKind.MetaExtension) - ); + return context.resolver.isReferencedAliasDeclaration(importNode); } function transformImportSpecifier( diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts index 35190705f..d41aefd75 100644 --- a/src/transformation/visitors/namespace.ts +++ b/src/transformation/visitors/namespace.ts @@ -2,6 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; +import { annotationRemoved } from "../utils/diagnostics"; import { addExportToIdentifier, createExportedIdentifier, getIdentifierExportScope } from "../utils/export"; import { createHoistableVariableDeclarationStatement, @@ -52,8 +53,8 @@ const currentNamespaces = new WeakMap = (node, context) => { const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node)); // If phantom namespace elide the declaration and return the body - if (annotations.has(AnnotationKind.Phantom) && node.body && ts.isModuleBlock(node.body)) { - return context.transformStatements(node.body.statements); + if (annotations.has(AnnotationKind.Phantom)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.Phantom)); } const currentNamespace = currentNamespaces.get(context); @@ -74,8 +75,8 @@ export const transformModuleDeclaration: FunctionVisitor = // - declared as a class or function at all (TS requires these to be before module, unless module is empty) const isFirstDeclaration = symbol === undefined || - (!symbol.declarations.some(d => ts.isClassLike(d) || ts.isFunctionDeclaration(d)) && - node === symbol.declarations.find(ts.isModuleDeclaration)); + (!symbol.declarations?.some(d => ts.isClassLike(d) || ts.isFunctionDeclaration(d)) && + ts.getOriginalNode(node) === symbol.declarations?.find(ts.isModuleDeclaration)); if (isNonModuleMergeable) { // 'local NS = NS or {}' or 'exportTable.NS = exportTable.NS or {}' diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index 970db6be0..2ed0ebe3e 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -1,11 +1,62 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; -import { FunctionVisitor } from "../context"; -import { isInTupleReturnFunction, isTupleReturnCall } from "../utils/annotations"; +import { FunctionVisitor, TransformationContext } from "../context"; import { validateAssignment } from "../utils/assignment-validation"; import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { ScopeType, walkScopesUp } from "../utils/scope"; -import { isArrayType } from "../utils/typescript"; +import { transformArguments } from "./call"; +import { + returnsMultiType, + shouldMultiReturnCallBeWrapped, + isMultiFunctionCall, + isMultiReturnType, + isInMultiReturnFunction, + canBeMultiReturnType, +} from "./language-extensions/multi"; +import { invalidMultiFunctionReturnType } from "../utils/diagnostics"; + +function transformExpressionsInReturn( + context: TransformationContext, + node: ts.Expression, + insideTryCatch: boolean +): lua.Expression[] { + const expressionType = context.checker.getTypeAtLocation(node); + + if (ts.isCallExpression(node)) { + // $multi(...) + if (isMultiFunctionCall(context, node)) { + // Don't allow $multi to be implicitly cast to something other than LuaMultiReturn + const type = context.checker.getContextualType(node); + if (type && !canBeMultiReturnType(type)) { + context.diagnostics.push(invalidMultiFunctionReturnType(node)); + } + + let returnValues = transformArguments(context, node.arguments); + if (insideTryCatch) { + returnValues = [wrapInTable(...returnValues)]; // Wrap results when returning inside try/catch + } + return returnValues; + } + + // Force-wrap LuaMultiReturn when returning inside try/catch + if (insideTryCatch && returnsMultiType(context, node) && !shouldMultiReturnCallBeWrapped(context, node)) { + return [wrapInTable(context.transformExpression(node))]; + } + } else if (isInMultiReturnFunction(context, node) && isMultiReturnType(expressionType)) { + // Unpack objects typed as LuaMultiReturn + return [createUnpackCall(context, context.transformExpression(node), node)]; + } + + return [context.transformExpression(node)]; +} + +export function transformExpressionBodyToReturnStatement( + context: TransformationContext, + node: ts.Expression +): lua.Statement { + const expressions = transformExpressionsInReturn(context, node, false); + return lua.createReturnStatement(expressions, node); +} export const transformReturnStatement: FunctionVisitor = (statement, context) => { // Bubble up explicit return flag and check if we're inside a try/catch block @@ -29,27 +80,7 @@ export const transformReturnStatement: FunctionVisitor = (st validateAssignment(context, statement, expressionType, returnType); } - if (isInTupleReturnFunction(context, statement)) { - // Parent function is a TupleReturn function - if (ts.isArrayLiteralExpression(statement.expression)) { - // If return expression is an array literal, leave out brackets. - results = statement.expression.elements.map(e => context.transformExpression(e)); - } else if (!isTupleReturnCall(context, statement.expression) && isArrayType(context, expressionType)) { - // If return expression is an array-type and not another TupleReturn call, unpack it - results = [ - createUnpackCall(context, context.transformExpression(statement.expression), statement.expression), - ]; - } else { - results = [context.transformExpression(statement.expression)]; - } - - // Wrap tupleReturn results when returning inside try/catch - if (insideTryCatch) { - results = [wrapInTable(...results)]; - } - } else { - results = [context.transformExpression(statement.expression)]; - } + results = transformExpressionsInReturn(context, statement.expression, insideTryCatch); } else { // Empty return results = []; diff --git a/src/transformation/visitors/sourceFile.ts b/src/transformation/visitors/sourceFile.ts index 539c9f9d7..41561c67f 100644 --- a/src/transformation/visitors/sourceFile.ts +++ b/src/transformation/visitors/sourceFile.ts @@ -3,6 +3,7 @@ import * as lua from "../../LuaAST"; import { assert } from "../../utils"; import { FunctionVisitor } from "../context"; import { createExportsIdentifier } from "../utils/lua-ast"; +import { getUsedLuaLibFeatures } from "../utils/lualib"; import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; import { hasExportEquals } from "../utils/typescript"; @@ -22,6 +23,7 @@ export const transformSourceFileNode: FunctionVisitor = (node, co } } else { pushScope(context, ScopeType.File); + statements = performHoisting(context, context.transformStatements(node.statements)); popScope(context); @@ -39,5 +41,6 @@ export const transformSourceFileNode: FunctionVisitor = (node, co } } - return lua.createBlock(statements, node); + const trivia = node.getFullText().match(/^#!.*\r?\n/)?.[0] ?? ""; + return lua.createFile(statements, getUsedLuaLibFeatures(context), trivia, node); }; diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts new file mode 100644 index 000000000..f8ebdc79d --- /dev/null +++ b/src/transformation/visitors/spread.ts @@ -0,0 +1,85 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { AnnotationKind, isVarargType } from "../utils/annotations"; +import { createUnpackCall } from "../utils/lua-ast"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { + findScope, + hasReferencedSymbol, + hasReferencedUndefinedLocalFunction, + isFunctionScopeWithDefinition, + ScopeType, +} from "../utils/scope"; +import { isArrayType } from "../utils/typescript"; +import { isMultiReturnCall } from "./language-extensions/multi"; +import { annotationRemoved } from "../utils/diagnostics"; +import { isGlobalVarargConstant } from "./language-extensions/vararg"; + +export function isOptimizedVarArgSpread(context: TransformationContext, symbol: ts.Symbol, identifier: ts.Identifier) { + if (!ts.isSpreadElement(identifier.parent)) { + return false; + } + + // Walk up, stopping at any scope types which could stop optimization + const scope = findScope(context, ScopeType.Function | ScopeType.Try | ScopeType.Catch | ScopeType.File); + if (!scope) { + return; + } + + // $vararg global constant + if (isGlobalVarargConstant(context, symbol, scope)) { + return true; + } + + // Scope must be a function scope associated with a real ts function + if (!isFunctionScopeWithDefinition(scope)) { + return false; + } + + // Scope cannot be an async function + if (scope.node.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword)) { + return false; + } + + // Identifier must be a vararg in the local function scope's parameters + const isSpreadParameter = (p: ts.ParameterDeclaration) => + p.dotDotDotToken && ts.isIdentifier(p.name) && context.checker.getSymbolAtLocation(p.name) === symbol; + if (!scope.node.parameters.some(isSpreadParameter)) { + return false; + } + + // De-optimize if already referenced outside of a spread, as the array may have been modified + if (hasReferencedSymbol(context, scope, symbol)) { + return false; + } + + // De-optimize if a function is being hoisted from below to above, as it may have modified the array + if (hasReferencedUndefinedLocalFunction(context, scope)) { + return false; + } + return true; +} + +// TODO: Currently it's also used as an array member +export const transformSpreadElement: FunctionVisitor = (node, context) => { + if (ts.isIdentifier(node.expression)) { + if (isVarargType(context, node.expression)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.Vararg)); + } + const symbol = context.checker.getSymbolAtLocation(node.expression); + if (symbol && isOptimizedVarArgSpread(context, symbol, node.expression)) { + return lua.createDotsLiteral(node); + } + } + + const innerExpression = context.transformExpression(node.expression); + if (isMultiReturnCall(context, node.expression)) return innerExpression; + + const type = context.checker.getTypeAtLocation(node.expression); + if (isArrayType(context, type)) { + return createUnpackCall(context, innerExpression, node); + } + + return transformLuaLibFunction(context, LuaLibFeature.Spread, node, innerExpression); +}; diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index 99ff3df7d..a82ff0bf0 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -18,10 +18,13 @@ export const transformSwitchStatement: FunctionVisitor = (st let statements: lua.Statement[] = []; - const caseClauses = statement.caseBlock.clauses.filter(ts.isCaseClause); - // Starting from the back, concatenating ifs into one big if/elseif statement - const concatenatedIf = caseClauses.reduceRight((previousCondition, clause, index) => { + const concatenatedIf = statement.caseBlock.clauses.reduceRight((previousCondition, clause, index) => { + if (ts.isDefaultClause(clause)) { + // Skip default clause here (needs to be included to ensure index lines up with index later) + return previousCondition; + } + // If the clause condition holds, go to the correct label const condition = lua.createBinaryExpression( switchVariable, diff --git a/src/transformation/visitors/template.ts b/src/transformation/visitors/template.ts index 784cf7e4e..9f9a19b33 100644 --- a/src/transformation/visitors/template.ts +++ b/src/transformation/visitors/template.ts @@ -3,6 +3,7 @@ import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; import { ContextType, getDeclarationContextType } from "../utils/function-context"; import { wrapInToStringForConcat } from "../utils/lua-ast"; +import { isStringType } from "../utils/typescript/types"; import { transformArguments, transformContextualCallExpression } from "./call"; // TODO: Source positions @@ -25,7 +26,12 @@ export const transformTemplateExpression: FunctionVisitor for (const span of node.templateSpans) { const expression = context.transformExpression(span.expression); - parts.push(wrapInToStringForConcat(expression)); + const spanType = context.checker.getTypeAtLocation(span.expression); + if (isStringType(context, spanType)) { + parts.push(expression); + } else { + parts.push(wrapInToStringForConcat(expression)); + } const text = span.literal.text; if (text.length > 0) { @@ -59,29 +65,35 @@ export const transformTaggedTemplateExpression: FunctionVisitor lua.createTableFieldExpression(lua.createStringLiteral(text))) + const rawStringsArray = ts.factory.createArrayLiteralExpression( + rawStrings.map(text => ts.factory.createStringLiteral(text)) ); - const stringTableLiteral = lua.createTableExpression([ - ...strings.map(partialString => lua.createTableFieldExpression(lua.createStringLiteral(partialString))), - lua.createTableFieldExpression(rawStringsTable, lua.createStringLiteral("raw")), + const stringObject = ts.factory.createObjectLiteralExpression([ + ...strings.map((partialString, i) => + ts.factory.createPropertyAssignment( + ts.factory.createNumericLiteral(i + 1), + ts.factory.createStringLiteral(partialString) + ) + ), + ts.factory.createPropertyAssignment("raw", rawStringsArray), ]); + expressions.unshift(stringObject); + // Evaluate if there is a self parameter to be used. const signature = context.checker.getResolvedSignature(expression); const signatureDeclaration = signature?.getDeclaration(); const useSelfParameter = signatureDeclaration && getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void; - // Argument evaluation. - const callArguments = transformArguments(context, expressions, signature); - callArguments.unshift(stringTableLiteral); - if (useSelfParameter) { - return transformContextualCallExpression(context, expression, callArguments); + return transformContextualCallExpression(context, expression, expressions, signature); } + // Argument evaluation. + const callArguments = transformArguments(context, expressions, signature); + const leftHandSideExpression = context.transformExpression(expression.tag); return lua.createCallExpression(leftHandSideExpression, callArguments); }; diff --git a/src/transformation/visitors/unary-expression.ts b/src/transformation/visitors/unary-expression.ts index 76b0e4941..5960c2200 100644 --- a/src/transformation/visitors/unary-expression.ts +++ b/src/transformation/visitors/unary-expression.ts @@ -25,7 +25,7 @@ export function transformUnaryExpressionStatement( context, expression, expression.operand, - ts.createLiteral(1), + ts.factory.createNumericLiteral(1), replacementOperator ); } else if (ts.isPostfixUnaryExpression(expression)) { @@ -37,7 +37,7 @@ export function transformUnaryExpressionStatement( context, expression, expression.operand, - ts.createLiteral(1), + ts.factory.createNumericLiteral(1), replacementOperator ); } @@ -50,7 +50,7 @@ export const transformPostfixUnaryExpression: FunctionVisitor; - const usedProperties = elements.map(e => - lua.createTableFieldExpression( - lua.createBooleanLiteral(true), - lua.createStringLiteral( - ((e.propertyName ?? e.name) as ts.Identifier).text, - e.propertyName ?? e.name - ) - ) + if (ts.isObjectBindingPattern(pattern)) { + const excludedProperties: ts.Identifier[] = []; + + for (const element of pattern.elements) { + // const { ...x } = ...; + // ~~~~ + if (element.dotDotDotToken) continue; + + // const { x } = ...; + // ~ + if (ts.isIdentifier(element.name) && !element.propertyName) { + excludedProperties.push(element.name); + } + + // const { x: ... } = ...; + // ~~~~~~ + if (element.propertyName && element.name && ts.isIdentifier(element.propertyName)) { + excludedProperties.push(element.propertyName); + } + } + + const excludedPropertiesTable = excludedProperties.map(e => + lua.createTableFieldExpression(lua.createBooleanLiteral(true), lua.createStringLiteral(e.text, e)) ); expression = transformLuaLibFunction( @@ -90,7 +102,7 @@ export function transformBindingPattern( LuaLibFeature.ObjectRest, undefined, tableExpression, - lua.createTableExpression(usedProperties) + lua.createTableExpression(excludedPropertiesTable) ); } else { expression = transformLuaLibFunction( @@ -104,7 +116,7 @@ export function transformBindingPattern( } else { expression = lua.createTableIndexExpression( tableExpression, - isObjectBindingPattern ? propertyName : lua.createNumericLiteral(index + 1) + ts.isObjectBindingPattern(pattern) ? propertyName : lua.createNumericLiteral(index + 1) ); } @@ -145,9 +157,11 @@ export function transformBindingVariableDeclaration( // Contain the expression in a temporary variable table = lua.createAnonymousIdentifier(); if (initializer) { - statements.push( - lua.createVariableDeclarationStatement(table, context.transformExpression(initializer)) - ); + let expression = context.transformExpression(initializer); + if (isMultiReturnCall(context, initializer)) { + expression = wrapInTable(expression); + } + statements.push(lua.createVariableDeclarationStatement(table, expression)); } } statements.push(...transformBindingPattern(context, bindingPattern, table)); @@ -160,8 +174,8 @@ export function transformBindingVariableDeclaration( : lua.createAnonymousIdentifier(); if (initializer) { - if (isTupleReturnCall(context, initializer)) { - // Don't unpack @tupleReturn annotated functions + if (isMultiReturnCall(context, initializer)) { + // Don't unpack LuaMultiReturn functions statements.push( ...createLocalOrExportedOrGlobalDeclaration( context, diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index c696c6900..78e03a7a6 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -2,13 +2,14 @@ import * as path from "path"; import { SourceNode } from "source-map"; import * as ts from "typescript"; import { CompilerOptions } from "../CompilerOptions"; -import { escapeString } from "../LuaPrinter"; -import { cast, formatPathToLuaPath, isNonNull, normalizeSlashes, trimExtension } from "../utils"; +import { escapeString, tstlHeader } from "../LuaPrinter"; +import { cast, formatPathToLuaPath, isNonNull, trimExtension } from "../utils"; import { couldNotFindBundleEntryPoint } from "./diagnostics"; -import { EmitFile, EmitHost, ProcessedFile } from "./utils"; +import { getEmitOutDir, getEmitPathRelativeToOutDir, getSourceDir } from "./transpiler"; +import { EmitFile, ProcessedFile } from "./utils"; -const createModulePath = (baseDir: string, pathToResolve: string) => - escapeString(formatPathToLuaPath(trimExtension(path.relative(baseDir, pathToResolve)))); +const createModulePath = (pathToResolve: string, program: ts.Program) => + escapeString(formatPathToLuaPath(trimExtension(getEmitPathRelativeToOutDir(pathToResolve, program)))); // Override `require` to read from ____modules table. const requireOverride = ` @@ -17,11 +18,11 @@ local ____moduleCache = {} local ____originalRequire = require local function require(file) if ____moduleCache[file] then - return ____moduleCache[file] + return ____moduleCache[file].value end if ____modules[file] then - ____moduleCache[file] = ____modules[file]() - return ____moduleCache[file] + ____moduleCache[file] = { value = ____modules[file]() } + return ____moduleCache[file].value else if ____originalRequire then return ____originalRequire(file) @@ -32,42 +33,37 @@ local function require(file) end `; -export function getBundleResult( - program: ts.Program, - emitHost: EmitHost, - files: ProcessedFile[] -): [ts.Diagnostic[], EmitFile] { +export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [ts.Diagnostic[], EmitFile] { const diagnostics: ts.Diagnostic[] = []; const options = program.getCompilerOptions() as CompilerOptions; const bundleFile = cast(options.luaBundle, isNonNull); const entryModule = cast(options.luaBundleEntry, isNonNull); - const rootDir = program.getCommonSourceDirectory(); - const outDir = options.outDir ?? rootDir; - const projectRootDir = options.configFilePath - ? path.dirname(options.configFilePath) - : emitHost.getCurrentDirectory(); - // Resolve project settings relative to project file. - const resolvedEntryModule = path.resolve(projectRootDir, entryModule); - const outputPath = normalizeSlashes(path.resolve(projectRootDir, bundleFile)); + const resolvedEntryModule = path.resolve(getSourceDir(program), entryModule); + const outputPath = path.resolve(getEmitOutDir(program), bundleFile); - if (!files.some(f => f.fileName === resolvedEntryModule)) { + if (program.getSourceFile(resolvedEntryModule) === undefined && program.getSourceFile(entryModule) === undefined) { diagnostics.push(couldNotFindBundleEntryPoint(entryModule)); - return [diagnostics, { outputPath, code: "" }]; } // For each file: [""] = function() end, - const moduleTableEntries = files.map(f => moduleSourceNode(f, createModulePath(outDir, f.fileName))); + const moduleTableEntries = files.map(f => moduleSourceNode(f, createModulePath(f.fileName, program))); // Create ____modules table containing all entries from moduleTableEntries const moduleTable = createModuleTableNode(moduleTableEntries); // return require("") - const entryPoint = `return require(${createModulePath(outDir, resolvedEntryModule)})\n`; + const entryPoint = `return require(${createModulePath(entryModule, program)})\n`; + + const sourceChunks = [requireOverride, moduleTable, entryPoint]; + + if (!options.noHeader) { + sourceChunks.unshift(tstlHeader); + } - const bundleNode = joinSourceChunks([requireOverride, moduleTable, entryPoint]); + const bundleNode = joinSourceChunks(sourceChunks); const { code, map } = bundleNode.toStringWithSourceMap(); return [ @@ -83,7 +79,7 @@ export function getBundleResult( function moduleSourceNode({ code, sourceMapNode }: ProcessedFile, modulePath: string): SourceNode { const tableEntryHead = `[${modulePath}] = function() `; - const tableEntryTail = "end,\n"; + const tableEntryTail = " end,\n"; return joinSourceChunks([tableEntryHead, sourceMapNode ?? code, tableEntryTail]); } diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index d0e609677..098d78740 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -1,8 +1,19 @@ import * as ts from "typescript"; import { createSerialDiagnosticFactory } from "../utils"; -const createDiagnosticFactory = (getMessage: (...args: TArgs) => string) => - createSerialDiagnosticFactory((...args: TArgs) => ({ messageText: getMessage(...args) })); +const createDiagnosticFactory = ( + getMessage: (...args: TArgs) => string, + category: ts.DiagnosticCategory = ts.DiagnosticCategory.Error +) => createSerialDiagnosticFactory((...args: TArgs) => ({ messageText: getMessage(...args), category })); + +export const couldNotResolveRequire = createDiagnosticFactory( + (requirePath: string, containingFile: string) => + `Could not resolve require path '${requirePath}' in file ${containingFile}.` +); + +export const couldNotReadDependency = createDiagnosticFactory( + (dependency: string) => `Could not read content of resolved dependency ${dependency}.` +); export const toLoadItShouldBeTranspiled = createDiagnosticFactory( (kind: string, transform: string) => @@ -37,3 +48,10 @@ export const usingLuaBundleWithInlineMightGenerateDuplicateCode = createSerialDi "Using 'luaBundle' with 'luaLibImport: \"inline\"' might generate duplicate code. " + "It is recommended to use 'luaLibImport: \"require\"'.", })); + +export const cannotBundleLibrary = createDiagnosticFactory( + () => + 'Cannot bundle probjects with"buildmode": "library". Projects including the library can still bundle (which will include external library files).' +); + +export const unsupportedJsxEmit = createDiagnosticFactory(() => 'JSX is only supported with "react" jsx option.'); diff --git a/src/transpilation/index.ts b/src/transpilation/index.ts index 628246ec9..59e83233a 100644 --- a/src/transpilation/index.ts +++ b/src/transpilation/index.ts @@ -45,7 +45,7 @@ const libCache: { [key: string]: ts.SourceFile } = {}; /** @internal */ export function createVirtualProgram(input: Record, options: CompilerOptions = {}): ts.Program { const compilerHost: ts.CompilerHost = { - fileExists: () => true, + fileExists: fileName => fileName in input || ts.sys.fileExists(fileName), getCanonicalFileName: fileName => fileName, getCurrentDirectory: () => "", getDefaultLibFileName: ts.getDefaultLibFileName, @@ -59,14 +59,22 @@ export function createVirtualProgram(input: Record, options: Com return ts.createSourceFile(fileName, input[fileName], ts.ScriptTarget.Latest, false); } + let filePath: string | undefined; + if (fileName.startsWith("lib.")) { - if (libCache[fileName]) return libCache[fileName]; const typeScriptDir = path.dirname(require.resolve("typescript")); - const filePath = path.join(typeScriptDir, fileName); - const content = fs.readFileSync(filePath, "utf8"); + filePath = path.join(typeScriptDir, fileName); + } - libCache[fileName] = ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, false); + if (fileName.includes("language-extensions")) { + const dtsName = fileName.replace(/(\.d)?(\.ts)$/, ".d.ts"); + filePath = path.resolve(dtsName); + } + if (filePath !== undefined) { + if (libCache[fileName]) return libCache[fileName]; + const content = fs.readFileSync(filePath, "utf8"); + libCache[fileName] = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, false); return libCache[fileName]; } }, diff --git a/src/transpilation/output-collector.ts b/src/transpilation/output-collector.ts index d18137c5a..866c1f79a 100644 --- a/src/transpilation/output-collector.ts +++ b/src/transpilation/output-collector.ts @@ -2,6 +2,7 @@ import * as ts from "typescript"; import { intersection, union } from "../utils"; export interface TranspiledFile { + outPath: string; sourceFiles: ts.SourceFile[]; lua?: string; luaSourceMap?: string; @@ -18,7 +19,7 @@ export function createEmitOutputCollector() { const writeFile: ts.WriteFileCallback = (fileName, data, _bom, _onError, sourceFiles = []) => { let file = files.find(f => intersection(f.sourceFiles, sourceFiles).length > 0); if (!file) { - file = { sourceFiles: [...sourceFiles] }; + file = { outPath: fileName, sourceFiles: [...sourceFiles] }; files.push(file); } else { file.sourceFiles = union(file.sourceFiles, sourceFiles); diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts new file mode 100644 index 000000000..38c130e84 --- /dev/null +++ b/src/transpilation/resolve.ts @@ -0,0 +1,354 @@ +import * as path from "path"; +import * as resolve from "enhanced-resolve"; +import * as ts from "typescript"; +import * as fs from "fs"; +import { EmitHost, ProcessedFile } from "./utils"; +import { SourceNode } from "source-map"; +import { getEmitPathRelativeToOutDir, getProjectRoot, getSourceDir } from "./transpiler"; +import { formatPathToLuaPath, normalizeSlashes, trimExtension } from "../utils"; +import { couldNotReadDependency, couldNotResolveRequire } from "./diagnostics"; +import { BuildMode, CompilerOptions } from "../CompilerOptions"; + +const resolver = resolve.ResolverFactory.createResolver({ + extensions: [".lua"], + enforceExtension: true, // Resolved file must be a lua file + fileSystem: { ...new resolve.CachedInputFileSystem(fs) }, + useSyncFileSystemCalls: true, +}); + +interface ResolutionResult { + resolvedFiles: ProcessedFile[]; + diagnostics: ts.Diagnostic[]; +} + +class ResolutionContext { + private resultsCache = new Map(); + + constructor( + public readonly program: ts.Program, + public readonly options: CompilerOptions, + private readonly emitHost: EmitHost + ) {} + + public resolve(file: ProcessedFile, required: string): ResolutionResult { + const resolvedDependency = resolveDependency(file, required, this.program, this.emitHost); + if (resolvedDependency) { + if (this.options.tstlVerbose) { + console.log(`Resolved ${required} to ${normalizeSlashes(resolvedDependency)}`); + } + + // Figure out resolved require path and dependency output path + const resolvedRequire = getEmitPathRelativeToOutDir(resolvedDependency, this.program); + + if (shouldRewriteRequires(resolvedDependency, this.program)) { + replaceRequireInCode(file, required, resolvedRequire); + replaceRequireInSourceMap(file, required, resolvedRequire); + } + + // Check cache to prevent resolving nested dependencies double to break dependency loops + if (this.resultsCache.has(resolvedDependency)) { + if (this.options.tstlVerbose) { + console.log(`Resolution cache hit for ${normalizeSlashes(resolvedDependency)}`); + } + return this.resultsCache.get(resolvedDependency)!; + } + + // If dependency is not part of project, add dependency to output and resolve its dependencies recursively + if (shouldIncludeDependency(resolvedDependency, this.program)) { + // If dependency resolved successfully, read its content + const dependencyContent = this.emitHost.readFile(resolvedDependency); + if (dependencyContent === undefined) { + return { resolvedFiles: [], diagnostics: [couldNotReadDependency(resolvedDependency)] }; + } + + const dependency = { + fileName: resolvedDependency, + code: dependencyContent, + }; + const nestedDependencies = resolveFileDependencies(dependency, this); + + // Cache result and return + const result = { + resolvedFiles: [dependency, ...nestedDependencies.resolvedFiles], + diagnostics: [...nestedDependencies.diagnostics], + }; + this.resultsCache.set(resolvedDependency, result); + return result; + } else { + const result = { + resolvedFiles: [], + diagnostics: [], + }; + this.resultsCache.set(resolvedDependency, result); + return result; + } + } else { + const fallbackRequire = fallbackResolve(required, getSourceDir(this.program), path.dirname(file.fileName)); + replaceRequireInCode(file, required, fallbackRequire); + replaceRequireInSourceMap(file, required, fallbackRequire); + + return { + resolvedFiles: [], + diagnostics: [ + couldNotResolveRequire(required, path.relative(getProjectRoot(this.program), file.fileName)), + ], + }; + } + } +} + +export function resolveDependencies(program: ts.Program, files: ProcessedFile[], emitHost: EmitHost): ResolutionResult { + const outFiles: ProcessedFile[] = [...files]; + const diagnostics: ts.Diagnostic[] = []; + const options = program.getCompilerOptions() as CompilerOptions; + + const resolutionContext = new ResolutionContext(program, options, emitHost); + + // Resolve dependencies for all processed files + for (const file of files) { + if (options.tstlVerbose) { + console.log(`Resolving dependencies for ${normalizeSlashes(file.fileName)}`); + } + + const resolutionResult = resolveFileDependencies(file, resolutionContext); + outFiles.push(...resolutionResult.resolvedFiles); + diagnostics.push(...resolutionResult.diagnostics); + } + + return { resolvedFiles: deduplicateResolvedFiles(outFiles), diagnostics }; +} + +function deduplicateResolvedFiles(files: ProcessedFile[]): ProcessedFile[] { + return [...new Map(files.map(f => [f.fileName, f])).values()]; +} + +function resolveFileDependencies(file: ProcessedFile, context: ResolutionContext): ResolutionResult { + const dependencies: ProcessedFile[] = []; + const diagnostics: ts.Diagnostic[] = []; + + for (const required of findRequiredPaths(file.code)) { + // Do no resolve lualib + if (required === "lualib_bundle") { + dependencies.push({ fileName: "lualib_bundle", code: "" }); + continue; + } + + // Do not resolve noResolution paths + if (required.startsWith("@NoResolution:")) { + // Remove @NoResolution prefix if not building in library mode + if (!isBuildModeLibrary(context.program)) { + const path = required.replace("@NoResolution:", ""); + replaceRequireInCode(file, required, path); + replaceRequireInSourceMap(file, required, path); + } + + // Skip + continue; + } + + // Try to resolve the import starting from the directory `file` is in + const resolvedDependency = context.resolve(file, required); + dependencies.push(...resolvedDependency.resolvedFiles); + diagnostics.push(...resolvedDependency.diagnostics); + } + return { resolvedFiles: dependencies, diagnostics }; +} + +function resolveDependency( + requiringFile: ProcessedFile, + dependency: string, + program: ts.Program, + emitHost: EmitHost +): string | undefined { + const options = program.getCompilerOptions() as CompilerOptions; + + const fileDirectory = path.dirname(requiringFile.fileName); + if (options.tstlVerbose) { + console.log(`Resolving "${dependency}" from ${normalizeSlashes(fileDirectory)}`); + } + + // Check if file is a file in the project + const resolvedPath = path.join(options.baseUrl ?? fileDirectory, dependency); + + const possibleProjectFiles = [ + resolvedPath, // JSON files need their extension as part of the import path, caught by this branch, + resolvedPath + ".ts", // Regular ts file + path.join(resolvedPath, "index.ts"), // Index ts file, + resolvedPath + ".tsx", // tsx file + path.join(resolvedPath, "index.tsx"), // tsx index + ]; + + for (const possibleFile of possibleProjectFiles) { + if (isProjectFile(possibleFile, program)) { + return possibleFile; + } + } + + // Check if this is a lua file in the project sources + const possibleLuaProjectFiles = [ + resolvedPath + ".lua", // lua file in sources + path.join(resolvedPath, "index.lua"), // lua index file in sources + path.join(resolvedPath, "init.lua"), // lua looks for /init.lua if it cannot find .lua + ]; + + for (const possibleFile of possibleLuaProjectFiles) { + if (emitHost.fileExists(possibleFile)) { + return possibleFile; + } + } + + // Check if this is a sibling of a required lua file + if (requiringFile.fileName.endsWith(".lua")) { + const luaFilePath = resolveLuaPath(fileDirectory, dependency, emitHost); + if (luaFilePath) { + return luaFilePath; + } + } + + // Not a TS file in our project sources, use resolver to check if we can find dependency + try { + const resolveResult = resolver.resolveSync({}, fileDirectory, dependency); + if (resolveResult) { + return resolveResult; + } + } catch (e) { + // resolveSync errors if it fails to resolve + } + + return undefined; +} + +function resolveLuaPath(fromPath: string, dependency: string, emitHost: EmitHost) { + const splitDependency = dependency.split("."); + if (splitDependency.length === 1) { + // If dependency has just one part (the file), look for a lua file with that name + const fileDirectory = walkUpFileTreeUntil(fromPath, dir => + emitHost.fileExists(path.join(dir, dependency) + ".lua") + ); + if (fileDirectory) { + return path.join(fileDirectory, dependency) + ".lua"; + } + } else { + // If dependency has multiple parts, look for the first directory of the require path, which must be in the lua root + const luaRoot = walkUpFileTreeUntil(fromPath, dir => + emitHost.directoryExists(path.join(dir, splitDependency[0])) + ); + if (luaRoot) { + return path.join(luaRoot, dependency.replace(/\./g, path.sep)) + ".lua"; + } + } +} + +function walkUpFileTreeUntil(fromDirectory: string, predicate: (dir: string) => boolean) { + const currentDir = path.normalize(fromDirectory).split(path.sep); + while (currentDir.length > 0) { + const dir = currentDir.join(path.sep); + if (predicate(dir)) { + return dir; + } + currentDir.pop(); + } + return undefined; +} + +function shouldRewriteRequires(resolvedDependency: string, program: ts.Program) { + return !isNodeModulesFile(resolvedDependency) || !isBuildModeLibrary(program); +} + +function shouldIncludeDependency(resolvedDependency: string, program: ts.Program) { + // Never include lua files (again) that are transpiled from project sources + if (!hasSourceFileInProject(resolvedDependency, program)) { + // Always include lua files not in node_modules (internal lua sources) + if (!isNodeModulesFile(resolvedDependency)) { + return true; + } else { + // Only include node_modules files if not in library mode + return !isBuildModeLibrary(program); + } + } + return false; +} + +function isBuildModeLibrary(program: ts.Program) { + return program.getCompilerOptions().buildMode === BuildMode.Library; +} + +function findRequiredPaths(code: string): string[] { + // Find all require("") paths in a lua code string + const paths: string[] = []; + const pattern = /(^|\s|;|=)require\("(.+)"\)/g; + // eslint-disable-next-line @typescript-eslint/ban-types + let match: RegExpExecArray | null; + while ((match = pattern.exec(code))) { + paths.push(match[2]); + } + + return paths; +} + +function replaceRequireInCode(file: ProcessedFile, originalRequire: string, newRequire: string): void { + const requirePath = formatPathToLuaPath(newRequire.replace(".lua", "")); + + // Escape special characters to prevent the regex from breaking... + const escapedRequire = originalRequire.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"); + + file.code = file.code.replace( + new RegExp(`(^|\\s|;|=)require\\("${escapedRequire}"\\)`), + `$1require("${requirePath}")` + ); +} + +function replaceRequireInSourceMap(file: ProcessedFile, originalRequire: string, newRequire: string): void { + const requirePath = formatPathToLuaPath(newRequire.replace(".lua", "")); + if (file.sourceMapNode) { + replaceInSourceMap(file.sourceMapNode, file.sourceMapNode, `"${originalRequire}"`, `"${requirePath}"`); + } +} + +function replaceInSourceMap(node: SourceNode, parent: SourceNode, require: string, resolvedRequire: string): boolean { + if ((!node.children || node.children.length === 0) && node.toString() === require) { + parent.children = [new SourceNode(node.line, node.column, node.source, [resolvedRequire])]; + return true; // Stop after finding the first occurrence + } + + if (node.children) { + for (const c of node.children) { + if (replaceInSourceMap(c, node, require, resolvedRequire)) { + return true; // Occurrence found in one of the children + } + } + } + + return false; // Did not find the require +} + +function isNodeModulesFile(filePath: string): boolean { + return path + .normalize(filePath) + .split(path.sep) + .some(p => p === "node_modules"); +} + +function isProjectFile(file: string, program: ts.Program): boolean { + return program.getSourceFile(file) !== undefined; +} + +function hasSourceFileInProject(filePath: string, program: ts.Program) { + const pathWithoutExtension = trimExtension(filePath); + return ( + isProjectFile(pathWithoutExtension + ".ts", program) || + isProjectFile(pathWithoutExtension + ".tsx", program) || + isProjectFile(pathWithoutExtension + ".json", program) + ); +} + +// Transform an import path to a lua require that is probably not correct, but can be used as fallback when regular resolution fails +function fallbackResolve(required: string, sourceRootDir: string, fileDir: string): string { + return formatPathToLuaPath( + path + .normalize(path.join(path.relative(sourceRootDir, fileDir), required)) + .split(path.sep) + .filter(s => s !== "." && s !== "..") + .join(path.sep) + ); +} diff --git a/src/transpilation/transformers.ts b/src/transpilation/transformers.ts index 470e7ad13..7b5aacddd 100644 --- a/src/transpilation/transformers.ts +++ b/src/transpilation/transformers.ts @@ -36,6 +36,7 @@ export function getTransformers( ...(transformersFromOptions.after ?? []), ...(customTransformers.after ?? []), + stripParenthesisExpressionsTransformer, luaTransformer, ], }; @@ -43,16 +44,40 @@ export function getTransformers( export const noImplicitSelfTransformer: ts.TransformerFactory = () => node => { const transformSourceFile: ts.Transformer = node => { - const empty = ts.createNotEmittedStatement(undefined!); + const empty = ts.factory.createNotEmittedStatement(undefined!); ts.addSyntheticLeadingComment(empty, ts.SyntaxKind.MultiLineCommentTrivia, "* @noSelfInFile ", true); - return ts.updateSourceFileNode(node, [empty, ...node.statements], node.isDeclarationFile); + return ts.factory.updateSourceFile(node, [empty, ...node.statements], node.isDeclarationFile); }; return ts.isBundle(node) - ? ts.updateBundle(node, node.sourceFiles.map(transformSourceFile)) + ? ts.factory.updateBundle(node, node.sourceFiles.map(transformSourceFile)) : transformSourceFile(node); }; +export const stripParenthesisExpressionsTransformer: ts.TransformerFactory = context => sourceFile => { + // Remove parenthesis expressions before transforming to Lua, so transpiler is not hindered by extra ParenthesizedExpression nodes + function unwrapParentheses(node: ts.Expression) { + while (ts.isParenthesizedExpression(node)) { + node = node.expression; + } + return node; + } + function visit(node: ts.Node): ts.Node { + // For now only call expressions strip their expressions of parentheses, there could be more cases where this is required + if (ts.isCallExpression(node)) { + return ts.factory.updateCallExpression( + node, + unwrapParentheses(node.expression), + node.typeArguments, + node.arguments + ); + } + + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(sourceFile, visit); +}; + function loadTransformersFromOptions(program: ts.Program, diagnostics: ts.Diagnostic[]): ts.CustomTransformers { const customTransformers: Required = { before: [], diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index 01d9278c5..fc645147f 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -27,6 +27,10 @@ export function getProgramTranspileResult( ): TranspileResult { const options = program.getCompilerOptions() as CompilerOptions; + if (options.tstlVerbose) { + console.log("Parsing project settings"); + } + const diagnostics = validateOptions(options); let transpiledFiles: ProcessedFile[] = []; @@ -57,21 +61,33 @@ export function getProgramTranspileResult( } const plugins = getPlugins(program, diagnostics, customPlugins); + + if (options.tstlVerbose) { + console.log(`Successfully loaded ${plugins.length} plugins`); + } + const visitorMap = createVisitorMap(plugins.map(p => p.visitors).filter(isNonNull)); const printer = createPrinter(plugins.map(p => p.printer).filter(isNonNull)); const processSourceFile = (sourceFile: ts.SourceFile) => { - const { luaAst, luaLibFeatures, diagnostics: transformDiagnostics } = transformSourceFile( - program, - sourceFile, - visitorMap - ); + if (options.tstlVerbose) { + console.log(`Transforming ${sourceFile.fileName}`); + } + + const { file, diagnostics: transformDiagnostics } = transformSourceFile(program, sourceFile, visitorMap); diagnostics.push(...transformDiagnostics); if (!options.noEmit && !options.emitDeclarationOnly) { - const printResult = printer(program, emitHost, sourceFile.fileName, luaAst, luaLibFeatures); - const sourceRootDir = program.getCommonSourceDirectory(); - const fileName = path.resolve(sourceRootDir, sourceFile.fileName); - transpiledFiles.push({ sourceFiles: [sourceFile], fileName, luaAst, ...printResult }); + if (options.tstlVerbose) { + console.log(`Printing ${sourceFile.fileName}`); + } + + const printResult = printer(program, emitHost, sourceFile.fileName, file); + transpiledFiles.push({ + sourceFiles: [sourceFile], + fileName: path.normalize(sourceFile.fileName), + luaAst: file, + ...printResult, + }); } }; @@ -87,7 +103,7 @@ export function getProgramTranspileResult( options.noEmit = false; const writeFile: ts.WriteFileCallback = (fileName, ...rest) => { - if (!fileName.endsWith(".js") && !fileName.endsWith(".js.map")) { + if (!fileName.endsWith(".js") && !fileName.endsWith(".js.map") && !fileName.endsWith(".json")) { writeFileResult(fileName, ...rest); } }; diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index 205b6b2db..e30410f73 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -1,9 +1,10 @@ import * as path from "path"; import * as ts from "typescript"; -import { isBundleEnabled } from "../CompilerOptions"; +import { CompilerOptions, isBundleEnabled } from "../CompilerOptions"; import { getLuaLibBundle } from "../LuaLib"; import { normalizeSlashes, trimExtension } from "../utils"; import { getBundleResult } from "./bundle"; +import { resolveDependencies } from "./resolve"; import { getProgramTranspileResult, TranspileOptions } from "./transpile"; import { EmitFile, EmitHost, ProcessedFile } from "./utils"; @@ -28,22 +29,36 @@ export class Transpiler { public emit(emitOptions: EmitOptions): EmitResult { const { program, writeFile = this.emitHost.writeFile } = emitOptions; + const verbose = (program.getCompilerOptions() as CompilerOptions).tstlVerbose; const { diagnostics, transpiledFiles: freshFiles } = getProgramTranspileResult( this.emitHost, writeFile, emitOptions ); + const { emitPlan } = this.getEmitPlan(program, diagnostics, freshFiles); + if (verbose) { + console.log("Emitting output"); + } + const options = program.getCompilerOptions(); const emitBOM = options.emitBOM ?? false; for (const { outputPath, code, sourceMap, sourceFiles } of emitPlan) { + if (verbose) { + console.log(`Emitting ${normalizeSlashes(outputPath)}`); + } + writeFile(outputPath, code, emitBOM, undefined, sourceFiles); if (options.sourceMap && sourceMap !== undefined) { writeFile(outputPath + ".map", sourceMap, emitBOM, undefined, sourceFiles); } } + if (verbose) { + console.log("Emit finished!"); + } + return { diagnostics, emitSkipped: emitPlan.length === 0 }; } @@ -52,29 +67,93 @@ export class Transpiler { diagnostics: ts.Diagnostic[], files: ProcessedFile[] ): { emitPlan: EmitFile[] } { - const options = program.getCompilerOptions(); - const rootDir = program.getCommonSourceDirectory(); - const outDir = options.outDir ?? rootDir; + const options = program.getCompilerOptions() as CompilerOptions; - const lualibRequired = files.some(f => f.code.includes('require("lualib_bundle")')); + if (options.tstlVerbose) { + console.log("Constructing emit plan"); + } + + // Resolve imported modules and modify output Lua requires + const resolutionResult = resolveDependencies(program, files, this.emitHost); + diagnostics.push(...resolutionResult.diagnostics); + + const lualibRequired = resolutionResult.resolvedFiles.some(f => f.fileName === "lualib_bundle"); if (lualibRequired) { - const fileName = normalizeSlashes(path.resolve(rootDir, "lualib_bundle.lua")); - files.unshift({ fileName, code: getLuaLibBundle(this.emitHost) }); + // Remove lualib placeholders from resolution result + resolutionResult.resolvedFiles = resolutionResult.resolvedFiles.filter(f => f.fileName !== "lualib_bundle"); + + if (options.tstlVerbose) { + console.log("Including lualib bundle"); + } + + // Add lualib bundle to source dir 'virtually', will be moved to correct output dir in emitPlan + const fileName = normalizeSlashes(path.resolve(getSourceDir(program), "lualib_bundle.lua")); + resolutionResult.resolvedFiles.unshift({ fileName, code: getLuaLibBundle(this.emitHost) }); } let emitPlan: EmitFile[]; if (isBundleEnabled(options)) { - const [bundleDiagnostics, bundleFile] = getBundleResult(program, this.emitHost, files); + const [bundleDiagnostics, bundleFile] = getBundleResult(program, resolutionResult.resolvedFiles); diagnostics.push(...bundleDiagnostics); emitPlan = [bundleFile]; } else { - emitPlan = files.map(file => { - const pathInOutDir = path.resolve(outDir, path.relative(rootDir, file.fileName)); - const outputPath = normalizeSlashes(trimExtension(pathInOutDir) + ".lua"); - return { ...file, outputPath }; - }); + emitPlan = resolutionResult.resolvedFiles.map(file => ({ + ...file, + outputPath: getEmitPath(file.fileName, program), + })); } return { emitPlan }; } } + +export function getEmitPath(file: string, program: ts.Program): string { + const relativeOutputPath = getEmitPathRelativeToOutDir(file, program); + const outDir = getEmitOutDir(program); + + return path.join(outDir, relativeOutputPath); +} + +export function getEmitPathRelativeToOutDir(fileName: string, program: ts.Program): string { + const sourceDir = getSourceDir(program); + // Default output path is relative path in source dir + let emitPathSplits = path.relative(sourceDir, fileName).split(path.sep); + + // If source is in a parent directory of source dir, move it into the source dir + emitPathSplits = emitPathSplits.filter(s => s !== ".."); + + // To avoid overwriting lua sources in node_modules, emit into lua_modules + if (emitPathSplits[0] === "node_modules") { + emitPathSplits[0] = "lua_modules"; + } + + // Make extension lua + emitPathSplits[emitPathSplits.length - 1] = trimExtension(emitPathSplits[emitPathSplits.length - 1]) + ".lua"; + + return path.join(...emitPathSplits); +} + +export function getSourceDir(program: ts.Program): string { + const rootDir = program.getCompilerOptions().rootDir; + if (rootDir && rootDir.length > 0) { + return path.isAbsolute(rootDir) ? rootDir : path.resolve(getProjectRoot(program), rootDir); + } + return program.getCommonSourceDirectory(); +} + +export function getEmitOutDir(program: ts.Program): string { + const outDir = program.getCompilerOptions().outDir; + if (outDir && outDir.length > 0) { + return path.isAbsolute(outDir) ? outDir : path.resolve(getProjectRoot(program), outDir); + } + + // If no outDir is provided, emit in project root + return getProjectRoot(program); +} + +export function getProjectRoot(program: ts.Program): string { + // Try to get the directory the tsconfig is in + const tsConfigPath = program.getCompilerOptions().configFilePath; + // If no tsconfig is known, use common source directory + return tsConfigPath ? path.dirname(tsConfigPath) : program.getCommonSourceDirectory(); +} diff --git a/src/transpilation/utils.ts b/src/transpilation/utils.ts index 98c3f5cc6..4b0a9c24f 100644 --- a/src/transpilation/utils.ts +++ b/src/transpilation/utils.ts @@ -8,6 +8,8 @@ import * as lua from "../LuaAST"; import * as diagnosticFactories from "./diagnostics"; export interface EmitHost { + directoryExists(path: string): boolean; + fileExists(path: string): boolean; getCurrentDirectory(): string; readFile(path: string): string | undefined; writeFile: ts.WriteFileCallback; @@ -21,7 +23,7 @@ interface BaseFile { export interface ProcessedFile extends BaseFile { fileName: string; - luaAst?: lua.Block; + luaAst?: lua.File; /** @internal */ sourceMapNode?: SourceNode; } diff --git a/src/tstl.ts b/src/tstl.ts index fb011be3c..d7b6d1df1 100644 --- a/src/tstl.ts +++ b/src/tstl.ts @@ -111,7 +111,7 @@ function performCompilation( diagnostics.forEach(reportDiagnostic); const exitCode = - diagnostics.length === 0 + diagnostics.filter(d => d.category === ts.DiagnosticCategory.Error).length === 0 ? ts.ExitStatus.Success : emitSkipped ? ts.ExitStatus.DiagnosticsPresent_OutputsSkipped diff --git a/src/typescript-internal.d.ts b/src/typescript-internal.d.ts index 7444d89d7..8fd8fd1ec 100644 --- a/src/typescript-internal.d.ts +++ b/src/typescript-internal.d.ts @@ -1,3 +1,5 @@ +import { DiagnosticsProducingTypeChecker } from "./transformation/context"; + export {}; declare module "typescript" { @@ -14,6 +16,7 @@ declare module "typescript" { interface Program { getCommonSourceDirectory(): string; + getDiagnosticsProducingTypeChecker(): DiagnosticsProducingTypeChecker; } interface CompilerOptions { @@ -23,5 +26,6 @@ declare module "typescript" { interface TypeChecker { getElementTypeOfArrayType(type: Type): Type | undefined; + getContextualTypeForObjectLiteralElement(element: ObjectLiteralElementLike): Type | undefined; } } diff --git a/src/utils.ts b/src/utils.ts index 1244068a4..72e6ee168 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -50,6 +50,7 @@ export function formatPathToLuaPath(filePath: string): string { type NoInfer = [T][T extends any ? 0 : never]; export function getOrUpdate( + // eslint-disable-next-line @typescript-eslint/ban-types map: Map | (K extends object ? WeakMap : never), key: K, getDefaultValue: () => NoInfer diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index 6b6349f9b..f157c9a21 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -104,6 +104,11 @@ describe("command line", () => { ["noHeader", "true", { noHeader: true }], ["sourceMapTraceback", "false", { sourceMapTraceback: false }], ["sourceMapTraceback", "true", { sourceMapTraceback: true }], + ["tstlVerbose", "true", { tstlVerbose: true }], + ["tstlVerbose", "false", { tstlVerbose: false }], + + ["buildMode", "default", { buildMode: tstl.BuildMode.Default }], + ["buildMode", "library", { buildMode: tstl.BuildMode.Library }], ["luaLibImport", "none", { luaLibImport: tstl.LuaLibImportKind.None }], ["luaLibImport", "always", { luaLibImport: tstl.LuaLibImportKind.Always }], @@ -158,6 +163,7 @@ describe("tsconfig", () => { }); test("should parse options case-sensitively", () => { + // eslint-disable-next-line @typescript-eslint/naming-convention const result = parseConfigFileContent({ tstl: { NoHeader: true } }); expect(result.errors).toHaveDiagnostics(); @@ -212,6 +218,9 @@ describe("tsconfig", () => { ["sourceMapTraceback", false, { sourceMapTraceback: false }], ["sourceMapTraceback", true, { sourceMapTraceback: true }], + ["buildMode", "default", { buildMode: tstl.BuildMode.Default }], + ["buildMode", "library", { buildMode: tstl.BuildMode.Library }], + ["luaLibImport", "none", { luaLibImport: tstl.LuaLibImportKind.None }], ["luaLibImport", "always", { luaLibImport: tstl.LuaLibImportKind.Always }], ["luaLibImport", "inline", { luaLibImport: tstl.LuaLibImportKind.Inline }], @@ -221,6 +230,7 @@ describe("tsconfig", () => { ["luaTarget", "5.1", { luaTarget: tstl.LuaTarget.Lua51 }], ["luaTarget", "5.2", { luaTarget: tstl.LuaTarget.Lua52 }], ["luaTarget", "5.3", { luaTarget: tstl.LuaTarget.Lua53 }], + ["luaTarget", "5.4", { luaTarget: tstl.LuaTarget.Lua54 }], ["luaTarget", "jit", { luaTarget: tstl.LuaTarget.LuaJIT }], ["luaBundle", "foo", { luaBundle: "foo" }], diff --git a/test/json.lua b/test/json.lua index e41c3798a..cd345c9b4 100644 --- a/test/json.lua +++ b/test/json.lua @@ -142,8 +142,4 @@ encode = function(val, stack) error("unexpected type '" .. t .. "'") end - --- TODO: Since it supports NaN and Infinity it is considered a superset of JSON, so it probably should be renamed -function JSONStringify(val) - return ( encode(val) ) -end +return {stringify = function(val) return ( encode(val) ) end} \ No newline at end of file diff --git a/test/legacy-utils.ts b/test/legacy-utils.ts deleted file mode 100644 index de781d954..000000000 --- a/test/legacy-utils.ts +++ /dev/null @@ -1,165 +0,0 @@ -import { lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; -import * as fs from "fs"; -import * as path from "path"; -import * as ts from "typescript"; -import * as tstl from "../src"; -import { formatPathToLuaPath } from "../src/utils"; - -export function transpileString( - str: string | { [filename: string]: string }, - options: tstl.CompilerOptions = {}, - ignoreDiagnostics = true -): string { - const { diagnostics, file } = transpileStringResult(str, options); - expect(file.lua).toBeDefined(); - - const errors = diagnostics.filter(d => !ignoreDiagnostics || d.source === "typescript-to-lua"); - expect(errors).not.toHaveDiagnostics(); - - return file.lua!.trim(); -} - -function transpileStringsAsProject(input: Record, options: tstl.CompilerOptions = {}) { - return tstl.transpileVirtualProject(input, { - luaTarget: tstl.LuaTarget.Lua53, - noHeader: true, - skipLibCheck: true, - target: ts.ScriptTarget.ESNext, - lib: ["lib.esnext.d.ts"], - experimentalDecorators: true, - ...options, - }); -} - -function transpileStringResult( - input: string | Record, - options: tstl.CompilerOptions = {} -): Required { - const { diagnostics, transpiledFiles } = transpileStringsAsProject( - typeof input === "string" ? { "main.ts": input } : input, - options - ); - - const file = transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => /\bmain\.[a-z]+$/.test(f.fileName))); - if (file === undefined) { - throw new Error('Program should have a file named "main"'); - } - - return { diagnostics, file }; -} - -const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); -const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8") + "\n"; -export function executeLua(luaStr: string, withLib = true): any { - luaStr = luaStr.replace(/require\("lualib_bundle"\)/g, lualibContent); - if (withLib) { - luaStr = minimalTestLib + luaStr; - } - - const L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - const status = lauxlib.luaL_dostring(L, to_luastring(luaStr)); - - if (status === lua.LUA_OK) { - // Read the return value from stack depending on its type. - if (lua.lua_isboolean(L, -1)) { - return lua.lua_toboolean(L, -1); - } else if (lua.lua_isnil(L, -1)) { - return undefined; - } else if (lua.lua_isnumber(L, -1)) { - return lua.lua_tonumber(L, -1); - } else if (lua.lua_isstring(L, -1)) { - return lua.lua_tojsstring(L, -1); - } else { - throw new Error("Unsupported lua return type: " + to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1)))); - } - } else { - // If the lua VM did not terminate with status code LUA_OK an error occurred. - // Throw a JS error with the message, retrieved by reading a string from the stack. - - // Filter control characters out of string which are in there because ???? - throw new Error("LUA ERROR: " + to_jsstring(lua.lua_tostring(L, -1).filter(c => c >= 20))); - } -} - -export function transpileAndExecute( - tsStr: string, - compilerOptions?: tstl.CompilerOptions, - luaHeader?: string, - tsHeader?: string -): any { - const wrappedTsString = `${tsHeader ?? ""} - declare function JSONStringify(this: void, p: any): string; - function __runTest(this: void): any {${tsStr}}`; - - const lua = `${luaHeader ?? ""} - ${transpileString(wrappedTsString, compilerOptions, false)} - return __runTest();`; - - return executeLua(lua); -} - -function getExportPath(fileName: string, options: ts.CompilerOptions): string { - const rootDir = options.rootDir ? path.resolve(options.rootDir) : path.resolve("."); - - const absolutePath = path.resolve(fileName.replace(/.ts$/, "")); - const absoluteRootDirPath = path.format(path.parse(rootDir)); - return formatPathToLuaPath(absolutePath.replace(absoluteRootDirPath, "").slice(1)); -} - -export function transpileAndExecuteProjectReturningMainExport( - typeScriptFiles: Record, - exportName: string, - options: tstl.CompilerOptions = {} -): [any, string] { - const mainFile = Object.keys(typeScriptFiles).find(typeScriptFileName => typeScriptFileName === "main.ts"); - if (!mainFile) { - throw new Error("An entry point file needs to be specified. This should be called main.ts"); - } - - const joinedTranspiledFiles = Object.keys(typeScriptFiles) - .filter(typeScriptFileName => typeScriptFileName !== "main.ts") - .map(typeScriptFileName => { - const modulePath = getExportPath(typeScriptFileName, options); - const tsCode = typeScriptFiles[typeScriptFileName]; - const luaCode = transpileString(tsCode, options); - return `package.preload["${modulePath}"] = function() - ${luaCode} - end`; - }) - .join("\n"); - - const luaCode = `return (function() - ${joinedTranspiledFiles} - ${transpileString(typeScriptFiles[mainFile])} - end)().${exportName}`; - - try { - return [executeLua(luaCode), luaCode]; - } catch (err) { - throw new Error(` - Encountered an error when executing the following Lua code: - - ${luaCode} - - ${err} - `); - } -} - -export function transpileExecuteAndReturnExport( - tsStr: string, - returnExport: string, - compilerOptions?: tstl.CompilerOptions, - luaHeader?: string -): any { - const wrappedTsString = `declare function JSONStringify(this: void, p: any): string; - ${tsStr}`; - - const lua = `return (function() - ${luaHeader ?? ""} - ${transpileString(wrappedTsString, compilerOptions, false)} - end)().${returnExport}`; - - return executeLua(lua); -} diff --git a/test/setup.ts b/test/setup.ts index 6d92e3332..de78ad24b 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -5,7 +5,7 @@ import * as tstl from "../src"; declare global { // eslint-disable-next-line @typescript-eslint/no-namespace namespace jest { - // eslint-disable-next-line @typescript-eslint/generic-type-naming + // eslint-disable-next-line @typescript-eslint/naming-convention interface Matchers { toHaveDiagnostics(expected?: number[]): R; } diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 942f17aa2..7fd968b00 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -24,38 +24,6 @@ escapedCharsInTemplateString = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \ nonEmptyTemplateString = (\\"Level 0: \\\\n\\\\t \\" .. ((\\"Level 1: \\\\n\\\\t\\\\t \\" .. ((\\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. \\"Last level \\\\n --\\") .. \\" \\\\n --\\")) .. \\" \\\\n --\\")) .. \\" \\\\n --\\"" `; -exports[`Transformation (classExtension1) 1`] = ` -"function MyClass.myFunction(self) -end" -`; - -exports[`Transformation (classExtension2) 1`] = ` -"function TestClass.myFunction(self) -end" -`; - -exports[`Transformation (classExtension3) 1`] = ` -"function RenamedTestClass.myFunction(self) -end -function RenamedMyClass.myFunction(self) -end" -`; - -exports[`Transformation (classExtension4) 1`] = ` -"MyClass.test = \\"test\\" -MyClass.testP = \\"testP\\" -function MyClass.myFunction(self) -end" -`; - -exports[`Transformation (classPureAbstract) 1`] = ` -"require(\\"lualib_bundle\\"); -ClassB = __TS__Class() -ClassB.name = \\"ClassB\\" -function ClassB.prototype.____constructor(self) -end" -`; - exports[`Transformation (exportStatement) 1`] = ` "local ____exports = {} local xyz = 4 @@ -64,7 +32,9 @@ ____exports.uwv = xyz do local ____export = require(\\"xyz\\") for ____exportKey, ____exportValue in pairs(____export) do - ____exports[____exportKey] = ____exportValue + if ____exportKey ~= \\"default\\" then + ____exports[____exportKey] = ____exportValue + end end end do @@ -260,11 +230,6 @@ return ____exports" exports[`Transformation (modulesVariableNoExport) 1`] = `"foo = \\"bar\\""`; -exports[`Transformation (namespacePhantom) 1`] = ` -"function nsMember(self) -end" -`; - exports[`Transformation (returnDefault) 1`] = ` "function myFunc(self) return diff --git a/test/translation/transformation.spec.ts b/test/translation/transformation.spec.ts index 7a5088fcb..42a4b4355 100644 --- a/test/translation/transformation.spec.ts +++ b/test/translation/transformation.spec.ts @@ -1,6 +1,8 @@ import * as fs from "fs"; import * as path from "path"; import * as tstl from "../../src"; +import { annotationDeprecated } from "../../src/transformation/utils/diagnostics"; +import { couldNotResolveRequire } from "../../src/transpilation/diagnostics"; import * as util from "../util"; const fixturesPath = path.join(__dirname, "./transformation"); @@ -13,6 +15,7 @@ const fixtures = fs test.each(fixtures)("Transformation (%s)", (_name, content) => { util.testModule(content) .setOptions({ luaLibImport: tstl.LuaLibImportKind.Require }) + .ignoreDiagnostics([annotationDeprecated.code, couldNotResolveRequire.code]) .disableSemanticCheck() .expectLuaToMatchSnapshot(); }); diff --git a/test/translation/transformation/classExtension1.ts b/test/translation/transformation/classExtension1.ts deleted file mode 100644 index 5df5bdeac..000000000 --- a/test/translation/transformation/classExtension1.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** @extension */ -class MyClass { - public myFunction() {} -} diff --git a/test/translation/transformation/classExtension2.ts b/test/translation/transformation/classExtension2.ts deleted file mode 100644 index 11145e9d5..000000000 --- a/test/translation/transformation/classExtension2.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** @extension */ -class TestClass {} - -/** @extension */ -class MyClass extends TestClass { - public myFunction() {} -} diff --git a/test/translation/transformation/classExtension3.ts b/test/translation/transformation/classExtension3.ts deleted file mode 100644 index 3fa37f05e..000000000 --- a/test/translation/transformation/classExtension3.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** @extension RenamedTestClass */ -class TestClass { - public myFunction() {} -} - -/** @extension RenamedMyClass */ -class MyClass extends TestClass { - public myFunction() {} -} diff --git a/test/translation/transformation/classExtension4.ts b/test/translation/transformation/classExtension4.ts deleted file mode 100644 index 8cb996079..000000000 --- a/test/translation/transformation/classExtension4.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** @extension */ -class MyClass { - public test: string = "test"; - private testP: string = "testP"; - public myFunction() {} -} diff --git a/test/translation/transformation/classPureAbstract.ts b/test/translation/transformation/classPureAbstract.ts deleted file mode 100644 index d9a661160..000000000 --- a/test/translation/transformation/classPureAbstract.ts +++ /dev/null @@ -1,3 +0,0 @@ -/** @pureAbstract */ -declare class ClassA {} -class ClassB extends ClassA {} diff --git a/test/translation/transformation/namespacePhantom.ts b/test/translation/transformation/namespacePhantom.ts deleted file mode 100644 index 2f003c28e..000000000 --- a/test/translation/transformation/namespacePhantom.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** @phantom */ -namespace myNamespace { - function nsMember() {} -} diff --git a/test/transpile/__snapshots__/directories.spec.ts.snap b/test/transpile/__snapshots__/directories.spec.ts.snap index 901d885f4..eaf179a6c 100644 --- a/test/transpile/__snapshots__/directories.spec.ts.snap +++ b/test/transpile/__snapshots__/directories.spec.ts.snap @@ -1,13 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`should be able to resolve ({"name": "baseurl", "options": [Object]}) 1`] = ` -Array [ - "directories/baseurl/out/lualib_bundle.lua", - "directories/baseurl/out/src/lib/nested/file.lua", - "directories/baseurl/out/src/main.lua", -] -`; - exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 1`] = ` Array [ "directories/basic/src/lib/file.lua", diff --git a/test/transpile/__snapshots__/project.spec.ts.snap b/test/transpile/__snapshots__/project.spec.ts.snap index 4db30085f..1effba209 100644 --- a/test/transpile/__snapshots__/project.spec.ts.snap +++ b/test/transpile/__snapshots__/project.spec.ts.snap @@ -1,29 +1,45 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`should give verbose output 1`] = ` +Array [ + "Parsing project settings", + "Successfully loaded 0 plugins", + "Transforming /test/transpile/project/otherFile.ts", + "Printing /test/transpile/project/otherFile.ts", + "Transforming /test/transpile/project/index.ts", + "Printing /test/transpile/project/index.ts", + "Constructing emit plan", + "Resolving dependencies for /test/transpile/project/otherFile.ts", + "Resolving dependencies for /test/transpile/project/index.ts", + "Resolving \\"./otherFile\\" from /test/transpile/project", + "Resolved ./otherFile to /test/transpile/project/otherFile.ts", + "Emitting output", + "Emitting /test/transpile/project/otherFile.lua", + "Emitting /test/transpile/project/index.lua", + "Emit finished!", +] +`; + exports[`should transpile 1`] = ` Array [ Object { - "name": "project/otherFile.lua", - "text": "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]] -local ____exports = {} + "filePath": "otherFile.lua", + "lua": "local ____exports = {} function ____exports.getNumber(self) return getAPIValue() end return ____exports ", - "writeByteOrderMark": false, }, Object { - "name": "project/index.lua", - "text": "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]] -local ____exports = {} + "filePath": "index.lua", + "lua": "local ____exports = {} local ____otherFile = require(\\"otherFile\\") local getNumber = ____otherFile.getNumber local myNumber = getNumber(nil) setAPIValue(myNumber * 5) return ____exports ", - "writeByteOrderMark": false, }, ] `; diff --git a/test/transpile/bundle.spec.ts b/test/transpile/bundle.spec.ts index 21e9f153a..718e1b112 100644 --- a/test/transpile/bundle.spec.ts +++ b/test/transpile/bundle.spec.ts @@ -1,19 +1,19 @@ import * as path from "path"; import * as util from "../util"; -import { transpileProjectResult } from "./run"; const projectDir = path.join(__dirname, "bundle"); const inputProject = path.join(projectDir, "tsconfig.json"); test("should transpile into one file", () => { - const { diagnostics, emittedFiles } = transpileProjectResult(inputProject); + const { diagnostics, transpiledFiles } = util.testProject(inputProject).getLuaResult(); expect(diagnostics).not.toHaveDiagnostics(); - expect(emittedFiles).toHaveLength(1); + expect(transpiledFiles).toHaveLength(1); - const { name, text } = emittedFiles[0]; + const { outPath, lua } = transpiledFiles[0]; // Verify the name is as specified in tsconfig - expect(name).toBe("bundle/bundle.lua"); + expect(outPath.endsWith(path.join("bundle", "bundle.lua"))).toBe(true); // Verify exported module by executing - expect(util.executeLuaModule(text)).toEqual({ myNumber: 3 }); + // Use an empty TS string because we already transpiled the TS project + util.testModule("").setLuaHeader(lua!).expectToEqual({ myNumber: 3 }); }); diff --git a/test/transpile/directories.spec.ts b/test/transpile/directories.spec.ts index 9141199e5..1c0bba994 100644 --- a/test/transpile/directories.spec.ts +++ b/test/transpile/directories.spec.ts @@ -13,7 +13,6 @@ test.each([ { name: "basic", options: { outDir: "out" } }, { name: "basic", options: { rootDir: "src" } }, { name: "basic", options: { rootDir: "src", outDir: "out" } }, - { name: "baseurl", options: { baseUrl: "./src/lib", rootDir: ".", outDir: "./out" } }, ])("should be able to resolve (%p)", ({ name, options: compilerOptions }) => { const projectPath = path.join(__dirname, "directories", name); jest.spyOn(process, "cwd").mockReturnValue(projectPath); diff --git a/test/transpile/directories/baseurl/src/lib/nested/file.ts b/test/transpile/directories/baseurl/src/lib/nested/file.ts deleted file mode 100644 index 4248a042b..000000000 --- a/test/transpile/directories/baseurl/src/lib/nested/file.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function test() { - return 1; -} diff --git a/test/transpile/directories/baseurl/src/main.ts b/test/transpile/directories/baseurl/src/main.ts deleted file mode 100644 index 1665f4e08..000000000 --- a/test/transpile/directories/baseurl/src/main.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { test } from "nested/file"; - -test(); diff --git a/test/transpile/lualib.spec.ts b/test/transpile/lualib.spec.ts new file mode 100644 index 000000000..0af391c46 --- /dev/null +++ b/test/transpile/lualib.spec.ts @@ -0,0 +1,26 @@ +import * as ts from "typescript"; +import { LuaLibFeature } from "../../src"; +import { loadLuaLibFeatures } from "../../src/LuaLib"; + +test.each(Object.entries(LuaLibFeature))("Lualib feature has correct dependencies (%p)", (_, feature) => { + const lualibCode = loadLuaLibFeatures([feature], ts.sys); + + // Find all used lualib features + const luaLibReferences = lualibCode.match(/__TS__[a-zA-Z_]+\(/g); + + // For every reference lualib function, check if its definition is also included + const missingReferences = []; + + if (luaLibReferences !== null) { + for (const reference of luaLibReferences) { + if ( + !lualibCode.includes(`function ${reference}`) && + !lualibCode.includes(`${reference.substring(0, reference.length - 1)} =`) + ) { + missingReferences.push(reference); + } + } + } + + expect(missingReferences).toHaveLength(0); +}); diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts new file mode 100644 index 000000000..0332d8c58 --- /dev/null +++ b/test/transpile/module-resolution.spec.ts @@ -0,0 +1,458 @@ +import * as path from "path"; +import * as tstl from "../../src"; +import * as util from "../util"; +import * as ts from "typescript"; +import { BuildMode, transpileProject } from "../../src"; + +describe("basic module resolution", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-node-modules"); + + const projectWithNodeModules = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")); + + test("can resolve global dependencies with declarations", () => { + // Declarations in the node_modules directory + expect(projectWithNodeModules.getLuaExecutionResult().globalWithDeclarationsResults).toEqual({ + foo: "foo from lua global with decls", + bar: "bar from lua global with decls: global with declarations!", + baz: "baz from lua global with decls", + }); + }); + + test("can resolve global dependencies with hand-written declarations", () => { + // No declarations in the node_modules directory, but written by hand in project dir + expect(projectWithNodeModules.getLuaExecutionResult().globalWithoutDeclarationsResults).toEqual({ + foo: "foo from lua global without decls", + bar: "bar from lua global without decls: global without declarations!", + baz: "baz from lua global without decls", + }); + }); + + test("can resolve module dependencies with declarations", () => { + // Declarations in the node_modules directory + expect(projectWithNodeModules.getLuaExecutionResult().moduleWithDeclarationsResults).toEqual({ + foo: "foo from lua module with decls", + bar: "bar from lua module with decls: module with declarations!", + baz: "baz from lua module with decls", + }); + }); + + test("can resolve module dependencies with hand-written declarations", () => { + // Declarations in the node_modules directory + expect(projectWithNodeModules.getLuaExecutionResult().moduleWithoutDeclarationsResults).toEqual({ + foo: "foo from lua module without decls", + bar: "bar from lua module without decls: module without declarations!", + baz: "baz from lua module without decls", + }); + }); + + test("can resolve package depencency with a dependency on another package", () => { + // Declarations in the node_modules directory + expect(projectWithNodeModules.getLuaExecutionResult().moduleWithDependencyResult).toEqual( + "Calling dependency: foo from lua module with decls" + ); + }); + + test("resolved package dependency included in bundle", () => { + const mainFile = path.join(projectPath, "main.ts"); + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual({ + globalWithDeclarationsResults: { + foo: "foo from lua global with decls", + bar: "bar from lua global with decls: global with declarations!", + baz: "baz from lua global with decls", + }, + globalWithoutDeclarationsResults: { + foo: "foo from lua global without decls", + bar: "bar from lua global without decls: global without declarations!", + baz: "baz from lua global without decls", + }, + moduleWithDeclarationsResults: { + foo: "foo from lua module with decls", + bar: "bar from lua module with decls: module with declarations!", + baz: "baz from lua module with decls", + }, + moduleWithDependencyResult: "Calling dependency: foo from lua module with decls", + moduleWithoutDeclarationsResults: { + foo: "foo from lua module without decls", + bar: "bar from lua module without decls: module without declarations!", + baz: "baz from lua module without decls", + }, + }); + }); +}); + +describe("module resolution with chained dependencies", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-dependency-chain"); + const expectedResult = { result: "dependency3", result2: "someFunc from otherfile.lua" }; + + test("can resolve dependencies in chain", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .expectToEqual(expectedResult); + }); + + test("resolved package dependency included in bundle", () => { + const mainFile = path.join(projectPath, "main.ts"); + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult); + }); + + test("works with different module setting", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ module: ts.ModuleKind.ESNext }) + .expectToEqual(expectedResult); + }); +}); + +describe("module resolution with outDir", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-dependency-chain"); + const expectedResult = { result: "dependency3", result2: "someFunc from otherfile.lua" }; + + test("emits files in outDir", () => { + const builder = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ outDir: "tstl-out" }) + .expectToEqual(expectedResult); + + // Get the output paths relative to the project path + const outPaths = builder.getLuaResult().transpiledFiles.map(f => path.relative(projectPath, f.outPath)); + expect(outPaths).toHaveLength(5); + expect(outPaths).toContain(path.join("tstl-out", "main.lua")); + // Note: outputs to lua_modules + expect(outPaths).toContain(path.join("tstl-out", "lua_modules", "dependency1", "index.lua")); + expect(outPaths).toContain(path.join("tstl-out", "lua_modules", "dependency1", "otherfile.lua")); + expect(outPaths).toContain(path.join("tstl-out", "lua_modules", "dependency2", "index.lua")); + expect(outPaths).toContain(path.join("tstl-out", "lua_modules", "dependency3", "index.lua")); + }); + + test("emits bundle in outDir", () => { + const mainFile = path.join(projectPath, "main.ts"); + const builder = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ outDir: "tstl-out", luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult); + + // Get the output paths relative to the project path + const outPaths = builder.getLuaResult().transpiledFiles.map(f => path.relative(projectPath, f.outPath)); + expect(outPaths).toHaveLength(1); + expect(outPaths).toContain(path.join("tstl-out", "bundle.lua")); + }); +}); + +describe("module resolution with sourceDir", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-sourceDir"); + const expectedResult = { + result: "dependency3", + functionInSubDir: "non-node_modules import", + functionReExportedFromSubDir: "nested func result", + nestedFunctionInSubDirOfSubDir: "nested func result", + nestedFunctionUsingFunctionFromParentDir: "nested func: non-node_modules import 2", + }; + + test("can resolve dependencies with sourceDir", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "src", "main.ts")) + .setOptions({ outDir: "tstl-out" }) + .expectToEqual(expectedResult); + }); + + test("can resolve dependencies and bundle files with sourceDir", () => { + const mainFile = path.join(projectPath, "src", "main.ts"); + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult); + }); +}); + +describe("module resolution project with lua sources", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-lua-sources"); + const expectedResult = { + funcFromLuaFile: "lua file in subdir", + funcFromSubDirLuaFile: "lua file in subdir", + }; + + test("can resolve lua dependencies", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ outDir: "tstl-out" }) + .expectToEqual(expectedResult); + }); + + test("can resolve dependencies and bundle files with sourceDir", () => { + const mainFile = path.join(projectPath, "main.ts"); + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult); + }); +}); + +describe("module resolution in library mode", () => { + test("result does not contain resolved paths", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-dependency-chain"); + + const { transpiledFiles } = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ buildMode: tstl.BuildMode.Library }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + for (const file of transpiledFiles) { + expect(file.lua).not.toContain('require("lua_modules'); + } + }); + + test("project works in library mode because no external dependencies", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-lua-sources"); + + const { transpiledFiles } = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ outDir: "tstl-out", buildMode: tstl.BuildMode.Library }) + .expectToEqual({ + funcFromLuaFile: "lua file in subdir", + funcFromSubDirLuaFile: "lua file in subdir", + }) + .getLuaResult(); + + for (const file of transpiledFiles) { + expect(file.lua).not.toContain('require("lua_modules'); + } + }); +}); + +describe("module resolution project with dependencies built by tstl library mode", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-tstl-library-modules"); + + // First compile dependencies into node_modules. NOTE: Actually writing to disk, very slow + transpileProject(path.join(projectPath, "dependency1-ts", "tsconfig.json")); + transpileProject(path.join(projectPath, "dependency2-ts", "tsconfig.json")); + + const expectedResult = { + dependency1IndexResult: "function in dependency 1 index: dependency1OtherFileFunc in dependency1/d1otherfile", + dependency1OtherFileFuncResult: "dependency1OtherFileFunc in dependency1/d1otherfile", + dependency2MainResult: "dependency 2 main", + dependency2OtherFileResult: "Dependency 2 func: my string argument", + }; + + test("can resolve lua dependencies", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ outDir: "tstl-out" }) + .expectToEqual(expectedResult); + }); + + test("can resolve dependencies and bundle", () => { + const mainFile = path.join(projectPath, "main.ts"); + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult); + }); +}); + +// Test fix for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1037 +describe("module resolution with tsx", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-tsx"); + + test("project with tsx files", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.tsx")) + .expectToEqual({ + result: "hello from other.tsx", + indexResult: "hello from dir/index.tsx", + }); + }); +}); + +describe("dependency with complicated inner structure", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-complicated-dependency"); + const tsConfigPath = path.join(projectPath, "tsconfig.json"); + const mainFilePath = path.join(projectPath, "main.ts"); + + const expectedResult = { + otherFileResult: "someFunc from otherfile.lua", + otherFileUtil: "util", + subsubresult: "result from subsub dir", + utilResult: "util", + subdirwithInitResult: "a", + }; + + // Test fix for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1055 + test("bundle should not contain duplicate files", () => { + const mainFile = path.join(projectPath, "main.ts"); + const { transpiledFiles } = util + .testProject(tsConfigPath) + .setMainFileName(mainFilePath) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult) + .getLuaResult(); + + expect(transpiledFiles).toHaveLength(1); + const lua = transpiledFiles[0].lua!; + // util is used in 2 places, but should only occur once in the bundle + const utilModuleOccurrences = (lua.match(/\["lua_modules\.dependency1\.util"\]/g) ?? []).length; + expect(utilModuleOccurrences).toBe(1); + }); + + // Test fix for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1054 + test("should be able to resolve dependency files in subdirectories", () => { + util.testProject(tsConfigPath).setMainFileName(mainFilePath).expectToEqual(expectedResult); + }); +}); + +test("module resolution should not try to resolve @noResolution annotation", () => { + util.testModule` + import * as json from "json"; + const test = json.decode("{}"); + ` + .addExtraFile( + "json.d.ts", + ` + /** @noResolution */ + declare module "json" { + function encode(this: void, data: unknown): string; + function decode(this: void, data: string): unknown; + } + ` + ) + .expectToHaveNoDiagnostics(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1062 +test("module resolution should not rewrite @NoResolution requires in library mode", () => { + const { transpiledFiles } = util.testModule` + import * as json from "json"; + const test = json.decode("{}"); + ` + .addExtraFile( + "json.d.ts", + ` + /** @noResolution */ + declare module "json" { + function encode(this: void, data: unknown): string; + function decode(this: void, data: string): unknown; + } + ` + ) + .setOptions({ buildMode: BuildMode.Library }) + .getLuaResult(); + + expect(transpiledFiles).toHaveLength(1); + expect(transpiledFiles[0].lua).toContain('require("@NoResolution:'); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1050 +test("module resolution should not try to resolve resolve-like functions", () => { + util.testModule` + function custom_require(this: void, value: string) { + return value; + } + + namespace ns { + export function require(this: void, value: string) { + return value; + } + } + + class MyClass { + require(value: string) { + return value; + } + } + const inst = new MyClass(); + + export const result = [ + custom_require("value 1"), + ns.require("value 2"), + inst.require("value 3") + ]; + + ` + .expectToHaveNoDiagnostics() + .expectToEqual({ + result: ["value 1", "value 2", "value 3"], + }); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1050 +test("module resolution uses baseURL to resolve imported files", () => { + util.testModule` + import { foo } from "dep1"; + import { bar } from "dep2"; + import { baz } from "luadep"; + + export const fooResult = foo(); + export const barResult = bar(); + export const bazResult = baz(); + ` + .addExtraFile( + "myproject/mydeps/dep1.ts", + ` + export function foo() { return "foo"; } + ` + ) + .addExtraFile( + "myproject/mydeps/dep2.ts", + ` + export function bar() { return "bar"; } + ` + ) + .addExtraFile( + "myproject/mydeps/luadep.d.ts", + ` + export function baz(): string; + ` + ) + .addExtraFile( + "myproject/mydeps/luadep.lua", + ` + return { baz = function() return "baz" end } + ` + ) + .setOptions({ baseUrl: "./myproject/mydeps" }) + .expectToEqual({ + fooResult: "foo", + barResult: "bar", + bazResult: "baz", + }); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1071 +test("includes lualib_bundle when external lua requests it", () => { + util.testModule` + export { foo } from "./lualibuser"; + ` + .addExtraFile( + "lualibuser.d.ts", + ` + export const foo: string[]; + ` + ) + .addExtraFile( + "lualibuser.lua", + ` + require("lualib_bundle") + + local result = {} + __TS__ArrayPush(result, "foo") + __TS__ArrayPush(result, "bar") + + return { foo = result } + ` + ) + .expectToEqual({ + foo: ["foo", "bar"], + }); +}); diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/main.ts b/test/transpile/module-resolution/project-with-complicated-dependency/main.ts new file mode 100644 index 000000000..70d8123fa --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/main.ts @@ -0,0 +1,7 @@ +import * as dependency1 from "dependency1"; + +export const otherFileResult = dependency1.otherFileFromDependency1(); +export const utilResult = dependency1.callUtil(); +export const otherFileUtil = dependency1.otherFileUtil(); +export const subsubresult = dependency1.subsubdirfileResult; +export const subdirwithInitResult = dependency1.subdirWithInitResult; diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts new file mode 100644 index 000000000..28f4f5baa --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts @@ -0,0 +1,6 @@ +/** @noSelfInFile */ +export declare function otherFileFromDependency1(): string; +export declare function callUtil(): string; +export declare function otherFileUtil(): string; +export const subsubdirfileResult: string; +export const subdirWithInitResult: string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua new file mode 100644 index 000000000..c3838b1f4 --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua @@ -0,0 +1,18 @@ +local otherfile = require("otherfile") +local util = require("util") +local subdirfile = require("subdir.subdirfile") +local othersubdirfile = require("subdir.othersubdirfile") +local subsubdirfile = require("subdir.subsubdir.subsubdirfile") +local subdirwithinit = require("subdirwithinit") + +return { + otherFileFromDependency1 = otherfile.someFunc, + callUtil = function() + return util.utilf() + end, + otherFileUtil = otherfile.callUtil, + subdirfileResult = subdirfile.subdirfileResult, + othersubdirfileResult = othersubdirfile.othersubdirfileResult, + subsubdirfileResult = subsubdirfile.subsubresult, + subdirWithInitResult = subdirwithinit.a() +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/otherfile.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/otherfile.lua new file mode 100644 index 000000000..0fb8719ac --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/otherfile.lua @@ -0,0 +1,10 @@ +local util = require("util") + +return { + someFunc = function() + return "someFunc from otherfile.lua" + end, + callUtil = function() + return util.utilf() + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/othersubdirfile.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/othersubdirfile.lua new file mode 100644 index 000000000..45e5c985f --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/othersubdirfile.lua @@ -0,0 +1,3 @@ +return { + result = "result from other subdirectory file" +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subdirfile.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subdirfile.lua new file mode 100644 index 000000000..fe26400a1 --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subdirfile.lua @@ -0,0 +1,5 @@ +local othersubdirfile = require("subdir.othersubdirfile") +return { + subdirfileResult = "result from subdirectory file!", + othersubdirfileResult = othersubdirfile.result +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subsubdir/subsubdirfile.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subsubdir/subsubdirfile.lua new file mode 100644 index 000000000..581c8f858 --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subsubdir/subsubdirfile.lua @@ -0,0 +1,3 @@ +return { + subsubresult = "result from subsub dir" +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdirwithinit/init.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdirwithinit/init.lua new file mode 100644 index 000000000..f26612a6f --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdirwithinit/init.lua @@ -0,0 +1,3 @@ +return { + a = function() return "a" end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/util.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/util.lua new file mode 100644 index 000000000..e4e812406 --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/util.lua @@ -0,0 +1,3 @@ +return { + utilf = function() return "util" end, +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/tsconfig.json b/test/transpile/module-resolution/project-with-complicated-dependency/tsconfig.json new file mode 100644 index 000000000..b76533290 --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "strict": true, + "moduleResolution": "Node", + "target": "esnext", + "lib": ["esnext"], + "types": [], + "rootDir": "." + } +} diff --git a/test/transpile/module-resolution/project-with-dependency-chain/main.ts b/test/transpile/module-resolution/project-with-dependency-chain/main.ts new file mode 100644 index 000000000..cda66cd55 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/main.ts @@ -0,0 +1,4 @@ +import * as dependency1 from "dependency1"; + +export const result = dependency1.f1(); +export const result2 = dependency1.otherFileFromDependency1(); diff --git a/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.d.ts b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.d.ts new file mode 100644 index 000000000..5155e72c5 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.d.ts @@ -0,0 +1,3 @@ +/** @noSelfInFile */ +export declare function f1(): string; +export declare function otherFileFromDependency1(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.lua b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.lua new file mode 100644 index 000000000..80cae6fb8 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.lua @@ -0,0 +1,7 @@ +local dependency2 = require("dependency2") +local otherfile = require("otherfile") + +return { + f1 = function() return dependency2.f2() end, + otherFileFromDependency1 = otherfile.someFunc +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/otherfile.lua b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/otherfile.lua new file mode 100644 index 000000000..871964bf7 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/otherfile.lua @@ -0,0 +1,5 @@ +return { + someFunc = function() + return "someFunc from otherfile.lua" + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency2/index.lua b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency2/index.lua new file mode 100644 index 000000000..10b36647e --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency2/index.lua @@ -0,0 +1,5 @@ +local dependency3 = require("dependency3") + +return { + f2 = dependency3.f3 +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency3/index.lua b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency3/index.lua new file mode 100644 index 000000000..112f9ba7e --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency3/index.lua @@ -0,0 +1,3 @@ +return { + f3 = function() return "dependency3" end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-dependency-chain/tsconfig.json b/test/transpile/module-resolution/project-with-dependency-chain/tsconfig.json new file mode 100644 index 000000000..b76533290 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "strict": true, + "moduleResolution": "Node", + "target": "esnext", + "lib": ["esnext"], + "types": [], + "rootDir": "." + } +} diff --git a/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.d.ts b/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.d.ts new file mode 100644 index 000000000..6166280f2 --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.d.ts @@ -0,0 +1,2 @@ +/** @noSelfInFile */ +export declare function funcFromSubDir(): string; diff --git a/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.lua b/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.lua new file mode 100644 index 000000000..a23007078 --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.lua @@ -0,0 +1,3 @@ +return { + funcFromSubDir = function() return "lua file in subdir" end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-lua-sources/luafile.d.ts b/test/transpile/module-resolution/project-with-lua-sources/luafile.d.ts new file mode 100644 index 000000000..6294675a1 --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/luafile.d.ts @@ -0,0 +1,2 @@ +/** @noSelfInFile */ +export declare function funcInLuaFile(): string; diff --git a/test/transpile/module-resolution/project-with-lua-sources/luafile.lua b/test/transpile/module-resolution/project-with-lua-sources/luafile.lua new file mode 100644 index 000000000..56e61090f --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/luafile.lua @@ -0,0 +1,3 @@ +return { + funcInLuaFile = function() return "lua file in subdir" end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-lua-sources/main.ts b/test/transpile/module-resolution/project-with-lua-sources/main.ts new file mode 100644 index 000000000..d4c19b440 --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/main.ts @@ -0,0 +1,5 @@ +import { funcInLuaFile } from "./luafile"; +import { funcFromSubDir } from "./lua_sources/otherluaFile"; + +export const funcFromLuaFile = funcInLuaFile(); +export const funcFromSubDirLuaFile = funcFromSubDir(); diff --git a/test/transpile/module-resolution/project-with-lua-sources/tsconfig.json b/test/transpile/module-resolution/project-with-lua-sources/tsconfig.json new file mode 100644 index 000000000..a07455ed7 --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "strict": true, + "target": "esnext", + "lib": ["esnext"], + "types": [], + "outDir": "tstl-out" + } +} diff --git a/test/transpile/module-resolution/project-with-node-modules/lua-global-without-decls.d.ts b/test/transpile/module-resolution/project-with-node-modules/lua-global-without-decls.d.ts new file mode 100644 index 000000000..4d1c1db1b --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/lua-global-without-decls.d.ts @@ -0,0 +1,4 @@ +/** @noSelfInFile */ +declare function fooGlobalWithoutDecls(): string; +declare function barGlobalWithoutDecls(param: string): string; +declare function bazGlobalWithoutDecls(): string; diff --git a/test/transpile/module-resolution/project-with-node-modules/lua-module-without-decls.d.ts b/test/transpile/module-resolution/project-with-node-modules/lua-module-without-decls.d.ts new file mode 100644 index 000000000..9ccfc9bfe --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/lua-module-without-decls.d.ts @@ -0,0 +1,9 @@ +/** @noSelfInFile */ +declare module "lua-module-without-decls" { + function foo(this: void): string; + function bar(this: void, param: string): string; +} + +declare module "lua-module-without-decls/baz" { + function baz(this: void): string; +} diff --git a/test/transpile/module-resolution/project-with-node-modules/main.ts b/test/transpile/module-resolution/project-with-node-modules/main.ts new file mode 100644 index 000000000..8d9332190 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/main.ts @@ -0,0 +1,39 @@ +import "lua-global-with-decls"; +import "lua-global-with-decls/baz"; + +import "lua-global-without-decls"; +import "lua-global-without-decls/baz"; + +import * as moduleWithDeclarations from "lua-module-with-decls"; +import * as moduleWithDeclarationsBaz from "lua-module-with-decls/baz"; + +import * as moduleWithoutDeclarations from "lua-module-without-decls"; +import * as moduleWithoutDeclarationsBaz from "lua-module-without-decls/baz"; + +import * as moduleWithDependency from "lua-module-with-dependency"; + +export const globalWithDeclarationsResults = { + foo: fooGlobal(), + bar: barGlobal("global with declarations!"), + baz: bazGlobal(), +}; + +export const globalWithoutDeclarationsResults = { + foo: fooGlobalWithoutDecls(), + bar: barGlobalWithoutDecls("global without declarations!"), + baz: bazGlobalWithoutDecls(), +}; + +export const moduleWithDeclarationsResults = { + foo: moduleWithDeclarations.foo(), + bar: moduleWithDeclarations.bar("module with declarations!"), + baz: moduleWithDeclarationsBaz.baz(), +}; + +export const moduleWithoutDeclarationsResults = { + foo: moduleWithoutDeclarations.foo(), + bar: moduleWithoutDeclarations.bar("module without declarations!"), + baz: moduleWithoutDeclarationsBaz.baz(), +}; + +export const moduleWithDependencyResult = moduleWithDependency.callDependency(); diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.d.ts b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.d.ts new file mode 100644 index 000000000..23f55b1ad --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.d.ts @@ -0,0 +1 @@ +declare function bazGlobal(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.lua new file mode 100644 index 000000000..952807f1a --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.lua @@ -0,0 +1,3 @@ +function bazGlobal() + return "baz from lua global with decls" +end \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.d.ts b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.d.ts new file mode 100644 index 000000000..1339056b5 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.d.ts @@ -0,0 +1,3 @@ +/** @noSelfInFile */ +declare function fooGlobal(): string; +declare function barGlobal(param: string): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.lua new file mode 100644 index 000000000..d10edd189 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.lua @@ -0,0 +1,6 @@ +function fooGlobal() + return "foo from lua global with decls" +end +function barGlobal(param) + return "bar from lua global with decls: " .. param +end \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/baz.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/baz.lua new file mode 100644 index 000000000..02980e662 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/baz.lua @@ -0,0 +1,3 @@ +function bazGlobalWithoutDecls() + return "baz from lua global without decls" +end \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/index.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/index.lua new file mode 100644 index 000000000..46dd970a0 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/index.lua @@ -0,0 +1,6 @@ +function fooGlobalWithoutDecls() + return "foo from lua global without decls" +end +function barGlobalWithoutDecls(param) + return "bar from lua global without decls: " .. param +end \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.d.ts b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.d.ts new file mode 100644 index 000000000..5f46a6ce2 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.d.ts @@ -0,0 +1,2 @@ +/** @noSelfInFile */ +export declare function baz(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.lua new file mode 100644 index 000000000..f4e16a0d7 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.lua @@ -0,0 +1,5 @@ +return { + baz = function() + return "baz from lua module with decls" + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.d.ts b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.d.ts new file mode 100644 index 000000000..aa83ce4a6 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.d.ts @@ -0,0 +1,3 @@ +/** @noSelfInFile */ +export declare function foo(): string; +export declare function bar(param: string): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.lua new file mode 100644 index 000000000..0c5d47fe6 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.lua @@ -0,0 +1,8 @@ +return { + foo = function() + return "foo from lua module with decls" + end, + bar = function(param) + return "bar from lua module with decls: " .. param + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.d.ts b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.d.ts new file mode 100644 index 000000000..381596acd --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.d.ts @@ -0,0 +1,2 @@ +/** @noSelf */ +export declare function callDependency(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.lua new file mode 100644 index 000000000..9bc475e5b --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.lua @@ -0,0 +1,7 @@ +local dependency = require("lua-module-with-decls") + +return { + callDependency = function() + return "Calling dependency: " .. dependency.foo() + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/baz.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/baz.lua new file mode 100644 index 000000000..7358f341b --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/baz.lua @@ -0,0 +1,5 @@ +return { + baz = function() + return "baz from lua module without decls" + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/index.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/index.lua new file mode 100644 index 000000000..e73581589 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/index.lua @@ -0,0 +1,8 @@ +return { + foo = function() + return "foo from lua module without decls" + end, + bar = function(param) + return "bar from lua module without decls: " .. param + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/tsconfig.json b/test/transpile/module-resolution/project-with-node-modules/tsconfig.json new file mode 100644 index 000000000..935b64af6 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "strict": true, + "moduleResolution": "Node", + "noUnusedLocals": true, + "noUnusedParameters": true, + "target": "esnext", + "lib": ["esnext"], + "types": [], + "rootDir": "." + } +} diff --git a/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.d.ts b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.d.ts new file mode 100644 index 000000000..761d6bc02 --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.d.ts @@ -0,0 +1,2 @@ +/** @noSelfInFile */ +export declare function f1(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.lua b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.lua new file mode 100644 index 000000000..dcf28d6fd --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.lua @@ -0,0 +1,5 @@ +local dependency2 = require("dependency2") + +return { + f1 = function() return dependency2.f2() end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency2/index.lua b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency2/index.lua new file mode 100644 index 000000000..10b36647e --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency2/index.lua @@ -0,0 +1,5 @@ +local dependency3 = require("dependency3") + +return { + f2 = dependency3.f3 +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency3/index.lua b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency3/index.lua new file mode 100644 index 000000000..112f9ba7e --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency3/index.lua @@ -0,0 +1,3 @@ +return { + f3 = function() return "dependency3" end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-sourceDir/src/main.ts b/test/transpile/module-resolution/project-with-sourceDir/src/main.ts new file mode 100644 index 000000000..9014f7b62 --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/src/main.ts @@ -0,0 +1,9 @@ +import * as dependency1 from "dependency1"; +import { func, nestedFunc } from "./subdir/otherfile"; +import { nestedFunc as nestedFuncOriginal, nestedFuncUsingParent } from "./subdir/subdirofsubdir/nestedfile"; + +export const result = dependency1.f1(); +export const functionInSubDir = func(); +export const functionReExportedFromSubDir = nestedFunc(); +export const nestedFunctionInSubDirOfSubDir = nestedFuncOriginal(); +export const nestedFunctionUsingFunctionFromParentDir = nestedFuncUsingParent(); diff --git a/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile.ts b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile.ts new file mode 100644 index 000000000..c12dee955 --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile.ts @@ -0,0 +1,5 @@ +export function func() { + return "non-node_modules import"; +} + +export { nestedFunc } from "./subdirofsubdir/nestedfile"; diff --git a/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile2.ts b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile2.ts new file mode 100644 index 000000000..1132c2ea1 --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile2.ts @@ -0,0 +1,3 @@ +export function func2() { + return "non-node_modules import 2"; +} diff --git a/test/transpile/module-resolution/project-with-sourceDir/src/subdir/subdirofsubdir/nestedfile.ts b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/subdirofsubdir/nestedfile.ts new file mode 100644 index 000000000..d316f023e --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/subdirofsubdir/nestedfile.ts @@ -0,0 +1,9 @@ +import { func2 } from "../otherfile2"; + +export function nestedFunc() { + return "nested func result"; +} + +export function nestedFuncUsingParent() { + return `nested func: ${func2()}`; +} diff --git a/test/transpile/module-resolution/project-with-sourceDir/tsconfig.json b/test/transpile/module-resolution/project-with-sourceDir/tsconfig.json new file mode 100644 index 000000000..200df2468 --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "strict": true, + "moduleResolution": "Node", + "target": "esnext", + "lib": ["esnext"], + "types": [], + "rootDir": "src" + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/d1otherfile.ts b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/d1otherfile.ts new file mode 100644 index 000000000..3877a1c52 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/d1otherfile.ts @@ -0,0 +1,3 @@ +export function dependency1OtherFileFunc() { + return "dependency1OtherFileFunc in dependency1/d1otherfile"; +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/index.ts b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/index.ts new file mode 100644 index 000000000..fc1cdddec --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/index.ts @@ -0,0 +1,5 @@ +import { dependency1OtherFileFunc } from "./d1otherfile"; + +export function dependency1IndexFunc() { + return "function in dependency 1 index: " + dependency1OtherFileFunc(); +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/tsconfig.json new file mode 100644 index 000000000..5fcb76fbe --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "outDir": "../node_modules/dependency1", + "declaration": true + }, + "tstl": { + "buildMode": "library" + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/d2otherfile.ts b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/d2otherfile.ts new file mode 100644 index 000000000..63e34f8b6 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/d2otherfile.ts @@ -0,0 +1,3 @@ +export function dependency2OtherFileFunc(this: void, arg: string) { + return `Dependency 2 func: ${arg}`; +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/main.ts b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/main.ts new file mode 100644 index 000000000..03b90c231 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/main.ts @@ -0,0 +1,5 @@ +export function dependency2Main() { + return "dependency 2 main"; +} + +export * from "./d2otherfile"; diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/tsconfig.json new file mode 100644 index 000000000..f77b336a2 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "outDir": "../node_modules/dependency2", + "declaration": true + }, + "tstl": { + "buildMode": "library" + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/main.ts b/test/transpile/module-resolution/project-with-tstl-library-modules/main.ts new file mode 100644 index 000000000..c1286088a --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/main.ts @@ -0,0 +1,8 @@ +import { dependency1IndexFunc } from "dependency1"; +import { dependency1OtherFileFunc } from "dependency1/d1otherfile"; +import { dependency2Main, dependency2OtherFileFunc } from "dependency2/main"; + +export const dependency1IndexResult = dependency1IndexFunc(); +export const dependency1OtherFileFuncResult = dependency1OtherFileFunc(); +export const dependency2MainResult = dependency2Main(); +export const dependency2OtherFileResult = dependency2OtherFileFunc("my string argument"); diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-modules/tsconfig.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/tsconfig.json @@ -0,0 +1 @@ +{} diff --git a/test/transpile/module-resolution/project-with-tsx/dir/index.tsx b/test/transpile/module-resolution/project-with-tsx/dir/index.tsx new file mode 100644 index 000000000..20c981b8a --- /dev/null +++ b/test/transpile/module-resolution/project-with-tsx/dir/index.tsx @@ -0,0 +1,3 @@ +export function indexf() { + return "hello from dir/index.tsx"; +} diff --git a/test/transpile/module-resolution/project-with-tsx/main.tsx b/test/transpile/module-resolution/project-with-tsx/main.tsx new file mode 100644 index 000000000..d17e2a7e4 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tsx/main.tsx @@ -0,0 +1,5 @@ +import { f } from "./other"; +import { indexf } from "./dir"; + +export const result = f(); +export const indexResult = indexf(); diff --git a/test/transpile/module-resolution/project-with-tsx/other.tsx b/test/transpile/module-resolution/project-with-tsx/other.tsx new file mode 100644 index 000000000..514705822 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tsx/other.tsx @@ -0,0 +1,3 @@ +export function f() { + return "hello from other.tsx"; +} diff --git a/test/transpile/module-resolution/project-with-tsx/tsconfig.json b/test/transpile/module-resolution/project-with-tsx/tsconfig.json new file mode 100644 index 000000000..b5fbd521b --- /dev/null +++ b/test/transpile/module-resolution/project-with-tsx/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "jsx": "react" + } +} diff --git a/test/transpile/paths.spec.ts b/test/transpile/paths.spec.ts new file mode 100644 index 000000000..33d4f6258 --- /dev/null +++ b/test/transpile/paths.spec.ts @@ -0,0 +1,120 @@ +import * as path from "path"; +import * as ts from "typescript"; +import { getSourceDir } from "../../src"; +import * as util from "../util"; + +const cwd = process.cwd(); + +// Path for project tsconfig.json to resolve for +const configFilePath = path.join(cwd, "tsconfig.json"); + +describe("getSourceDir", () => { + test("with rootDir", () => { + const program = ts.createProgram(["main.ts", "src/otherfile.ts"], { configFilePath, rootDir: "src" }); + + // getCommonSourceDirectory does not work right so mock it + jest.spyOn(program, "getCommonSourceDirectory").mockReturnValue(cwd); + + expect(getSourceDir(program)).toBe(path.join(cwd, "src")); + }); + + test("without rootDir", () => { + const program = ts.createProgram(["main.ts", "src/otherfile.ts"], { configFilePath }); + + // getCommonSourceDirectory does not work right so mock it + jest.spyOn(program, "getCommonSourceDirectory").mockReturnValue(cwd); + + // Common sources directory is project root + expect(normalize(getSourceDir(program))).toBe(cwd); + }); + + test("without rootDir in src dir", () => { + const program = ts.createProgram([path.join(cwd, "src", "main.ts"), path.join(cwd, "src", "otherfile.ts")], { + configFilePath, + }); + + // getCommonSourceDirectory does not work right so mock it + jest.spyOn(program, "getCommonSourceDirectory").mockReturnValue(path.join(cwd, "src")); + + // Common sources directory is src + expect(normalize(getSourceDir(program))).toBe(path.join(cwd, "src")); + }); +}); + +describe("getEmitPath", () => { + test("puts files next to input without options", () => { + const { transpiledFiles } = util.testModule`` + .setMainFileName("main.ts") + .addExtraFile("dir/extra.ts", "") + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toContain("main.lua"); + expect(fileNames).toContain(path.join("dir", "extra.lua")); + }); + + test("puts files in outdir", () => { + const outDir = path.join(cwd, "tstl-out"); + const { transpiledFiles } = util.testModule`` + .setMainFileName("main.ts") + .addExtraFile("dir/extra.ts", "") + .setOptions({ outDir }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toContain(path.join(outDir, "main.lua")); + expect(fileNames).toContain(path.join(outDir, "dir", "extra.lua")); + }); + + test("puts files from rootDir in outdir", () => { + const outDir = path.join(cwd, "tstl-out"); + const { transpiledFiles } = util.testModule`` + .setMainFileName("src/main.ts") + .addExtraFile("src/extra.ts", "") + .setOptions({ rootDir: "src", outDir }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toContain(path.join(outDir, "main.lua")); + expect(fileNames).toContain(path.join(outDir, "extra.lua")); + }); + + test("puts bundle relative to project root", () => { + const { transpiledFiles } = util.testModule`` + .setMainFileName("src/main.ts") + .addExtraFile("src/extra.ts", "") + .setOptions({ configFilePath, rootDir: "src", luaBundle: "out/bundle.lua", luaBundleEntry: "src/main.ts" }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toHaveLength(1); + expect(fileNames).toContain(path.join(cwd, "out", "bundle.lua")); + }); + + test("puts bundle relative to outdir", () => { + const { transpiledFiles } = util.testModule`` + .setMainFileName("src/main.ts") + .addExtraFile("src/extra.ts", "") + .setOptions({ + configFilePath, + rootDir: "src", + outDir: "out1", + luaBundle: "out2/bundle.lua", + luaBundleEntry: "src/main.ts", + }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toHaveLength(1); + expect(fileNames).toContain(path.join(cwd, "out1", "out2", "bundle.lua")); + }); +}); + +function normalize(path: string) { + return path.endsWith("/") ? path.slice(0, path.length - 1) : path; +} diff --git a/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap b/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap new file mode 100644 index 000000000..9902416ab --- /dev/null +++ b/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap @@ -0,0 +1,29 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`statement comments 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + --This comment on variable declaration was added by a plugin! + --- This one too! + local foo = \\"bar\\" + -- This trailing comment was also added by a plugin! + --- Example luadoc comment + ---@param paramName ParamClass + foo = \\"baz\\" + --[[ This plugin can also (kinda) create multiline comments. + -- Line 2 + --]] + --[[Multiline comments are supported as arrays + This is the second line!]] + while true do + end + --Single line comments and multiline comments can also be mixed + --[[Like this + Pretty cool!]] + --Empty multiline comment below: + --[[]] + --Single line multiline comment: + --[[Single line]] +end +return ____exports" +`; diff --git a/test/transpile/plugins/add-comments.ts b/test/transpile/plugins/add-comments.ts new file mode 100644 index 000000000..9beb01432 --- /dev/null +++ b/test/transpile/plugins/add-comments.ts @@ -0,0 +1,62 @@ +import * as ts from "typescript"; +import * as tstl from "../../../src"; + +const plugin: tstl.Plugin = { + visitors: { + [ts.SyntaxKind.VariableStatement](node, context) { + const result = context.superTransformStatements(node); + + const firstLuaStatement = result[0]; + const lastLuaStatement = result[result.length - 1]; + + firstLuaStatement.leadingComments = [ + "This comment on variable declaration was added by a plugin!", + "- This one too!", + ]; + + lastLuaStatement.trailingComments = [" This trailing comment was also added by a plugin!"]; + + return result; + }, + [ts.SyntaxKind.ExpressionStatement](node, context) { + const result = context.superTransformStatements(node); + + const firstLuaStatement = result[0]; + const lastLuaStatement = result[result.length - 1]; + + firstLuaStatement.leadingComments = ["- Example luadoc comment", "-@param paramName ParamClass"]; + + lastLuaStatement.trailingComments = [ + "[[ This plugin can also (kinda) create multiline comments.", + " Line 2", + "]]", + ]; + + return result; + }, + [ts.SyntaxKind.WhileStatement](node, context) { + const result = context.superTransformStatements(node); + + const firstLuaStatement = result[0]; + const lastLuaStatement = result[result.length - 1]; + + firstLuaStatement.leadingComments = [ + ["Multiline comments are supported as arrays", "This is the second line!"], + ]; + + lastLuaStatement.trailingComments = [ + "Single line comments and multiline comments can also be mixed", + ["Like this", "Pretty cool!"], + "Empty multiline comment below:", + [], + "Single line multiline comment:", + ["Single line"], + ]; + + return result; + }, + }, +}; + +// eslint-disable-next-line import/no-default-export +export default plugin; diff --git a/test/transpile/plugins/arguments.ts b/test/transpile/plugins/arguments.ts new file mode 100644 index 000000000..f6aa2ba6e --- /dev/null +++ b/test/transpile/plugins/arguments.ts @@ -0,0 +1,28 @@ +import * as ts from "typescript"; +import * as tstl from "../../../src"; + +interface Options { + name: string; + option: boolean; +} + +// eslint-disable-next-line import/no-default-export +export default function plugin(options: Options): tstl.Plugin { + return { + visitors: { + [ts.SyntaxKind.ReturnStatement]: () => + tstl.createReturnStatement([ + tstl.createTableExpression([ + tstl.createTableFieldExpression( + tstl.createStringLiteral(options.name), + tstl.createStringLiteral("name") + ), + tstl.createTableFieldExpression( + tstl.createBooleanLiteral(options.option), + tstl.createStringLiteral("option") + ), + ]), + ]), + }, + }; +} diff --git a/test/transpile/plugins/plugins.spec.ts b/test/transpile/plugins/plugins.spec.ts index ce2ebc7a6..eaaee3dca 100644 --- a/test/transpile/plugins/plugins.spec.ts +++ b/test/transpile/plugins/plugins.spec.ts @@ -22,3 +22,41 @@ test("visitor using super", () => { .setOptions({ luaPlugins: [{ name: path.join(__dirname, "visitor-super.ts") }] }) .expectToEqual("bar"); }); + +test("passing arguments", () => { + util.testFunction` + return {}; + ` + .setOptions({ luaPlugins: [{ name: path.join(__dirname, "arguments.ts"), option: true }] }) + .expectToEqual({ name: path.join(__dirname, "arguments.ts"), option: true }); +}); + +test("statement comments", () => { + util.testFunction` + let foo = "bar"; + foo = "baz"; + while (true) {} + ` + .setOptions({ luaPlugins: [{ name: path.join(__dirname, "add-comments.ts") }] }) + .expectLuaToMatchSnapshot(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1013 +test.each(["namespace", "module"])("%s with TS transformer plugin", moduleOrNamespace => { + util.testModule` + import { ns } from "module"; + export const result = ns.returnsBool(); + ` + .addExtraFile( + "module.ts", + ` + export ${moduleOrNamespace} ns { + export function returnsBool() { + return false; + } + } + ` + ) + .setOptions({ plugins: [{ transform: path.join(__dirname, "transformer-plugin.ts") }] }) + .expectNoExecutionError(); +}); diff --git a/test/transpile/plugins/transformer-plugin.ts b/test/transpile/plugins/transformer-plugin.ts new file mode 100644 index 000000000..8b338723c --- /dev/null +++ b/test/transpile/plugins/transformer-plugin.ts @@ -0,0 +1,15 @@ +/** + * This is a TS tranformer plugin that replaces any return statement to 'return true'. + */ +import * as ts from "typescript"; + +const replaceNode = (node: ts.Node) => { + if (ts.isReturnStatement(node)) { + return ts.factory.createReturnStatement(ts.factory.createTrue()); + } +}; +const createTransformer = () => (context: ts.TransformationContext) => { + const visit = (node: ts.Node): ts.Node => replaceNode(node) ?? ts.visitEachChild(node, visit, context); + return (file: ts.SourceFile) => ts.visitNode(file, visit); +}; +exports.default = createTransformer; diff --git a/test/transpile/project.spec.ts b/test/transpile/project.spec.ts index 6f262dada..49234975b 100644 --- a/test/transpile/project.spec.ts +++ b/test/transpile/project.spec.ts @@ -1,8 +1,35 @@ import * as path from "path"; -import { transpileProjectResult } from "./run"; +import { normalizeSlashes } from "../../src/utils"; +import * as util from "../util"; test("should transpile", () => { - const { diagnostics, emittedFiles } = transpileProjectResult(path.join(__dirname, "project", "tsconfig.json")); - expect(diagnostics).not.toHaveDiagnostics(); - expect(emittedFiles).toMatchSnapshot(); + const projectDir = path.join(__dirname, "project"); + const { transpiledFiles } = util + .testProject(path.join(projectDir, "tsconfig.json")) + .setMainFileName(path.join(projectDir, "index.ts")) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + expect( + transpiledFiles.map(f => ({ filePath: path.relative(projectDir, f.outPath), lua: f.lua })) + ).toMatchSnapshot(); +}); + +test("should give verbose output", () => { + // Capture console logs + const consoleLogs: string[] = []; + const originalLog = console.log; + console.log = (...args: any[]) => { + consoleLogs.push(args.map(a => a.toString().replace(normalizeSlashes(process.cwd()), "")).join(",")); + }; + + const projectDir = path.join(__dirname, "project"); + util.testProject(path.join(projectDir, "tsconfig.json")) + .setMainFileName(path.join(projectDir, "index.ts")) + .setOptions({ tstlVerbose: true }) + .expectToHaveNoDiagnostics(); + + console.log = originalLog; + + expect(consoleLogs).toMatchSnapshot(); }); diff --git a/test/transpile/run.ts b/test/transpile/run.ts index 8890d7a18..a24a76b9f 100644 --- a/test/transpile/run.ts +++ b/test/transpile/run.ts @@ -1,7 +1,6 @@ import * as path from "path"; import * as ts from "typescript"; import * as tstl from "../../src"; -import { parseConfigFileWithSystem } from "../../src/cli/tsconfig"; import { normalizeSlashes } from "../../src/utils"; export function transpileFilesResult(rootNames: string[], options: tstl.CompilerOptions) { @@ -16,12 +15,3 @@ export function transpileFilesResult(rootNames: string[], options: tstl.Compiler return { diagnostics, emittedFiles }; } - -export function transpileProjectResult(configFileName: string) { - const parseResult = parseConfigFileWithSystem(configFileName); - if (parseResult.errors.length > 0) { - return { diagnostics: parseResult.errors, emittedFiles: [] }; - } - - return transpileFilesResult(parseResult.fileNames, parseResult.options); -} diff --git a/test/transpile/transformers/fixtures.ts b/test/transpile/transformers/fixtures.ts index c998d6efc..dff7667be 100644 --- a/test/transpile/transformers/fixtures.ts +++ b/test/transpile/transformers/fixtures.ts @@ -6,35 +6,39 @@ import { visitAndReplace } from "./utils"; export const program = (program: ts.Program, options: { value: any }): ts.TransformerFactory => checker(program.getTypeChecker(), options); -export const config = ({ value }: { value: any }): ts.TransformerFactory => context => file => - visitAndReplace(context, file, node => { - if (!ts.isReturnStatement(node)) return; - return ts.updateReturn(node, ts.createLiteral(value)); - }); +export const config = + ({ value }: { value: any }): ts.TransformerFactory => + context => + file => + visitAndReplace(context, file, node => { + if (!ts.isReturnStatement(node)) return; + return ts.factory.updateReturnStatement(node, value ? ts.factory.createTrue() : ts.factory.createFalse()); + }); -export const checker = ( - checker: ts.TypeChecker, - { value }: { value: any } -): ts.TransformerFactory => context => file => - visitAndReplace(context, file, node => { - if (!ts.isReturnStatement(node) || !node.expression) return; - const type = checker.getTypeAtLocation(node.expression); - if ((type.flags & ts.TypeFlags.BooleanLiteral) === 0) return; - return ts.updateReturn(node, ts.createLiteral(value)); - }); +export const checker = + (checker: ts.TypeChecker, { value }: { value: any }): ts.TransformerFactory => + context => + file => + visitAndReplace(context, file, node => { + if (!ts.isReturnStatement(node) || !node.expression) return; + const type = checker.getTypeAtLocation(node.expression); + if ((type.flags & ts.TypeFlags.BooleanLiteral) === 0) return; + return ts.factory.updateReturnStatement(node, value ? ts.factory.createTrue() : ts.factory.createFalse()); + }); export const raw: ts.TransformerFactory = context => file => visitAndReplace(context, file, node => { if (!ts.isReturnStatement(node)) return; - return ts.updateReturn(node, ts.createLiteral(true)); + return ts.factory.updateReturnStatement(node, ts.factory.createTrue()); }); -export const compilerOptions = ( - options: tstl.CompilerOptions -): ts.TransformerFactory => context => file => { - assert(options.plugins?.length === 1); - return visitAndReplace(context, file, node => { - if (!ts.isReturnStatement(node)) return; - return ts.updateReturn(node, ts.createLiteral(true)); - }); -}; +export const compilerOptions = + (options: tstl.CompilerOptions): ts.TransformerFactory => + context => + file => { + assert(options.plugins?.length === 1); + return visitAndReplace(context, file, node => { + if (!ts.isReturnStatement(node)) return; + return ts.factory.updateReturnStatement(node, ts.factory.createTrue()); + }); + }; diff --git a/test/transpile/transformers/transformers.spec.ts b/test/transpile/transformers/transformers.spec.ts index e166198bd..02290d9d1 100644 --- a/test/transpile/transformers/transformers.spec.ts +++ b/test/transpile/transformers/transformers.spec.ts @@ -23,6 +23,7 @@ test("transformer resolution error", () => { .expectToHaveDiagnostics(); }); +// This tests plugin transformers by transforming the `return false` statement to a `return true` statement. describe("factory types", () => { test.each(["program", "config", "checker", "raw", "compilerOptions"] as const)("%s", type => { util.testFunction` diff --git a/test/tsconfig.json b/test/tsconfig.json index de0b21bdd..86d7c9359 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -3,8 +3,7 @@ "compilerOptions": { "rootDir": "..", "types": ["node", "jest"], - "baseUrl": ".", - "paths": { "*": ["types/*"] } + "baseUrl": "." }, "include": [".", "../src"], "exclude": [ @@ -13,6 +12,7 @@ "cli/watch", "transpile/directories", "transpile/outFile", - "../src/lualib" + "../src/lualib", + "../language-extensions" ] } diff --git a/test/types/fengari.d.ts b/test/types/fengari.d.ts deleted file mode 100644 index 8b13b169d..000000000 --- a/test/types/fengari.d.ts +++ /dev/null @@ -1,347 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/explicit-member-accessibility, @typescript-eslint/class-name-casing */ - -export const FENGARI_AUTHORS: string; -export const FENGARI_COPYRIGHT: string; -export const FENGARI_RELEASE: string; -export const FENGARI_VERSION: string; -export const FENGARI_VERSION_MAJOR: string; -export const FENGARI_VERSION_MINOR: string; -export const FENGARI_VERSION_NUM: number; -export const FENGARI_VERSION_RELEASE: string; -export namespace lauxlib { - const LUA_ERRFILE: number; - const LUA_FILEHANDLE: Uint8Array; - const LUA_LOADED_TABLE: Uint8Array; - const LUA_NOREF: number; - const LUA_PRELOAD_TABLE: Uint8Array; - const LUA_REFNIL: number; - class luaL_Buffer { - L: any; - b: any; - n: any; - } - function luaL_addchar(B: any, c: any): void; - function luaL_addlstring(B: any, s: any, l: any): void; - function luaL_addsize(B: any, s: any): void; - function luaL_addstring(B: any, s: any): void; - function luaL_addvalue(B: any): void; - function luaL_argcheck(L: any, cond: any, arg: any, extramsg: any): void; - function luaL_argerror(L: any, arg: any, extramsg: any): any; - function luaL_buffinit(L: any, B: any): void; - function luaL_buffinitsize(L: any, B: any, sz: any): any; - function luaL_callmeta(L: any, obj: any, event: any): any; - function luaL_checkany(L: any, arg: any): void; - function luaL_checkinteger(L: any, arg: any): any; - function luaL_checklstring(L: any, arg: any): any; - function luaL_checknumber(L: any, arg: any): any; - function luaL_checkoption(L: any, arg: any, def: any, lst: any): any; - function luaL_checkstack(L: any, space: any, msg: any): void; - function luaL_checkstring(L: any, arg: any): any; - function luaL_checktype(L: any, arg: any, t: any): void; - function luaL_checkudata(L: any, ud: any, tname: any): any; - function luaL_checkversion(L: any): void; - function luaL_checkversion_(L: any, ver: any, sz: any): void; - function luaL_dofile(L: any, filename: any): any; - function luaL_dostring(L: any, s: any): any; - function luaL_error(L: any, fmt: any, argp: any): any; - function luaL_execresult(L: any, e: any): any; - function luaL_fileresult(L: any, stat: any, fname: any, e: any): any; - function luaL_getmetafield(L: any, obj: any, event: any): any; - function luaL_getmetatable(L: any, n: any): any; - function luaL_getsubtable(L: any, idx: any, fname: any): any; - function luaL_gsub(L: any, s: any, p: any, r: any): any; - function luaL_len(L: any, idx: any): any; - function luaL_loadbuffer(L: any, s: any, sz: any, n: any): any; - function luaL_loadbufferx(L: any, buff: any, size: any, name: any, mode: any): any; - function luaL_loadfile(L: any, filename: any): any; - function luaL_loadfilex(L: any, filename: any, mode: any): any; - function luaL_loadstring(L: any, s: any): any; - function luaL_newlib(L: any, l: any): void; - function luaL_newlibtable(L: any): void; - function luaL_newmetatable(L: any, tname: any): any; - function luaL_newstate(): any; - function luaL_opt(L: any, f: any, n: any, d: any): any; - function luaL_optinteger(L: any, arg: any, def: any): any; - function luaL_optlstring(L: any, arg: any, def: any): any; - function luaL_optnumber(L: any, arg: any, def: any): any; - function luaL_optstring(L: any, arg: any, def: any): any; - function luaL_prepbuffer(B: any): any; - function luaL_prepbuffsize(B: any, sz: any): any; - function luaL_pushresult(B: any): void; - function luaL_pushresultsize(B: any, sz: any): void; - function luaL_ref(L: any, t: any): any; - function luaL_requiref(L: any, modname: any, openf: any, glb: any): void; - function luaL_setfuncs(L: any, l: any, nup: any): void; - function luaL_setmetatable(L: any, tname: any): void; - function luaL_testudata(L: any, ud: any, tname: any): any; - function luaL_tolstring(L: any, idx: any): any; - function luaL_traceback(L: any, L1: any, msg: any, level: any): void; - function luaL_typename(L: any, i: any): any; - function luaL_unref(L: any, t: any, ref: any): void; - function luaL_where(L: any, level: any): void; - function lua_writestringerror(...args: any[]): void; -} -export namespace lua { - const LUA_AUTHORS: string; - const LUA_COPYRIGHT: string; - const LUA_ERRERR: number; - const LUA_ERRGCMM: number; - const LUA_ERRMEM: number; - const LUA_ERRRUN: number; - const LUA_ERRSYNTAX: number; - const LUA_HOOKCALL: number; - const LUA_HOOKCOUNT: number; - const LUA_HOOKLINE: number; - const LUA_HOOKRET: number; - const LUA_HOOKTAILCALL: number; - const LUA_MASKCALL: number; - const LUA_MASKCOUNT: number; - const LUA_MASKLINE: number; - const LUA_MASKRET: number; - const LUA_MINSTACK: number; - const LUA_MULTRET: number; - const LUA_NUMTAGS: number; - const LUA_OK: number; - const LUA_OPADD: number; - const LUA_OPBAND: number; - const LUA_OPBNOT: number; - const LUA_OPBOR: number; - const LUA_OPBXOR: number; - const LUA_OPDIV: number; - const LUA_OPEQ: number; - const LUA_OPIDIV: number; - const LUA_OPLE: number; - const LUA_OPLT: number; - const LUA_OPMOD: number; - const LUA_OPMUL: number; - const LUA_OPPOW: number; - const LUA_OPSHL: number; - const LUA_OPSHR: number; - const LUA_OPSUB: number; - const LUA_OPUNM: number; - const LUA_REGISTRYINDEX: number; - const LUA_RELEASE: string; - const LUA_RIDX_GLOBALS: number; - const LUA_RIDX_LAST: number; - const LUA_RIDX_MAINTHREAD: number; - const LUA_SIGNATURE: Uint8Array; - const LUA_TBOOLEAN: number; - const LUA_TFUNCTION: number; - const LUA_TLIGHTUSERDATA: number; - const LUA_TNIL: number; - const LUA_TNONE: number; - const LUA_TNUMBER: number; - const LUA_TSTRING: number; - const LUA_TTABLE: number; - const LUA_TTHREAD: number; - const LUA_TUSERDATA: number; - const LUA_VERSION: string; - const LUA_VERSION_MAJOR: string; - const LUA_VERSION_MINOR: string; - const LUA_VERSION_NUM: number; - const LUA_VERSION_RELEASE: string; - const LUA_YIELD: number; - class lua_Debug { - event: any; - name: any; - namewhat: any; - what: any; - source: any; - currentline: any; - linedefined: any; - lastlinedefined: any; - nups: any; - nparams: any; - isvararg: any; - istailcall: any; - short_src: any; - i_ci: any; - } - function lua_absindex(L: any, idx: any): any; - function lua_arith(L: any, op: any): void; - function lua_atnativeerror(L: any, errorf: any): any; - function lua_atpanic(L: any, panicf: any): any; - function lua_call(L: any, n: any, r: any): void; - function lua_callk(L: any, nargs: any, nresults: any, ctx: any, k: any): void; - function lua_checkstack(L: any, n: any): any; - function lua_close(L: any): void; - function lua_compare(L: any, index1: any, index2: any, op: any): any; - function lua_concat(L: any, n: any): void; - function lua_copy(L: any, fromidx: any, toidx: any): void; - function lua_createtable(L: any, narray: any, nrec: any): void; - function lua_dump(L: any, writer: any, data: any, strip: any): any; - function lua_error(L: any): void; - function lua_gc(): void; - function lua_getallocf(): any; - function lua_getextraspace(): any; - function lua_getfield(L: any, idx: any, k: any): any; - function lua_getglobal(L: any, name: any): any; - function lua_gethook(L: any): any; - function lua_gethookcount(L: any): any; - function lua_gethookmask(L: any): any; - function lua_geti(L: any, idx: any, n: any): any; - function lua_getinfo(L: any, what: any, ar: any): any; - function lua_getlocal(L: any, ar: any, n: any): any; - function lua_getmetatable(L: any, objindex: any): any; - function lua_getstack(L: any, level: any, ar: any): any; - function lua_gettable(L: any, idx: any): any; - function lua_gettop(L: any): any; - function lua_getupvalue(L: any, funcindex: any, n: any): any; - function lua_getuservalue(L: any, idx: any): any; - function lua_insert(L: any, idx: any): void; - function lua_isboolean(L: any, n: any): any; - function lua_iscfunction(L: any, idx: any): any; - function lua_isfunction(L: any, idx: any): any; - function lua_isinteger(L: any, idx: any): any; - function lua_islightuserdata(L: any, idx: any): any; - function lua_isnil(L: any, n: any): any; - function lua_isnone(L: any, n: any): any; - function lua_isnoneornil(L: any, n: any): any; - function lua_isnumber(L: any, idx: any): any; - function lua_isproxy(p: any, L: any): any; - function lua_isstring(L: any, idx: any): any; - function lua_istable(L: any, idx: any): any; - function lua_isthread(L: any, idx: any): any; - function lua_isuserdata(L: any, idx: any): any; - function lua_isyieldable(L: any): any; - function lua_len(L: any, idx: any): void; - function lua_load(L: any, reader: any, data: any, chunkname: any, mode: any): any; - function lua_newstate(): any; - function lua_newtable(L: any): void; - function lua_newthread(L: any): any; - function lua_newuserdata(L: any, size: any): any; - function lua_next(L: any, idx: any): any; - function lua_pcall(L: any, n: any, r: any, f: any): any; - function lua_pcallk(L: any, nargs: any, nresults: any, errfunc: any, ctx: any, k: any): any; - function lua_pop(L: any, n: any): void; - function lua_pushboolean(L: any, b: any): void; - function lua_pushcclosure(L: any, fn: any, n: any): void; - function lua_pushcfunction(L: any, fn: any): void; - function lua_pushfstring(L: any, fmt: any, argp: any): any; - function lua_pushglobaltable(L: any): void; - function lua_pushinteger(L: any, n: any): void; - function lua_pushjsclosure(L: any, fn: any, n: any): void; - function lua_pushjsfunction(L: any, fn: any): void; - function lua_pushlightuserdata(L: any, p: any): void; - function lua_pushliteral(L: any, s: any): any; - function lua_pushlstring(L: any, s: any, len: any): any; - function lua_pushnil(L: any): void; - function lua_pushnumber(L: any, n: any): void; - function lua_pushstring(L: any, s: any): any; - function lua_pushthread(L: any): any; - function lua_pushvalue(L: any, idx: any): void; - function lua_pushvfstring(L: any, fmt: any, argp: any): any; - function lua_rawequal(L: any, index1: any, index2: any): any; - function lua_rawget(L: any, idx: any): any; - function lua_rawgeti(L: any, idx: any, n: any): any; - function lua_rawgetp(L: any, idx: any, p: any): any; - function lua_rawlen(L: any, idx: any): any; - function lua_rawset(L: any, idx: any): void; - function lua_rawseti(L: any, idx: any, n: any): void; - function lua_rawsetp(L: any, idx: any, p: any): void; - function lua_register(L: any, n: any, f: any): void; - function lua_remove(L: any, idx: any): void; - function lua_replace(L: any, idx: any): void; - function lua_resume(L: any, from: any, nargs: any): any; - function lua_rotate(L: any, idx: any, n: any): void; - const lua_setallof: any; - function lua_setfield(L: any, idx: any, k: any): void; - function lua_setglobal(L: any, name: any): void; - function lua_sethook(L: any, func: any, mask: any, count: any): void; - function lua_seti(L: any, idx: any, n: any): void; - function lua_setlocal(L: any, ar: any, n: any): any; - function lua_setmetatable(L: any, objindex: any): any; - function lua_settable(L: any, idx: any): void; - function lua_settop(L: any, idx: any): void; - function lua_setupvalue(L: any, funcindex: any, n: any): any; - function lua_setuservalue(L: any, idx: any): void; - function lua_status(L: any): any; - function lua_stringtonumber(L: any, s: any): any; - function lua_toboolean(L: any, idx: any): any; - function lua_tocfunction(L: any, idx: any): any; - function lua_todataview(L: any, idx: any): any; - function lua_tointeger(L: any, idx: any): any; - function lua_tointegerx(L: any, idx: any): any; - function lua_tojsstring(L: any, idx: any): any; - function lua_tolstring(L: any, idx: any): any; - function lua_tonumber(L: any, idx: any): any; - function lua_tonumberx(L: any, idx: any): any; - function lua_topointer(L: any, idx: any): any; - function lua_toproxy(L: any, idx: any): any; - function lua_tostring(L: any, idx: any): LuaString; - function lua_tothread(L: any, idx: any): any; - function lua_touserdata(L: any, idx: any): any; - function lua_type(L: any, idx: any): any; - function lua_typename(L: any, t: any): any; - function lua_upvalueid(L: any, fidx: any, n: any): any; - function lua_upvalueindex(i: any): any; - function lua_upvaluejoin(L: any, fidx1: any, n1: any, fidx2: any, n2: any): void; - function lua_version(L: any): any; - function lua_xmove(from: any, to: any, n: any): void; - function lua_yield(L: any, n: any): void; - function lua_yieldk(L: any, nresults: any, ctx: any, k: any): any; -} -export namespace luaconf { - const LUAI_MAXSTACK: number; - const LUAL_BUFFERSIZE: number; - const LUA_COMPAT_FLOATSTRING: boolean; - const LUA_DIRSEP: string; - const LUA_EXEC_DIR: string; - const LUA_IDSIZE: number; - const LUA_INTEGER_FMT: string; - const LUA_INTEGER_FRMLEN: string; - const LUA_JSDIR: string; - const LUA_JSPATH_DEFAULT: Uint8Array; - const LUA_LDIR: string; - const LUA_MAXINTEGER: number; - const LUA_MININTEGER: number; - const LUA_NUMBER_FMT: string; - const LUA_NUMBER_FRMLEN: string; - const LUA_PATH_DEFAULT: Uint8Array; - const LUA_PATH_MARK: string; - const LUA_PATH_SEP: string; - const LUA_SHRDIR: string; - const LUA_VDIR: string; - function frexp(value: any): any; - function ldexp(mantissa: any, exponent: any): any; - function lua_getlocaledecpoint(): any; - function lua_integer2str(n: any): any; - function lua_number2str(n: any): any; - function lua_numbertointeger(n: any): any; - function luai_apicheck(l: any, e: any): void; -} -export namespace lualib { - const LUA_BITLIBNAME: string; - const LUA_COLIBNAME: string; - const LUA_DBLIBNAME: string; - const LUA_FENGARILIBNAME: string; - const LUA_IOLIBNAME: string; - const LUA_LOADLIBNAME: string; - const LUA_MATHLIBNAME: string; - const LUA_OSLIBNAME: string; - const LUA_STRLIBNAME: string; - const LUA_TABLIBNAME: string; - const LUA_UTF8LIBNAME: string; - const LUA_VERSUFFIX: string; - function luaL_openlibs(L: any): void; - function lua_assert(c: any): void; - function luaopen_coroutine(L: any): any; - function luaopen_debug(L: any): any; - function luaopen_fengari(L: any): any; - function luaopen_io(L: any): any; - function luaopen_math(L: any): any; - function luaopen_os(L: any): any; - function luaopen_package(L: any): any; - function luaopen_string(L: any): any; - function luaopen_table(L: any): any; - function luaopen_utf8(L: any): any; -} - -export type LuaString = number[]; - -export function luastring_eq(a: any, b: any): any; -export function luastring_indexOf(s: any, v: any, i: any): any; -export function luastring_of(): any; -export function to_jsstring(value: LuaString, from?: any, to?: any, replacement_char?: any): string; -export function to_luastring(str: string, cache?: any): LuaString; -export function to_uristring(a: any): any; diff --git a/test/unit/__snapshots__/bundle.spec.ts.snap b/test/unit/__snapshots__/bundle.spec.ts.snap index 84c10f3d5..20d4ec657 100644 --- a/test/unit/__snapshots__/bundle.spec.ts.snap +++ b/test/unit/__snapshots__/bundle.spec.ts.snap @@ -2,6 +2,8 @@ exports[`LuaLibImportKind.Inline generates a warning: diagnostics 1`] = `"warning TSTL: Using 'luaBundle' with 'luaLibImport: \\"inline\\"' might generate duplicate code. It is recommended to use 'luaLibImport: \\"require\\"'."`; +exports[`bundling not allowed for buildmode library: diagnostics 1`] = `"error TSTL: Cannot bundle probjects with\\"buildmode\\": \\"library\\". Projects including the library can still bundle (which will include external library files)."`; + exports[`luaEntry doesn't exist: diagnostics 1`] = `"error TSTL: Could not find bundle entry point 'entry.ts'. It should be a file in the project."`; exports[`no entry point: diagnostics 1`] = `"error TSTL: 'luaBundleEntry' is required when 'luaBundle' is enabled."`; diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap index fd53ab8ac..03bb46230 100644 --- a/test/unit/__snapshots__/expressions.spec.ts.snap +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -335,6 +335,87 @@ ____exports.__result = a | b return ____exports" `; +exports[`Bitop [5.4] ("~a") 1`] = ` +"local ____exports = {} +____exports.__result = ~a +return ____exports" +`; + +exports[`Bitop [5.4] ("a&=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a & b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.4] ("a&b") 1`] = ` +"local ____exports = {} +____exports.__result = a & b +return ____exports" +`; + +exports[`Bitop [5.4] ("a<<=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a << b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.4] ("a<>>=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a >> b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.4] ("a>>>b") 1`] = ` +"local ____exports = {} +____exports.__result = a >> b +return ____exports" +`; + +exports[`Bitop [5.4] ("a^=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a ~ b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.4] ("a^b") 1`] = ` +"local ____exports = {} +____exports.__result = a ~ b +return ____exports" +`; + +exports[`Bitop [5.4] ("a|=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a | b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.4] ("a|b") 1`] = ` +"local ____exports = {} +____exports.__result = a | b +return ____exports" +`; + exports[`Bitop [JIT] ("~a") 1`] = ` "local ____exports = {} ____exports.__result = bit.bnot(a) @@ -431,6 +512,12 @@ ____exports.__result = bit.bor(a, b) return ____exports" `; +exports[`Null Expression 1`] = ` +"local ____exports = {} +____exports.__result = nil +return ____exports" +`; + exports[`Unary expressions basic ("!a") 1`] = ` "local ____exports = {} function ____exports.__main(self) @@ -472,17 +559,19 @@ return ____exports" `; exports[`Unary expressions basic ("delete tbl.test") 1`] = ` -"local ____exports = {} +"require(\\"lualib_bundle\\"); +local ____exports = {} function ____exports.__main(self) - tbl.test = nil + __TS__Delete(tbl, \\"test\\") end return ____exports" `; exports[`Unary expressions basic ("delete tbl['test']") 1`] = ` -"local ____exports = {} +"require(\\"lualib_bundle\\"); +local ____exports = {} function ____exports.__main(self) - tbl.test = nil + __TS__Delete(tbl, \\"test\\") end return ____exports" `; @@ -504,27 +593,29 @@ return ____exports" `; exports[`Unary expressions basic ("let a = delete tbl.test") 1`] = ` -"local ____exports = {} +"require(\\"lualib_bundle\\"); +local ____exports = {} function ____exports.__main(self) - local a = (function() - tbl.test = nil - return true - end)() + local a = __TS__Delete(tbl, \\"test\\") end return ____exports" `; exports[`Unary expressions basic ("let a = delete tbl['test']") 1`] = ` -"local ____exports = {} +"require(\\"lualib_bundle\\"); +local ____exports = {} function ____exports.__main(self) - local a = (function() - tbl.test = nil - return true - end)() + local a = __TS__Delete(tbl, \\"test\\") end return ____exports" `; +exports[`Undefined Expression 1`] = ` +"local ____exports = {} +____exports.__result = nil +return ____exports" +`; + exports[`Unsupported bitop 5.3 ("a>>=b"): code 1`] = ` "local ____exports = {} ____exports.__result = (function() @@ -543,3 +634,22 @@ return ____exports" `; exports[`Unsupported bitop 5.3 ("a>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Right shift operator is not supported for target Lua 5.3. Use \`>>>\` instead."`; + +exports[`Unsupported bitop 5.4 ("a>>=b"): code 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a >> b + return a +end)() +return ____exports" +`; + +exports[`Unsupported bitop 5.4 ("a>>=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Right shift operator is not supported for target Lua 5.3. Use \`>>>\` instead."`; + +exports[`Unsupported bitop 5.4 ("a>>b"): code 1`] = ` +"local ____exports = {} +____exports.__result = a >> b +return ____exports" +`; + +exports[`Unsupported bitop 5.4 ("a>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Right shift operator is not supported for target Lua 5.3. Use \`>>>\` instead."`; diff --git a/test/unit/__snapshots__/file.spec.ts.snap b/test/unit/__snapshots__/file.spec.ts.snap new file mode 100644 index 000000000..12a004c6c --- /dev/null +++ b/test/unit/__snapshots__/file.spec.ts.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`shebang CRLF 1`] = ` +"#!/usr/bin/env lua +foo = true" +`; + +exports[`shebang LF 1`] = ` +"#!/usr/bin/env lua +foo = true" +`; diff --git a/test/unit/__snapshots__/identifiers.spec.ts.snap b/test/unit/__snapshots__/identifiers.spec.ts.snap index 6ab8a4433..d955068e5 100644 --- a/test/unit/__snapshots__/identifiers.spec.ts.snap +++ b/test/unit/__snapshots__/identifiers.spec.ts.snap @@ -128,6 +128,14 @@ exports[`ambient identifier must be a valid lua identifier (object literal short exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'ɥɣɎɌͼƛಠ'. Ambient identifiers must be valid lua identifiers."`; +exports[`declaration-only variable with lua keyword as name is not renamed 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + type(7) +end +return ____exports" +`; + exports[`undeclared identifier must be a valid lua identifier ("$$"): code 1`] = `"foo = _____24_24_24"`; exports[`undeclared identifier must be a valid lua identifier ("$$"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; diff --git a/test/unit/__snapshots__/spread.spec.ts.snap b/test/unit/__snapshots__/spread.spec.ts.snap new file mode 100644 index 000000000..0b49fd80a --- /dev/null +++ b/test/unit/__snapshots__/spread.spec.ts.snap @@ -0,0 +1,175 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`vararg spread optimization $multi 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function multi(self, ...) + return ... + end + local function test(self, ...) + return select( + 2, + multi(nil, ...) + ) + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization basic use 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(self, ...) + return pick(nil, ...) + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization block statement 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(self, ...) + local result + do + result = pick(nil, ...) + end + return result + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization body-less arrow function 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(____, ...) + return pick(nil, ...) + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization curry 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function test(self, fn, ...) + return fn(nil, ...) + end + return test( + nil, + function(____, arg) return arg end, + \\"foobar\\" + ) +end +return ____exports" +`; + +exports[`vararg spread optimization curry with indirect type 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function test(self, obj, ...) + local fn = obj.fn + return fn(nil, ...) + end + return test( + nil, + { + fn = function(____, arg) return arg end + }, + \\"foobar\\" + ) +end +return ____exports" +`; + +exports[`vararg spread optimization finally clause 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(self, ...) + do + pcall( + function() + error(\\"foobar\\", 0) + end + ) + do + return pick(nil, ...) + end + end + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization function type declared inside scope 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function test(self, ...) + local function fn(____, ...) + local args = {...} + return args[1] + end + return fn(nil, ...) + end + test(nil, \\"foobar\\") +end +return ____exports" +`; + +exports[`vararg spread optimization if statement 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(self, ...) + if true then + return pick(nil, ...) + end + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization loop statement 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(self, ...) + repeat + do + return pick(nil, ...) + end + until not false + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; diff --git a/test/unit/__snapshots__/conditionals.spec.ts.snap b/test/unit/__snapshots__/switch.spec.ts.snap similarity index 97% rename from test/unit/__snapshots__/conditionals.spec.ts.snap rename to test/unit/__snapshots__/switch.spec.ts.snap index e7d003fa5..19a763566 100644 --- a/test/unit/__snapshots__/conditionals.spec.ts.snap +++ b/test/unit/__snapshots__/switch.spec.ts.snap @@ -1,6 +1,18 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`array 1`] = ` +exports[`switch not allowed in 5.1: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local ____switch3 = \\"abc\\" + goto ____switch3_end + ::____switch3_end:: +end +return ____exports" +`; + +exports[`switch not allowed in 5.1: diagnostics 1`] = `"main.ts(2,9): error TSTL: Switch statements is/are not supported for target Lua 5.1."`; + +exports[`switch uses elseif 1`] = ` "local ____exports = {} function ____exports.__main(self) local result = -1 @@ -39,15 +51,3 @@ function ____exports.__main(self) end return ____exports" `; - -exports[`switch not allowed in 5.1: code 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local ____switch3 = \\"abc\\" - goto ____switch3_end - ::____switch3_end:: -end -return ____exports" -`; - -exports[`switch not allowed in 5.1: diagnostics 1`] = `"main.ts(2,9): error TSTL: Switch statements is/are not supported for target Lua 5.1."`; diff --git a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap new file mode 100644 index 000000000..6dacea3ad --- /dev/null +++ b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap @@ -0,0 +1,149 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`LuaTable deprecation warning property access set: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + return tbl:set(\\"foo\\", 0) +end +return ____exports" +`; + +exports[`LuaTable deprecation warning property access set: diagnostics 1`] = `"main.ts(12,16): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; + +exports[`LuaTable removed warning constructor: code 1`] = ` +"require(\\"lualib_bundle\\"); +____table = __TS__New(Table)" +`; + +exports[`LuaTable removed warning constructor: diagnostics 1`] = `"main.ts(11,15): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; + +exports[`LuaTable removed warning property access get: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + return tbl:get(\\"foo\\") +end +return ____exports" +`; + +exports[`LuaTable removed warning property access get: diagnostics 1`] = `"main.ts(12,16): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; + +exports[`LuaTable removed warning property access length: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + return tbl.length +end +return ____exports" +`; + +exports[`LuaTable removed warning property access length: diagnostics 1`] = `"main.ts(12,16): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; + +exports[`extension removed: code 1`] = ` +"require(\\"lualib_bundle\\"); +B = __TS__Class() +B.name = \\"B\\" +__TS__ClassExtends(B, A)" +`; + +exports[`extension removed: code 2`] = ` +"require(\\"lualib_bundle\\"); +B = __TS__Class() +B.name = \\"B\\" +__TS__ClassExtends(B, A)" +`; + +exports[`extension removed: diagnostics 1`] = `"main.ts(4,9): error TSTL: '@extension' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information."`; + +exports[`extension removed: diagnostics 2`] = `"main.ts(4,9): error TSTL: '@metaExtension' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information."`; + +exports[`forRange removed: code 1`] = `""`; + +exports[`forRange removed: diagnostics 1`] = `"main.ts(4,25): error TSTL: '@forRange' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#forrange for more information."`; + +exports[`luaiterator removed: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local arr = {\\"a\\", \\"b\\", \\"c\\"} + local function luaIter(self) + local i = 0 + return function() return arr[(function() + local ____tmp = i + i = ____tmp + 1 + return ____tmp + end)() + 1] end + end + local result = \\"\\" + return result +end +return ____exports" +`; + +exports[`luaiterator removed: diagnostics 1`] = `"main.ts(10,23): error TSTL: '@luaIterator' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luaiterator for more information."`; + +exports[`phantom removed: code 1`] = ` +"A = A or ({}) +do + local function nsMember(self) + end +end" +`; + +exports[`phantom removed: diagnostics 1`] = `"main.ts(3,9): error TSTL: '@phantom' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#phantom for more information."`; + +exports[`pureAbstract removed: code 1`] = ` +"require(\\"lualib_bundle\\"); +ClassB = __TS__Class() +ClassB.name = \\"ClassB\\" +__TS__ClassExtends(ClassB, ClassA)" +`; + +exports[`pureAbstract removed: diagnostics 1`] = `"main.ts(4,22): error TSTL: '@pureAbstract' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#pureabstract for more information."`; + +exports[`tuplereturn lambda: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function f() + return {3, 4} + end +end +return ____exports" +`; + +exports[`tuplereturn lambda: diagnostics 1`] = `"main.ts(2,39): error TSTL: '@tupleReturn' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#tuplereturn for more information."`; + +exports[`tuplereturn removed on function declaration: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function tuple(self) + return {3, 5, 1} + end +end +return ____exports" +`; + +exports[`tuplereturn removed on function declaration: diagnostics 1`] = `"main.ts(3,9): error TSTL: '@tupleReturn' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#tuplereturn for more information."`; + +exports[`tuplereturn removed: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function tuple(self) + return {3, 5, 1} + end + return tuple(nil)[3] +end +return ____exports" +`; + +exports[`tuplereturn removed: diagnostics 1`] = ` +"main.ts(3,9): error TSTL: '@tupleReturn' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#tuplereturn for more information. +main.ts(4,16): error TSTL: '@tupleReturn' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#tuplereturn for more information." +`; + +exports[`vararg removed: code 1`] = ` +"function foo(self, ...) +end +function vararg(self, ...) + foo(_G, ...) +end" +`; + +exports[`vararg removed: diagnostics 1`] = `"main.ts(6,17): error TSTL: '@vararg' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#vararg for more information."`; diff --git a/test/unit/annotations/__snapshots__/extension.spec.ts.snap b/test/unit/annotations/__snapshots__/extension.spec.ts.snap deleted file mode 100644 index f69a1315a..000000000 --- a/test/unit/annotations/__snapshots__/extension.spec.ts.snap +++ /dev/null @@ -1,50 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Class construct extension ("extension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -b = __TS__New(B)" -`; - -exports[`Class construct extension ("extension"): diagnostics 1`] = `"main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation."`; - -exports[`Class construct extension ("metaExtension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -local __meta__A = debug.getregistry().A -b = __TS__New(B)" -`; - -exports[`Class construct extension ("metaExtension"): diagnostics 1`] = `"main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation."`; - -exports[`Class extends extension ("extension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -C = __TS__Class() -C.name = \\"C\\" -__TS__ClassExtends(C, B)" -`; - -exports[`Class extends extension ("extension"): diagnostics 1`] = `"main.ts(5,9): error TSTL: Cannot extend classes with '@extension' or '@metaExtension' annotation."`; - -exports[`Class extends extension ("metaExtension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -local __meta__A = debug.getregistry().A -C = __TS__Class() -C.name = \\"C\\" -__TS__ClassExtends(C, B)" -`; - -exports[`Class extends extension ("metaExtension"): diagnostics 1`] = `"main.ts(5,9): error TSTL: Cannot extend classes with '@extension' or '@metaExtension' annotation."`; - -exports[`instanceof extension ("extension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -result = __TS__InstanceOf(foo, B)" -`; - -exports[`instanceof extension ("extension"): diagnostics 1`] = `"main.ts(6,24): error TSTL: Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation."`; - -exports[`instanceof extension ("metaExtension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -local __meta__A = debug.getregistry().A -result = __TS__InstanceOf(foo, B)" -`; - -exports[`instanceof extension ("metaExtension"): diagnostics 1`] = `"main.ts(6,24): error TSTL: Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation."`; diff --git a/test/unit/annotations/__snapshots__/forRange.spec.ts.snap b/test/unit/annotations/__snapshots__/forRange.spec.ts.snap deleted file mode 100644 index e752d0782..000000000 --- a/test/unit/annotations/__snapshots__/forRange.spec.ts.snap +++ /dev/null @@ -1,89 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`invalid usage argument count ([]): code 1`] = ` -"for i = 0, 0 do -end" -`; - -exports[`invalid usage argument count ([]): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: Expected 2-3 arguments, but got 0."`; - -exports[`invalid usage argument count ([1, 2, 3, 4]): code 1`] = ` -"for i = 1, 2, 3 do -end" -`; - -exports[`invalid usage argument count ([1, 2, 3, 4]): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: Expected 2-3 arguments, but got 4."`; - -exports[`invalid usage argument count ([1]): code 1`] = ` -"for i = 1, 0 do -end" -`; - -exports[`invalid usage argument count ([1]): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: Expected 2-3 arguments, but got 1."`; - -exports[`invalid usage argument types: code 1`] = ` -"for i = \\"foo\\", 2 do -end" -`; - -exports[`invalid usage argument types: diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: arguments must be numbers."`; - -exports[`invalid usage non-ambient declaration: code 1`] = ` -"function luaRange(self) -end" -`; - -exports[`invalid usage non-ambient declaration: diagnostics 1`] = `"main.ts(3,22): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage non-declared loop variable: code 1`] = ` -"for ____ = 1, 10, 2 do -end" -`; - -exports[`invalid usage non-declared loop variable: diagnostics 1`] = `"main.ts(7,18): error TSTL: Invalid @forRange call: loop must declare it's own control variable."`; - -exports[`invalid usage reference ("const call = undefined as any; call(luaRange);"): code 1`] = ` -"call = nil -call(_G, luaRange)" -`; - -exports[`invalid usage reference ("const call = undefined as any; call(luaRange);"): diagnostics 1`] = `"main.ts(6,49): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage reference ("const range = luaRange(1, 10);"): code 1`] = `"range = luaRange(_G, 1, 10)"`; - -exports[`invalid usage reference ("const range = luaRange(1, 10);"): diagnostics 1`] = `"main.ts(6,27): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage reference ("for (const i of [...luaRange(1, 10)]) {}"): code 1`] = ` -"for ____, i in ipairs( - { - table.unpack( - luaRange(_G, 1, 10) - ) - } -) do -end" -`; - -exports[`invalid usage reference ("for (const i of [...luaRange(1, 10)]) {}"): diagnostics 1`] = `"main.ts(6,33): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage reference ("let array = [0, luaRange, 1];"): code 1`] = `"array = {0, luaRange, 1}"`; - -exports[`invalid usage reference ("let array = [0, luaRange, 1];"): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage reference ("luaRange.call(null, 0, 0, 0);"): code 1`] = `"luaRange(nil, 0, 0, 0)"`; - -exports[`invalid usage reference ("luaRange.call(null, 0, 0, 0);"): diagnostics 1`] = `"main.ts(6,13): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage return type: code 1`] = ` -"for i = 1, 10 do -end" -`; - -exports[`invalid usage return type: diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: function must return Iterable."`; - -exports[`invalid usage variable destructuring: code 1`] = ` -"for ____ = 1, 10, 2 do -end" -`; - -exports[`invalid usage variable destructuring: diagnostics 1`] = `"main.ts(6,18): error TSTL: Invalid @forRange call: destructuring cannot be used."`; diff --git a/test/unit/annotations/__snapshots__/luaIterator.spec.ts.snap b/test/unit/annotations/__snapshots__/luaIterator.spec.ts.snap deleted file mode 100644 index 24761ca3a..000000000 --- a/test/unit/annotations/__snapshots__/luaIterator.spec.ts.snap +++ /dev/null @@ -1,15 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`forof lua iterator tuple-return single existing variable: code 1`] = ` -"for ____ in luaIter(_G) do -end" -`; - -exports[`forof lua iterator tuple-return single existing variable: diagnostics 1`] = `"main.ts(9,14): error TSTL: Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. You must use a destructuring statement to catch results from a lua iterator with the '@tupleReturn' annotation."`; - -exports[`forof lua iterator tuple-return single variable: code 1`] = ` -"for ____ in luaIter(_G) do -end" -`; - -exports[`forof lua iterator tuple-return single variable: diagnostics 1`] = `"main.ts(8,18): error TSTL: Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. You must use a destructuring statement to catch results from a lua iterator with the '@tupleReturn' annotation."`; diff --git a/test/unit/annotations/__snapshots__/luaTable.spec.ts.snap b/test/unit/annotations/__snapshots__/luaTable.spec.ts.snap deleted file mode 100644 index fae2b1f20..000000000 --- a/test/unit/annotations/__snapshots__/luaTable.spec.ts.snap +++ /dev/null @@ -1,197 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Cannot extend LuaTable class ("class Ext extends Table {}"): code 1`] = ` -"require(\\"lualib_bundle\\"); -Ext = __TS__Class() -Ext.name = \\"Ext\\" -__TS__ClassExtends(Ext, Table)" -`; - -exports[`Cannot extend LuaTable class ("class Ext extends Table {}"): diagnostics 1`] = `"main.ts(11,19): error TSTL: Cannot extend classes with the '@luaTable' annotation."`; - -exports[`Cannot extend LuaTable class ("const c = class Ext extends Table {}"): code 1`] = ` -"require(\\"lualib_bundle\\"); -c = (function() - local Ext = __TS__Class() - Ext.name = \\"Ext\\" - __TS__ClassExtends(Ext, Table) - return Ext -end)()" -`; - -exports[`Cannot extend LuaTable class ("const c = class Ext extends Table {}"): diagnostics 1`] = `"main.ts(11,29): error TSTL: Cannot extend classes with the '@luaTable' annotation."`; - -exports[`Cannot isolate LuaTable method ("get"): code 1`] = `"property = tbl.get"`; - -exports[`Cannot isolate LuaTable method ("get"): code 2`] = `"property = tbl.get"`; - -exports[`Cannot isolate LuaTable method ("get"): diagnostics 1`] = `"main.ts(11,21): error TSTL: LuaTable.get is unsupported."`; - -exports[`Cannot isolate LuaTable method ("get"): diagnostics 2`] = `"main.ts(13,21): error TSTL: LuaTable.get is unsupported."`; - -exports[`Cannot isolate LuaTable method ("set"): code 1`] = `"property = tbl.set"`; - -exports[`Cannot isolate LuaTable method ("set"): code 2`] = `"property = tbl.set"`; - -exports[`Cannot isolate LuaTable method ("set"): diagnostics 1`] = `"main.ts(11,21): error TSTL: LuaTable.set is unsupported."`; - -exports[`Cannot isolate LuaTable method ("set"): diagnostics 2`] = `"main.ts(13,21): error TSTL: LuaTable.set is unsupported."`; - -exports[`Cannot set LuaTable length: code 1`] = `"tbl.length = 2"`; - -exports[`Cannot set LuaTable length: code 2`] = `"tbl.length = 2"`; - -exports[`Cannot set LuaTable length: diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: A LuaTable object's length cannot be re-assigned."`; - -exports[`Cannot set LuaTable length: diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: A LuaTable object's length cannot be re-assigned."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"get\\"](\\"field\\")"): code 1`] = `"tbl.get(tbl, \\"field\\")"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"get\\"](\\"field\\")"): code 2`] = `"tbl.get(tbl, \\"field\\")"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"get\\"](\\"field\\")"): diagnostics 1`] = `"main.ts(11,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"get\\"](\\"field\\")"): diagnostics 2`] = `"main.ts(13,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"length\\"]"): code 1`] = `"local ____ = tbl.length"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"length\\"]"): code 2`] = `"local ____ = tbl.length"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"length\\"]"): diagnostics 1`] = `"main.ts(11,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"length\\"]"): diagnostics 2`] = `"main.ts(13,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"set\\"](\\"field\\")"): code 1`] = `"tbl.set(tbl, \\"field\\")"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"set\\"](\\"field\\")"): code 2`] = `"tbl.set(tbl, \\"field\\")"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"set\\"](\\"field\\")"): diagnostics 1`] = `"main.ts(11,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"set\\"](\\"field\\")"): diagnostics 2`] = `"main.ts(13,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use instanceof on a LuaTable class ("tbl instanceof Table"): code 1`] = ` -"require(\\"lualib_bundle\\"); -__TS__InstanceOf(tbl, Table)" -`; - -exports[`Cannot use instanceof on a LuaTable class ("tbl instanceof Table"): diagnostics 1`] = `"main.ts(11,1): error TSTL: The instanceof operator cannot be used with a '@luaTable' class."`; - -exports[`Forbidden LuaTable use ("tbl.get()"): code 1`] = `"local ____ = tbl[nil]"`; - -exports[`Forbidden LuaTable use ("tbl.get()"): code 2`] = `"local ____ = tbl[nil]"`; - -exports[`Forbidden LuaTable use ("tbl.get()"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 1 arguments, but got 0."`; - -exports[`Forbidden LuaTable use ("tbl.get()"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 1 arguments, but got 0."`; - -exports[`Forbidden LuaTable use ("tbl.get(\\"field\\", \\"field2\\")"): code 1`] = `"local ____ = tbl.field"`; - -exports[`Forbidden LuaTable use ("tbl.get(\\"field\\", \\"field2\\")"): code 2`] = `"local ____ = tbl.field"`; - -exports[`Forbidden LuaTable use ("tbl.get(\\"field\\", \\"field2\\")"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 1 arguments, but got 2."`; - -exports[`Forbidden LuaTable use ("tbl.get(\\"field\\", \\"field2\\")"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 1 arguments, but got 2."`; - -exports[`Forbidden LuaTable use ("tbl.set()"): code 1`] = `"tbl[nil] = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set()"): code 2`] = `"tbl[nil] = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set()"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 0."`; - -exports[`Forbidden LuaTable use ("tbl.set()"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 0."`; - -exports[`Forbidden LuaTable use ("tbl.set(...([\\"field\\", 0] as const))"): code 1`] = `"tbl[table.unpack({\\"field\\", 0})] = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set(...([\\"field\\", 0] as const))"): code 2`] = `"tbl[table.unpack({\\"field\\", 0})] = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set(...([\\"field\\", 0] as const))"): diagnostics 1`] = `"main.ts(11,9): error TSTL: Invalid @luaTable usage: Arguments cannot be spread."`; - -exports[`Forbidden LuaTable use ("tbl.set(...([\\"field\\", 0] as const))"): diagnostics 2`] = `"main.ts(13,9): error TSTL: Invalid @luaTable usage: Arguments cannot be spread."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\")"): code 1`] = `"tbl.field = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\")"): code 2`] = `"tbl.field = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\")"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 1."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\")"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 1."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", ...([0] as const))"): code 1`] = `"tbl.field = table.unpack({0})"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", ...([0] as const))"): code 2`] = `"tbl.field = table.unpack({0})"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", ...([0] as const))"): diagnostics 1`] = `"main.ts(11,18): error TSTL: Invalid @luaTable usage: Arguments cannot be spread."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", ...([0] as const))"): diagnostics 2`] = `"main.ts(13,18): error TSTL: Invalid @luaTable usage: Arguments cannot be spread."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", 0, 1)"): code 1`] = `"tbl.field = 0"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", 0, 1)"): code 2`] = `"tbl.field = 0"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", 0, 1)"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 3."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", 0, 1)"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 3."`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ class Table {}"): code 1`] = ` -"require(\\"lualib_bundle\\"); -Table = __TS__Class() -Table.name = \\"Table\\" -function Table.prototype.____constructor(self) -end" -`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ class Table {}"): diagnostics 1`] = `"main.ts(1,18): error TSTL: Classes with the '@luaTable' annotation must be ambient."`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ const c = class Table {}"): code 1`] = ` -"require(\\"lualib_bundle\\"); -c = (function() - local Table = __TS__Class() - Table.name = \\"Table\\" - function Table.prototype.____constructor(self) - end - return Table -end)()" -`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ const c = class Table {}"): diagnostics 1`] = `"main.ts(1,28): error TSTL: Classes with the '@luaTable' annotation must be ambient."`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ export class Table {}"): code 1`] = ` -"require(\\"lualib_bundle\\"); -local ____exports = {} -____exports.Table = __TS__Class() -local Table = ____exports.Table -Table.name = \\"Table\\" -function Table.prototype.____constructor(self) -end -return ____exports" -`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ export class Table {}"): diagnostics 1`] = `"main.ts(1,18): error TSTL: Classes with the '@luaTable' annotation must be ambient."`; - -exports[`LuaTable set() cannot be used in a LuaTable call expression: code 1`] = `"exp = tbl:set(\\"value\\", 5)"`; - -exports[`LuaTable set() cannot be used in a LuaTable call expression: code 2`] = `"exp = tbl:set(\\"value\\", 5)"`; - -exports[`LuaTable set() cannot be used in a LuaTable call expression: diagnostics 1`] = `"main.ts(11,17): error TSTL: LuaTable.set is unsupported."`; - -exports[`LuaTable set() cannot be used in a LuaTable call expression: diagnostics 2`] = `"main.ts(13,17): error TSTL: LuaTable.set is unsupported."`; - -exports[`LuaTables cannot be constructed with arguments: code 1`] = `"____table = {}"`; - -exports[`LuaTables cannot be constructed with arguments: diagnostics 1`] = `"main.ts(11,15): error TSTL: Invalid @luaTable usage: No parameters are allowed when constructing a LuaTable object."`; - -exports[`LuaTables cannot have other members: code 1`] = `"tbl:other()"`; - -exports[`LuaTables cannot have other members: code 2`] = `"tbl:other()"`; - -exports[`LuaTables cannot have other members: code 3`] = `"x = tbl:other()"`; - -exports[`LuaTables cannot have other members: code 4`] = `"x = tbl:other()"`; - -exports[`LuaTables cannot have other members: diagnostics 1`] = `"main.ts(11,5): error TSTL: LuaTable.other is unsupported."`; - -exports[`LuaTables cannot have other members: diagnostics 2`] = `"main.ts(13,5): error TSTL: LuaTable.other is unsupported."`; - -exports[`LuaTables cannot have other members: diagnostics 3`] = `"main.ts(11,13): error TSTL: LuaTable.other is unsupported."`; - -exports[`LuaTables cannot have other members: diagnostics 4`] = `"main.ts(13,13): error TSTL: LuaTable.other is unsupported."`; diff --git a/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap b/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap deleted file mode 100644 index ba6b5e0a1..000000000 --- a/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap +++ /dev/null @@ -1,17 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`DontAllowInstantiation: code 1`] = ` -"require(\\"lualib_bundle\\"); -local __meta___LOADED = debug.getregistry()._LOADED -e = __TS__New(Ext)" -`; - -exports[`DontAllowInstantiation: diagnostics 1`] = `"main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation."`; - -exports[`IncorrectUsage: code 1`] = ` -"function LoadedExt.test(self) - return 5 -end" -`; - -exports[`IncorrectUsage: diagnostics 1`] = `"main.ts(3,9): error TSTL: '@metaExtension' annotation requires the extension of the metatable class."`; diff --git a/test/unit/annotations/customConstructor.spec.ts b/test/unit/annotations/customConstructor.spec.ts index 007c64c3f..86858f700 100644 --- a/test/unit/annotations/customConstructor.spec.ts +++ b/test/unit/annotations/customConstructor.spec.ts @@ -19,9 +19,12 @@ test("CustomCreate", () => { } `; - const result = util.transpileAndExecute("return new Point2D(1, 2).x;", undefined, luaHeader, tsHeader); - - expect(result).toBe(1); + // Can't use expectToMatchJsResult because above is not valid TS/JS + util.testModule`export default new Point2D(1, 2).x;` + .setTsHeader(tsHeader) + .setLuaHeader(luaHeader) + .setReturnExport("default") + .expectToEqual(1); }); test("IncorrectUsage", () => { diff --git a/test/unit/annotations/deprecated.spec.ts b/test/unit/annotations/deprecated.spec.ts new file mode 100644 index 000000000..f7f0ac9b1 --- /dev/null +++ b/test/unit/annotations/deprecated.spec.ts @@ -0,0 +1,124 @@ +import { annotationRemoved } from "../../../src/transformation/utils/diagnostics"; +import * as util from "../../util"; + +test.each(["extension", "metaExtension"])("extension removed", extensionType => { + util.testModule` + declare class A {} + /** @${extensionType} **/ + class B extends A {} + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("phantom removed", () => { + util.testModule` + /** @phantom **/ + namespace A { + function nsMember() {} + } + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("pureAbstract removed", () => { + util.testModule` + /** @pureAbstract */ + declare class ClassA {} + class ClassB extends ClassA {} + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("forRange removed", () => { + util.testModule` + /** @forRange */ + declare function forRange(start: number, limit: number, step?: number): number[]; + for (const i of forRange(1, 10)) {} + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("vararg removed", () => { + util.testModule` + /** @vararg */ + type VarArg = T & { readonly __brand: unique symbol }; + function foo(...args: any[]) {} + function vararg(...args: VarArg) { + foo(...args); + } + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("luaiterator removed", () => { + util.testFunction` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + interface Iter extends Iterable {} + function luaIter(): Iter { + let i = 0; + return (() => arr[i++]) as any; + } + let result = ""; + for (let e of luaIter()) { result += e; } + return result; + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("tuplereturn removed", () => { + util.testFunction` + /** @tupleReturn */ + function tuple(): [number, number, number] { return [3, 5, 1]; } + return tuple()[2]; + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code, annotationRemoved.code]); // One annotation on the function, one on the call +}); + +test("tuplereturn removed on function declaration", () => { + util.testFunction` + /** @tupleReturn */ + function tuple(): [number, number, number] { return [3, 5, 1]; } + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("tuplereturn lambda", () => { + util.testFunction` + const f = /** @tupleReturn */ () => [3, 4]; + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +const tableLibClass = ` +/** @luaTable */ +declare class Table { + length: number; + constructor(notAllowed?: any); + set(key?: K, value?: V, notAllowed?: any): void; + get(key?: K, notAllowed?: any): V; + other(): void; +} +declare let tbl: Table; +`; + +test("LuaTable removed warning constructor", () => { + util.testModule("const table = new Table();") + .setTsHeader(tableLibClass) + .expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("LuaTable removed warning property access length", () => { + util.testFunction` + return tbl.length; + ` + .setTsHeader(tableLibClass) + .expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("LuaTable removed warning property access get", () => { + util.testFunction` + return tbl.get("foo"); + ` + .setTsHeader(tableLibClass) + .expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("LuaTable deprecation warning property access set", () => { + util.testFunction` + return tbl.set("foo", 0); + ` + .setTsHeader(tableLibClass) + .expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); diff --git a/test/unit/annotations/extension.spec.ts b/test/unit/annotations/extension.spec.ts deleted file mode 100644 index c8da1b81b..000000000 --- a/test/unit/annotations/extension.spec.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { - extensionCannotConstruct, - extensionCannotExtend, - extensionInvalidInstanceOf, -} from "../../../src/transformation/utils/diagnostics"; -import * as util from "../../util"; - -test.each(["extension", "metaExtension"])("Class extends extension (%p)", extensionType => { - util.testModule` - declare class A {} - /** @${extensionType} **/ - class B extends A {} - class C extends B {} - `.expectDiagnosticsToMatchSnapshot([extensionCannotExtend.code]); -}); - -test.each(["extension", "metaExtension"])("Class construct extension (%p)", extensionType => { - util.testModule` - declare class A {} - /** @${extensionType} **/ - class B extends A {} - const b = new B(); - `.expectDiagnosticsToMatchSnapshot([extensionCannotConstruct.code]); -}); - -test.each(["extension", "metaExtension"])("instanceof extension (%p)", extensionType => { - util.testModule` - declare class A {} - /** @${extensionType} **/ - class B extends A {} - declare const foo: any; - const result = foo instanceof B; - `.expectDiagnosticsToMatchSnapshot([extensionInvalidInstanceOf.code]); -}); diff --git a/test/unit/annotations/forRange.spec.ts b/test/unit/annotations/forRange.spec.ts deleted file mode 100644 index 661c45253..000000000 --- a/test/unit/annotations/forRange.spec.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { invalidForRangeCall } from "../../../src/transformation/utils/diagnostics"; -import * as util from "../../util"; - -const createForRangeDeclaration = (args = "i: number, j: number, k?: number", returns = "number[]") => ` - /** @forRange */ - declare function luaRange(${args}): ${returns}; -`; - -test.each([ - { args: [1, 10], results: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }, - { args: [1, 10, 2], results: [1, 3, 5, 7, 9] }, - { args: [10, 1, -1], results: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] }, - { args: [10, 1, -2], results: [10, 8, 6, 4, 2] }, -])("usage in for...of loop", ({ args, results }) => { - util.testModule` - ${createForRangeDeclaration()} - export const results: number[] = []; - - for (const i of luaRange(${args})) { - results.push(i); - } - ` - .setReturnExport("results") - .expectToEqual(results); -}); - -describe("invalid usage", () => { - test("non-ambient declaration", () => { - util.testModule` - /** @forRange */ - function luaRange() {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test.each<[number[]]>([[[]], [[1]], [[1, 2, 3, 4]]])("argument count (%p)", args => { - util.testModule` - ${createForRangeDeclaration("...args: number[]")} - for (const i of luaRange(${args})) {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test("non-declared loop variable", () => { - util.testModule` - ${createForRangeDeclaration()} - let i: number; - for (i of luaRange(1, 10, 2)) {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test("argument types", () => { - util.testModule` - ${createForRangeDeclaration("i: string, j: number")} - for (const i of luaRange("foo", 2)) {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test("variable destructuring", () => { - util.testModule` - ${createForRangeDeclaration(undefined, "number[][]")} - for (const [i] of luaRange(1, 10, 2)) {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test("return type", () => { - util.testModule` - ${createForRangeDeclaration(undefined, "string[]")} - for (const i of luaRange(1, 10)) {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test.each([ - "const range = luaRange(1, 10);", - "luaRange.call(null, 0, 0, 0);", - "let array = [0, luaRange, 1];", - "const call = undefined as any; call(luaRange);", - "for (const i of [...luaRange(1, 10)]) {}", - ])("reference (%p)", statement => { - util.testModule` - ${createForRangeDeclaration()} - ${statement} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); -}); diff --git a/test/unit/annotations/luaIterator.spec.ts b/test/unit/annotations/luaIterator.spec.ts deleted file mode 100644 index 46e324bc5..000000000 --- a/test/unit/annotations/luaIterator.spec.ts +++ /dev/null @@ -1,209 +0,0 @@ -import * as util from "../../util"; -import { luaIteratorForbiddenUsage } from "../../../src/transformation/utils/diagnostics"; - -test("forof lua iterator", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i++]) as any; - } - let result = ""; - for (let e of luaIter()) { result += e; } - return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("abc"); -}); - -test("forof array lua iterator", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Array {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i++]) as any; - } - let result = ""; - for (let e of luaIter()) { result += e; } - return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("abc"); -}); - -test("forof lua iterator with existing variable", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i++]) as any; - } - let result = ""; - let e: string; - for (e of luaIter()) { result += e; } - return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("abc"); -}); - -test("forof lua iterator destructuring", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i] && [i.toString(), arr[i++]]) as any; - } - let result = ""; - for (let [a, b] of luaIter()) { result += a + b; } - return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("0a1b2c"); -}); - -test("forof lua iterator destructuring with existing variables", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i] && [i.toString(), arr[i++]]) as any; - } - let result = ""; - let a: string; - let b: string; - for ([a, b] of luaIter()) { result += a + b; } - return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("0a1b2c"); -}); - -test("forof lua iterator tuple-return", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - /** @tupleReturn */ - function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } - return iter as any; - } - let result = ""; - for (let [a, b] of luaIter()) { result += a + b; } - return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("0a1b2c"); -}); - -test("forof lua iterator tuple-return with existing variables", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - /** @tupleReturn */ - function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } - return iter as any; - } - let result = ""; - let a: string; - let b: string; - for ([a, b] of luaIter()) { result += a + b; } - return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("0a1b2c"); -}); - -test("forof lua iterator tuple-return single variable", () => { - util.testModule` - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - declare function luaIter(): Iter; - for (let x of luaIter()) {} - `.expectDiagnosticsToMatchSnapshot([luaIteratorForbiddenUsage.code]); -}); - -test("forof lua iterator tuple-return single existing variable", () => { - util.testModule` - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - declare function luaIter(): Iter; - let x: [string, string]; - for (x of luaIter()) {} - `.expectDiagnosticsToMatchSnapshot([luaIteratorForbiddenUsage.code]); -}); - -test("forof forwarded lua iterator", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let i = 0; - function iter() { return arr[i++]; } - return iter as any; - } - function forward() { - const iter = luaIter(); - return iter; - } - let result = ""; - for (let a of forward()) { result += a; } - return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("abc"); -}); - -test("forof forwarded lua iterator with tupleReturn", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - /** @tupleReturn */ - function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } - return iter as any; - } - function forward() { - const iter = luaIter(); - return iter; - } - let result = ""; - for (let [a, b] of forward()) { result += a + b; } - return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("0a1b2c"); -}); diff --git a/test/unit/annotations/luaTable.spec.ts b/test/unit/annotations/luaTable.spec.ts deleted file mode 100644 index 8829938bb..000000000 --- a/test/unit/annotations/luaTable.spec.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { - luaTableCannotBeAccessedDynamically, - luaTableCannotBeExtended, - luaTableForbiddenUsage, - luaTableMustBeAmbient, - unsupportedProperty, - luaTableInvalidInstanceOf, -} from "../../../src/transformation/utils/diagnostics"; -import * as util from "../../util"; - -const tableLibClass = ` -/** @luaTable */ -declare class Table { - length: number; - constructor(notAllowed?: any); - set(key?: K, value?: V, notAllowed?: any): void; - get(key?: K, notAllowed?: any): V; - other(): void; -} -declare let tbl: Table; -`; - -const tableLibInterface = ` -/** @luaTable */ -declare interface Table { - length: number; - set(key?: K, value?: V, notAllowed?: any): void; - get(key?: K, notAllowed?: any): V; - other(): void; -} - -/** @luaTable */ -declare const Table: new (notAllowed?: any) => Table; -declare let tbl: Table; -`; - -test.each([tableLibClass])("LuaTables cannot be constructed with arguments", tableLib => { - util.testModule(tableLib + "const table = new Table(true);").expectDiagnosticsToMatchSnapshot([ - luaTableForbiddenUsage.code, - ]); -}); - -test.each([tableLibClass, tableLibInterface])( - "LuaTable set() cannot be used in a LuaTable call expression", - tableLib => { - util.testModule(tableLib + 'const exp = tbl.set("value", 5)').expectDiagnosticsToMatchSnapshot([ - unsupportedProperty.code, - ]); - } -); - -test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { - util.testModule(tableLib + "tbl.other()").expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); -}); - -test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { - util.testModule(tableLib + "let x = tbl.other()").expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); -}); - -test.each([tableLibClass])("LuaTable new", tableLib => { - const content = tableLib + "tbl = new Table();"; - expect(util.transpileString(content)).toEqual("tbl = {}"); -}); - -test.each([tableLibClass])("LuaTable length", tableLib => { - const content = tableLib + "tbl = new Table();\nreturn tbl.length;"; - const lua = util.transpileString(content); - expect(util.executeLua(lua)).toEqual(0); -}); - -test.each([tableLibClass, tableLibInterface])("Cannot set LuaTable length", tableLib => { - util.testModule(tableLib + "tbl.length = 2;").expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); -}); - -test.each([tableLibClass, tableLibInterface])("Forbidden LuaTable use", tableLib => { - test.each([ - "tbl.get()", - 'tbl.get("field", "field2")', - "tbl.set()", - 'tbl.set("field")', - 'tbl.set("field", 0, 1)', - 'tbl.set(...(["field", 0] as const))', - 'tbl.set("field", ...([0] as const))', - ])("Forbidden LuaTable use (%p)", invalidCode => { - util.testModule(tableLib + invalidCode).expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); - }); -}); - -test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { - test.each(["class Ext extends Table {}", "const c = class Ext extends Table {}"])( - "Cannot extend LuaTable class (%p)", - code => { - util.testModule(tableLib + code).expectDiagnosticsToMatchSnapshot([luaTableCannotBeExtended.code]); - } - ); -}); - -test.each([ - "/** @luaTable */ class Table {}", - "/** @luaTable */ export class Table {}", - "/** @luaTable */ const c = class Table {}", -])("LuaTable classes must be ambient (%p)", code => { - util.testModule(code).expectDiagnosticsToMatchSnapshot([luaTableMustBeAmbient.code]); -}); - -test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { - test.each(["tbl instanceof Table"])("Cannot use instanceof on a LuaTable class (%p)", code => { - util.testModule(tableLib + code).expectDiagnosticsToMatchSnapshot([luaTableInvalidInstanceOf.code]); - }); -}); - -test.each([tableLibClass, tableLibInterface])("Cannot use ElementAccessExpression on a LuaTable", tableLib => { - test.each(['tbl["get"]("field")', 'tbl["set"]("field")', 'tbl["length"]'])( - "Cannot use ElementAccessExpression on a LuaTable (%p)", - code => { - util.testModule(tableLib + code).expectDiagnosticsToMatchSnapshot([ - luaTableCannotBeAccessedDynamically.code, - ]); - } - ); -}); - -test.each([tableLibClass, tableLibInterface])("Cannot isolate LuaTable methods", tableLib => { - test.each(["set", "get"])("Cannot isolate LuaTable method (%p)", propertyName => { - util.testModule(`${tableLib} let property = tbl.${propertyName}`).expectDiagnosticsToMatchSnapshot([ - unsupportedProperty.code, - ]); - }); -}); - -test.each([tableLibClass])("LuaTable functional tests", tableLib => { - test.each<[string, any]>([ - ['const t = new Table(); t.set("field", "value"); return t.get("field");', "value"], - ['const t = new Table(); t.set("field", 0); return t.get("field");', 0], - ["const t = new Table(); t.set(1, true); return t.length", 1], - ["const t = new Table(); t.set(t.length + 1, true); t.set(t.length + 1, true); return t.length", 2], - ['const k = "k"; const t = { data: new Table() }; t.data.set(k, 3); return t.data.get(k);', 3], - ])("LuaTable test (%p)", (code, expectedReturnValue) => { - expect(util.transpileAndExecute(code, undefined, undefined, tableLib)).toBe(expectedReturnValue); - }); -}); diff --git a/test/unit/annotations/metaExtension.spec.ts b/test/unit/annotations/metaExtension.spec.ts deleted file mode 100644 index 405eeee5a..000000000 --- a/test/unit/annotations/metaExtension.spec.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { extensionCannotConstruct, metaExtensionMissingExtends } from "../../../src/transformation/utils/diagnostics"; -import * as util from "../../util"; - -test("MetaExtension", () => { - const tsHeader = ` - declare class _LOADED {} - declare namespace debug { - function getregistry(): any; - } - /** @metaExtension */ - class LoadedExt extends _LOADED { - public static test() { - return 5; - } - } - `; - - const result = util.transpileAndExecute( - 'return debug.getregistry()["_LOADED"].test();', - undefined, - undefined, - tsHeader - ); - - expect(result).toBe(5); -}); - -test("IncorrectUsage", () => { - util.testModule` - /** @metaExtension */ - class LoadedExt { - public static test() { - return 5; - } - } - `.expectDiagnosticsToMatchSnapshot([metaExtensionMissingExtends.code]); -}); - -test("DontAllowInstantiation", () => { - util.testModule` - declare class _LOADED {} - /** @metaExtension */ - class Ext extends _LOADED {} - const e = new Ext(); - `.expectDiagnosticsToMatchSnapshot([extensionCannotConstruct.code]); -}); diff --git a/test/unit/annotations/tupleReturn.spec.ts b/test/unit/annotations/tupleReturn.spec.ts deleted file mode 100644 index 7c7c7ae9b..000000000 --- a/test/unit/annotations/tupleReturn.spec.ts +++ /dev/null @@ -1,443 +0,0 @@ -import * as util from "../../util"; - -const expectNoUnpack: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).not.toContain("unpack"); - -test("Tuple Return Access", () => { - util.testFunction` - /** @tupleReturn */ - function tuple(): [number, number, number] { return [3, 5, 1]; } - return tuple()[2]; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Return Destruct Declaration", () => { - util.testFunction` - /** @tupleReturn */ - function tuple(): [number, number, number] { return [3,5,1]; } - const [,b,c] = tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Return Destruct Assignment", () => { - util.testFunction` - /** @tupleReturn */ - function tuple(): [number, number] { return [3,6]; } - let [a,b] = [1,2]; - [b,a] = tuple(); - return a - b; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Static Method Return Destruct", () => { - util.testFunction` - class Test { - /** @tupleReturn */ - static tuple(): [number, number, number] { return [3,5,1]; } - } - const [a,b,c] = Test.tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Static Function Property Return Destruct", () => { - util.testFunction` - class Test { - /** @tupleReturn */ - static tuple: () => [number, number, number] = () => [3,5,1]; - } - const [a,b,c] = Test.tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Non-Static Method Return Destruct", () => { - util.testFunction` - class Test { - /** @tupleReturn */ - tuple(): [number, number, number] { return [3,5,1]; } - } - const t = new Test(); - const [a,b,c] = t.tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Non-Static Function Property Return Destruct", () => { - util.testFunction` - class Test { - /** @tupleReturn */ - tuple: () => [number, number, number] = () => [3,5,1]; - } - const t = new Test(); - const [a,b,c] = t.tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Interface Method Return Destruct", () => { - util.testFunction` - interface Test { - /** @tupleReturn */ - tuple(): [number, number, number]; - } - const t: Test = { - tuple() { return [3,5,1]; } - }; - const [a,b,c] = t.tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Interface Function Property Return Destruct", () => { - util.testFunction` - interface Test { - /** @tupleReturn */ - tuple: () => [number, number, number]; - } - const t: Test = { - tuple: () => [3,5,1] - }; - const [a,b,c] = t.tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Object Literal Method Return Destruct", () => { - util.testFunction` - const t = { - /** @tupleReturn */ - tuple() { return [3,5,1]; } - }; - const [a,b,c] = t.tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Object Literal Function Property Return Destruct", () => { - util.testFunction` - const t = { - /** @tupleReturn */ - tuple: () => [3,5,1] - }; - const [a,b,c] = t.tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Return on Arrow Function", () => { - util.testFunction` - const fn = /** @tupleReturn */ (s: string) => [s, "bar"]; - const [a, b] = fn("foo"); - return a + b; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Return Inference", () => { - util.testFunction` - /** @tupleReturn */ interface Fn { (s: string): [string, string] } - const fn: Fn = s => [s, "bar"]; - const [a, b] = fn("foo"); - return a + b; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Return Inference as Argument", () => { - util.testFunction` - /** @tupleReturn */ interface Fn { (s: string): [string, string] } - function foo(fn: Fn) { - const [a, b] = fn("foo"); - return a + b; - } - return foo(s => [s, "bar"]); - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Return Inference as Elipsis Argument", () => { - util.testFunction` - /** @tupleReturn */ interface Fn { (s: string): [string, string] } - function foo(_: number, ...fn: Fn[]) { - const [a, b] = fn[0]("foo"); - return a + b; - } - return foo(0, s => [s, "bar"]); - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Return Inference as Elipsis Tuple Argument", () => { - util.testFunction` - /** @tupleReturn */ interface Fn { (s: string): [string, string] } - function foo(_: number, ...fn: [number, Fn]) { - const [a, b] = fn[1]("foo"); - return a + b; - } - return foo(0, 0, s => [s, "bar"]); - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Return in Spread", () => { - util.testFunction` - /** @tupleReturn */ function foo(): [string, string] { - return ["foo", "bar"]; - } - function bar(a: string, b: string) { - return a + b; - } - return bar(...foo()); - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Return on Type Alias", () => { - util.testFunction` - /** @tupleReturn */ type Fn = () => [number, number]; - const fn: Fn = () => [1, 2]; - const [a, b] = fn(); - return a + b; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Return on Interface", () => { - util.testFunction` - /** @tupleReturn */ interface Fn { (): [number, number]; } - const fn: Fn = () => [1, 2]; - const [a, b] = fn(); - return a + b; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Return on Interface Signature", () => { - util.testFunction` - interface Fn { - /** @tupleReturn */ (): [number, number]; - } - const fn: Fn = () => [1, 2]; - const [a, b] = fn(); - return a + b; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Return on Overload", () => { - util.testFunction` - function fn(a: number): number; - /** @tupleReturn */ function fn(a: string, b: string): [string, string]; - function fn(a: number | string, b?: string): number | [string, string] { - if (typeof a === "number") { - return a; - } else { - return [a, b as string]; - } - } - const a = fn(3); - const [b, c] = fn("foo", "bar"); - return a + b + c - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Return on Interface Overload", () => { - util.testFunction` - interface Fn { - (a: number): number; - /** @tupleReturn */ (a: string, b: string): [string, string]; - } - const fn = ((a: number | string, b?: string): number | [string, string] => { - if (typeof a === "number") { - return a; - } else { - return [a, b as string]; - } - }) as Fn; - const a = fn(3); - const [b, c] = fn("foo", "bar"); - return a + b + c - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Return on Interface Method Overload", () => { - util.testFunction` - interface Foo { - foo(a: number): number; - /** @tupleReturn */ foo(a: string, b: string): [string, string]; - } - const bar = { - foo: (a: number | string, b?: string): number | [string, string] => { - if (typeof a === "number") { - return a; - } else { - return [a, b as string]; - } - } - } as Foo; - const a = bar.foo(3); - const [b, c] = bar.foo("foo", "bar"); - return a + b + c; - ` - .tap(expectNoUnpack) - .expectToMatchJsResult(); -}); - -test("Tuple Return vs Non-Tuple Return Overload", () => { - const luaHeader = ` - function fn(a, b) - if type(a) == "number" then - return {a, a + 1} - else - return a, b - end - end - `; - - const tsHeader = ` - declare function fn(this: void, a: number): [number, number]; - /** @tupleReturn */ declare function fn(this: void, a: string, b: string): [string, string]; - `; - - util.testFunction` - const [a, b] = fn(3); - const [c, d] = fn("foo", "bar"); - return (a + b) + c + d; - ` - .setTsHeader(tsHeader) - .setLuaHeader(luaHeader) - .expectToEqual("7foobar"); -}); - -test("TupleReturn assignment", () => { - util.testFunction` - /** @tupleReturn */ - function abc(this: void): number[] { - return [3, 5]; - } - let [a, b] = abc(); - return { a, b }; - `.expectToMatchJsResult(); -}); - -test("TupleReturn Single assignment", () => { - util.testFunction` - /** @tupleReturn */ - function abc(this: void): [number, string] { - return [3, "foo"]; - } - let a = abc(); - a = abc(); - return a; - `.expectToMatchJsResult(); -}); - -test("TupleReturn interface assignment", () => { - const lua = util.testFunction` - interface def { - /** @tupleReturn */ - abc(); - } declare const jkl : def; - let [a,b] = jkl.abc(); - `.getMainLuaCodeChunk(); - - expect(lua).toContain("local a, b = jkl:abc()"); -}); - -test("TupleReturn namespace assignment", () => { - const lua = util.testFunction` - declare namespace def { - /** @tupleReturn */ - function abc(this: void) {} - } - let [a,b] = def.abc(); - `.getMainLuaCodeChunk(); - - expect(lua).toContain("local a, b = def.abc()"); -}); - -test("TupleReturn method assignment", () => { - const lua = util.testFunction` - declare class def { - /** @tupleReturn */ - abc() { return [1,2,3]; } - } const jkl = new def(); - let [a,b] = jkl.abc(); - `.getMainLuaCodeChunk(); - - expect(lua).toContain("local a, b = jkl:abc()"); -}); - -test("TupleReturn functional", () => { - const code = ` - /** @tupleReturn */ - function abc(): [number, string] { return [3, "a"]; } - const [a, b] = abc(); - return b + a; - `; - - const result = util.transpileAndExecute(code); - - expect(result).toBe("a3"); -}); - -test("TupleReturn single", () => { - const code = ` - /** @tupleReturn */ - function abc(): [number, string] { return [3, "a"]; } - const res = abc(); - return res.length - `; - - const result = util.transpileAndExecute(code); - - expect(result).toBe(2); -}); - -test("TupleReturn in expression", () => { - const code = ` - /** @tupleReturn */ - function abc(): [number, string] { return [3, "a"]; } - return abc()[1] + abc()[0]; - `; - - const result = util.transpileAndExecute(code); - - expect(result).toBe("a3"); -}); diff --git a/test/unit/annotations/vararg.spec.ts b/test/unit/annotations/vararg.spec.ts deleted file mode 100644 index 1635ef13a..000000000 --- a/test/unit/annotations/vararg.spec.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as util from "../../util"; - -const varargDeclaration = ` - /** @vararg */ - type LuaVararg = A & { __luaVararg?: never }; -`; - -test("@vararg", () => { - util.testFunction` - ${varargDeclaration} - function foo(a: unknown, ...b: LuaVararg) { - const c = [...b]; - return c.join(""); - } - function bar(a: unknown, ...b: LuaVararg) { - return foo(a, ...b); - } - return bar("A", "B", "C", "D"); - ` - .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("b = ")) - .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("unpack")) - .expectToMatchJsResult(); -}); - -test("@vararg array access", () => { - util.testFunction` - ${varargDeclaration} - function foo(a: unknown, ...b: LuaVararg) { - const c = [...b]; - return c.join("") + b[0]; - } - return foo("A", "B", "C", "D"); - `.expectToMatchJsResult(); -}); - -test("@vararg global", () => { - util.testModule` - ${varargDeclaration} - declare const arg: LuaVararg; - export const result = [...arg].join(""); - ` - .setLuaFactory(code => `return (function(...) ${code} end)("A", "B", "C", "D")`) - .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("unpack")) - .expectToEqual({ result: "ABCD" }); -}); diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 02e1a3b9b..71a7503e2 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -12,7 +12,8 @@ test.each(["const", "let"])("%s declaration not top-level is not global", declar }); test.each(["const", "let"])("top-level %s declaration is global", declarationKind => { - util.testBundle` + // Can't be tested with expectToMatchJsResult because in JS that would not be global + util.testModule` import './a'; export const result = foo; ` @@ -93,16 +94,17 @@ test.each([ "[x[1], x[0]] = tr()", "x = [y[1], y[0]]", "[x[0], x[1]] = [y[1], y[0]]", -])("Tuple assignment expressions (%p)", expression => { +])("multi return assignment expressions (%p)", expression => { util.testFunction` let x: [string, string] = ["x0", "x1"]; let y: [string, string] = ["y0", "y1"]; function t(): [string, string] { return ["t0", "t1"] }; - /** @tupleReturn */ - function tr(): [string, string] { return ["tr0", "tr1"] }; + function tr(): LuaMultiReturn<[string, string]> { return $multi("tr0", "tr1"); }; const r = ${expression}; return \`\${r[0]},\${r[1]}\` - `.expectToMatchJsResult(); + ` + .withLanguageExtensions() + .expectToMatchJsResult(); }); test.each([ @@ -121,6 +123,9 @@ test.each([ "x ^= y", "x <<= y", "x >>>= y", + "x &&= y", + "x ||= y", + "x ??= y", ])("Operator assignment statements (%p)", statement => { util.testFunction` let x = 3; @@ -323,3 +328,170 @@ test.each([ return { r, o, a }; `.expectToMatchJsResult(); }); + +test("local variable declaration referencing self indirectly", () => { + util.testFunction` + let cb: () => void; + + function foo(newCb: () => void) { + cb = newCb; + return "foo"; + } + + let bar = foo(() => { + bar = "bar"; + }); + + cb(); + return bar; + `.expectToMatchJsResult(); +}); + +test("local multiple variable declaration referencing self indirectly", () => { + util.testFunction` + let cb: () => void; + + function foo(newCb: () => void) { + cb = newCb; + return ["a", "foo", "c"]; + } + + let [a, bar, c] = foo(() => { + bar = "bar"; + }); + + cb(); + return bar; + `.expectToMatchJsResult(); +}); + +describe.each(["x &&= y", "x ||= y"])("boolean compound assignment (%p)", assignment => { + const booleanCases = [ + [false, false], + [false, true], + [true, false], + [true, true], + ]; + test.each(booleanCases)("matches JS", (x, y) => { + util.testFunction` + let x = ${x}; + let y = ${y}; + ${assignment}; + return x; + `.expectToMatchJsResult(); + }); +}); + +test.each([undefined, 3])("nullish coalescing compound assignment", initialValue => { + util.testFunction` + let x: number = ${util.formatCode(initialValue)}; + x ??= 5; + return x; + `.expectToMatchJsResult(); +}); + +test("nullish coalescing compound assignment lhs false", () => { + util.testFunction` + let x = false; + x ??= true; + return x; + `.expectToMatchJsResult(); +}); + +test("nullish coalescing compound assignment side effect not evaluated", () => { + util.testFunction` + let x = 3; + let y = 10; + x ??= (y += 5); + return [x, y]; + `.expectToMatchJsResult(); +}); + +test.each([ + { operator: "||=", initialValue: true }, + { operator: "&&=", initialValue: false }, + { operator: "??=", initialValue: false }, +])("compound assignment short-circuits and does not call setter", ({ operator, initialValue }) => { + /* + In JS if the rhs does not affect the resulting value, the setter is NOT called: + * x.y ||= z is translated to x.y || (x.y = z). + * x.y &&= z is translated to x.y && (x.y = z). + * x.y ||= z is translated to x.y !== undefined && (x.y = z). + + Test if setter in Lua is called same nr of times as in JS. + */ + util.testModule` + export let setterCalled = 0; + + class MyClass { + + get prop(): any { + return ${initialValue}; + } + + set prop(value: any) { + setterCalled++; + } + } + + const inst = new MyClass(); + inst.prop ${operator} 8; + `.expectToMatchJsResult(); +}); + +test.each([ + { operator: "||=", initialValue: true }, + { operator: "&&=", initialValue: false }, + { operator: "??=", initialValue: false }, +])("compound assignment short-circuits and does not call setter as expression", ({ operator, initialValue }) => { + /* + In JS if the rhs does not affect the resulting value, the setter is NOT called: + * x.y ||= z is translated to x.y || (x.y = z). + * x.y &&= z is translated to x.y && (x.y = z). + * x.y ||= z is translated to x.y !== undefined && (x.y = z). + + Test if setter in Lua is called same nr of times as in JS. + */ + util.testModule` + export let setterCalled = 0; + + class MyClass { + + get prop(): any { + return ${initialValue}; + } + + set prop(value: any) { + setterCalled++; + } + } + + const inst = new MyClass(); + export const result = (inst.prop ${operator} 8); + `.expectToMatchJsResult(); +}); + +test.each([ + { operator: "+=", initialValue: 3 }, + { operator: "-=", initialValue: 10 }, + { operator: "*=", initialValue: 4 }, + { operator: "/=", initialValue: 20 }, + { operator: "||=", initialValue: false }, + { operator: "&&=", initialValue: true }, + { operator: "??=", initialValue: undefined }, +])("compound assignment side effects", ({ operator, initialValue }) => { + // Test if when assigning to something with potential side effects, they are only evaluated once. + util.testFunction` + const obj: { prop: any} = { prop: ${initialValue} }; + + let objGot = 0; + function getObj() { + objGot++; + return obj; + } + + getObj().prop ${operator} 4; + + return [obj, objGot]; + `.expectToMatchJsResult(); +}); diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 57c162f94..037ebe2a7 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -160,12 +160,21 @@ describe("array.length", () => { util.testExpression`[1, 2, 3].length = ${length}`.expectToEqual(length); }); - test.each([-1, -7, 0.1, NaN, Infinity, -Infinity])("throws on invalid values (%p)", length => { + test.each([-1, -7, 0.1])("throws on invalid values (%p)", length => { util.testFunction` [1, 2, 3].length = ${length}; `.expectToEqual(new util.ExecutionError(`invalid array length: ${length}`)); }); + test.each([NaN, Infinity, -Infinity])("throws on invalid special values (%p)", length => { + // Need to get the actual lua tostring version of inf/nan + // this is platform dependent so we can/should not hardcode it + const luaSpecialValueString = util.testExpression`(${length}).toString()`.getLuaExecutionResult(); + util.testFunction` + [1, 2, 3].length = ${length}; + `.expectToEqual(new util.ExecutionError(`invalid array length: ${luaSpecialValueString}`)); + }); + test("in array destructuring", () => { util.testFunction` const array = [0, 1, 2]; @@ -209,19 +218,27 @@ describe("delete", () => { `.expectToMatchJsResult(); }); - test("returns true when element exists", () => { + test("returns true when deletion attempt was allowed", () => { util.testFunction` const array = [1, 2, 3, 4]; - const exists = delete array[2]; - return { exists, a: array[0], b: array[1], c: array[2], d: array[3] }; + const success = delete array[2]; + return { success, a: array[0], b: array[1], c: array[2], d: array[3] }; `.expectToMatchJsResult(); }); - test("returns false when element not exists", () => { + test("returns false when deletion attempt was disallowed", () => { util.testFunction` const array = [1, 2, 3, 4]; - const exists = delete array[4]; - return { exists, a: array[0], b: array[1], c: array[2], d: array[3] }; + Object.defineProperty(array, 2, { configurable: false }); + + let success; + try { + success = delete array[2]; + } catch { + success = "error"; + } + + return { success, a: array[0], b: array[1], c: array[2], d: array[3] }; `.expectToMatchJsResult(); }); }); @@ -577,6 +594,35 @@ describe.each(["reduce", "reduceRight"])("array.%s", reduce => { }); }); +test.each([{ array: [] }, { array: ["a", "b", "c"] }, { array: [{ foo: "foo" }, { bar: "bar" }] }])( + "array.entries (%p)", + ({ array }) => { + util.testFunction` + const array = ${util.formatCode(array)}; + const result = []; + for (const [i, v] of array.entries()) { + result.push([i, v]); + } + return result; + `.expectToMatchJsResult(); + } +); + +test("array.entries indirect use", () => { + util.testFunction` + const entries = ["a", "b", "c"].entries(); + const result = []; + for (const [i, v] of entries) { + result.push([i, v]); + } + return result; + `.expectToMatchJsResult(); +}); + +test("array.entries destructured", () => { + util.testExpression`[...["a", "b", "c"].entries()]`.expectToMatchJsResult(); +}); + const genericChecks = [ "function generic(array: T)", "function generic(array: T)", @@ -586,27 +632,45 @@ const genericChecks = [ ]; test.each(genericChecks)("array constrained generic foreach (%p)", signature => { - const code = ` - ${signature}: number { - let sum = 0; - array.forEach(item => { - if (typeof item === "number") { - sum += item; - } - }); - return sum; - } - return generic([1, 2, 3]); - `; - expect(util.transpileAndExecute(code)).toBe(6); + util.testFunction` + ${signature}: number { + let sum = 0; + array.forEach(item => { + if (typeof item === "number") { + sum += item; + } + }); + return sum; + } + return generic([1, 2, 3]); + `.expectToMatchJsResult(); }); test.each(genericChecks)("array constrained generic length (%p)", signature => { - const code = ` - ${signature}: number { - return array.length; - } - return generic([1, 2, 3]); - `; - expect(util.transpileAndExecute(code)).toBe(3); + util.testFunction` + ${signature}: number { + return array.length; + } + return generic([1, 2, 3]); + `.expectToMatchJsResult(); +}); + +test.each(["[]", '"hello"', "42", "[1, 2, 3]", '{ a: "foo", b: "bar" }'])( + "Array.isArray matches JavaScript (%p)", + valueString => { + util.testExpression`Array.isArray(${valueString})`.expectToMatchJsResult(); + } +); + +test("Array.isArray returns true for empty objects", () => { + // Important edge case we cannot handle correctly due to [] and {} + // being identical in Lua. We assume [] is more common than Array.isArray({}), + // so it is more important to handle [] right, sacrificing the result for {}. + // See discussion: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/737 + util.testExpression`Array.isArray({})`.expectToEqual(true); +}); + +// Test fix for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/738 +test("array.prototype.concat issue #738", () => { + util.testExpression`([] as any[]).concat(13, 323, {x: 3}, [2, 3])`.expectToMatchJsResult(); }); diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts new file mode 100644 index 000000000..0a9c3513e --- /dev/null +++ b/test/unit/builtins/async-await.spec.ts @@ -0,0 +1,371 @@ +import { ModuleKind, ScriptTarget } from "typescript"; +import { awaitMustBeInAsyncFunction } from "../../../src/transformation/utils/diagnostics"; +import * as util from "../../util"; + +const promiseTestLib = ` +// Some logging utility, useful for asserting orders of operations + +const allLogs: any[] = []; +function log(...values: any[]) { + allLogs.push(...values); +} + +// Create a promise and store its resolve and reject functions, useful for creating pending promises + +function defer() { + let resolve: (data: any) => void = () => {}; + let reject: (reason: string) => void = () => {}; + const promise = new Promise((res, rej) => { + resolve = res; + reject = rej; + }); + return { promise, resolve, reject }; +}`; + +test("can await already resolved promise", () => { + util.testFunction` + const result = []; + async function abc() { + return await Promise.resolve(30); + } + abc().then(value => result.push(value)); + + return result; + `.expectToEqual([30]); +}); + +test("can await already rejected promise", () => { + util.testFunction` + const result = []; + async function abc() { + return await Promise.reject("test rejection"); + } + abc().catch(reason => result.push(reason)); + + return result; + `.expectToEqual(["test rejection"]); +}); + +test("can await pending promise", () => { + util.testFunction` + const { promise, resolve } = defer(); + promise.then(data => log("resolving original promise", data)); + + async function abc() { + return await promise; + } + + const awaitingPromise = abc(); + awaitingPromise.then(data => log("resolving awaiting promise", data)); + + resolve("resolved data"); + + return allLogs; + + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["resolving original promise", "resolved data", "resolving awaiting promise", "resolved data"]); +}); + +test("can await non-promise values", () => { + util.testFunction` + async function foo() { + return await "foo"; + } + + async function bar() { + return await { foo: await foo(), bar: "bar" }; + } + + async function baz() { + return (await bar()).foo + (await bar()).bar; + } + + const { state, value } = baz() as any; + return { state, value }; + `.expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: "foobar", + }); +}); + +test.each(["async function abc() {", "const abc = async () => {"])( + "can return non-promise from async function (%p)", + functionHeader => { + util.testFunction` + const { promise, resolve } = defer(); + promise.then(data => log("resolving original promise", data)); + + ${functionHeader} + await promise; + return "abc return data" + } + + const awaitingPromise = abc(); + awaitingPromise.then(data => log("resolving awaiting promise", data)); + + resolve("resolved data"); + + return allLogs; + + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + "resolving original promise", + "resolved data", + "resolving awaiting promise", + "abc return data", + ]); + } +); + +test.each(["async function abc() {", "const abc = async () => {"])( + "can have multiple awaits in async function (%p)", + functionHeader => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + const { promise: promise3, resolve: resolve3 } = defer(); + promise1.then(data => log("resolving promise1", data)); + promise2.then(data => log("resolving promise2", data)); + promise3.then(data => log("resolving promise3", data)); + + ${functionHeader} + const result1 = await promise1; + const result2 = await promise2; + const result3 = await promise3; + return [result1, result2, result3]; + } + + const awaitingPromise = abc(); + awaitingPromise.then(data => log("resolving awaiting promise", data)); + + resolve1("data1"); + resolve2("data2"); + resolve3("data3"); + + return allLogs; + + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + "resolving promise1", + "data1", + "resolving promise2", + "data2", + "resolving promise3", + "data3", + "resolving awaiting promise", + ["data1", "data2", "data3"], + ]); + } +); + +test("can make async lambdas with expression body", () => { + util.testFunction` + const foo = async () => "foo"; + const bar = async () => await foo(); + + const { state, value } = bar() as any; + return { state, value }; + `.expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: "foo", + }); +}); + +test("can await async function from async function", () => { + util.testFunction` + const { promise, resolve } = defer(); + promise.then(data => log("resolving original promise", data)); + + async function abc() { + return await promise; + } + + async function def() { + return await abc(); + } + + const awaitingPromise = def(); + awaitingPromise.then(data => log("resolving awaiting promise", data)); + + resolve("resolved data"); + + return allLogs; + + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["resolving original promise", "resolved data", "resolving awaiting promise", "resolved data"]); +}); + +test("async function returning value is same as non-async function returning promise", () => { + util.testFunction` + function f(): Promise { + return Promise.resolve(42); + } + + async function fAsync(): Promise { + return 42; + } + + const { state: state1, value: value1 } = f() as any; + const { state: state2, value: value2 } = fAsync() as any; + + return { + state1, value1, + state2, value2 + }; + `.expectToEqual({ + state1: 1, // __TS__PromiseState.Fulfilled + value1: 42, + state2: 1, // __TS__PromiseState.Fulfilled + value2: 42, + }); +}); + +test("correctly handles awaited functions rejecting", () => { + util.testFunction` + const { promise: promise1, reject } = defer(); + const { promise: promise2 } = defer(); + + promise1.then(data => log("resolving promise1", data), reason => log("rejecting promise1", reason)); + promise2.then(data => log("resolving promise2", data)); + + async function abc() { + const result1 = await promise1; + const result2 = await promise2; + return [result1, result2]; + } + + const awaitingPromise = abc(); + awaitingPromise.catch(reason => log("awaiting promise was rejected because:", reason)); + + reject("test reject"); + + return allLogs; + + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["rejecting promise1", "test reject", "awaiting promise was rejected because:", "test reject"]); +}); + +test("can call async function at top-level", () => { + util.testModule` + export let aStarted = false; + async function a() { + aStarted = true; + return 42; + } + + a(); // Call async function (but cannot await) + ` + .setOptions({ module: ModuleKind.ESNext, target: ScriptTarget.ES2017 }) + .expectToEqual({ + aStarted: true, + }); +}); + +test("async function throws error", () => { + util.testFunction` + async function a() { + throw "test throw"; + } + + const { state, rejectionReason } = a() as any; + return { state, rejectionReason }; + `.expectToEqual({ + state: 2, // __TS__PromiseState.Rejected + rejectionReason: "test throw", + }); +}); + +test("async lambda throws error", () => { + util.testFunction` + const a = async () => { + throw "test throw"; + } + + const { state, rejectionReason } = a() as any; + return { state, rejectionReason }; + `.expectToEqual({ + state: 2, // __TS__PromiseState.Rejected + rejectionReason: "test throw", + }); +}); + +test("async function throws object", () => { + util.testFunction` + async function a() { + throw new Error("test throw"); + } + + const { state, rejectionReason } = a() as any; + return { state, rejectionReason }; + `.expectToEqual({ + state: 2, // __TS__PromiseState.Rejected + rejectionReason: { + message: "test throw", + name: "Error", + stack: expect.stringContaining("stack traceback"), + }, + }); +}); + +test.each([ + "await a();", + "const b = await a();", + "export const b = await a();", + "declare function foo(n: number): number; foo(await a());", + "declare function foo(n: number): number; const b = foo(await a());", + "const b = [await a()];", + "const b = [4, await a()];", + "const b = true ? 4 : await a();", +])("cannot await at top-level (%p)", awaitUsage => { + util.testModule` + async function a() { + return 42; + } + + ${awaitUsage} + export {} // Required to make TS happy, cannot await without import/exports + ` + .setOptions({ module: ModuleKind.ESNext, target: ScriptTarget.ES2017 }) + .expectToHaveDiagnostics([awaitMustBeInAsyncFunction.code]); +}); + +test("async function can access varargs", () => { + util.testFunction` + const { promise, resolve } = defer(); + + async function a(...args: string[]) { + log(await promise); + log(args[1]); + } + + const awaitingPromise = a("A", "B", "C"); + resolve("resolved"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["resolved", "B"]); +}); + +test("async function can forward varargs", () => { + util.testFunction` + const { promise, resolve } = defer(); + + async function a(...args: string[]) { + log(await promise); + log(...args); + } + + const awaitingPromise = a("A", "B", "C"); + resolve("resolved"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["resolved", "A", "B", "C"]); +}); diff --git a/test/unit/builtins/map.spec.ts b/test/unit/builtins/map.spec.ts index e9edd2508..7eec8844d 100644 --- a/test/unit/builtins/map.spec.ts +++ b/test/unit/builtins/map.spec.ts @@ -1,95 +1,94 @@ import * as util from "../../util"; test("map constructor", () => { - const result = util.transpileAndExecute("let mymap = new Map(); return mymap.size;"); - - expect(result).toBe(0); + util.testFunction` + let mymap = new Map(); + return mymap.size; + `.expectToMatchJsResult(); }); test("map iterable constructor", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([["a", "c"],["b", "d"]]); - return mymap.has("a") && mymap.has("b");` - ); - - expect(result).toBe(true); + util.testFunction` + let mymap = new Map([["a", "c"],["b", "d"]]); + return mymap.has("a") && mymap.has("b"); + `.expectToMatchJsResult(); }); test("map iterable constructor map", () => { - const result = util.transpileAndExecute(` + util.testFunction` let mymap = new Map(new Map([["a", "c"],["b", "d"]])); return mymap.has("a") && mymap.has("b"); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("map clear", () => { const mapTS = 'let mymap = new Map([["a", "c"],["b", "d"]]); mymap.clear();'; - const size = util.transpileAndExecute(mapTS + "return mymap.size;"); - expect(size).toBe(0); + util.testExpression("mymap.size").setTsHeader(mapTS).expectToMatchJsResult(); - const contains = util.transpileAndExecute(mapTS + 'return !mymap.has("a") && !mymap.has("b");'); - expect(contains).toBe(true); + util.testExpression('!mymap.has("a") && !mymap.has("b")').setTsHeader(mapTS).expectToMatchJsResult(); }); test("map delete", () => { - const mapTS = 'let mymap = new Map([["a", "c"],["b", "d"]]); mymap.delete("a");'; - const contains = util.transpileAndExecute(mapTS + 'return mymap.has("b") && !mymap.has("a");'); - expect(contains).toBe(true); + util.testFunction` + let mymap = new Map([["a", "c"],["b", "d"]]); + mymap.delete("a"); + return mymap.has("b") && !mymap.has("a"); + `.expectToMatchJsResult(); }); test("map entries", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + util.testFunction` + let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; for (const [key, value] of mymap.entries()) { count += key + value; } - return count;` - ); - expect(result).toBe(27); + return count; + `.expectToMatchJsResult(); }); test("map foreach", () => { - const result = util.transpileAndExecute( + util.testFunction( `let mymap = new Map([["a", 2],["b", 3],["c", 4]]); let count = 0; mymap.forEach(i => count += i); return count;` - ); - - expect(result).toBe(9); + ).expectToMatchJsResult(); }); test("map foreach keys", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + util.testFunction` + let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; mymap.forEach((value, key) => { count += key; }); - return count;` - ); - - expect(result).toBe(18); + return count; + `.expectToMatchJsResult(); }); test("map get", () => { - const result = util.transpileAndExecute('let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("a");'); - - expect(result).toBe("c"); + util.testFunction` + let mymap = new Map([["a", "c"],["b", "d"]]); + return mymap.get("a"); + `.expectToMatchJsResult(); }); test("map get missing", () => { - const result = util.transpileAndExecute('let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("c");'); - expect(result).toBeUndefined(); + util.testFunction` + let mymap = new Map([["a", "c"],["b", "d"]]); + return mymap.get("c"); + `.expectToMatchJsResult(); }); test("map has", () => { - const contains = util.transpileAndExecute('let mymap = new Map([["a", "c"]]); return mymap.has("a");'); - expect(contains).toBe(true); + util.testFunction` + let mymap = new Map([["a", "c"]]); + return mymap.has("a"); + `.expectToMatchJsResult(); }); test("map has false", () => { - const contains = util.transpileAndExecute('let mymap = new Map(); return mymap.has("a");'); - expect(contains).toBe(false); + util.testFunction` + let mymap = new Map(); + return mymap.has("a"); + `.expectToMatchJsResult(); }); test.each([ @@ -117,42 +116,36 @@ test.each([ }); test("map keys", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + util.testFunction` + let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; for (const key of mymap.keys()) { count += key; } - return count;` - ); - - expect(result).toBe(18); + return count; + `.expectToMatchJsResult(); }); test("map set", () => { const mapTS = 'let mymap = new Map(); mymap.set("a", 5);'; - const has = util.transpileAndExecute(mapTS + 'return mymap.has("a");'); - expect(has).toBe(true); + util.testFunction(mapTS + 'return mymap.has("a");').expectToMatchJsResult(); - const value = util.transpileAndExecute(mapTS + 'return mymap.get("a")'); - expect(value).toBe(5); + util.testFunction(mapTS + 'return mymap.get("a")').expectToMatchJsResult(); }); test("map values", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + util.testFunction` + let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; for (const value of mymap.values()) { count += value; } - return count;` - ); - - expect(result).toBe(9); + return count; + `.expectToMatchJsResult(); }); test("map size", () => { - expect(util.transpileAndExecute("let m = new Map(); return m.size;")).toBe(0); - expect(util.transpileAndExecute("let m = new Map(); m.set(1,3); return m.size;")).toBe(1); - expect(util.transpileAndExecute("let m = new Map([[1,2],[3,4]]); return m.size;")).toBe(2); - expect(util.transpileAndExecute("let m = new Map([[1,2],[3,4]]); m.clear(); return m.size;")).toBe(0); - expect(util.transpileAndExecute("let m = new Map([[1,2],[3,4]]); m.delete(3); return m.size;")).toBe(1); + util.testFunction("let m = new Map(); return m.size;").expectToMatchJsResult(); + util.testFunction("let m = new Map(); m.set(1,3); return m.size;").expectToMatchJsResult(); + util.testFunction("let m = new Map([[1,2],[3,4]]); return m.size;").expectToMatchJsResult(); + util.testFunction("let m = new Map([[1,2],[3,4]]); m.clear(); return m.size;").expectToMatchJsResult(); + util.testFunction("let m = new Map([[1,2],[3,4]]); m.delete(3); return m.size;").expectToMatchJsResult(); }); const iterationMethods = ["entries", "keys", "values"]; diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts index faaeacbcd..dd928c68d 100644 --- a/test/unit/builtins/math.spec.ts +++ b/test/unit/builtins/math.spec.ts @@ -34,8 +34,14 @@ util.testEachVersion("Math.atan2", () => util.testExpression`Math.atan2(4, 5)`, [tstl.LuaTarget.Lua51]: builder => builder.tap(expectMathAtan2), [tstl.LuaTarget.Lua52]: builder => builder.tap(expectMathAtan2), [tstl.LuaTarget.Lua53]: builder => builder.tap(expectMathAtan), + [tstl.LuaTarget.Lua54]: builder => builder.tap(expectMathAtan2), }); -test("Math.atan2(4, 5)", () => { - util.testExpression`Math.atan2(4, 5)`.expectToMatchJsResult(); +util.testEachVersion("Math.atan2(4, 5)", () => util.testExpression`Math.atan2(4, 5)`, { + [tstl.LuaTarget.Universal]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.LuaJIT]: false, + [tstl.LuaTarget.Lua51]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.Lua52]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.Lua53]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.Lua54]: builder => builder.expectToMatchJsResult(), }); diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index 2f52c1d7d..f58209c31 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -56,8 +56,17 @@ test.each(toStringPairs)("(%p).toString(%p)", (value, radix) => { util.testExpressionTemplate`(${value}).toString(${radix})`.expectToMatchJsResult(); }); -test.each([NaN, Infinity, -Infinity])("%p.toString(2)", value => { - util.testExpressionTemplate`(${value}).toString(2)`.expectToMatchJsResult(); +test.each([ + [NaN, "(0/0)"], + [Infinity, "(1/0)"], + [-Infinity, "(-(1/0))"], +])("%p.toString(2)", (value, luaNativeSpecialNum) => { + // Need to get the actual lua tostring version of inf/nan + // this is platform dependent so we can/should not hardcode it + const luaNativeSpecialNumString = util.testExpression`${luaNativeSpecialNum}.toString()`.getLuaExecutionResult(); + // Cannot use expectToMatchJsResult because this actually wont be the same in JS in Lua + // TODO fix this in lualib/NumberToString.ts + util.testExpressionTemplate`(${value}).toString(2)`.expectToEqual(luaNativeSpecialNumString); }); test.each(cases)("isNaN(%p)", value => { @@ -78,3 +87,57 @@ test("number intersected method", () => { test("numbers overflowing the float limit become math.huge", () => { util.testExpression`1e309`.expectToMatchJsResult(); }); + +describe.each(["parseInt", "parseFloat"])("parse numbers with %s", parseFunction => { + const numberStrings = ["3", "3.0", "9", "42", "239810241", "-20391", "3.1415", "2.7182", "-34910.3"]; + + test.each(numberStrings)("parses (%s)", numberString => { + util.testExpression`${parseFunction}("${numberString}")`.expectToMatchJsResult(); + }); + + test("empty string", () => { + util.testExpression`${parseFunction}("")`.expectToMatchJsResult(); + }); + + test("invalid string", () => { + util.testExpression`${parseFunction}("bla")`.expectToMatchJsResult(); + }); + + test.each(["1px", "2300m", "3,4", "452adkfl"])("trailing text (%s)", numberString => { + util.testExpression`${parseFunction}("${numberString}")`.expectToMatchJsResult(); + }); + + test.each([" 3", " 4", " -231", " 1px"])("leading whitespace (%s)", numberString => { + util.testExpression`${parseFunction}("${numberString}")`.expectToMatchJsResult(); + }); +}); + +test.each(["Infinity", "-Infinity", " -Infinity"])("parseFloat handles Infinity", numberString => { + util.testExpression`parseFloat("${numberString}")`.expectToMatchJsResult(); +}); + +test.each([ + { numberString: "36", base: 8 }, + { numberString: "-36", base: 8 }, + { numberString: "100010101101", base: 2 }, + { numberString: "-100010101101", base: 2 }, + { numberString: "3F", base: 16 }, +])("parseInt with base (%p)", ({ numberString, base }) => { + util.testExpression`parseInt("${numberString}", ${base})`.expectToMatchJsResult(); +}); + +test.each(["0x4A", "-0x42", "0X42", " 0x391", " -0x8F"])("parseInt detects hexadecimal", numberString => { + util.testExpression`parseInt("${numberString}")`.expectToMatchJsResult(); +}); + +test.each([1, 37, -100])("parseInt with invalid base (%p)", base => { + util.testExpression`parseInt("11111", ${base})`.expectToMatchJsResult(); +}); + +test.each([ + { numberString: "36px", base: 8 }, + { numberString: "10001010110231", base: 2 }, + { numberString: "3Fcolor", base: 16 }, +])("parseInt with base and trailing text (%p)", ({ numberString, base }) => { + util.testExpression`parseInt("${numberString}", ${base})`.expectToMatchJsResult(); +}); diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts index b4866d2e7..fb0fe26ba 100644 --- a/test/unit/builtins/object.spec.ts +++ b/test/unit/builtins/object.spec.ts @@ -11,15 +11,21 @@ test.each([ }); test.each([{}, { abc: 3 }, { abc: 3, def: "xyz" }])("Object.entries (%p)", obj => { - util.testExpressionTemplate`Object.entries(${obj})`.expectToMatchJsResult(); + const testBuilder = util.testExpressionTemplate`Object.entries(${obj})`; + // Need custom matcher because order is not guaranteed in neither JS nor Lua + expect(testBuilder.getJsExecutionResult()).toEqual(expect.arrayContaining(testBuilder.getLuaExecutionResult())); }); test.each([{}, { abc: 3 }, { abc: 3, def: "xyz" }])("Object.keys (%p)", obj => { - util.testExpressionTemplate`Object.keys(${obj})`.expectToMatchJsResult(); + const testBuilder = util.testExpressionTemplate`Object.keys(${obj})`; + // Need custom matcher because order is not guaranteed in neither JS nor Lua + expect(testBuilder.getJsExecutionResult()).toEqual(expect.arrayContaining(testBuilder.getLuaExecutionResult())); }); test.each([{}, { abc: "def" }, { abc: 3, def: "xyz" }])("Object.values (%p)", obj => { - util.testExpressionTemplate`Object.values(${obj})`.expectToMatchJsResult(); + const testBuilder = util.testExpressionTemplate`Object.values(${obj})`; + // Need custom matcher because order is not guaranteed in neither JS nor Lua + expect(testBuilder.getJsExecutionResult()).toEqual(expect.arrayContaining(testBuilder.getLuaExecutionResult())); }); test.each(["[]", '[["a", 1], ["b", 2]]', '[["a", 1], ["a", 2]]', 'new Map([["foo", "bar"]])'])( @@ -121,3 +127,117 @@ describe(".hasOwnProperty()", () => { `.expectToMatchJsResult(); }); }); + +const trueFalseTests = [[true], [false]] as const; + +describe("Object.defineProperty", () => { + test.each(trueFalseTests)("writable (%p)", value => { + util.testFunction` + const foo = { bar: true }; + Object.defineProperty(foo, "bar", { writable: ${value} }); + let error = false; + try { + foo.bar = false; + } catch { + error = true; + } + return { foobar: foo.bar, error }; + `.expectToMatchJsResult(); + }); + + test.each(trueFalseTests)("configurable (%p)", value => { + util.testFunction` + const foo = { bar: true }; + Object.defineProperty(foo, "bar", { configurable: ${value} }); + try { delete foo.bar } catch {}; + return foo.bar; + `.expectToMatchJsResult(); + }); + + test("defines a new property", () => { + util.testFunction` + const foo: any = {}; + Object.defineProperty(foo, "bar", { value: true }); + return foo.bar; + `.expectToMatchJsResult(); + }); + + test("overwrites an existing property", () => { + util.testFunction` + const foo = { bar: false }; + Object.defineProperty(foo, "bar", { value: true }); + return foo.bar; + `.expectToMatchJsResult(); + }); + + test("default descriptor", () => { + util.testFunction` + const foo = {}; + Object.defineProperty(foo, "bar", {}); + return Object.getOwnPropertyDescriptor(foo, "bar"); + `.expectToMatchJsResult(); + }); + + test.each([ + ["{ value: true, get: () => true }"], + ["{ value: true, set: value => {} }"], + ["{ writable: true, get: () => true }"], + ])("invalid descriptor (%p)", props => { + util.testFunction` + const foo: any = {}; + let err = false; + + try { + Object.defineProperty(foo, "bar", ${props}); + } catch { + err = true; + } + + return { prop: foo.bar, err }; + `.expectToMatchJsResult(); + }); +}); + +describe("Object.getOwnPropertyDescriptor", () => { + test("descriptor is exactly the same as the last one set", () => { + util.testFunction` + const foo = {}; + Object.defineProperty(foo, "bar", {}); + return Object.getOwnPropertyDescriptor(foo, "bar"); + `.expectToMatchJsResult(); + }); +}); + +describe("Object.getOwnPropertyDescriptors", () => { + test("all descriptors match", () => { + util.testFunction` + const foo = { bar: true }; + Object.defineProperty(foo, "bar", {}); + return Object.getOwnPropertyDescriptors(foo); + `.expectToMatchJsResult(); + }); +}); + +describe("delete from object", () => { + test("delete from object", () => { + util.testFunction` + const obj = { foo: "bar", bar: "baz" }; + delete obj["foo"]; + return obj; + ` + .setTsHeader("declare function setmetatable(this: void, table: T, metatable: any): T;") + .expectToEqual({ bar: "baz" }); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/993 + test("delete from object with metatable", () => { + util.testFunction` + const obj = { foo: "bar", bar: "baz" }; + setmetatable(obj, {}); + delete obj["foo"]; + return obj; + ` + .setTsHeader("declare function setmetatable(this: void, table: T, metatable: any): T;") + .expectToEqual({ bar: "baz" }); + }); +}); diff --git a/test/unit/builtins/promise.spec.ts b/test/unit/builtins/promise.spec.ts new file mode 100644 index 000000000..4a22f7514 --- /dev/null +++ b/test/unit/builtins/promise.spec.ts @@ -0,0 +1,1175 @@ +import * as util from "../../util"; + +const promiseTestLib = ` +// Some logging utility, useful for asserting orders of operations + +const allLogs: any[] = []; +function log(...values: any[]) { + allLogs.push(...values); +} + +// Create a promise and store its resolve and reject functions, useful for creating pending promises + +function defer() { + let resolve: (data: any) => void = () => {}; + let reject: (reason: string) => void = () => {}; + const promise = new Promise((res, rej) => { + resolve = res; + reject = rej; + }); + return { promise, resolve, reject }; +}`; + +test("can create resolved promise", () => { + util.testFunction` + const { state, value } = Promise.resolve(42) as any; + return { state, value }; + `.expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: 42, + }); +}); + +test("can create rejected promise", () => { + util.testFunction` + const { state, rejectionReason } = Promise.reject("test rejection") as any; + return { state, rejectionReason }; + `.expectToEqual({ + state: 2, // __TS__PromiseState.Rejected + rejectionReason: "test rejection", + }); +}); + +test("promise constructor executor throwing rejects promise", () => { + util.testFunction` + const { state, rejectionReason } = new Promise(() => { throw "executor exception"; }) as any; + return { state, rejectionReason }; + `.expectToEqual({ + state: 2, // __TS__PromiseState.Rejected + rejectionReason: "executor exception", + }); +}); + +test("promise can be resolved", () => { + util.testFunction` + const { promise, resolve } = defer(); + + let result: string | undefined; + let rejectResult: string | undefined; + + promise.then( + data => { result = data; }, + reason => { rejectResult = reason; } + ); + + const beforeResolve = result; + + resolve("Hello!"); + + const afterResolve = result; + + return { beforeResolve, afterResolve, rejectResult }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + beforeResolve: undefined, + afterResolve: "Hello!", + rejectResult: undefined, + }); +}); + +test("promise can be rejected", () => { + util.testFunction` + const { promise, reject } = defer(); + + let resolveResult: string | undefined; + let rejectResult: string | undefined; + + promise.then( + data => { resolveResult = data; }, + reason => { rejectResult = reason; } + ); + + const beforeReject = rejectResult; + + reject("Hello!"); + + const afterReject = rejectResult; + + return { beforeReject, afterReject, resolveResult }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + beforeReject: undefined, + afterReject: "Hello!", + resolveResult: undefined, + }); +}); + +test("promise cannot be resolved more than once", () => { + util.testFunction` + const { promise, resolve } = defer(); + + promise.then( + data => { log(data); } + ); + + resolve("Hello!"); + resolve("World!"); // Second resolve should be ignored + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["Hello!"]); +}); + +test("promise cannot be rejected more than once", () => { + util.testFunction` + const { promise, reject } = defer(); + + promise.then( + _ => {}, + reason => { log(reason); } + ); + + reject("Hello!"); + reject("World!"); // Second reject should be ignored + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["Hello!"]); +}); + +test("promise cannot be rejected after resolving", () => { + util.testFunction` + const { promise, resolve, reject } = defer(); + + promise.then( + data => { log(data); }, + reason => { log(reason); } + ); + + resolve("Hello!"); + reject("World!"); // should be ignored because already resolved + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["Hello!"]); +}); + +test("promise cannot be resolved after rejecting", () => { + util.testFunction` + const { promise, resolve, reject } = defer(); + + promise.then( + data => { log(data); }, + reason => { log(reason); } + ); + + reject("Hello!"); + resolve("World!"); // should be ignored because already rejected + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["Hello!"]); +}); + +test("promise can be (then-resolve) observed more than once", () => { + util.testFunction` + const { promise, resolve } = defer(); + + promise.then( + data => { log("then 1: " + data); } + ); + + promise.then( + data => { log("then 2: " + data); } + ); + + resolve("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["then 1: Hello!", "then 2: Hello!"]); +}); + +test("promise can be (then-reject) observed more than once", () => { + util.testFunction` + const { promise, reject } = defer(); + + promise.then( + undefined, + reason => { log("then 1: " + reason); } + ); + + promise.then( + undefined, + reason => { log("then 2: " + reason); }, + ); + + reject("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["then 1: Hello!", "then 2: Hello!"]); +}); + +test("promise can be (catch) observed more than once", () => { + util.testFunction` + const { promise, reject } = defer(); + + promise.catch( + reason => { log("catch 1: " + reason); } + ); + + promise.catch( + reason => { log("catch 2: " + reason); }, + ); + + reject("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["catch 1: Hello!", "catch 2: Hello!"]); +}); + +test("promise chained resolve resolves all", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + const { promise: promise3, resolve: resolve3 } = defer(); + + promise3.then(data => { + log("promise3: " + data); + resolve2(data); + }); + promise2.then(data => { + log("promise2: " + data); + resolve1(data); + }); + promise1.then(data => { + log("promise1: " + data); + }); + + resolve3("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise3: Hello!", "promise2: Hello!", "promise1: Hello!"]); +}); + +test("promise then returns a literal", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const promise2 = promise.then(data => { + log("promise resolved with: " + data); + return "promise 1 resolved: " + data; + }); + + promise2.then(data => { + log("promise2 resolved with: " + data); + }); + + resolve("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise resolved with: Hello!", "promise2 resolved with: promise 1 resolved: Hello!"]); +}); + +test("promise then returns a resolved promise", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const promise2 = promise.then(data => { + log("promise resolved with: " + data); + return Promise.resolve("promise 1 resolved: " + data); + }); + + promise2.then(data => { + log("promise2 resolved with: " + data); + }); + + resolve("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise resolved with: Hello!", "promise2 resolved with: promise 1 resolved: Hello!"]); +}); + +test("promise then returns a rejected promise", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const promise2 = promise.then(data => { + log("promise resolved with: " + data); + return Promise.reject("promise 1: reject!"); + }); + + promise2.catch(reason => { + log("promise2 rejected with: " + reason); + }); + + resolve("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise resolved with: Hello!", "promise2 rejected with: promise 1: reject!"]); +}); + +test("promise then returns a pending promise (resolves)", () => { + util.testFunction` + const { promise, resolve } = defer(); + + let resolve2: any; + + const promise2 = promise.then(data => { + log("promise resolved with: " + data); + + const promise3 = new Promise((res) => { + resolve2 = res; + }); + + promise3.then(data2 => { + log("promise3 resolved with: " + data2); + }); + + return promise3; + }); + + promise2.then(data => { + log("promise2 resolved with: " + data); + }); + + // Resolve promise 1 + resolve("Hello!"); + + // Resolve promise 2 and 3 + resolve2("World!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + "promise resolved with: Hello!", + "promise3 resolved with: World!", + "promise2 resolved with: World!", + ]); +}); + +test("promise then returns a pending promise (rejects)", () => { + util.testFunction` + const { promise, resolve } = defer(); + + let reject: any; + + const promise2 = promise.then(data => { + log("promise resolved with: " + data); + + const promise3 = new Promise((_, rej) => { + reject = rej; + }); + + promise3.catch(reason => { + log("promise3 rejected with: " + reason); + }); + + return promise3; + }); + + promise2.catch(reason => { + log("promise2 rejected with: " + reason); + }); + + // Resolve promise 1 + resolve("Hello!"); + + // Reject promise 2 and 3 + reject("World!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + "promise resolved with: Hello!", + "promise3 rejected with: World!", + "promise2 rejected with: World!", + ]); +}); + +test("promise then onFulfilled throws", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const promise2 = promise.then(data => { + throw "fulfill exception!" + }); + + promise2.catch(reason => { + log("promise2 rejected with: " + reason); + }); + + resolve("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise2 rejected with: fulfill exception!"]); +}); + +test("promise then onRejected throws", () => { + util.testFunction` + const { promise, reject } = defer(); + + const promise2 = promise.then( + _ => {}, + reason => { throw "fulfill exception from onReject!" } + ); + + promise2.catch(reason => { + log("promise2 rejected with: " + reason); + }); + + reject("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise2 rejected with: fulfill exception from onReject!"]); +}); + +test("then on resolved promise immediately calls callback", () => { + util.testFunction` + Promise.resolve(42).then(data => { log(data); }); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([42]); +}); + +test("then on rejected promise immediately calls callback", () => { + util.testFunction` + Promise.reject("already rejected").then(data => { log("resolved", data); }, reason => { log("rejected", reason); }); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["rejected", "already rejected"]); +}); + +test("second then throws", () => { + util.testFunction` + const { promise, resolve } = defer(); + + promise.then(data => { + // nothing + log("then1", data) + }); + + promise.then(data => { + log("then2", data) + throw "test throw"; + }).catch(err => { + // caught + log("rejected: ", err) + }); + + resolve("mydata"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["then1", "mydata", "then2", "mydata", "rejected: ", "test throw"]); +}); + +test("chained then throws", () => { + util.testFunction` + const { promise, resolve } = defer(); + + promise.then(data => { + // nothing + log("then1", data) + }).then(data => { + log("then2", data) + throw "test throw"; + }).catch(err => { + // caught + log("rejected: ", err) + }); + + resolve("mydata"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + "then1", + "mydata", + "then2", // Does not have data because first then returned undefined + "rejected: ", + "test throw", + ]); +}); + +test("catch on rejected promise immediately calls callback", () => { + util.testFunction` + Promise.reject("already rejected").catch(reason => { log(reason); }); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["already rejected"]); +}); + +test("finally on resolved promise immediately calls callback", () => { + util.testFunction` + Promise.resolve(42).finally(() => { log("finally"); }); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["finally"]); +}); + +test("finally on rejected promise immediately calls callback", () => { + util.testFunction` + Promise.reject("already rejected").finally(() => { log("finally"); }); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["finally"]); +}); + +test("direct chaining", () => { + util.testFunction` + const { promise, resolve } = defer(); + + promise + .then(data => { + log("resolving then1", data); + return "then 1 data"; + }).then(data => { + log("resolving then2", data); + throw "test throw"; + }).catch(reason => { + log("handling catch", reason); + }); + + resolve("test data"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + "resolving then1", + "test data", + "resolving then2", + "then 1 data", + "handling catch", + "test throw", + ]); +}); + +describe("finally behaves same as then/catch", () => { + const thenCatchPromise = ` + const { promise, resolve, reject } = defer(); + promise + .then(data => { + log("do something", data); + log("final code"); + }) + .catch(reason => { + log("handling error", data); + log("final code"); + }); + `; + + const finallyPromise = ` + const { promise, resolve, reject } = defer(); + promise + .then(data => { + log("do something", data); + }) + .catch(reason => { + log("handling error", reason); + }) + .finally(() => { + log("final code"); + }); + `; + + test("when resolving", () => { + const thenResult = util.testFunction` + ${thenCatchPromise} + resolve("test data"); + return allLogs; + ` + .setTsHeader(promiseTestLib) + .getLuaExecutionResult(); + + const finallyResult = util.testFunction` + ${finallyPromise} + resolve("test data"); + return allLogs; + ` + .setTsHeader(promiseTestLib) + .getLuaExecutionResult(); + + expect(finallyResult).toEqual(thenResult); + }); + + test("when rejecting", () => { + const thenResult = util.testFunction` + ${thenCatchPromise} + reject("test rejection reason"); + return allLogs; + ` + .setTsHeader(promiseTestLib) + .getLuaExecutionResult(); + + const finallyResult = util.testFunction` + ${finallyPromise} + reject("test rejection reason"); + return allLogs; + ` + .setTsHeader(promiseTestLib) + .getLuaExecutionResult(); + + expect(finallyResult).toEqual(thenResult); + }); +}); + +test("example: asynchronous web request", () => { + const testHarness = ` + interface UserData { name: string, age: number} + const requests = new Map void>(); + function getUserData(id: number, callback: (userData: UserData) => void) { + requests.set(id, callback); + } + function emulateRequestReturn(id: number, data: UserData) { + requests.get(id)!(data); + } + `; + + util.testFunction` + // Wrap function getUserData(id: number, callback: (userData: UserData) => void) into a Promise + function getUserDataAsync(id: number): Promise { + return new Promise(resolve => { + getUserData(id, resolve); + }); + } + + const user1DataPromise = getUserDataAsync(1); + const user2DataPromise = getUserDataAsync(2); + + user1DataPromise.then(() => log("received data for user 1")); + user2DataPromise.then(() => log("received data for user 2")); + + const allDataPromise = Promise.all([user1DataPromise, user2DataPromise]); + + allDataPromise.then(([user1data, user2data]) => { + log("all requests completed", user1data, user2data); + }); + + emulateRequestReturn(2, { name: "bar", age: 42 }); + emulateRequestReturn(1, { name: "foo", age: 35 }); + + return allLogs; + ` + .setTsHeader(testHarness + promiseTestLib) + .expectToEqual([ + "received data for user 2", + "received data for user 1", + "all requests completed", + { + name: "foo", + age: 35, + }, + { + name: "bar", + age: 42, + }, + ]); +}); + +test("promise is instanceof promise", () => { + util.testExpression`Promise.resolve(4) instanceof Promise`.expectToMatchJsResult(); +}); + +describe("Promise.all", () => { + test("resolves once all arguments are resolved", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + const { promise: promise3, resolve: resolve3 } = defer(); + + const promise = Promise.all([promise1, promise2, promise3]); + promise.then(([result1, result2, result3]) => { + log(result1, result2, result3); + }); + + resolve1("promise 1 result!"); + resolve2("promise 2 result!"); + resolve3("promise 3 result!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise 1 result!", "promise 2 result!", "promise 3 result!"]); + }); + + test("rejects on first rejection", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, reject: reject2 } = defer(); + const { promise: promise3, resolve: resolve3 } = defer(); + + const promise = Promise.all([promise1, promise2, promise3]); + promise.then( + ([result1, result2, result3]) => { + log(result1, result2, result3); + }, + reason => { + log(reason); + } + ); + + resolve1("promise 1 result!"); + reject2("promise 2 rejects!"); + resolve3("promise 3 result!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise 2 rejects!"]); + }); + + test("handles already-resolved promises", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + + const promise = Promise.all([promise1, Promise.resolve("already resolved!")]); + promise.then(([result1, result2]) => { + log(result1, result2); + }); + + resolve1("promise 1 result!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise 1 result!", "already resolved!"]); + }); + + test("handles non-promise data", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + + const promise = Promise.all([42, promise1, "foo"]); + promise.then(([result1, result2, result3]) => { + log(result1, result2, result3); + }); + + resolve1("promise 1 result!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([42, "promise 1 result!", "foo"]); + }); + + test("returns already-resolved promise if no pending promises in arguments", () => { + util.testFunction` + const { state, value } = Promise.all([42, Promise.resolve("already resolved!"), "foo"]) as any; + return { state, value }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: [42, "already resolved!", "foo"], + }); + }); + + test("returns already-rejected promise if already rejected promise in arguments", () => { + util.testFunction` + const { state, rejectionReason } = Promise.all([42, Promise.reject("already rejected!")]) as any; + return { state, rejectionReason }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 2, // __TS__PromiseState.Rejected + rejectionReason: "already rejected!", + }); + }); +}); + +describe("Promise.allSettled", () => { + test("resolves once all arguments are resolved", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + const { promise: promise3, resolve: resolve3 } = defer(); + + const promise = Promise.allSettled([promise1, promise2, promise3]); + promise.then(([result1, result2, result3]) => { + log(result1, result2, result3); + }); + + resolve3("promise 3 result!"); + resolve1("promise 1 result!"); + resolve2("promise 2 result!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + { status: "fulfilled", value: "promise 1 result!" }, + { status: "fulfilled", value: "promise 2 result!" }, + { status: "fulfilled", value: "promise 3 result!" }, + ]); + }); + + test("resolves once all arguments are rejected", () => { + util.testFunction` + const { promise: promise1, reject: reject1 } = defer(); + const { promise: promise2, reject: reject2 } = defer(); + const { promise: promise3, reject: reject3 } = defer(); + + const promise = Promise.allSettled([promise1, promise2, promise3]); + promise.then(([result1, result2, result3]) => { + log(result1, result2, result3); + }); + + reject2("promise 2 rejected!"); + reject1("promise 1 rejected!"); + reject3("promise 3 rejected!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + { status: "rejected", reason: "promise 1 rejected!" }, + { status: "rejected", reason: "promise 2 rejected!" }, + { status: "rejected", reason: "promise 3 rejected!" }, + ]); + }); + + test("resolves once all arguments are rejected or resolved", () => { + util.testFunction` + const { promise: promise1, reject: reject1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + const { promise: promise3, reject: reject3 } = defer(); + + const promise = Promise.allSettled([promise1, promise2, promise3]); + promise.then(([result1, result2, result3]) => { + log(result1, result2, result3); + }); + + resolve2("promise 2 resolved!"); + reject1("promise 1 rejected!"); + reject3("promise 3 rejected!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + { status: "rejected", reason: "promise 1 rejected!" }, + { status: "fulfilled", value: "promise 2 resolved!" }, + { status: "rejected", reason: "promise 3 rejected!" }, + ]); + }); + + test("handles already resolved promises", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const returnedPromise = Promise.allSettled([Promise.resolve("already resolved"), promise]); + returnedPromise.then(([result1, result2]) => { + log(result1, result2); + }); + + resolve("promise resolved!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + { status: "fulfilled", value: "already resolved" }, + { status: "fulfilled", value: "promise resolved!" }, + ]); + }); + + test("handles already rejected promises", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const returnedPromise = Promise.allSettled([Promise.reject("already rejected"), promise]); + returnedPromise.then(([result1, result2]) => { + log(result1, result2); + }); + + resolve("promise resolved!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + { status: "rejected", reason: "already rejected" }, + { status: "fulfilled", value: "promise resolved!" }, + ]); + }); + + test("handles literal arguments", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const returnedPromise = Promise.allSettled(["my literal", promise]); + returnedPromise.then(([result1, result2]) => { + log(result1, result2); + }); + + resolve("promise resolved!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + { status: "fulfilled", value: "my literal" }, + { status: "fulfilled", value: "promise resolved!" }, + ]); + }); + + test("returns resolved promise for empty argument list", () => { + util.testFunction` + const { state, value } = Promise.allSettled([]) as any; + return { state, value }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: [], + }); + }); +}); + +describe("Promise.any", () => { + test("resolves once first promise resolves", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + const { promise: promise3, resolve: resolve3 } = defer(); + + const promise = Promise.any([promise1, promise2, promise3]); + promise.then(data => { + log(data); + }); + + resolve2("promise 2 result!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise 2 result!"]); + }); + + test("rejects once all promises reject", () => { + util.testFunction` + const { promise: promise1, reject: reject1 } = defer(); + const { promise: promise2, reject: reject2 } = defer(); + const { promise: promise3, reject: reject3 } = defer(); + + const promise = Promise.any([promise1, promise2, promise3]); + promise.catch(reason => { + log(reason); + }); + + reject2("promise 2 rejected!"); + reject3("promise 3 rejected!"); + reject1("promise 1 rejected!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + { + name: "AggregateError", + message: "All Promises rejected", + errors: ["promise 2 rejected!", "promise 3 rejected!", "promise 1 rejected!"], + }, + ]); + }); + + test("handles already rejected promises", () => { + util.testFunction` + const { promise: promise1, reject: reject1 } = defer(); + const { promise: promise2, reject: reject2 } = defer(); + + const promise = Promise.any([promise1, Promise.reject("already rejected!"), promise2]); + promise.catch(reason => { + log(reason); + }); + + reject2("promise 2 rejected!"); + reject1("promise 1 rejected!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + { + name: "AggregateError", + message: "All Promises rejected", + errors: ["already rejected!", "promise 2 rejected!", "promise 1 rejected!"], + }, + ]); + }); + + test("rejects if iterable is empty", () => { + util.testFunction` + const { state, rejectionReason } = Promise.any([]) as any; + return { state, rejectionReason }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 2, // __TS__PromiseState.Rejected + rejectionReason: "No promises to resolve with .any()", + }); + }); + + test("immediately resolves with literal", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const { state, value } = Promise.any([promise, "my literal"]) as any; + return { state, value }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: "my literal", + }); + }); + + test("immediately resolves with resolved promise", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const { state, value } = Promise.any([promise, Promise.resolve("my resolved promise")]) as any; + return { state, value }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: "my resolved promise", + }); + }); +}); + +describe("Promise.race", () => { + test("resolves once first promise resolves", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + const { promise: promise3, resolve: resolve3 } = defer(); + + const promise = Promise.race([promise1, promise2, promise3]); + promise.then(data => { + log(data); + }); + + resolve2("promise 2 result!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise 2 result!"]); + }); + + test("rejects once first promise rejects", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, reject: reject2 } = defer(); + const { promise: promise3, resolve: resolve3 } = defer(); + + const promise = Promise.race([promise1, promise2, promise3]); + promise.catch(reason => { + log(reason); + }); + + reject2("promise 2 rejected!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise 2 rejected!"]); + }); + + test("returns resolved promise if arguments contain resolved promise", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + + const { state, value } = Promise.race([promise1, Promise.resolve("already resolved!"), promise2]) as any; + return { state, value }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: "already resolved!", + }); + }); + + test("returns resolved promise if arguments contain literal", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + + const { state, value } = Promise.race([promise1, "my literal", promise2]) as any; + return { state, value }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: "my literal", + }); + }); + + test("returns rejected promise if arguments contain rejected promise", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + + const { state, rejectionReason } = Promise.race([promise1, Promise.reject("already rejected!"), promise2]) as any; + return { state, rejectionReason }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 2, // __TS__PromiseState.Rejected + rejectionReason: "already rejected!", + }); + }); + + test("returns forever pending promise if argument array is empty", () => { + util.testFunction` + const { state } = Promise.race([]) as any; + return { state }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 0, // __TS__PromiseState.Pending + }); + }); +}); diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index 00f5c878d..c31ef012f 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -1,3 +1,4 @@ +import { LuaLibImportKind } from "../../../src"; import * as util from "../../util"; test("Supported lua string function", () => { @@ -164,9 +165,9 @@ test.each([ { inp: "hello test", start: 3, ignored: 0, end: 2 }, ])("string.substr with expression (%p)", ({ inp, start, ignored, end }) => { const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); - const result = util.transpileAndExecute(`return "${inp}".substr(${paramStr})`); - - expect(result).toBe(inp.substr(start, end)); + util.testExpression` + "${inp}".substr(${paramStr}) + `.expectToMatchJsResult(); }); test.each(["", "h", "hello"])("string.length (%p)", input => { @@ -193,6 +194,19 @@ test.each([ util.testExpressionTemplate`${inp}.split(${separator})`.expectToMatchJsResult(); }); +test("string.split inline", () => { + util.testExpression`"a, b, c".split(",")` + .setOptions({ luaLibImport: LuaLibImportKind.Inline }) + .expectToMatchJsResult(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1009 +test("string.split inline empty separator", () => { + util.testExpression`"a, b, c".split("")` + .setOptions({ luaLibImport: LuaLibImportKind.Inline }) + .expectToMatchJsResult(); +}); + test.each([ { inp: "hello test", index: 0 }, { inp: "hello test", index: 1 }, @@ -233,6 +247,7 @@ test.each([ test.each<{ inp: string; args: Parameters }>([ { inp: "hello test", args: [""] }, { inp: "hello test", args: ["hello"] }, + { inp: "HELLO test", args: ["hello"] }, { inp: "hello test", args: ["test"] }, { inp: "hello test", args: ["test", 6] }, ])("string.startsWith (%p)", ({ inp, args }) => { @@ -242,12 +257,25 @@ test.each<{ inp: string; args: Parameters }>([ test.each<{ inp: string; args: Parameters }>([ { inp: "hello test", args: [""] }, { inp: "hello test", args: ["test"] }, + { inp: "hello TEST", args: ["test"] }, { inp: "hello test", args: ["hello"] }, { inp: "hello test", args: ["hello", 5] }, ])("string.endsWith (%p)", ({ inp, args }) => { util.testExpression`"${inp}".endsWith(${util.formatCode(...args)})`.expectToMatchJsResult(); }); +test.each<{ inp: string; args: Parameters }>([ + { inp: "hello test", args: [""] }, + { inp: "hello test", args: ["test"] }, + { inp: "HELLO TEST", args: ["test"] }, + { inp: "hello test", args: ["hello"] }, + { inp: "HELLO TEST", args: ["hello"] }, + { inp: "hello test", args: ["hello", 5] }, + { inp: "hello test", args: ["test", 6] }, +])("string.includes (%p)", ({ inp, args }) => { + util.testExpression`"${inp}".includes(${util.formatCode(...args)})`.expectToMatchJsResult(); +}); + test.each([ { inp: "hello test", count: 0 }, { inp: "hello test", count: 1 }, @@ -282,13 +310,12 @@ test.each([ "function generic(string: T)", "type StringType = string; function generic(string: T)", ])("string constrained generic foreach (%p)", signature => { - const code = ` - ${signature}: number { - return string.length; - } - return generic("string"); - `; - expect(util.transpileAndExecute(code)).toBe(6); + util.testFunction` + ${signature}: number { + return string.length; + } + return generic("string"); + `.expectToMatchJsResult(); }); const trimTestCases = [ diff --git a/test/unit/builtins/weakMap.spec.ts b/test/unit/builtins/weakMap.spec.ts index ab3ba12fb..812e43622 100644 --- a/test/unit/builtins/weakMap.spec.ts +++ b/test/unit/builtins/weakMap.spec.ts @@ -6,94 +6,76 @@ const initRefsTs = ` `; test("weakMap constructor", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, 1]]); return mymap.get(ref); - `); - - expect(result).toBe(1); + `.expectToMatchJsResult(); }); test("weakMap iterable constructor", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, 1], [ref2, 2]]); return mymap.has(ref) && mymap.has(ref2); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakMap iterable constructor map", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap(new Map([[ref, 1], [ref2, 2]])); return mymap.has(ref) && mymap.has(ref2); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakMap delete", () => { - const contains = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, true], [ref2, true]]); mymap.delete(ref2); return mymap.has(ref) && !mymap.has(ref2); - `); - - expect(contains).toBe(true); + `.expectToMatchJsResult(); }); test("weakMap get", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, 1], [{}, 2]]); return mymap.get(ref); - `); - - expect(result).toBe(1); + `.expectToMatchJsResult(); }); test("weakMap get missing", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[{}, true]]); return mymap.get({}); - `); - - expect(result).toBeUndefined(); + `.expectToMatchJsResult(); }); test("weakMap has", () => { - const contains = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, true]]); return mymap.has(ref); - `); - - expect(contains).toBe(true); + `.expectToMatchJsResult(); }); test("weakMap has false", () => { - const contains = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, true]]); return mymap.has(ref2); - `); - - expect(contains).toBe(false); + `.expectToMatchJsResult(); }); test("weakMap has null", () => { - const contains = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[{}, true]]); return mymap.has(null); - `); - - expect(contains).toBe(false); + `.expectToMatchJsResult(); }); test("weakMap set", () => { @@ -103,20 +85,20 @@ test("weakMap set", () => { mymap.set(ref, 5); `; - const has = util.transpileAndExecute(init + "return mymap.has(ref);"); - expect(has).toBe(true); + util.testFunction(init + "return mymap.has(ref);").expectToMatchJsResult(); - const value = util.transpileAndExecute(init + "return mymap.get(ref)"); - expect(value).toBe(5); + util.testFunction(init + "return mymap.get(ref)").expectToMatchJsResult(); }); test("weakMap has no map features (size)", () => { - expect(util.transpileAndExecute("return (new WeakMap() as any).size")).toBeUndefined(); + util.testExpression("(new WeakMap() as any).size").expectToMatchJsResult(); }); test.each(["clear()", "keys()", "values()", "entries()", "forEach(() => {})"])( "weakMap has no map features (%p)", call => { - expect(() => util.transpileAndExecute(`(new WeakMap() as any).${call}`)).toThrow(); + const testBuilder = util.testFunction(`(new WeakMap() as any).${call}`); + const luaResult = testBuilder.getLuaExecutionResult(); + expect(luaResult.message).toContain("attempt to call a nil value"); } ); diff --git a/test/unit/builtins/weakSet.spec.ts b/test/unit/builtins/weakSet.spec.ts index fe6accf45..33c5e80c3 100644 --- a/test/unit/builtins/weakSet.spec.ts +++ b/test/unit/builtins/weakSet.spec.ts @@ -6,74 +6,65 @@ const initRefsTs = ` `; test("weakSet constructor", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet([ref]); return myset.has(ref) - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakSet iterable constructor", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet([ref, ref2]); return myset.has(ref) && myset.has(ref2); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakSet iterable constructor set", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet(new Set([ref, ref2])); return myset.has(ref) && myset.has(ref2); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakSet add", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet(); myset.add(ref); return myset.has(ref); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakSet add different references", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet(); myset.add({}); return myset.has({}); - `); - - expect(result).toBe(false); + `.expectToMatchJsResult(); }); test("weakSet delete", () => { - const contains = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet([ref, ref2]); myset.delete(ref); return myset.has(ref2) && !myset.has(ref); - `); - expect(contains).toBe(true); + `.expectToMatchJsResult(); }); test("weakSet has no set features (size)", () => { - expect(util.transpileAndExecute("return (new WeakSet() as any).size")).toBeUndefined(); + util.testExpression("(new WeakSet() as any).size").expectToMatchJsResult(); }); test.each(["clear()", "keys()", "values()", "entries()", "forEach(() => {})"])( "weakSet has no set features (%p)", call => { - expect(() => util.transpileAndExecute(`(new WeakSet() as any).${call}`)).toThrow(); + const testBuilder = util.testFunction(`(new WeakSet() as any).${call}`); + const luaResult = testBuilder.getLuaExecutionResult(); + expect(luaResult.message).toContain("attempt to call a nil value"); } ); diff --git a/test/unit/bundle.spec.ts b/test/unit/bundle.spec.ts index d28f4bf25..b8179363a 100644 --- a/test/unit/bundle.spec.ts +++ b/test/unit/bundle.spec.ts @@ -1,4 +1,4 @@ -import { LuaLibImportKind } from "../../src"; +import { BuildMode, LuaLibImportKind } from "../../src"; import * as diagnosticFactories from "../../src/transpilation/diagnostics"; import * as util from "../util"; @@ -59,6 +59,16 @@ test("entry point in directory", () => { .expectToEqual({ value: true }); }); +test("entry point in rootDir", () => { + util.testModule` + export { value } from "./module"; + ` + .setMainFileName("src/main.ts") + .addExtraFile("src/module.ts", "export const value = true") + .setOptions({ rootDir: "src", luaBundle: "bundle.lua", luaBundleEntry: "src/main.ts" }) + .expectToEqual({ value: true }); +}); + test("LuaLibImportKind.Require", () => { util.testBundle` export const result = [1, 2]; @@ -99,6 +109,29 @@ test("cyclic imports", () => { .expectToEqual(new util.ExecutionError("stack overflow")); }); +test("does not evaluate files multiple times", () => { + util.testBundle` + import "./countingfile"; + import "./otherfile"; + + export const count = _count; + ` + .addExtraFile( + "otherfile.ts", + ` + import "./countingfile"; + ` + ) + .addExtraFile( + "countingfile.ts", + ` + declare var _count: number | undefined; + _count = (_count ?? 0) + 1; + ` + ) + .expectToEqual({ count: 1 }); +}); + test("no entry point", () => { util.testBundle`` .setOptions({ luaBundleEntry: undefined }) @@ -110,3 +143,9 @@ test("luaEntry doesn't exist", () => { .setEntryPoint("entry.ts") .expectDiagnosticsToMatchSnapshot([diagnosticFactories.couldNotFindBundleEntryPoint.code], true); }); + +test("bundling not allowed for buildmode library", () => { + util.testBundle`` + .setOptions({ buildMode: BuildMode.Library }) + .expectDiagnosticsToMatchSnapshot([diagnosticFactories.cannotBundleLibrary.code], true); +}); diff --git a/test/unit/classes/accessors.spec.ts b/test/unit/classes/accessors.spec.ts index 4004a43f2..8a39fb21b 100644 --- a/test/unit/classes/accessors.spec.ts +++ b/test/unit/classes/accessors.spec.ts @@ -23,34 +23,6 @@ test("get accessor in base class", () => { `.expectToMatchJsResult(); }); -test.skip("get accessor override", () => { - util.testFunction` - class Foo { - _foo = "foo"; - foo = "foo"; - } - class Bar extends Foo { - get foo() { return this._foo + "bar"; } - } - const b = new Bar(); - return b.foo; - `.expectToMatchJsResult(); -}); - -test.skip("get accessor overridden", () => { - util.testFunction` - class Foo { - _foo = "foo"; - get foo() { return this._foo; } - } - class Bar extends Foo { - foo = "bar"; - } - const b = new Bar(); - return b.foo; - `.expectToMatchJsResult(); -}); - test("get accessor override accessor", () => { util.testFunction` class Foo { @@ -125,37 +97,6 @@ test("set accessor in base class", () => { `.expectToMatchJsResult(); }); -test("set accessor override", () => { - util.testFunction` - class Foo { - _foo = "foo"; - foo = "foo"; - } - class Bar extends Foo { - set foo(val: string) { this._foo = val; } - } - const b = new Bar(); - b.foo = "bar" - return b._foo; - `.expectToMatchJsResult(); -}); - -test("set accessor overridden", () => { - util.testFunction` - class Foo { - _foo = "baz"; - set foo(val: string) { this._foo = val; } - } - class Bar extends Foo { - foo = "foo"; // triggers base class setter - } - const b = new Bar(); - const fooOriginal = b._foo; - b.foo = "bar" - return fooOriginal + b._foo; - `.expectToMatchJsResult(); -}); - test("set accessor override accessor", () => { util.testFunction` class Foo { @@ -250,19 +191,6 @@ test("static get accessor override", () => { `.expectToMatchJsResult(); }); -test.skip("static get accessor overridden", () => { - util.testFunction` - class Foo { - static _foo = "foo"; - static get foo() { return this._foo; } - } - class Bar extends Foo { - static foo = "bar"; - } - return Bar.foo; - `.expectToMatchJsResult(); -}); - test("static get accessor override accessor", () => { util.testFunction` class Foo { diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index f4c14df34..f9ab4fe61 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -761,3 +761,41 @@ test("constructor class name available with constructor", () => { .setReturnExport("className") .expectToEqual("MyClass"); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/959 +test("methods accessed via this index pass correct context", () => { + util.testModule` + class Example { + baz = 3; + foo() { + this["bar"]() + } + + bar() { + return this.baz; + } + } + + const inst = new Example(); + export const result = inst.foo(); + `.expectToMatchJsResult(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/959 +test.each(['(this["bar"])', '((((this["bar"]))))'])("methods in parentheses pass correct context %s", callPath => { + util.testModule` + class Example { + baz = 3; + foo() { + ${callPath}() + } + + bar() { + return this.baz; + } + } + + const inst = new Example(); + export const result = inst.foo(); + `.expectToMatchJsResult(); +}); diff --git a/test/unit/classes/decorators.spec.ts b/test/unit/classes/decorators.spec.ts index cba245c1f..dadb73655 100644 --- a/test/unit/classes/decorators.spec.ts +++ b/test/unit/classes/decorators.spec.ts @@ -126,3 +126,61 @@ test("Exported class decorator", () => { .setReturnExport("Foo", "bar") .expectToMatchJsResult(); }); + +test.each([ + ["@decorator method() {}"], + ["@decorator property;"], + ["@decorator propertyWithInitializer = () => {};"], + ["@decorator ['evaluated property'];"], + ["@decorator get getter() { return 5 }"], + ["@decorator set setter(value) {}"], + ["@decorator static method() {}"], + ["@decorator static property;"], + ["@decorator static propertyWithInitializer = () => {}"], + ["@decorator static get getter() { return 5 }"], + ["@decorator static set setter(value) {}"], + ["@decorator static ['evaluated property'];"], + ["method(@decorator a) {}"], + ["static method(@decorator a) {}"], +])("Decorate class member (%p)", classMember => { + util.testFunction` + let decoratorParameters: any; + + const decorator = (target, key, index?) => { + const targetKind = target === Foo ? "Foo" : target === Foo.prototype ? "Foo.prototype" : "unknown"; + decoratorParameters = { targetKind, key, index: typeof index }; + }; + + class Foo { + ${classMember} + } + + return decoratorParameters; + `.expectToMatchJsResult(); +}); + +describe("Decorators /w descriptors", () => { + test.each([ + ["return { writable: true }", "return { configurable: true }"], + ["desc.writable = true", "return { configurable: true }"], + ])("Combine decorators (%p + %p)", (decorateA, decorateB) => { + util.testFunction` + const A = (target, key, desc): any => { ${decorateA} }; + const B = (target, key, desc): any => { ${decorateB} }; + class Foo { @A @B static method() {} } + const { value, ...rest } = Object.getOwnPropertyDescriptor(Foo, "method"); + return rest; + `.expectToMatchJsResult(); + }); + + test.each(["return { value: true }", "desc.value = true"])( + "Use decorator to override method value", + overrideStatement => { + util.testFunction` + const decorator = (target, key, desc): any => { ${overrideStatement} }; + class Foo { @decorator static method() {} } + return Foo.method; + `.expectToMatchJsResult(); + } + ); +}); diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index 890c6dc71..c9717d0c0 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -1,5 +1,4 @@ import * as tstl from "../../src"; -import { unsupportedForTarget } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; test.each([0, 1])("if (%p)", inp => { @@ -52,302 +51,6 @@ test.each([0, 1, 2, 3])("ifelseifelse (%p)", inp => { `.expectToMatchJsResult(); }); -test.each([0, 1, 2, 3])("switch (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: - result = 0; - break; - case 1: - result = 1; - break; - case 2: - result = 2; - break; - } - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("switchdefault (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: - result = 0; - break; - case 1: - result = 1; - break; - case 2: - result = 2; - break; - default: - result = -2; - break; - } - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 0, 2, 3, 4, 5, 7])("switchfallthrough (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: - result = 0; - case 1: - result = 1; - break; - case 2: - result = 2; - case 3: - case 4: - result = 4; - break; - case 5: - result = 5; - case 6: - result += 10; - break; - case 7: - result = 7; - default: - result = -2; - break; - } - - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("nestedSwitch (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp} as number) { - case 0: - result = 0; - break; - case 1: - switch(${inp} as number) { - case 0: - result = 0; - break; - case 1: - result = 1; - break; - default: - result = -3; - break; - } - break; - case 2: - result = 2; - break; - default: - result = -2; - break; - } - return result; - `.expectToMatchJsResult(); -}); - -test("switch cases scope", () => { - util.testFunction` - switch (0 as number) { - case 0: - let foo: number | undefined = 1; - case 1: - foo = 2; - case 2: - return foo; - } - `.expectToMatchJsResult(); -}); - -test("variable in nested scope does not interfere with case scope", () => { - util.testFunction` - let foo: number = 0; - switch (foo) { - case 0: { - let foo = 1; - } - - case 1: - return foo; - } - `.expectToMatchJsResult(); -}); - -test("switch using variable re-declared in cases", () => { - util.testFunction` - let foo: number = 0; - switch (foo) { - case 0: - let foo = true; - case 1: - return foo; - } - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2])("switch with block statement scope (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: { - let x = 0; - result = 0; - break; - } - case 1: { - let x = 1; - result = x; - } - case 2: { - let x = 2; - result = x; - break; - } - } - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("switchReturn (%p)", inp => { - util.testFunction` - switch (${inp}) { - case 0: - return 0; - break; - case 1: - return 1; - case 2: - return 2; - break; - } - - return -1; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("switchWithBrackets (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: { - result = 0; - break; - } - case 1: { - result = 1; - break; - } - case 2: { - result = 2; - break; - } - } - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("switchWithBracketsBreakInConditional (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: { - result = 0; - break; - } - case 1: { - result = 1; - - if (result == 1) break; - } - case 2: { - result = 2; - break; - } - } - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("switchWithBracketsBreakInInternalLoop (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp} as number) { - case 0: { - result = 0; - - for (let i = 0; i < 5; i++) { - result++; - - if (i >= 2) { - break; - } - } - } - case 1: { - result++; - break; - } - case 2: { - result = 2; - break; - } - } - return result; - `.expectToMatchJsResult(); -}); - -test("switch uses elseif", () => { - test("array", () => { - util.testFunction` - let result: number = -1; - - switch (2 as number) { - case 0: { - result = 200; - break; - } - - case 1: { - result = 100; - break; - } - - case 2: { - result = 1; - break; - } - } - - return result; - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); -}); - -test("switch not allowed in 5.1", () => { - util.testFunction` - switch ("abc") {} - ` - .setOptions({ luaTarget: tstl.LuaTarget.Lua51 }) - .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); -}); - test.each([ { input: "true ? 'a' : 'b'" }, { input: "false ? 'a' : 'b'" }, @@ -368,9 +71,6 @@ test.each([ { input: "true ? false : true", options: { luaTarget: tstl.LuaTarget.Lua51 } }, { input: "false ? false : true", options: { luaTarget: tstl.LuaTarget.Lua51 } }, { input: "true ? undefined : true", options: { luaTarget: tstl.LuaTarget.Lua51 } }, - { input: "true ? false : true", options: { luaTarget: tstl.LuaTarget.LuaJIT } }, - { input: "false ? false : true", options: { luaTarget: tstl.LuaTarget.LuaJIT } }, - { input: "true ? undefined : true", options: { luaTarget: tstl.LuaTarget.LuaJIT } }, ])("Ternary operator (%p)", ({ input, options }) => { util.testFunction` const literalValue = "literal"; diff --git a/test/unit/destructuring.spec.ts b/test/unit/destructuring.spec.ts index 761930ec2..2ec12c7d1 100644 --- a/test/unit/destructuring.spec.ts +++ b/test/unit/destructuring.spec.ts @@ -12,6 +12,8 @@ const testCases = [ { binding: "{ ...rest }", value: {} }, { binding: "{ x, ...rest }", value: { x: "x" } }, { binding: "{ x, ...rest }", value: { x: "x", y: "y", z: "z" } }, + { binding: "{ x, ...y }", value: { x: "x", y: "y", z: "z" } }, + { binding: "{ x: y, ...z }", value: { x: "x", y: "y", z: "z" } }, { binding: "[]", value: [] }, { binding: "[x, y]", value: ["x", "y"] }, diff --git a/test/unit/enum.spec.ts b/test/unit/enum.spec.ts index 8da16355c..f421be2c5 100644 --- a/test/unit/enum.spec.ts +++ b/test/unit/enum.spec.ts @@ -154,3 +154,52 @@ test("toString", () => { return foo(TestEnum.A); `.expectToMatchJsResult(); }); + +test("enum merging", () => { + util.testFunction` + enum TestEnum { + A, B + } + + enum TestEnum { + C = 3, + D + } + + return ${serializeEnum("TestEnum")} + `.expectToMatchJsResult(); +}); + +test("enum merging with overlap", () => { + util.testFunction` + enum TestEnum { + A, B + } + + enum TestEnum { + C = 1, + D + } + + return ${serializeEnum("TestEnum")} + `.expectToMatchJsResult(); +}); + +test("enum merging multiple files", () => { + util.testModule` + import "./otherfile" + enum TestEnum { + A, B + } + + export default ${serializeEnum("TestEnum")} + ` + .addExtraFile( + "otherfile.ts", + `enum TestEnum { + C = 3, + D + }` + ) + .expectToMatchJsResult(); +}); diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index 27e0ce839..0c24503f0 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -51,7 +51,7 @@ test("re-throw (no catch var)", () => { }); test("return from try", () => { - const code = ` + util.testFunction` function foobar() { try { return "foobar"; @@ -59,12 +59,11 @@ test("return from try", () => { } } return foobar(); - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("return nil from try", () => { - const code = ` + util.testFunction` let x = "unset"; function foobar() { try { @@ -75,28 +74,26 @@ test("return nil from try", () => { } foobar(); return x; - `; - expect(util.transpileAndExecute(code)).toBe("unset"); + `.expectToMatchJsResult(); }); -test("tuple return from try", () => { - const code = ` - /** @tupleReturn */ +test("multi return from try", () => { + const testBuilder = util.testFunction` function foobar() { try { - return ["foo", "bar"]; + return $multi("foo", "bar"); } catch { } } const [foo, bar] = foobar(); return foo + bar; - `; - expect(util.transpileString(code)).not.toMatch("unpack(foobar"); - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.withLanguageExtensions(); + expect(testBuilder.getMainLuaCodeChunk()).not.toMatch("unpack(foobar"); + testBuilder.expectToMatchJsResult(); }); test("return from catch", () => { - const code = ` + util.testFunction` function foobar() { try { throw "foobar"; @@ -105,12 +102,11 @@ test("return from catch", () => { } } return foobar(); - `; - expect(util.transpileAndExecute(code)).toMatch(/foobar catch$/); + `.expectToMatchJsResult(); }); test("return nil from catch", () => { - const code = ` + util.testFunction` let x = "unset"; function foobar() { try { @@ -122,29 +118,27 @@ test("return nil from catch", () => { } foobar(); return x; - `; - expect(util.transpileAndExecute(code)).toBe("unset"); + `.expectToMatchJsResult(); }); -test("tuple return from catch", () => { - const code = ` - /** @tupleReturn */ - function foobar(): [string, string] { +test("multi return from catch", () => { + const testBuilder = util.testFunction` + function foobar(): LuaMultiReturn<[string, string]> { try { throw "foobar"; } catch (e) { - return [e.toString(), " catch"]; + return $multi(e.toString(), " catch"); } } const [foo, bar] = foobar(); return foo + bar; - `; - expect(util.transpileString(code)).not.toMatch("unpack(foobar"); - expect(util.transpileAndExecute(code)).toMatch(/foobar catch$/); + `.withLanguageExtensions(); + expect(testBuilder.getMainLuaCodeChunk()).not.toMatch("unpack(foobar"); + testBuilder.expectToMatchJsResult(); }); test("return from nested try", () => { - const code = ` + util.testFunction` function foobar() { try { try { @@ -155,12 +149,11 @@ test("return from nested try", () => { } } return foobar(); - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("return from nested catch", () => { - const code = ` + util.testFunction` function foobar() { try { throw "foobar"; @@ -173,15 +166,11 @@ test("return from nested catch", () => { } } return foobar(); - `; - const result = util.transpileAndExecute(code); - expect(result).toMatch("catch1"); - expect(result).toMatch("catch2"); - expect(result).toMatch("foobar"); + `.expectToMatchJsResult(); }); test("return from try->finally", () => { - const code = ` + util.testFunction` let x = "unevaluated"; function evaluate(arg: unknown) { x = "evaluated"; @@ -196,12 +185,11 @@ test("return from try->finally", () => { } } return foobar() + " " + x; - `; - expect(util.transpileAndExecute(code)).toBe("finally evaluated"); + `.expectToMatchJsResult(); }); test("return from catch->finally", () => { - const code = ` + util.testFunction` let x = "unevaluated"; function evaluate(arg: unknown) { x = "evaluated"; @@ -217,57 +205,56 @@ test("return from catch->finally", () => { } } return foobar() + " " + x; - `; - expect(util.transpileAndExecute(code)).toBe("finally evaluated"); + `.expectToMatchJsResult(); }); -test("tuple return from try->finally", () => { - const code = ` +test("multi return from try->finally", () => { + util.testFunction` let x = "unevaluated"; function evaluate(arg: string) { x = "evaluated"; return arg; } - /** @tupleReturn */ function foobar() { try { - return [evaluate("foo"), "bar"]; + return $multi(evaluate("foo"), "bar"); } catch { } finally { - return ["final", "ly"]; + return $multi("final", "ly"); } } const [foo, bar] = foobar(); return foo + bar + " " + x; - `; - expect(util.transpileAndExecute(code)).toBe("finally evaluated"); + ` + .withLanguageExtensions() + .expectToMatchJsResult(); }); -test("tuple return from catch->finally", () => { - const code = ` +test("multi return from catch->finally", () => { + util.testFunction` let x = "unevaluated"; function evaluate(arg: string) { x = "evaluated"; return arg; } - /** @tupleReturn */ function foobar() { try { throw "foo"; } catch (e) { - return [evaluate(e), "bar"]; + return $multi(evaluate(e), "bar"); } finally { - return ["final", "ly"]; + return $multi("final", "ly"); } } const [foo, bar] = foobar(); return foo + bar + " " + x; - `; - expect(util.transpileAndExecute(code)).toBe("finally evaluated"); + ` + .withLanguageExtensions() + .expectToMatchJsResult(); }); test("return from nested finally", () => { - const code = ` + util.testFunction` let x = ""; function foobar() { try { @@ -282,8 +269,7 @@ test("return from nested finally", () => { } } return foobar() + " " + x; - `; - expect(util.transpileAndExecute(code)).toBe("finally AB"); + `.expectToMatchJsResult(); }); test.each([ diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 6720fe8fb..71c014fda 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -30,12 +30,10 @@ test.each(["1==1", "1===1", "1!=1", "1!==1", "1>1", "1>=1", "1<1", "1<=1", "1&&1 ); test.each(["'key' in obj", "'existingKey' in obj", "0 in obj", "9 in obj"])("Binary expression in (%p)", input => { - const tsHeader = "declare var obj: any;"; - const tsSource = `return ${input}`; - const luaHeader = "obj = { existingKey = 1 }"; - const result = util.transpileAndExecute(tsSource, undefined, luaHeader, tsHeader); - - expect(result).toBe(eval(`let obj = { existingKey: 1 }; ${input}`)); + util.testFunction` + let obj = { existingKey: 1 }; + return ${input}; + `.expectToMatchJsResult(); }); test.each(["a+=b", "a-=b", "a*=b", "a/=b", "a%=b", "a**=b"])("Binary expressions overridden operators (%p)", input => { @@ -48,8 +46,8 @@ test.each(["a+=b", "a-=b", "a*=b", "a/=b", "a%=b", "a**=b"])("Binary expressions }); const supportedInAll = ["~a", "a&b", "a&=b", "a|b", "a|=b", "a^b", "a^=b", "a<>>b", "a>>>=b"]; -const unsupportedIn53 = ["a>>b", "a>>=b"]; -const allBinaryOperators = [...supportedInAll, ...unsupportedIn53]; +const unsupportedIn53And54 = ["a>>b", "a>>=b"]; +const allBinaryOperators = [...supportedInAll, ...unsupportedIn53And54]; test.each(allBinaryOperators)("Bitop [5.1] (%p)", input => { // Bit operations not supported in 5.1, expect an exception util.testExpression(input) @@ -79,13 +77,27 @@ test.each(supportedInAll)("Bitop [5.3] (%p)", input => { .expectLuaToMatchSnapshot(); }); -test.each(unsupportedIn53)("Unsupported bitop 5.3 (%p)", input => { +test.each(supportedInAll)("Bitop [5.4] (%p)", input => { + util.testExpression(input) + .setOptions({ luaTarget: tstl.LuaTarget.Lua54, luaLibImport: tstl.LuaLibImportKind.None }) + .disableSemanticCheck() + .expectLuaToMatchSnapshot(); +}); + +test.each(unsupportedIn53And54)("Unsupported bitop 5.3 (%p)", input => { util.testExpression(input) .setOptions({ luaTarget: tstl.LuaTarget.Lua53, luaLibImport: tstl.LuaLibImportKind.None }) .disableSemanticCheck() .expectDiagnosticsToMatchSnapshot([unsupportedRightShiftOperator.code]); }); +test.each(unsupportedIn53And54)("Unsupported bitop 5.4 (%p)", input => { + util.testExpression(input) + .setOptions({ luaTarget: tstl.LuaTarget.Lua54, luaLibImport: tstl.LuaLibImportKind.None }) + .disableSemanticCheck() + .expectDiagnosticsToMatchSnapshot([unsupportedRightShiftOperator.code]); +}); + test.each(["1+1", "-1+1", "1*30+4", "1*(3+4)", "1*(3+4*2)", "10-(4+5)"])( "Binary expressions ordering parentheses (%p)", input => { @@ -119,11 +131,11 @@ test("Binary Comma Statement in For Loop", () => { }); test("Null Expression", () => { - expect(util.transpileString("null")).toBe("local ____ = nil"); + util.testExpression("null").expectLuaToMatchSnapshot(); }); test("Undefined Expression", () => { - expect(util.transpileString("undefined")).toBe("local ____ = nil"); + util.testExpression("undefined").expectLuaToMatchSnapshot(); }); test.each(["i++", "i--", "++i", "--i"])("Incrementor value (%p)", expression => { diff --git a/test/unit/file.spec.ts b/test/unit/file.spec.ts new file mode 100644 index 000000000..12a136408 --- /dev/null +++ b/test/unit/file.spec.ts @@ -0,0 +1,41 @@ +import * as util from "../util"; + +describe("JSON", () => { + test.each([0, "", [], [1, "2", []], { a: "b" }, { a: { b: "c" } }])("JSON (%p)", json => { + util.testModule(JSON.stringify(json)).setMainFileName("main.json").expectToEqual(json); + }); + + test("empty file throws runtime error", () => { + util.testModule("") + .setMainFileName("main.json") + .expectToEqual(new util.ExecutionError("Unexpected end of JSON input")); + }); + + test("JSON modules can be imported", () => { + util.testModule` + import * as jsonData from "./jsonModule.json"; + export const result = jsonData; + ` + .addExtraFile("jsonModule.json", '{ "jsonField1": "hello, this is JSON", "jsonField2": ["a", "b", "c"] }') + .expectToEqual({ + result: { + jsonField1: "hello, this is JSON", + jsonField2: ["a", "b", "c"], + }, + }); + }); +}); + +describe("shebang", () => { + test("LF", () => { + util.testModule`#!/usr/bin/env lua\n + const foo = true; + `.expectLuaToMatchSnapshot(); + }); + + test("CRLF", () => { + util.testModule`#!/usr/bin/env lua\r\n + const foo = true; + `.expectLuaToMatchSnapshot(); + }); +}); diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index 20f76e273..2d9d8f1e3 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -66,19 +66,12 @@ test("Function default parameter", () => { }); test.each([{ inp: [] }, { inp: [5] }, { inp: [1, 2] }])("Function Default Values (%p)", ({ inp }) => { - // Default value is 3 for v1 - const v1 = inp.length > 0 ? inp[0] : 3; - // Default value is 4 for v2 - const v2 = inp.length > 1 ? inp[1] : 4; - const callArgs = inp.join(","); - const result = util.transpileAndExecute( + util.testFunction( `let add = function(a: number = 3, b: number = 4) { return a+b; }; return add(${callArgs});` - ); - - expect(result).toBe(v1 + v2); + ).expectToMatchJsResult(); }); test("Function default array binding parameter", () => { @@ -476,7 +469,8 @@ test("missing declaration name", () => { }); test("top-level function declaration is global", () => { - util.testBundle` + // Can't be tested with expectToMatchJsResult because in JS that would not be global + util.testModule` import './a'; export const result = foo(); ` diff --git a/test/unit/functions/generators.spec.ts b/test/unit/functions/generators.spec.ts index 90fb67aa4..7065aecf6 100644 --- a/test/unit/functions/generators.spec.ts +++ b/test/unit/functions/generators.spec.ts @@ -51,6 +51,59 @@ test("for..of", () => { `.expectToMatchJsResult(); }); +describe("yield*", () => { + test("generator", () => { + util.testFunction` + function* subGenerator() { + yield 1; + yield 2; + yield 3; + } + + function* generator() { + yield 0; + return yield* subGenerator(); + } + + const it = generator(); + return [it.next(), it.next(), it.next(), it.next(), it.next()]; + `.expectToMatchJsResult(); + }); + + test("array", () => { + util.testFunction` + function* generator() { + return yield* [1, 2, 3]; + } + + const it = generator(); + return [it.next(), it.next(), it.next(), it.next()]; + `.expectToMatchJsResult(); + }); + + test("string", () => { + util.testFunction` + function* generator() { + return yield* "abc"; + } + + const it = generator(); + return [it.next(), it.next(), it.next(), it.next()]; + `.expectToMatchJsResult(); + }); + + test("iterable", () => { + util.testFunction` + function* generator() { + return yield* new Set([1, 2, 3]); + } + + const it = generator(); + return [it.next(), it.next(), it.next(), it.next()]; + `.expectToMatchJsResult(); + }); +}); + test("function expression", () => { util.testFunction` const generator = function*() { diff --git a/test/unit/functions/noImplicitSelfOption.spec.ts b/test/unit/functions/noImplicitSelfOption.spec.ts index f61e37cb2..2da1d9722 100644 --- a/test/unit/functions/noImplicitSelfOption.spec.ts +++ b/test/unit/functions/noImplicitSelfOption.spec.ts @@ -1,3 +1,4 @@ +import { couldNotResolveRequire } from "../../../src/transpilation/diagnostics"; import * as util from "../../util"; test("enables noSelfInFile behavior for functions", () => { @@ -31,10 +32,13 @@ test("generates declaration files with @noSelfInFile", () => { const fooDeclaration = fooBuilder.getLuaResult().transpiledFiles.find(f => f.declaration)?.declaration; util.assert(fooDeclaration !== undefined); + expect(fooDeclaration).toContain("@noSelfInFile"); + util.testModule` - import { bar } from "./foo.d"; + import { bar } from "./foo"; const test: (this: void) => void = bar; ` .addExtraFile("foo.d.ts", fooDeclaration) + .ignoreDiagnostics([couldNotResolveRequire.code]) // no foo implementation in the project to create foo.lua .expectToHaveNoDiagnostics(); }); diff --git a/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap b/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap index 55e61f9ae..7ed8e7560 100644 --- a/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap +++ b/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap @@ -247,7 +247,7 @@ exports[`Invalid function argument ({"definition": "interface FuncPropInterface const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function argument ({"definition": "interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function argument ({"definition": "interface NoSelfMethodInterface { /** @noSelf */ @@ -639,7 +639,7 @@ exports[`Invalid function assignment ({"definition": "interface FuncPropInterfac const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function assignment ({"definition": "interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function assignment ({"definition": "interface NoSelfMethodInterface { /** @noSelf */ @@ -1031,7 +1031,7 @@ exports[`Invalid function generic argument ({"definition": "interface FuncPropIn const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function generic argument ({"definition": "interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function generic argument ({"definition": "interface NoSelfMethodInterface { /** @noSelf */ @@ -1391,7 +1391,7 @@ exports[`Invalid function return ({"definition": "interface FuncPropInterface { const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function return ({"definition": "interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function return ({"definition": "interface NoSelfMethodInterface { /** @noSelf */ @@ -1791,7 +1791,7 @@ exports[`Invalid function variable declaration ({"definition": "interface FuncPr const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function variable declaration ({"definition": "interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function variable declaration ({"definition": "interface NoSelfMethodInterface { /** @noSelf */ diff --git a/test/unit/functions/validation/functionExpressionTypeInference.spec.ts b/test/unit/functions/validation/functionExpressionTypeInference.spec.ts index e475f2216..abac4e483 100644 --- a/test/unit/functions/validation/functionExpressionTypeInference.spec.ts +++ b/test/unit/functions/validation/functionExpressionTypeInference.spec.ts @@ -13,7 +13,7 @@ test.each(["noSelf", "noSelfInFile"])("noSelf function method argument (%p)", no const c = new NS.C(); return c.method(foo); `; - expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foo"); + util.testFunction(code).setTsHeader(header).expectToMatchJsResult(); }); test("noSelfInFile works when first statement has other annotations", () => { @@ -30,20 +30,21 @@ test("noSelfInFile works when first statement has other annotations", () => { test.each(["(this: void, s: string) => string", "(this: any, s: string) => string", "(s: string) => string"])( "Function expression type inference in binary operator (%p)", funcType => { - const header = `declare const undefinedFunc: ${funcType};`; - const code = ` - let func: ${funcType} = s => s; - func = undefinedFunc || (s => s); - return func("foo"); - `; - expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foo"); + const header = `let undefinedFunc: (${funcType}) | undefined;`; + util.testFunction` + let func: ${funcType} = s => s; + func = undefinedFunc || (s => s); + return func("foo"); + ` + .setTsHeader(header) + .expectToMatchJsResult(); } ); test.each(["s => s", "(s => s)", "function(s) { return s; }", "(function(s) { return s; })"])( "Function expression type inference in class (%p)", funcExp => { - const code = ` + util.testFunction` class Foo { func: (this: void, s: string) => string = ${funcExp}; method: (s: string) => string = ${funcExp}; @@ -52,8 +53,7 @@ test.each(["s => s", "(s => s)", "function(s) { return s; }", "(function(s) { re } const foo = new Foo(); return foo.func("a") + foo.method("b") + Foo.staticFunc("c") + Foo.staticMethod("d"); - `; - expect(util.transpileAndExecute(code)).toBe("abcd"); + `.expectToMatchJsResult(); } ); @@ -67,23 +67,21 @@ test.each([ { assignTo: "let foo: Foo; foo", funcExp: "function(s) { return s; }" }, { assignTo: "let foo: Foo; foo", funcExp: "(function(s) { return s; })" }, ])("Function expression type inference in object literal (%p)", ({ assignTo, funcExp }) => { - const code = ` + util.testFunction` interface Foo { func(this: void, s: string): string; method(this: this, s: string): string; } ${assignTo} = {func: ${funcExp}, method: ${funcExp}}; return foo.method("foo") + foo.func("bar"); - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("Function expression type inference in object literal assigned to narrower type", () => { - const code = ` + util.testFunction` let foo: {} = {bar: s => s}; return (foo as {bar: (a: any) => any}).bar("foobar"); - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test.each([ @@ -96,14 +94,13 @@ test.each([ { assignTo: "let foo: Foo; foo", funcExp: "function(s) { return s; }" }, { assignTo: "let foo: Foo; foo", funcExp: "(function(s) { return s; })" }, ])("Function expression type inference in object literal (generic key) (%p)", ({ assignTo, funcExp }) => { - const code = ` - interface Foo { - [f: string]: (this: void, s: string) => string; - } - ${assignTo} = {func: ${funcExp}}; - return foo.func("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + util.testFunction` + interface Foo { + [f: string]: (this: void, s: string) => string; + } + ${assignTo} = {func: ${funcExp}}; + return foo.func("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -204,7 +201,7 @@ test.each([ funcExp: "(function(s) { return s; })", }, ])("Function expression type inference in tuple (%p)", ({ assignTo, func, method, funcExp }) => { - const code = ` + util.testFunction` interface Foo { method(s: string): string; } @@ -217,8 +214,7 @@ test.each([ ${assignTo} = [${funcExp}, ${funcExp}]; const foo: Foo = {method: ${method}}; return foo.method("foo") + ${func}("bar"); - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test.each([ @@ -239,7 +235,7 @@ test.each([ { assignTo: "let meth: Method; [meth]", method: "meth", funcExp: "function(s) { return s; }" }, { assignTo: "let meth: Method; [meth]", method: "meth", funcExp: "(function(s) { return s; })" }, ])("Function expression type inference in array (%p)", ({ assignTo, method, funcExp }) => { - const code = ` + util.testFunction` interface Foo { method(s: string): string; } @@ -249,8 +245,7 @@ test.each([ ${assignTo} = [${funcExp}]; const foo: Foo = {method: ${method}}; return foo.method("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -261,12 +256,11 @@ test.each([ { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, ])("Function expression type inference in union (%p)", ({ funcType, funcExp }) => { - const code = ` + util.testFunction` type U = string | number | (${funcType}); const u: U = ${funcExp}; return (u as ${funcType})("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -277,12 +271,11 @@ test.each([ { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, ])("Function expression type inference in union tuple (%p)", ({ funcType, funcExp }) => { - const code = ` + util.testFunction` interface I { callback: ${funcType}; } let a: I[] | number = [{ callback: ${funcExp} }]; return a[0].callback("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -293,11 +286,10 @@ test.each([ { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, ])("Function expression type inference in as cast (%p)", ({ funcType, funcExp }) => { - const code = ` + util.testFunction` const fn: ${funcType} = (${funcExp}) as (${funcType}); return fn("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -308,11 +300,10 @@ test.each([ { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, ])("Function expression type inference in type assertion (%p)", ({ funcType, funcExp }) => { - const code = ` + util.testFunction` const fn: ${funcType} = <${funcType}>(${funcExp}); return fn("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -323,13 +314,12 @@ test.each([ { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, ])("Function expression type inference in constructor (%p)", ({ funcType, funcExp }) => { - const code = ` + util.testFunction` class C { result: string; constructor(fn: ${funcType}) { this.result = fn("foo"); } } const c = new C(${funcExp}); return c.result; - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); diff --git a/test/unit/functions/validation/functionPermutations.ts b/test/unit/functions/validation/functionPermutations.ts index ebf00dfae..f95af8ab3 100644 --- a/test/unit/functions/validation/functionPermutations.ts +++ b/test/unit/functions/validation/functionPermutations.ts @@ -87,7 +87,7 @@ export const selfTestFunctions: TestFunction[] = [ { value: "methodInterface.method", definition: `interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }`, + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };`, }, { value: "anonMethodInterface.anonMethod", diff --git a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts index 7d678496b..cd12b4ba8 100644 --- a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts @@ -10,7 +10,7 @@ test.each(invalidTestFunctionAssignments)( "Invalid function variable declaration (%p)", (testFunction, functionType, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} const fn: ${functionType} = ${testFunction.value}; `.expectDiagnosticsToMatchSnapshot( [isSelfConversion ? unsupportedSelfFunctionConversion.code : unsupportedNoSelfFunctionConversion.code], @@ -23,7 +23,7 @@ test.each(invalidTestFunctionAssignments)( "Invalid function assignment (%p)", (testFunction, functionType, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} let fn: ${functionType}; fn = ${testFunction.value}; `.expectDiagnosticsToMatchSnapshot( @@ -35,7 +35,7 @@ test.each(invalidTestFunctionAssignments)( test.each(invalidTestFunctionCasts)("Invalid function assignment with cast (%p)", (testFunction, castedFunction) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} let fn: typeof ${testFunction.value}; fn = ${castedFunction}; `.expectDiagnosticsToMatchSnapshot( @@ -48,7 +48,7 @@ test.each(invalidTestFunctionAssignments)( "Invalid function argument (%p)", (testFunction, functionType, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} declare function takesFunction(fn: ${functionType}); takesFunction(${testFunction.value}); `.expectDiagnosticsToMatchSnapshot( @@ -68,7 +68,7 @@ test("Invalid lua lib function argument", () => { test.each(invalidTestFunctionCasts)("Invalid function argument with cast (%p)", (testFunction, castedFunction) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} declare function takesFunction(fn: typeof ${testFunction.value}); takesFunction(${castedFunction}); `.expectDiagnosticsToMatchSnapshot( @@ -81,7 +81,7 @@ test.each(invalidTestFunctionAssignments)( "Invalid function generic argument (%p)", (testFunction, functionType, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} declare function takesFunction(fn: T); takesFunction(${testFunction.value}); `.expectDiagnosticsToMatchSnapshot( @@ -95,7 +95,7 @@ test.each(invalidTestFunctionAssignments)( "Invalid function return (%p)", (testFunction, functionType, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} function returnsFunction(): ${functionType} { return ${testFunction.value}; } @@ -110,7 +110,7 @@ test.each(invalidTestFunctionCasts)( "Invalid function return with cast (%p)", (testFunction, castedFunction, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} function returnsFunction(): typeof ${testFunction.value} { return ${castedFunction}; } diff --git a/test/unit/functions/validation/validFunctionAssignments.spec.ts b/test/unit/functions/validation/validFunctionAssignments.spec.ts index a491ccd7b..d9613692d 100644 --- a/test/unit/functions/validation/validFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/validFunctionAssignments.spec.ts @@ -15,54 +15,64 @@ import { } from "./functionPermutations"; test.each(validTestFunctionAssignments)("Valid function variable declaration (%p)", (testFunction, functionType) => { - const code = `const fn: ${functionType} = ${testFunction.value}; - return fn("foobar");`; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + const fn: ${functionType} = ${testFunction.value}; + return fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each(validTestFunctionAssignments)("Valid function assignment (%p)", (testFunction, functionType) => { - const code = `let fn: ${functionType}; - fn = ${testFunction.value}; - return fn("foobar");`; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + let fn: ${functionType}; + fn = ${testFunction.value}; + return fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each(validTestFunctionCasts)("Valid function assignment with cast (%p)", (testFunction, castedFunction) => { - const code = ` - let fn: typeof ${testFunction.value}; - fn = ${castedFunction}; - return fn("foobar"); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + let fn: typeof ${testFunction.value}; + fn = ${castedFunction}; + return fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each(validTestFunctionAssignments)("Valid function argument (%p)", (testFunction, functionType) => { - const code = ` - function takesFunction(fn: ${functionType}) { - return fn("foobar"); - } - return takesFunction(${testFunction.value}); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + function takesFunction(fn: ${functionType}) { + return fn("foobar"); + } + return takesFunction(${testFunction.value}); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test("Valid lua lib function argument", () => { - const code = `let result = ""; + util.testFunction` + let result = ""; function foo(this: any, value: string) { result += value; } const a = ['foo', 'bar']; a.forEach(foo); - return result;`; - expect(util.transpileAndExecute(code)).toBe("foobar"); + return result; + `.expectToMatchJsResult(); }); test.each(validTestFunctionCasts)("Valid function argument with cast (%p)", (testFunction, castedFunction) => { - const code = ` - function takesFunction(fn: typeof ${testFunction.value}) { - return fn("foobar"); - } - return takesFunction(${castedFunction}); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + function takesFunction(fn: typeof ${testFunction.value}) { + return fn("foobar"); + } + return takesFunction(${castedFunction}); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each([ @@ -77,60 +87,66 @@ test.each([ ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), ...noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), ])("Valid function generic argument (%p)", (testFunction, functionType) => { - const code = ` + util.testFunction` function takesFunction(fn: T) { return fn("foobar"); } return takesFunction(${testFunction.value}); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each([ ...anonTestFunctionExpressions.map((f): [TestFunction, string[]] => [f, ["0", "'foobar'"]]), ...selfTestFunctionExpressions.map((f): [TestFunction, string[]] => [f, ["0", "'foobar'"]]), ...noSelfTestFunctionExpressions.map((f): [TestFunction, string[]] => [f, ["'foobar'"]]), -])("Valid function expression argument with no signature (%p)", (testFunction, args) => { - const code = ` +])("Valid function expression argument with no signature (%p, %p)", (testFunction, args) => { + util.testFunction` const takesFunction: any = (fn: (this: void, ...args: any[]) => any, ...args: any[]) => { return fn(...args); } return takesFunction(${testFunction.value}, ${args.join(", ")}); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToEqual("foobar"); }); test.each(validTestFunctionAssignments)("Valid function return (%p)", (testFunction, functionType) => { - const code = ` - function returnsFunction(): ${functionType} { - return ${testFunction.value}; - } - const fn = returnsFunction(); - return fn("foobar"); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + function returnsFunction(): ${functionType} { + return ${testFunction.value}; + } + const fn = returnsFunction(); + return fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each(validTestFunctionCasts)("Valid function return with cast (%p)", (testFunction, castedFunction) => { - const code = `function returnsFunction(): typeof ${testFunction.value} { - return ${castedFunction}; - } - const fn = returnsFunction(); - return fn("foobar");`; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + function returnsFunction(): typeof ${testFunction.value} { + return ${castedFunction}; + } + const fn = returnsFunction(); + return fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test("Valid function tuple assignment", () => { - const code = `interface Func { (this: void, s: string): string; } - function getTuple(): [number, Func] { return [1, s => s]; } - let [i, f]: [number, Func] = getTuple(); - return f("foo");`; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); + util.testFunction` + interface Func { (this: void, s: string): string; } + function getTuple(): [number, Func] { return [1, s => s]; } + let [i, f]: [number, Func] = getTuple(); + return f("foo"); + `.expectToMatchJsResult(); }); test("Interface method assignment", () => { - const code = ` + util.testFunction` class Foo { method(s: string): string { return s + "+method"; } lambdaProp: (s: string) => string = s => s + "+lambdaProp"; @@ -141,46 +157,44 @@ test("Interface method assignment", () => { } const foo: IFoo = new Foo(); return foo.method("foo") + "|" + foo.lambdaProp("bar"); - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo+method|bar+lambdaProp"); + `.expectToMatchJsResult(); }); test("Valid interface method assignment", () => { - const code = `interface A { fn(this: void, s: string): string; } - interface B { fn(this: void, s: string): string; } - const a: A = { fn(this: void, s) { return s; } }; - const b: B = a; - return b.fn("foo");`; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); + util.testFunction` + interface A { fn(this: void, s: string): string; } + interface B { fn(this: void, s: string): string; } + const a: A = { fn(this: void, s) { return s; } }; + const b: B = a; + return b.fn("foo"); + `.expectToMatchJsResult(); }); test("Valid method tuple assignment", () => { - const code = `interface Foo { method(s: string): string; } - interface Meth { (this: Foo, s: string): string; } - let meth: Meth = s => s; - function getTuple(): [number, Meth] { return [1, meth]; } - let [i, f]: [number, Meth] = getTuple(); - let foo: Foo = {method: f}; - return foo.method("foo");`; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); + util.testFunction` + interface Foo { method(s: string): string; } + interface Meth { (this: Foo, s: string): string; } + let meth: Meth = s => s; + function getTuple(): [number, Meth] { return [1, meth]; } + let [i, f]: [number, Meth] = getTuple(); + let foo: Foo = {method: f}; + return foo.method("foo"); + `.expectToMatchJsResult(); }); test.each([ - { assignType: "(this: any, s: string) => string", args: ["foo"], expectResult: "foobar" }, - { assignType: "{(this: any, s: string): string}", args: ["foo"], expectResult: "foobar" }, - { assignType: "(this: any, s1: string, s2: string) => string", args: ["foo", "baz"], expectResult: "foobaz" }, - { assignType: "{(this: any, s1: string, s2: string): string}", args: ["foo", "baz"], expectResult: "foobaz" }, -])("Valid function overload assignment (%p)", ({ assignType, args, expectResult }) => { - const code = `interface O { - (s1: string, s2: string): string; - (s: string): string; - } - const o: O = (s1: string, s2?: string) => s1 + (s2 || "bar"); - let f: ${assignType} = o; - return f(${args.map(a => '"' + a + '"').join(", ")});`; - const result = util.transpileAndExecute(code); - expect(result).toBe(expectResult); + { assignType: "(this: any, s: string) => string", args: ["foo"] }, + { assignType: "{(this: any, s: string): string}", args: ["foo"] }, + { assignType: "(this: any, s1: string, s2: string) => string", args: ["foo", "baz"] }, + { assignType: "{(this: any, s1: string, s2: string): string}", args: ["foo", "baz"] }, +])("Valid function overload assignment (%p)", ({ assignType, args }) => { + util.testFunction` + interface O { + (s1: string, s2: string): string; + (s: string): string; + } + const o: O = (s1: string, s2?: string) => s1 + (s2 || "bar"); + let f: ${assignType} = o; + return f(${args.map(a => '"' + a + '"').join(", ")}); + `.expectToMatchJsResult(); }); diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index 997c53f73..144460067 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -2,110 +2,101 @@ import * as ts from "typescript"; import * as util from "../util"; test.each(["let", "const"])("Let/Const Hoisting (%p)", varType => { - const code = ` + util.testFunction` let bar: string; function setBar() { bar = foo; } ${varType} foo = "foo"; setBar(); return foo; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test.each(["let", "const"])("Exported Let/Const Hoisting (%p)", varType => { - const code = ` + util.testModule` let bar: string; function setBar() { bar = foo; } export ${varType} foo = "foo"; setBar(); - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test("Global Function Hoisting", () => { - const code = ` + util.testFunction` const foo = bar(); function bar() { return "bar"; } return foo; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("bar"); + `.expectToMatchJsResult(); }); test("Local Function Hoisting", () => { - const code = ` + util.testModule` export const foo = bar(); function bar() { return "bar"; } - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("bar"); + `.expectToMatchJsResult(); }); test("Exported Function Hoisting", () => { - const code = ` + util.testModule` const foo = bar(); export function bar() { return "bar"; } export const baz = foo; - `; - const result = util.transpileExecuteAndReturnExport(code, "baz"); - expect(result).toBe("bar"); + ` + .setReturnExport("baz") + .expectToMatchJsResult(); }); test("Namespace Function Hoisting", () => { - const code = ` - let foo: string; - namespace NS { - foo = bar(); - function bar() { return "bar"; } - } - `; - const result = util.transpileAndExecute("return foo;", undefined, undefined, code); - expect(result).toBe("bar"); + util.testFunction` + return foo; + ` + .setTsHeader( + ` + let foo: string; + namespace NS { + foo = bar(); + function bar() { return "bar"; } + } + ` + ) + .expectToMatchJsResult(); }); test("Exported Namespace Function Hoisting", () => { - const code = ` - let foo: string; - namespace NS { - foo = bar(); - export function bar() { return "bar"; } - } - `; - const result = util.transpileAndExecute("return foo;", undefined, undefined, code); - expect(result).toBe("bar"); + util.testFunction("return foo;") + .setTsHeader( + ` + let foo: string; + namespace NS { + foo = bar(); + export function bar() { return "bar"; } + } + ` + ) + .expectToMatchJsResult(); }); -test.each([ - { varType: "let", expectResult: "bar" }, - { varType: "const", expectResult: "bar" }, -])("Hoisting in Non-Function Scope (%p)", ({ varType, expectResult }) => { - const code = ` - function foo() { - ${varType} bar = "bar"; - for (let i = 0; i < 1; ++i) { - ${varType} bar = "foo"; - } - return bar; +test.each(["let", "const"])("Hoisting in Non-Function Scope (%p)", varType => { + util.testFunction` + function foo() { + ${varType} bar = "bar"; + for (let i = 0; i < 1; ++i) { + ${varType} bar = "foo"; } - return foo(); - `; - const result = util.transpileAndExecute(code); - expect(result).toBe(expectResult); + return bar; + } + return foo(); + `.expectToMatchJsResult(); }); test("Hoisting due to reference from hoisted function", () => { - const code = ` + util.testFunction` const foo = "foo"; const result = bar(); function bar() { return foo; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test("Hoisting with synthetic source file node", () => { @@ -116,9 +107,9 @@ test("Hoisting with synthetic source file node", () => { .setCustomTransformers({ before: [ () => sourceFile => - ts.updateSourceFileNode( + ts.factory.updateSourceFile( sourceFile, - [ts.createNotEmittedStatement(undefined!), ...sourceFile.statements], + [ts.factory.createNotEmittedStatement(undefined!), ...sourceFile.statements], sourceFile.isDeclarationFile, sourceFile.referencedFiles, sourceFile.typeReferenceDirectives, @@ -131,7 +122,7 @@ test("Hoisting with synthetic source file node", () => { }); test("Namespace Hoisting", () => { - const code = ` + util.testModule` function bar() { return NS.foo; } @@ -139,13 +130,11 @@ test("Namespace Hoisting", () => { export let foo = "foo"; } export const foo = bar(); - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test("Exported Namespace Hoisting", () => { - const code = ` + util.testModule` function bar() { return NS.foo; } @@ -153,9 +142,7 @@ test("Exported Namespace Hoisting", () => { export let foo = "foo"; } export const foo = bar(); - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test("Nested Namespace Hoisting", () => { @@ -176,7 +163,7 @@ test("Nested Namespace Hoisting", () => { }); test("Class Hoisting", () => { - const code = ` + util.testModule` function makeFoo() { return new Foo(); } @@ -184,13 +171,11 @@ test("Class Hoisting", () => { public bar = "foo"; } export const foo = makeFoo().bar; - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test("Enum Hoisting", () => { - const code = ` + util.testModule` function bar() { return E.A; } @@ -198,13 +183,14 @@ test("Enum Hoisting", () => { A = "foo" } export const foo = bar(); - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); + `.expectToHaveNoDiagnostics(); }); test("Import hoisting (named)", () => { - util.testBundle` + // TODO cant be tested with expectToEqualJSResult because of + // the scuffed module setup in TestBuilder.executeJs (module hoisting is not possible) + // should be updated once vm.module becomes stable + util.testModule` export const result = foo; import { foo } from "./module"; ` @@ -213,16 +199,22 @@ test("Import hoisting (named)", () => { }); test("Import hoisting (namespace)", () => { - util.testBundle` - export const result = module.foo; - import * as module from "./module"; + // TODO cant be tested with expectToEqualJSresult because of + // the scuffed module setup in TestBuilder.executeJs (module hoisting is not possible) + // should be updated once vm.module becomes stable + util.testModule` + export const result = m.foo; + import * as m from "./module"; ` .addExtraFile("module.ts", "export const foo = true;") .expectToEqual({ result: true }); }); test("Import hoisting (side-effect)", () => { - util.testBundle` + // TODO cant be tested with expectToEqualJSResult because of + // the scuffed module setup in TestBuilder.executeJs (module hoisting is not possible) + // should be updated once vm.module becomes stable + util.testModule` export const result = (globalThis as any).result; import "./module"; ` @@ -231,7 +223,8 @@ test("Import hoisting (side-effect)", () => { }); test("Import hoisted before function", () => { - util.testBundle` + // Can't use expectToMatchJsResult because above is not valid TS/JS + util.testModule` export let result: any; baz(); @@ -246,11 +239,22 @@ test("Import hoisted before function", () => { }); test("Hoisting Shorthand Property", () => { - const code = ` + util.testFunction` function foo() { return { bar }.bar; } let bar = "foobar"; - return foo();`; - expect(util.transpileAndExecute(code)).toBe("foobar"); + return foo(); + `.expectToMatchJsResult(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/944 +test("Hoisting variable without initializer", () => { + util.testFunction` + function foo() { + return x; + } + let x: number; + return foo(); + `.expectToMatchJsResult(); }); diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index ba2bcd8a0..9f72ad671 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -132,20 +132,21 @@ test.each(validTsInvalidLuaNames)( ); test.each(validTsInvalidLuaNames)("exported values with invalid lua identifier names (%p)", name => { - const code = `export const ${name} = "foobar";`; - const lua = util.transpileString(code); + const testBuilder = util.testModule(`export const ${name} = "foobar";`); + const lua = testBuilder.getMainLuaCodeChunk(); + const luaResult = testBuilder.getLuaExecutionResult(); expect(lua.indexOf(`"${name}"`)).toBeGreaterThanOrEqual(0); - expect(util.executeLua(`return (function() ${lua} end)()["${name}"]`)).toBe("foobar"); + expect(luaResult[name]).toBe("foobar"); }); test("exported identifiers referenced in namespace (%p)", () => { - const code = ` + util.testModule` export const foo = "foobar"; namespace NS { export const bar = foo; } - export const baz = NS.bar;`; - expect(util.transpileExecuteAndReturnExport(code, "baz")).toBe("foobar"); + export const baz = NS.bar; + `.expectToMatchJsResult(); }); test("exported namespace identifiers referenced in different namespace (%p)", () => { @@ -157,31 +158,31 @@ test("exported namespace identifiers referenced in different namespace (%p)", () } export const baz = B.bar; }`; - expect(util.transpileAndExecute("return A.baz", undefined, undefined, tsHeader)).toBe("foobar"); + util.testFunction("return A.baz").setTsHeader(tsHeader).expectToMatchJsResult(); }); test("exported identifiers referenced in nested scope (%p)", () => { - const code = ` + util.testModule` export const foo = "foobar"; namespace A { export namespace B { export const bar = foo; } } - export const baz = A.B.bar;`; - expect(util.transpileExecuteAndReturnExport(code, "baz")).toBe("foobar"); + export const baz = A.B.bar; + `.expectToMatchJsResult(); }); test.each(validTsInvalidLuaNames)( "exported values with invalid lua identifier names referenced in different scope (%p)", name => { - const code = ` - export const ${name} = "foobar"; - namespace NS { - export const foo = ${name}; - } - export const bar = NS.foo;`; - expect(util.transpileExecuteAndReturnExport(code, "bar")).toBe("foobar"); + util.testModule` + export const ${name} = "foobar"; + namespace NS { + export const foo = ${name}; + } + export const bar = NS.foo; + `.expectToMatchJsResult(); } ); @@ -223,103 +224,92 @@ test.each(validTsInvalidLuaNames)("exported decorated class with invalid lua nam describe("lua keyword as identifier doesn't interfere with lua's value", () => { test("variable (nil)", () => { - const code = ` + util.testFunction` const nil = "foobar"; - return \`\${undefined}|\${nil}\``; - - expect(util.transpileAndExecute(code)).toBe("nil|foobar"); + return \`\${undefined}|\${nil}\` + `.expectToEqual("nil|foobar"); }); test("variable (and)", () => { - const code = ` + util.testFunction` const and = "foobar"; - return true && and;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return true && and; + `.expectToMatchJsResult(); }); test("variable (elseif)", () => { - const code = ` + util.testFunction` const elseif = "foobar"; if (false) { } else if (elseif) { return elseif; - }`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + } + `.expectToMatchJsResult(); }); test("variable (end)", () => { - const code = ` + util.testFunction` const end = "foobar"; { return end; - }`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + } + `.expectToMatchJsResult(); }); test("variable (local)", () => { - const code = ` + util.testFunction` const local = "foobar"; - return local;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return local; + `.expectToMatchJsResult(); }); test("variable (not)", () => { - const code = ` + util.testFunction` const not = "foobar"; - return (!false) && not;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return (!false) && not; + `.expectToMatchJsResult(); }); test("variable (or)", () => { - const code = ` + util.testFunction` const or = "foobar"; - return false || or;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return false || or; + `.expectToMatchJsResult(); }); test("variable (repeat)", () => { - const code = ` + util.testFunction` const repeat = "foobar"; do {} while (false); - return repeat;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return repeat; + `.expectToMatchJsResult(); }); test("variable (then)", () => { - const code = ` + util.testFunction` const then = "foobar"; if (then) { return then; - }`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + } + `.expectToMatchJsResult(); }); test("variable (until)", () => { - const code = ` + util.testFunction` const until = "foobar"; do {} while (false); - return until;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return until; + `.expectToMatchJsResult(); }); test("variable (goto)", () => { - const code = ` + util.testFunction` const goto = "foobar"; switch (goto) { case goto: return goto; - }`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + } + `.expectToMatchJsResult(); }); test("variable (print)", () => { @@ -332,42 +322,48 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const tsHeader = ` declare let result: string;`; - const code = ` - const print = "foobar"; - console.log(print); - return result;`; - const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; - expect(util.transpileAndExecute(code, compilerOptions, luaHeader, tsHeader)).toBe("foobar"); + util.testFunction` + const print = "foobar"; + console.log(print); + return result; + ` + .setLuaHeader(luaHeader) + .setTsHeader(tsHeader) + .setOptions(compilerOptions) + .expectToEqual("foobar"); }); test("variable (type)", () => { - const code = ` + util.testFunction` function type(this: void, a: unknown) { return (typeof a) + "|foobar"; } - return type(7);`; - - expect(util.transpileAndExecute(code)).toBe("number|foobar"); + return type(7); + `.expectToMatchJsResult(); }); test("variable (error)", () => { - const code = ` + const executionResult = util.testFunction` const error = "foobar"; - throw error;`; + throw error; + `.getLuaExecutionResult(); - expect(() => util.transpileAndExecute(code)).toThrow(/^LUA ERROR: foobar$/); + expect(executionResult).toEqual(new util.ExecutionError("foobar")); }); test("variable (assert)", () => { - const code = ` - const assert = false; - console.assert(assert, "foobar");`; - const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; - expect(() => util.transpileAndExecute(code, compilerOptions)).toThrow(/^LUA ERROR: .+ foobar$/); + const luaResult = util.testFunction` + const assert = false; + console.assert(assert, "foobar"); + ` + .setOptions(compilerOptions) + .getLuaExecutionResult(); + + expect(luaResult).toEqual(new util.ExecutionError("foobar")); }); test("variable (debug)", () => { @@ -380,297 +376,272 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const tsHeader = ` declare let result: string;`; - const code = ` + const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; + + const luaResult = util.testFunction` const debug = "foobar"; console.trace(debug); - return result;`; - - const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; + return result; + ` + .setTsHeader(tsHeader) + .setLuaHeader(luaHeader) + .setOptions(compilerOptions) + .getLuaExecutionResult(); - expect(util.transpileAndExecute(code, compilerOptions, luaHeader, tsHeader)).toMatch( - /^foobar\nstack traceback.+/ - ); + expect(luaResult).toMatch(/^foobar\nstack traceback.+/); }); test("variable (string)", () => { - const code = ` + util.testFunction` const string = "foobar"; - return string[0];`; - - expect(util.transpileAndExecute(code)).toBe("f"); + return string[0]; + `.expectToMatchJsResult(); }); test("variable (math)", () => { - const code = ` + util.testFunction` const math = -17; - return Math.abs(math);`; - - expect(util.transpileAndExecute(code)).toBe(17); + return Math.abs(math); + `.expectToMatchJsResult(); }); test("variable (table)", () => { - const code = ` + util.testFunction` const table = ["foobar"]; - return table.pop();`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return table.pop(); + `.expectToMatchJsResult(); }); test("variable (coroutine)", () => { - const code = ` + util.testFunction` const coroutine = "foobar"; function *foo() { yield coroutine; } - return foo().next().value;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return foo().next().value; + `.expectToMatchJsResult(); }); test("variable (pairs)", () => { - const code = ` + util.testFunction` const pairs = {foobar: "foobar"}; let result = ""; for (const key in pairs) { result += key; } - return result;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return result; + `.expectToMatchJsResult(); }); test("variable (pcall)", () => { - const code = ` + util.testFunction` const pcall = "foobar"; try {} finally {} - return pcall;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return pcall; + `.expectToMatchJsResult(); }); test("variable (rawget)", () => { - const code = ` + util.testFunction` const rawget = {foobar: "foobar"}; - return rawget.hasOwnProperty("foobar");`; - - expect(util.transpileAndExecute(code)).toBe(true); + return rawget.hasOwnProperty("foobar"); + `.expectToMatchJsResult(); }); test("variable (require)", () => { - const code = ` + const luaHeader = 'package.loaded.someModule = {foo = "bar"}'; + + const luaResult = util.testModule` const require = "foobar"; export { foo } from "someModule"; - export const result = require;`; - - const lua = ` - package.loaded.someModule = {foo = "bar"} - return (function() - ${util.transpileString(code, undefined, true)} - end)().result`; + export const result = require; + ` + .setLuaHeader(luaHeader) + .getLuaExecutionResult(); - expect(util.executeLua(lua)).toBe("foobar"); + expect(luaResult.result).toBe("foobar"); }); test("variable (tostring)", () => { - const code = ` + util.testFunction` const tostring = 17; - return tostring.toString();`; - - expect(util.transpileAndExecute(code)).toBe(17); + return tostring.toString(); + `.expectToMatchJsResult(); }); test("variable (unpack)", () => { - const code = ` - const unpack = ["foo", "bar"]; - const [foo, bar] = unpack;`; + // Can't use expectToMatchJsResult because above is not valid TS/JS + const luaHeader = "unpack = table.unpack"; - const lua = ` - unpack = table.unpack - ${util.transpileString(code, undefined, false)} - return foo .. bar`; + const luaResult = util.testFunction` + const unpack = ["foo", "bar"]; + const [foo, bar] = unpack; + return foo + bar; + ` + .setLuaHeader(luaHeader) + .getLuaExecutionResult(); - expect(util.executeLua(lua)).toBe("foobar"); + expect(luaResult).toBe("foobar"); }); test("variable (_G)", () => { - const code = ` + util.testFunction` const _G = "bar"; (globalThis as any).foo = "foo"; return (globalThis as any).foo + _G; - `; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("function parameter", () => { - const code = ` + util.testFunction` function foo(type: unknown) { return \`\${typeof type}|\${type}\`; } - return foo("foobar");`; - - expect(util.transpileAndExecute(code)).toBe("string|foobar"); + return foo("foobar"); + `.expectToMatchJsResult(); }); test("destructured property function parameter", () => { - const code = ` + util.testFunction` function foo({type}: any) { return \`\${typeof type}|\${type}\`; } - return foo({type: "foobar"});`; - - expect(util.transpileAndExecute(code)).toBe("string|foobar"); + return foo({type: "foobar"}); + `.expectToMatchJsResult(); }); test("destructured array element function parameter", () => { - const code = ` + util.testFunction` function foo([type]: any) { return \`\${typeof type}|\${type}\`; } - return foo(["foobar"]);`; - - expect(util.transpileAndExecute(code)).toBe("string|foobar"); + return foo(["foobar"]); + `.expectToMatchJsResult(); }); test("property", () => { - const code = ` + util.testFunction` const type = "foobar"; const foo = { type: type }; - return type + "|" + foo.type + "|" + typeof type;`; - - expect(util.transpileAndExecute(code)).toBe("foobar|foobar|string"); + return type + "|" + foo.type + "|" + typeof type; + `.expectToMatchJsResult(); }); test("shorthand property", () => { - const code = ` + util.testFunction` const type = "foobar"; const foo = { type }; - return type + "|" + foo.type + "|" + typeof type;`; - - expect(util.transpileAndExecute(code)).toBe("foobar|foobar|string"); + return type + "|" + foo.type + "|" + typeof type; + `.expectToMatchJsResult(); }); test("destructured property", () => { - const code = ` + util.testFunction` const foo = { type: "foobar" }; const { type: type } = foo; - return type + "|" + foo.type + "|" + typeof type;`; - - expect(util.transpileAndExecute(code)).toBe("foobar|foobar|string"); + return type + "|" + foo.type + "|" + typeof type; + `.expectToMatchJsResult(); }); test("destructured shorthand property", () => { - const code = ` + util.testFunction` const foo = { type: "foobar" }; const { type } = foo; - return type + "|" + foo.type + "|" + typeof type;`; - - expect(util.transpileAndExecute(code)).toBe("foobar|foobar|string"); + return type + "|" + foo.type + "|" + typeof type; + `.expectToMatchJsResult(); }); test("destructured array element", () => { - const code = ` + util.testFunction` const foo = ["foobar"]; const [type] = foo; - return type + "|" + typeof type;`; - - expect(util.transpileAndExecute(code)).toBe("foobar|string"); + return type + "|" + typeof type; + `.expectToMatchJsResult(); }); test.each(["type", "type as type"])("imported variable (%p)", importName => { - const luaHeader = ` - package.loaded.someModule = {type = "foobar"}`; + // Can't use expectToMatchJsResult because above is not valid TS/JS + const luaHeader = 'package.loaded.someModule = {type = "foobar"}'; - const code = ` + const luaResult = util.testModule` import {${importName}} from "someModule"; export const result = typeof 7 + "|" + type; - `; - - const lua = util.transpileString(code); - const result = util.executeLua(`${luaHeader} return (function() ${lua} end)().result`); + ` + .setLuaHeader(luaHeader) + .getLuaExecutionResult(); - expect(result).toBe("number|foobar"); + expect(luaResult.result).toBe("number|foobar"); }); - test.each([ - { returnExport: "type", expectResult: "foobar" }, - { returnExport: "mytype", expectResult: "foobar" }, - { returnExport: "result", expectResult: "string|foobar" }, - ])("separately exported variable (%p)", ({ returnExport, expectResult }) => { - const code = ` + test("separately exported variable (%p)", () => { + util.testModule` const type = "foobar"; export { type } export { type as mytype } - export const result = typeof type + "|" + type;`; - - expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + export const result = typeof type + "|" + type; + `.expectToMatchJsResult(); }); test.each(["type", "type as type"])("re-exported variable with lua keyword as name (%p)", importName => { - const code = ` - export { ${importName} } from "someModule"`; + // Can't use expectToMatchJsResult because above is not valid TS/JS - const lua = ` - package.loaded.someModule = {type = "foobar"} - return (function() - ${util.transpileString(code)} - end)().type`; + const luaHeader = 'package.loaded.someModule = {type = "foobar"}'; - expect(util.executeLua(lua)).toBe("foobar"); + const luaResult = util.testModule` + export { ${importName} } from "someModule"; + ` + .setLuaHeader(luaHeader) + .getLuaExecutionResult(); + + expect(luaResult.type).toBe("foobar"); }); test("class", () => { - const code = ` + util.testFunction` class type { method() { return typeof 0; } static staticMethod() { return typeof "foo"; } } const t = new type(); - return t.method() + "|" + type.staticMethod();`; - - expect(util.transpileAndExecute(code)).toBe("number|string"); + return t.method() + "|" + type.staticMethod(); + `.expectToMatchJsResult(); }); test("subclass of class", () => { - const code = ` + util.testFunction` class type { method() { return typeof 0; } static staticMethod() { return typeof "foo"; } } class Foo extends type {} const foo = new Foo(); - return foo.method() + "|" + Foo.staticMethod();`; - - expect(util.transpileAndExecute(code)).toBe("number|string"); + return foo.method() + "|" + Foo.staticMethod(); + `.expectToMatchJsResult(); }); - test.each([ - { returnExport: "result", expectResult: "number|string" }, - { returnExport: "type ~= nil", expectResult: true }, - ])("exported class (%p)", ({ returnExport, expectResult }) => { - const code = ` + test.each(["result", "type ~= nil"])("exported class (%p)", returnExport => { + util.testModule` export class type { method() { return typeof 0; } static staticMethod() { return typeof "foo"; } } const t = new type(); - export const result = t.method() + "|" + type.staticMethod();`; - - expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + export const result = t.method() + "|" + type.staticMethod(); + ` + .setReturnExport(returnExport) + .expectToMatchJsResult(); }); - test.each([ - { returnExport: "result", expectResult: "number|string" }, - { returnExport: "type ~= nil", expectResult: true }, - ])("subclass of exported class (%p)", ({ returnExport, expectResult }) => { - const code = ` + test.each(["result", "type ~= nil"])("subclass of exported class (%p)", returnExport => { + util.testModule` export class type { method() { return typeof 0; } static staticMethod() { return typeof "foo"; } } class Foo extends type {} const foo = new Foo(); - export const result = foo.method() + "|" + Foo.staticMethod();`; - - expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + export const result = foo.method() + "|" + Foo.staticMethod(); + ` + .setReturnExport(returnExport) + .expectToMatchJsResult(); }); test("namespace", () => { @@ -682,20 +653,16 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const code = ` return typeof type.foo + "|" + type.foo`; - expect(util.transpileAndExecute(code, undefined, undefined, tsHeader)).toBe("string|foobar"); + util.testFunction(code).setTsHeader(tsHeader).expectToMatchJsResult(); }); - test.each([ - { returnExport: "result", expectResult: "string|foobar" }, - { returnExport: "type ~= nil", expectResult: true }, - ])("exported namespace (%p)", ({ returnExport, expectResult }) => { - const code = ` + test("exported namespace (%p)", () => { + util.testModule` export namespace type { export const foo = "foobar"; } - export const result = typeof type.foo + "|" + type.foo;`; - - expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + export const result = typeof type.foo + "|" + type.foo; + `.expectToMatchJsResult(); }); test("merged namespace", () => { @@ -717,14 +684,11 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const t = new type(); return \`\${t.method()}|\${type.staticMethod()}|\${typeof type.foo}|\${type.foo}|\${type.bar}\`;`; - expect(util.transpileAndExecute(code, undefined, undefined, tsHeader)).toBe("number|boolean|string|foo|bar"); + util.testFunction(code).setTsHeader(tsHeader).expectToMatchJsResult(); }); - test.each([ - { returnExport: "result", expectResult: "number|boolean|string|foo|bar" }, - { returnExport: "type ~= nil", expectResult: true }, - ])("exported merged namespace (%p)", ({ returnExport, expectResult }) => { - const code = ` + test.each(["result", "type ~= nil"])("exported merged namespace (%p)", returnExport => { + util.testModule` export class type { method() { return typeof 0; } static staticMethod() { return typeof true; } @@ -739,25 +703,23 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { } const t = new type(); - export const result = \`\${t.method()}|\${type.staticMethod()}|\${typeof type.foo}|\${type.foo}|\${type.bar}\`;`; - - expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + export const result = \`\${t.method()}|\${type.staticMethod()}|\${typeof type.foo}|\${type.foo}|\${type.bar}\`; + ` + .setReturnExport(returnExport) + .expectToMatchJsResult(); }); }); test("declaration-only variable with lua keyword as name is not renamed", () => { - const code = ` - declare function type(this: void, a: unknown): string; - type(7);`; - - expect(util.transpileString(code, undefined, false)).toBe("type(7)"); + util.testFunction("type(7)") + .setTsHeader("declare function type(this: void, a: unknown): string;") + .expectLuaToMatchSnapshot(); }); test("exported variable with lua keyword as name is not renamed", () => { - const code = ` - export const print = "foobar";`; - - expect(util.transpileExecuteAndReturnExport(code, "print")).toBe("foobar"); + util.testModule` + export const print = "foobar"; + `.expectToMatchJsResult(); }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/846 diff --git a/test/unit/json.spec.ts b/test/unit/json.spec.ts deleted file mode 100644 index 2f4b0d6a5..000000000 --- a/test/unit/json.spec.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as util from "../util"; - -test.each([0, "", [], [1, "2", []], { a: "b" }, { a: { b: "c" } }])("JSON (%p)", json => { - util.testModule(JSON.stringify(json)).setMainFileName("main.json").expectToEqual(json); -}); - -test("Empty JSON file error", () => { - util.testModule("") - .setMainFileName("main.json") - .expectToEqual(new util.ExecutionError("Unexpected end of JSON input")); -}); diff --git a/test/unit/jsx.spec.ts b/test/unit/jsx.spec.ts new file mode 100644 index 000000000..5734b33ee --- /dev/null +++ b/test/unit/jsx.spec.ts @@ -0,0 +1,361 @@ +import * as util from "../util"; +import { TestBuilder } from "../util"; +import { JsxEmit } from "typescript"; + +// language=TypeScript +const reactLib = ` + export class Component { + static isClass = true + } + + namespace React { + const isLua = typeof Component === "object" + + export function createElement( + this: void, + type: any, + props?: any, + ...children: any[] + ) { + let typeStr: string + if (isLua) { + typeStr = + typeof type === "function" ? "<< function >>" : + typeof type === "object" ? \`<< class \${type.name} >>\` : + type + } else { + typeStr = typeof type === "function" ? (type.isClass ? \`<< class \${type.name} >>\` : "<< function >>") + : type + } + + return { + type: typeStr, + props, + children + }; + } + + export class Fragment extends Component { + } + } + export default React; +`; +// language=TypeScript +const jsxTypings = `declare namespace JSX { + interface IntrinsicElements { + a: any + b: any + foo: any + bar: any + div: any + "with-dash": any + } +} +`; + +function testJsx(...args: [string] | [TemplateStringsArray, ...any[]]): TestBuilder { + return util + .testFunction(...args) + .setOptions({ + jsx: JsxEmit.React, + }) + .setMainFileName("main.tsx") + .addExtraFile("react.ts", reactLib) + .addExtraFile("jsx.d.ts", jsxTypings) + .setTsHeader('import React, { Component } from "./react";'); +} + +describe("jsx", () => { + test("element", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("self closing element", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("element with dash name", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("custom element", () => { + testJsx` + function Foo() {} + return + `.expectToMatchJsResult(); + }); + test("fragment", () => { + testJsx` + return <> + `.expectToMatchJsResult(); + }); + test("fragment with children", () => { + testJsx` + return <> + `.expectToMatchJsResult(); + }); + test("esoteric component names", () => { + testJsx` + class _Foo extends Component {} + return <_Foo /> + `.expectToMatchJsResult(); + + testJsx` + class $ extends Component {} + return <$ /> + `.expectToMatchJsResult(); + + testJsx` + class é extends Component {} + return <é /> + `.expectToMatchJsResult(); + }); + test("nested elements", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("many nested elements", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("interpolated children", () => { + testJsx` + const x = 3 + return {x} + `.expectToMatchJsResult(); + }); + test("string prop", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("value prop", () => { + testJsx` + const x = 5 + return + `.expectToMatchJsResult(); + }); + test("quoted prop", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("shorthand prop", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("spaces in jsxText", () => { + testJsx` + return this + is somemultiline + text thing. + + + `.expectToMatchJsResult(); + }); + test("multiline string jsxText", () => { + testJsx` + return + foo bar + baz + + `.expectToMatchJsResult(); + }); + + test("access tag value", () => { + testJsx` + const a = { b(){} }; + return + `.expectToMatchJsResult(); + testJsx` + const a = { b: { c: { d(){} } } }; + return + `.expectToMatchJsResult(); + }); + + test("spread props", () => { + testJsx` + const x = {c: "d", e: "f"} + return + `.expectToMatchJsResult(); + testJsx` + const x = {c: "d", e: "no"} + return + `.expectToMatchJsResult(); + }); + + test("comment children", () => { + testJsx` + return + {/* comment */} + {/* another comment */} + + `.expectToMatchJsResult(); + testJsx` + return + + {/* comment */} + + + `.expectToMatchJsResult(); + }); + + test("multiline string prop value", () => { + testJsx` + return
+ `.expectToMatchJsResult(); + testJsx` + return
+ `.expectToMatchJsResult(); + }); + + test("prop strings with entities", () => { + testJsx` + return
+ `.expectToMatchJsResult(); + }); + test("jsxText with entities", () => { + testJsx` + return 9+10<21 + `.expectToMatchJsResult(); + }); + + test("Spread children", () => { + // doesn't actually "spread" (typescript's current behavior) + testJsx` + const children = [, ] + return {...children} + `.expectToMatchJsResult(); + }); + + test("complex", () => { + testJsx` + const x = 3 + const props = {one: "two", three: 4} + return + `.expectToMatchJsResult(); + }); + + // language=TypeScript + const customJsxLib = `export namespace MyLib { + export function myCreate( + this: void, + type: any, + props: any, + ...children: any[] + ) { + return { type: typeof type, props, children, myThing: true }; + } + + export function MyFragment() { + } + } + `; + + test("custom JSX factory", () => { + testJsx` + return c + ` + .setTsHeader('import { MyLib } from "./myJsx";') + .setOptions({ jsxFactory: "MyLib.myCreate" }) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + testJsx` + return c + ` + .setTsHeader('import { MyLib } from "./myJsx";const myCreate2 = MyLib.myCreate;') + .setOptions({ jsxFactory: "myCreate2" }) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + }); + test("custom fragment factory", () => { + testJsx` + return <>c + ` + .setTsHeader('import { MyLib } from "./myJsx";') + .setOptions({ jsxFactory: "MyLib.myCreate", jsxFragmentFactory: "MyLib.MyFragment" }) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + testJsx` + return <>c + ` + .setTsHeader('import { MyLib } from "./myJsx";function MyFragment2(){};') + .setOptions({ jsxFactory: "MyLib.myCreate", jsxFragmentFactory: "MyFragment2" }) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + }); + test("custom JSX pragma", () => { + testJsx` + return c + ` + .setTsHeader('/** @jsx MyLib.myCreate */\nimport { MyLib } from "./myJsx";') + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + testJsx` + return c + ` + .setTsHeader('/** @jsx myCreate2 */import { MyLib } from "./myJsx";const myCreate2 = MyLib.myCreate;') + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + }); + test("custom fragment pragma", () => { + testJsx` + return <>c + ` + .setTsHeader( + '/** @jsx MyLib.myCreate */\n/** @jsxFrag MyLib.MyFragment */\nimport { MyLib } from "./myJsx";' + ) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + testJsx` + return <>c + ` + .setTsHeader( + "/** @jsx MyLib.myCreate */\n/** @jsxFrag MyFragment2 */\n" + + 'import { MyLib } from "./myJsx";function MyFragment2(){};' + ) + .setOptions({ jsxFactory: "MyLib.myCreate", jsxFragmentFactory: "MyFragment" }) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + }); + + test("forward declare components", () => { + testJsx` + const foo = + + function Foo(){} + + return foo + `.expectToMatchJsResult(); + }); + + test("invalid jsx config", () => { + testJsx(` + return + `) + .setOptions({ + jsx: JsxEmit.Preserve, + }) + .expectToHaveDiagnostics(); + }); +}); diff --git a/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap b/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap new file mode 100644 index 000000000..1f76110a4 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap @@ -0,0 +1,52 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`LuaIterable with LuaMultiReturn value type invalid LuaIterable without destructuring ("for (const s of testIterable()) {}"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function testIterable() + local strsArray = {{\\"a1\\", \\"a2\\"}, {\\"b1\\", \\"b2\\"}, {\\"c1\\", \\"c2\\"}} + local i = 0 + return function() + local strs = strsArray[(function() + local ____tmp = i + i = ____tmp + 1 + return ____tmp + end)() + 1] + if strs then + return table.unpack(strs) + end + end + end + for ____ in testIterable() do + end +end +return ____exports" +`; + +exports[`LuaIterable with LuaMultiReturn value type invalid LuaIterable without destructuring ("for (const s of testIterable()) {}"): diagnostics 1`] = `"main.ts(14,24): error TSTL: LuaIterable with a LuaMultiReturn return value type must be destructured."`; + +exports[`LuaIterable with LuaMultiReturn value type invalid LuaIterable without destructuring ("let s; for (s of testIterable()) {}"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function testIterable() + local strsArray = {{\\"a1\\", \\"a2\\"}, {\\"b1\\", \\"b2\\"}, {\\"c1\\", \\"c2\\"}} + local i = 0 + return function() + local strs = strsArray[(function() + local ____tmp = i + i = ____tmp + 1 + return ____tmp + end)() + 1] + if strs then + return table.unpack(strs) + end + end + end + local s + for ____ in testIterable() do + end +end +return ____exports" +`; + +exports[`LuaIterable with LuaMultiReturn value type invalid LuaIterable without destructuring ("let s; for (s of testIterable()) {}"): diagnostics 1`] = `"main.ts(14,25): error TSTL: LuaIterable with a LuaMultiReturn return value type must be destructured."`; diff --git a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap new file mode 100644 index 000000000..36b928202 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap @@ -0,0 +1,255 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`disallow LuaMultiReturn non-numeric access: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function multi(self, ...) + return ... + end + return select( + \\"forEach\\", + multi(nil) + ) +end +return ____exports" +`; + +exports[`disallow LuaMultiReturn non-numeric access: code 2`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function multi(self, ...) + return ... + end + return ({ + multi(nil) + }).forEach +end +return ____exports" +`; + +exports[`disallow LuaMultiReturn non-numeric access: diagnostics 1`] = `"main.ts(7,16): error TSTL: The LuaMultiReturn type can only be accessed via an element access expression of a numeric type."`; + +exports[`disallow LuaMultiReturn non-numeric access: diagnostics 2`] = `"main.ts(7,16): error TSTL: The LuaMultiReturn type can only be accessed via an element access expression of a numeric type."`; + +exports[`invalid $multi call ($multi()): code 1`] = `"____(_G)"`; + +exports[`invalid $multi call ($multi()): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid $multi call ($multi): code 1`] = `"local ____ = ____"`; + +exports[`invalid $multi call ($multi): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid $multi call (([a] = $multi(1)) => {}): code 1`] = ` +"local function ____(____, ____bindingPattern0) + if ____bindingPattern0 == nil then + ____bindingPattern0 = { + ____(_G, 1) + } + end + local a = ____bindingPattern0[1] +end" +`; + +exports[`invalid $multi call (([a] = $multi(1)) => {}): diagnostics 1`] = `"main.ts(2,16): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid $multi call (({ $multi });): code 1`] = `"local ____ = nil"`; + +exports[`invalid $multi call (({ $multi });): diagnostics 1`] = `"main.ts(2,12): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid $multi call (const [a = 0] = $multi()): code 1`] = ` +"a = ____(_G) +if a == nil then + a = 0 +end" +`; + +exports[`invalid $multi call (const [a = 0] = $multi()): diagnostics 1`] = `"main.ts(2,25): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid $multi call (const {} = $multi();): code 1`] = ` +"local ____ = { + { + ____(_G) + } +}" +`; + +exports[`invalid $multi call (const {} = $multi();): diagnostics 1`] = `"main.ts(2,20): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid $multi call (const a = $multi();): code 1`] = ` +"a = { + ____(_G) +}" +`; + +exports[`invalid $multi call (const a = $multi();): diagnostics 1`] = `"main.ts(2,19): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid $multi implicit cast: code 1`] = ` +"function badMulti(self) + return \\"foo\\", 42 +end" +`; + +exports[`invalid $multi implicit cast: diagnostics 1`] = `"main.ts(3,20): error TSTL: The $multi function cannot be cast to a non-LuaMultiReturn type."`; + +exports[`invalid direct $multi function use (const [a = 1] = $multi()): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + return ... +end +local a = ____(nil) +if a == nil then + a = 1 +end +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (const [a = 1] = $multi()): diagnostics 1`] = `"main.ts(7,25): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid direct $multi function use (const [a = 1] = $multi(2)): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + return ... +end +local a = ____(nil, 2) +if a == nil then + a = 1 +end +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (const [a = 1] = $multi(2)): diagnostics 1`] = `"main.ts(7,25): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid direct $multi function use (const [a] = $multi()): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + return ... +end +local a = ____(nil) +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (const [a] = $multi()): diagnostics 1`] = `"main.ts(7,21): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid direct $multi function use (const [a] = $multi(1)): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + return ... +end +local a = ____(nil, 1) +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (const [a] = $multi(1)): diagnostics 1`] = `"main.ts(7,21): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid direct $multi function use (const _ = null, [a] = $multi(1)): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + return ... +end +local _ = nil +local a = ____(nil, 1) +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (const _ = null, [a] = $multi(1)): diagnostics 1`] = `"main.ts(7,31): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi(...ar)): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + return ... +end +local ar = {1} +local a = ____( + nil, + table.unpack(ar) +) +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi(...ar)): diagnostics 1`] = `"main.ts(7,37): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid direct $multi function use (let a; [a] = $multi()): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + return ... +end +local a +local ____ = { + ____(nil) +} +a = ____[1] +____exports.a = a +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (let a; [a] = $multi()): diagnostics 1`] = `"main.ts(7,22): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); false; 1) {}): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + return ... +end +local a +do + local ____ = { + ____(nil, 1, 2) + } + a = ____[1] + ____exports.a = a + while false do + local ____ = 1 + end +end +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,27): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2); false; 1) {}): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + return ... +end +local a +do + local a = ____(nil, 1, 2) + while false do + local ____ = 1 + end +end +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,33): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid direct $multi function use (let a; if ([a] = $multi(1)) { ++a; }): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + return ... +end +local a +if (function() + local ____ = { + ____(nil, 1) + } + a = ____[1] + ____exports.a = a + return ____ +end)() then + a = a + 1 + ____exports.a = a +end +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (let a; if ([a] = $multi(1)) { ++a; }): diagnostics 1`] = `"main.ts(7,26): error TSTL: The $multi function must be called in a return statement."`; diff --git a/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap b/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap new file mode 100644 index 000000000..cfeef91c8 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap @@ -0,0 +1,133 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`operator mapping - invalid use (const foo = (op as any)(1, 2);): code 1`] = `"foo = op(_G, 1, 2)"`; + +exports[`operator mapping - invalid use (const foo = (op as any)(1, 2);): diagnostics 1`] = `"main.ts(3,22): error TSTL: This function must always be directly called and cannot be referred to."`; + +exports[`operator mapping - invalid use (const foo = [op];): code 1`] = `"foo = {op}"`; + +exports[`operator mapping - invalid use (const foo = [op];): diagnostics 1`] = `"main.ts(3,22): error TSTL: This function must always be directly called and cannot be referred to."`; + +exports[`operator mapping - invalid use (const foo = \`\${op}\`): code 1`] = `"foo = tostring(op)"`; + +exports[`operator mapping - invalid use (const foo = \`\${op}\`): diagnostics 1`] = `"main.ts(3,24): error TSTL: This function must always be directly called and cannot be referred to."`; + +exports[`operator mapping - invalid use (const foo: unknown = op;): code 1`] = `"foo = op"`; + +exports[`operator mapping - invalid use (const foo: unknown = op;): diagnostics 1`] = `"main.ts(3,30): error TSTL: This function must always be directly called and cannot be referred to."`; + +exports[`operator mapping - invalid use (declare function foo(op: LuaAddition): void; foo(op);): code 1`] = `"foo(_G, op)"`; + +exports[`operator mapping - invalid use (declare function foo(op: LuaAddition): void; foo(op);): diagnostics 1`] = `"main.ts(3,82): error TSTL: This function must always be directly called and cannot be referred to."`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseAnd): code 1`] = `"local ____ = left & right"`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseAnd): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseExclusiveOr): code 1`] = `"local ____ = left ~ right"`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseExclusiveOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseLeftShift): code 1`] = `"local ____ = left << right"`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseLeftShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseOr): code 1`] = `"local ____ = left | right"`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseRightShift): code 1`] = `"local ____ = left >> right"`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseRightShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.1 LuaFloorDivision): code 1`] = `"local ____ = left // right"`; + +exports[`unsupported binary operator mapping (5.1 LuaFloorDivision): diagnostics 1`] = `"main.ts(6,9): error TSTL: Floor division operator is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseAnd): code 1`] = `"local ____ = left & right"`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseAnd): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseExclusiveOr): code 1`] = `"local ____ = left ~ right"`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseExclusiveOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseLeftShift): code 1`] = `"local ____ = left << right"`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseLeftShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseOr): code 1`] = `"local ____ = left | right"`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseRightShift): code 1`] = `"local ____ = left >> right"`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseRightShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (5.2 LuaFloorDivision): code 1`] = `"local ____ = left // right"`; + +exports[`unsupported binary operator mapping (5.2 LuaFloorDivision): diagnostics 1`] = `"main.ts(6,9): error TSTL: Floor division operator is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseAnd): code 1`] = `"local ____ = left & right"`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseAnd): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseExclusiveOr): code 1`] = `"local ____ = left ~ right"`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseExclusiveOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseLeftShift): code 1`] = `"local ____ = left << right"`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseLeftShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseOr): code 1`] = `"local ____ = left | right"`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseRightShift): code 1`] = `"local ____ = left >> right"`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseRightShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (JIT LuaFloorDivision): code 1`] = `"local ____ = left // right"`; + +exports[`unsupported binary operator mapping (JIT LuaFloorDivision): diagnostics 1`] = `"main.ts(6,9): error TSTL: Floor division operator is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseAnd): code 1`] = `"local ____ = left & right"`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseAnd): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseExclusiveOr): code 1`] = `"local ____ = left ~ right"`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseExclusiveOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseLeftShift): code 1`] = `"local ____ = left << right"`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseLeftShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseOr): code 1`] = `"local ____ = left | right"`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseRightShift): code 1`] = `"local ____ = left >> right"`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseRightShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (universal LuaFloorDivision): code 1`] = `"local ____ = left // right"`; + +exports[`unsupported binary operator mapping (universal LuaFloorDivision): diagnostics 1`] = `"main.ts(6,9): error TSTL: Floor division operator is/are not supported for target Lua 5.1."`; + +exports[`unsupported unary operator mapping (5.1 LuaBitwiseNot): code 1`] = `"local ____ = ~operand"`; + +exports[`unsupported unary operator mapping (5.1 LuaBitwiseNot): diagnostics 1`] = `"main.ts(5,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported unary operator mapping (5.2 LuaBitwiseNot): code 1`] = `"local ____ = ~operand"`; + +exports[`unsupported unary operator mapping (5.2 LuaBitwiseNot): diagnostics 1`] = `"main.ts(5,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported unary operator mapping (JIT LuaBitwiseNot): code 1`] = `"local ____ = ~operand"`; + +exports[`unsupported unary operator mapping (JIT LuaBitwiseNot): diagnostics 1`] = `"main.ts(5,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported unary operator mapping (universal LuaBitwiseNot): code 1`] = `"local ____ = ~operand"`; + +exports[`unsupported unary operator mapping (universal LuaBitwiseNot): diagnostics 1`] = `"main.ts(5,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; diff --git a/test/unit/language-extensions/__snapshots__/range.spec.ts.snap b/test/unit/language-extensions/__snapshots__/range.spec.ts.snap new file mode 100644 index 000000000..f066c1260 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/range.spec.ts.snap @@ -0,0 +1,88 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`$range invalid control variable: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local i + for ____ = 1, 5 do + end +end +return ____exports" +`; + +exports[`$range invalid control variable: diagnostics 1`] = `"main.ts(3,14): error TSTL: For loop using $range must declare a single control variable."`; + +exports[`$range invalid use ("const range = $range;"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local range = ____ +end +return ____exports" +`; + +exports[`$range invalid use ("const range = $range;"): diagnostics 1`] = `"main.ts(2,23): error TSTL: $range can only be used in a for...of loop."`; + +exports[`$range invalid use ("const x = $range(1, 10);"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local x = ____(nil, 1, 10) +end +return ____exports" +`; + +exports[`$range invalid use ("const x = $range(1, 10);"): diagnostics 1`] = `"main.ts(2,19): error TSTL: $range can only be used in a for...of loop."`; + +exports[`$range invalid use ("const y = [...$range(1, 10)];"): code 1`] = ` +"require(\\"lualib_bundle\\"); +local ____exports = {} +function ____exports.__main(self) + local y = { + __TS__Spread( + ____(nil, 1, 10) + ) + } +end +return ____exports" +`; + +exports[`$range invalid use ("const y = [...$range(1, 10)];"): diagnostics 1`] = `"main.ts(2,23): error TSTL: $range can only be used in a for...of loop."`; + +exports[`$range invalid use ("for (const i in $range(1, 10, 2)) {}"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + for i in pairs( + ____(nil, 1, 10, 2) + ) do + end +end +return ____exports" +`; + +exports[`$range invalid use ("for (const i in $range(1, 10, 2)) {}"): diagnostics 1`] = `"main.ts(2,25): error TSTL: $range can only be used in a for...of loop."`; + +exports[`$range invalid use ("for (const i of $range(1, 10, 2) as number[]) {}"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + for ____, i in ipairs( + ____(nil, 1, 10, 2) + ) do + end +end +return ____exports" +`; + +exports[`$range invalid use ("for (const i of $range(1, 10, 2) as number[]) {}"): diagnostics 1`] = `"main.ts(2,25): error TSTL: $range can only be used in a for...of loop."`; + +exports[`$range invalid use ("for (const i of ($range(1, 10, 2))) {}"): code 1`] = ` +"require(\\"lualib_bundle\\"); +local ____exports = {} +function ____exports.__main(self) + for ____, i in __TS__Iterator( + ____(nil, 1, 10, 2) + ) do + end +end +return ____exports" +`; + +exports[`$range invalid use ("for (const i of ($range(1, 10, 2))) {}"): diagnostics 1`] = `"main.ts(2,26): error TSTL: $range can only be used in a for...of loop."`; diff --git a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap new file mode 100644 index 000000000..5deed95c3 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap @@ -0,0 +1,173 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("null"): code 1`] = ` +"local ____exports = {} +____exports.__result = {} +return ____exports" +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("null"): diagnostics 1`] = `"main.ts(1,38): error TS2344: Type 'null' does not satisfy the constraint 'AnyNotNil'."`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("number | undefined"): code 1`] = ` +"local ____exports = {} +____exports.__result = {} +return ____exports" +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("number | undefined"): diagnostics 1`] = ` +"main.ts(1,38): error TS2344: Type 'number | undefined' does not satisfy the constraint 'AnyNotNil'. + Type 'undefined' is not assignable to type 'AnyNotNil'." +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("string | null"): code 1`] = ` +"local ____exports = {} +____exports.__result = {} +return ____exports" +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("string | null"): diagnostics 1`] = ` +"main.ts(1,38): error TS2344: Type 'string | null' does not satisfy the constraint 'AnyNotNil'. + Type 'null' is not assignable to type 'AnyNotNil'." +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("undefined"): code 1`] = ` +"local ____exports = {} +____exports.__result = {} +return ____exports" +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("undefined"): diagnostics 1`] = `"main.ts(1,38): error TS2344: Type 'undefined' does not satisfy the constraint 'AnyNotNil'."`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("unknown"): code 1`] = ` +"local ____exports = {} +____exports.__result = {} +return ____exports" +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("unknown"): diagnostics 1`] = `"main.ts(1,38): error TS2344: Type 'unknown' does not satisfy the constraint 'AnyNotNil'."`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = [tableDelete({}, \\"foo\\")];"): code 1`] = ` +"foo = { + (function() + ({}).foo = nil + return nil + end)() +}" +`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = [tableDelete({}, \\"foo\\")];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = \`\${tableDelete({}, \\"foo\\")}\`;"): code 1`] = ` +"foo = tostring( + (function() + ({}).foo = nil + return nil + end)() +)" +`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = \`\${tableDelete({}, \\"foo\\")}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = tableDelete({}, \\"foo\\");"): code 1`] = ` +"foo = (function() + ({}).foo = nil + return nil +end)()" +`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = tableDelete({}, \\"foo\\");"): diagnostics 1`] = `"main.ts(3,25): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("declare function foo(arg: any): void; foo(tableDelete({}, \\"foo\\"));"): code 1`] = ` +"foo( + _G, + (function() + ({}).foo = nil + return nil + end)() +)" +`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("declare function foo(arg: any): void; foo(tableDelete({}, \\"foo\\"));"): diagnostics 1`] = `"main.ts(3,55): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = [setTable({}, \\"foo\\", 3)];"): code 1`] = ` +"foo = { + (function() + ({}).foo = 3 + return nil + end)() +}" +`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = [setTable({}, \\"foo\\", 3)];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = \`\${setTable({}, \\"foo\\", 3)}\`;"): code 1`] = ` +"foo = tostring( + (function() + ({}).foo = 3 + return nil + end)() +)" +`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = \`\${setTable({}, \\"foo\\", 3)}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = setTable({}, \\"foo\\", 3);"): code 1`] = ` +"foo = (function() + ({}).foo = 3 + return nil +end)()" +`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = setTable({}, \\"foo\\", 3);"): diagnostics 1`] = `"main.ts(3,25): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("declare function foo(arg: any): void; foo(setTable({}, \\"foo\\", 3));"): code 1`] = ` +"foo( + _G, + (function() + ({}).foo = 3 + return nil + end)() +)" +`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("declare function foo(arg: any): void; foo(setTable({}, \\"foo\\", 3));"): diagnostics 1`] = `"main.ts(3,55): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = (getTable as any)(1, 2);"): code 1`] = `"foo = getTable(_G, 1, 2)"`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = (getTable as any)(1, 2);"): diagnostics 1`] = `"main.ts(3,26): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = [getTable];"): code 1`] = `"foo = {getTable}"`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = [getTable];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = \`\${getTable}\`;"): code 1`] = `"foo = tostring(getTable)"`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = \`\${getTable}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo: unknown = getTable;"): code 1`] = `"foo = getTable"`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo: unknown = getTable;"): diagnostics 1`] = `"main.ts(3,34): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("declare function foo(getTable: LuaTableGet<{}, string, number>): void; foo(getTable);"): code 1`] = `"foo(_G, getTable)"`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("declare function foo(getTable: LuaTableGet<{}, string, number>): void; foo(getTable);"): diagnostics 1`] = `"main.ts(3,88): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use ("const foo = (tableHas as any)(1, 2);"): code 1`] = `"foo = tableHas(_G, 1, 2)"`; + +exports[`LuaTableHas extension invalid use ("const foo = (tableHas as any)(1, 2);"): diagnostics 1`] = `"main.ts(3,26): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use ("const foo = [tableHas];"): code 1`] = `"foo = {tableHas}"`; + +exports[`LuaTableHas extension invalid use ("const foo = [tableHas];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use ("const foo = \`\${tableHas}\`;"): code 1`] = `"foo = tostring(tableHas)"`; + +exports[`LuaTableHas extension invalid use ("const foo = \`\${tableHas}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use ("const foo: unknown = tableHas;"): code 1`] = `"foo = tableHas"`; + +exports[`LuaTableHas extension invalid use ("const foo: unknown = tableHas;"): diagnostics 1`] = `"main.ts(3,34): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use ("declare function foo(tableHas: LuaTableHas<{}, string>): void; foo(tableHas);"): code 1`] = `"foo(_G, tableHas)"`; + +exports[`LuaTableHas extension invalid use ("declare function foo(tableHas: LuaTableHas<{}, string>): void; foo(tableHas);"): diagnostics 1`] = `"main.ts(3,80): error TSTL: This function must be called directly and cannot be referred to."`; diff --git a/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap b/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap new file mode 100644 index 000000000..819cc27a0 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap @@ -0,0 +1,37 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`$vararg invalid use ("const l = $vararg.length"): code 1`] = `"l = #____"`; + +exports[`$vararg invalid use ("const l = $vararg.length"): diagnostics 1`] = `"main.ts(2,19): error TSTL: $vararg can only be used in a spread element ('...$vararg') in global scope."`; + +exports[`$vararg invalid use ("const x = $vararg;"): code 1`] = `"x = ____"`; + +exports[`$vararg invalid use ("const x = $vararg;"): diagnostics 1`] = `"main.ts(2,19): error TSTL: $vararg can only be used in a spread element ('...$vararg') in global scope."`; + +exports[`$vararg invalid use ("for (const x of $vararg) {}"): code 1`] = ` +"for ____, x in ipairs(____) do +end" +`; + +exports[`$vararg invalid use ("for (const x of $vararg) {}"): diagnostics 1`] = `"main.ts(2,25): error TSTL: $vararg can only be used in a spread element ('...$vararg') in global scope."`; + +exports[`$vararg invalid use ("function f(s: string[]) {} f($vararg);"): code 1`] = ` +"function f(self, s) +end +f(_G, ____)" +`; + +exports[`$vararg invalid use ("function f(s: string[]) {} f($vararg);"): diagnostics 1`] = `"main.ts(2,38): error TSTL: $vararg can only be used in a spread element ('...$vararg') in global scope."`; + +exports[`$vararg invalid use ("function foo(...args: string[]) {} function bar() { foo(...$vararg); }"): code 1`] = ` +"function foo(self, ...) +end +function bar(self) + foo( + _G, + table.unpack(____) + ) +end" +`; + +exports[`$vararg invalid use ("function foo(...args: string[]) {} function bar() { foo(...$vararg); }"): diagnostics 1`] = `"main.ts(2,68): error TSTL: $vararg can only be used in a spread element ('...$vararg') in global scope."`; diff --git a/test/unit/language-extensions/iterable.spec.ts b/test/unit/language-extensions/iterable.spec.ts new file mode 100644 index 000000000..7d79db509 --- /dev/null +++ b/test/unit/language-extensions/iterable.spec.ts @@ -0,0 +1,546 @@ +import * as util from "../../util"; +import { invalidMultiIterableWithoutDestructuring } from "../../../src/transformation/utils/diagnostics"; + +describe("simple LuaIterable", () => { + const testIterable = ` + function testIterable(this: void): LuaIterable { + const strs = ["a", "b", "c"]; + let i = 0; + return (() => strs[i++]) as any; + } + `; + const testResults = ["a", "b", "c"]; + + test("const control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + for (const s of testIterable()) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("let control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + for (let s of testIterable()) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("external control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + let s: string; + for (s of testIterable()) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("function forward", () => { + util.testFunction` + ${testIterable} + function forward() { return testIterable(); } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("function indirect forward", () => { + util.testFunction` + ${testIterable} + function forward() { const iter = testIterable(); return iter; } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("arrow function forward", () => { + util.testFunction` + ${testIterable} + const forward = () => testIterable(); + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("manual use", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + const iter = testIterable(); + while (true) { + const val = iter(); + if (!val) { + break; + } + results.push(val); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); +}); + +describe("LuaIterable using state", () => { + const testIterable = ` + function iterator(this: void, strs: string[], lastStr: string) { + return strs[strs.indexOf(lastStr) + 1]; + } + const testIterable = (() => $multi(iterator, ["a", "b", "c"], "")) as (() => LuaIterable); + `; + const testResults = ["a", "b", "c"]; + + test("const control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + for (const s of testIterable()) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("let control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + for (let s of testIterable()) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("external control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + let s: string; + for (s of testIterable()) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("function forward", () => { + util.testFunction` + ${testIterable} + function forward() { return testIterable(); } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("function indirect forward", () => { + util.testFunction` + ${testIterable} + function forward() { const iter = testIterable(); return iter; } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("arrow function forward", () => { + util.testFunction` + ${testIterable} + const forward = () => testIterable(); + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("manual use", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + let [iter, state, val] = testIterable(); + while (true) { + val = iter(state, val); + if (!val) { + break; + } + results.push(val); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); +}); + +describe("LuaIterable with array value type", () => { + const testIterable = ` + function testIterable(this: void): LuaIterable { + const strsArray = [["a1", "a2"], ["b1", "b2"], ["c1", "c2"]]; + let i = 0; + return (() => strsArray[i++]) as any; + } + `; + const testResults = [ + ["a1", "a2"], + ["b1", "b2"], + ["c1", "c2"], + ]; + + test("basic destructuring", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + for (const [x, y] of testIterable()) { + results.push([x, y]); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("destructure with external control variable", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + let x: string, y: string; + for ([x, y] of testIterable()) { + results.push([x, y]); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("destructure with function forward", () => { + util.testFunction` + ${testIterable} + function forward() { return testIterable(); } + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("destructure with function indirect forward", () => { + util.testFunction` + ${testIterable} + function forward() { const iter = testIterable(); return iter; } + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("destructure arrow function forward", () => { + util.testFunction` + ${testIterable} + const forward = () => testIterable(); + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("manual use", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + const iter = testIterable(); + while (true) { + const val = iter(); + if (!val) { + break; + } + results.push(val); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); +}); + +describe("LuaIterable with LuaMultiReturn value type", () => { + const testIterable = ` + function testIterable(this: void): LuaIterable> { + const strsArray = [["a1", "a2"], ["b1", "b2"], ["c1", "c2"]]; + let i = 0; + return (() => { + const strs = strsArray[i++]; + if (strs) { + return $multi(...strs); + } + }) as any; + } + `; + const testResults = [ + ["a1", "a2"], + ["b1", "b2"], + ["c1", "c2"], + ]; + + test("basic destructuring", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + for (const [x, y] of testIterable()) { + results.push([x, y]); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("destructure with external control variable", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + let x: string, y: string; + for ([x, y] of testIterable()) { + results.push([x, y]); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("destructure with function forward", () => { + util.testFunction` + ${testIterable} + function forward() { return testIterable(); } + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("destructure with function indirect forward", () => { + util.testFunction` + ${testIterable} + function forward() { const iter = testIterable(); return iter; } + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("destructure arrow function forward", () => { + util.testFunction` + ${testIterable} + const forward = () => testIterable(); + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("destructure manual use", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + const iter = testIterable(); + while (true) { + const [x, y] = iter(); + if (!x) { + break; + } + results.push([x, y]); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test.each(["for (const s of testIterable()) {}", "let s; for (s of testIterable()) {}"])( + "invalid LuaIterable without destructuring (%p)", + statement => { + util.testFunction` + ${testIterable} + ${statement} + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot([invalidMultiIterableWithoutDestructuring.code]); + } + ); +}); + +describe("LuaIterable property", () => { + const testIterable = ` + class IterableTester { + public strs = ["a", "b", "c"]; + + public get values(): LuaIterable { + let i = 0; + return (() => this.strs[i++]) as any; + } + } + const tester = new IterableTester(); + `; + const testResults = ["a", "b", "c"]; + + test("basic usage", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + for (const s of tester.values) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("external control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + let s: string; + for (s of tester.values) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("function forward", () => { + util.testFunction` + ${testIterable} + function forward() { return tester.values; } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("function indirect forward", () => { + util.testFunction` + ${testIterable} + function forward() { const iter = tester.values; return iter; } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("arrow function forward", () => { + util.testFunction` + ${testIterable} + const forward = () => tester.values; + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); + + test("manual use", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + const iter = tester.values; + while (true) { + const val = iter(); + if (!val) { + break; + } + results.push(val); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); + }); +}); diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts new file mode 100644 index 000000000..50784a3db --- /dev/null +++ b/test/unit/language-extensions/multi.spec.ts @@ -0,0 +1,299 @@ +import * as util from "../../util"; +import { + invalidMultiFunctionUse, + invalidMultiReturnAccess, + invalidMultiFunctionReturnType, +} from "../../../src/transformation/utils/diagnostics"; + +test("multi example use case", () => { + util.testModule` + function multiReturn(): LuaMultiReturn<[string, number]> { + return $multi("foo", 5); + } + + const [a, b] = multiReturn(); + export { a, b }; + ` + .withLanguageExtensions() + .expectToEqual({ a: "foo", b: 5 }); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/995 +test("Destructuring assignment of LuaMultiReturn", () => { + util.testModule` + function multiReturn(): LuaMultiReturn<[number, number, number]> { + return $multi(1, 2, 3); + } + + const [a, ...b] = multiReturn(); + export {a, b}; + ` + .withLanguageExtensions() + .expectToEqual({ a: 1, b: [2, 3] }); +}); + +test("Destructuring assignment of LuaMultiReturn returning nil", () => { + util.testModule` + function multiReturn(): LuaMultiReturn<[number, number, number]> { + return; + } + + const [a, ...b] = multiReturn(); + export {a, b}; + ` + .withLanguageExtensions() + .expectToEqual({ a: undefined, b: [] }); +}); + +test.each<[string, any]>([ + ["$multi()", undefined], + ["$multi(true)", true], + ["$multi(1, 2)", 1], +])("$multi call on return statement (%s)", (expression, result) => { + util.testFunction` + return ${expression}; + ` + .withLanguageExtensions() + .expectToEqual(result); +}); + +const multiFunction = ` +function multi(...args) { + return $multi(...args); +} +`; + +const createCasesThatCall = (name: string): Array<[string, any]> => [ + [`let a; [a] = ${name}()`, undefined], + [`const [a] = ${name}()`, undefined], + [`const [a] = ${name}(1)`, 1], + [`const [a = 1] = ${name}()`, 1], + [`const [a = 1] = ${name}(2)`, 2], + [`const ar = [1]; const [a] = ${name}(...ar)`, 1], + [`const _ = null, [a] = ${name}(1)`, 1], + [`let a; for (const [a] = ${name}(1, 2); false; 1) {}`, undefined], + [`let a; for ([a] = ${name}(1, 2); false; 1) {}`, 1], + [`let a; if ([a] = ${name}(1)) { ++a; }`, 2], +]; + +test.each<[string, any]>(createCasesThatCall("$multi"))("invalid direct $multi function use (%s)", statement => { + util.testModule` + ${multiFunction} + ${statement} + export { a }; + ` + .withLanguageExtensions() + .setReturnExport("a") + .expectDiagnosticsToMatchSnapshot([invalidMultiFunctionUse.code]); +}); + +test.each<[string, any]>(createCasesThatCall("multi"))( + "valid indirect $multi function use (%s)", + (statement, result) => { + util.testModule` + ${multiFunction} + ${statement} + export { a }; + ` + .withLanguageExtensions() + .setReturnExport("a") + .expectToEqual(result); + } +); + +test.each<[string, number[]]>([ + ["$multi", [invalidMultiFunctionUse.code]], + ["$multi()", [invalidMultiFunctionUse.code]], + ["({ $multi });", [invalidMultiFunctionUse.code]], + ["const a = $multi();", [invalidMultiFunctionUse.code]], + ["const {} = $multi();", [invalidMultiFunctionUse.code]], + ["([a] = $multi(1)) => {}", [invalidMultiFunctionUse.code]], + ["const [a = 0] = $multi()", [invalidMultiFunctionUse.code]], +])("invalid $multi call (%s)", (statement, diagnostics) => { + util.testModule` + ${statement} + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot(diagnostics); +}); + +test("function to spread multi type result from multi type function", () => { + util.testFunction` + ${multiFunction} + function m() { + return $multi(...multi(true)); + } + return m(); + ` + .withLanguageExtensions() + .expectToEqual(true); +}); + +test("$multi call with destructuring assignment side effects", () => { + util.testModule` + ${multiFunction} + let a; + export { a }; + [a] = multi(1); + ` + .withLanguageExtensions() + .setReturnExport("a") + .expectToEqual(1); +}); + +test("allow $multi call in ArrowFunction body", () => { + util.testFunction` + const call = () => $multi(1); + const [result] = call(); + return result; + ` + .withLanguageExtensions() + .expectToEqual(1); +}); + +test("forward $multi call", () => { + util.testFunction` + function foo() { return $multi(1, 2); } + function call() { return foo(); } + const [resultA, resultB] = call(); + return [resultA, resultB]; + ` + .withLanguageExtensions() + .expectToEqual([1, 2]); +}); + +test("forward $multi call indirect", () => { + util.testFunction` + function foo() { return $multi(1, 2); } + function call() { const m = foo(); return m; } + const [resultA, resultB] = call(); + return [resultA, resultB]; + ` + .withLanguageExtensions() + .expectToEqual([1, 2]); +}); + +test("forward $multi call in ArrowFunction body", () => { + util.testFunction` + const foo = () => $multi(1, 2); + const call = () => foo(); + const [resultA, resultB] = call(); + return [resultA, resultB]; + ` + .withLanguageExtensions() + .expectToEqual([1, 2]); +}); + +test.each(["0", "i"])("allow LuaMultiReturn numeric access (%s)", expression => { + util.testFunction` + ${multiFunction} + const i = 0; + return multi(1)[${expression}]; + ` + .withLanguageExtensions() + .expectToEqual(1); +}); + +test.each(["multi()['forEach']", "multi().forEach"])("disallow LuaMultiReturn non-numeric access", expression => { + util.testFunction` + ${multiFunction} + return ${expression}; + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot([invalidMultiReturnAccess.code]); +}); + +test("invalid $multi implicit cast", () => { + util.testModule` + function badMulti(): [string, number] { + return $multi("foo", 42); + } + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot([invalidMultiFunctionReturnType.code]); +}); + +test.each([ + { flag: true, result: 4 }, + { flag: false, result: 7 }, +])("overloaded $multi/non-$multi return", ({ flag, result }) => { + util.testFunction` + function multiOverload(flag: true): LuaMultiReturn<[string, number]>; + function multiOverload(flag: false): [string, number]; + function multiOverload(flag: boolean) { + if (flag) { + return $multi("foo", 4); + } else { + return ["bar", 7]; + } + } + const [x, y] = multiOverload(${flag}); + return y; + ` + .withLanguageExtensions() + .expectToEqual(result); +}); + +test("return $multi from try", () => { + util.testFunction` + function multiTest() { + try { + return $multi(1, 2); + } catch { + } + } + const [_, a] = multiTest(); + return a; + ` + .withLanguageExtensions() + .expectToEqual(2); +}); + +test("return $multi from catch", () => { + util.testFunction` + function multiTest() { + try { + throw "error"; + } catch { + return $multi(1, 2); + } + } + const [_, a] = multiTest(); + return a; + ` + .withLanguageExtensions() + .expectToEqual(2); +}); + +test("return LuaMultiReturn from try", () => { + util.testFunction` + ${multiFunction} + function multiTest() { + try { + return multi(1, 2); + } catch { + } + } + const [_, a] = multiTest(); + return a; + ` + .withLanguageExtensions() + .expectToEqual(2); +}); + +test("return LuaMultiReturn from catch", () => { + util.testFunction` + ${multiFunction} + function multiTest() { + try { + throw "error"; + } catch { + return multi(1, 2); + } + } + const [_, a] = multiTest(); + return a; + ` + .withLanguageExtensions() + .expectToEqual(2); +}); diff --git a/test/unit/language-extensions/operators.spec.ts b/test/unit/language-extensions/operators.spec.ts new file mode 100644 index 000000000..c84f8aac9 --- /dev/null +++ b/test/unit/language-extensions/operators.spec.ts @@ -0,0 +1,392 @@ +import * as path from "path"; +import * as util from "../../util"; +import * as tstl from "../../../src"; +import { invalidOperatorMappingUse } from "../../../src/transformation/utils/diagnostics"; +import { LuaTarget } from "../../../src"; +import { unsupportedForTarget } from "../../../src/transformation/utils/diagnostics"; + +const operatorsProjectOptions: tstl.CompilerOptions = { + luaTarget: LuaTarget.Lua54, + types: [path.resolve(__dirname, "../../../language-extensions")], +}; + +const operatorMapTestObject = ` + class OpTest { + public value: number; + public constructor(value: number) { this.value = value; } + + public __add(other: OpTest): OpTest; + public __add(other: number): number; + public __add(other: OpTest | number) { + if (typeof other === "number") { + return this.value + other; + } else { + return new OpTest(this.value + other.value); + } + } + public __sub(other: OpTest) { return new OpTest(this.value - other.value); } + public __mul(other: OpTest) { return new OpTest(this.value * other.value); } + public __div(other: OpTest) { return new OpTest(this.value / other.value); } + public __mod(other: OpTest) { return new OpTest(this.value % other.value); } + public __pow(other: OpTest) { return new OpTest(this.value ** other.value); } + public __idiv(other: OpTest) { return new OpTest(Math.floor(this.value / other.value)); } + public __band(other: OpTest) { return new OpTest(this.value & other.value); } + public __bor(other: OpTest) { return new OpTest(this.value | other.value); } + public __bxor(other: OpTest) { return new OpTest(this.value ^ other.value); } + public __shl(other: OpTest) { return new OpTest(this.value << other.value); } + public __shr(other: OpTest) { return new OpTest(this.value >>> other.value); } + + public __lt(other: OpTest) { return this.value < other.value; } + public __gt(other: OpTest) { return this.value > other.value; } + + public __concat(other: OpTest) { return this.value.toString() + other.value.toString(); } + + public __unm() { return -this.value; } + public __bnot() { return ~this.value; } + public __len() { return this.value; } + } +`; + +const binaryMathOperatorTests: Array<{ opType: string; left: number; right: number; expectResult: number }> = [ + { opType: "LuaAddition", left: 7, right: 4, expectResult: 11 }, + { opType: "LuaSubtraction", left: 7, right: 4, expectResult: 3 }, + { opType: "LuaMultiplication", left: 7, right: 4, expectResult: 28 }, + { opType: "LuaDivision", left: 7, right: 4, expectResult: 1.75 }, + { opType: "LuaModulo", left: 7, right: 4, expectResult: 3 }, + { opType: "LuaPower", left: 7, right: 4, expectResult: 2401 }, + { opType: "LuaFloorDivision", left: 7, right: 4, expectResult: 1 }, + { opType: "LuaBitwiseAnd", left: 6, right: 5, expectResult: 4 }, + { opType: "LuaBitwiseOr", left: 6, right: 5, expectResult: 7 }, + { opType: "LuaBitwiseExclusiveOr", left: 6, right: 5, expectResult: 3 }, + { opType: "LuaBitwiseLeftShift", left: 7, right: 2, expectResult: 28 }, + { opType: "LuaBitwiseRightShift", left: 7, right: 2, expectResult: 1 }, +]; + +test.each(binaryMathOperatorTests)( + "binary math operator mapping - global function (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare const op: ${opType}; + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = op(left, right).value; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +test.each(binaryMathOperatorTests)( + "binary math operator mapping - static function (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const op: ${opType}; + } + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = OpTest.op(left, right).value; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +test.each(binaryMathOperatorTests)( + "binary math operator mapping - method (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + op: ${opType}Method; + } + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = left.op(right).value; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +const luaTargetsPre53 = [LuaTarget.Lua51, LuaTarget.Lua52, LuaTarget.LuaJIT, LuaTarget.Universal]; + +const operatorTypesPost53 = [ + "LuaFloorDivision", + "LuaBitwiseAnd", + "LuaBitwiseOr", + "LuaBitwiseExclusiveOr", + "LuaBitwiseLeftShift", + "LuaBitwiseRightShift", +]; + +test.each(luaTargetsPre53.flatMap(target => operatorTypesPost53.map(opType => [target, opType] as const)))( + "unsupported binary operator mapping (%s %s)", + (luaTarget, opType) => { + util.testModule` + declare interface OpTest { value: number; } + declare const op: ${opType}; + declare const left: OpTest; + declare const right: OpTest; + op(left, right); + ` + .setOptions({ ...operatorsProjectOptions, luaTarget }) + .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); + } +); + +const comparisonOperatorTests: Array<{ opType: string; left: number; right: number; expectResult: boolean }> = [ + { opType: "LuaLessThan", left: 7, right: 4, expectResult: false }, + { opType: "LuaLessThan", left: 4, right: 7, expectResult: true }, + { opType: "LuaGreaterThan", left: 7, right: 4, expectResult: true }, + { opType: "LuaGreaterThan", left: 4, right: 7, expectResult: false }, +]; + +test.each(comparisonOperatorTests)( + "comparison operator mapping - global function (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare const op: ${opType}; + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = op(left, right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +test.each(comparisonOperatorTests)( + "comparison operator mapping - static function (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const op: ${opType}; + } + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = OpTest.op(left, right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +test.each(comparisonOperatorTests)( + "comparison operator mapping - method (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + op: ${opType}Method; + } + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = left.op(right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +test("concat operator mapping - global function", () => { + util.testModule` + ${operatorMapTestObject} + declare const op: LuaConcat; + const left = new OpTest(7); + const right = new OpTest(4); + export const result = op(left, right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual("74"); +}); + +test("concat operator mapping - static function", () => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const op: LuaConcat; + } + const left = new OpTest(7); + const right = new OpTest(4); + export const result = OpTest.op(left, right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual("74"); +}); + +test("concat operator mapping - method", () => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + op: LuaConcatMethod; + } + const left = new OpTest(7); + const right = new OpTest(4); + export const result = left.op(right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual("74"); +}); + +const unaryOperatorTests: Array<{ opType: string; operand: number; expectResult: number }> = [ + { opType: "LuaNegation", operand: 13, expectResult: -13 }, + { opType: "LuaBitwiseNot", operand: 13, expectResult: -14 }, + { opType: "LuaLength", operand: 13, expectResult: 13 }, +]; + +test.each(unaryOperatorTests)("unary operator mapping - global function (%s)", ({ opType, operand, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare const op: ${opType}; + const operand = new OpTest(${operand}); + export const result = op(operand); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); +}); + +test.each(unaryOperatorTests)("unary operator mapping - static function (%s)", ({ opType, operand, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const op: ${opType}; + } + const operand = new OpTest(${operand}); + export const result = OpTest.op(operand); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); +}); + +test.each(unaryOperatorTests)("unary operator mapping - method (%s)", ({ opType, operand, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + op: ${opType}Method; + } + const operand = new OpTest(${operand}); + export const result = operand.op(); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); +}); + +test.each(luaTargetsPre53)("unsupported unary operator mapping (%s LuaBitwiseNot)", luaTarget => { + util.testModule` + declare interface OpTest { value: number; } + declare const op: LuaBitwiseNot; + declare const operand: OpTest; + op(operand); + ` + .setOptions({ ...operatorsProjectOptions, luaTarget }) + .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); +}); + +test("operator mapping overload - global function", () => { + util.testModule` + ${operatorMapTestObject} + declare const op: LuaAddition & LuaAddition; + const left = new OpTest(4); + const right = new OpTest(7); + const resultA = op(left, right).value; + const resultB = op(left, 13); + export const result = {resultA, resultB}; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual({ resultA: 11, resultB: 17 }); +}); + +test("operator mapping overload - static function", () => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const op: LuaAddition & LuaAddition; + } + const left = new OpTest(4); + const right = new OpTest(7); + const resultA = OpTest.op(left, right).value; + const resultB = OpTest.op(left, 13); + export const result = {resultA, resultB}; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual({ resultA: 11, resultB: 17 }); +}); + +test("operator mapping overload - method", () => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + op: LuaAdditionMethod & LuaAdditionMethod; + } + const left = new OpTest(4); + const right = new OpTest(7); + const resultA = left.op(right).value; + const resultB = left.op(13); + export const result = {resultA, resultB}; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual({ resultA: 11, resultB: 17 }); +}); + +test("operator mapping - method element call", () => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + add: LuaAdditionMethod; + } + const left = new OpTest(7); + export const result = left["add"](4); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(11); +}); + +test("operator mapping - function element call", () => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const add: LuaAddition; + } + const left = new OpTest(7); + export const result = OpTest["add"](left, 4); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(11); +}); + +test.each([ + "const foo: unknown = op;", + "const foo = `${op}`", + "declare function foo(op: LuaAddition): void; foo(op);", + "const foo = (op as any)(1, 2);", + "const foo = [op];", +])("operator mapping - invalid use (%s)", invalidCode => { + util.testModule` + declare const op: LuaAddition; + ${invalidCode} + ` + .setOptions(operatorsProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidOperatorMappingUse.code]); +}); diff --git a/test/unit/language-extensions/range.spec.ts b/test/unit/language-extensions/range.spec.ts new file mode 100644 index 000000000..3fc5539f6 --- /dev/null +++ b/test/unit/language-extensions/range.spec.ts @@ -0,0 +1,62 @@ +import * as util from "../../util"; +import { invalidRangeControlVariable, invalidRangeUse } from "../../../src/transformation/utils/diagnostics"; + +test("$range basic use", () => { + util.testFunction` + const result: number[] = []; + for (const i of $range(1, 5)) { + result.push(i); + } + return result; + ` + .withLanguageExtensions() + .expectToEqual([1, 2, 3, 4, 5]); +}); + +test("$range basic use with step", () => { + util.testFunction` + const result: number[] = []; + for (const i of $range(1, 10, 2)) { + result.push(i); + } + return result; + ` + .withLanguageExtensions() + .expectToEqual([1, 3, 5, 7, 9]); +}); + +test("$range basic use reverse", () => { + util.testFunction` + const result: number[] = []; + for (const i of $range(5, 1, -1)) { + result.push(i); + } + return result; + ` + .withLanguageExtensions() + .expectToEqual([5, 4, 3, 2, 1]); +}); + +test("$range invalid control variable", () => { + util.testFunction` + let i: number; + for (i of $range(1, 5)) {} + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot([invalidRangeControlVariable.code]); +}); + +test.each([ + "for (const i in $range(1, 10, 2)) {}", + "const x = $range(1, 10);", + "const range = $range;", + "const y = [...$range(1, 10)];", + "for (const i of ($range(1, 10, 2))) {}", + "for (const i of $range(1, 10, 2) as number[]) {}", +])("$range invalid use (%p)", statement => { + util.testFunction` + ${statement} + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot([invalidRangeUse.code]); +}); diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts new file mode 100644 index 000000000..0c652dca9 --- /dev/null +++ b/test/unit/language-extensions/table.spec.ts @@ -0,0 +1,328 @@ +import * as util from "../../util"; +import { + invalidTableDeleteExpression, + invalidTableExtensionUse, + invalidTableSetExpression, +} from "../../../src/transformation/utils/diagnostics"; + +describe("LuaTableGet & LuaTableSet extensions", () => { + test("stand-alone function", () => { + util.testModule` + declare const getTable: LuaTableGet<{}, string, number>; + declare const setTable: LuaTableSet<{}, string, number>; + const tbl = {}; + setTable(tbl, "foo", 3); + const result = getTable(tbl, "foo"); + export { result } + ` + .withLanguageExtensions() + .setReturnExport("result") + .expectToEqual(3); + }); + + test("namespace function", () => { + util.testModule` + declare namespace Table { + export const get: LuaTableGet<{}, string, number>; + export const set: LuaTableSet<{}, string, number>; + } + const tbl = {}; + Table.set(tbl, "foo", 3); + const result = Table.get(tbl, "foo"); + export { result } + ` + .withLanguageExtensions() + .setReturnExport("result") + .expectToEqual(3); + }); + + test("method", () => { + util.testModule` + interface Table { + get: LuaTableGetMethod; + set: LuaTableSetMethod; + } + const tbl = {} as Table; + tbl.set("foo", 3); + const result = tbl.get("foo"); + export { result } + ` + .withLanguageExtensions() + .setReturnExport("result") + .expectToEqual(3); + }); + + test.each([ + "const foo: unknown = getTable;", + "const foo = `${getTable}`;", + "declare function foo(getTable: LuaTableGet<{}, string, number>): void; foo(getTable);", + "const foo = (getTable as any)(1, 2);", + "const foo = [getTable];", + ])("invalid use (%p)", statement => { + util.testModule` + declare const getTable: LuaTableGet<{}, string, number>; + ${statement} + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot([invalidTableExtensionUse.code]); + }); + + test.each([ + 'const foo = setTable({}, "foo", 3);', + 'const foo = `${setTable({}, "foo", 3)}`;', + 'declare function foo(arg: any): void; foo(setTable({}, "foo", 3));', + 'const foo = [setTable({}, "foo", 3)];', + ])("LuaTableSet invalid use as expression (%p)", expression => { + util.testModule` + declare const setTable: LuaTableSet<{}, string, number>; + ${expression} + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot([invalidTableSetExpression.code]); + }); +}); + +describe("LuaTableHas extension", () => { + test("LuaTableHas standalone function", () => { + util.testModule` + declare const tableHas: LuaTableHas<{}, string>; + const table = { foo: "bar" }; + + export const hasFoo = tableHas(table, "foo"); + export const hasBaz = tableHas(table, "baz"); + ` + .withLanguageExtensions() + .expectToEqual({ hasFoo: true, hasBaz: false }); + }); + + test("LuaTableHas nested expression", () => { + util.testModule` + declare const tableHas: LuaTableHas<{}, string>; + const table = { foo: "bar" }; + + export const result = \`table has foo: \${tableHas(table, "foo")}\`; + ` + .withLanguageExtensions() + .expectToEqual({ result: "table has foo: true" }); + }); + + test("LuaTableHas namespace function", () => { + util.testModule` + declare namespace Table { + export const tableHas: LuaTableHas<{}, string>; + } + const table = { foo: "bar" }; + + export const hasFoo = Table.tableHas(table, "foo"); + export const hasBaz = Table.tableHas(table, "baz"); + ` + .withLanguageExtensions() + .expectToEqual({ hasFoo: true, hasBaz: false }); + }); + + test("LuaTableHasMethod method", () => { + util.testModule` + interface TableWithHas { + has: LuaTableHasMethod; + set: LuaTableSetMethod; + } + const table = {} as TableWithHas; + table.set("foo", 42); + + export const hasFoo = table.has("foo"); + export const hasBaz = table.has("baz"); + ` + .withLanguageExtensions() + .expectToEqual({ hasFoo: true, hasBaz: false }); + }); + + test("LuaTableHas as statement", () => { + util.testModule` + declare const tableHas: LuaTableHas<{}, string>; + const table = { foo: "bar" }; + + let count = 0; + function getKey() { + count++; + return "foo"; + } + + // The result is not captured, but the expression will be evaulated + tableHas(table, getKey()); + + export const numCalls = count; + ` + .withLanguageExtensions() + .expectToEqual({ numCalls: 1 }); + }); + + test.each([ + "const foo: unknown = tableHas;", + "const foo = `${tableHas}`;", + "declare function foo(tableHas: LuaTableHas<{}, string>): void; foo(tableHas);", + "const foo = (tableHas as any)(1, 2);", + "const foo = [tableHas];", + ])("invalid use (%p)", statement => { + util.testModule` + declare const tableHas: LuaTableHas<{}, string>; + ${statement} + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot([invalidTableExtensionUse.code]); + }); +}); + +describe("LuaTableDelete extension", () => { + test("LuaTableDelete standalone function", () => { + util.testModule` + declare const tableDelete: LuaTableDelete<{}, string>; + + export const table = { foo: "bar", baz: "baz" }; + tableDelete(table, "foo"); + ` + .withLanguageExtensions() + .expectToEqual({ table: { baz: "baz" } }); + }); + + test("LuaTableDelete namespace function", () => { + util.testModule` + declare namespace Table { + export const tableDelete: LuaTableDelete<{}, string>; + } + + export const table = { foo: "bar", baz: "baz" }; + Table.tableDelete(table, "foo"); + ` + .withLanguageExtensions() + .expectToEqual({ table: { baz: "baz" } }); + }); + + test("LuaTableHasMethod method", () => { + util.testModule` + interface TableWithDelete { + delete: LuaTableDeleteMethod; + set: LuaTableSetMethod; + } + export const table = {} as TableWithDelete; + table.set("foo", 42); + table.set("bar", 12); + table.delete("foo"); + ` + .withLanguageExtensions() + .expectToEqual({ table: { bar: 12 } }); + }); + + test.each([ + 'const foo = tableDelete({}, "foo");', + 'const foo = `${tableDelete({}, "foo")}`;', + 'declare function foo(arg: any): void; foo(tableDelete({}, "foo"));', + 'const foo = [tableDelete({}, "foo")];', + ])("LuaTableDelete invalid use as expression (%p)", expression => { + util.testModule` + declare const tableDelete: LuaTableDelete<{}, string>; + ${expression} + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot([invalidTableDeleteExpression.code]); + }); +}); + +describe("LuaTable extension interface", () => { + test("untyped table", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set("foo", 3); + return tbl.get("foo"); + ` + .withLanguageExtensions() + .expectToEqual(3); + }); + + test("typed table", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set("foo", 3); + return tbl.get("foo"); + ` + .withLanguageExtensions() + .expectToEqual(3); + }); + + // Test to catch issue from https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1033 + test("typed table in type declaration", () => { + util.testFunction` + function fill(tbl: LuaTable) { + tbl.set("foo", 3); + return tbl; + } + return fill(new LuaTable()).get("foo"); + ` + .withLanguageExtensions() + .expectToEqual(3); + }); + + test.each([["null"], ["undefined"], ["number | undefined"], ["string | null"], ["unknown"]])( + "LuaTable in strict mode does not accept key type that could be nil (%p)", + keyType => { + util.testExpression`new LuaTable<${keyType}, unknown>()` + .withLanguageExtensions() + .setOptions({ strict: true }) + .expectToHaveDiagnostics() + .expectDiagnosticsToMatchSnapshot(); + } + ); + + test("object keyed table", () => { + util.testFunction` + interface Key { keyStr: string } + const key: Key = {keyStr: "foo"}; + const tbl = new LuaTable(); + tbl.set(key, 3); + return tbl.get(key); + ` + .withLanguageExtensions() + .expectToEqual(3); + }); + + test("table length", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set(1, "foo"); + tbl.set(3, "bar"); + return tbl.length(); + ` + .withLanguageExtensions() + .expectToEqual(1); + }); + + test("table has", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set(3, "foo"); + return [tbl.has(1), tbl.has(3)]; + ` + .withLanguageExtensions() + .expectToEqual([false, true]); + }); + + test("table delete", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set("foo", 1); + tbl.set("bar", 3); + tbl.set("baz", 5); + tbl.delete("bar"); + tbl.delete("foo"); + return tbl; + ` + .withLanguageExtensions() + .expectToEqual({ baz: 5 }); + }); + + test.each(['new LuaTable().get("foo");', 'new LuaTable().set("foo", "bar");'])( + "table immediate access (%p)", + statement => { + util.testFunction(statement).withLanguageExtensions().expectToHaveNoDiagnostics(); + } + ); +}); diff --git a/test/unit/language-extensions/vararg.spec.ts b/test/unit/language-extensions/vararg.spec.ts new file mode 100644 index 000000000..18872c161 --- /dev/null +++ b/test/unit/language-extensions/vararg.spec.ts @@ -0,0 +1,32 @@ +import * as util from "../../util"; +import { invalidVarargUse } from "../../../src/transformation/utils/diagnostics"; + +test.each([ + 'const result = [...$vararg].join("")', + 'let result: string; { result = [...$vararg].join(""); }', + 'let result: string; if (true) { result = [...$vararg].join(""); }', + 'let result: string; do { result = [...$vararg].join(""); } while (false);', +])("$vararg valid use (%p)", statement => { + util.testModule` + ${statement} + export { result }; + ` + .withLanguageExtensions() + .setLuaFactory(code => `return (function(...) ${code} end)("A", "B", "C", "D")`) + .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("unpack")) + .expectToEqual({ result: "ABCD" }); +}); + +test.each([ + "const x = $vararg;", + "for (const x of $vararg) {}", + "const l = $vararg.length", + "function f(s: string[]) {} f($vararg);", + "function foo(...args: string[]) {} function bar() { foo(...$vararg); }", +])("$vararg invalid use (%p)", statement => { + util.testModule` + ${statement} + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot([invalidVarargUse.code]); +}); diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index b35bbd767..a3d4db239 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -198,18 +198,15 @@ test("for scope", () => { test.each([ { inp: { test1: 0, test2: 1, test3: 2 }, - expected: { test1: 1, test2: 2, test3: 3 }, }, -])("forin[Object] (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let objTest = ${JSON.stringify(inp)}; +])("forin[Object] (%p)", ({ inp }) => { + util.testFunctionTemplate` + let objTest = ${inp}; for (let key in objTest) { objTest[key] = objTest[key] + 1; } - return JSONStringify(objTest);` - ); - - expect(JSON.parse(result)).toEqual(expected); + return objTest; + `.expectToMatchJsResult(); }); test("forin[Array]", () => { @@ -219,11 +216,9 @@ test("forin[Array]", () => { `.expectDiagnosticsToMatchSnapshot([forbiddenForIn.code]); }); -test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 }, expected: { a: 0, b: 0, c: 2, d: 0, e: 4 } }])( - "forin with continue (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let obj = ${JSON.stringify(inp)}; +test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 } }])("forin with continue (%p)", ({ inp }) => { + util.testFunctionTemplate` + let obj = ${inp}; for (let i in obj) { if (obj[i] % 2 == 0) { continue; @@ -231,24 +226,19 @@ test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 }, expected: { a: 0, b: 0, c: 2 obj[i] = 0; } - return JSONStringify(obj);` - ); - - expect(result).toBe(JSON.stringify(expected)); - } -); + return obj; + `.expectToMatchJsResult(); +}); -test.each([{ inp: [0, 1, 2], expected: [1, 2, 3] }])("forof (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let objTest = ${JSON.stringify(inp)}; +test.each([{ inp: [0, 1, 2] }])("forof (%p)", ({ inp }) => { + util.testFunctionTemplate` + let objTest = ${inp}; let arrResultTest = []; for (let value of objTest) { arrResultTest.push(value + 1) } - return JSONStringify(arrResultTest);` - ); - - expect(result).toBe(JSON.stringify(expected)); + return arrResultTest; + `.expectToMatchJsResult(); }); test("Tuple loop", () => { @@ -455,73 +445,25 @@ test.each(["", "abc", "a\0c"])("forof string (%p)", string => { describe("for...of empty destructuring", () => { const declareTests = (destructuringPrefix: string) => { test("array", () => { - const code = ` + util.testFunction` const arr = [["a"], ["b"], ["c"]]; let i = 0; for (${destructuringPrefix}[] of arr) { ++i; } return i; - `; - expect(util.transpileAndExecute(code)).toBe(3); + `.expectToMatchJsResult(); }); test("iterable", () => { - const code = ` + util.testFunction` const iter: Iterable = [["a"], ["b"], ["c"]]; let i = 0; for (${destructuringPrefix}[] of iter) { ++i; } return i; - `; - expect(util.transpileAndExecute(code)).toBe(3); - }); - - test("luaIterator", () => { - const code = ` - const arr = [["a"], ["b"], ["c"]]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let it = 0; - return (() => arr[it++]) as any; - } - let i = 0; - for (${destructuringPrefix}[] of luaIter()) { - ++i; - } - return i; - `; - expect(util.transpileAndExecute(code)).toBe(3); - }); - - test("luaIterator+tupleReturn", () => { - const code = ` - const arr = [["a", "b"], ["c", "d"], ["e", "f"]]; - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let it = 0; - /** @tupleReturn */ - function iter() { - const e = arr[it++]; - if (e) { - return e; - } - } - return iter as any; - } - let i = 0; - for (${destructuringPrefix}[] of luaIter()) { - ++i; - } - return i; - `; - expect(util.transpileAndExecute(code)).toBe(3); + `.expectToMatchJsResult(); }); }; @@ -544,6 +486,7 @@ for (const testCase of [ [tstl.LuaTarget.Lua51]: builder => builder.expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]), [tstl.LuaTarget.Lua52]: expectContinueGotoLabel, [tstl.LuaTarget.Lua53]: expectContinueGotoLabel, + [tstl.LuaTarget.Lua54]: expectContinueGotoLabel, [tstl.LuaTarget.LuaJIT]: expectContinueGotoLabel, }); } @@ -583,7 +526,7 @@ test("do...while double-negation", () => { }); test("for...in with pre-defined variable", () => { - util.testFunction` + const testBuilder = util.testFunction` const obj = { x: "y", foo: "bar" }; let x = ""; @@ -592,16 +535,23 @@ test("for...in with pre-defined variable", () => { result.push(x); } return result; - `.expectToMatchJsResult(); + `; + // Need custom matcher because order is not guaranteed in neither JS nor Lua + expect(testBuilder.getJsExecutionResult()).toEqual(expect.arrayContaining(testBuilder.getLuaExecutionResult())); }); test("for...in with pre-defined variable keeps last value", () => { - util.testFunction` - const obj = { x: "y", foo: "bar" }; + const keyX = "x"; + const keyFoo = "foo"; + + const result = util.testFunction` + const obj = { ${keyX}: "y", ${keyFoo}: "bar" }; let x = ""; for (x in obj) { } return x; - `.expectToMatchJsResult(); + `.getLuaExecutionResult(); + // Need custom matcher because order is not guaranteed in neither JS nor Lua + expect([keyX, keyFoo]).toContain(result); }); diff --git a/test/unit/modules/__snapshots__/resolution.spec.ts.snap b/test/unit/modules/__snapshots__/resolution.spec.ts.snap index d4228141d..4db74c57f 100644 --- a/test/unit/modules/__snapshots__/resolution.spec.ts.snap +++ b/test/unit/modules/__snapshots__/resolution.spec.ts.snap @@ -2,9 +2,9 @@ exports[`doesn't resolve paths out of root dir: code 1`] = ` "local ____exports = {} -local module = require(\\"../module\\") +local module = require(\\"module\\") local ____ = module return ____exports" `; -exports[`doesn't resolve paths out of root dir: diagnostics 1`] = `"src/main.ts(2,33): error TSTL: Cannot create require path. Module '../module' does not exist within --rootDir."`; +exports[`doesn't resolve paths out of root dir: diagnostics 1`] = `"error TSTL: Could not resolve require path '../module' in file main.ts."`; diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index 885f24541..ffdc36ce9 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -58,138 +58,113 @@ test.each(["ke-bab", "dollar$", "singlequote'", "hash#", "s p a c e", "ɥɣɎɌ import { foo } from "./${name}"; export { foo }; ` - .disableSemanticCheck() - .setLuaHeader('setmetatable(package.loaded, { __index = function() return { foo = "bar" } end })') + .addExtraFile(`${name}.ts`, 'export const foo = "bar";') .setReturnExport("foo") .expectToEqual("bar"); } ); test.each(["export default value;", "export { value as default };"])("Export Default From (%p)", exportStatement => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - export { default } from "./module"; - `, - "module.ts": ` + util.testModule` + export { default } from "./module"; + ` + .addExtraFile( + "module.ts", + ` export const value = true; ${exportStatement}; - `, - }, - "default" - ); - - expect(result).toBe(true); + ` + ) + .expectToMatchJsResult(); }); test("Default Import and Export Expression", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport from "./module"; - export const value = defaultExport; - `, - "module.ts": ` + util.testModule` + import defaultExport from "./module"; + export const value = defaultExport; + ` + .addExtraFile( + "module.ts", + ` export default 1 + 2 + 3; - `, - }, - "value" - ); - - expect(result).toBe(6); + ` + ) + .expectToMatchJsResult(); }); test("Import and Export Assignment", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import * as m from "./module"; - export const value = m; - `, - "module.ts": ` + util.testModule` + // @ts-ignore + import * as m from "./module"; + export const value = m; + ` + .setOptions({ module: ts.ModuleKind.CommonJS }) + .addExtraFile( + "module.ts", + ` export = true; - `, - }, - "value" - ); - - expect(result).toBe(true); + ` + ) + .expectToMatchJsResult(); }); test("Mixed Exports, Default and Named Imports", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport, { a, b, c } from "./module"; - export const value = defaultExport + b + c; - `, - "module.ts": ` + util.testModule` + import defaultExport, { a, b, c } from "./module"; + export const value = defaultExport + b + c; + ` + .addExtraFile( + "module.ts", + ` export const a = 1; export const b = 2; export const c = 3; export default a; - `, - }, - "value" - ); - - expect(result).toBe(6); + ` + ) + .expectToMatchJsResult(); }); test("Mixed Exports, Default and Namespace Import", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport, * as ns from "./module"; - export const value = defaultExport + ns.b + ns.c; - `, - "module.ts": ` + util.testModule` + import defaultExport, * as ns from "./module"; + export const value = defaultExport + ns.b + ns.c; + ` + .addExtraFile( + "module.ts", + ` export const a = 1; export const b = 2; export const c = 3; export default a; - `, - }, - "value" - ); - - expect(result).toBe(6); + ` + ) + .expectToMatchJsResult(); }); test("Export Default Function", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport from "./module"; - export const value = defaultExport(); - `, - "module.ts": ` + const mainCode = ` + import defaultExport from "./module"; + export const value = defaultExport(); + `; + util.testModule(mainCode) + .addExtraFile( + "module.ts", + ` export default function() { return true; } - `, - }, - "value" - ); - - expect(result).toBe(true); + ` + ) + .expectToMatchJsResult(); }); test("Export Equals", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import * as module from "./module"; - export const value = module; - `, - "module.ts": ` - export = true; - `, - }, - "value" - ); - - expect(result).toBe(true); + util.testModule` + export = true; + ` + .setOptions({ module: ts.ModuleKind.CommonJS }) + .expectToMatchJsResult(); }); const reassignmentTestCases = [ @@ -275,3 +250,33 @@ test("export default function with future reference", () => { .setReturnExport("result") .expectToMatchJsResult(); }); + +const moduleFile = ` +export default true; +export const foo = "bar"; +`; + +test("export all does not include default", () => { + util.testModule` + export * from "./module"; + ` + .setOptions({ module: ts.ModuleKind.CommonJS }) + .addExtraFile("module.ts", moduleFile) + .expectToMatchJsResult(); +}); + +test("namespace export does not include default", () => { + util.testModule` + export * as result from "./module"; + ` + .addExtraFile("module.ts", moduleFile) + .expectToMatchJsResult(); +}); + +test("namespace export with unsafe Lua name", () => { + util.testModule` + export * as $$$ from "./module"; + ` + .addExtraFile("module.ts", moduleFile) + .expectToMatchJsResult(); +}); diff --git a/test/unit/modules/resolution.spec.ts b/test/unit/modules/resolution.spec.ts index 541c28c56..b2c7194b5 100644 --- a/test/unit/modules/resolution.spec.ts +++ b/test/unit/modules/resolution.spec.ts @@ -1,12 +1,14 @@ import * as ts from "typescript"; -import { unresolvableRequirePath } from "../../../src/transformation/utils/diagnostics"; +import { couldNotResolveRequire } from "../../../src/transpilation/diagnostics"; import * as util from "../../util"; const requireRegex = /require\("(.*?)"\)/; -const expectToRequire = (expected: string): util.TapCallback => builder => { - const [, requiredPath] = builder.getMainLuaCodeChunk().match(requireRegex) ?? []; - expect(requiredPath).toBe(expected); -}; +const expectToRequire = + (expected: string): util.TapCallback => + builder => { + const [, requiredPath] = builder.getMainLuaCodeChunk().match(requireRegex) ?? []; + expect(requiredPath).toBe(expected); + }; test.each([ { @@ -69,6 +71,7 @@ test.each([ module; ` .setMainFileName(filePath) + .addExtraFile(`${usedPath}.ts`, "") .setOptions(options) .tap(expectToRequire(expected)); }); @@ -81,7 +84,7 @@ test("doesn't resolve paths out of root dir", () => { .setMainFileName("src/main.ts") .setOptions({ rootDir: "./src" }) .disableSemanticCheck() - .expectDiagnosticsToMatchSnapshot([unresolvableRequirePath.code]); + .expectDiagnosticsToMatchSnapshot([couldNotResolveRequire.code]); }); test.each([ diff --git a/test/unit/namespaces.spec.ts b/test/unit/namespaces.spec.ts index 159fb8534..762152d67 100644 --- a/test/unit/namespaces.spec.ts +++ b/test/unit/namespaces.spec.ts @@ -11,14 +11,9 @@ test("legacy internal module syntax", () => { }); test("global scoping", () => { - const result = util.transpileAndExecute( - "return a.foo();", - undefined, - undefined, - 'namespace a { export function foo() { return "bar"; } }' - ); - - expect(result).toBe("bar"); + util.testFunction("return a.foo();") + .setTsHeader('namespace a { export function foo() { return "bar"; } }') + .expectToMatchJsResult(); }); test("nested namespace", () => { @@ -94,7 +89,7 @@ test("namespace merging across files", () => { } `; - util.testBundle` + util.testModule` import './a'; import './b'; @@ -102,7 +97,7 @@ test("namespace merging across files", () => { ` .addExtraFile("a.ts", a) .addExtraFile("b.ts", b) - .expectToEqual({ result: { foo: "foo", bar: "bar" } }); + .expectToMatchJsResult(); }); test("declared namespace function call", () => { diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index 819143e1f..16e7582d0 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -63,3 +63,66 @@ test.each(['{x: "foobar"}.x', '{x: "foobar"}["x"]', '{x: () => "foobar"}.x()', ' util.testExpression(expression).expectToMatchJsResult(); } ); + +describe("noSelf in functions", () => { + test("Explicit this: void parameter", () => { + // language=TypeScript + util.testFunction` + const obj: Record string> = { + method(a) { + return a; + }, + func: function(a) { + return a; + }, + arrow: (a) => { + return a; + } + }; + return [obj.method("a") ?? "nil", obj.func("b") ?? "nil", obj.arrow("c") ?? "nil"]; + `.expectToMatchJsResult(); + }); + + test("No self annotation", () => { + // language=TypeScript + util.testFunction` + const obj: Record string> = { + method(a) { + return a; + }, + func: function(a) { + return a; + }, + arrow: (a) => { + return a; + } + }; + return [obj.method("a") ?? "nil", obj.func("b") ?? "nil", obj.arrow("c") ?? "nil"]; + `.expectToMatchJsResult(); + }); + + test("individual function types", () => { + // language=TypeScript + util.testFunction` + interface FunctionContainer { + method: (this: void, a: string) => string + func: (this: void, a: string) => string + arrow: (this: void, a: string) => string + } + + const obj: FunctionContainer = { + method(a) { + return a + }, + func: function(a) { + return a + }, + arrow: (a) => { + return a + } + } + + return [obj.method("a") ?? "nil", obj.func("b") ?? "nil", obj.arrow("c") ?? "nil"]; + `.expectToMatchJsResult(); + }); +}); diff --git a/test/unit/optionalChaining.spec.ts b/test/unit/optionalChaining.spec.ts new file mode 100644 index 000000000..9763a91c6 --- /dev/null +++ b/test/unit/optionalChaining.spec.ts @@ -0,0 +1,178 @@ +import { notAllowedOptionalAssignment } from "../../src/transformation/utils/diagnostics"; +import * as util from "../util"; + +test.each(["null", "undefined", '{ foo: "foo" }'])("optional chaining (%p)", value => { + util.testFunction` + const obj: any = ${value}; + return obj?.foo; + `.expectToMatchJsResult(); +}); + +test("long optional chain", () => { + util.testFunction` + const a = { b: { c: { d: { e: { f: "hello!"}}}}}; + return a.b?.c?.d.e.f; + `.expectToMatchJsResult(); +}); + +test.each(["undefined", "{}", "{ foo: {} }", "{ foo: {bar: 'baz'}}"])("nested optional chaining (%p)", value => { + util.testFunction` + const obj: { foo?: { bar?: string } } | undefined = ${value}; + return obj?.foo?.bar; + `.expectToMatchJsResult(); +}); + +test.each(["undefined", "{}", "{ foo: {} }", "{ foo: {bar: 'baz'}}"])( + "nested optional chaining combined with coalescing (%p)", + value => { + util.testFunction` + const obj: { foo?: { bar?: string } } | undefined = ${value}; + return obj?.foo?.bar ?? "not found"; + `.expectToMatchJsResult(); + } +); + +test.each(["[1, 2, 3, 4]", "undefined"])("optional array access (%p)", value => { + util.testFunction` + const arr: number[] | undefined = ${value}; + return arr?.[2]; + `.expectToMatchJsResult(); +}); + +test.each(["[1, [2, [3, [4, 5]]]]", "[1, [2, [3, undefined]]] ", "[1, undefined]"])( + "optional element access nested (%p)", + value => { + util.testFunction` + const arr: [number, [number, [number, [number, number] | undefined]]] | [number, undefined] = ${value}; + return arr[1]?.[1][1]?.[0]; + `.expectToMatchJsResult(); + } +); + +test.each(["{ }", "{ a: { } }", "{ a: { b: [{ c: 10 }] } }"])( + "optional nested element access properties (%p)", + value => { + util.testFunction` + const obj: {a?: {b?: Array<{c: number }> } } = ${value}; + return [obj["a"]?.["b"]?.[0]?.["c"] ?? "not found", obj["a"]?.["b"]?.[2]?.["c"] ?? "not found"]; + `.expectToMatchJsResult(); + } +); + +test("optional element function calls", () => { + util.testFunction` + const obj: { value: string; foo?(this: void, v: number): number; bar?(this: void, v: number): number; } = { + value: "foobar", + foo: (v: number) => v + 10 + } + const fooKey = "foo"; + const barKey = "bar"; + return obj[barKey]?.(5) ?? obj[fooKey]?.(15); + `.expectToMatchJsResult(); +}); + +test("optional element access method calls", () => { + util.testFunction` + const obj: { value: string; foo?(prefix: string): string; bar?(prefix: string): string; } = { + value: "foobar", + foo(prefix: string) { return prefix + this.value; } + } + const fooKey = "foo"; + const barKey = "bar"; + return obj[barKey]?.("bar?") ?? obj[fooKey]?.("foo?"); + `.expectToMatchJsResult(); +}); + +test("no side effects", () => { + util.testFunction` + function getFoo(): { foo: number } | undefined { + return { foo: 42 }; + } + let barCalls = 0; + function getBar(): { bar: number } | undefined { + barCalls += 1; + return undefined; + } + const result = getFoo()?.foo ?? getBar()?.bar; + return { result, barCalls }; + `.expectToMatchJsResult(); +}); + +// Test for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1044 +test("does not crash when incorrectly used in assignment (#1044)", () => { + const { diagnostics } = util.testFunction` + foo?.bar = "foo"; + `.getLuaResult(); + + expect(diagnostics.find(d => d.code === notAllowedOptionalAssignment.code)).toBeDefined(); +}); + +describe("optional chaining function calls", () => { + test.each(["() => 4", "undefined"])("stand-alone optional function (%p)", value => { + util.testFunction` + const f: (() => number) | undefined = ${value}; + return f?.(); + `.expectToMatchJsResult(); + }); + + test("methods present", () => { + util.testFunction` + const objWithMethods = { + foo() { + return 3; + }, + bar(this: void) { + return 5; + } + }; + + return [objWithMethods?.foo(), objWithMethods?.bar()]; + `.expectToMatchJsResult(); + }); + + test("object with method can be undefined", () => { + util.testFunction` + const objWithMethods: { foo: () => number, bar: (this: void) => number } | undefined = undefined; + return [objWithMethods?.foo() ?? "no foo", objWithMethods?.bar() ?? "no bar"]; + `.expectToMatchJsResult(); + }); + + test("nested optional method call", () => { + util.testFunction` + type typeWithOptional = { a?: { b: { c: () => number } } }; + + const objWithMethods: typeWithOptional = {}; + const objWithMethods2: typeWithOptional = { a: { b: { c: () => 4 } } }; + + return { + expectNil: objWithMethods.a?.b.c(), + expectFour: objWithMethods2.a?.b.c() + }; + `.expectToMatchJsResult(); + }); + + test("methods are undefined", () => { + util.testFunction` + const objWithMethods: { foo?: () => number, bar?: (this: void) => number } = {}; + return [objWithMethods.foo?.() ?? "no foo", objWithMethods.bar?.() ?? "no bar"]; + `.expectToMatchJsResult(); + }); + + test("optional method of optional method result", () => { + util.testFunction` + const obj: { a?: () => {b: {c?: () => number }}} = {}; + const obj2: { a?: () => {b: {c?: () => number }}} = { a: () => ({b: {}})}; + const obj3: { a?: () => {b: {c?: () => number }}} = { a: () => ({b: { c: () => 5 }})}; + + return [obj.a?.().b.c?.() ?? "nil", obj2.a?.().b.c?.() ?? "nil", obj3.a?.().b.c?.() ?? "nil"]; + `.expectToMatchJsResult(); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1085 + test("incorrect type, method is not a function", () => { + util.testFunction` + const obj: any = {}; + obj?.foo(); + `.expectToEqual(new util.ExecutionError("foo is not a function")); + }); +}); diff --git a/test/unit/overloads.spec.ts b/test/unit/overloads.spec.ts index f911eeb2f..d18daa000 100644 --- a/test/unit/overloads.spec.ts +++ b/test/unit/overloads.spec.ts @@ -1,8 +1,8 @@ import * as util from "../util"; test("overload function1", () => { - const result = util.transpileAndExecute( - `function abc(def: number): string; + util.testFunction` + function abc(def: number): string; function abc(def: string): string; function abc(def: number | string): string { if (typeof def == "number") { @@ -11,15 +11,13 @@ test("overload function1", () => { return def; } } - return abc(3);` - ); - - expect(result).toBe("jkl9"); + return abc(3); + `.expectToMatchJsResult(); }); test("overload function2", () => { - const result = util.transpileAndExecute( - `function abc(def: number): string; + util.testFunction` + function abc(def: number): string; function abc(def: string): string; function abc(def: number | string): string { if (typeof def == "number") { @@ -28,15 +26,13 @@ test("overload function2", () => { return def; } } - return abc("ghj");` - ); - - expect(result).toBe("ghj"); + return abc("ghj"); + `.expectToMatchJsResult(); }); test("overload method1", () => { - const result = util.transpileAndExecute( - `class myclass { + util.testFunction` + class myclass { static abc(def: number): string; static abc(def: string): string; static abc(def: number | string): string { @@ -47,15 +43,13 @@ test("overload method1", () => { } } } - return myclass.abc(3);` - ); - - expect(result).toBe("jkl9"); + return myclass.abc(3); + `.expectToMatchJsResult(); }); test("overload method2", () => { - const result = util.transpileAndExecute( - `class myclass { + util.testFunction` + class myclass { static abc(def: number): string; static abc(def: string): string; static abc(def: number | string): string { @@ -66,15 +60,13 @@ test("overload method2", () => { } } } - return myclass.abc("ghj");` - ); - - expect(result).toBe("ghj"); + return myclass.abc("ghj"); + `.expectToMatchJsResult(); }); test("constructor1", () => { - const result = util.transpileAndExecute( - `class myclass { + util.testFunction` + class myclass { num: number; str: string; @@ -89,15 +81,13 @@ test("constructor1", () => { } } const inst = new myclass(3); - return inst.num` - ); - - expect(result).toBe(3); + return inst.num; + `.expectToMatchJsResult(); }); test("constructor2", () => { - const result = util.transpileAndExecute( - `class myclass { + util.testFunction` + class myclass { num: number; str: string; @@ -112,8 +102,6 @@ test("constructor2", () => { } } const inst = new myclass("ghj"); - return inst.str` - ); - - expect(result).toBe("ghj"); + return inst.str + `.expectToMatchJsResult(); }); diff --git a/test/unit/printer/deadCodeAfterReturn.spec.ts b/test/unit/printer/deadCodeAfterReturn.spec.ts index 0ccead50e..fba16387a 100644 --- a/test/unit/printer/deadCodeAfterReturn.spec.ts +++ b/test/unit/printer/deadCodeAfterReturn.spec.ts @@ -37,25 +37,25 @@ test("Method dead code after return", () => { }); test("for dead code after return", () => { - const result = util.transpileAndExecute("for (let i = 0; i < 10; i++) { return 3; const b = 8; }"); - - expect(result).toBe(3); + util.testFunction` + for (let i = 0; i < 10; i++) { return 3; const b = 8; } + `.expectToMatchJsResult(); }); test("for..in dead code after return", () => { - const result = util.transpileAndExecute('for (let a in {"a": 5, "b": 8}) { return 3; const b = 8; }'); - - expect(result).toBe(3); + util.testFunction` + for (let a in {"a": 5, "b": 8}) { return 3; const b = 8; } + `.expectToMatchJsResult(); }); test("for..of dead code after return", () => { - const result = util.transpileAndExecute("for (let a of [1,2,4]) { return 3; const b = 8; }"); - - expect(result).toBe(3); + util.testFunction` + for (let a of [1,2,4]) { return 3; const b = 8; } + `.expectToMatchJsResult(); }); test("while dead code after return", () => { - const result = util.transpileAndExecute("while (true) { return 3; const b = 8; }"); - - expect(result).toBe(3); + util.testFunction` + while (true) { return 3; const b = 8; } + `.expectToMatchJsResult(); }); diff --git a/test/unit/printer/parenthesis.spec.ts b/test/unit/printer/parenthesis.spec.ts index ef08a6e3d..6c8e58156 100644 --- a/test/unit/printer/parenthesis.spec.ts +++ b/test/unit/printer/parenthesis.spec.ts @@ -1,7 +1,7 @@ import * as util from "../../util"; test("binary expression with 'as' type assertion wrapped in parenthesis", () => { - expect(util.transpileAndExecute("return 2 * (3 - 2 as number);")).toBe(2); + util.testFunction("return 2 * (3 - 2 as number);").expectToMatchJsResult(); }); test.each([ @@ -26,7 +26,7 @@ test.each([ declare function z(this: void): unknown; ${expression}`; - const lua = util.transpileString(code, undefined, false); + const lua = util.testExpression(code).getMainLuaCodeChunk(); expect(lua).not.toMatch(/\(.+\)/); }); @@ -50,15 +50,14 @@ test.each([ declare let y: {}; ${expression}`; - const lua = util.transpileString(code, undefined, false); + const lua = util.testExpression(code).getMainLuaCodeChunk(); expect(lua).toMatch(/\(.+\)/); }); test("not operator precedence (%p)", () => { - const code = ` + util.testFunction` const a = true; const b = false; - return !a && b;`; - - expect(util.transpileAndExecute(code)).toBe(false); + return !a && b; + `.expectToMatchJsResult(); }); diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index 84a6596a6..891945dc3 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -1,5 +1,6 @@ import { Position, SourceMapConsumer } from "source-map"; import * as tstl from "../../../src"; +import { couldNotResolveRequire } from "../../../src/transpilation/diagnostics"; import * as util from "../../util"; test.each([ @@ -144,7 +145,11 @@ test.each([ ], }, ])("Source map has correct mapping (%p)", async ({ code, assertPatterns }) => { - const file = util.testModule(code).expectToHaveNoDiagnostics().getMainLuaFileResult(); + const file = util + .testModule(code) + .ignoreDiagnostics([couldNotResolveRequire.code]) + .expectToHaveNoDiagnostics() + .getMainLuaFileResult(); const consumer = await new SourceMapConsumer(file.luaSourceMap); for (const { luaPattern, typeScriptPattern } of assertPatterns) { @@ -157,32 +162,25 @@ test.each([ }); test.each([ - { fileName: "/proj/foo.ts", config: {}, mapSource: "foo.ts", fullSource: "foo.ts" }, + { fileName: "/proj/foo.ts", config: {} }, { fileName: "/proj/src/foo.ts", config: { outDir: "/proj/dst" }, - mapSource: "../src/foo.ts", - fullSource: "../src/foo.ts", }, { fileName: "/proj/src/foo.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst" }, - mapSource: "../src/foo.ts", - fullSource: "../src/foo.ts", }, { fileName: "/proj/src/sub/foo.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst" }, - mapSource: "../../src/sub/foo.ts", - fullSource: "../../src/sub/foo.ts", }, { fileName: "/proj/src/sub/main.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst", sourceRoot: "bin" }, - mapSource: "sub/main.ts", - fullSource: "bin/sub/main.ts", + fullSource: "bin/proj/src/sub/main.ts", }, -])("Source map has correct sources (%p)", async ({ fileName, config, mapSource, fullSource }) => { +])("Source map has correct sources (%p)", async ({ fileName, config, fullSource }) => { const file = util.testModule` const foo = "foo" ` @@ -192,11 +190,11 @@ test.each([ const sourceMap = JSON.parse(file.luaSourceMap); expect(sourceMap.sources).toHaveLength(1); - expect(sourceMap.sources[0]).toBe(mapSource); + expect(sourceMap.sources[0]).toBe(fileName); const consumer = await new SourceMapConsumer(file.luaSourceMap); expect(consumer.sources).toHaveLength(1); - expect(consumer.sources[0]).toBe(fullSource); + expect(consumer.sources[0]).toBe(fullSource ?? fileName); }); test.each([ @@ -274,6 +272,15 @@ test("sourceMapTraceback saves sourcemap in _G", () => { } }); +test("sourceMapTraceback gives traceback", () => { + const builder = util.testFunction` + return (debug.traceback as (this: void)=>string)(); + `.setOptions({ sourceMapTraceback: true, luaLibImport: tstl.LuaLibImportKind.Inline }); + + const traceback = builder.getLuaExecutionResult(); + expect(traceback).toEqual(expect.any(String)); +}); + test("Inline sourcemaps", () => { const code = ` function abc() { diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index b3b7c95a0..6b29d0cae 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -22,15 +22,16 @@ describe.each(["function call", "array literal"] as const)("in %s", kind => { util.testExpression(factory(expression)).expectToMatchJsResult(); }); - test.each(arrayLiteralCases)("of tuple return call (%p)", expression => { + test.each(arrayLiteralCases)("of multi return call (%p)", expression => { util.testFunction` - /** @tupleReturn */ function tuple(...args: any[]) { - return args; + return $multi(...args); } return ${factory(`...tuple(${expression})`)}; - `.expectToMatchJsResult(); + ` + .withLanguageExtensions() + .expectToMatchJsResult(); }); test("of multiple string literals", () => { @@ -73,27 +74,29 @@ describe("in function call", () => { return foo(...array); `, { - [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack), + [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack).expectToMatchJsResult(), [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), - [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack), - [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack), + [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua54]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), } ); }); describe("in array literal", () => { util.testEachVersion(undefined, () => util.testExpression`[...[0, 1, 2]]`, { - [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack), + [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack).expectToMatchJsResult(), [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), - [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack), - [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack), + [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua54]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), }); test("of array literal /w OmittedExpression", () => { util.testFunction` - const array = [1, 2, ...[3], , 5]; + const array = [1, 2, ...[3], 5, , 6]; return { a: array[0], b: array[1], c: array[2], d: array[3] }; `.expectToMatchJsResult(); }); @@ -128,3 +131,338 @@ describe("in object literal", () => { `.expectToMatchJsResult(); }); }); + +describe("vararg spread optimization", () => { + test("basic use", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + return pick(...args); + } + return test("a", "b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("body-less arrow function", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + const test = (...args: string[]) => pick(...args); + return test("a", "b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("if statement", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + if (true) { + return pick(...args); + } + } + return test("a", "b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("loop statement", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + do { + return pick(...args); + } while (false); + } + return test("a", "b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("block statement", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + let result: string; + { + result = pick(...args); + } + return result; + } + return test("a", "b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("finally clause", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + try { + throw "foobar"; + } catch { + } finally { + return pick(...args); + } + } + return test("a" ,"b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("$multi", () => { + util.testFunction` + function multi(...args: string[]) { + return $multi(...args); + } + function test(...args: string[]) { + return multi(...args)[1]; + } + return test("a" ,"b", "c"); + ` + .withLanguageExtensions() + .expectLuaToMatchSnapshot() + .expectToEqual("b"); + }); + + test("curry", () => { + util.testFunction` + function test(fn: (...args: A) => void, ...args: A) { + return fn(...args); + } + return test((arg: string) => arg, "foobar"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("curry with indirect type", () => { + util.testFunction` + function test(obj: {fn: (...args: A) => void}, ...args: A) { + const fn = obj.fn; + return fn(...args); + } + return test({fn: (arg: string) => arg}, "foobar"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("function type declared inside scope", () => { + util.testFunction` + function test(...args: A) { + const fn: (...args: A) => A[0] = (...args) => args[0]; + return fn(...args); + } + test("foobar"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); +}); + +describe("vararg spread de-optimization", () => { + test("array modification", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + args[1] = "foobar"; + return pick(...args); + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("array modification in hoisted function", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + hoisted(); + const result = pick(...args); + function hoisted() { args[1] = "foobar"; } + return result; + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("array modification in secondary hoisted function", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + function triggersHoisted() { hoisted(); } + triggersHoisted(); + const result = pick(...args); + function hoisted() { args[1] = "foobar"; } + return result; + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); +}); + +describe("vararg spread in IIFE", () => { + test("comma operator", () => { + util.testFunction` + function dummy() { return "foobar"; } + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + return (dummy(), pick(...args)); + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("assignment expression", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + let x: string; + return (x = pick(...args)); + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("destructured assignment expression", () => { + util.testFunction` + function pick(...args: string[]) { return [args[1]]; } + function test(...args: string[]) { + let x: string; + return ([x] = pick(...args)); + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("property-access assignment expression", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + let x: {val?: string} = {}; + return (x.val = pick(...args)); + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("binary compound assignment", () => { + util.testFunction` + function pick(...args: number[]) { return args[1]; } + function test(...args: number[]) { + let x = 1; + return x += pick(...args); + } + return test(1, 2, 3); + `.expectToMatchJsResult(); + }); + + test("postfix unary compound assignment", () => { + util.testFunction` + function pick(...args: number[]) { return args[1]; } + function test(...args: number[]) { + let x = [7, 8, 9]; + return x[pick(...args)]++; + } + return test(1, 2, 3); + `.expectToMatchJsResult(); + }); + + test("prefix unary compound assignment", () => { + util.testFunction` + function pick(...args: number[]) { return args[1]; } + function test(...args: number[]) { + let x = [7, 8, 9]; + return ++x[pick(...args)]; + } + return test(1, 2, 3); + `.expectToMatchJsResult(); + }); + + test("try clause", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + try { + return pick(...args) + } catch {} + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("catch clause", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + try { + throw "foobar"; + } catch { + return pick(...args) + } + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("class expression", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + const fooClass = class Foo { foo = pick(...args); }; + return new fooClass().foo; + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("self-referencing function expression", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + const test = function testName(...args: string[]) { + return \`\${typeof testName}:\${pick(...args)}\`; + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("method indirect access (access args)", () => { + util.testFunction` + const obj = { $method: () => obj.arg, arg: "foobar" }; + function getObj(...args: string[]) { obj.arg = args[1]; return obj; } + function test(...args: string[]) { + return getObj(...args).$method(); + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("method indirect access (method args)", () => { + util.testFunction` + const obj = { $pick: (...args: string[]) => args[1] }; + function getObj() { return obj; } + function test(...args: string[]) { + return getObj().$pick(...args); + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("tagged template method indirect access", () => { + util.testFunction` + const obj = { $tag: (t: TemplateStringsArray, ...args: string[]) => args[1] }; + function getObj() { return obj; } + function pick(...args: string[]): string { return args[1]; } + function test(...args: string[]) { + return getObj().$tag\`FOO\${pick(...args)}BAR\`; + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); +}); diff --git a/test/unit/switch.spec.ts b/test/unit/switch.spec.ts new file mode 100644 index 000000000..c264850c2 --- /dev/null +++ b/test/unit/switch.spec.ts @@ -0,0 +1,361 @@ +import * as tstl from "../../src"; +import { unsupportedForTarget } from "../../src/transformation/utils/diagnostics"; +import * as util from "../util"; + +test.each([0, 1, 2, 3])("switch (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: + result = 0; + break; + case 1: + result = 1; + break; + case 2: + result = 2; + break; + } + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("switchdefault (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: + result = 0; + break; + case 1: + result = 1; + break; + case 2: + result = 2; + break; + default: + result = -2; + break; + } + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 0, 2, 3, 4, 5, 7])("switchfallthrough (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: + result = 0; + case 1: + result = 1; + break; + case 2: + result = 2; + case 3: + case 4: + result = 4; + break; + case 5: + result = 5; + case 6: + result += 10; + break; + case 7: + result = 7; + default: + result = -2; + break; + } + + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("nestedSwitch (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp} as number) { + case 0: + result = 0; + break; + case 1: + switch(${inp} as number) { + case 0: + result = 0; + break; + case 1: + result = 1; + break; + default: + result = -3; + break; + } + break; + case 2: + result = 2; + break; + default: + result = -2; + break; + } + return result; + `.expectToMatchJsResult(); +}); + +test("switch cases scope", () => { + util.testFunction` + switch (0 as number) { + case 0: + let foo: number | undefined = 1; + case 1: + foo = 2; + case 2: + return foo; + } + `.expectToMatchJsResult(); +}); + +test("variable in nested scope does not interfere with case scope", () => { + util.testFunction` + let foo: number = 0; + switch (foo) { + case 0: { + let foo = 1; + } + + case 1: + return foo; + } + `.expectToMatchJsResult(); +}); + +test("switch using variable re-declared in cases", () => { + util.testFunction` + let foo: number = 0; + switch (foo) { + case 0: + let foo = true; + case 1: + return foo; + } + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2])("switch with block statement scope (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: { + let x = 0; + result = 0; + break; + } + case 1: { + let x = 1; + result = x; + } + case 2: { + let x = 2; + result = x; + break; + } + } + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("switchReturn (%p)", inp => { + util.testFunction` + switch (${inp}) { + case 0: + return 0; + break; + case 1: + return 1; + case 2: + return 2; + break; + } + + return -1; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("switchWithBrackets (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: { + result = 0; + break; + } + case 1: { + result = 1; + break; + } + case 2: { + result = 2; + break; + } + } + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("switchWithBracketsBreakInConditional (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: { + result = 0; + break; + } + case 1: { + result = 1; + + if (result == 1) break; + } + case 2: { + result = 2; + break; + } + } + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("switchWithBracketsBreakInInternalLoop (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp} as number) { + case 0: { + result = 0; + + for (let i = 0; i < 5; i++) { + result++; + + if (i >= 2) { + break; + } + } + } + case 1: { + result++; + break; + } + case 2: { + result = 2; + break; + } + } + return result; + `.expectToMatchJsResult(); +}); + +test("switch uses elseif", () => { + util.testFunction` + let result: number = -1; + + switch (2 as number) { + case 0: { + result = 200; + break; + } + + case 1: { + result = 100; + break; + } + + case 2: { + result = 1; + break; + } + } + + return result; + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); +}); + +test("switch not allowed in 5.1", () => { + util.testFunction` + switch ("abc") {} + ` + .setOptions({ luaTarget: tstl.LuaTarget.Lua51 }) + .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/967 +test("switch default case not last - first", () => { + util.testFunction` + switch (3 as number) { + default: + return "wrong"; + case 3: + return "right"; + } + `.expectToMatchJsResult(); +}); + +test("switch default case not last - second", () => { + util.testFunction` + switch (3 as number) { + case 4: + return "also wrong"; + default: + return "wrong"; + case 3: + return "right"; + } + `.expectToMatchJsResult(); +}); + +test("switch fallthrough enters default", () => { + util.testFunction` + const out = []; + switch (3 as number) { + case 3: + out.push("3"); + default: + out.push("default"); + } + return out; + `.expectToMatchJsResult(); +}); + +test("switch fallthrough does not enter earlier default", () => { + util.testFunction` + const out = []; + switch (3 as number) { + default: + out.push("default"); + case 3: + out.push("3"); + } + return out; + `.expectToMatchJsResult(); +}); + +test("switch fallthrough stops after default", () => { + util.testFunction` + const out = []; + switch (4 as number) { + default: + out.push("default"); + case 3: + out.push("3"); + } + return out; + `.expectToMatchJsResult(); +}); diff --git a/test/unit/templateLiterals.spec.ts b/test/unit/templateLiterals.spec.ts index 7db192a88..d5dc519a5 100644 --- a/test/unit/templateLiterals.spec.ts +++ b/test/unit/templateLiterals.spec.ts @@ -60,3 +60,26 @@ test.each(["func`noSelfParameter`", "obj.func`noSelfParameter`", "obj[`func`]`no `.expectToMatchJsResult(); } ); + +test.each(["number", "string | any"])("template span expect tostring for non string type (%p)", type => { + util.testFunction` + // @ts-ignore + const msg = "" as ${type}; + return \`\${msg}\`; + ` + .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain("tostring")) + .expectToMatchJsResult(); +}); + +test.each(["string", "'string literal type'", "string & unknown"])( + "template span expect no tostring for string-like type (%p)", + type => { + util.testFunction` + // @ts-ignore + const msg = "" as ${type}; + return \`\${msg}\`; + ` + .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toContain("tostring")) + .expectToMatchJsResult(); + } +); diff --git a/test/util.ts b/test/util.ts index 560b0102f..4398b1098 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,6 +1,6 @@ /* eslint-disable jest/no-standalone-expect */ import * as nativeAssert from "assert"; -import { lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; +import { LauxLib, Lua, LuaLib, LuaState, LUA_OK } from "lua-wasm-bindings/dist/lua"; import * as fs from "fs"; import { stringify } from "javascript-stringify"; import * as path from "path"; @@ -9,12 +9,36 @@ import * as ts from "typescript"; import * as vm from "vm"; import * as tstl from "../src"; import { createEmitOutputCollector } from "../src/transpilation/output-collector"; +import { EmitHost, getEmitOutDir, transpileProject } from "../src"; +import { formatPathToLuaPath, normalizeSlashes } from "../src/utils"; -export * from "./legacy-utils"; +const jsonLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); +const luaLib = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); // Using `test` directly makes eslint-plugin-jest consider this file as a test const defineTest = test; +function getLuaBindingsForVersion(target: tstl.LuaTarget): { lauxlib: LauxLib; lua: Lua; lualib: LuaLib } { + if (target === tstl.LuaTarget.Lua51) { + const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.51"); + return { lauxlib, lua, lualib }; + } + if (target === tstl.LuaTarget.Lua52) { + const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.52"); + return { lauxlib, lua, lualib }; + } + if (target === tstl.LuaTarget.Lua53) { + const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.53"); + return { lauxlib, lua, lualib }; + } + if (target === tstl.LuaTarget.LuaJIT) { + throw Error("Can't use executeLua() or expectToMatchJsResult() wit LuaJIT as target!"); + } + + const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.54"); + return { lauxlib, lua, lualib }; +} + export function assert(value: any, message?: string | Error): asserts value { nativeAssert(value, message); } @@ -41,76 +65,6 @@ export function testEachVersion( } } -function executeLua(code: string): any { - const L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - const status = lauxlib.luaL_dostring(L, to_luastring(code)); - - if (status === lua.LUA_OK) { - if (lua.lua_isstring(L, -1)) { - const result = eval(`(${lua.lua_tojsstring(L, -1)})`); - return result === null ? undefined : result; - } else { - const returnType = to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1))); - throw new Error(`Unsupported Lua return type: ${returnType}`); - } - } else { - // Filter out control characters appearing on some systems - const luaStackString = lua.lua_tostring(L, -1).filter(c => c >= 20); - const message = to_jsstring(luaStackString).replace(/^\[string "--\.\.\."\]:\d+: /, ""); - return new ExecutionError(message); - } -} - -const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); -const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); -export function executeLuaModule(code: string): any { - const lualibImport = code.includes('require("lualib_bundle")') - ? `package.preload.lualib_bundle = function()\n${lualibContent}\nend` - : ""; - - return executeLua(`${minimalTestLib}\n${lualibImport}\nreturn JSONStringify((function()\n${code}\nend)())`); -} - -function executeJsModule(code: string): any { - const exports = {}; - const context = vm.createContext({ exports, module: { exports } }); - context.global = context; - let result: unknown; - try { - result = vm.runInContext(code, context); - } catch (error) { - return new ExecutionError(error.message); - } - - function transform(currentValue: any): any { - if (currentValue === null) { - return undefined; - } - - if (Array.isArray(currentValue)) { - return currentValue.map(transform); - } - - if (typeof currentValue === "object") { - for (const [key, value] of Object.entries(currentValue)) { - currentValue[key] = transform(value); - if (currentValue[key] === undefined) { - delete currentValue[key]; - } - } - - if (Object.keys(currentValue).length === 0) { - return []; - } - } - - return currentValue; - } - - return transform(result); -} - const memoize: MethodDecorator = (_target, _propertyKey, descriptor) => { const originalFunction = descriptor.value as any; const memoized = new WeakMap(); @@ -162,7 +116,7 @@ export abstract class TestBuilder { return this; } - protected abstract getLuaCodeWithWrapper: (code: string) => string; + protected abstract getLuaCodeWithWrapper(code: string): string; public setLuaFactory(luaFactory: (code: string) => string): this { expect(this.hasProgram).toBe(false); this.getLuaCodeWithWrapper = luaFactory; @@ -176,8 +130,8 @@ export abstract class TestBuilder { return this; } - private options: tstl.CompilerOptions = { - luaTarget: tstl.LuaTarget.Lua53, + protected options: tstl.CompilerOptions = { + luaTarget: tstl.LuaTarget.Lua54, noHeader: true, skipLibCheck: true, target: ts.ScriptTarget.ES2017, @@ -193,14 +147,23 @@ export abstract class TestBuilder { return this; } + public withLanguageExtensions(): this { + this.setOptions({ types: [path.resolve(__dirname, "..", "language-extensions")] }); + // Polyfill lualib for JS + this.setJsHeader(` + function $multi(...args) { return args; } + `); + return this; + } + protected mainFileName = "main.ts"; public setMainFileName(mainFileName: string): this { expect(this.hasProgram).toBe(false); - this.mainFileName = mainFileName; + this.mainFileName = normalizeSlashes(mainFileName); return this; } - private extraFiles: Record = {}; + protected extraFiles: Record = {}; public addExtraFile(fileName: string, code: string): this { expect(this.hasProgram).toBe(false); this.extraFiles[fileName] = code; @@ -224,14 +187,34 @@ export abstract class TestBuilder { @memoize public getProgram(): ts.Program { this.hasProgram = true; - return tstl.createVirtualProgram({ ...this.extraFiles, [this.mainFileName]: this.getTsCode() }, this.options); + + // Exclude lua files from TS program, but keep them in extraFiles so module resolution can find them + const nonLuaExtraFiles = Object.fromEntries( + Object.entries(this.extraFiles).filter(([fileName]) => !fileName.endsWith(".lua")) + ); + + return tstl.createVirtualProgram( + { ...nonLuaExtraFiles, [normalizeSlashes(this.mainFileName)]: this.getTsCode() }, + this.options + ); + } + + private getEmitHost(): EmitHost { + return { + fileExists: (path: string) => normalizeSlashes(path) in this.extraFiles, + directoryExists: (path: string) => + Object.keys(this.extraFiles).some(f => f.startsWith(normalizeSlashes(path))), + getCurrentDirectory: () => ".", + readFile: (path: string) => this.extraFiles[normalizeSlashes(path)] ?? ts.sys.readFile(path), + writeFile() {}, + }; } @memoize public getLuaResult(): tstl.TranspileVirtualProjectResult { const program = this.getProgram(); const collector = createEmitOutputCollector(); - const { diagnostics: transpileDiagnostics } = new tstl.Transpiler().emit({ + const { diagnostics: transpileDiagnostics } = new tstl.Transpiler({ emitHost: this.getEmitHost() }).emit({ program, customTransformers: this.customTransformers, writeFile: collector.writeFile, @@ -250,7 +233,10 @@ export abstract class TestBuilder { const { transpiledFiles } = this.getLuaResult(); const mainFile = this.options.luaBundle ? transpiledFiles[0] - : transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => f.fileName === this.mainFileName)); + : transpiledFiles.find(({ sourceFiles }) => + sourceFiles.some(f => normalizeSlashes(f.fileName) === this.mainFileName) + ); + expect(mainFile).toMatchObject({ lua: expect.any(String), luaSourceMap: expect.any(String) }); return mainFile as ExecutableTranspiledFile; } @@ -263,7 +249,7 @@ export abstract class TestBuilder { @memoize public getLuaExecutionResult(): any { - return executeLuaModule(this.getLuaCodeWithWrapper(this.getMainLuaCodeChunk())); + return this.executeLua(); } @memoize @@ -277,10 +263,11 @@ export abstract class TestBuilder { } @memoize - protected getMainJsCodeChunk(): string { + public getMainJsCodeChunk(): string { const { transpiledFiles } = this.getJsResult(); - const code = transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => f.fileName === this.mainFileName)) - ?.js; + const code = transpiledFiles.find(({ sourceFiles }) => + sourceFiles.some(f => f.fileName === this.mainFileName) + )?.js; assert(code !== undefined); const header = this.jsHeader ? `${this.jsHeader.trimRight()}\n` : ""; @@ -291,26 +278,37 @@ export abstract class TestBuilder { @memoize public getJsExecutionResult(): any { - return executeJsModule(this.getJsCodeWithWrapper()); + return this.executeJs(); } // Utilities private getLuaDiagnostics(): ts.Diagnostic[] { const { diagnostics } = this.getLuaResult(); - return diagnostics.filter(d => this.semanticCheck || d.source === "typescript-to-lua"); + return diagnostics.filter( + d => (this.semanticCheck || d.source === "typescript-to-lua") && !this.ignoredDiagnostics.includes(d.code) + ); } // Actions - public debug(): this { - const luaCode = this.getMainLuaCodeChunk().replace(/^/gm, " "); + public debug(includeLualib = false): this { + const transpiledFiles = this.getLuaResult().transpiledFiles; + const luaCode = transpiledFiles + .filter(f => includeLualib || f.outPath !== "lualib_bundle.lua") + .map(f => `[${f.outPath}]:\n${f.lua?.replace(/^/gm, " ")}`); const value = prettyFormat(this.getLuaExecutionResult()).replace(/^/gm, " "); - console.log(`Lua Code:\n${luaCode}\n\nValue:\n${value}`); + console.log(`Lua Code:\n${luaCode.join("\n")}\n\nValue:\n${value}`); return this; } private diagnosticsChecked = false; + private ignoredDiagnostics: number[] = []; + + public ignoreDiagnostics(ignored: number[]): this { + this.ignoredDiagnostics.push(...ignored); + return this; + } public expectToHaveDiagnostics(expected?: number[]): this { if (this.diagnosticsChecked) return this; @@ -337,9 +335,19 @@ export abstract class TestBuilder { return this; } + private expectNoJsExecutionError(): this { + const jsResult = this.getJsExecutionResult(); + if (jsResult instanceof ExecutionError) { + throw jsResult; + } + + return this; + } + public expectToMatchJsResult(allowErrors = false): this { this.expectToHaveNoDiagnostics(); if (!allowErrors) this.expectNoExecutionError(); + if (!allowErrors) this.expectNoJsExecutionError(); const luaResult = this.getLuaExecutionResult(); const jsResult = this.getJsExecutionResult(); @@ -381,12 +389,148 @@ export abstract class TestBuilder { callback(this); return this; } + + private executeLua(): any { + // Main file + const mainFile = this.getMainLuaCodeChunk(); + + const { lauxlib, lua, lualib } = getLuaBindingsForVersion(this.options.luaTarget ?? tstl.LuaTarget.Lua54); + + const L = lauxlib.luaL_newstate(); + lualib.luaL_openlibs(L); + + // Load modules + // Json + this.packagePreloadLuaFile(L, lua, lauxlib, "json", jsonLib); + // Lua lib + if ( + this.options.luaLibImport === tstl.LuaLibImportKind.Require || + mainFile.includes('require("lualib_bundle")') + ) { + this.packagePreloadLuaFile(L, lua, lauxlib, "lualib_bundle", luaLib); + } + + // Load all transpiled files into Lua's package cache + const { transpiledFiles } = this.getLuaResult(); + for (const transpiledFile of transpiledFiles) { + if (transpiledFile.lua) { + const filePath = path.relative(getEmitOutDir(this.getProgram()), transpiledFile.outPath); + this.packagePreloadLuaFile(L, lua, lauxlib, filePath, transpiledFile.lua); + } + } + + // Execute Main + const wrappedMainCode = ` +local JSON = require("json"); +return JSON.stringify((function() + ${this.getLuaCodeWithWrapper(mainFile)} +end)());`; + + const status = lauxlib.luaL_dostring(L, wrappedMainCode); + + if (status === LUA_OK) { + if (lua.lua_isstring(L, -1)) { + const result = eval(`(${lua.lua_tostring(L, -1)})`); + lua.lua_close(L); + return result === null ? undefined : result; + } else { + const returnType = lua.lua_typename(L, lua.lua_type(L, -1)); + lua.lua_close(L); + throw new Error(`Unsupported Lua return type: ${returnType}`); + } + } else { + const luaStackString = lua.lua_tostring(L, -1); + const message = luaStackString.replace(/^\[string "(--)?\.\.\."\]:\d+: /, ""); + lua.lua_close(L); + return new ExecutionError(message); + } + } + + private packagePreloadLuaFile(state: LuaState, lua: Lua, lauxlib: LauxLib, fileName: string, fileContent: string) { + // Adding source Lua to the package.preload cache will allow require to find it + lua.lua_getglobal(state, "package"); + lua.lua_getfield(state, -1, "preload"); + lauxlib.luaL_loadstring(state, fileContent); + lua.lua_setfield(state, -2, formatPathToLuaPath(fileName.replace(".lua", ""))); + } + + private executeJs(): any { + const { transpiledFiles } = this.getJsResult(); + // Custom require for extra files. Really basic. Global support is hacky + // TODO Should be replaced with vm.Module https://nodejs.org/api/vm.html#vm_class_vm_module + // once stable + const globalContext: any = {}; + const mainExports = {}; + globalContext.exports = mainExports; + globalContext.module = { exports: mainExports }; + globalContext.require = (fileName: string) => { + // create clean export object for "module" + const moduleExports = {}; + globalContext.exports = moduleExports; + globalContext.module = { exports: moduleExports }; + const transpiledExtraFile = transpiledFiles.find(({ sourceFiles }) => + sourceFiles.some(f => f.fileName === fileName.replace("./", "") + ".ts") + ); + + if (transpiledExtraFile?.js) { + vm.runInContext(transpiledExtraFile.js, globalContext); + } + + // Have to return globalContext.module.exports + // becuase module.exports might no longer be equal to moduleExports (export assignment) + const result = globalContext.module.exports; + // Reset module/export + globalContext.exports = mainExports; + globalContext.module = { exports: mainExports }; + return result; + }; + + vm.createContext(globalContext); + + let result: unknown; + try { + result = vm.runInContext(this.getJsCodeWithWrapper(), globalContext); + } catch (error) { + return new ExecutionError(error.message); + } + + function removeUndefinedFields(obj: any): any { + if (obj === null) { + return undefined; + } + + if (Array.isArray(obj)) { + return obj.map(removeUndefinedFields); + } + + if (typeof obj === "object") { + const copy: any = {}; + for (const [key, value] of Object.entries(obj)) { + if (obj[key] !== undefined) { + copy[key] = removeUndefinedFields(value); + } + } + + if (Object.keys(copy).length === 0) { + return []; + } + + return copy; + } + + return obj; + } + + return removeUndefinedFields(result); + } } class AccessorTestBuilder extends TestBuilder { protected accessor = ""; - protected getLuaCodeWithWrapper = (code: string) => `return (function()\n${code}\nend)()${this.accessor}`; + protected getLuaCodeWithWrapper(code: string) { + return `return (function()\n${code}\nend)()${this.accessor}`; + } @memoize protected getJsCodeWithWrapper(): string { @@ -412,7 +556,6 @@ class ModuleTestBuilder extends AccessorTestBuilder { return this; } } - class FunctionTestBuilder extends AccessorTestBuilder { protected accessor = ".__main()"; public getTsCode(): string { @@ -427,25 +570,40 @@ class ExpressionTestBuilder extends AccessorTestBuilder { } } -const createTestBuilderFactory = ( - builder: new (_tsCode: string) => T, - serializeSubstitutions: boolean -) => (...args: [string] | [TemplateStringsArray, ...any[]]): T => { - let tsCode: string; - if (typeof args[0] === "string") { - expect(serializeSubstitutions).toBe(false); - tsCode = args[0]; - } else { - let [raw, ...substitutions] = args; - if (serializeSubstitutions) { - substitutions = substitutions.map(s => formatCode(s)); - } +class ProjectTestBuilder extends ModuleTestBuilder { + constructor(private tsConfig: string) { + super(""); + this.setOptions({ configFilePath: this.tsConfig, ...tstl.parseConfigFileWithSystem(this.tsConfig) }); + } - tsCode = String.raw(Object.assign([], { raw }), ...substitutions); + @memoize + public getLuaResult(): tstl.TranspileVirtualProjectResult { + // Override getLuaResult to use transpileProject with tsconfig.json instead + const collector = createEmitOutputCollector(); + const { diagnostics } = transpileProject(this.tsConfig, this.options, collector.writeFile); + + return { diagnostics: [...diagnostics], transpiledFiles: collector.files }; } +} - return new builder(tsCode); -}; +const createTestBuilderFactory = + (builder: new (_tsCode: string) => T, serializeSubstitutions: boolean) => + (...args: [string] | [TemplateStringsArray, ...any[]]): T => { + let tsCode: string; + if (typeof args[0] === "string") { + expect(serializeSubstitutions).toBe(false); + tsCode = args[0]; + } else { + let [raw, ...substitutions] = args; + if (serializeSubstitutions) { + substitutions = substitutions.map(s => formatCode(s)); + } + + tsCode = String.raw(Object.assign([], { raw }), ...substitutions); + } + + return new builder(tsCode); + }; export const testBundle = createTestBuilderFactory(BundleTestBuilder, false); export const testModule = createTestBuilderFactory(ModuleTestBuilder, false); @@ -454,3 +612,4 @@ export const testFunction = createTestBuilderFactory(FunctionTestBuilder, false) export const testFunctionTemplate = createTestBuilderFactory(FunctionTestBuilder, true); export const testExpression = createTestBuilderFactory(ExpressionTestBuilder, false); export const testExpressionTemplate = createTestBuilderFactory(ExpressionTestBuilder, true); +export const testProject = createTestBuilderFactory(ProjectTestBuilder, false);